]> Shamusworld >> Repos - stargem2/blobdiff - src/video.cpp
Finally fixed problems with demo mode.
[stargem2] / src / video.cpp
old mode 100755 (executable)
new mode 100644 (file)
index fe552b9..8baa478
 //
 // VIDEO.CPP: SDL/local hardware specific video routines
 //
-// by James L. Hammons
+// by James Hammons
 //
 
 #include "video.h"
-
-//#include "SDL.h"
+#include <SDL2/SDL.h>
 #include <string.h>    // Why??? (for memset, etc... Lazy!) Dunno why, but this just strikes me as wrong...
 #include <malloc.h>
-#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 = NULL;
-SDL_Joystick * joystick;
+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)
 {
-       // Set up SDL library
-       if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE) < 0)
+       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;
        }
 
-       // Get proper info about the platform we're running on...
-       const SDL_VideoInfo * info = SDL_GetVideoInfo();
+       int retVal = SDL_CreateWindowAndRenderer(VIRTUAL_SCREEN_WIDTH * 3, VIRTUAL_SCREEN_HEIGHT * 3, SDL_WINDOW_OPENGL, &sdlWindow, &sdlRenderer);
 
-       if (!info)
+       if (retVal != 0)
        {
-               WriteLog("Video: SDL is unable to get the video info: %s\n", SDL_GetError());
+               WriteLog("Video: Could not window and/or renderer: %s\n", SDL_GetError());
                return false;
        }
 
-       WriteLog("Video: Hardware is%s available...\n", (info->hw_available ? "" : " NOT"));
-       WriteLog("Video: Hardware blit is%s available...\n", (info->blit_hw ? "" : " NOT"));
-
-       if (settings.useOpenGL)
-       {
-               mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_OPENGL;
-               SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-//We want 32BPP, so force the issue...
-               SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
-               SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
-               SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
-       }
-       else
-       {
-               mainSurfaceFlags = SDL_DOUBLEBUF;
-
-               if (info->hw_available)
-                       mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE;
-
-               if (info->blit_hw)
-                       mainSurfaceFlags |= SDL_HWACCEL;
-       }
-
-       if (settings.fullscreen)
-               mainSurfaceFlags |= SDL_FULLSCREEN;
-
-       // Create the primary SDL display (32 BPP)
-       if (settings.useOpenGL)
-               mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH * 2, VIRTUAL_SCREEN_HEIGHT * 2, 32, mainSurfaceFlags);
-       else
-               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;
-       }
-
-       // 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);
-
-       SDL_WM_SetCaption("StarGem2", "StarGem2");
-
-       // 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);
+       // 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);
 
-       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
+       sdlTexture = SDL_CreateTexture(sdlRenderer,
+               SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING,
+               VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT);
 
        WriteLog("Video: Successfully initialized.\n");
        return true;
@@ -180,298 +55,41 @@ WriteLog("\n");//*/
 //
 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();
 }
 
