diff --git a/data/tr1/ship/shaders/2d.glsl b/data/tr1/ship/shaders/2d.glsl index adb3230ed..8c1006e09 100644 --- a/data/tr1/ship/shaders/2d.glsl +++ b/data/tr1/ship/shaders/2d.glsl @@ -18,21 +18,31 @@ void main(void) { // Fragment shader uniform sampler2D tex0; +uniform sampler1D pal0; +uniform bool paletteEnabled; #ifdef OGL33C #define OUTCOLOR outColor - #define TEXTURE texture + #define TEXTURE2D texture + #define TEXTURE1D texture in vec2 vertTexCoords; out vec4 outColor; #else #define OUTCOLOR gl_FragColor - #define TEXTURE texture2D + #define TEXTURE2D texture2D + #define TEXTURE1D texture1D varying vec2 vertTexCoords; #endif void main(void) { - OUTCOLOR = TEXTURE(tex0, vertTexCoords); + if (paletteEnabled) { + float paletteIndex = TEXTURE2D(tex0, vertTexCoords).r; + vec4 tmp = TEXTURE1D(pal0, paletteIndex); + OUTCOLOR = vec4(paletteIndex, tmp.g, tmp.b, 0); + } else { + OUTCOLOR = TEXTURE2D(tex0, vertTexCoords); + } } #endif // VERTEX diff --git a/data/tr2/ship/shaders/2d.glsl b/data/tr2/ship/shaders/2d.glsl new file mode 100644 index 000000000..e0a0bff6f --- /dev/null +++ b/data/tr2/ship/shaders/2d.glsl @@ -0,0 +1,47 @@ +#ifdef VERTEX +// Vertex shader + +#ifdef OGL33C + out vec2 vertTexCoords; +#else + varying vec2 vertTexCoords; +#endif + +layout(location = 0) in vec2 inPosition; + +void main(void) { + vertTexCoords = inPosition; + gl_Position = vec4(vertTexCoords * vec2(2.0, -2.0) + vec2(-1.0, 1.0), 0.0, 1.0); +} + +#else +// Fragment shader + +uniform sampler2D tex0; +uniform sampler1D pal0; +uniform bool paletteEnabled; + +#ifdef OGL33C + #define OUTCOLOR outColor + #define TEXTURE2D texture + #define TEXTURE1D texture + + in vec2 vertTexCoords; + out vec4 outColor; +#else + #define OUTCOLOR gl_FragColor + #define TEXTURE2D texture2D + #define TEXTURE1D texture1D + + varying vec2 vertTexCoords; +#endif + +void main(void) { + if (paletteEnabled) { + float paletteIndex = TEXTURE2D(tex0, vertTexCoords).r; + OUTCOLOR = TEXTURE1D(pal0, paletteIndex); + } else { + OUTCOLOR = TEXTURE2D(tex0, vertTexCoords); + } +} +#endif // VERTEX diff --git a/data/tr2/ship/shaders/3d.glsl b/data/tr2/ship/shaders/3d.glsl new file mode 100644 index 000000000..b7ee85dfa --- /dev/null +++ b/data/tr2/ship/shaders/3d.glsl @@ -0,0 +1,76 @@ +#ifdef VERTEX +// Vertex shader + +layout(location = 0) in vec3 inPosition; +layout(location = 1) in vec3 inTexCoords; +layout(location = 2) in vec4 inColor; + +uniform mat4 matProjection; +uniform mat4 matModelView; + +#ifdef OGL33C + out vec4 vertColor; + out vec3 vertTexCoords; +#else + varying vec4 vertColor; + varying vec3 vertTexCoords; +#endif + +void main(void) { + gl_Position = matProjection * matModelView * vec4(inPosition, 1); + vertColor = inColor / 255.0; + vertTexCoords = inTexCoords; +} + +#else +// Fragment shader + +uniform sampler2D tex0; +uniform bool texturingEnabled; +uniform bool smoothingEnabled; + +#ifdef OGL33C + #define OUTCOLOR outColor + #define TEXTURESIZE textureSize + #define TEXTURE texture + #define TEXELFETCH texelFetch + + in vec4 vertColor; + in vec3 vertTexCoords; + out vec4 OUTCOLOR; +#else + #define OUTCOLOR gl_FragColor + #define TEXTURESIZE textureSize2D + #define TEXELFETCH texelFetch2D + #define TEXTURE texture2D + + varying vec4 vertColor; + varying vec3 vertTexCoords; +#endif + +void main(void) { + OUTCOLOR = vertColor; + + if (texturingEnabled) { +#if defined(GL_EXT_gpu_shader4) || defined(OGL33C) + if (smoothingEnabled) { + // do not use smoothing for chroma key + ivec2 size = TEXTURESIZE(tex0, 0); + int tx = int((vertTexCoords.x / vertTexCoords.z) * size.x) % size.x; + int ty = int((vertTexCoords.y / vertTexCoords.z) * size.y) % size.y; + vec4 texel = TEXELFETCH(tex0, ivec2(tx, ty), 0); + if (texel.a == 0.0) { + discard; + } + } +#endif + + vec4 texColor = TEXTURE(tex0, vertTexCoords.xy / vertTexCoords.z); + if (texColor.a == 0.0) { + discard; + } + + OUTCOLOR = vec4(OUTCOLOR.rgb * texColor.rgb, texColor.a); + } +} +#endif // VERTEX diff --git a/data/tr2/ship/shaders/fbo.glsl b/data/tr2/ship/shaders/fbo.glsl new file mode 100644 index 000000000..ebc393978 --- /dev/null +++ b/data/tr2/ship/shaders/fbo.glsl @@ -0,0 +1,38 @@ +#ifdef VERTEX +// Vertex shader + +layout(location = 0) in vec2 inPosition; + +#ifdef OGL33C + out vec2 vertTexCoords; +#else + varying vec2 vertTexCoords; +#endif + +void main(void) { + vertTexCoords = inPosition; + gl_Position = vec4(vertTexCoords * vec2(2.0, 2.0) + vec2(-1.0, -1.0), 0.0, 1.0); +} + +#else +// Fragment shader + +uniform sampler2D tex0; + +#ifdef OGL33C + #define OUTCOLOR outColor + #define TEXTURE texture + + in vec2 vertTexCoords; + out vec4 OUTCOLOR; +#else + #define OUTCOLOR gl_FragColor + #define TEXTURE texture2D + + varying vec2 vertTexCoords; +#endif + +void main(void) { + OUTCOLOR = TEXTURE(tex0, vertTexCoords); +} +#endif // VERTEX diff --git a/docs/tr2/CHANGELOG.md b/docs/tr2/CHANGELOG.md index 1fc9f0c9c..11aca4f04 100644 --- a/docs/tr2/CHANGELOG.md +++ b/docs/tr2/CHANGELOG.md @@ -1,4 +1,9 @@ ## [Unreleased](https://github.com/LostArtefacts/TRX/compare/tr2-0.6...develop) - ××××-××-×× +- switched rendering to use hybrid OpenGL+DirectX approach + - (WIP) changed fullscreen behavior to use windowed desktop mode + - changed the F2 key behavior (F2 reduces screen size, Shift+F2 increases it again) + - removed triple buffering option + - removed dither option (which seems to have had no effect) - added support for custom levels to enforce values for any config setting (#1846) - added an option to fix inventory item usage duplication (#1586) - added optional automatic key/puzzle inventory item pre-selection (#1884) diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index edd8a09d2..5fd97e10d 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -874,9 +874,9 @@ int32_t __cdecl BGND_AddTexture(int32_t tile_idx, BYTE *bitmap, int32_t pal_index, RGB_888 *bmp_pal); void __cdecl BGND_GetPageHandles(void); void __cdecl BGND_DrawInGameBlack(void); -void __cdecl DrawQuad(float sx, float sy, float width, float height, D3DCOLOR color); +void __cdecl BGND_DrawQuad(float sx, float sy, float width, float height, D3DCOLOR color); void __cdecl BGND_DrawInGameBackground(void); -void __cdecl DrawTextureTile(int32_t sx, int32_t sy, int32_t width, int32_t height, HWR_TEXTURE_HANDLE tex_source, int32_t tu, int32_t tv, int32_t t_width, int32_t t_height, D3DCOLOR color0, D3DCOLOR color1, D3DCOLOR color2, D3DCOLOR color3); +void __cdecl BGND_DrawTextureTile(int32_t sx, int32_t sy, int32_t width, int32_t height, HWR_TEXTURE_HANDLE tex_source, int32_t tu, int32_t tv, int32_t t_width, int32_t t_height, D3DCOLOR color0, D3DCOLOR color1, D3DCOLOR color2, D3DCOLOR color3); D3DCOLOR __cdecl BGND_CenterLighting(int32_t x, int32_t y, int32_t width, int32_t height); void __cdecl BGND_Free(void); bool __cdecl BGND_Init(void); @@ -1473,7 +1473,7 @@ int32_t __cdecl Lara_TestClimb(int32_t x, int32_t y, int32_t z, int32_t xfront, int32_t zfront, int32_t item_height, int16_t item_room, int32_t *shift); bool __cdecl SE_WriteAppSettings(APP_SETTINGS *settings); void __cdecl S_CopyBufferToScreen(void); -void __cdecl DrawTextureTile(int32_t sx, int32_t sy, int32_t width, int32_t height, HWR_TEXTURE_HANDLE tex_source, int32_t tu, int32_t tv, int32_t t_width, int32_t t_height, D3DCOLOR color0, D3DCOLOR color1, D3DCOLOR color2, D3DCOLOR color3); +void __cdecl BGND_DrawTextureTile(int32_t sx, int32_t sy, int32_t width, int32_t height, HWR_TEXTURE_HANDLE tex_source, int32_t tu, int32_t tv, int32_t t_width, int32_t t_height, D3DCOLOR color0, D3DCOLOR color1, D3DCOLOR color2, D3DCOLOR color3); void __cdecl RollingBall_Collision(int16_t item_num, ITEM *litem, COLL_INFO *coll); bool __cdecl Level_Load(const char *file_name, int32_t level_num); void __cdecl Camera_LoadCutsceneFrame(void); @@ -1739,7 +1739,7 @@ void __cdecl HotLiquid_Control(int16_t fx_num); void __cdecl CutscenePlayer_Control(int16_t item_num); void __cdecl Window_2_Control(int16_t item_num); -void __cdecl DrawQuad(float sx, float sy, float width, float height, D3DCOLOR color); +void __cdecl BGND_DrawQuad(float sx, float sy, float width, float height, D3DCOLOR color); INT_PTR __stdcall SE_AdvancedDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); void __cdecl Earthquake_Control(int16_t item_num); void __cdecl ModifyStartInfo(int32_t level_num); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index d0f6afd15..01516877a 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -182,7 +182,7 @@ typedef struct __unaligned { bool dither; bool zbuffer; bool bilinear_filtering; - bool triple_buffering; + bool triple_buffering; // TODO: remove this option bool fullscreen; bool sound_enabled; bool lara_mic; @@ -207,16 +207,37 @@ typedef struct __unaligned { } TEXPAGE_DESC; typedef struct __unaligned { - uint8_t red; - uint8_t green; - uint8_t blue; + union { + uint8_t red; + uint8_t r; + }; + union { + uint8_t green; + uint8_t g; + }; + union { + uint8_t blue; + uint8_t b; + }; } RGB_888; typedef struct __unaligned { - uint8_t red; - uint8_t green; - uint8_t blue; - uint8_t alpha; + union { + uint8_t red; + uint8_t r; + }; + union { + uint8_t green; + uint8_t g; + }; + union { + uint8_t blue; + uint8_t b; + }; + union { + uint8_t alpha; + uint8_t a; + }; } RGBA_8888; typedef struct { @@ -3789,9 +3810,9 @@ typedef enum { 0x00443B50 0x00B9 +R int32_t __cdecl BGND_AddTexture(int32_t tile_idx, BYTE *bitmap, int32_t pal_index, RGB_888 *bmp_pal); 0x00443C10 0x0032 +R void __cdecl BGND_GetPageHandles(void); 0x00443C50 0x005F +R void __cdecl BGND_DrawInGameBlack(void); -0x00443CB0 0x00DC +R void __cdecl DrawQuad(float sx, float sy, float width, float height, D3DCOLOR color); +0x00443CB0 0x00DC +R void __cdecl BGND_DrawQuad(float sx, float sy, float width, float height, D3DCOLOR color); 0x00443D90 0x0220 +R void __cdecl BGND_DrawInGameBackground(void); -0x00443FB0 0x0251 +R void __cdecl DrawTextureTile(int32_t sx, int32_t sy, int32_t width, int32_t height, HWR_TEXTURE_HANDLE tex_source, int32_t tu, int32_t tv, int32_t t_width, int32_t t_height, D3DCOLOR color0, D3DCOLOR color1, D3DCOLOR color2, D3DCOLOR color3); +0x00443FB0 0x0251 +R void __cdecl BGND_DrawTextureTile(int32_t sx, int32_t sy, int32_t width, int32_t height, HWR_TEXTURE_HANDLE tex_source, int32_t tu, int32_t tv, int32_t t_width, int32_t t_height, D3DCOLOR color0, D3DCOLOR color1, D3DCOLOR color2, D3DCOLOR color3); 0x00444210 0x008B +R D3DCOLOR __cdecl BGND_CenterLighting(int32_t x, int32_t y, int32_t width, int32_t height); 0x004444C0 0x004D +R void __cdecl BGND_Free(void); 0x00444510 0x0030 +R bool __cdecl BGND_Init(void); diff --git a/src/libtrx/game/shell/common.c b/src/libtrx/game/shell/common.c new file mode 100644 index 000000000..30d3f37c6 --- /dev/null +++ b/src/libtrx/game/shell/common.c @@ -0,0 +1,61 @@ +#include "game/shell.h" +#include "log.h" +#include "memory.h" + +static void M_ShowFatalError(const char *const message) +{ + LOG_ERROR("%s", message); + SDL_Window *const window = Shell_GetWindow(); + SDL_ShowSimpleMessageBox( + SDL_MESSAGEBOX_ERROR, "Tomb Raider Error", message, window); + Shell_Terminate(1); +} + +void Shell_Terminate(int32_t exit_code) +{ + Shell_Shutdown(); + + SDL_Window *const window = Shell_GetWindow(); + if (window != NULL) { + SDL_DestroyWindow(window); + } + SDL_Quit(); + exit(exit_code); +} + +void Shell_ExitSystem(const char *message) +{ + M_ShowFatalError(message); + Shell_Shutdown(); +} + +void Shell_ExitSystemFmt(const char *fmt, ...) +{ + va_list va; + va_start(va, fmt); + int32_t size = vsnprintf(NULL, 0, fmt, va) + 1; + char *message = Memory_Alloc(size); + va_end(va); + + va_start(va, fmt); + vsnprintf(message, size, fmt, va); + va_end(va); + + Shell_ExitSystem(message); + + Memory_FreePointer(&message); +} + +int32_t Shell_GetCurrentDisplayWidth(void) +{ + SDL_DisplayMode dm; + SDL_GetCurrentDisplayMode(0, &dm); + return dm.w; +} + +int32_t Shell_GetCurrentDisplayHeight(void) +{ + SDL_DisplayMode dm; + SDL_GetCurrentDisplayMode(0, &dm); + return dm.h; +} diff --git a/src/libtrx/game/ui/events.c b/src/libtrx/game/ui/events.c index dba84427b..90afa0479 100644 --- a/src/libtrx/game/ui/events.c +++ b/src/libtrx/game/ui/events.c @@ -2,6 +2,7 @@ #include "config/common.h" +#include #include static EVENT_MANAGER *m_EventManager = NULL; @@ -10,12 +11,14 @@ static void M_HandleConfigChange(const EVENT *event, void *data); static void M_HandleConfigChange(const EVENT *const event, void *const data) { - const EVENT new_event = { - .name = "canvas_resize", - .sender = NULL, - .data = NULL, - }; - EventManager_Fire(m_EventManager, &new_event); + if (m_EventManager != NULL) { + const EVENT new_event = { + .name = "canvas_resize", + .sender = NULL, + .data = NULL, + }; + EventManager_Fire(m_EventManager, &new_event); + } } void UI_Events_Init(void) @@ -34,16 +37,21 @@ int32_t UI_Events_Subscribe( const char *const event_name, const UI_WIDGET *const sender, const EVENT_LISTENER listener, void *const user_data) { + assert(m_EventManager != NULL); return EventManager_Subscribe( m_EventManager, event_name, sender, listener, user_data); } void UI_Events_Unsubscribe(const int32_t listener_id) { - EventManager_Unsubscribe(m_EventManager, listener_id); + if (m_EventManager != NULL) { + EventManager_Unsubscribe(m_EventManager, listener_id); + } } void UI_Events_Fire(const EVENT *const event) { - EventManager_Fire(m_EventManager, event); + if (m_EventManager != NULL) { + EventManager_Fire(m_EventManager, event); + } } diff --git a/src/libtrx/gfx/2d/2d_renderer.c b/src/libtrx/gfx/2d/2d_renderer.c index 361245f28..1add1cc07 100644 --- a/src/libtrx/gfx/2d/2d_renderer.c +++ b/src/libtrx/gfx/2d/2d_renderer.c @@ -11,6 +11,7 @@ void GFX_2D_Renderer_Init( { LOG_INFO(""); assert(renderer != NULL); + renderer->use_palette = false; GFX_GL_Buffer_Init(&renderer->surface_buffer, GL_ARRAY_BUFFER); GFX_GL_Buffer_Bind(&renderer->surface_buffer); @@ -25,17 +26,7 @@ void GFX_2D_Renderer_Init( &renderer->surface_format, 0, 2, GL_FLOAT, GL_FALSE, 0, 0); GFX_GL_Texture_Init(&renderer->surface_texture, GL_TEXTURE_2D); - - GFX_GL_Sampler_Init(&renderer->sampler); - GFX_GL_Sampler_Bind(&renderer->sampler, 0); - GFX_GL_Sampler_Parameteri( - &renderer->sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - GFX_GL_Sampler_Parameteri( - &renderer->sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - GFX_GL_Sampler_Parameteri( - &renderer->sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - GFX_GL_Sampler_Parameteri( - &renderer->sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + GFX_GL_Texture_Init(&renderer->palette_texture, GL_TEXTURE_1D); GFX_GL_Program_Init(&renderer->program); GFX_GL_Program_AttachShader( @@ -47,6 +38,19 @@ void GFX_2D_Renderer_Init( GFX_GL_Program_Link(&renderer->program); GFX_GL_Program_FragmentData(&renderer->program, "fragColor"); + renderer->loc_tex0 = + GFX_GL_Program_UniformLocation(&renderer->program, "tex0"); + renderer->loc_pal0 = + GFX_GL_Program_UniformLocation(&renderer->program, "pal0"); + renderer->loc_palette_enabled = + GFX_GL_Program_UniformLocation(&renderer->program, "paletteEnabled"); + + GFX_GL_Program_Bind(&renderer->program); + GFX_GL_Program_Uniform1i(&renderer->program, renderer->loc_tex0, 0); + GFX_GL_Program_Uniform1i(&renderer->program, renderer->loc_pal0, 1); + GFX_GL_Program_Uniform1i( + &renderer->program, renderer->loc_palette_enabled, false); + GFX_GL_CheckError(); } @@ -58,7 +62,7 @@ void GFX_2D_Renderer_Close(GFX_2D_RENDERER *renderer) GFX_GL_VertexArray_Close(&renderer->surface_format); GFX_GL_Buffer_Close(&renderer->surface_buffer); GFX_GL_Texture_Close(&renderer->surface_texture); - GFX_GL_Sampler_Close(&renderer->sampler); + GFX_GL_Texture_Close(&renderer->palette_texture); GFX_GL_Program_Close(&renderer->program); } @@ -89,14 +93,61 @@ void GFX_2D_Renderer_Upload( } } +void GFX_2D_Renderer_SetPalette( + GFX_2D_RENDERER *renderer, const GFX_PALETTE_ENTRY *const palette) +{ + if (palette == NULL) { + if (renderer->use_palette) { + GFX_GL_Program_Bind(&renderer->program); + GFX_GL_Program_Uniform1i( + &renderer->program, renderer->loc_palette_enabled, false); + } + renderer->use_palette = false; + return; + } + + if (!renderer->use_palette) { + GFX_GL_Program_Bind(&renderer->program); + GFX_GL_Texture_Init(&renderer->palette_texture, GL_TEXTURE_1D); + GFX_GL_Program_Uniform1i(&renderer->program, renderer->loc_pal0, 1); + GFX_GL_Program_Uniform1i( + &renderer->program, renderer->loc_palette_enabled, true); + renderer->use_palette = true; + } + + glActiveTexture(GL_TEXTURE0); + GFX_GL_Texture_Bind(&renderer->surface_texture); + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glActiveTexture(GL_TEXTURE1); + GFX_GL_Texture_Bind(&renderer->palette_texture); + GFX_PALETTE_ENTRY faux_palette[256]; + for (int32_t i = 0; i < 256; i++) { + faux_palette[i].r = 255; + faux_palette[i].g = 255 - i; + faux_palette[i].b = i; + } + glTexImage1D( + GL_TEXTURE_1D, 0, GL_RGB8, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, palette); + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + GFX_GL_CheckError(); +} + void GFX_2D_Renderer_Render(GFX_2D_RENDERER *renderer) { assert(renderer != NULL); + GFX_GL_Program_Bind(&renderer->program); GFX_GL_Buffer_Bind(&renderer->surface_buffer); GFX_GL_VertexArray_Bind(&renderer->surface_format); + glActiveTexture(GL_TEXTURE0); GFX_GL_Texture_Bind(&renderer->surface_texture); - GFX_GL_Sampler_Bind(&renderer->sampler, 0); + if (renderer->use_palette) { + glActiveTexture(GL_TEXTURE1); + GFX_GL_Texture_Bind(&renderer->palette_texture); + } GLboolean blend = glIsEnabled(GL_BLEND); if (blend) { @@ -120,4 +171,5 @@ void GFX_2D_Renderer_Render(GFX_2D_RENDERER *renderer) if (depth_test) { glEnable(GL_DEPTH_TEST); } + glActiveTexture(GL_TEXTURE0); } diff --git a/src/libtrx/include/libtrx/game/enum_map.def b/src/libtrx/include/libtrx/game/enum_map.def index 80194d8f6..cc0fedf09 100644 --- a/src/libtrx/include/libtrx/game/enum_map.def +++ b/src/libtrx/include/libtrx/game/enum_map.def @@ -57,5 +57,4 @@ ENUM_MAP_DEFINE(INPUT_ROLE, INPUT_ROLE_SWITCH_INTERNAL_SCREEN_SIZE, "switch_inte ENUM_MAP_DEFINE(INPUT_ROLE, INPUT_ROLE_TOGGLE_BILINEAR_FILTER, "toggle_bilinear_filter") ENUM_MAP_DEFINE(INPUT_ROLE, INPUT_ROLE_TOGGLE_PERSPECTIVE_FILTER, "toggle_perspective_filter") ENUM_MAP_DEFINE(INPUT_ROLE, INPUT_ROLE_TOGGLE_Z_BUFFER, "toggle_z_buffer") -ENUM_MAP_DEFINE(INPUT_ROLE, INPUT_ROLE_TOGGLE_DITHER, "toggle_dither") ENUM_MAP_DEFINE(INPUT_ROLE, INPUT_ROLE_TOGGLE_RENDERING_MODE, "toggle_rendering_mode") diff --git a/src/libtrx/include/libtrx/game/input/backends/keyboard_tr2.def b/src/libtrx/include/libtrx/game/input/backends/keyboard_tr2.def index c71dc739d..a68219f3d 100644 --- a/src/libtrx/include/libtrx/game/input/backends/keyboard_tr2.def +++ b/src/libtrx/include/libtrx/game/input/backends/keyboard_tr2.def @@ -36,7 +36,6 @@ INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_SWITCH_INTERNAL_SCREEN_SIZE, SDL_SCANCODE_F2) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_TOGGLE_BILINEAR_FILTER, SDL_SCANCODE_F3) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_TOGGLE_PERSPECTIVE_FILTER, SDL_SCANCODE_F4) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_TOGGLE_Z_BUFFER, SDL_SCANCODE_F7) -INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_TOGGLE_DITHER, SDL_SCANCODE_UNKNOWN) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_TOGGLE_FULLSCREEN, SDL_SCANCODE_UNKNOWN) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_TOGGLE_RENDERING_MODE, SDL_SCANCODE_F12) diff --git a/src/libtrx/include/libtrx/game/input/roles_tr2.def b/src/libtrx/include/libtrx/game/input/roles_tr2.def index 15bf615eb..8cf1adb5b 100644 --- a/src/libtrx/include/libtrx/game/input/roles_tr2.def +++ b/src/libtrx/include/libtrx/game/input/roles_tr2.def @@ -47,5 +47,4 @@ INPUT_ROLE_DEFINE(SWITCH_INTERNAL_SCREEN_SIZE, switch_internal_screen_size) INPUT_ROLE_DEFINE(TOGGLE_BILINEAR_FILTER, toggle_bilinear_filter) INPUT_ROLE_DEFINE(TOGGLE_PERSPECTIVE_FILTER, toggle_perspective_filter) INPUT_ROLE_DEFINE(TOGGLE_Z_BUFFER, toggle_z_buffer) -INPUT_ROLE_DEFINE(TOGGLE_DITHER, toggle_dither) INPUT_ROLE_DEFINE(TOGGLE_RENDERING_MODE, toggle_rendering_mode) diff --git a/src/libtrx/include/libtrx/game/shell.h b/src/libtrx/include/libtrx/game/shell.h index ab0b725f4..2bb15f067 100644 --- a/src/libtrx/include/libtrx/game/shell.h +++ b/src/libtrx/include/libtrx/game/shell.h @@ -1,4 +1,14 @@ #pragma once +#include +#include + +extern void Shell_Shutdown(void); +extern SDL_Window *Shell_GetWindow(void); + +void Shell_Terminate(int32_t exit_code); void Shell_ExitSystem(const char *message); void Shell_ExitSystemFmt(const char *fmt, ...); + +int32_t Shell_GetCurrentDisplayWidth(void); +int32_t Shell_GetCurrentDisplayHeight(void); diff --git a/src/libtrx/include/libtrx/gfx/2d/2d_renderer.h b/src/libtrx/include/libtrx/gfx/2d/2d_renderer.h index 162dfdd33..93b046cdf 100644 --- a/src/libtrx/include/libtrx/gfx/2d/2d_renderer.h +++ b/src/libtrx/include/libtrx/gfx/2d/2d_renderer.h @@ -3,7 +3,6 @@ #include "../config.h" #include "../gl/buffer.h" #include "../gl/program.h" -#include "../gl/sampler.h" #include "../gl/texture.h" #include "../gl/vertex_array.h" #include "2d_surface.h" @@ -11,14 +10,24 @@ #include #include +typedef struct { + uint8_t r, g, b; +} GFX_PALETTE_ENTRY; + typedef struct { uint32_t width; uint32_t height; GFX_GL_VERTEX_ARRAY surface_format; GFX_GL_BUFFER surface_buffer; GFX_GL_TEXTURE surface_texture; - GFX_GL_SAMPLER sampler; + GFX_GL_TEXTURE palette_texture; GFX_GL_PROGRAM program; + bool use_palette; + + // shader variable locations + GLint loc_tex0; + GLint loc_pal0; + GLint loc_palette_enabled; } GFX_2D_RENDERER; void GFX_2D_Renderer_Init(GFX_2D_RENDERER *renderer, const GFX_CONFIG *config); @@ -26,4 +35,8 @@ void GFX_2D_Renderer_Close(GFX_2D_RENDERER *renderer); void GFX_2D_Renderer_Upload( GFX_2D_RENDERER *renderer, GFX_2D_SURFACE_DESC *desc, const uint8_t *data); + +void GFX_2D_Renderer_SetPalette( + GFX_2D_RENDERER *renderer, const GFX_PALETTE_ENTRY *palette); + void GFX_2D_Renderer_Render(GFX_2D_RENDERER *renderer); diff --git a/src/libtrx/include/libtrx/utils.h b/src/libtrx/include/libtrx/utils.h index 3a942261f..4c73dfd7d 100644 --- a/src/libtrx/include/libtrx/utils.h +++ b/src/libtrx/include/libtrx/utils.h @@ -34,6 +34,8 @@ (b) = (c); \ } while (0) +#define ALIGN(a, bytes) ((a + (bytes) - 1) & (~(bytes - 1))) + #define MKTAG(a, b, c, d) \ ((a) | ((b) << 8) | ((c) << 16) | ((unsigned)(d) << 24)) diff --git a/src/libtrx/meson.build b/src/libtrx/meson.build index 07c81c809..bbcf82a85 100644 --- a/src/libtrx/meson.build +++ b/src/libtrx/meson.build @@ -102,6 +102,7 @@ sources = [ 'game/objects/names.c', 'game/objects/vars.c', 'game/rooms/common.c', + 'game/shell/common.c', 'game/text.c', 'game/ui/common.c', 'game/ui/events.c', diff --git a/src/tr1/game/screen.c b/src/tr1/game/screen.c index b9f4bcba8..0d6c4a98b 100644 --- a/src/tr1/game/screen.c +++ b/src/tr1/game/screen.c @@ -2,11 +2,11 @@ #include "config.h" #include "game/output.h" +#include "game/shell.h" #include "game/viewport.h" #include "global/const.h" #include "global/types.h" #include "math/matrix.h" -#include "specific/s_shell.h" #include @@ -72,8 +72,8 @@ void Screen_Init(void) // set the first resolution size to desktop size res = &m_Resolutions[0]; - res->width = S_Shell_GetCurrentDisplayWidth(); - res->height = S_Shell_GetCurrentDisplayHeight(); + res->width = Shell_GetCurrentDisplayWidth(); + res->height = Shell_GetCurrentDisplayHeight(); // select matching resolution from config if (g_Config.resolution_width > 0 && g_Config.resolution_height > 0) { diff --git a/src/tr1/game/shell.c b/src/tr1/game/shell.c index 0fd16f41e..019069872 100644 --- a/src/tr1/game/shell.c +++ b/src/tr1/game/shell.c @@ -218,22 +218,6 @@ void Shell_Main(void) GameString_Shutdown(); } -void Shell_ExitSystem(const char *message) -{ - S_Shell_ShowFatalError(message); - Shell_Shutdown(); -} - -void Shell_ExitSystemFmt(const char *fmt, ...) -{ - va_list va; - va_start(va, fmt); - char message[150]; - vsnprintf(message, 150, fmt, va); - va_end(va); - Shell_ExitSystem(message); -} - void Shell_ProcessInput(void) { if (g_InputDB.screenshot) { diff --git a/src/tr1/game/shell.h b/src/tr1/game/shell.h index 4d476b29c..99deb49ab 100644 --- a/src/tr1/game/shell.h +++ b/src/tr1/game/shell.h @@ -1,11 +1,10 @@ #pragma once +#include + #include void Shell_Init(const char *gameflow_path); const char *Shell_GetGameflowPath(void); void Shell_ProcessInput(void); -void Shell_Shutdown(void); void Shell_Main(void); -void Shell_ExitSystem(const char *message); -void Shell_ExitSystemFmt(const char *fmt, ...); diff --git a/src/tr1/specific/s_shell.c b/src/tr1/specific/s_shell.c index c4a48863e..9713e18c6 100644 --- a/src/tr1/specific/s_shell.c +++ b/src/tr1/specific/s_shell.c @@ -21,6 +21,7 @@ #define SDL_MAIN_HANDLED +#include #ifdef _WIN32 #include #include @@ -164,31 +165,13 @@ void S_Shell_Init(void) SDL_ShowWindow(m_Window); } -void S_Shell_ShowFatalError(const char *message) -{ - LOG_ERROR("%s", message); - SDL_ShowSimpleMessageBox( - SDL_MESSAGEBOX_ERROR, "Tomb Raider Error", message, m_Window); - S_Shell_TerminateGame(1); -} - -void S_Shell_TerminateGame(int exit_code) -{ - Shell_Shutdown(); - if (m_Window) { - SDL_DestroyWindow(m_Window); - } - SDL_Quit(); - exit(exit_code); -} - void S_Shell_SpinMessageLoop(void) { SDL_Event event; while (SDL_PollEvent(&event) != 0) { switch (event.type) { case SDL_QUIT: - S_Shell_TerminateGame(0); + Shell_Terminate(0); break; case SDL_WINDOWEVENT: @@ -298,9 +281,7 @@ int main(int argc, char **argv) m_ArgStrings = argv; if (SDL_Init(SDL_INIT_EVENTS | SDL_INIT_VIDEO) < 0) { - char buf[256]; - sprintf(buf, "Cannot initialize SDL: %s", SDL_GetError()); - S_Shell_ShowFatalError(buf); + Shell_ExitSystemFmt("Cannot initialize SDL: %s", SDL_GetError()); return 1; } @@ -314,7 +295,7 @@ int main(int argc, char **argv) Shell_Main(); - S_Shell_TerminateGame(0); + Shell_Terminate(0); return 0; } @@ -391,21 +372,7 @@ bool S_Shell_GetCommandLine(int *arg_count, char ***args) return true; } -void *S_Shell_GetWindowHandle(void) -{ - return (void *)m_Window; -} - -int S_Shell_GetCurrentDisplayWidth(void) -{ - SDL_DisplayMode dm; - SDL_GetCurrentDisplayMode(0, &dm); - return dm.w; -} - -int S_Shell_GetCurrentDisplayHeight(void) +SDL_Window *Shell_GetWindow(void) { - SDL_DisplayMode dm; - SDL_GetCurrentDisplayMode(0, &dm); - return dm.h; + return m_Window; } diff --git a/src/tr1/specific/s_shell.h b/src/tr1/specific/s_shell.h index 16137abd5..2122f0107 100644 --- a/src/tr1/specific/s_shell.h +++ b/src/tr1/specific/s_shell.h @@ -3,15 +3,9 @@ #include #include -void S_Shell_ShowFatalError(const char *message); - void S_Shell_Init(void); void S_Shell_CreateWindow(void); void S_Shell_SpinMessageLoop(void); bool S_Shell_GetCommandLine(int *arg_count, char ***args); -void *S_Shell_GetWindowHandle(void); void S_Shell_ToggleFullscreen(void); void S_Shell_HandleWindowResize(void); -void S_Shell_TerminateGame(int exit_code); -int S_Shell_GetCurrentDisplayWidth(void); -int S_Shell_GetCurrentDisplayHeight(void); diff --git a/src/tr2/decomp/decomp.c b/src/tr2/decomp/decomp.c index dda171e50..87472aa34 100644 --- a/src/tr2/decomp/decomp.c +++ b/src/tr2/decomp/decomp.c @@ -1,6 +1,7 @@ #include "decomp/decomp.h" #include "config.h" +#include "decomp/render_new.h" #include "decomp/savegame.h" #include "game/background.h" #include "game/camera.h" @@ -42,14 +43,13 @@ #include #include +#include #include #include #define IDI_MAINICON 100 static void M_DisplayPicture(const char *file_name, bool copy_palette); -static bool M_InsertDisplayModeInListSorted( - DISPLAY_MODE_LIST *mode_list, DISPLAY_MODE *src_mode); static void M_DisplayModeListInit(DISPLAY_MODE_LIST *mode_list); static void M_DisplayModeListDelete(DISPLAY_MODE_LIST *mode_list); @@ -192,39 +192,11 @@ static DISPLAY_MODE *M_InsertDisplayModeInListTail(DISPLAY_MODE_LIST *mode_list) return &node->body; } -static bool M_InsertDisplayModeInListSorted( - DISPLAY_MODE_LIST *mode_list, DISPLAY_MODE *src_mode) -{ - DISPLAY_MODE *dst_mode = NULL; - - if (mode_list->head == NULL - || CompareVideoModes(src_mode, &mode_list->head->body)) { - dst_mode = M_InsertDisplayModeInListHead(mode_list); - goto finish; - } - for (DISPLAY_MODE_NODE *node = mode_list->head; node != NULL; - node = node->next) { - if (CompareVideoModes(src_mode, &node->body)) { - dst_mode = M_InsertDisplayMode(mode_list, node); - goto finish; - } - } - dst_mode = M_InsertDisplayModeInListTail(mode_list); - -finish: - if (dst_mode == NULL) { - return false; - } - *dst_mode = *src_mode; - return true; -} - int32_t __cdecl GameInit(void) { // clang-format off return WinVidInit() && Direct3DInit() - && RenderInit() && InitTextures() && HWR_Init() && BGND_Init(); @@ -247,8 +219,6 @@ int32_t __stdcall WinMain( return 0; } - // TODO: install exception handler - bool is_setup_requested = UT_FindArg("setup") != 0; if (!GameInit()) { UT_ErrorBox(IDS_DX5_REQUIRED, NULL); @@ -256,6 +226,11 @@ int32_t __stdcall WinMain( } int32_t app_settings_status = SE_ReadAppSettings(&g_SavedAppSettings); + if (!WinVidCreateGameWindow()) { + UT_ErrorBox(IDS_DX5_REQUIRED, NULL); + goto cleanup; + } + if (!app_settings_status) { goto cleanup; } @@ -319,12 +294,8 @@ void __cdecl WinInReadKeyboard(uint8_t *input_data) int32_t __cdecl WinGameStart(void) { - // try { WinVidStart(); RenderStart(true); - // } catch (int32_t error) { - // return error; - // } return 0; } @@ -332,7 +303,6 @@ int16_t __cdecl TitleSequence(void) { GF_N_LoadStrings(-1); - TempVideoAdjust(1, 1.0); g_NoInputCounter = 0; if (!g_IsTitleLoaded) { @@ -390,36 +360,6 @@ int16_t __cdecl TitleSequence(void) return GFD_EXIT_GAME; } -void __cdecl WinVidSetMinWindowSize(int32_t width, int32_t height) -{ - g_MinWindowClientWidth = width; - g_MinWindowClientHeight = height; - GameWindowCalculateSizeFromClient(&width, &height); - g_MinWindowWidth = width; - g_MinWindowHeight = height; - g_IsMinWindowSizeSet = true; -} - -void __cdecl WinVidSetMaxWindowSize(int32_t width, int32_t height) -{ - g_MaxWindowClientWidth = width; - g_MaxWindowClientHeight = height; - GameWindowCalculateSizeFromClient(&width, &height); - g_MaxWindowWidth = width; - g_MaxWindowHeight = height; - g_IsMaxWindowSizeSet = true; -} - -void __cdecl WinVidClearMinWindowSize(void) -{ - g_IsMinWindowSizeSet = false; -} - -void __cdecl WinVidClearMaxWindowSize(void) -{ - g_IsMaxWindowSizeSet = false; -} - int32_t __cdecl CalculateWindowWidth(const int32_t width, const int32_t height) { if (g_SavedAppSettings.aspect_mode == AM_4_3) { @@ -442,172 +382,11 @@ int32_t __cdecl CalculateWindowHeight(const int32_t width, const int32_t height) return height; } -bool __cdecl WinVidGetMinMaxInfo(LPMINMAXINFO info) -{ - if (!g_IsGameWindowCreated) { - return false; - } - - if (g_IsGameFullScreen) { - info->ptMaxTrackSize.x = g_FullScreenWidth; - info->ptMaxTrackSize.y = g_FullScreenHeight; - info->ptMinTrackSize.x = g_FullScreenWidth; - info->ptMinTrackSize.y = g_FullScreenHeight; - info->ptMaxSize.x = g_FullScreenWidth; - info->ptMaxSize.y = g_FullScreenHeight; - return true; - } - - if (g_IsMinWindowSizeSet) { - info->ptMinTrackSize.x = g_MinWindowWidth; - info->ptMinTrackSize.y = g_MinWindowHeight; - } - - if (g_IsMinMaxInfoSpecial) { - int32_t width = g_GameWindowWidth; - int32_t height = g_GameWindowHeight; - GameWindowCalculateSizeFromClient(&width, &height); - info->ptMaxSize.x = width; - info->ptMaxTrackSize.x = width; - info->ptMaxSize.y = height; - info->ptMaxTrackSize.y = height; - } else if (g_IsMaxWindowSizeSet) { - info->ptMaxTrackSize.x = g_MaxWindowWidth; - info->ptMaxTrackSize.y = g_MaxWindowHeight; - info->ptMaxSize.x = g_MaxWindowWidth; - info->ptMaxSize.y = g_MaxWindowHeight; - } - - return g_IsMinWindowSizeSet || g_IsMaxWindowSizeSet; -} - HWND __cdecl WinVidFindGameWindow(void) { return FindWindowA(CLASS_NAME, WINDOW_NAME); } -bool __cdecl WinVidSpinMessageLoop(bool need_wait) -{ - if (g_IsMessageLoopClosed) { - return 0; - } - - g_MessageLoopCounter++; - - do { - if (need_wait) { - WaitMessage(); - } else { - need_wait = true; - } - - MSG msg; - while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessageA(&msg); - if (msg.message == WM_QUIT) { - g_AppResultCode = msg.wParam; - g_IsMessageLoopClosed = true; - g_IsGameToExit = true; - g_StopInventory = true; - g_MessageLoopCounter--; - return 0; - } - } - } while (!g_IsGameWindowActive || g_IsGameWindowMinimized); - - g_MessageLoopCounter--; - return true; -} - -void __cdecl WinVidShowGameWindow(const int32_t cmd_show) -{ - if (cmd_show != SW_SHOW || !g_IsGameWindowShow) { - g_IsGameWindowUpdating = true; - ShowWindow(g_GameWindowHandle, cmd_show); - UpdateWindow(g_GameWindowHandle); - g_IsGameWindowUpdating = false; - g_IsGameWindowShow = true; - } -} - -void __cdecl WinVidHideGameWindow(void) -{ - if (g_IsGameWindowShow) { - g_IsGameWindowUpdating = true; - ShowWindow(g_GameWindowHandle, SW_HIDE); - UpdateWindow(g_GameWindowHandle); - g_IsGameWindowUpdating = false; - g_IsGameWindowShow = false; - } -} - -void __cdecl WinVidSetGameWindowSize(int32_t width, int32_t height) -{ - GameWindowCalculateSizeFromClient(&width, &height); - SetWindowPos( - g_GameWindowHandle, NULL, 0, 0, width, height, - SWP_NOCOPYBITS | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE); -} - -bool __cdecl ShowDDrawGameWindow(bool active) -{ - if (!g_GameWindowHandle || !g_DDraw) { - return false; - } - if (g_IsDDrawGameWindowShow) { - return true; - } - - RECT rect; - GetWindowRect(g_GameWindowHandle, &rect); - g_GameWindowX = rect.left; - g_GameWindowY = rect.top; - - if (active) { - WinVidShowGameWindow(SW_SHOW); - } - - g_IsGameWindowUpdating = true; - uint32_t flags = DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT - | DDSCL_FULLSCREEN; - if (!active) - flags |= DDSCL_NOWINDOWCHANGES; - const HRESULT result = - IDirectDraw_SetCooperativeLevel(g_DDraw, g_GameWindowHandle, flags); - g_IsGameWindowUpdating = false; - if (FAILED(result)) { - return false; - } - - g_IsDDrawGameWindowShow = true; - return true; -} - -bool __cdecl HideDDrawGameWindow(void) -{ - if (!g_GameWindowHandle || !g_DDraw) { - return false; - } - if (!g_IsDDrawGameWindowShow) { - return true; - } - - WinVidHideGameWindow(); - g_IsGameWindowUpdating = true; - const HRESULT result = IDirectDraw_SetCooperativeLevel( - g_DDraw, g_GameWindowHandle, DDSCL_NORMAL); - if (SUCCEEDED(result)) { - g_IsDDrawGameWindowShow = false; - SetWindowPos( - g_GameWindowHandle, NULL, g_GameWindowX, g_GameWindowY, 0, 0, - SWP_NOCOPYBITS | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE); - } - - g_IsGameWindowUpdating = false; - return SUCCEEDED(result); -} - HRESULT __cdecl DDrawSurfaceCreate(LPDDSDESC dsp, LPDDS *surface) { LPDIRECTDRAWSURFACE sub_surface; @@ -748,140 +527,6 @@ DWORD __cdecl CalculateCompatibleColor( // clang-format on } -bool __cdecl WinVidGetDisplayMode(DISPLAY_MODE *disp_mode) -{ - DDSDESC dsp = { .dwSize = sizeof(DDSDESC), 0 }; - - if (FAILED(IDirectDraw_GetDisplayMode(g_DDraw, &dsp))) { - return false; - } - - // clang-format off - if (!(dsp.dwFlags & DDSD_WIDTH) - || !(dsp.dwFlags & DDSD_HEIGHT) - || !(dsp.dwFlags & DDSD_PIXELFORMAT) - || !(dsp.ddpfPixelFormat.dwFlags & DDPF_RGB) - ) { - return false; - } - // clang-format on - - disp_mode->width = dsp.dwWidth; - disp_mode->height = dsp.dwHeight; - disp_mode->bpp = dsp.ddpfPixelFormat.dwRGBBitCount; - disp_mode->vga = (dsp.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) != 0 - ? VGA_256_COLOR - : VGA_NO_VGA; - return true; -} - -bool __cdecl WinVidGoFullScreen(DISPLAY_MODE *disp_mode) -{ - g_FullScreenWidth = disp_mode->width; - g_FullScreenHeight = disp_mode->height; - g_FullScreenBPP = disp_mode->bpp; - g_FullScreenVGA = disp_mode->vga; - - if (!ShowDDrawGameWindow(true)) { - return false; - } - - g_IsGameWindowUpdating = true; - const HRESULT rc = IDirectDraw4_SetDisplayMode( - g_DDraw, disp_mode->width, disp_mode->height, disp_mode->bpp, 0, - disp_mode->vga == VGA_STANDARD ? DDSDM_STANDARDVGAMODE : 0); - g_IsGameWindowUpdating = false; - - if (FAILED(rc)) { - return false; - } - - g_IsGameFullScreen = true; - return true; -} - -bool __cdecl WinVidGoWindowed( - int32_t width, int32_t height, DISPLAY_MODE *disp_mode) -{ - if (!HideDDrawGameWindow()) { - return false; - } - if (!WinVidGetDisplayMode(disp_mode)) { - return false; - } - - int32_t max_width = disp_mode->width; - int32_t max_height = - CalculateWindowHeight(disp_mode->width, disp_mode->height); - if (max_height > disp_mode->height) { - max_height = disp_mode->height; - max_width = CalculateWindowWidth(disp_mode->width, max_height); - } - WinVidSetMaxWindowSize(max_width, max_height); - - if (width > max_width || height > max_height) { - width = max_width; - height = max_height; - } - - g_IsGameFullScreen = false; - g_IsGameWindowUpdating = true; - WinVidSetGameWindowSize(width, height); - g_IsGameWindowUpdating = false; - - RECT rect; - GetClientRect(g_GameWindowHandle, &rect); - MapWindowPoints(g_GameWindowHandle, NULL, (LPPOINT)&rect, 2); - - if ((rect.left > 0 || rect.right < disp_mode->width) - && (rect.top > 0 || rect.bottom < disp_mode->height)) { - WinVidShowGameWindow(SW_SHOW); - } else { - WinVidShowGameWindow(SW_MAXIMIZE); - } - - disp_mode->width = width; - disp_mode->height = height; - return true; -} - -void __cdecl WinVidSetDisplayAdapter(DISPLAY_ADAPTER *disp_adapter) -{ - DISPLAY_MODE disp_mode; - - disp_adapter->sw_windowed_supported = false; - disp_adapter->hw_windowed_supported = false; - disp_adapter->screen_width = 0; - - if (disp_adapter->adapter_guid_ptr != NULL) { - return; - } - - if (!DDrawCreate(NULL)) { - return; - } - - bool result = WinVidGetDisplayMode(&disp_mode); - DDrawRelease(); - - if (!result) { - return; - } - - disp_mode.width &= ~0x1F; - if (disp_mode.width * 3 / 4 > disp_mode.height) { - disp_mode.width = (disp_mode.height * 4 / 3) & ~0x1F; - } - - disp_adapter->sw_windowed_supported = disp_mode.vga == VGA_256_COLOR; - disp_adapter->hw_windowed_supported = disp_adapter->hw_render_supported - && (disp_adapter->hw_device_desc.dwFlags & D3DDD_DEVICERENDERBITDEPTH) - != 0 - && (GetRenderBitDepth(disp_mode.bpp) - & disp_adapter->hw_device_desc.dwDeviceRenderBitDepth) - != 0; -} - void __cdecl Game_SetCutsceneTrack(const int32_t track) { g_CineTrackID = track; @@ -1165,32 +810,15 @@ int32_t __cdecl Level_Initialise( void __cdecl RestoreLostBuffers(void) { - if (g_PrimaryBufferSurface == NULL) { - Shell_ExitSystem("Oops... no front buffer"); - return; - } bool rebuild = false; - if (FAILED(DDrawSurfaceRestoreLost( - g_PrimaryBufferSurface, NULL, g_SavedAppSettings.fullscreen))) { - rebuild = true; - } - - if ((g_SavedAppSettings.fullscreen - || g_SavedAppSettings.render_mode == RM_HARDWARE) - && FAILED(DDrawSurfaceRestoreLost( - g_BackBufferSurface, g_PrimaryBufferSurface, true))) { - rebuild = true; - } - - if (g_SavedAppSettings.triple_buffering - && FAILED(DDrawSurfaceRestoreLost( - g_ThirdBufferSurface, g_PrimaryBufferSurface, true))) { + if (g_BackBufferSurface != NULL + && FAILED(DDrawSurfaceRestoreLost(g_BackBufferSurface, NULL, false))) { rebuild = true; } - if (g_SavedAppSettings.render_mode == RM_SOFTWARE + if (g_RenderBufferSurface != NULL && FAILED( DDrawSurfaceRestoreLost(g_RenderBufferSurface, NULL, false))) { rebuild = true; @@ -1214,67 +842,6 @@ void __cdecl RestoreLostBuffers(void) } } -void __cdecl CreateScreenBuffers(void) -{ - { - DDSDESC dsp = { - .dwSize = sizeof(DDSDESC), - .dwFlags = DDSD_BACKBUFFERCOUNT | DDSD_CAPS, - .dwBackBufferCount = (g_SavedAppSettings.triple_buffering) ? 2 : 1, - .ddsCaps.dwCaps = - DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX, - }; - if (g_SavedAppSettings.render_mode == RM_HARDWARE) { - dsp.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE; - } - if (FAILED(DDrawSurfaceCreate(&dsp, &g_PrimaryBufferSurface))) { - Shell_ExitSystem("Failed to create primary screen buffer"); - } - WinVidClearBuffer(g_PrimaryBufferSurface, NULL, 0); - } - - { - DDSCAPS caps = { - .dwCaps = DDSCAPS_BACKBUFFER, - }; - if (FAILED(IDirectDrawSurface_GetAttachedSurface( - g_PrimaryBufferSurface, &caps, &g_BackBufferSurface))) { - Shell_ExitSystem("Failed to create back screen buffer"); - } - WinVidClearBuffer(g_BackBufferSurface, NULL, 0); - } - - if (g_SavedAppSettings.triple_buffering) { - DDSCAPS caps = { - .dwCaps = DDSCAPS_FLIP, - }; - if (FAILED(IDirectDrawSurface_GetAttachedSurface( - g_BackBufferSurface, &caps, &g_ThirdBufferSurface))) { - Shell_ExitSystem("Failed to create third screen buffer"); - } - WinVidClearBuffer(g_ThirdBufferSurface, NULL, 0); - } -} - -void __cdecl CreatePrimarySurface(void) -{ - if ((g_GameVid_IsVga && g_SavedAppSettings.render_mode == RM_HARDWARE) - || (!g_GameVid_IsVga - && g_SavedAppSettings.render_mode == RM_SOFTWARE)) { - Shell_ExitSystem("Wrong bit depth"); - } - - DDSDESC dsp = { - .dwSize = sizeof(DDSDESC), - .dwFlags = DDSD_CAPS, - .ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE, - }; - - if (FAILED(DDrawSurfaceCreate(&dsp, &g_PrimaryBufferSurface))) { - Shell_ExitSystem("Failed to create primary screen buffer"); - } -} - void __cdecl CreateBackBuffer(void) { DDSDESC dsp = { @@ -1295,56 +862,9 @@ void __cdecl CreateBackBuffer(void) WinVidClearBuffer(g_BackBufferSurface, 0, 0); } -void __cdecl CreateClipper(void) -{ - if (FAILED(IDirectDraw_CreateClipper(g_DDraw, 0, &g_DDrawClipper, NULL))) { - Shell_ExitSystem("Failed to create clipper"); - } - - if (FAILED(IDirectDrawClipper_SetHWnd( - g_DDrawClipper, 0, g_GameWindowHandle))) { - Shell_ExitSystem("Failed to attach clipper to the game window"); - } - - if (FAILED(IDirectDrawSurface_SetClipper( - g_PrimaryBufferSurface, g_DDrawClipper))) { - Shell_ExitSystem("Failed to attach clipper to the primary surface"); - } -} - void __cdecl CreateWindowPalette(void) { - memset(g_WinVid_Palette, 0, sizeof(g_WinVid_Palette)); - - DWORD flags = DDPCAPS_8BIT; - if (g_GameVid_IsWindowedVGA) { - for (int32_t i = 0; i < 10; i++) { - g_WinVid_Palette[i].peFlags = PC_EXPLICIT; - g_WinVid_Palette[i].peRed = i; - } - for (int32_t i = 10; i < 246; i++) { - g_WinVid_Palette[i].peFlags = PC_NOCOLLAPSE | PC_RESERVED; - } - for (int32_t i = 246; i < 256; i++) { - g_WinVid_Palette[i].peFlags = PC_EXPLICIT; - g_WinVid_Palette[i].peRed = i; // TODO: i - 246? - } - } else { - for (int32_t i = 0; i < 256; i++) { - g_WinVid_Palette[i].peFlags = PC_RESERVED; - } - flags |= DDPCAPS_ALLOW256; - } - - if (FAILED(IDirectDraw_CreatePalette( - g_DDraw, flags, g_WinVid_Palette, &g_DDrawPalette, 0))) { - Shell_ExitSystem("Failed to create palette"); - } - - if (FAILED(IDirectDrawSurface_SetPalette( - g_PrimaryBufferSurface, g_DDrawPalette))) { - Shell_ExitSystem("Failed to attach palette to the primary buffer"); - } + memset(g_SDLPalette, 0, sizeof(RGB_888) * 256); } void __cdecl CreateZBuffer(void) @@ -1402,8 +922,10 @@ void __cdecl CreateRenderBuffer(void) }, }; - if (FAILED(DDrawSurfaceCreate(&dsp, &g_RenderBufferSurface))) { - Shell_ExitSystem("Failed to create render buffer"); + LOG_DEBUG("creating render buffer: %d x %d", dsp.dwWidth, dsp.dwHeight); + const HRESULT rc = DDrawSurfaceCreate(&dsp, &g_RenderBufferSurface); + if (FAILED(rc)) { + Shell_ExitSystemFmt("Failed to create render buffer: %08x", rc); } if (!WinVidClearBuffer(g_RenderBufferSurface, NULL, 0)) { @@ -1423,7 +945,9 @@ void __cdecl CreatePictureBuffer(void) }, }; - if (FAILED(DDrawSurfaceCreate(&dsp, &g_PictureBufferSurface))) { + LOG_DEBUG("creating picture buffer: %d x %d", dsp.dwWidth, dsp.dwHeight); + const HRESULT rc = DDrawSurfaceCreate(&dsp, &g_PictureBufferSurface); + if (FAILED(rc)) { Shell_ExitSystem("Failed to create picture buffer"); } } @@ -1445,35 +969,13 @@ void __cdecl ClearBuffers(DWORD flags, DWORD fill_color) if (g_SavedAppSettings.render_mode == RM_HARDWARE) { DWORD d3d_clear_flags = 0; - if (flags & CLRB_BACK_BUFFER) { - d3d_clear_flags |= D3DCLEAR_TARGET; - } - if (flags & CLRB_Z_BUFFER) { d3d_clear_flags |= D3DCLEAR_ZBUFFER; } - - if (d3d_clear_flags != 0) { - D3DRECT d3d_rect = { - .x1 = win_rect.left, - .y1 = win_rect.top, - .x2 = win_rect.right, - .y2 = win_rect.bottom, - }; - IDirect3DViewport_Clear(g_D3DView, 1, &d3d_rect, d3d_clear_flags); - } - } else { - if (flags & CLRB_BACK_BUFFER) { - WinVidClearBuffer(g_BackBufferSurface, &win_rect, fill_color); - } - } - - if (flags & CLRB_PRIMARY_BUFFER) { - WinVidClearBuffer(g_PrimaryBufferSurface, &win_rect, fill_color); } - if (flags & CLRB_THIRD_BUFFER) { - WinVidClearBuffer(g_ThirdBufferSurface, &win_rect, fill_color); + if (flags & CLRB_BACK_BUFFER) { + WinVidClearBuffer(g_BackBufferSurface, &win_rect, fill_color); } if (flags & CLRB_RENDER_BUFFER) { @@ -1487,178 +989,11 @@ void __cdecl ClearBuffers(DWORD flags, DWORD fill_color) win_rect.bottom = 480; WinVidClearBuffer(g_PictureBufferSurface, &win_rect, fill_color); } - - if (flags & CLRB_WINDOWED_PRIMARY_BUFFER) { - win_rect.left = g_GameWindowPositionX; - win_rect.top = g_GameWindowPositionY; - win_rect.right = g_GameWindowPositionX + g_GameWindowWidth; - win_rect.bottom = g_GameWindowPositionY + g_GameWindowHeight; - WinVidClearBuffer(g_PrimaryBufferSurface, &win_rect, fill_color); - } -} - -void __cdecl UpdateFrame(const bool need_run_message_loop, LPRECT rect) -{ - if (rect == NULL) { - rect = &g_GameVid_Rect; - } - - RestoreLostBuffers(); - if (g_SavedAppSettings.fullscreen) { - if (g_SavedAppSettings.render_mode == RM_SOFTWARE) { - IDirectDrawSurface_Blt( - g_BackBufferSurface, rect, g_RenderBufferSurface, rect, - DDBLT_WAIT, NULL); - } - IDirectDrawSurface_Flip(g_PrimaryBufferSurface, NULL, DDFLIP_WAIT); - } else { - RECT dst_rect; - dst_rect.left = g_GameWindowPositionX + rect->left; - dst_rect.top = g_GameWindowPositionY + rect->top; - dst_rect.bottom = g_GameWindowPositionY + rect->bottom; - dst_rect.right = g_GameWindowPositionX + rect->right; - LPDDS dst_surface = g_SavedAppSettings.render_mode == RM_SOFTWARE - ? g_RenderBufferSurface - : g_BackBufferSurface; - IDirectDrawSurface_Blt( - g_PrimaryBufferSurface, &dst_rect, dst_surface, rect, DDBLT_WAIT, - NULL); - } - - if (need_run_message_loop) { - WinVidSpinMessageLoop(false); - } -} - -void __cdecl WaitPrimaryBufferFlip(void) -{ - if (g_SavedAppSettings.flip_broken && g_SavedAppSettings.fullscreen) { - while (IDirectDrawSurface_GetFlipStatus( - g_PrimaryBufferSurface, DDGFS_ISFLIPDONE) - == DDERR_WASSTILLDRAWING) { } - } -} - -bool __cdecl RenderInit(void) -{ - return true; } void __cdecl RenderStart(const bool is_reset) { - if (is_reset) { - g_NeedToReloadTextures = false; - } - - if (g_SavedAppSettings.fullscreen) { - assert(g_SavedAppSettings.video_mode != NULL); - - DISPLAY_MODE disp_mode = g_SavedAppSettings.video_mode->body; - - const bool result = WinVidGoFullScreen(&disp_mode); - assert(result); - - CreateScreenBuffers(); - g_GameVid_Width = disp_mode.width; - g_GameVid_Height = disp_mode.height; - g_GameVid_BPP = disp_mode.bpp; - g_GameVid_BufWidth = disp_mode.width; - g_GameVid_BufHeight = disp_mode.height; - g_GameVid_IsVga = disp_mode.vga != VGA_NO_VGA; - g_GameVid_IsWindowedVGA = false; - g_GameVid_IsFullscreenVGA = disp_mode.vga == VGA_STANDARD; - } else { - int32_t min_width = 320; - int32_t min_height = CalculateWindowHeight(320, 200); - if (min_height < 200) { - min_width = CalculateWindowWidth(320, 200); - min_height = 200; - } - - WinVidSetMinWindowSize(min_width, min_height); - - DISPLAY_MODE disp_mode; - const bool result = WinVidGoWindowed( - g_SavedAppSettings.window_width, g_SavedAppSettings.window_height, - &disp_mode); - assert(result); - - g_GameVid_Width = disp_mode.width; - g_GameVid_Height = disp_mode.height; - g_GameVid_BPP = disp_mode.bpp; - - g_GameVid_BufWidth = (disp_mode.width + 0x1F) & ~0x1F; - g_GameVid_BufHeight = (disp_mode.height + 0x1F) & ~0x1F; - g_GameVid_IsVga = disp_mode.vga != 0; - g_GameVid_IsWindowedVGA = disp_mode.vga != VGA_NO_VGA; - g_GameVid_IsFullscreenVGA = false; - - CreatePrimarySurface(); - if (g_SavedAppSettings.render_mode == RM_HARDWARE) { - CreateBackBuffer(); - } - CreateClipper(); - } - - DDPIXELFORMAT pixel_format = { 0 }; - pixel_format.dwSize = sizeof(DDPIXELFORMAT); - const HRESULT result = IDirectDrawSurface_GetPixelFormat( - g_PrimaryBufferSurface, &pixel_format); - if (FAILED(result)) { - Shell_ExitSystem("GetPixelFormat() failed"); - } - - WinVidGetColorBitMasks(&g_ColorBitMasks, &pixel_format); - if (g_GameVid_IsVga) { - CreateWindowPalette(); - } - - if (g_SavedAppSettings.render_mode == RM_HARDWARE) { - if (g_SavedAppSettings.zbuffer) { - CreateZBuffer(); - } - D3DDeviceCreate(g_BackBufferSurface); - EnumerateTextureFormats(); - } else { - CreateRenderBuffer(); - if (g_PictureBufferSurface == NULL) { - CreatePictureBuffer(); - } - } - - if (g_NeedToReloadTextures) { - bool is_16bit_textures = g_TextureFormat.bpp >= 16; - if (g_IsWindowedVGA != g_GameVid_IsWindowedVGA - || g_Is16bitTextures != is_16bit_textures) { - S_ReloadLevelGraphics( - g_IsWindowedVGA != g_GameVid_IsWindowedVGA, - g_Is16bitTextures != is_16bit_textures); - g_IsWindowedVGA = g_GameVid_IsWindowedVGA; - g_Is16bitTextures = is_16bit_textures; - } else if (g_SavedAppSettings.render_mode == RM_HARDWARE) { - ReloadTextures(true); - HWR_GetPageHandles(); - } - } else { - g_IsWindowedVGA = g_GameVid_IsWindowedVGA; - g_Is16bitTextures = g_TextureFormat.bpp >= 16; - } - - g_GameVid_BufRect.left = 0; - g_GameVid_BufRect.top = 0; - g_GameVid_BufRect.right = g_GameVid_BufWidth; - g_GameVid_BufRect.bottom = g_GameVid_BufHeight; - - g_GameVid_Rect.left = 0; - g_GameVid_Rect.top = 0; - g_GameVid_Rect.right = g_GameVid_Width; - g_GameVid_Rect.bottom = g_GameVid_Height; - - g_DumpWidth = g_GameVid_Width; - g_DumpHeight = g_GameVid_Height; - - setup_screen_size(); - g_NeedToReloadTextures = true; + NewRenderer_Start(is_reset); } void __cdecl RenderFinish(bool need_to_clear_textures) @@ -1696,11 +1031,6 @@ void __cdecl RenderFinish(bool need_to_clear_textures) g_DDrawClipper = NULL; } - if (g_ThirdBufferSurface != NULL) { - IDirectDrawSurface_Release(g_ThirdBufferSurface); - g_ThirdBufferSurface = NULL; - } - if (g_BackBufferSurface != NULL) { IDirectDrawSurface_Release(g_BackBufferSurface); g_BackBufferSurface = NULL; @@ -1718,6 +1048,7 @@ void __cdecl RenderFinish(bool need_to_clear_textures) bool __cdecl ApplySettings(const APP_SETTINGS *const new_settings) { + LOG_DEBUG("!"); char mode_string[64] = { 0 }; APP_SETTINGS old_settings = g_SavedAppSettings; @@ -1730,20 +1061,14 @@ bool __cdecl ApplySettings(const APP_SETTINGS *const new_settings) S_InitialiseScreen(GFL_NO_LEVEL); if (g_SavedAppSettings.render_mode != old_settings.render_mode) { - S_ReloadLevelGraphics(1, 1); + S_ReloadLevelGraphics(true, true); } else if ( g_SavedAppSettings.render_mode == RM_SOFTWARE && g_SavedAppSettings.fullscreen != old_settings.fullscreen) { - S_ReloadLevelGraphics(1, 0); + S_ReloadLevelGraphics(true, false); } - if (g_SavedAppSettings.fullscreen) { - sprintf( - mode_string, "%dx%dx%d", g_GameVid_Width, g_GameVid_Height, - g_GameVid_BPP); - } else { - sprintf(mode_string, "%dx%d", g_GameVid_Width, g_GameVid_Height); - } + sprintf(mode_string, "%dx%d", g_GameVid_Width, g_GameVid_Height); Overlay_DisplayModeInfo(mode_string); return true; @@ -1751,6 +1076,7 @@ bool __cdecl ApplySettings(const APP_SETTINGS *const new_settings) void __cdecl GameApplySettings(APP_SETTINGS *const new_settings) { + LOG_DEBUG("!"); bool need_init_render_state = false; bool need_adjust_texel = false; bool need_rebuild_buffers = false; @@ -1765,11 +1091,12 @@ void __cdecl GameApplySettings(APP_SETTINGS *const new_settings) } if (new_settings->render_mode != g_SavedAppSettings.render_mode - || new_settings->video_mode != g_SavedAppSettings.video_mode + || (!new_settings->fullscreen + && (new_settings->window_width != g_SavedAppSettings.window_width + || new_settings->window_height + != g_SavedAppSettings.window_height)) || new_settings->fullscreen != g_SavedAppSettings.fullscreen - || new_settings->zbuffer != g_SavedAppSettings.zbuffer - || new_settings->triple_buffering - != g_SavedAppSettings.triple_buffering) { + || new_settings->zbuffer != g_SavedAppSettings.zbuffer) { ApplySettings(new_settings); S_AdjustTexelCoordinates(); return; @@ -1789,45 +1116,6 @@ void __cdecl GameApplySettings(APP_SETTINGS *const new_settings) need_adjust_texel = true; } - if (!new_settings->fullscreen) { - if (new_settings->window_width != g_SavedAppSettings.window_width - || new_settings->window_height - != g_SavedAppSettings.window_height) { - DISPLAY_MODE disp_mode; - if (!WinVidGoWindowed( - new_settings->window_width, new_settings->window_height, - &disp_mode)) { - return; - } - new_settings->window_width = disp_mode.width; - new_settings->window_height = disp_mode.height; - if (new_settings->window_width != g_SavedAppSettings.window_width - || new_settings->window_height - != g_SavedAppSettings.window_height) { - if (g_GameVid_BufWidth - new_settings->window_width < 0 - || g_GameVid_BufWidth - new_settings->window_width > 64 - || g_GameVid_BufHeight - new_settings->window_height < 0 - || g_GameVid_BufHeight - new_settings->window_height > 64) { - need_rebuild_buffers = true; - } else { - g_SavedAppSettings.window_width = - new_settings->window_width; - g_SavedAppSettings.window_height = - new_settings->window_height; - g_GameVid_Width = new_settings->window_width; - g_GameVid_Height = new_settings->window_height; - g_GameVid_Rect.right = new_settings->window_width; - g_GameVid_Rect.bottom = new_settings->window_height; - if (g_SavedAppSettings.render_mode == RM_HARDWARE) { - D3DSetViewport(); - } - setup_screen_size(); - g_WinVidNeedToResetBuffers = false; - } - } - } - } - if (need_init_render_state) { g_SavedAppSettings.perspective_correct = new_settings->perspective_correct; @@ -1961,6 +1249,7 @@ bool __cdecl D3DSetViewport(void) void __cdecl D3DDeviceCreate(LPDDS lpBackBuffer) { + LOG_DEBUG("backbuffer: %p", lpBackBuffer); if (g_D3D == NULL && !D3DCreate()) { Shell_ExitSystem("Failed to create D3D"); } @@ -2032,6 +1321,7 @@ bool __cdecl Direct3DInit(void) bool __cdecl DDrawCreate(LPGUID lpGUID) { + LOG_DEBUG(""); if (FAILED(DirectDrawCreate(lpGUID, &g_DDrawInterface, 0))) { return false; } @@ -2061,150 +1351,10 @@ void __cdecl DDrawRelease(void) } } -void __cdecl GameWindowCalculateSizeFromClient( - int32_t *const width, int32_t *const height) -{ - RECT rect = { 0, 0, *width, *height }; - const DWORD style = GetWindowLong(g_GameWindowHandle, GWL_STYLE); - const DWORD style_ex = GetWindowLong(g_GameWindowHandle, GWL_EXSTYLE); - AdjustWindowRectEx(&rect, style, FALSE, style_ex); - *width = rect.right - rect.left; - *height = rect.bottom - rect.top; -} - -void __cdecl GameWindowCalculateSizeFromClientByZero( - int32_t *const width, int32_t *const height) -{ - RECT rect = { 0, 0, 0, 0 }; - const DWORD style = GetWindowLong(g_GameWindowHandle, GWL_STYLE); - const DWORD styleEx = GetWindowLong(g_GameWindowHandle, GWL_EXSTYLE); - AdjustWindowRectEx(&rect, style, FALSE, styleEx); - *width += rect.left - rect.right; - *height += rect.top - rect.bottom; -} - -bool __thiscall CompareVideoModes( - const DISPLAY_MODE *const mode1, const DISPLAY_MODE *const mode2) -{ - const int32_t square1 = mode1->width * mode1->height; - const int32_t square2 = mode2->width * mode2->height; - if (square1 < square2) { - return true; - } - if (square1 > square2) { - return false; - } - if (mode1->bpp < mode2->bpp) { - return true; - } - if (mode1->bpp > mode2->bpp) { - return false; - } - if (mode1->vga < mode2->vga) { - return true; - } - if (mode1->vga > mode2->vga) { - return false; - } - return false; -} - -bool __cdecl WinVidGetDisplayModes(void) -{ - for (DISPLAY_ADAPTER_NODE *adapter = g_DisplayAdapterList.head; adapter; - adapter = adapter->next) { - DDrawCreate(adapter->body.adapter_guid_ptr); - ShowDDrawGameWindow(false); - g_DDraw->lpVtbl->EnumDisplayModes( - g_DDraw, DDEDM_STANDARDVGAMODES, NULL, (LPVOID)&adapter->body, - EnumDisplayModesCallback); - HideDDrawGameWindow(); - DDrawRelease(); - } - return true; -} - -HRESULT __stdcall EnumDisplayModesCallback( - LPDDSDESC lpDDSurfaceDesc, LPVOID lpContext) -{ - DISPLAY_ADAPTER *adapter = (DISPLAY_ADAPTER *)lpContext; - VGA_MODE vga_mode = VGA_NO_VGA; - bool sw_renderer_supported = false; - - if (!(lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT) - || !(lpDDSurfaceDesc->dwFlags & DDSD_WIDTH) - || !(lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) - || !(lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_RGB)) { - return DDENUMRET_OK; - } - - if ((lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) != 0 - && lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount == 8) { - if (lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_MODEX) { - vga_mode = VGA_MODEX; - } else if (lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_STANDARDVGAMODE) { - vga_mode = VGA_STANDARD; - } else { - vga_mode = VGA_256_COLOR; - } - - if (lpDDSurfaceDesc->dwWidth == 320 && lpDDSurfaceDesc->dwHeight == 200 - && (!adapter->is_vga_mode1_presented - || vga_mode < adapter->vga_mode1.vga)) { - adapter->vga_mode1.width = 320; - adapter->vga_mode1.height = 200; - adapter->vga_mode1.bpp = 8; - adapter->vga_mode1.vga = vga_mode; - adapter->is_vga_mode1_presented = true; - } - - if (lpDDSurfaceDesc->dwWidth == 640 && lpDDSurfaceDesc->dwHeight == 480 - && (!adapter->is_vga_mode2_presented - || vga_mode < adapter->vga_mode2.vga)) { - adapter->vga_mode2.width = 640; - adapter->vga_mode2.height = 480; - adapter->vga_mode2.bpp = 8; - adapter->vga_mode2.vga = vga_mode; - adapter->is_vga_mode2_presented = true; - } - sw_renderer_supported = true; - } - - DISPLAY_MODE video_mode = { - .width = lpDDSurfaceDesc->dwWidth, - .height = lpDDSurfaceDesc->dwHeight, - .bpp = lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount, - .vga = vga_mode, - }; - - int32_t render_bit_depth = - GetRenderBitDepth(lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount); - - if (adapter->hw_render_supported - && (render_bit_depth & adapter->hw_device_desc.dwDeviceRenderBitDepth) - != 0) { - M_InsertDisplayModeInListSorted( - &adapter->hw_disp_mode_list, &video_mode); - } - - if (sw_renderer_supported) { - M_InsertDisplayModeInListSorted( - &adapter->sw_disp_mode_list, &video_mode); - } - - return DDENUMRET_OK; -} - bool __cdecl WinVidInit(void) { g_AppResultCode = 0; - // clang-format off - return WinVidRegisterGameWindowClass() - && WinVidCreateGameWindow() - && WinVidGetDisplayAdapters() - && g_DisplayAdapterList.count - && WinVidGetDisplayModes(); - // clang-format on + return WinVidGetDisplayAdapters() && g_DisplayAdapterList.count; } bool __cdecl WinVidGetDisplayAdapters(void) @@ -2311,288 +1461,6 @@ BOOL WINAPI EnumDisplayAdaptersCallback( return TRUE; } -bool __cdecl WinVidRegisterGameWindowClass(void) -{ - WNDCLASSEXA wnd_class = { - .cbSize = sizeof(WNDCLASSEXA), - .style = 0, - .lpfnWndProc = WinVidGameWindowProc, - .hInstance = g_GameModule, - .hIcon = LoadIcon(g_GameModule, MAKEINTRESOURCE(IDI_MAINICON)), - .hCursor = LoadCursor(NULL, IDC_ARROW), - .lpszClassName = g_GameClassName, - 0, - }; - return RegisterClassExA(&wnd_class) != 0; -} - -LRESULT CALLBACK -WinVidGameWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - if (g_IsFMVPlaying) { - switch (Msg) { - case WM_DESTROY: - g_IsGameWindowCreated = false; - g_GameWindowHandle = NULL; - PostQuitMessage(0); - break; - - case WM_MOVE: - g_GameWindowPositionX = LOWORD(lParam); - g_GameWindowPositionY = HIWORD(lParam); - break; - - case WM_ACTIVATEAPP: - g_IsGameWindowActive = wParam != 0; - break; - - case WM_SYSCOMMAND: - if (wParam == SC_KEYMENU) { - return 0; - } - break; - } - return DefWindowProc(hWnd, Msg, wParam, lParam); - } - - switch (Msg) { - case WM_CREATE: - g_IsGameWindowCreated = true; - break; - - case WM_DESTROY: - g_IsGameWindowCreated = false; - g_GameWindowHandle = NULL; - PostQuitMessage(0); - break; - - case WM_MOVE: - g_GameWindowPositionX = LOWORD(lParam); - g_GameWindowPositionY = HIWORD(lParam); - break; - - case WM_SIZE: - switch (wParam) { - case SIZE_RESTORED: - g_IsGameWindowMinimized = false; - g_IsGameWindowMaximized = false; - break; - - case SIZE_MAXIMIZED: - g_IsGameWindowMinimized = false; - g_IsGameWindowMaximized = true; - break; - - case SIZE_MINIMIZED: - g_IsGameWindowMinimized = true; - g_IsGameWindowMaximized = false; - return DefWindowProc(hWnd, Msg, wParam, lParam); - - default: - return DefWindowProc(hWnd, Msg, wParam, lParam); - } - - if (g_IsGameFullScreen - || (LOWORD(lParam) == g_GameWindowWidth - && HIWORD(lParam) == g_GameWindowHeight)) { - break; - } - - g_GameWindowWidth = LOWORD(lParam); - g_GameWindowHeight = HIWORD(lParam); - if (g_IsGameWindowUpdating) { - break; - } - - UpdateGameResolution(); - break; - - case WM_PAINT: { - PAINTSTRUCT paint; - HDC hdc = BeginPaint(hWnd, &paint); - LPDDS surface = (g_SavedAppSettings.render_mode == RM_SOFTWARE) - ? g_RenderBufferSurface - : g_BackBufferSurface; - if (g_IsGameFullScreen || !g_PrimaryBufferSurface || !surface) { - HBRUSH brush = (HBRUSH)GetStockObject(BLACK_BRUSH); - FillRect(hdc, &paint.rcPaint, brush); - } else { - if (g_SavedAppSettings.render_mode == RM_SOFTWARE - && !WinVidCheckGameWindowPalette(hWnd) - && g_RenderBufferSurface) { - WinVidClearBuffer(g_RenderBufferSurface, NULL, 0); - } - UpdateFrame(false, NULL); - } - EndPaint(hWnd, &paint); - return 0; - } - - case WM_ACTIVATE: - if (LOWORD(wParam) && g_DDrawPalette != NULL - && g_PrimaryBufferSurface != NULL) { - g_PrimaryBufferSurface->lpVtbl->SetPalette( - g_PrimaryBufferSurface, g_DDrawPalette); - } - break; - - case WM_ERASEBKGND: - return 1; - - case WM_ACTIVATEAPP: - if (wParam && !g_IsGameWindowActive && g_IsGameFullScreen - && g_SavedAppSettings.render_mode == RM_HARDWARE) { - g_WinVidNeedToResetBuffers = true; - } - g_IsGameWindowActive = (wParam != 0); - break; - - case WM_SETCURSOR: - if (g_IsGameFullScreen) { - SetCursor(NULL); - return 1; - } - break; - - case WM_GETMINMAXINFO: - if (WinVidGetMinMaxInfo((LPMINMAXINFO)lParam)) { - return 0; - } - break; - - case WM_NCPAINT: - case WM_NCLBUTTONDOWN: - case WM_NCLBUTTONDBLCLK: - case WM_NCRBUTTONDOWN: - case WM_NCRBUTTONDBLCLK: - case WM_NCMBUTTONDOWN: - case WM_NCMBUTTONDBLCLK: - if (g_IsGameFullScreen) { - return 0; - } - break; - - case WM_SYSCOMMAND: - if (wParam == SC_KEYMENU) { - return 0; - } - break; - - case WM_SIZING: - WinVidResizeGameWindow(hWnd, wParam, (LPRECT)lParam); - break; - - case WM_MOVING: - if (g_IsGameFullScreen || g_IsGameWindowMaximized) { - GetWindowRect(hWnd, (LPRECT)lParam); - return 1; - } - break; - - case WM_ENTERSIZEMOVE: - g_IsGameWindowChanging = true; - break; - - case WM_EXITSIZEMOVE: - g_IsGameWindowChanging = false; - break; - - case WM_PALETTECHANGED: - if (hWnd != (HWND)wParam && !g_IsGameFullScreen && g_DDrawPalette) { - InvalidateRect(hWnd, NULL, FALSE); - } - break; - } - - return DefWindowProc(hWnd, Msg, wParam, lParam); -} - -void __cdecl WinVidResizeGameWindow(HWND hWnd, int32_t edge, LPRECT rect) -{ - if (g_IsGameFullScreen) { - rect->left = 0; - rect->top = 0; - rect->right = g_FullScreenWidth; - rect->bottom = g_FullScreenHeight; - } - - const bool is_shift_pressed = GetAsyncKeyState(VK_SHIFT) < 0; - int32_t width = rect->right - rect->left; - int32_t height = rect->bottom - rect->top; - GameWindowCalculateSizeFromClientByZero(&width, &height); - - if (edge == WMSZ_TOP || edge == WMSZ_BOTTOM) { - if (is_shift_pressed) { - height &= ~0x1F; - } - width = CalculateWindowWidth(width, height); - } else { - if (is_shift_pressed) { - width &= ~0x1F; - } - height = CalculateWindowHeight(width, height); - } - - if (g_IsMinWindowSizeSet) { - CLAMPL(width, g_MinWindowClientWidth); - CLAMPL(height, g_MinWindowClientHeight); - } - - if (g_IsMaxWindowSizeSet) { - CLAMPG(width, g_MaxWindowClientWidth); - CLAMPG(height, g_MaxWindowClientHeight); - } - - GameWindowCalculateSizeFromClient(&width, &height); - - switch (edge) { - case WMSZ_TOPLEFT: - rect->left = rect->right - width; - rect->top = rect->bottom - height; - break; - - case WMSZ_RIGHT: - case WMSZ_BOTTOM: - case WMSZ_BOTTOMRIGHT: - rect->right = rect->left + width; - rect->bottom = rect->top + height; - break; - - case WMSZ_LEFT: - case WMSZ_BOTTOMLEFT: - rect->left = rect->right - width; - rect->bottom = rect->top + height; - break; - - case WMSZ_TOP: - case WMSZ_TOPRIGHT: - rect->right = rect->left + width; - rect->top = rect->bottom - height; - break; - } -} - -bool __cdecl WinVidCheckGameWindowPalette(HWND hWnd) -{ - const HDC hdc = GetDC(hWnd); - if (hdc == NULL) { - return false; - } - - PALETTEENTRY sys_palette[256]; - GetSystemPaletteEntries(hdc, 0, 256, sys_palette); - ReleaseDC(hWnd, hdc); - - RGB_888 buf_palette[256]; - for (int32_t i = 0; i < 256; i++) { - buf_palette[i].red = sys_palette[i].peRed; - buf_palette[i].green = sys_palette[i].peGreen; - buf_palette[i].blue = sys_palette[i].peBlue; - } - - return memcmp(buf_palette, g_GamePalette8, sizeof(buf_palette)) == 0; -} - bool __cdecl WinVidCreateGameWindow(void) { g_IsGameWindowActive = true; @@ -2607,17 +1475,6 @@ bool __cdecl WinVidCreateGameWindow(void) g_IsMinMaxInfoSpecial = false; g_IsGameWindowChanging = false; - WinVidClearMinWindowSize(); - WinVidClearMaxWindowSize(); - - g_GameWindowHandle = CreateWindowEx( - WS_EX_APPWINDOW, g_GameClassName, g_GameWindowName, WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, - g_GameModule, NULL); - if (g_GameWindowHandle == NULL) { - return false; - } - int32_t result = SDL_Init(SDL_INIT_EVENTS | SDL_INIT_VIDEO); if (result < 0) { Shell_ExitSystemFmt( @@ -2625,51 +1482,33 @@ bool __cdecl WinVidCreateGameWindow(void) return false; } - SDL_Window *sdl_window = SDL_CreateWindowFrom(g_GameWindowHandle); - if (sdl_window == NULL) { + LOG_DEBUG( + "%d x %d", g_SavedAppSettings.window_width, + g_SavedAppSettings.window_height); + g_SDLWindow = SDL_CreateWindow( + "TR2X", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + g_SavedAppSettings.window_width, g_SavedAppSettings.window_height, + SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL); + + if (g_SDLWindow == NULL) { Shell_ExitSystemFmt("Failed to create SDL window: %s", SDL_GetError()); return false; } - RECT rect; - GetWindowRect(g_GameWindowHandle, &rect); - g_GameWindowX = rect.left; - g_GameWindowY = rect.top; - - WinVidHideGameWindow(); + GFX_Context_SetDisplaySize(1280, 720); + GFX_Context_SetWindowSize(1280, 720); + GFX_Context_Attach(g_SDLWindow, GFX_GL_21); + GFX_Context_SetRenderingMode(GFX_RM_FRAMEBUFFER); return true; } -void __cdecl WinVidFreeWindow(void) -{ - WinVidExitMessage(); - UnregisterClassA(g_GameClassName, g_GameModule); -} - void __cdecl WinVidExitMessage(void) { - if (g_GameWindowHandle == NULL || !IsWindow(g_GameWindowHandle)) { - return; - } - - PostMessage(g_GameWindowHandle, WM_CLOSE, 0, 0); - while (WinVidSpinMessageLoop(false)) { } - g_GameWindowHandle = NULL; -} - -DISPLAY_ADAPTER_NODE *__cdecl WinVidGetDisplayAdapter(const GUID *guid_ptr) -{ - if (guid_ptr != NULL) { - for (DISPLAY_ADAPTER_NODE *adapter = g_DisplayAdapterList.head; - adapter != NULL; adapter = adapter->next) { - if (memcmp(&adapter->body.adapter_guid, guid_ptr, sizeof(GUID)) - == 0) { - return adapter; - } - } + if (g_SDLWindow != NULL) { + SDL_DestroyWindow(g_SDLWindow); + g_SDLWindow = NULL; } - return g_PrimaryDisplayAdapter; } void __cdecl WinVidStart(void) @@ -2704,9 +1543,6 @@ void __cdecl WinVidStart(void) void __cdecl WinVidFinish(void) { - if (g_IsDDrawGameWindowShow) { - HideDDrawGameWindow(); - } DDrawRelease(); } @@ -2874,7 +1710,6 @@ void __cdecl DisplayCredits(void) return; } - g_IsVidModeLock = true; RGB_888 old_palette[256]; memcpy(old_palette, g_GamePalette8, sizeof(RGB_888) * 256); memset(g_GamePalette8, 0, sizeof(RGB_888) * 256); @@ -2908,13 +1743,12 @@ void __cdecl DisplayCredits(void) memcpy(g_GamePalette8, old_palette, sizeof(g_GamePalette8)); S_Wait(300, true); FadeToPal(30, g_GamePalette8); - g_IsVidModeLock = false; } DWORD __cdecl S_DumpScreen(void) { const int32_t passed = Clock_WaitTick(); - ScreenPartialDump(); + NewRenderer_UpdateFrame(); return passed; } @@ -2934,24 +1768,13 @@ void __cdecl S_InitialisePolyList(bool clear_back_buffer) if (g_WinVidNeedToResetBuffers) { RestoreLostBuffers(); - WinVidSpinMessageLoop(0); + Shell_ProcessEvents(); - if (g_SavedAppSettings.fullscreen) { - clear_buffer_flags = CLRB_BACK_BUFFER | CLRB_PRIMARY_BUFFER; - if (g_SavedAppSettings.render_mode == RM_SOFTWARE) { - clear_buffer_flags |= CLRB_RENDER_BUFFER; - } - if (g_SavedAppSettings.triple_buffering) { - clear_buffer_flags |= CLRB_THIRD_BUFFER; - } - WaitPrimaryBufferFlip(); + clear_buffer_flags = CLRB_WINDOWED_PRIMARY_BUFFER; + if (g_SavedAppSettings.render_mode == RM_HARDWARE) { + clear_buffer_flags |= CLRB_BACK_BUFFER; } else { - clear_buffer_flags = CLRB_WINDOWED_PRIMARY_BUFFER; - if (g_SavedAppSettings.render_mode == RM_HARDWARE) { - clear_buffer_flags |= CLRB_BACK_BUFFER; - } else { - clear_buffer_flags |= CLRB_RENDER_BUFFER; - } + clear_buffer_flags |= CLRB_RENDER_BUFFER; } ClearBuffers(clear_buffer_flags, 0); clear_back_buffer = 0; @@ -2987,9 +1810,6 @@ void __cdecl S_InitialiseScreen(const GAMEFLOW_LEVEL_TYPE level_type) if (level_type < 0) { FadeToPal(0, g_GamePalette8); } else { - if (level_type != GFL_TITLE) { - TempVideoRemove(); - } FadeToPal(FRAMES_PER_SECOND, g_GamePalette8); } @@ -3065,9 +1885,6 @@ void __cdecl S_DrawScreenFBox( void __cdecl S_FinishInventory(void) { - if (g_Inv_Mode != INV_TITLE_MODE) { - TempVideoRemove(); - } } void __cdecl S_FadeToBlack(void) @@ -3075,9 +1892,7 @@ void __cdecl S_FadeToBlack(void) memset(g_GamePalette8, 0, sizeof(g_GamePalette8)); FadeToPal(10, g_GamePalette8); ScreenClear(false); - ScreenDump(); - ScreenClear(false); - ScreenDump(); + NewRenderer_UpdateFrame(); } uint16_t __cdecl S_FindColor( @@ -3089,12 +1904,13 @@ uint16_t __cdecl S_FindColor( void __cdecl S_CopyBufferToScreen(void) { if (g_SavedAppSettings.render_mode == RM_SOFTWARE) { - if (memcmp(g_GamePalette8, g_PicturePalette, 256 * 100) != 0) { + if (memcmp(g_GamePalette8, g_PicturePalette, 256 * sizeof(RGB_888)) + != 0) { S_SyncPictureBufferPalette(); } g_RenderBufferSurface->lpVtbl->Blt( - g_RenderBufferSurface, &g_GameVid_Rect, g_PictureBufferSurface, - NULL, DDBLT_WAIT, NULL); + g_RenderBufferSurface, NULL, g_PictureBufferSurface, NULL, + DDBLT_WAIT, NULL); } else if (g_BGND_PictureIsReady) { BGND_GetPageHandles(); HWR_EnableZBuffer(false, false); @@ -3112,22 +1928,22 @@ void __cdecl S_CopyBufferToScreen(void) y[i] = g_PhdWinMinY + tile_y[i] * g_PhdWinHeight / 480; } - DrawTextureTile( + BGND_DrawTextureTile( x[0], y[0], x[1] - x[0], y[1] - y[0], g_BGND_PageHandles[0], 0, 0, 256, 256, color, color, color, color); - DrawTextureTile( + BGND_DrawTextureTile( x[1], y[0], x[2] - x[1], y[1] - y[0], g_BGND_PageHandles[1], 0, 0, 256, 256, color, color, color, color); - DrawTextureTile( + BGND_DrawTextureTile( x[2], y[0], x[3] - x[2], y[1] - y[0], g_BGND_PageHandles[2], 0, 0, 128, 256, color, color, color, color); - DrawTextureTile( + BGND_DrawTextureTile( x[0], y[1], x[1] - x[0], y[2] - y[1], g_BGND_PageHandles[3], 0, 0, 256, 224, color, color, color, color); - DrawTextureTile( + BGND_DrawTextureTile( x[1], y[1], x[2] - x[1], y[2] - y[1], g_BGND_PageHandles[4], 0, 0, 256, 224, color, color, color, color); - DrawTextureTile( + BGND_DrawTextureTile( x[2], y[1], x[3] - x[2], y[2] - y[1], g_BGND_PageHandles[2], 128, 0, 128, 224, color, color, color, color); HWR_EnableZBuffer(true, true); @@ -3162,20 +1978,10 @@ void __cdecl DecreaseScreenSize(void) void __cdecl TempVideoAdjust(const int32_t hires, const double sizer) { - g_IsVidSizeLock = true; - if (sizer != g_GameSizer) { - g_GameSizer = sizer; - setup_screen_size(); - } } void __cdecl TempVideoRemove(void) { - g_IsVidSizeLock = false; - if (g_GameSizer != g_GameSizerCopy) { - g_GameSizer = g_GameSizerCopy; - setup_screen_size(); - } } void __cdecl setup_screen_size(void) diff --git a/src/tr2/decomp/decomp.h b/src/tr2/decomp/decomp.h index cd6f3f038..175e9d29a 100644 --- a/src/tr2/decomp/decomp.h +++ b/src/tr2/decomp/decomp.h @@ -21,20 +21,10 @@ void __cdecl DInputRelease(void); void __cdecl WinInReadKeyboard(uint8_t *input_data); int32_t __cdecl WinGameStart(void); int16_t __cdecl TitleSequence(void); -void __cdecl WinVidSetMinWindowSize(int32_t width, int32_t height); -void __cdecl WinVidSetMaxWindowSize(int32_t width, int32_t height); -void __cdecl WinVidClearMinWindowSize(void); -void __cdecl WinVidClearMaxWindowSize(void); int32_t __cdecl CalculateWindowWidth(int32_t width, int32_t height); int32_t __cdecl CalculateWindowHeight(int32_t width, int32_t height); -bool __cdecl WinVidGetMinMaxInfo(LPMINMAXINFO info); HWND __cdecl WinVidFindGameWindow(void); -bool __cdecl WinVidSpinMessageLoop(bool need_wait); -void __cdecl WinVidShowGameWindow(int32_t cmd_show); void __cdecl WinVidHideGameWindow(void); -void __cdecl WinVidSetGameWindowSize(int32_t width, int32_t height); -bool __cdecl ShowDDrawGameWindow(bool active); -bool __cdecl HideDDrawGameWindow(void); HRESULT __cdecl DDrawSurfaceCreate(LPDDSDESC dsp, LPDDS *surface); HRESULT __cdecl DDrawSurfaceRestoreLost( LPDDS surface1, LPDDS surface2, bool blank); @@ -50,11 +40,6 @@ void __cdecl BitMaskGetNumberOfBits( DWORD __cdecl CalculateCompatibleColor( const COLOR_BIT_MASKS *mask, int32_t red, int32_t green, int32_t blue, int32_t alpha); -bool __cdecl WinVidGetDisplayMode(DISPLAY_MODE *disp_mode); -bool __cdecl WinVidGoFullScreen(DISPLAY_MODE *disp_mode); -bool __cdecl WinVidGoWindowed( - int32_t width, int32_t height, DISPLAY_MODE *disp_mode); -void __cdecl WinVidSetDisplayAdapter(DISPLAY_ADAPTER *disp_adapter); void __cdecl Game_SetCutsceneTrack(int32_t track); int32_t __cdecl Game_Cutscene_Start(int32_t level_num); void __cdecl Misc_InitCinematicRooms(void); @@ -65,19 +50,14 @@ void __cdecl CutscenePlayer1_Initialise(int16_t item_num); void __cdecl CutscenePlayerGen_Initialise(int16_t item_num); int32_t __cdecl Level_Initialise( int32_t level_num, GAMEFLOW_LEVEL_TYPE level_type); -void __cdecl CreateScreenBuffers(void); -void __cdecl CreatePrimarySurface(void); void __cdecl CreateBackBuffer(void); -void __cdecl CreateClipper(void); void __cdecl CreateWindowPalette(void); void __cdecl CreateZBuffer(void); int32_t __cdecl GetZBufferDepth(void); void __cdecl CreateRenderBuffer(void); void __cdecl CreatePictureBuffer(void); void __cdecl ClearBuffers(DWORD flags, DWORD fill_color); -void __cdecl UpdateFrame(bool need_run_message_loop, LPRECT rect); void __cdecl RestoreLostBuffers(void); -void __cdecl WaitPrimaryBufferFlip(void); bool __cdecl RenderInit(void); void __cdecl RenderStart(bool is_reset); void __cdecl RenderFinish(bool need_to_clear_textures); @@ -98,14 +78,6 @@ void __cdecl Direct3DRelease(void); bool __cdecl Direct3DInit(void); bool __cdecl DDrawCreate(LPGUID lpGUID); void __cdecl DDrawRelease(void); -void __cdecl GameWindowCalculateSizeFromClient(int32_t *width, int32_t *height); -void __cdecl GameWindowCalculateSizeFromClientByZero( - int32_t *width, int32_t *height); -bool __thiscall CompareVideoModes( - const DISPLAY_MODE *mode1, const DISPLAY_MODE *mode2); -bool __cdecl WinVidGetDisplayModes(void); -HRESULT __stdcall EnumDisplayModesCallback( - LPDDSDESC lpDDSurfaceDesc, LPVOID lpContext); bool __cdecl WinVidInit(void); bool __cdecl WinVidGetDisplayAdapters(void); bool __cdecl EnumerateDisplayAdapters( @@ -200,8 +172,6 @@ void __cdecl CleanupTextures(void); bool __cdecl InitTextures(void); void __cdecl S_SyncPictureBufferPalette(void); void __cdecl S_DontDisplayPicture(void); -void __cdecl ScreenDump(void); -void __cdecl ScreenPartialDump(void); void __cdecl FadeToPal(int32_t fade_value, const RGB_888 *palette); void __cdecl ScreenClear(bool is_phd_win_size); void __cdecl S_CopyScreenToBuffer(void); diff --git a/src/tr2/decomp/decomp2.c b/src/tr2/decomp/decomp2.c index 69162b403..fbf3ce497 100644 --- a/src/tr2/decomp/decomp2.c +++ b/src/tr2/decomp/decomp2.c @@ -415,62 +415,29 @@ void __cdecl S_DontDisplayPicture(void) } } -void __cdecl ScreenDump(void) -{ - UpdateFrame(true, NULL); -} - -void __cdecl ScreenPartialDump(void) -{ - UpdateFrame(true, &g_PhdWinRect); -} - void __cdecl FadeToPal(const int32_t fade_value, const RGB_888 *const palette) { - if (!g_GameVid_IsVga) { - return; - } - - int32_t start_idx; - int32_t end_idx; - if (g_GameVid_IsWindowedVGA) { - start_idx = 10; - end_idx = 246; - } else { - start_idx = 0; - end_idx = 256; - } - const int32_t pal_size = end_idx - start_idx; - if (fade_value <= 1) { - for (int32_t i = start_idx; i < end_idx; i++) { - g_WinVid_Palette[i].peRed = palette[i].red; - g_WinVid_Palette[i].peGreen = palette[i].green; - g_WinVid_Palette[i].peBlue = palette[i].blue; + for (int32_t i = 0; i < 256; i++) { + g_SDLPalette[i].r = palette[i].r; + g_SDLPalette[i].g = palette[i].g; + g_SDLPalette[i].b = palette[i].b; } - g_DDrawPalette->lpVtbl->SetEntries( - g_DDrawPalette, 0, start_idx, pal_size, - &g_WinVid_Palette[start_idx]); return; } - PALETTEENTRY fade_pal[256]; - for (int32_t i = start_idx; i < end_idx; i++) { - fade_pal[i] = g_WinVid_Palette[i]; - } + GFX_PALETTE_ENTRY fade_pal[256]; + memcpy(fade_pal, g_SDLPalette, sizeof(GFX_PALETTE_ENTRY) * 256); for (int32_t j = 0; j <= fade_value; j++) { - for (int32_t i = start_idx; i < end_idx; i++) { - g_WinVid_Palette[i].peRed = fade_pal[i].peRed - + (palette[i].red - fade_pal[i].peRed) * j / fade_value; - g_WinVid_Palette[i].peGreen = fade_pal[i].peGreen - + (palette[i].green - fade_pal[i].peGreen) * j / fade_value; - g_WinVid_Palette[i].peBlue = fade_pal[i].peBlue - + (palette[i].blue - fade_pal[i].peBlue) * j / fade_value; + for (int32_t i = 0; i < 256; i++) { + const GFX_PALETTE_ENTRY *const c1 = &fade_pal[i]; + const RGB_888 *const c2 = &palette[i]; + GFX_PALETTE_ENTRY *const dst = &g_SDLPalette[i]; + dst->r = c1->r + (c2->r - c1->r) * j / fade_value; + dst->g = c1->g + (c2->g - c1->g) * j / fade_value; + dst->b = c1->b + (c2->b - c1->b) * j / fade_value; } - g_DDrawPalette->lpVtbl->SetEntries( - g_DDrawPalette, 0, start_idx, pal_size, - &g_WinVid_Palette[start_idx]); S_DumpScreen(); } } @@ -495,8 +462,8 @@ void __cdecl S_CopyScreenToBuffer(void) } g_PictureBufferSurface->lpVtbl->Blt( - g_PictureBufferSurface, NULL, g_RenderBufferSurface, &g_GameVid_Rect, - DDBLT_WAIT, NULL); + g_PictureBufferSurface, NULL, g_RenderBufferSurface, NULL, DDBLT_WAIT, + NULL); DDSURFACEDESC desc; if (SUCCEEDED(WinVidBufferLock( diff --git a/src/tr2/decomp/fmv.c b/src/tr2/decomp/fmv.c index 98a6dd049..b294f39d3 100644 --- a/src/tr2/decomp/fmv.c +++ b/src/tr2/decomp/fmv.c @@ -363,7 +363,6 @@ void __cdecl WinPlayFMV(const char *const file_name, const bool is_playback) Video_PumpEvents(video); Shell_ProcessEvents(); - WinVidSpinMessageLoop(false); Input_Update(); Shell_ProcessInput(); diff --git a/src/tr2/decomp/render_new.c b/src/tr2/decomp/render_new.c new file mode 100644 index 000000000..c22151b9a --- /dev/null +++ b/src/tr2/decomp/render_new.c @@ -0,0 +1,229 @@ +#include "decomp/decomp.h" +#include "game/hwr.h" +#include "game/shell.h" +#include "global/vars.h" + +#include +#include + +#include +#include +#include + +typedef struct { + struct { + int32_t x; + int32_t y; + int32_t width; + int32_t height; + int32_t pitch; + enum AVPixelFormat fmt; + } src, dst; +} M_BLIT_PARAMS; + +static M_BLIT_PARAMS m_LastBlit = { 0 }; +static struct SwsContext *m_SwsContext = NULL; + +static void M_ReinitialiseContext(const M_BLIT_PARAMS *new_blit); +static void M_DestroyContext(void); + +static void M_ReinitialiseContext(const M_BLIT_PARAMS *const new_blit) +{ + LOG_DEBUG("Reinitializing SWS context"); + M_DestroyContext(); + + m_LastBlit = *new_blit; + + m_SwsContext = sws_getContext( + new_blit->src.width, new_blit->src.height, new_blit->src.fmt, + new_blit->dst.width, new_blit->dst.height, new_blit->dst.fmt, SWS_POINT, + NULL, NULL, NULL); + + if (m_SwsContext == NULL) { + Shell_ExitSystemFmt( + "Failed to get SWS context (tried %d,%d@%dx%d -> %d,%d@%dx%d)", + new_blit->src.x, new_blit->src.y, new_blit->src.width, + new_blit->src.height, new_blit->dst.x, new_blit->dst.y, + new_blit->dst.width, new_blit->dst.height); + } +} + +static void M_DestroyContext(void) +{ + // TODO: use me + if (m_SwsContext != NULL) { + sws_freeContext(m_SwsContext); + m_SwsContext = NULL; + } +} + +static M_BLIT_PARAMS M_GetBlit(LPDDSURFACEDESC desc) +{ + M_BLIT_PARAMS blit = { + .src = { + .x = 0, + .y = 0, + .width = g_GameVid_BufWidth, + .height = g_GameVid_BufHeight, + .pitch = 0, + .fmt = AV_PIX_FMT_NONE, + }, + .dst = { + .x = 0, + .y = 0, + .width = GFX_Context_GetDisplayWidth(), + .height = GFX_Context_GetDisplayHeight(), + .pitch = g_SDLSurface->desc.pitch, + .fmt = AV_PIX_FMT_RGB24, + }, + }; + + if (desc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 + || g_SavedAppSettings.render_mode == RM_SOFTWARE) { + blit.src.fmt = AV_PIX_FMT_GRAY8; + blit.src.pitch = blit.src.width; + } else { + switch (desc->ddpfPixelFormat.dwRGBBitCount) { + case 16: + blit.src.fmt = desc->ddpfPixelFormat.dwRBitMask == 0xF800 + ? AV_PIX_FMT_RGB565 + : AV_PIX_FMT_BGR565; + break; + case 24: + blit.src.fmt = desc->ddpfPixelFormat.dwRBitMask == 255 + ? AV_PIX_FMT_RGB24 + : AV_PIX_FMT_BGR24; + break; + case 32: + blit.src.fmt = desc->ddpfPixelFormat.dwRBitMask == 255 + ? AV_PIX_FMT_RGB0 + : AV_PIX_FMT_BGR0; + break; + } + blit.src.pitch = desc->lPitch; + } + + return blit; +} + +void NewRenderer_UpdateFrame(void) +{ + if (g_SDLSurface == NULL || g_SDLRenderer2D == NULL) { + return; + } + + LPDDS src_surface = g_SavedAppSettings.render_mode == RM_SOFTWARE + ? g_RenderBufferSurface + : g_BackBufferSurface; + + DDSURFACEDESC desc; + HRESULT rc = + WinVidBufferLock(src_surface, &desc, DDLOCK_WRITEONLY | DDLOCK_WAIT); + if (FAILED(rc)) { + Shell_ExitSystemFmt("Failed to lock the render surface: %08x", rc); + } + + const M_BLIT_PARAMS blit = M_GetBlit(&desc); + if (memcmp(&m_LastBlit, &blit, sizeof(M_BLIT_PARAMS)) != 0) { + M_ReinitialiseContext(&blit); + } + + int src_linesize[4] = { blit.src.pitch, 0, 0, 0 }; + uint8_t *src_planes[4] = { desc.lpSurface, NULL, NULL, NULL }; + src_planes[0] += blit.src.y * src_linesize[0]; + src_planes[0] += av_image_get_linesize(blit.src.fmt, blit.src.x, 0); + + int dst_linesize[4] = { blit.dst.pitch, 0, 0, 0 }; + uint8_t *dst_planes[4] = { g_SDLSurface->buffer, NULL, NULL, NULL }; + dst_planes[0] += blit.dst.y * dst_linesize[0]; + dst_planes[0] += av_image_get_linesize(blit.dst.fmt, blit.dst.x, 0); + + sws_scale( + m_SwsContext, (const uint8_t *const *)src_planes, src_linesize, 0, + blit.src.height, (uint8_t *const *)dst_planes, dst_linesize); + + rc = src_surface->lpVtbl->Unlock(src_surface, desc.lpSurface); + if (FAILED(rc)) { + Shell_ExitSystemFmt("Failed to unlock the render surface: %08x", rc); + } + + GFX_2D_Renderer_SetPalette( + g_SDLRenderer2D, + g_SavedAppSettings.render_mode == RM_SOFTWARE ? g_SDLPalette : NULL); + GFX_2D_Renderer_Upload( + g_SDLRenderer2D, &g_SDLSurface->desc, g_SDLSurface->buffer); + GFX_2D_Renderer_Render(g_SDLRenderer2D); + + GFX_Context_SwapBuffers(); +} + +void NewRenderer_Start(bool is_reset) +{ + if (is_reset) { + g_NeedToReloadTextures = false; + } + + if (g_SavedAppSettings.fullscreen) { + Shell_GoFullscreen(); + g_GameVid_Width = Shell_GetCurrentDisplayWidth(); + g_GameVid_Height = Shell_GetCurrentDisplayHeight(); + g_GameVid_BufWidth = g_GameVid_Width; + g_GameVid_BufHeight = g_GameVid_Height; + } else { + int32_t min_width = 320; + int32_t min_height = CalculateWindowHeight(320, 200); + if (min_height < 200) { + min_width = CalculateWindowWidth(320, 200); + min_height = 200; + } + + Shell_GoWindowed( + g_SavedAppSettings.window_width, g_SavedAppSettings.window_height); + + g_GameVid_Width = g_GameWindowWidth; + g_GameVid_Height = g_GameWindowHeight; + g_GameVid_BufWidth = ALIGN(g_GameVid_Width, 32); + g_GameVid_BufHeight = ALIGN(g_GameVid_Height, 32); + } + + CreateWindowPalette(); + + if (g_SavedAppSettings.render_mode == RM_HARDWARE) { + CreateBackBuffer(); + if (g_SavedAppSettings.zbuffer) { + CreateZBuffer(); + } + D3DDeviceCreate(g_BackBufferSurface); + EnumerateTextureFormats(); + } else { + CreateRenderBuffer(); + if (g_PictureBufferSurface == NULL) { + CreatePictureBuffer(); + } + } + + if (g_NeedToReloadTextures) { + if (g_SavedAppSettings.render_mode == RM_SOFTWARE) { + S_ReloadLevelGraphics(true, true); + } else if (g_SavedAppSettings.render_mode == RM_HARDWARE) { + ReloadTextures(true); + HWR_GetPageHandles(); + } + } + + g_GameVid_BufRect.left = 0; + g_GameVid_BufRect.top = 0; + g_GameVid_BufRect.right = g_GameVid_BufWidth; + g_GameVid_BufRect.bottom = g_GameVid_BufHeight; + + g_GameVid_Rect.left = 0; + g_GameVid_Rect.top = 0; + g_GameVid_Rect.right = g_GameVid_Width; + g_GameVid_Rect.bottom = g_GameVid_Height; + + g_DumpWidth = g_GameVid_Width; + g_DumpHeight = g_GameVid_Height; + + setup_screen_size(); + g_NeedToReloadTextures = true; +} diff --git a/src/tr2/decomp/render_new.h b/src/tr2/decomp/render_new.h new file mode 100644 index 000000000..87c342578 --- /dev/null +++ b/src/tr2/decomp/render_new.h @@ -0,0 +1,6 @@ +#pragma once + +#include + +void NewRenderer_UpdateFrame(void); +void NewRenderer_Start(bool is_reset); diff --git a/src/tr2/decomp/stats.c b/src/tr2/decomp/stats.c index 278937711..a8c2d9a2d 100644 --- a/src/tr2/decomp/stats.c +++ b/src/tr2/decomp/stats.c @@ -316,7 +316,6 @@ int32_t __cdecl LevelStats(const int32_t level_num) Music_Play(g_GameFlow.level_complete_track, MPM_ALWAYS); - TempVideoAdjust(g_HiRes, 1.0); FadeToPal(30, g_GamePalette8); Overlay_HideGameInfo(); S_CopyScreenToBuffer(); @@ -354,7 +353,6 @@ int32_t __cdecl LevelStats(const int32_t level_num) g_SaveGame.current_level = level_num + 1; start->available = 0; S_FadeToBlack(); - TempVideoRemove(); return 0; } diff --git a/src/tr2/game/background.c b/src/tr2/game/background.c index e617ae67f..4b7283e25 100644 --- a/src/tr2/game/background.c +++ b/src/tr2/game/background.c @@ -88,13 +88,13 @@ void __cdecl BGND_GetPageHandles(void) void __cdecl BGND_DrawInGameBlack(void) { HWR_EnableZBuffer(false, false); - DrawQuad( + BGND_DrawQuad( (float)g_PhdWinMinX, (float)g_PhdWinMinY, (float)g_PhdWinWidth, (float)g_PhdWinHeight, 0); HWR_EnableZBuffer(true, true); } -void __cdecl DrawQuad( +void __cdecl BGND_DrawQuad( const float sx, const float sy, const float width, const float height, const D3DCOLOR color) { @@ -184,7 +184,7 @@ void __cdecl BGND_DrawInGameBackground(void) BGND_CenterLighting(x1, y1, g_PhdWinWidth, g_PhdWinHeight), }; - DrawTextureTile( + BGND_DrawTextureTile( x0, y0, x1 - x0, y1 - y0, tex_source, tu, tv, t_width, t_height, color[0], color[1], color[2], color[3]); @@ -196,7 +196,7 @@ void __cdecl BGND_DrawInGameBackground(void) HWR_EnableZBuffer(true, true); } -void __cdecl DrawTextureTile( +void __cdecl BGND_DrawTextureTile( const int32_t sx, const int32_t sy, const int32_t width, const int32_t height, const HWR_TEXTURE_HANDLE tex_source, const int32_t tu, const int32_t tv, const int32_t t_width, const int32_t t_height, diff --git a/src/tr2/game/background.h b/src/tr2/game/background.h index 9699f8c01..d12a531c9 100644 --- a/src/tr2/game/background.h +++ b/src/tr2/game/background.h @@ -13,10 +13,10 @@ int32_t __cdecl BGND_AddTexture( const RGB_888 *bmp_pal); void __cdecl BGND_GetPageHandles(void); void __cdecl BGND_DrawInGameBlack(void); -void __cdecl DrawQuad( +void __cdecl BGND_DrawQuad( float sx, float sy, float width, float height, D3DCOLOR color); void __cdecl BGND_DrawInGameBackground(void); -void __cdecl DrawTextureTile( +void __cdecl BGND_DrawTextureTile( int32_t sx, int32_t sy, int32_t width, int32_t height, HWR_TEXTURE_HANDLE tex_source, int32_t tu, int32_t tv, int32_t t_width, int32_t t_height, D3DCOLOR color0, D3DCOLOR color1, D3DCOLOR color2, diff --git a/src/tr2/game/hwr.c b/src/tr2/game/hwr.c index b09c6d2e3..0e4d7c63c 100644 --- a/src/tr2/game/hwr.c +++ b/src/tr2/game/hwr.c @@ -36,10 +36,6 @@ void __cdecl HWR_InitState(void) g_D3DDev, D3DRENDERSTATE_TEXTUREPERSPECTIVE, g_SavedAppSettings.perspective_correct ? TRUE : FALSE); - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, D3DRENDERSTATE_DITHERENABLE, - g_SavedAppSettings.dither ? TRUE : FALSE); - g_AlphaBlendEnabler = g_CurrentDisplayAdapter.shade_restricted ? D3DRENDERSTATE_STIPPLEDALPHA : D3DRENDERSTATE_ALPHABLENDENABLE; @@ -71,8 +67,12 @@ void __cdecl HWR_InitState(void) void __cdecl HWR_ResetTexSource(void) { g_CurrentTexSource = 0; - g_D3DDev->lpVtbl->SetRenderState(g_D3DDev, D3DRENDERSTATE_TEXTUREHANDLE, 0); - g_D3DDev->lpVtbl->SetRenderState(g_D3DDev, D3DRENDERSTATE_FLUSHBATCH, 0); + if (g_D3DDev != NULL) { + g_D3DDev->lpVtbl->SetRenderState( + g_D3DDev, D3DRENDERSTATE_TEXTUREHANDLE, 0); + g_D3DDev->lpVtbl->SetRenderState( + g_D3DDev, D3DRENDERSTATE_FLUSHBATCH, 0); + } } void __cdecl HWR_ResetColorKey(void) @@ -155,7 +155,6 @@ void __cdecl HWR_EnableZBuffer(const bool z_write_enable, const bool z_enable) void __cdecl HWR_BeginScene(void) { HWR_GetPageHandles(); - WaitPrimaryBufferFlip(); g_D3DDev->lpVtbl->BeginScene(g_D3DDev); } diff --git a/src/tr2/game/input.c b/src/tr2/game/input.c index 9af2d5948..97aafc5e9 100644 --- a/src/tr2/game/input.c +++ b/src/tr2/game/input.c @@ -105,7 +105,6 @@ static void M_UpdateFromBackend( s->toggle_bilinear_filter |= backend->is_pressed(layout, INPUT_ROLE_TOGGLE_BILINEAR_FILTER); s->toggle_perspective_filter |= backend->is_pressed(layout, INPUT_ROLE_TOGGLE_PERSPECTIVE_FILTER); s->toggle_z_buffer |= backend->is_pressed(layout, INPUT_ROLE_TOGGLE_Z_BUFFER); - s->toggle_dither |= backend->is_pressed(layout, INPUT_ROLE_TOGGLE_DITHER); s->toggle_fullscreen |= backend->is_pressed(layout, INPUT_ROLE_TOGGLE_FULLSCREEN); s->toggle_rendering_mode |= backend->is_pressed(layout, INPUT_ROLE_TOGGLE_RENDERING_MODE); // clang-format on diff --git a/src/tr2/game/inventory/common.c b/src/tr2/game/inventory/common.c index dea9d0a32..14254c2a2 100644 --- a/src/tr2/game/inventory/common.c +++ b/src/tr2/game/inventory/common.c @@ -110,10 +110,6 @@ void __cdecl Inv_Construct(void) { S_SetupAboveWater(0); - if (g_Inv_Mode != INV_TITLE_MODE) { - TempVideoAdjust(g_HiRes, 1.0); - } - g_PhdWinRight = g_PhdWinMaxX; g_PhdWinLeft = 0; g_PhdWinTop = 0; diff --git a/src/tr2/game/output.c b/src/tr2/game/output.c index 97ec1c769..09d2ffa85 100644 --- a/src/tr2/game/output.c +++ b/src/tr2/game/output.c @@ -353,6 +353,21 @@ void __cdecl Output_Init( int32_t far_z, int16_t view_angle, int32_t screen_width, int32_t screen_height) { + g_SDLRenderer2D = GFX_Context_GetRenderer2D(); + g_SDLRenderer3D = GFX_Context_GetRenderer3D(); + + GFX_2D_SURFACE_DESC surface_desc = { + .width = screen_width, + .height = screen_height, + .pitch = screen_width * 3, + .bit_count = 24, + .tex_format = GL_RGB, + .tex_type = GL_UNSIGNED_BYTE, + }; + GFX_Context_SetDisplaySize(screen_width, screen_height); + GFX_Context_SetWindowSize(width, height); + g_SDLSurface = GFX_2D_Surface_Create(&surface_desc); + Viewport_Init( x, y, width, height, near_z, far_z, view_angle * PHD_DEGREE, screen_width, screen_height); diff --git a/src/tr2/game/shell.h b/src/tr2/game/shell.h index 003b6f91e..45a748e4b 100644 --- a/src/tr2/game/shell.h +++ b/src/tr2/game/shell.h @@ -2,3 +2,5 @@ #include "game/shell/common.h" #include "game/shell/input.h" + +#include diff --git a/src/tr2/game/shell/common.c b/src/tr2/game/shell/common.c index 91dfc8d06..bcdef571e 100644 --- a/src/tr2/game/shell/common.c +++ b/src/tr2/game/shell/common.c @@ -20,7 +20,9 @@ #include "global/vars.h" #include +#include #include +#include #include #include @@ -29,12 +31,129 @@ #define GAMEBUF_MEM_CAP 0x380000 +static int32_t m_UpdateLock = 0; static const char *m_CurrentGameflowPath = "cfg/TR2X_gameflow.json5"; +static void M_HandleFocusGained(void); +static void M_HandleFocusLost(void); +static void M_HandleWindowShown(void); +static void M_HandleWindowRestored(void); +static void M_HandleWindowMinimized(void); +static void M_HandleWindowMaximized(void); +static void M_HandleWindowMoved(int32_t x, int32_t y); +static void M_HandleWindowResized(int32_t width, int32_t height); +static void M_HandleKeyDown(const SDL_Event *event); +static void M_HandleKeyUp(const SDL_Event *event); +static void M_HandleQuit(void); + +static void M_HandleFocusGained(void) +{ + if (!g_IsGameWindowActive && g_IsGameFullScreen + && g_SavedAppSettings.render_mode == RM_HARDWARE) { + g_WinVidNeedToResetBuffers = true; + } + SDL_ShowCursor(g_IsGameFullScreen ? SDL_DISABLE : SDL_ENABLE); + g_IsGameWindowActive = true; +} + +static void M_HandleFocusLost(void) +{ + g_IsGameWindowActive = false; +} + +static void M_HandleWindowShown(void) +{ + g_IsGameWindowCreated = true; +} + +static void M_HandleWindowRestored(void) +{ + g_IsGameWindowMinimized = false; + g_IsGameWindowMaximized = false; +} + +static void M_HandleWindowMinimized(void) +{ + g_IsGameWindowMinimized = true; + g_IsGameWindowMaximized = false; +} + +static void M_HandleWindowMaximized(void) +{ + g_IsGameWindowMinimized = false; + g_IsGameWindowMaximized = true; +} + +static void M_HandleWindowMoved(const int32_t x, const int32_t y) +{ + g_GameWindowPositionX = x; + g_GameWindowPositionY = y; +} + +static void M_HandleWindowResized(int32_t width, int32_t height) +{ + if (m_UpdateLock > 0) { + return; + } + + if (g_IsMinWindowSizeSet) { + CLAMPL(width, g_MinWindowClientWidth); + CLAMPL(height, g_MinWindowClientHeight); + } + + if (g_IsMaxWindowSizeSet) { + CLAMPG(width, g_MaxWindowClientWidth); + CLAMPG(height, g_MaxWindowClientHeight); + } + + if (g_IsGameFullScreen + || (g_GameWindowWidth == width && g_GameWindowHeight == height)) { + return; + } + + m_UpdateLock++; + g_GameWindowWidth = width; + g_GameWindowHeight = height; + UpdateGameResolution(); + m_UpdateLock--; +} + +static void M_HandleKeyDown(const SDL_Event *const event) +{ + // NOTE: This normally would get handled by Input_Update, + // but by the time Input_Update gets ran, we may already have lost + // some keypresses if the player types really fast, so we need to + // react sooner. + if (!FMV_IsPlaying() && !Console_IsOpened() + && Input_IsPressed( + INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout, + INPUT_ROLE_ENTER_CONSOLE)) { + Console_Open(); + } else { + UI_HandleKeyDown(event->key.keysym.sym); + } +} + +static void M_HandleKeyUp(const SDL_Event *const event) +{ + // NOTE: needs special handling on Windows - + // SDL_SCANCODE_PRINTSCREEN is not sufficient to react to this. + if (event->key.keysym.sym == SDLK_PRINTSCREEN) { + Screenshot_Make(g_Config.rendering.screenshot_format); + } +} + +static void M_HandleQuit(void) +{ + g_IsGameWindowCreated = false; + g_IsMessageLoopClosed = true; + g_IsGameToExit = true; + g_StopInventory = true; +} + // TODO: refactor the hell out of me void __cdecl Shell_Main(void) { - g_HiRes = 0; g_ScreenSizer = 0; g_GameSizer = 1.0; g_GameSizerCopy = 1.0; @@ -70,13 +189,7 @@ void __cdecl Shell_Main(void) S_FrontEndCheck(); S_LoadSettings(); - g_HiRes = -1; GameBuf_Init(GAMEBUF_MEM_CAP); - g_HiRes = 0; - - TempVideoAdjust(1, 1.0); - - g_IsVidModeLock = 1; S_DisplayPicture("data\\legal.pcx", 0); S_InitialisePolyList(0); @@ -88,7 +201,6 @@ void __cdecl Shell_Main(void) S_Wait(180, true); S_FadeToBlack(); S_DontDisplayPicture(); - g_IsVidModeLock = 0; const bool is_frontend_fail = GF_DoFrontendSequence(); if (g_IsGameToExit) { @@ -183,40 +295,44 @@ void __cdecl Shell_Shutdown(void) BGND_Free(); RenderFinish(false); WinVidFinish(); - WinVidHideGameWindow(); Text_Shutdown(); UI_Shutdown(); GameBuf_Shutdown(); Config_Shutdown(); } -void __cdecl Shell_ExitSystem(const char *const message) +const char *Shell_GetGameflowPath(void) { - MessageBoxA(NULL, message, NULL, MB_ICONWARNING); - Shell_Shutdown(); - exit(1); + return m_CurrentGameflowPath; } -void __cdecl Shell_ExitSystemFmt(const char *fmt, ...) +void Shell_GoFullscreen(void) { - va_list va; - va_start(va, fmt); - int32_t size = vsnprintf(NULL, 0, fmt, va) + 1; - char *message = Memory_Alloc(size); - va_end(va); + LOG_DEBUG("going fullscreen"); - va_start(va, fmt); - vsnprintf(message, size, fmt, va); - va_end(va); - - Shell_ExitSystem(message); + m_UpdateLock++; + SDL_SetWindowFullscreen(g_SDLWindow, SDL_WINDOW_FULLSCREEN_DESKTOP); + SDL_ShowWindow(g_SDLWindow); + Shell_ProcessEvents(); + m_UpdateLock--; - Memory_FreePointer(&message); + g_IsGameWindowShow = true; + g_IsGameFullScreen = true; } -const char *Shell_GetGameflowPath(void) +void Shell_GoWindowed(const int32_t target_width, const int32_t target_height) { - return m_CurrentGameflowPath; + LOG_DEBUG("going windowed"); + g_GameWindowWidth = target_width; + g_GameWindowHeight = target_height; + g_IsGameFullScreen = false; + + m_UpdateLock++; + SDL_SetWindowFullscreen(g_SDLWindow, 0); + SDL_SetWindowSize(g_SDLWindow, target_width, target_height); + SDL_ShowWindow(g_SDLWindow); + Shell_ProcessEvents(); + m_UpdateLock--; } // TODO: try to call this function in a single place after introducing phasers. @@ -226,33 +342,16 @@ void Shell_ProcessEvents(void) while (SDL_PollEvent(&event) != 0) { switch (event.type) { case SDL_QUIT: - g_IsMessageLoopClosed = true; - g_IsGameToExit = true; - g_StopInventory = true; + M_HandleQuit(); break; case SDL_KEYDOWN: { - // NOTE: This normally would get handled by Input_Update, - // but by the time Input_Update gets ran, we may already have lost - // some keypresses if the player types really fast, so we need to - // react sooner. - if (!FMV_IsPlaying() && !Console_IsOpened() - && Input_IsPressed( - INPUT_BACKEND_KEYBOARD, g_Config.input.keyboard_layout, - INPUT_ROLE_ENTER_CONSOLE)) { - Console_Open(); - } else { - UI_HandleKeyDown(event.key.keysym.sym); - } + M_HandleKeyDown(&event); break; } case SDL_KEYUP: - // NOTE: needs special handling on Windows - - // SDL_SCANCODE_PRINTSCREEN is not sufficient to react to this. - if (event.key.keysym.sym == SDLK_PRINTSCREEN) { - Screenshot_Make(g_Config.rendering.screenshot_format); - } + M_HandleKeyUp(&event); break; case SDL_TEXTEDITING: @@ -272,6 +371,47 @@ void Shell_ProcessEvents(void) case SDL_JOYDEVICEREMOVED: Input_ShutdownController(); break; + + case SDL_WINDOWEVENT: + switch (event.window.event) { + case SDL_WINDOWEVENT_SHOWN: + M_HandleWindowShown(); + break; + + case SDL_WINDOWEVENT_FOCUS_GAINED: + M_HandleFocusGained(); + break; + + case SDL_WINDOWEVENT_FOCUS_LOST: + M_HandleFocusLost(); + break; + + case SDL_WINDOWEVENT_RESTORED: + M_HandleWindowRestored(); + break; + + case SDL_WINDOWEVENT_MINIMIZED: + M_HandleWindowMinimized(); + break; + + case SDL_WINDOWEVENT_MAXIMIZED: + M_HandleWindowMaximized(); + break; + + case SDL_WINDOWEVENT_MOVED: + M_HandleWindowMoved(event.window.data1, event.window.data2); + break; + + case SDL_WINDOWEVENT_RESIZED: + M_HandleWindowResized(event.window.data1, event.window.data2); + break; + } + break; } } } + +SDL_Window *Shell_GetWindow(void) +{ + return g_SDLWindow; +} diff --git a/src/tr2/game/shell/common.h b/src/tr2/game/shell/common.h index e903c190c..66d4cfaec 100644 --- a/src/tr2/game/shell/common.h +++ b/src/tr2/game/shell/common.h @@ -3,9 +3,9 @@ #include "global/types.h" void __cdecl Shell_Main(void); -void __cdecl Shell_Shutdown(void); -void __cdecl Shell_ExitSystem(const char *message); -void __cdecl Shell_ExitSystemFmt(const char *fmt, ...); const char *Shell_GetGameflowPath(void); void Shell_ProcessEvents(void); + +void Shell_GoFullscreen(void); +void Shell_GoWindowed(int32_t target_width, int32_t target_height); diff --git a/src/tr2/game/shell/input.c b/src/tr2/game/shell/input.c index 1c27c4a5d..ad078506b 100644 --- a/src/tr2/game/shell/input.c +++ b/src/tr2/game/shell/input.c @@ -18,8 +18,6 @@ static void M_ToggleBilinearFiltering(void); static void M_TogglePerspectiveCorrection(void); static void M_ToggleZBuffer(void); -static void M_ToggleTripleBuffering(void); -static void M_ToggleDither(void); static void M_ToggleFullscreen(void); static void M_ToggleRenderingMode(void); static void M_DecreaseResolutionOrBPP(void); @@ -51,38 +49,19 @@ static void M_ToggleZBuffer(void) GameApplySettings(&new_settings); } -static void M_ToggleTripleBuffering(void) -{ - if (g_SavedAppSettings.fullscreen) { - return; - } - - APP_SETTINGS new_settings = g_SavedAppSettings; - new_settings.triple_buffering = !new_settings.triple_buffering; - GameApplySettings(&new_settings); -} - -static void M_ToggleDither(void) -{ - APP_SETTINGS new_settings = g_SavedAppSettings; - new_settings.dither = !new_settings.dither; - GameApplySettings(&new_settings); -} - +#include static void M_ToggleFullscreen(void) { - if (g_IsVidModeLock) { - return; - } - + LOG_DEBUG("oh"); APP_SETTINGS new_settings = g_SavedAppSettings; new_settings.fullscreen = !new_settings.fullscreen; + GameApplySettings(&new_settings); +#ifndef SDL_WINDOW if (g_SavedAppSettings.fullscreen) { const int32_t win_width = MAX(g_PhdWinWidth, 320); const int32_t win_height = MAX(g_PhdWinHeight, 240); new_settings.window_height = win_height; new_settings.window_width = CalculateWindowWidth(win_width, win_height); - new_settings.triple_buffering = 0; GameApplySettings(&new_settings); g_GameSizer = 1.0; @@ -117,18 +96,16 @@ static void M_ToggleFullscreen(void) GameApplySettings(&new_settings); } } +#endif } static void M_ToggleRenderingMode(void) { - if (g_IsVidModeLock || g_Inv_IsActive) { - return; - } - APP_SETTINGS new_settings = g_SavedAppSettings; new_settings.render_mode = new_settings.render_mode == RM_HARDWARE ? RM_SOFTWARE : RM_HARDWARE; +#ifndef SDL_WINDOW const DISPLAY_MODE_LIST *const mode_list = new_settings.render_mode == RM_HARDWARE ? &g_CurrentDisplayAdapter.hw_disp_mode_list @@ -158,14 +135,14 @@ static void M_ToggleRenderingMode(void) new_settings.video_mode = mode; new_settings.fullscreen = 1; +#endif + GameApplySettings(&new_settings); } static void M_DecreaseResolutionOrBPP(void) { - if (g_IsVidSizeLock || g_Camera.type == CAM_CINEMATIC - || g_GameFlow.screen_sizing_disabled - || !g_SavedAppSettings.fullscreen) { + if (g_Camera.type == CAM_CINEMATIC) { return; } @@ -201,9 +178,7 @@ static void M_DecreaseResolutionOrBPP(void) static void M_IncreaseResolutionOrBPP(void) { - if (g_IsVidSizeLock || g_Camera.type == CAM_CINEMATIC - || g_GameFlow.screen_sizing_disabled - || !g_SavedAppSettings.fullscreen) { + if (g_Camera.type == CAM_CINEMATIC) { return; } @@ -238,9 +213,7 @@ static void M_IncreaseResolutionOrBPP(void) static void M_DecreaseInternalScreenSize(void) { - if (g_IsVidSizeLock || g_Camera.type == CAM_CINEMATIC - || g_GameFlow.screen_sizing_disabled - || !g_SavedAppSettings.fullscreen) { + if (g_Camera.type == CAM_CINEMATIC) { return; } @@ -249,9 +222,7 @@ static void M_DecreaseInternalScreenSize(void) static void M_IncreaseInternalScreenSize(void) { - if (g_IsVidSizeLock || g_Camera.type == CAM_CINEMATIC - || g_GameFlow.screen_sizing_disabled - || !g_SavedAppSettings.fullscreen) { + if (g_Camera.type == CAM_CINEMATIC) { return; } @@ -274,9 +245,9 @@ void Shell_ProcessInput(void) if (g_InputDB.switch_internal_screen_size) { if (g_Input.slow) { - M_DecreaseInternalScreenSize(); - } else { M_IncreaseInternalScreenSize(); + } else { + M_DecreaseInternalScreenSize(); } } @@ -292,10 +263,6 @@ void Shell_ProcessInput(void) M_ToggleZBuffer(); } - if (g_InputDB.toggle_dither) { - M_ToggleDither(); - } - if (g_InputDB.toggle_fullscreen) { M_ToggleFullscreen(); } diff --git a/src/tr2/global/types.h b/src/tr2/global/types.h index 74d0e76b0..d17cdb3b5 100644 --- a/src/tr2/global/types.h +++ b/src/tr2/global/types.h @@ -197,7 +197,7 @@ typedef struct __unaligned { bool dither; bool zbuffer; bool bilinear_filtering; - bool triple_buffering; + bool triple_buffering; // TODO: remove this option bool fullscreen; bool sound_enabled; bool lara_mic; @@ -222,16 +222,37 @@ typedef struct __unaligned { } TEXPAGE_DESC; typedef struct __unaligned { - uint8_t red; - uint8_t green; - uint8_t blue; + union { + uint8_t red; + uint8_t r; + }; + union { + uint8_t green; + uint8_t g; + }; + union { + uint8_t blue; + uint8_t b; + }; } RGB_888; typedef struct __unaligned { - uint8_t red; - uint8_t green; - uint8_t blue; - uint8_t alpha; + union { + uint8_t red; + uint8_t r; + }; + union { + uint8_t green; + uint8_t g; + }; + union { + uint8_t blue; + uint8_t b; + }; + union { + uint8_t alpha; + uint8_t a; + }; } RGBA_8888; typedef struct { diff --git a/src/tr2/global/vars.c b/src/tr2/global/vars.c index f30f7feab..c824ba3cd 100644 --- a/src/tr2/global/vars.c +++ b/src/tr2/global/vars.c @@ -5,3 +5,8 @@ const char *g_TR2XVersion = "TR2X (non-Docker build)"; #endif GAME_FLOW_DIR g_GF_OverrideDir = (GAME_FLOW_DIR)-1; +SDL_Window *g_SDLWindow = NULL; +GFX_2D_RENDERER *g_SDLRenderer2D = NULL; +GFX_3D_RENDERER *g_SDLRenderer3D = NULL; +GFX_2D_SURFACE *g_SDLSurface = NULL; +GFX_PALETTE_ENTRY g_SDLPalette[256] = { 0 }; diff --git a/src/tr2/global/vars.h b/src/tr2/global/vars.h index 65ced5de3..3e0b2d1a9 100644 --- a/src/tr2/global/vars.h +++ b/src/tr2/global/vars.h @@ -2,5 +2,14 @@ #include "global/vars_decomp.h" +#include + +#include + extern const char *g_TR2XVersion; extern GAME_FLOW_DIR g_GF_OverrideDir; +extern SDL_Window *g_SDLWindow; +extern GFX_3D_RENDERER *g_SDLRenderer3D; +extern GFX_2D_RENDERER *g_SDLRenderer2D; +extern GFX_2D_SURFACE *g_SDLSurface; +extern GFX_PALETTE_ENTRY g_SDLPalette[256]; diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index 992550e5e..1887d38c5 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -167,22 +167,9 @@ static void M_DecompGeneral(const bool enable) INJECT(enable, 0x00444980, Direct3DInit); INJECT(enable, 0x00444BD0, DDrawCreate); INJECT(enable, 0x00444C30, DDrawRelease); - INJECT(enable, 0x00444C70, GameWindowCalculateSizeFromClient); - INJECT(enable, 0x00444CF0, GameWindowCalculateSizeFromClientByZero); - INJECT(enable, 0x00444D60, WinVidSetMinWindowSize); - INJECT(enable, 0x00444DB0, WinVidClearMinWindowSize); - INJECT(enable, 0x00444DC0, WinVidSetMaxWindowSize); - INJECT(enable, 0x00444E10, WinVidClearMaxWindowSize); INJECT(enable, 0x00444E20, CalculateWindowWidth); INJECT(enable, 0x00444E70, CalculateWindowHeight); - INJECT(enable, 0x00444EA0, WinVidGetMinMaxInfo); INJECT(enable, 0x00444FB0, WinVidFindGameWindow); - INJECT(enable, 0x00444FD0, WinVidSpinMessageLoop); - INJECT(enable, 0x004450C0, WinVidShowGameWindow); - INJECT(enable, 0x00445110, WinVidHideGameWindow); - INJECT(enable, 0x00445150, WinVidSetGameWindowSize); - INJECT(enable, 0x00445190, ShowDDrawGameWindow); - INJECT(enable, 0x00445240, HideDDrawGameWindow); INJECT(enable, 0x004452D0, DDrawSurfaceCreate); INJECT(enable, 0x00445320, DDrawSurfaceRestoreLost); INJECT(enable, 0x00445370, WinVidClearBuffer); @@ -193,25 +180,12 @@ static void M_DecompGeneral(const bool enable) INJECT(enable, 0x00445550, WinVidGetColorBitMasks); INJECT(enable, 0x004455D0, BitMaskGetNumberOfBits); INJECT(enable, 0x00445620, CalculateCompatibleColor); - INJECT(enable, 0x00445690, WinVidGetDisplayMode); - INJECT(enable, 0x00445720, WinVidGoFullScreen); - INJECT(enable, 0x004457B0, WinVidGoWindowed); - INJECT(enable, 0x004458C0, WinVidSetDisplayAdapter); - INJECT(enable, 0x004459A0, CompareVideoModes); - INJECT(enable, 0x004459F0, WinVidGetDisplayModes); - INJECT(enable, 0x00445A50, EnumDisplayModesCallback); INJECT(enable, 0x00445E10, WinVidInit); INJECT(enable, 0x00445E50, WinVidGetDisplayAdapters); INJECT(enable, 0x00445F20, EnumerateDisplayAdapters); INJECT(enable, 0x00445F40, EnumDisplayAdaptersCallback); - INJECT(enable, 0x00446140, WinVidRegisterGameWindowClass); - INJECT(enable, 0x004461B0, WinVidGameWindowProc); - INJECT(enable, 0x004467C0, WinVidResizeGameWindow); - INJECT(enable, 0x004469A0, WinVidCheckGameWindowPalette); INJECT(enable, 0x00446A60, WinVidCreateGameWindow); - INJECT(enable, 0x00446B30, WinVidFreeWindow); INJECT(enable, 0x00446B60, WinVidExitMessage); - INJECT(enable, 0x00446BB0, WinVidGetDisplayAdapter); INJECT(enable, 0x00446C00, WinVidStart); INJECT(enable, 0x00446F80, WinVidFinish); INJECT(enable, 0x004471F0, DInputCreate); @@ -224,10 +198,7 @@ static void M_DecompGeneral(const bool enable) INJECT(enable, 0x004479D0, TempVideoRemove); INJECT(enable, 0x00447A10, S_FadeInInventory); INJECT(enable, 0x00447A50, S_FadeOutInventory); - INJECT(enable, 0x00448430, CreateScreenBuffers); - INJECT(enable, 0x00448570, CreatePrimarySurface); INJECT(enable, 0x00448610, CreateBackBuffer); - INJECT(enable, 0x004486B0, CreateClipper); INJECT(enable, 0x00448750, CreateWindowPalette); INJECT(enable, 0x00448830, CreateZBuffer); INJECT(enable, 0x004488F0, GetZBufferDepth); @@ -235,9 +206,6 @@ static void M_DecompGeneral(const bool enable) INJECT(enable, 0x004489D0, CreatePictureBuffer); INJECT(enable, 0x00448A40, ClearBuffers); INJECT(enable, 0x00448BF0, RestoreLostBuffers); - INJECT(enable, 0x00448D30, UpdateFrame); - INJECT(enable, 0x00448E00, WaitPrimaryBufferFlip); - INJECT(enable, 0x00448E40, RenderInit); INJECT(enable, 0x00448E50, RenderStart); INJECT(enable, 0x00449200, RenderFinish); INJECT(enable, 0x004492F0, ApplySettings); @@ -273,8 +241,6 @@ static void M_DecompGeneral(const bool enable) INJECT(enable, 0x00451DE0, S_DisplayPicture); INJECT(enable, 0x00451EF0, S_SyncPictureBufferPalette); INJECT(enable, 0x00451F70, S_DontDisplayPicture); - INJECT(enable, 0x00451F80, ScreenDump); - INJECT(enable, 0x00451F90, ScreenPartialDump); INJECT(enable, 0x00451FA0, FadeToPal); INJECT(enable, 0x00452170, ScreenClear); INJECT(enable, 0x004521A0, S_CopyScreenToBuffer); @@ -420,9 +386,9 @@ static void M_Background(const bool enable) INJECT(enable, 0x00443B50, BGND_AddTexture); INJECT(enable, 0x00443C10, BGND_GetPageHandles); INJECT(enable, 0x00443C50, BGND_DrawInGameBlack); - INJECT(enable, 0x00443CB0, DrawQuad); + INJECT(enable, 0x00443CB0, BGND_DrawQuad); INJECT(enable, 0x00443D90, BGND_DrawInGameBackground); - INJECT(enable, 0x00443FB0, DrawTextureTile); + INJECT(enable, 0x00443FB0, BGND_DrawTextureTile); INJECT(enable, 0x00444210, BGND_CenterLighting); INJECT(enable, 0x004444C0, BGND_Free); INJECT(enable, 0x00444510, BGND_Init); diff --git a/src/tr2/meson.build b/src/tr2/meson.build index 669c9f9fd..507f5d0a0 100644 --- a/src/tr2/meson.build +++ b/src/tr2/meson.build @@ -19,6 +19,7 @@ build_opts = [ '-Wno-unused', '-Wno-address-of-packed-member', '-DMESON_BUILD', + '-DSDL_WINDOW', '-fno-omit-frame-pointer', '-ffile-prefix-map=@0@/='.format(relative_dir), ] + trx.get_variable('defines') @@ -83,6 +84,7 @@ dll_sources = [ 'decomp/effects.c', 'decomp/flares.c', 'decomp/fmv.c', + 'decomp/render_new.c', 'decomp/savegame.c', 'decomp/skidoo.c', 'decomp/stats.c',