Convert low-level rendering to SDL

This commit is contained in:
Alexander Batalov 2022-05-19 14:01:17 +03:00
parent b8a0d0d413
commit 8565a55540
3 changed files with 112 additions and 107 deletions

View File

@ -1,5 +1,6 @@
#include "core.h" #include "core.h"
#include "config.h"
#include "color.h" #include "color.h"
#include "dinput.h" #include "dinput.h"
#include "draw.h" #include "draw.h"
@ -9,6 +10,9 @@
#include "window_manager.h" #include "window_manager.h"
#include "window_manager_private.h" #include "window_manager_private.h"
#include <SDL.h>
#include <SDL_syswm.h>
// NOT USED. // NOT USED.
void (*_idle_func)() = NULL; void (*_idle_func)() = NULL;
@ -365,6 +369,10 @@ int gKeyboardLayout;
// 0x6AD93C // 0x6AD93C
unsigned char gPressedPhysicalKeysCount; unsigned char gPressedPhysicalKeysCount;
SDL_Window* gSdlWindow = NULL;
SDL_Surface* gSdlWindowSurface = NULL;
SDL_Surface* gSdlSurface = NULL;
// 0x4C8A70 // 0x4C8A70
int coreInit(int a1) int coreInit(int a1)
{ {
@ -2020,7 +2028,30 @@ void _zero_vid_mem()
// 0x4CAE1C // 0x4CAE1C
int _GNW95_init_mode_ex(int width, int height, int bpp) int _GNW95_init_mode_ex(int width, int height, int bpp)
{ {
if (_GNW95_init_window() == -1) { bool fullscreen = true;
Config resolutionConfig;
if (configInit(&resolutionConfig)) {
if (configRead(&resolutionConfig, "f2_res.ini", false)) {
int screenWidth;
if (configGetInt(&resolutionConfig, "MAIN", "SCR_WIDTH", &screenWidth)) {
width = screenWidth;
}
int screenHeight;
if (configGetInt(&resolutionConfig, "MAIN", "SCR_HEIGHT", &screenHeight)) {
height = screenHeight;
}
bool windowed;
if (configGetBool(&resolutionConfig, "MAIN", "WINDOWED", &windowed)) {
fullscreen = !windowed;
}
}
configFree(&resolutionConfig);
}
if (_GNW95_init_window(width, height, fullscreen) == -1) {
return -1; return -1;
} }
@ -2057,17 +2088,36 @@ int _init_vesa_mode(int width, int height)
} }
// 0x4CAEDC // 0x4CAEDC
int _GNW95_init_window() int _GNW95_init_window(int width, int height, bool fullscreen)
{ {
if (gProgramWindow == NULL) { if (gProgramWindow == NULL) {
int width = GetSystemMetrics(SM_CXSCREEN); if (SDL_Init(SDL_INIT_VIDEO) != 0) {
int height = GetSystemMetrics(SM_CYSCREEN);
gProgramWindow = CreateWindowExA(WS_EX_TOPMOST, "GNW95 Class", gProgramWindowTitle, WS_POPUP | WS_VISIBLE | WS_SYSMENU, 0, 0, width, height, NULL, NULL, gInstance, NULL);
if (gProgramWindow == NULL) {
return -1; return -1;
} }
gSdlWindow = SDL_CreateWindow(gProgramWindowTitle, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
if (gSdlWindow == NULL) {
return -1;
}
gSdlWindowSurface = SDL_GetWindowSurface(gSdlWindow);
if (gSdlWindowSurface == NULL) {
SDL_DestroyWindow(gSdlWindow);
gSdlWindow = NULL;
return -1;
}
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
if (!SDL_GetWindowWMInfo(gSdlWindow, &info)) {
SDL_DestroyWindow(gSdlWindow);
gSdlWindow = NULL;
return -1;
}
gProgramWindow = info.info.win.window;
UpdateWindow(gProgramWindow); UpdateWindow(gProgramWindow);
SetFocus(gProgramWindow); SetFocus(gProgramWindow);
} }
@ -2111,7 +2161,7 @@ int getShiftForBitMask(int mask)
// 0x4CAF9C // 0x4CAF9C
int directDrawInit(int width, int height, int bpp) int directDrawInit(int width, int height, int bpp)
{ {
if (gDirectDraw != NULL) { if (gSdlSurface != NULL) {
unsigned char* palette = directDrawGetPalette(); unsigned char* palette = directDrawGetPalette();
directDrawFree(); directDrawFree();
@ -2124,47 +2174,18 @@ int directDrawInit(int width, int height, int bpp)
return 0; return 0;
} }
if (gDirectDrawCreateProc(NULL, &gDirectDraw, NULL) != DD_OK) { gSdlSurface = SDL_CreateRGBSurface(0, width, height, bpp, 0, 0, 0, 0);
return -1;
}
if (IDirectDraw_SetCooperativeLevel(gDirectDraw, gProgramWindow, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN) != DD_OK) {
return -1;
}
if (IDirectDraw_SetDisplayMode(gDirectDraw, width, height, bpp) != DD_OK) {
return -1;
}
DDSURFACEDESC ddsd;
memset(&ddsd, 0, sizeof(DDSURFACEDESC));
ddsd.dwSize = sizeof(DDSURFACEDESC);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
if (IDirectDraw_CreateSurface(gDirectDraw, &ddsd, &gDirectDrawSurface1, NULL) != DD_OK) {
return -1;
}
gDirectDrawSurface2 = gDirectDrawSurface1;
if (bpp == 8) { if (bpp == 8) {
PALETTEENTRY pe[256]; SDL_Color colors[256];
for (int index = 0; index < 256; index++) { for (int index = 0; index < 256; index++) {
pe[index].peRed = index; colors[index].r = index;
pe[index].peGreen = index; colors[index].g = index;
pe[index].peBlue = index; colors[index].b = index;
pe[index].peFlags = 0; colors[index].a = 255;
} }
if (IDirectDraw_CreatePalette(gDirectDraw, DDPCAPS_8BIT | DDPCAPS_ALLOW256, pe, &gDirectDrawPalette, NULL) != DD_OK) { SDL_SetPaletteColors(gSdlSurface->format->palette, colors, 0, 256);
return -1;
}
if (IDirectDrawSurface_SetPalette(gDirectDrawSurface1, gDirectDrawPalette) != DD_OK) {
return -1;
}
return 0; return 0;
} else { } else {
@ -2190,41 +2211,30 @@ int directDrawInit(int width, int height, int bpp)
// 0x4CB1B0 // 0x4CB1B0
void directDrawFree() void directDrawFree()
{ {
if (gDirectDraw != NULL) { if (gSdlSurface != NULL) {
IDirectDraw_RestoreDisplayMode(gDirectDraw); SDL_FreeSurface(gSdlSurface);
gSdlSurface = NULL;
if (gDirectDrawSurface1 != NULL) {
IDirectDrawSurface_Release(gDirectDrawSurface1);
gDirectDrawSurface1 = NULL;
gDirectDrawSurface2 = NULL;
}
if (gDirectDrawPalette != NULL) {
IDirectDrawPalette_Release(gDirectDrawPalette);
gDirectDrawPalette = NULL;
}
IDirectDraw_Release(gDirectDraw);
gDirectDraw = NULL;
} }
} }
// 0x4CB310 // 0x4CB310
void directDrawSetPaletteInRange(unsigned char* palette, int start, int count) void directDrawSetPaletteInRange(unsigned char* palette, int start, int count)
{ {
if (gDirectDrawPalette != NULL) { if (gSdlSurface != NULL && gSdlSurface->format->palette != NULL) {
PALETTEENTRY entries[256]; SDL_Color colors[256];
if (count != 0) { if (count != 0) {
for (int index = 0; index < count; index++) { for (int index = 0; index < count; index++) {
entries[index].peRed = palette[index * 3] << 2; colors[index].r = palette[index * 3] << 2;
entries[index].peGreen = palette[index * 3 + 1] << 2; colors[index].g = palette[index * 3 + 1] << 2;
entries[index].peBlue = palette[index * 3 + 2] << 2; colors[index].b = palette[index * 3 + 2] << 2;
entries[index].peFlags = PC_NOCOLLAPSE; colors[index].a = 255;
} }
} }
IDirectDrawPalette_SetEntries(gDirectDrawPalette, 0, start, count, entries); SDL_SetPaletteColors(gSdlSurface->format->palette, colors, start, count);
SDL_BlitSurface(gSdlSurface, NULL, gSdlWindowSurface, NULL);
SDL_UpdateWindowSurface(gSdlWindow);
} else { } else {
for (int index = start; index < start + count; index++) { for (int index = start; index < start + count; index++) {
unsigned short r = palette[0] << 2; unsigned short r = palette[0] << 2;
@ -2256,17 +2266,19 @@ void directDrawSetPaletteInRange(unsigned char* palette, int start, int count)
// 0x4CB568 // 0x4CB568
void directDrawSetPalette(unsigned char* palette) void directDrawSetPalette(unsigned char* palette)
{ {
if (gDirectDrawPalette != NULL) { if (gSdlSurface != NULL && gSdlSurface->format->palette != NULL) {
PALETTEENTRY entries[256]; SDL_Color colors[256];
for (int index = 0; index < 256; index++) { for (int index = 0; index < 256; index++) {
entries[index].peRed = palette[index * 3] << 2; colors[index].r = palette[index * 3] << 2;
entries[index].peGreen = palette[index * 3 + 1] << 2; colors[index].g = palette[index * 3 + 1] << 2;
entries[index].peBlue = palette[index * 3 + 2] << 2; colors[index].b = palette[index * 3 + 2] << 2;
entries[index].peFlags = PC_NOCOLLAPSE; colors[index].a = 255;
} }
IDirectDrawPalette_SetEntries(gDirectDrawPalette, 0, 0, 256, entries); SDL_SetPaletteColors(gSdlSurface->format->palette, colors, 0, 256);
SDL_BlitSurface(gSdlSurface, NULL, gSdlWindowSurface, NULL);
SDL_UpdateWindowSurface(gSdlWindow);
} else { } else {
for (int index = 0; index < 256; index++) { for (int index = 0; index < 256; index++) {
unsigned short r = palette[index * 3] << 2; unsigned short r = palette[index * 3] << 2;
@ -2289,6 +2301,7 @@ void directDrawSetPalette(unsigned char* palette)
windowRefreshAll(&_scr_size); windowRefreshAll(&_scr_size);
} }
if (_update_palette_func != NULL) { if (_update_palette_func != NULL) {
_update_palette_func(); _update_palette_func();
} }
@ -2297,17 +2310,14 @@ void directDrawSetPalette(unsigned char* palette)
// 0x4CB68C // 0x4CB68C
unsigned char* directDrawGetPalette() unsigned char* directDrawGetPalette()
{ {
if (gDirectDrawPalette != NULL) { if (gSdlSurface != NULL && gSdlSurface->format->palette != NULL) {
PALETTEENTRY paletteEntries[256]; SDL_Color* colors = gSdlSurface->format->palette->colors;
if (IDirectDrawPalette_GetEntries(gDirectDrawPalette, 0, 0, 256, paletteEntries) != DD_OK) {
return NULL;
}
for (int index = 0; index < 256; index++) { for (int index = 0; index < 256; index++) {
PALETTEENTRY* paletteEntry = &(paletteEntries[index]); SDL_Color* color = &(colors[index]);
gLastVideoModePalette[index * 3] = paletteEntry->peRed >> 2; gLastVideoModePalette[index * 3] = color->r >> 2;
gLastVideoModePalette[index * 3 + 1] = paletteEntry->peGreen >> 2; gLastVideoModePalette[index * 3 + 1] = color->g >> 2;
gLastVideoModePalette[index * 3 + 2] = paletteEntry->peBlue >> 2; gLastVideoModePalette[index * 3 + 2] = color->b >> 2;
} }
return gLastVideoModePalette; return gLastVideoModePalette;
@ -2335,31 +2345,21 @@ unsigned char* directDrawGetPalette()
// 0x4CB850 // 0x4CB850
void _GNW95_ShowRect(unsigned char* src, int srcPitch, int a3, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY) void _GNW95_ShowRect(unsigned char* src, int srcPitch, int a3, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY)
{ {
DDSURFACEDESC ddsd; SDL_LockSurface(gSdlSurface);
HRESULT hr; blitBufferToBuffer(src + srcPitch * srcY + srcX, srcWidth, srcHeight, srcPitch, (unsigned char*)gSdlSurface->pixels + gSdlSurface->pitch * destY + destX, gSdlSurface->pitch);
SDL_UnlockSurface(gSdlSurface);
if (!gProgramIsActive) { SDL_Rect srcRect;
return; srcRect.x = destX;
} srcRect.y = destY;
srcRect.w = srcWidth;
srcRect.h = srcHeight;
while (1) { SDL_Rect destRect;
ddsd.dwSize = sizeof(DDSURFACEDESC); destRect.x = destX;
destRect.y = destY;
hr = IDirectDrawSurface_Lock(gDirectDrawSurface1, NULL, &ddsd, 1, NULL); SDL_BlitSurface(gSdlSurface, &srcRect, gSdlWindowSurface, &destRect);
if (hr == DD_OK) { SDL_UpdateWindowSurface(gSdlWindow);
break;
}
if (hr == DDERR_SURFACELOST) {
if (IDirectDrawSurface_Restore(gDirectDrawSurface2) != DD_OK) {
return;
}
}
}
blitBufferToBuffer(src + srcPitch * srcY + srcX, srcWidth, srcHeight, srcPitch, (unsigned char*)ddsd.lpSurface + ddsd.lPitch * destY + destX, ddsd.lPitch);
IDirectDrawSurface_Unlock(gDirectDrawSurface1, ddsd.lpSurface);
} }
// 0x4CB93C // 0x4CB93C

View File

@ -594,7 +594,7 @@ void _get_start_mode_();
void _zero_vid_mem(); void _zero_vid_mem();
int _GNW95_init_mode_ex(int width, int height, int bpp); int _GNW95_init_mode_ex(int width, int height, int bpp);
int _init_vesa_mode(int width, int height); int _init_vesa_mode(int width, int height);
int _GNW95_init_window(); int _GNW95_init_window(int width, int height, bool fullscreen);
int getShiftForBitMask(int mask); int getShiftForBitMask(int mask);
int directDrawInit(int width, int height, int bpp); int directDrawInit(int width, int height, int bpp);
void directDrawFree(); void directDrawFree();

View File

@ -129,6 +129,11 @@ int gameMoviesSave(File* stream)
// 0x44E690 // 0x44E690
int gameMoviePlay(int movie, int flags) int gameMoviePlay(int movie, int flags)
{ {
// TODO: SDL
paletteSetEntries(gPaletteBlack);
gGameMoviesSeen[movie] = 1;
return 0;
gGameMovieIsPlaying = true; gGameMovieIsPlaying = true;
const char* movieFileName = gMovieFileNames[movie]; const char* movieFileName = gMovieFileNames[movie];