-
-
-#if 0
-///
-
-#include "SDL.h"
-#include <string.h>    // Why??? (for memset, etc... Lazy!) Dunno why, but this just strikes me as wrong...
-#include <malloc.h>
-#include "sdlemu_opengl.h"
-#include "types.h"
-#include "log.h"
-#include "settings.h"
-#include "video.h"
-
-// External global variables
-
-SDL_Surface * surface, * mainSurface;
-Uint32 mainSurfaceFlags;
-uint8 * backbuffer;
-SDL_Joystick * joystick;
-uint8 color[16];
-uint32 palette[256];
-
-//
-// 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;
-       }
-
-       // 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 (1)//(vjs.useOpenGL)
-       {
-               mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF | SDL_OPENGL;
-               SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-       }
-       else
-       {
-               if (info->hw_available)
-               {
-                       mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF;
-                       WriteLog("Video: Hardware available...\n");
-               }
-
-               if (info->blit_hw)
-               {
-                       mainSurfaceFlags |= SDL_HWACCEL;
-                       WriteLog("Video: Hardware blit available...\n");
-               }
-       }
-
-//     if (vjs.fullscreen)
-//             mainSurfaceFlags |= SDL_FULLSCREEN;
-
-       if (0)//(!vjs.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);
-
-       if (mainSurface == NULL)
-       {
-               WriteLog("Video: SDL is unable to set the video mode: %s\n", SDL_GetError());
-               return false;
-       }
-
-       SDL_WM_SetCaption("StarGem2", "StarGem2");
-
-       // Create the primary SDL display (8 BPP, palettized)
-//     surface = SDL_CreateRGBSurface(SDL_SWSURFACE, VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT,
-//             8, 0, 0, 0, 0);
-       // Create the primary SDL display (32 BPP)
-       surface = SDL_CreateRGBSurface(SDL_SWSURFACE, VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, 32,
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
-               0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
-#else
-               0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
-#endif
-               );
-/*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 primary SDL surface: %s\n", SDL_GetError());
-               return false;
-       }
-
-       // Initialize Williams' palette (RGB coded as: 3 bits red, 3 bits green, 2 bits blue)
-       for(uint32 i=0; i<256; i++)
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
-               palette[i] = (((i & 0x01) * 33 + ((i & 0x02) >> 1) * 71 + ((i & 0x04) >> 2) * 151) << 24)
-                       | ((((i & 0x08) >> 3) * 33 + ((i & 0x10) >> 4) * 71 + ((i & 0x20) >> 5) * 151) << 16)
-                       | ((((i & 0x40) >> 6) * 71 + ((i & 0x80) >> 7) * 151) << 8) | 0xFF;//*/
-#else
-               palette[i] = ((i & 0x01) * 33 + ((i & 0x02) >> 1) * 71 + ((i & 0x04) >> 2) * 151)
-                       | ((((i & 0x08) >> 3) * 33 + ((i & 0x10) >> 4) * 71 + ((i & 0x20) >> 5) * 151) << 8)
-                       | ((((i & 0x40) >> 6) * 71 + ((i & 0x80) >> 7) * 151) << 16) | 0xFF000000;//*/
-#endif
-
-//     if (vjs.useOpenGL)
-       if (1)
-//Should make another setting here, for either linear or nearest (instead of just picking one)
-//And we have! ;-) Not... ;-(
-//             sdlemu_init_opengl(surface, 1/*method*/, 2/*size*/, 0);//vjs.glFilter/*texture type (linear, nearest)*/);
-               sdlemu_init_opengl(surface, mainSurface, 1 /*method*/,
-                       0 /*vjs.glFilter /texture type (linear, nearest)*/,
-                       0 /* Automatic bpp selection based upon src */);
-
-       // Initialize Joystick support under SDL
-/*     if (1)//(vjs.useJoystick)
-       {
-               if (SDL_NumJoysticks() <= 0)
-               {
-                       vjs.useJoystick = false;
-                       WriteLog("Video: No joystick(s) or joypad(s) detected on your system. Using keyboard...\n");
-               }
-               else
-               {
-                       if ((joystick = SDL_JoystickOpen(vjs.joyport)) == 0)
-                       {
-                               vjs.useJoystick = false;
-                               WriteLog("Video: Unable to open a Joystick on port: %d\n", (int)vjs.joyport);
-                       }
-                       else
-                               WriteLog("Video: Using: %s\n", SDL_JoystickName(vjs.joyport));
-               }
-       }*/
-
-       // Set up the backbuffer
-       backbuffer = (uint8 *)malloc(320 * 240 * sizeof(uint8));
-       memset(backbuffer, 0x00, VIRTUAL_SCREEN_WIDTH * VIRTUAL_SCREEN_HEIGHT * sizeof(uint8));
-
-       WriteLog("Video: Successfully initialized.\n");
-       return true;
-}
-
-#endif
-
-
-
 //
 // Render the backbuffer to the primary screen surface
 //
 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_BlitSurface(surface, NULL, mainSurface, NULL);
