Reorganize svga (#109)

This commit is contained in:
Alexander Batalov 2023-10-05 08:13:48 +03:00 committed by GitHub
parent 271601221e
commit c138d7fb9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 148 additions and 354 deletions

View File

@ -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) {

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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:

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -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_ */