X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fvideo.cpp;h=fbd2262181b6762ecb201d6c66b16640eaf420f0;hb=c0001155bc0909da61f6c849c0be9b16e9b7f4b6;hp=082120eb0f1d9ff0b3896fcc6181db9f4d925af8;hpb=eeb2935c12ef41a63049126748c2574b324403a5;p=apple2 diff --git a/src/video.cpp b/src/video.cpp index 082120e..fbd2262 100755 --- a/src/video.cpp +++ b/src/video.cpp @@ -1,302 +1,99 @@ -// -// VIDEO.CPP: SDL/local hardware specific video routines -// -// by James L. Hammons -// -// JLH = James L. Hammons -// -// WHO WHEN WHAT -// --- ---------- ------------------------------------------------------------ -// JLH 01/04/2006 Added changelog ;-) -// JLH 01/20/2006 Cut out unnecessary buffering -// - -#include "video.h" - -//#include -#include // Why??? (for memset, etc... Lazy!) Dunno why, but this just strikes me as wrong... -#include -#include "sdlemu_opengl.h" -#include "log.h" -#include "settings.h" -#include "icon.h" - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN -#define MASK_R 0xFF000000 -#define MASK_G 0x00FF0000 -#define MASK_B 0x0000FF00 -#define MASK_A 0x000000FF -#else -#define MASK_R 0x000000FF -#define MASK_G 0x0000FF00 -#define MASK_B 0x00FF0000 -#define MASK_A 0xFF000000 -#endif - -//#define TEST_ALPHA_BLENDING - -// Exported global variables (actually, these are LOCAL global variables, EXPORTED...) - -SDL_Surface * surface, * mainSurface, * someAlphaSurface; -Uint32 mainSurfaceFlags; -//uint32 scrBuffer[VIRTUAL_SCREEN_WIDTH * VIRTUAL_SCREEN_HEIGHT]; -uint32 * scrBuffer = NULL; -SDL_Joystick * joystick; - -// -// Prime SDL and create surfaces -// -bool InitVideo(void) -{ - // Set up SDL library - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE) < 0) - { - WriteLog("Video: Could not initialize the SDL library: %s\n", SDL_GetError()); - return false; - } - - //Set icon (mainly for Win32 target--though seems to work under KDE as well...!) - SDL_Surface * iconSurf = SDL_CreateRGBSurfaceFrom(icon, 32, 32, 32, 128, - MASK_R, MASK_G, MASK_B, MASK_A); - SDL_WM_SetIcon(iconSurf, NULL); - SDL_FreeSurface(iconSurf); - - // Get proper info about the platform we're running on... - const SDL_VideoInfo * info = SDL_GetVideoInfo(); - - if (!info) - { - WriteLog("Video: SDL is unable to get the video info: %s\n", SDL_GetError()); - return false; - } - - if (settings.useOpenGL) - { - mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF | SDL_OPENGL; - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - } - else - { - mainSurfaceFlags = SDL_DOUBLEBUF; - - if (info->hw_available) - { - mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE; - WriteLog("Video: Hardware available...\n"); - } - - if (info->blit_hw) - { - mainSurfaceFlags |= SDL_HWACCEL; - WriteLog("Video: Hardware blit available...\n"); - } - } - - if (settings.fullscreen) - mainSurfaceFlags |= SDL_FULLSCREEN; - - // Create the primary SDL display (32 BPP) - if (!settings.useOpenGL) - mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, 32, mainSurfaceFlags); - else -// mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH * 2, VIRTUAL_SCREEN_HEIGHT * 2, 32, mainSurfaceFlags); -// mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT * 2, 32, mainSurfaceFlags); - mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, 32, mainSurfaceFlags); - - if (mainSurface == NULL) - { - WriteLog("Video: SDL is unable to set the video mode: %s\n", SDL_GetError()); - return false; - } - - SDL_WM_SetCaption("Apple 2 SDL", "Apple 2 SDL"); - - // Create the secondary SDL display (32 BPP) that we use directly - surface = SDL_CreateRGBSurface(SDL_SWSURFACE, VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, 32, - MASK_R, MASK_G, MASK_B, MASK_A); -/*WriteLog("Video: Created secondary surface with attributes:\n\n"); -WriteLog("\tWidth, height: %u x %u\n", surface->w, surface->h); -WriteLog("\t Pitch: %u\n", surface->pitch); -WriteLog("\t Palette: %08X\n", surface->format->palette); -WriteLog("\t BPP: %u\n", surface->format->BitsPerPixel); -WriteLog("\t BytesPP: %u\n", surface->format->BytesPerPixel); -WriteLog("\t RMask: %08X\n", surface->format->Rmask); -WriteLog("\t GMask: %08X\n", surface->format->Gmask); -WriteLog("\t BMask: %08X\n", surface->format->Bmask); -WriteLog("\t AMask: %08X\n", surface->format->Amask); -WriteLog("\n");//*/ - - if (surface == NULL) - { - WriteLog("Video: Could not create secondary SDL surface: %s\n", SDL_GetError()); - return false; - } - - if (settings.useOpenGL) - sdlemu_init_opengl(surface, mainSurface, 1 /*method*/, settings.glFilter /*texture type (linear, nearest)*/, - 0 /* Automatic bpp selection based upon src */); - - // Initialize Joystick support under SDL -/* if (settings.useJoystick) - { - if (SDL_NumJoysticks() <= 0) - { - settings.useJoystick = false; - WriteLog("Video: No joystick(s) or joypad(s) detected on your system. Using keyboard...\n"); - } - else - { - if ((joystick = SDL_JoystickOpen(settings.joyport)) == 0) - { - settings.useJoystick = false; - WriteLog("Video: Unable to open a Joystick on port: %d\n", (int)settings.joyport); - } - else - WriteLog("Video: Using: %s\n", SDL_JoystickName(settings.joyport)); - } - }//*/ - - // Set up the scrBuffer - scrBuffer = (uint32 *)surface->pixels; // Kludge--And shouldn't have to lock since it's a software surface... -//needed? Dunno. Mebbe an SDL function instead? -// memset(scrBuffer, 0x00, VIRTUAL_SCREEN_WIDTH * VIRTUAL_SCREEN_HEIGHT * sizeof(uint32)); - -#ifdef TEST_ALPHA_BLENDING -//Here's some code to test alpha blending... -//Well whaddya know, it works. :-) - someAlphaSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, 30, 30, 32, - MASK_R, MASK_G, MASK_B, MASK_A); - - for(int i=0; i<30; i++) - { - for(int j=0; j<30; j++) - { - uint32 color = (uint32)(((double)(i * j) / (29.0 * 29.0)) * 255.0); - color = (color << 24) | 0x00FF00FF; - ((uint32 *)someAlphaSurface->pixels)[(j * 30) + i] = color; - } - } -//End test code -#endif - - WriteLog("Video: Successfully initialized.\n"); - return true; -} - -// -// Free various SDL components -// -void VideoDone(void) -{ - if (settings.useOpenGL) - sdlemu_close_opengl(); - - SDL_JoystickClose(joystick); - SDL_FreeSurface(surface); - SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_TIMER); - SDL_Quit(); -} - -// -// Render the screen buffer to the primary screen surface -// -//void RenderBackbuffer(void) -void RenderScreenBuffer(void) -{ -//WriteLog("Video: Blitting a %u x %u surface to the main surface...\n", surface->w, surface->h); -//Don't need this crapola--why have a separate buffer just to copy it to THIS -//buffer in order to copy it to the main screen? That's what *I* thought! -/* if (SDL_MUSTLOCK(surface)) - while (SDL_LockSurface(surface) < 0) - SDL_Delay(10); - - memcpy(surface->pixels, scrBuffer, VIRTUAL_SCREEN_WIDTH * VIRTUAL_SCREEN_HEIGHT * sizeof(uint32)); - - if (SDL_MUSTLOCK(surface)) - SDL_UnlockSurface(surface);//*/ -#ifdef TEST_ALPHA_BLENDING -SDL_Rect dstRect = { 100, 100, 30, 30 }; -SDL_BlitSurface(someAlphaSurface, NULL, surface, &dstRect); -#endif - - if (settings.useOpenGL) - sdlemu_draw_texture(mainSurface, surface, 1/*1=GL_QUADS*/); - else - { -// SDL_Rect rect = { 0, 0, surface->w, surface->h }; -// SDL_BlitSurface(surface, &rect, mainSurface, &rect); - SDL_BlitSurface(surface, NULL, mainSurface, NULL); - SDL_Flip(mainSurface); - } -} - -/* -// -// Resize the main SDL screen & scrBuffer -// -void ResizeScreen(uint32 width, uint32 height) -{ - char window_title[256]; - - SDL_FreeSurface(surface); - surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 16, - 0x7C00, 0x03E0, 0x001F, 0); - - if (surface == NULL) - { - WriteLog("Video: Could not create primary SDL surface: %s", SDL_GetError()); - exit(1); - } - - if (settings.useOpenGL) - // This seems to work well for resizing (i.e., changes in the pixel width)... - sdlemu_resize_texture(surface, mainSurface, settings.glFilter); - else - { - mainSurface = SDL_SetVideoMode(width, height, 16, mainSurfaceFlags); - - if (mainSurface == NULL) - { - WriteLog("Video: SDL is unable to set the video mode: %s\n", SDL_GetError()); - exit(1); - } - } - - sWriteLog(window_title, "Virtual Jaguar (%i x %i)", (int)width, (int)height); - SDL_WM_SetCaption(window_title, window_title); - - // This seems to work well for resizing (i.e., changes in the pixel width)... -// if (settings.useOpenGL) -// sdlemu_resize_texture(surface, mainSurface); -}*/ - -/* -// -// Fullscreen <-> window switching -// -//NOTE: This does *NOT* work with OpenGL rendering! !!! FIX !!! -void ToggleFullscreen(void) -{ - settings.fullscreen = !settings.fullscreen; - mainSurfaceFlags &= ~SDL_FULLSCREEN; - - if (settings.fullscreen) - mainSurfaceFlags |= SDL_FULLSCREEN; - - if (!settings.useOpenGL) - mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, 32, mainSurfaceFlags); - else -// mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH * 2, VIRTUAL_SCREEN_HEIGHT * 2, 32, mainSurfaceFlags); -// mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT * 2, 32, mainSurfaceFlags); - mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, 32, mainSurfaceFlags); -// mainSurface = SDL_SetVideoMode(tom_width, tom_height, 16, mainSurfaceFlags); - - if (mainSurface == NULL) - { - WriteLog("Video: SDL is unable to set the video mode: %s\n", SDL_GetError()); - exit(1); - } - - SDL_WM_SetCaption("Apple 2 SDL", "Apple 2 SDL"); -} -//*/ +// +// VIDEO.CPP: SDL/local hardware specific video routines +// +// by James L. Hammons +// +// JLH = James L. Hammons +// +// WHO WHEN WHAT +// --- ---------- ------------------------------------------------------------ +// JLH 01/04/2006 Added changelog ;-) +// JLH 01/20/2006 Cut out unnecessary buffering +// + +#include "video.h" +#include +#include // Why??? (for memset, etc... Lazy!) Dunno why, but this just strikes me as wrong... +#include +#include "log.h" +#include "settings.h" + + +// Exported global variables (actually, these are LOCAL global variables, EXPORTED...) + +static SDL_Window * sdlWindow = NULL; +static SDL_Renderer * sdlRenderer = NULL; +static SDL_Texture * sdlTexture = NULL; +uint32_t scrBuffer[VIRTUAL_SCREEN_WIDTH * VIRTUAL_SCREEN_HEIGHT * sizeof(uint32_t)]; + + +// +// Prime SDL and create surfaces +// +bool InitVideo(void) +{ + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE) != 0) + { + WriteLog("Video: Could not initialize the SDL library: %s\n", SDL_GetError()); + return false; + } + + int retVal = SDL_CreateWindowAndRenderer(VIRTUAL_SCREEN_WIDTH * 2, VIRTUAL_SCREEN_HEIGHT * 2, SDL_WINDOW_OPENGL, &sdlWindow, &sdlRenderer); + + if (retVal != 0) + { + WriteLog("Video: Could not window and/or renderer: %s\n", SDL_GetError()); + return false; + } + + // Make the scaled rendering look smoother. + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); +// SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest"); + SDL_RenderSetLogicalSize(sdlRenderer, VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT); + + sdlTexture = SDL_CreateTexture(sdlRenderer, + SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, + VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT); + + WriteLog("Video: Successfully initialized.\n"); + return true; +} + + +// +// Free various SDL components +// +void VideoDone(void) +{ + WriteLog("Video: Shutting down SDL...\n"); + SDL_Quit(); + WriteLog("Video: Done.\n"); +} + + +// +// Render the screen buffer to the primary screen surface +// +void RenderScreenBuffer(void) +{ + SDL_UpdateTexture(sdlTexture, NULL, scrBuffer, VIRTUAL_SCREEN_WIDTH * sizeof(Uint32)); + SDL_RenderClear(sdlRenderer); + SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL); + SDL_RenderPresent(sdlRenderer); +} + + +// +// Fullscreen <-> window switching +// +void ToggleFullScreen(void) +{ + settings.fullscreen = !settings.fullscreen; + + int retVal = SDL_SetWindowFullscreen(sdlWindow, (settings.fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)); + SDL_ShowCursor(settings.fullscreen ? 0 : 1); + + if (retVal != 0) + WriteLog("Video::ToggleFullScreen: SDL error = %s\n", SDL_GetError()); +} +