-               SDL_Flip(mainSurface);
-    }
-}
-
-//
-// Render the backbuffer to the primary screen surface
-//
-void RenderScreenBuffer2(void)
-{
-#if 0
-//WriteLog("Video: Blitting a %u x %u surface to the main surface...", surface->w, surface->h);
-       if (SDL_MUSTLOCK(surface))
-               while (SDL_LockSurface(surface) < 0)
-                       SDL_Delay(10);
-
-//This *does* ignore the screen's actual pitch... !!! FIX !!!
-       uint32 * screen = (uint32 *)surface->pixels;
-       for(int i=0; i<320*240; i++)
-               screen[i] = palette[color[scrBuffer[i]]];
-//WriteLog("[blitted backbuffer]...");
-
-       if (SDL_MUSTLOCK(surface))
-               SDL_UnlockSurface(surface);
-#endif
-
-       if (settings.useOpenGL)
-               sdlemu_draw_texture(mainSurface, surface, 1/*1=GL_QUADS*/);
-       else
-       {
-               SDL_BlitSurface(surface, NULL, mainSurface, NULL);
-               SDL_Flip(mainSurface);
-    }
-//WriteLog("done.\n");
+       SDL_UpdateTexture(sdlTexture, NULL, scrBuffer, VIRTUAL_SCREEN_WIDTH * sizeof(Uint32));
+       SDL_RenderClear(sdlRenderer);
+       SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL);
+       SDL_RenderPresent(sdlRenderer);
 }
 
-/*
 //
-// Resize the main SDL screen & backbuffer
+// Fullscreen <-> window switching
 //
-void ResizeScreen(uint32 width, uint32 height)
+void ToggleFullScreen(void)
 {
-       char window_title[256];
+       settings.fullscreen = !settings.fullscreen;
+       int retVal;
 
-       SDL_FreeSurface(surface);
-       surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 16,
-               0x7C00, 0x03E0, 0x001F, 0);
-
-       if (surface == NULL)
+       if (settings.fullscreen)
        {
-               WriteLog("Video: Could not create primary SDL surface: %s", SDL_GetError());
-               exit(1);
+               retVal = SDL_SetWindowFullscreen(sdlWindow, SDL_WINDOW_FULLSCREEN_DESKTOP);
+               SDL_ShowCursor(0);
        }
-
-       if (vjs.useOpenGL)
-               // This seems to work well for resizing (i.e., changes in the pixel width)...
-               sdlemu_resize_texture(surface, mainSurface, vjs.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);
-               }
+               retVal = SDL_SetWindowFullscreen(sdlWindow, 0);
+               SDL_ShowCursor(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 (vjs.useOpenGL)
-//             sdlemu_resize_texture(surface, mainSurface);
-}
-
-//
-// Fullscreen <-> window switching
-//
-//NOTE: This does *NOT* work with OpenGL rendering! !!! FIX !!!
-void ToggleFullscreen(void)
-{
-       vjs.fullscreen = !vjs.fullscreen;
-       mainSurfaceFlags &= ~SDL_FULLSCREEN;
-
-       if (vjs.fullscreen)
-               mainSurfaceFlags |= SDL_FULLSCREEN;
-
-       mainSurface = SDL_SetVideoMode(tom_width, tom_height, 16, mainSurfaceFlags);
-
-       if (mainSurface == NULL)
+       if (retVal != 0)
        {
-               WriteLog("Video: SDL is unable to set the video mode: %s\n", SDL_GetError());
-               exit(1);
+               WriteLog("Video::ToggleFullScreen: SDL error = %s\n", SDL_GetError());
        }
-
-       SDL_WM_SetCaption("Virtual Jaguar", "Virtual Jaguar");
 }
-*/