//
#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[VIRTUAL_SCREEN_WIDTH * VIRTUAL_SCREEN_HEIGHT];
-uint32 * scrBuffer = NULL, * mainScrBuffer = 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 | SDL_INIT_EVENTTHREAD) < 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;
}
- //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();
+ int retVal = SDL_CreateWindowAndRenderer(VIRTUAL_SCREEN_WIDTH * 2, VIRTUAL_SCREEN_HEIGHT * 2, 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;
}
- 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");
- }
+ // 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);
- 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);
-#if 0
-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");
-#endif
-
- 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));
- // Set up the mainScrBuffer
- mainScrBuffer = (uint32 *)mainSurface->pixels; // May need to lock...
-
-#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
+ 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 OpenGL...\n");
- if (settings.useOpenGL)
- sdlemu_close_opengl();
-
-// WriteLog("Video: Shutting down joystick....\n");
-// SDL_JoystickClose(joystick);
- WriteLog("Video: Freeing 'surface'...\n");
- SDL_FreeSurface(surface);
-#warning "The problem is here: Doing the SDL_Quit function causes a double free. !!! FIX !!!"
-#warning "Some googling suggests that it may be the thread component causing the trouble."
-#if 0
-*** glibc detected *** ./apple2: double free or corruption (!prev): 0x08239480 ***
-======= Backtrace: =========
-/lib/libc.so.6[0xb7c96572]
-/lib/libc.so.6[0xb7c97cc3]
-/lib/libc.so.6(cfree+0x6d)[0xb7c9afed]
-/usr/lib/dri/radeon_dri.so(_mesa_free+0x1d)[0xb6edefbd]
-/usr/lib/dri/radeon_dri.so(_mesa_delete_texture_image+0x41)[0xb6efc6b1]
-/usr/lib/dri/radeon_dri.so(_mesa_delete_texture_object+0x75)[0xb6f032d5]
-/usr/lib/dri/radeon_dri.so[0xb6e898fd]
-/usr/lib/dri/radeon_dri.so[0xb6eab379]
-/usr/lib/dri/radeon_dri.so(_mesa_HashDeleteAll+0x66)[0xb6ecb236]
-/usr/lib/dri/radeon_dri.so[0xb6eabb76]
-/usr/lib/dri/radeon_dri.so(_mesa_free_context_data+0x1d1)[0xb6eac8e1]
-/usr/lib/dri/radeon_dri.so(_mesa_destroy_context+0x26)[0xb6eac976]
-/usr/lib/dri/radeon_dri.so(radeonDestroyContext+0x13b)[0xb6e7b97b]
-/usr/lib/dri/radeon_dri.so[0xb6e779c7]
-//usr//lib/opengl/xorg-x11/lib/libGL.so.1[0xb7dc3e0c]
-//usr//lib/opengl/xorg-x11/lib/libGL.so.1[0xb7d9ec75]
-/usr/lib/libSDL-1.2.so.0[0xb7f488d2]
-/usr/lib/libSDL-1.2.so.0[0xb7f4cb67]
-/usr/lib/libSDL-1.2.so.0[0xb7f4cda7]
-/usr/lib/libSDL-1.2.so.0(SDL_VideoQuit+0x4e)[0xb7f3af6e]
-/usr/lib/libSDL-1.2.so.0(SDL_QuitSubSystem+0x5b)[0xb7f0e5cb]
-/usr/lib/libSDL-1.2.so.0(SDL_Quit+0x1e)[0xb7f0e66e]
-./apple2[0x806b3e5]
-./apple2[0x806be81]
-/lib/libc.so.6(__libc_start_main+0xe1)[0xb7c3da51]
-./apple2[0x804a541]
-#endif
-// WriteLog("Video: Shutting down SDL subsystems...\n");
-// SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_EVENTTHREAD);
WriteLog("Video: Shutting down SDL...\n");
SDL_Quit();
WriteLog("Video: Done.\n");
}
+
//
// 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);
- }
+ SDL_UpdateTexture(sdlTexture, NULL, scrBuffer, VIRTUAL_SCREEN_WIDTH * sizeof(Uint32));
+ SDL_RenderClear(sdlRenderer);
+ SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL);
+ SDL_RenderPresent(sdlRenderer);
}
-// Is this even necessary? (Could call SDL_Flip directly...)
-void FlipMainScreen(void)
-{
-#ifdef TEST_ALPHA_BLENDING
-SDL_Rect dstRect = { 100, 100, 30, 30 };
-SDL_BlitSurface(someAlphaSurface, NULL, mainSurface, &dstRect);
-#endif
- if (settings.useOpenGL)
- sdlemu_draw_texture(mainSurface, surface, 1/*1=GL_QUADS*/);
- else
- 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)
+void ToggleFullScreen(void)
{
settings.fullscreen = !settings.fullscreen;
- mainSurfaceFlags &= ~SDL_FULLSCREEN;
- if (settings.fullscreen)
- mainSurfaceFlags |= SDL_FULLSCREEN;
+ int retVal = SDL_SetWindowFullscreen(sdlWindow, (settings.fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0));
+ SDL_ShowCursor(settings.fullscreen ? 0 : 1);
- 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");
+ if (retVal != 0)
+ WriteLog("Video::ToggleFullScreen: SDL error = %s\n", SDL_GetError());
}
-//*/
+