diff --git a/src/game/game.cc b/src/game/game.cc index 9ceff8b..c01b514 100644 --- a/src/game/game.cc +++ b/src/game/game.cc @@ -124,7 +124,7 @@ DB_DATABASE* master_db_handle; DB_DATABASE* critter_db_handle; // 0x43B080 -int game_init(const char* windowTitle, bool isMapper, int font, int a4, int argc, char** argv) +int game_init(const char* windowTitle, bool isMapper, int font, int flags, int argc, char** argv) { char path[COMPAT_MAX_PATH]; @@ -142,7 +142,42 @@ int game_init(const char* windowTitle, bool isMapper, int font, int a4, int argc } win_set_minimized_title(windowTitle); - initWindow(1, a4); + + VideoOptions video_options; + video_options.width = 640; + video_options.height = 480; + video_options.fullscreen = true; + video_options.scale = 1; + + Config resolutionConfig; + if (config_init(&resolutionConfig)) { + if (config_load(&resolutionConfig, "f1_res.ini", false)) { + int screenWidth; + if (config_get_value(&resolutionConfig, "MAIN", "SCR_WIDTH", &screenWidth)) { + video_options.width = std::max(screenWidth, 640); + } + + int screenHeight; + if (config_get_value(&resolutionConfig, "MAIN", "SCR_HEIGHT", &screenHeight)) { + video_options.height = std::max(screenHeight, 480); + } + + bool windowed; + if (configGetBool(&resolutionConfig, "MAIN", "WINDOWED", &windowed)) { + video_options.fullscreen = !windowed; + } + + int scaleValue; + if (config_get_value(&resolutionConfig, "MAIN", "SCALE_2X", &scaleValue)) { + video_options.scale = scaleValue + 1; + video_options.width /= video_options.scale; + video_options.height /= video_options.scale; + } + } + config_exit(&resolutionConfig); + } + + initWindow(&video_options, flags); palette_init(); if (!game_in_mapper) { diff --git a/src/game/game.h b/src/game/game.h index 9f33893..40a47c6 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -25,7 +25,7 @@ extern MessageList misc_message_file; extern DB_DATABASE* master_db_handle; extern DB_DATABASE* critter_db_handle; -int game_init(const char* windowTitle, bool isMapper, int a3, int a4, int argc, char** argv); +int game_init(const char* windowTitle, bool isMapper, int font, int flags, int argc, char** argv); void game_reset(); void game_exit(); int game_handle_input(int eventCode, bool isInCombatMode); diff --git a/src/game/main.cc b/src/game/main.cc index ab3d351..4f8efc1 100644 --- a/src/game/main.cc +++ b/src/game/main.cc @@ -250,6 +250,9 @@ static void main_exit_system() main_selfrun_exit(); game_exit(); + + // TODO: Find a better place for this call. + SDL_Quit(); } // 0x472958 diff --git a/src/game/map.cc b/src/game/map.cc index 4eaf457..737c258 100644 --- a/src/game/map.cc +++ b/src/game/map.cc @@ -279,7 +279,7 @@ int iso_init() // NOTE: Uninline. square_init(); - display_win = win_add(0, 0, screenGetWidth(), screenGetVisibleHeight(), 256, 10); + display_win = win_add(0, 0, screenGetWidth(), screenGetHeight() - INTERFACE_BAR_HEIGHT, 256, 10); if (display_win == -1) { debug_printf("win_add failed in iso_init\n"); return -1; diff --git a/src/int/window.cc b/src/int/window.cc index 07d59db..fede3b8 100644 --- a/src/int/window.cc +++ b/src/int/window.cc @@ -105,54 +105,6 @@ static int winTOS = -1; // 0x508698 static int currentWindow = -1; -// 0x50869C -static VideoSystemInitProc* gfx_init[12] = { - init_mode_320_200, - init_mode_640_480, - init_mode_640_480_16, - init_mode_320_400, - init_mode_640_480_16, - init_mode_640_400, - init_mode_640_480_16, - init_mode_800_600, - init_mode_640_480_16, - init_mode_1024_768, - init_mode_640_480_16, - init_mode_1280_1024, -}; - -// 0x5086CC -static int fontnum[12] = { - 3, - 0, - 0, - 3, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, -}; - -// 0x5086FC -static Size sizes[12] = { - { 320, 200 }, - { 640, 480 }, - { 640, 240 }, - { 320, 400 }, - { 640, 200 }, - { 640, 400 }, - { 800, 300 }, - { 800, 600 }, - { 1024, 384 }, - { 1024, 768 }, - { 1280, 512 }, - { 1280, 1024 }, -}; - // 0x50875C static int numInputFunc = 0; @@ -1575,7 +1527,7 @@ static void windowRemoveProgramReferences(Program* program) } // 0x4A5C9C -void initWindow(int resolution, int a2) +void initWindow(VideoOptions* video_options, int flags) { char err[COMPAT_MAX_PATH]; int rc; @@ -1588,17 +1540,18 @@ void initWindow(int resolution, int a2) currentTextColorB = 0; currentHighlightColorR = 0; currentHighlightColorG = 0; + currentHighlightColorB = 0; currentTextFlags = 0x2010000; - yres = sizes[resolution].height; // screen height - currentHighlightColorB = 0; - xres = sizes[resolution].width; // screen width + // TODO: Review usage. + yres = 640; + xres = 480; for (int i = 0; i < MANAGED_WINDOW_COUNT; i++) { windows[i].window = -1; } - rc = win_init(gfx_init[resolution], GNW95_reset_mode, a2); + rc = win_init(video_options, flags); if (rc != WINDOW_MANAGER_OK) { switch (rc) { case WINDOW_MANAGER_ERR_INITIALIZING_VIDEO_MODE: diff --git a/src/int/window.h b/src/int/window.h index 9d22d27..5f8b415 100644 --- a/src/int/window.h +++ b/src/int/window.h @@ -6,6 +6,7 @@ #include "int/widget.h" #include "plib/gnw/gnw.h" #include "plib/gnw/rect.h" +#include "plib/gnw/svga_types.h" namespace fallout { @@ -86,7 +87,7 @@ int windowDisplayTransBuf(unsigned char* src, int srcWidth, int srcHeight, int d int windowDisplayBufScaled(unsigned char* src, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight); int windowGetXres(); int windowGetYres(); -void initWindow(int resolution, int a2); +void initWindow(VideoOptions* video_options, int flags); void windowSetWindowFuncs(ManagedWindowCreateCallback* createCallback, ManagedWindowSelectFunc* selectCallback, WindowDeleteCallback* deleteCallback, DisplayInWindowCallback* displayCallback); void windowClose(); bool windowDeleteButton(const char* buttonName); diff --git a/src/plib/gnw/gnw.cc b/src/plib/gnw/gnw.cc index ab74e31..ff7cdb9 100644 --- a/src/plib/gnw/gnw.cc +++ b/src/plib/gnw/gnw.cc @@ -57,9 +57,6 @@ static int window_index[MAX_WINDOW_COUNT]; // 0x6AC1E8 static Window* window[MAX_WINDOW_COUNT]; -// 0x6AC2B0 -static VideoSystemExitProc* video_reset; - // 0x6AC2B4 static int num_windows; @@ -72,9 +69,6 @@ static bool buffering; // 0x6AC2C0 static int bk_color; -// 0x6AC2C4 -static VideoSystemInitProc* video_set; - // 0x6AC2C8 static int doing_refresh_all; @@ -82,7 +76,7 @@ static int doing_refresh_all; void* GNW_texture; // 0x4C1CF0 -int win_init(VideoSystemInitProc* videoSystemInitProc, VideoSystemExitProc* videoSystemExitProc, int flags) +int win_init(VideoOptions* video_options, int flags) { #ifdef _WIN32 CloseHandle(GNW95_mutex); @@ -117,32 +111,16 @@ int win_init(VideoSystemInitProc* videoSystemInitProc, VideoSystemExitProc* vide return WINDOW_MANAGER_ERR_INITIALIZING_TEXT_FONTS; } - reset_mode(); - - video_set = videoSystemInitProc; - video_reset = GNW95_reset_mode; - - int rc = videoSystemInitProc(); - if (rc == -1) { - if (video_reset != NULL) { - video_reset(); - } + if (!svga_init(video_options)) { + svga_exit(); return WINDOW_MANAGER_ERR_INITIALIZING_VIDEO_MODE; } - if (rc == 8) { - return WINDOW_MANAGER_ERR_8; - } - if ((flags & 1) != 0) { screen_buffer = (unsigned char*)mem_malloc((scr_size.lry - scr_size.uly + 1) * (scr_size.lrx - scr_size.ulx + 1)); if (screen_buffer == NULL) { - if (video_reset != NULL) { - video_reset(); - } else { - GNW95_reset_mode(); - } + svga_exit(); return WINDOW_MANAGER_ERR_NO_MEMORY; } @@ -157,11 +135,7 @@ int win_init(VideoSystemInitProc* videoSystemInitProc, VideoSystemExitProc* vide if (!initColors()) { unsigned char* palette = (unsigned char*)mem_malloc(768); if (palette == NULL) { - if (video_reset != NULL) { - video_reset(); - } else { - GNW95_reset_mode(); - } + svga_exit(); if (screen_buffer != NULL) { mem_free(screen_buffer); @@ -188,11 +162,7 @@ int win_init(VideoSystemInitProc* videoSystemInitProc, VideoSystemExitProc* vide Window* w = window[0] = (Window*)mem_malloc(sizeof(*w)); if (w == NULL) { - if (video_reset != NULL) { - video_reset(); - } else { - GNW95_reset_mode(); - } + svga_exit(); if (screen_buffer != NULL) { mem_free(screen_buffer); @@ -260,9 +230,7 @@ void win_exit(void) mem_free(screen_buffer); } - if (video_reset != NULL) { - video_reset(); - } + svga_exit(); GNW_input_exit(); GNW_rect_exit(); diff --git a/src/plib/gnw/gnw.h b/src/plib/gnw/gnw.h index 64b8278..86166b0 100644 --- a/src/plib/gnw/gnw.h +++ b/src/plib/gnw/gnw.h @@ -5,6 +5,7 @@ #include "plib/gnw/gnw_types.h" #include "plib/gnw/rect.h" +#include "plib/gnw/svga_types.h" namespace fallout { @@ -29,15 +30,12 @@ typedef enum WindowManagerErr { WINDOW_MANAGER_ERR_INITIALIZING_INPUT = 11, } WindowManagerErr; -typedef int(VideoSystemInitProc)(); -typedef void(VideoSystemExitProc)(); - extern bool GNW_win_init_flag; extern int GNW_wcolor[6]; extern void* GNW_texture; -int win_init(VideoSystemInitProc* videoSystemInitProc, VideoSystemExitProc* videoSystemExitProc, int a3); +int win_init(VideoOptions* video_options, int flags); int win_active(); void win_exit(void); int win_add(int x, int y, int width, int height, int color, int flags); diff --git a/src/plib/gnw/svga.cc b/src/plib/gnw/svga.cc index af29efd..98f8b00 100644 --- a/src/plib/gnw/svga.cc +++ b/src/plib/gnw/svga.cc @@ -1,7 +1,5 @@ #include "plib/gnw/svga.h" -#include "game/config.h" -#include "game/intface.h" #include "plib/gnw/gnw.h" #include "plib/gnw/grbuf.h" #include "plib/gnw/mouse.h" @@ -9,9 +7,6 @@ namespace fallout { -static int GNW95_init_mode_ex(int width, int height, int bpp); -static int GNW95_init_mode(int width, int height); - static bool createRenderer(int width, int height); static void destroyRenderer(); @@ -30,214 +25,6 @@ SDL_Surface* gSdlTextureSurface = NULL; // TODO: Remove once migration to update-render cycle is completed. FpsLimiter sharedFpsLimiter; -// 0x4CAD08 -int init_mode_320_200() -{ - return GNW95_init_mode_ex(320, 200, 8); -} - -// 0x4CAD40 -int init_mode_320_400() -{ - return GNW95_init_mode_ex(320, 400, 8); -} - -// 0x4CAD5C -int init_mode_640_480_16() -{ - return -1; -} - -// 0x4CAD64 -int init_mode_640_480() -{ - return GNW95_init_mode(640, 480); -} - -// 0x4CAD94 -int init_mode_640_400() -{ - return GNW95_init_mode(640, 400); -} - -// 0x4CADA8 -int init_mode_800_600() -{ - return GNW95_init_mode(800, 600); -} - -// 0x4CADBC -int init_mode_1024_768() -{ - return GNW95_init_mode(1024, 768); -} - -// 0x4CADD0 -int init_mode_1280_1024() -{ - return GNW95_init_mode(1280, 1024); -} - -// 0x4CADE4 -int init_vesa_mode(int mode, int width, int height, int half) -{ - if (half != 0) { - return -1; - } - - return GNW95_init_mode_ex(width, height, 8); -} - -// 0x4CADF3 -int get_start_mode() -{ - return -1; -} - -// 0x4CADF8 -void reset_mode() -{ -} - -// 0x4CAE1C -static int GNW95_init_mode_ex(int width, int height, int bpp) -{ - bool fullscreen = true; - int scale = 1; - - Config resolutionConfig; - if (config_init(&resolutionConfig)) { - if (config_load(&resolutionConfig, "f1_res.ini", false)) { - int screenWidth; - if (config_get_value(&resolutionConfig, "MAIN", "SCR_WIDTH", &screenWidth)) { - width = screenWidth; - } - - int screenHeight; - if (config_get_value(&resolutionConfig, "MAIN", "SCR_HEIGHT", &screenHeight)) { - height = screenHeight; - } - - bool windowed; - if (configGetBool(&resolutionConfig, "MAIN", "WINDOWED", &windowed)) { - fullscreen = !windowed; - } - - int scaleValue; - if (config_get_value(&resolutionConfig, "MAIN", "SCALE_2X", &scaleValue)) { - scale = scaleValue + 1; // 0 = 1x, 1 = 2x - // Only allow scaling if resulting game resolution is >= 640x480 - if ((width / scale) < 640 || (height / scale) < 480) { - scale = 1; - } else { - width /= scale; - height /= scale; - } - } - } - config_exit(&resolutionConfig); - } - - if (GNW95_init_window(width, height, fullscreen, scale) == -1) { - return -1; - } - - if (GNW95_init_DirectDraw(width, height, bpp) == -1) { - return -1; - } - - scr_size.ulx = 0; - scr_size.uly = 0; - scr_size.lrx = width - 1; - scr_size.lry = height - 1; - - mouse_blit_trans = NULL; - scr_blit = GNW95_ShowRect; - mouse_blit = GNW95_ShowRect; - - return 0; -} - -// 0x4CAECC -static int GNW95_init_mode(int width, int height) -{ - return GNW95_init_mode_ex(width, height, 8); -} - -// 0x4CAEDC -int GNW95_init_window(int width, int height, bool fullscreen, int scale) -{ - if (gSdlWindow == NULL) { - SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl"); - - if (SDL_Init(SDL_INIT_VIDEO) != 0) { - return -1; - } - - Uint32 windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI; - - if (fullscreen) { - windowFlags |= SDL_WINDOW_FULLSCREEN; - } - - gSdlWindow = SDL_CreateWindow(GNW95_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width * scale, height * scale, windowFlags); - if (gSdlWindow == NULL) { - return -1; - } - - if (!createRenderer(width, height)) { - destroyRenderer(); - - SDL_DestroyWindow(gSdlWindow); - gSdlWindow = NULL; - - return -1; - } - } - - return 0; -} - -// 0x4CAF9C -int GNW95_init_DirectDraw(int width, int height, int bpp) -{ - if (gSdlSurface != NULL) { - unsigned char* palette = GNW95_GetPalette(); - GNW95_reset_mode(); - - if (GNW95_init_DirectDraw(width, height, bpp) == -1) { - return -1; - } - - GNW95_SetPalette(palette); - - return 0; - } - - gSdlSurface = SDL_CreateRGBSurface(0, width, height, bpp, 0, 0, 0, 0); - - SDL_Color colors[256]; - for (int index = 0; index < 256; index++) { - colors[index].r = index; - colors[index].g = index; - colors[index].b = index; - colors[index].a = 255; - } - - SDL_SetPaletteColors(gSdlSurface->format->palette, colors, 0, 256); - - return 0; -} - -// 0x4CB1B0 -void GNW95_reset_mode() -{ - if (gSdlSurface != NULL) { - SDL_FreeSurface(gSdlSurface); - gSdlSurface = NULL; - } -} - // 0x4CB310 void GNW95_SetPaletteEntries(unsigned char* palette, int start, int count) { @@ -276,25 +63,6 @@ void GNW95_SetPalette(unsigned char* palette) } } -// 0x4CB68C -unsigned char* GNW95_GetPalette() -{ - static unsigned char palette[768]; - - if (gSdlSurface != NULL && gSdlSurface->format->palette != NULL) { - SDL_Color* colors = gSdlSurface->format->palette->colors; - - for (int index = 0; index < 256; index++) { - SDL_Color* color = &(colors[index]); - palette[index * 3] = color->r >> 2; - palette[index * 3 + 1] = color->g >> 2; - palette[index * 3 + 2] = color->b >> 2; - } - } - - return palette; -} - // 0x4CB850 void GNW95_ShowRect(unsigned char* src, unsigned int srcPitch, unsigned int a3, unsigned int srcX, unsigned int srcY, unsigned int srcWidth, unsigned int srcHeight, unsigned int destX, unsigned int destY) { @@ -312,6 +80,86 @@ void GNW95_ShowRect(unsigned char* src, unsigned int srcPitch, unsigned int a3, SDL_BlitSurface(gSdlSurface, &srcRect, gSdlTextureSurface, &destRect); } +bool svga_init(VideoOptions* video_options) +{ + SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl"); + + if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) { + return false; + } + + Uint32 windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI; + + if (video_options->fullscreen) { + windowFlags |= SDL_WINDOW_FULLSCREEN; + } + + gSdlWindow = SDL_CreateWindow(GNW95_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + video_options->width * video_options->scale, + video_options->height * video_options->scale, + windowFlags); + if (gSdlWindow == NULL) { + return false; + } + + if (!createRenderer(video_options->width, video_options->height)) { + destroyRenderer(); + + SDL_DestroyWindow(gSdlWindow); + gSdlWindow = NULL; + + return false; + } + + gSdlSurface = SDL_CreateRGBSurface(0, + video_options->width, + video_options->height, + 8, + 0, + 0, + 0, + 0); + if (gSdlSurface == NULL) { + destroyRenderer(); + + SDL_DestroyWindow(gSdlWindow); + gSdlWindow = NULL; + } + + SDL_Color colors[256]; + for (int index = 0; index < 256; index++) { + colors[index].r = index; + colors[index].g = index; + colors[index].b = index; + colors[index].a = 255; + } + + SDL_SetPaletteColors(gSdlSurface->format->palette, colors, 0, 256); + + scr_size.ulx = 0; + scr_size.uly = 0; + scr_size.lrx = video_options->width - 1; + scr_size.lry = video_options->height - 1; + + mouse_blit_trans = NULL; + scr_blit = GNW95_ShowRect; + mouse_blit = GNW95_ShowRect; + + return true; +} + +void svga_exit() +{ + destroyRenderer(); + + if (gSdlWindow != NULL) { + SDL_DestroyWindow(gSdlWindow); + gSdlWindow = NULL; + } + + SDL_QuitSubSystem(SDL_INIT_VIDEO); +} + int screenGetWidth() { // TODO: Make it on par with _xres; @@ -324,11 +172,6 @@ int screenGetHeight() return rectGetHeight(&scr_size); } -int screenGetVisibleHeight() -{ - return screenGetHeight() - INTERFACE_BAR_HEIGHT; -} - static bool createRenderer(int width, int height) { gSdlRenderer = SDL_CreateRenderer(gSdlWindow, -1, 0); diff --git a/src/plib/gnw/svga.h b/src/plib/gnw/svga.h index 5426562..61d51f2 100644 --- a/src/plib/gnw/svga.h +++ b/src/plib/gnw/svga.h @@ -19,28 +19,14 @@ extern SDL_Texture* gSdlTexture; extern SDL_Surface* gSdlTextureSurface; extern FpsLimiter sharedFpsLimiter; -int init_mode_320_200(); -int init_mode_320_400(); -int init_mode_640_480_16(); -int init_mode_640_480(); -int init_mode_640_400(); -int init_mode_800_600(); -int init_mode_1024_768(); -int init_mode_1280_1024(); -int init_vesa_mode(int mode, int width, int height, int half); -int get_start_mode(); -void reset_mode(); -int GNW95_init_window(int width, int height, bool fullscreen, int scale); -int GNW95_init_DirectDraw(int width, int height, int bpp); -void GNW95_reset_mode(); void GNW95_SetPaletteEntries(unsigned char* a1, int a2, int a3); void GNW95_SetPalette(unsigned char* palette); -unsigned char* GNW95_GetPalette(); void GNW95_ShowRect(unsigned char* src, unsigned int src_pitch, unsigned int a3, unsigned int src_x, unsigned int src_y, unsigned int src_width, unsigned int src_height, unsigned int dest_x, unsigned int dest_y); +bool svga_init(VideoOptions* video_options); +void svga_exit(); int screenGetWidth(); int screenGetHeight(); -int screenGetVisibleHeight(); void handleWindowSizeChanged(); void renderPresent(); diff --git a/src/plib/gnw/svga_types.h b/src/plib/gnw/svga_types.h index ce46c14..4b3b62c 100644 --- a/src/plib/gnw/svga_types.h +++ b/src/plib/gnw/svga_types.h @@ -14,6 +14,13 @@ typedef int(SetModeFunc)(); typedef void(ScreenTransBlitFunc)(unsigned char* srcBuf, unsigned int srcW, unsigned int srcH, unsigned int subX, unsigned int subY, unsigned int subW, unsigned int subH, unsigned int dstX, unsigned int dstY, unsigned char trans); typedef void(ScreenBlitFunc)(unsigned char* srcBuf, unsigned int srcW, unsigned int srcH, unsigned int subX, unsigned int subY, unsigned int subW, unsigned int subH, unsigned int dstX, unsigned int dstY); +typedef struct VideoOptions { + int width; + int height; + bool fullscreen; + int scale; +} VideoOptions; + } // namespace fallout #endif /* FALLOUT_PLIB_GNW_SVGA_TYPES_H_ */