From 8941bfdf04771cdd8288d55502a5b9105ab6bb9c Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Mon, 9 Dec 2024 22:59:17 +0100 Subject: [PATCH] tr2: use hybrid OpenGL/DirectX rendering --- data/tr2/ship/shaders/2d.glsl | 76 + data/tr2/ship/shaders/3d.glsl | 78 + data/tr2/ship/shaders/fade.glsl | 25 + data/tr2/ship/shaders/fbo.glsl | 38 + docs/tr2/CHANGELOG.md | 23 +- docs/tr2/README.md | 22 +- docs/tr2/progress.svg | 300 +- docs/tr2/progress.txt | 465 +- src/libtrx/include/libtrx/game/enum_map.def | 1 - .../game/input/backends/keyboard_tr2.def | 1 - .../include/libtrx/game/input/roles_tr2.def | 1 - src/libtrx/include/libtrx/utils.h | 2 + src/libtrx/log_windows.c | 6 +- src/tr2/config.c | 22 + src/tr2/config.h | 26 + src/tr2/config_map.def | 25 +- src/tr2/decomp/decomp.c | 2883 +---------- src/tr2/decomp/decomp.h | 171 - src/tr2/decomp/decomp2.c | 692 --- src/tr2/decomp/fmv.c | 353 +- src/tr2/decomp/fmv.h | 8 +- src/tr2/decomp/stats.c | 41 +- src/tr2/game/background.c | 295 -- src/tr2/game/background.h | 25 - src/tr2/game/camera.c | 1 - src/tr2/game/demo.c | 4 +- src/tr2/game/fader.c | 77 + src/tr2/game/fader.h | 24 + src/tr2/game/game.c | 146 +- src/tr2/game/game.h | 2 + src/tr2/game/gameflow.c | 8 +- src/tr2/game/hwr.c | 283 -- src/tr2/game/hwr.h | 27 - src/tr2/game/input.c | 1 - src/tr2/game/inventory/common.c | 640 +-- src/tr2/game/lara/draw.c | 4 +- src/tr2/game/level.c | 184 +- src/tr2/game/level.h | 4 - src/tr2/game/objects/common.c | 2 +- src/tr2/game/option/option.c | 39 +- src/tr2/game/option/option.h | 38 +- src/tr2/game/option/option_compass.c | 6 +- src/tr2/game/option/option_controls.c | 10 +- src/tr2/game/option/option_detail.c | 6 +- src/tr2/game/option/option_passport.c | 6 +- src/tr2/game/option/option_sound.c | 6 +- src/tr2/game/output.c | 4312 ++--------------- src/tr2/game/output.h | 163 +- src/tr2/game/overlay.c | 37 +- src/tr2/game/render/common.c | 366 ++ src/tr2/game/render/common.h | 70 + src/tr2/game/render/hwr.c | 1628 +++++++ src/tr2/game/render/hwr.h | 5 + src/tr2/game/render/priv.c | 533 ++ src/tr2/game/render/priv.h | 81 + src/tr2/game/render/swr.c | 2270 +++++++++ src/tr2/game/render/swr.h | 5 + src/tr2/game/render/util.c | 23 + src/tr2/game/render/util.h | 5 + src/tr2/game/requester.c | 10 +- src/tr2/game/room_draw.c | 13 +- src/tr2/game/shell.h | 2 + src/tr2/game/shell/common.c | 451 +- src/tr2/game/shell/common.h | 12 +- src/tr2/game/shell/input.c | 237 +- src/tr2/game/text.c | 21 +- src/tr2/game/ui/common.c | 2 + src/tr2/game/viewport.c | 124 +- src/tr2/game/viewport.h | 21 +- src/tr2/global/enum_map.c | 3 + src/tr2/global/enum_map.def | 14 + src/tr2/global/funcs.h | 70 - src/tr2/global/types.h | 1664 +------ src/tr2/global/types_decomp.h | 1506 ++++++ src/tr2/global/vars.c | 5 + src/tr2/global/vars.h | 7 + src/tr2/global/vars_decomp.h | 106 - src/tr2/inject_exec.c | 273 +- src/tr2/lib/cpp.h | 2 - src/tr2/lib/ddraw.h | 19 - src/tr2/lib/dinput.h | 8 - src/tr2/lib/dsound.h | 11 - src/tr2/lib/player.h | 30 - src/tr2/lib/winmm.c | 32 - src/tr2/lib/winmm.h | 25 - src/tr2/main_dll.c | 2 - src/tr2/meson.build | 11 +- src/tr2/specific/s_flagged_string.c | 49 - src/tr2/specific/s_flagged_string.h | 10 - tools/sort_imports | 8 +- .../TR2X_ConfigTool/Resources/Lang/en.json | 17 + .../Resources/specification.json | 23 +- tools/tr2/generate_funcs | 6 +- 93 files changed, 9117 insertions(+), 12272 deletions(-) create mode 100644 data/tr2/ship/shaders/2d.glsl create mode 100644 data/tr2/ship/shaders/3d.glsl create mode 100644 data/tr2/ship/shaders/fade.glsl create mode 100644 data/tr2/ship/shaders/fbo.glsl delete mode 100644 src/tr2/decomp/decomp2.c delete mode 100644 src/tr2/game/background.c delete mode 100644 src/tr2/game/background.h create mode 100644 src/tr2/game/fader.c create mode 100644 src/tr2/game/fader.h delete mode 100644 src/tr2/game/hwr.c delete mode 100644 src/tr2/game/hwr.h create mode 100644 src/tr2/game/render/common.c create mode 100644 src/tr2/game/render/common.h create mode 100644 src/tr2/game/render/hwr.c create mode 100644 src/tr2/game/render/hwr.h create mode 100644 src/tr2/game/render/priv.c create mode 100644 src/tr2/game/render/priv.h create mode 100644 src/tr2/game/render/swr.c create mode 100644 src/tr2/game/render/swr.h create mode 100644 src/tr2/game/render/util.c create mode 100644 src/tr2/game/render/util.h create mode 100644 src/tr2/global/types_decomp.h delete mode 100644 src/tr2/lib/cpp.h delete mode 100644 src/tr2/lib/ddraw.h delete mode 100644 src/tr2/lib/dinput.h delete mode 100644 src/tr2/lib/dsound.h delete mode 100644 src/tr2/lib/player.h delete mode 100644 src/tr2/lib/winmm.c delete mode 100644 src/tr2/lib/winmm.h delete mode 100644 src/tr2/specific/s_flagged_string.c delete mode 100644 src/tr2/specific/s_flagged_string.h diff --git a/data/tr2/ship/shaders/2d.glsl b/data/tr2/ship/shaders/2d.glsl new file mode 100644 index 000000000..a432e6bc4 --- /dev/null +++ b/data/tr2/ship/shaders/2d.glsl @@ -0,0 +1,76 @@ +#ifdef VERTEX +// Vertex shader + +#ifdef OGL33C + out vec2 vertTexCoords; + out vec2 vertCoords; +#else + varying vec2 vertTexCoords; + varying vec2 vertCoords; +#endif + +layout(location = 0) in vec2 inPosition; +layout(location = 1) in vec2 inTexCoords; + +void main(void) { + gl_Position = vec4(inPosition * vec2(2.0, -2.0) + vec2(-1.0, 1.0), 0.0, 1.0); + vertCoords = inPosition; + vertTexCoords = inTexCoords; +} + +#else +// Fragment shader + +#define EFFECT_NONE 0 +#define EFFECT_VIGNETTE 1 + +uniform sampler2D texMain; +uniform sampler1D texPalette; +uniform sampler2D texAlpha; +uniform bool paletteEnabled; +uniform bool alphaEnabled; +uniform int effect; + +#ifdef OGL33C + #define OUTCOLOR outColor + #define TEXTURE2D texture + #define TEXTURE1D texture + + in vec2 vertTexCoords; + in vec2 vertCoords; + out vec4 outColor; +#else + #define OUTCOLOR gl_FragColor + #define TEXTURE2D texture2D + #define TEXTURE1D texture1D + + varying vec2 vertTexCoords; + varying vec2 vertCoords; +#endif + +void main(void) { + vec2 uv = vertTexCoords; + + if (alphaEnabled) { + float alpha = TEXTURE2D(texAlpha, uv).r; + if (alpha < 0.5) { + discard; + } + } + + if (paletteEnabled) { + float paletteIndex = TEXTURE2D(texMain, uv).r; + OUTCOLOR = TEXTURE1D(texPalette, paletteIndex); + } else { + OUTCOLOR = TEXTURE2D(texMain, uv); + } + + if (effect == EFFECT_VIGNETTE) { + float x_dist = vertCoords.x - 0.5; + float y_dist = vertCoords.y - 0.5; + float light = 256 - sqrt(x_dist * x_dist + y_dist * y_dist ) * 300.0; + light = clamp(light, 0, 255) / 255; + OUTCOLOR *= vec4(light, light, light, 1); + } +} +#endif // VERTEX diff --git a/data/tr2/ship/shaders/3d.glsl b/data/tr2/ship/shaders/3d.glsl new file mode 100644 index 000000000..a87843ac9 --- /dev/null +++ b/data/tr2/ship/shaders/3d.glsl @@ -0,0 +1,78 @@ +#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; +uniform bool alphaPointDiscard; +uniform float alphaThreshold; + +#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 (alphaPointDiscard && 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 (alphaThreshold >= 0.0 && texColor.a <= alphaThreshold) { + discard; + } + + OUTCOLOR = vec4(OUTCOLOR.rgb * texColor.rgb, texColor.a); + } +} +#endif // VERTEX diff --git a/data/tr2/ship/shaders/fade.glsl b/data/tr2/ship/shaders/fade.glsl new file mode 100644 index 000000000..43578c8a4 --- /dev/null +++ b/data/tr2/ship/shaders/fade.glsl @@ -0,0 +1,25 @@ +#ifdef VERTEX +// Vertex shader + +layout(location = 0) in vec2 inPosition; + +void main(void) { + gl_Position = vec4(inPosition * vec2(2.0, -2.0) + vec2(-1.0, 1.0), 0.0, 1.0); +} + +#else +// Fragment shader + +uniform float opacity; + +#ifdef OGL33C + #define OUTCOLOR outColor + out vec4 outColor; +#else + #define OUTCOLOR gl_FragColor +#endif + +void main(void) { + OUTCOLOR = vec4(0, 0, 0, opacity); +} +#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 c581793d6..084fed351 100644 --- a/docs/tr2/CHANGELOG.md +++ b/docs/tr2/CHANGELOG.md @@ -1,14 +1,23 @@ ## [Unreleased](https://github.com/LostArtefacts/TRX/compare/tr2-0.6...develop) - ××××-××-×× +- switched to OpenGL rendering + - changed fullscreen behavior to use windowed desktop mode + - added an option for 1-2-3-4× pixel upscaling (available under the F1/Shift-F1 key) + - added the ability to use the window border option at all times (available under the F2/Shift-F2 key) + - added the ability to toggle between the SWR/HWR renderer at runtime (available under the F12 key) + - added fade effects to the HWR renderer + - changed the SWR to use the picture's palette for the background pictures +- replaced fully the Windows Registry configuration with .json files + - removed setup dialog support (using `Tomb2.exe -setup` will have no effect on TR2X) + - removed unused detail level option + - removed triple buffering option + - removed dither option +- added toggle wireframe option (available with `/set` console command and with Shift+F7) - 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) - added a search feature to the config tool (#1889) - added an option to fix rotation on some pickup items to better suit 3D pickup mode (#1613) -- added an ability to use the game sizer at all times -- changed config to store certain values in the .json file rather than Windows registry - - music volume - - sound volume - - game sizer +- added ability to turn fade effects on/off - fixed a crash relating to audio decoding (#1895) - fixed depth problems when drawing certain rooms (#1853, regression from 0.6) - fixed Lara getting stuck in her hit animation if she is hit while mounting the boat or skidoo (#1606) @@ -35,6 +44,10 @@ - fixed Lara's left arm becoming stuck if a flare is drawn just before the final cutscene in Home Sweet Home (#1992) - fixed game crash when trying to draw too many rooms at once (#1998) - fixed resizing game window on the stats dialog cloning the UI elements, eventually crashing the game (#1999) +- fixed exiting the game with Alt+F4 not immediately working in cutscenes +- fixed game freezing when starting demo/credits/inventory offscreen +- fixed controllers dialog missing background in the software renderer mode (#1978, regression from 0.6) +- fixed distant rooms sometimes not appearing, causing the skybox to be visible when it shouldn't (#2000) - removed unused detail level option ## [0.6](https://github.com/LostArtefacts/TRX/compare/tr2-0.5...tr2-0.6) - 2024-11-06 diff --git a/docs/tr2/README.md b/docs/tr2/README.md index bf70ffadb..cffb9b4c4 100644 --- a/docs/tr2/README.md +++ b/docs/tr2/README.md @@ -43,6 +43,9 @@ decompilation process. We recognize that there is much work to be done. - fixed a potential crash if Lara is on the skidoo in a room with many other adjoining rooms - fixed a softlock in Home Sweet Home if the final cutscene is triggered while Lara is on water surface - fixed Lara's left arm becoming stuck if a flare is drawn just before the final cutscene in Home Sweet Home +- fixed game freezing when starting demo/credits/inventory offscreen +- fixed exiting the game with Alt+F4 not immediately working in cutscenes +- fixed a crash when trying to draw too many rooms at once - fixed the following floor data issues: - **Opera House**: fixed the trigger under item 203 to trigger it rather than item 204 - **Wreck of the Maria Doria**: fixed room 98 not having water @@ -62,6 +65,7 @@ decompilation process. We recognize that there is much work to be done. #### Input - added additional custom control schemes - added customizable controller support +- added ability to hold forward/back to move through menus more quickly - fixed setting user keys being very difficult - fixed skipping FMVs triggering inventory - fixed skipping credits working too fast @@ -70,14 +74,19 @@ decompilation process. We recognize that there is much work to be done. - fixed the dragon counting as more than one kill if allowed to revive - fixed enemies that are run over by the skidoo not being counted in the statistics -#### Input -- added ability to hold forward/back to move through menus more quickly - #### Visuals - added support for HD FMVs +- added wireframe mode +- added an option for 1-2-3-4× pixel upscaling +- added the ability to use the window border option at all times +- added the ability to toggle between the software/hardware renderer at runtime +- added fade effects to the hardware renderer +- changed the software renderer to use the picture's palette for the background pictures +- fixed fullscreen issues - fixed TGA screenshots crashing the game - fixed the camera being cut off after using the gong hammer in Ice Palace - fixed Lara's underwater hue being retained when re-entering a boat +- fixed distant rooms sometimes not appearing, causing the skybox to be visible when it shouldn't - improved FMV mode behavior - stopped switching screen resolutions - improved vertex movement when looking through water portals @@ -94,10 +103,13 @@ decompilation process. We recognize that there is much work to be done. - added .jpeg/.png screenshots - added ability to skip FMVs with both the Action key - added ability to skip end credits with the Action and Escape keys +- ported audio decoding library to ffmpeg - ported video decoding library to ffmpeg -- ported audio output library to SDL -- ported input method to SDL +- ported input backend to SDL +- ported audio backend to SDL +- ported video backend to SDL - fixed screenshots not working in windowed mode - fixed screenshots key not getting debounced - changed screenshots to be put in the screenshots/ directory - changed saves to be put in the saves/ directory +- removed `-setup` dialog diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index e89aba359..f4260a5a3 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -80.71% (1004) · 16.88% (210) · 0% (0) · 2.41% (30) +86.33% (1074) · 11.25% (140) · 0% (0) · 2.41% (30) - - + + @@ -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); @@ -1028,7 +1028,7 @@ void __cdecl GameApplySettings(APP_SETTINGS *new_settings); void __cdecl UpdateGameResolution(void); LPCTSTR __cdecl DecodeErrorMessage(DWORD error_code); -BOOL __cdecl ReadFileSync(HANDLE handle, LPVOID lpBuffer, DWORD nBytesToRead, LPDWORD lpnBytesRead, LPOVERLAPPED lpOverlapped); +BOOL __cdecl ReadFileSync(HANDLE handle, LPVOID lpBuffer, DWORD nBytesToRead, LPDWORD lpnBytesRead, LPOVERLAPPED lpOverlapped); BOOL __cdecl Level_LoadTexturePages(HANDLE handle); BOOL __cdecl Level_LoadRooms(HANDLE handle); void __cdecl AdjustTextureUVs(bool reset_uv_add); @@ -1141,14 +1141,14 @@ void __cdecl S_OutputPolyList(void); int32_t __cdecl S_GetObjectBounds(const BOUNDS_16 *bounds); void __cdecl S_InsertBackPolygon(int32_t x0, int32_t y0, int32_t x1, int32_t y1); -void __cdecl S_PrintShadow(int16_t radius, const BOUNDS_16 *bounds, const ITEM *item); +void __cdecl Output_InsertShadow(int16_t radius, const BOUNDS_16 *bounds, const ITEM *item); void __cdecl S_CalculateLight(int32_t x, int32_t y, int32_t z, int16_t room_num); void __cdecl S_CalculateStaticLight(int16_t adder); void __cdecl S_CalculateStaticMeshLight(int32_t x, int32_t y, int32_t z, int32_t shade_1, int32_t shade_2, ROOM *room); void __cdecl S_LightRoom(ROOM *room); -void __cdecl S_DrawHealthBar(int32_t percent); -void __cdecl S_DrawAirBar(int32_t percent); -void __cdecl AnimateTextures(int32_t ticks); +void __cdecl Output_DrawHealthBar(int32_t percent); +void __cdecl Output_DrawAirBar(int32_t percent); +void __cdecl Output_AnimateTextures(int32_t ticks); void __cdecl S_SetupBelowWater(BOOL underwater); void __cdecl S_SetupAboveWater(BOOL underwater); void __cdecl S_AnimateTextures(int32_t ticks); @@ -1161,44 +1161,44 @@ void __cdecl ScreenClear(bool is_phd_win_size); void __cdecl S_CopyScreenToBuffer(void); void __cdecl S_CopyBufferToScreen(void); -BOOL __cdecl DecompPCX(const uint8_t *pcx, size_t pcx_size, LPBYTE pic, RGB_888 *pal); +BOOL __cdecl DecompPCX(const uint8_t *pcx, size_t pcx_size, LPBYTE pic, RGB_888 *pal); sub_4523A0 sub_4523B0 -bool __cdecl OpenGameRegistryKey(LPCTSTR key); -LONG __cdecl CloseGameRegistryKey(void); -bool __cdecl SE_WriteAppSettings(APP_SETTINGS *settings); +bool __cdecl OpenGameRegistryKey(LPCTSTR key); +LONG __cdecl CloseGameRegistryKey(void); +bool __cdecl SE_WriteAppSettings(APP_SETTINGS *settings); int32_t __cdecl SE_ReadAppSettings(APP_SETTINGS *settings); -bool __cdecl SE_GraphicsTestStart(void); -void __cdecl SE_GraphicsTestFinish(void); -int32_t __cdecl SE_GraphicsTestExecute(void); -int32_t __cdecl SE_GraphicsTest(void); -bool __cdecl SE_SoundTestStart(void); -void __cdecl SE_SoundTestFinish(void); -int32_t __cdecl SE_SoundTestExecute(void); -int32_t __cdecl SE_SoundTest(void); -int32_t __stdcall SE_PropSheetCallback(HWND hwndDlg, UINT uMsg, LPARAM lParam); -LRESULT __stdcall SE_NewPropSheetWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -bool __cdecl SE_ShowSetupDialog(HWND hParent, bool isDefault); -INT_PTR __stdcall SE_GraphicsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -void __cdecl SE_GraphicsDlgFullScreenModesUpdate(HWND hwndDlg); -void __cdecl SE_GraphicsAdapterSet(HWND hwndDlg, DISPLAY_ADAPTER_NODE *adapter); -void __cdecl SE_GraphicsDlgUpdate(HWND hwndDlg); -void __cdecl SE_GraphicsDlgInit(HWND hwndDlg); -INT_PTR __stdcall SE_SoundDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -void __cdecl SE_SoundAdapterSet(HWND hwndDlg, SOUND_ADAPTER_NODE *adapter); -void __cdecl SE_SoundDlgUpdate(HWND hwndDlg); -void __cdecl SE_SoundDlgInit(HWND hwndDlg); -INT_PTR __stdcall SE_ControlsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -void __cdecl SE_ControlsJoystickSet(HWND hwndDlg, JOYSTICK_NODE *joystick); -void __cdecl SE_ControlsDlgUpdate(HWND hwndDlg); -void __cdecl SE_ControlsDlgInit(HWND hwndDlg); -INT_PTR __stdcall SE_OptionsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -void __cdecl SE_OptionsDlgUpdate(HWND hwndDlg); -void __cdecl SE_OptionsStrCat(LPTSTR *dstString, bool isEnabled, bool *isNext, LPCTSTR srcString); -INT_PTR __stdcall SE_AdvancedDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -void __cdecl SE_AdvancedDlgUpdate(HWND hwndDlg); -void __cdecl SE_AdvancedDlgInit(HWND hwndDlg); -HWND __cdecl SE_FindSetupDialog(void); +bool __cdecl SE_GraphicsTestStart(void); +void __cdecl SE_GraphicsTestFinish(void); +int32_t __cdecl SE_GraphicsTestExecute(void); +int32_t __cdecl SE_GraphicsTest(void); +bool __cdecl SE_SoundTestStart(void); +void __cdecl SE_SoundTestFinish(void); +int32_t __cdecl SE_SoundTestExecute(void); +int32_t __cdecl SE_SoundTest(void); +int32_t __stdcall SE_PropSheetCallback(HWND hwndDlg, UINT uMsg, LPARAM lParam); +LRESULT __stdcall SE_NewPropSheetWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +bool __cdecl SE_ShowSetupDialog(HWND hParent, bool isDefault); +INT_PTR __stdcall SE_GraphicsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +void __cdecl SE_GraphicsDlgFullScreenModesUpdate(HWND hwndDlg); +void __cdecl SE_GraphicsAdapterSet(HWND hwndDlg, DISPLAY_ADAPTER_NODE *adapter); +void __cdecl SE_GraphicsDlgUpdate(HWND hwndDlg); +void __cdecl SE_GraphicsDlgInit(HWND hwndDlg); +INT_PTR __stdcall SE_SoundDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +void __cdecl SE_SoundAdapterSet(HWND hwndDlg, SOUND_ADAPTER_NODE *adapter); +void __cdecl SE_SoundDlgUpdate(HWND hwndDlg); +void __cdecl SE_SoundDlgInit(HWND hwndDlg); +INT_PTR __stdcall SE_ControlsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +void __cdecl SE_ControlsJoystickSet(HWND hwndDlg, JOYSTICK_NODE *joystick); +void __cdecl SE_ControlsDlgUpdate(HWND hwndDlg); +void __cdecl SE_ControlsDlgInit(HWND hwndDlg); +INT_PTR __stdcall SE_OptionsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +void __cdecl SE_OptionsDlgUpdate(HWND hwndDlg); +void __cdecl SE_OptionsStrCat(LPTSTR *dstString, bool isEnabled, bool *isNext, LPCTSTR srcString); +INT_PTR __stdcall SE_AdvancedDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +void __cdecl SE_AdvancedDlgUpdate(HWND hwndDlg); +void __cdecl SE_AdvancedDlgInit(HWND hwndDlg); +HWND __cdecl SE_FindSetupDialog(void); BOOL __cdecl Shell_Main(void); int16_t __cdecl TitleSequence(void); void __cdecl CheckCheatMode(void); @@ -1249,38 +1249,38 @@ void __cdecl UpdateTicks(void); bool __cdecl TIME_Init(void); DWORD __cdecl Sync(void); -LPVOID __cdecl UT_LoadResource(LPCTSTR lpName, LPCTSTR lpType); +LPVOID __cdecl UT_LoadResource(LPCTSTR lpName, LPCTSTR lpType); void __cdecl UT_InitAccurateTimer(void); double __cdecl UT_Microseconds(void); -BOOL __cdecl UT_CenterWindow(HWND hWnd); -LPTSTR __cdecl UT_FindArg(LPCTSTR str); -int32_t __cdecl UT_MessageBox(LPCTSTR lpText, HWND hWnd); -int32_t __cdecl UT_ErrorBox(UINT uID, HWND hWnd); -LPCTSTR __cdecl GuidBinaryToString(GUID *guid); -bool __cdecl GuidStringToBinary(LPCTSTR lpString, GUID *guid); -BOOL __cdecl OpenRegistryKey(LPCTSTR lpSubKey); -bool __cdecl IsNewRegistryKeyCreated(void); -LONG __cdecl CloseRegistryKey(void); -LONG __cdecl SetRegistryDwordValue(LPCTSTR lpValueName, DWORD value); -LONG __cdecl SetRegistryBoolValue(LPCTSTR lpValueName, bool value); -LONG __cdecl SetRegistryFloatValue(LPCTSTR lpValueName, double value); -LONG __cdecl SetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize); -LONG __cdecl SetRegistryStringValue(LPCTSTR lpValueName, LPCTSTR value, int32_t length); -LONG __cdecl DeleteRegistryValue(LPCTSTR lpValueName); -bool __cdecl GetRegistryDwordValue(LPCTSTR lpValueName, DWORD *pValue, DWORD defaultValue); -bool __cdecl GetRegistryBoolValue(LPCTSTR lpValueName, bool *pValue, bool defaultValue); -bool __cdecl GetRegistryFloatValue(LPCTSTR lpValueName, double *value, double defaultValue); -bool __cdecl GetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize, LPBYTE defaultValue); -bool __cdecl GetRegistryStringValue(LPCTSTR lpValueName, LPTSTR value, DWORD maxSize, LPCTSTR defaultValue); -bool __cdecl GetRegistryGuidValue(LPCTSTR lpValueName, GUID *value, GUID *defaultValue); -void __thiscall SE_ReleaseBitmapResource(BITMAP_RESOURCE *bmpRsrc); -void __thiscall SE_LoadBitmapResource(BITMAP_RESOURCE *bmpRsrc, LPCTSTR lpName); -void __thiscall SE_DrawBitmap(BITMAP_RESOURCE *bmpRsrc, HDC hdc, int32_t x, int32_t y); -void __thiscall SE_UpdateBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd, HWND hSender); -void __thiscall SE_ChangeBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd); -bool __cdecl SE_RegisterSetupWindowClass(void); -LRESULT __stdcall SE_SetupWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -void __cdecl SE_PassMessageToImage(HWND hWnd, UINT uMsg, WPARAM wParam); +BOOL __cdecl UT_CenterWindow(HWND hWnd); +LPTSTR __cdecl UT_FindArg(LPCTSTR str); +int32_t __cdecl UT_MessageBox(LPCTSTR lpText, HWND hWnd); +int32_t __cdecl UT_ErrorBox(UINT uID, HWND hWnd); +LPCTSTR __cdecl GuidBinaryToString(GUID *guid); +bool __cdecl GuidStringToBinary(LPCTSTR lpString, GUID *guid); +BOOL __cdecl OpenRegistryKey(LPCTSTR lpSubKey); +bool __cdecl IsNewRegistryKeyCreated(void); +LONG __cdecl CloseRegistryKey(void); +LONG __cdecl SetRegistryDwordValue(LPCTSTR lpValueName, DWORD value); +LONG __cdecl SetRegistryBoolValue(LPCTSTR lpValueName, bool value); +LONG __cdecl SetRegistryFloatValue(LPCTSTR lpValueName, double value); +LONG __cdecl SetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize); +LONG __cdecl SetRegistryStringValue(LPCTSTR lpValueName, LPCTSTR value, int32_t length); +LONG __cdecl DeleteRegistryValue(LPCTSTR lpValueName); +bool __cdecl GetRegistryDwordValue(LPCTSTR lpValueName, DWORD *pValue, DWORD defaultValue); +bool __cdecl GetRegistryBoolValue(LPCTSTR lpValueName, bool *pValue, bool defaultValue); +bool __cdecl GetRegistryFloatValue(LPCTSTR lpValueName, double *value, double defaultValue); +bool __cdecl GetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize, LPBYTE defaultValue); +bool __cdecl GetRegistryStringValue(LPCTSTR lpValueName, LPTSTR value, DWORD maxSize, LPCTSTR defaultValue); +bool __cdecl GetRegistryGuidValue(LPCTSTR lpValueName, GUID *value, GUID *defaultValue); +void __thiscall SE_ReleaseBitmapResource(BITMAP_RESOURCE *bmpRsrc); +void __thiscall SE_LoadBitmapResource(BITMAP_RESOURCE *bmpRsrc, LPCTSTR lpName); +void __thiscall SE_DrawBitmap(BITMAP_RESOURCE *bmpRsrc, HDC hdc, int32_t x, int32_t y); +void __thiscall SE_UpdateBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd, HWND hSender); +void __thiscall SE_ChangeBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd); +bool __cdecl SE_RegisterSetupWindowClass(void); +LRESULT __stdcall SE_SetupWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +void __cdecl SE_PassMessageToImage(HWND hWnd, UINT uMsg, WPARAM wParam); void __cdecl UT_MemBlt(BYTE *dstBuf, DWORD dstX, DWORD dstY, DWORD width, DWORD height, DWORD dstPitch, BYTE *srcBuf, DWORD srcX, DWORD srcY, DWORD srcPitch); void __cdecl Matrix_Push(void); void __cdecl Matrix_PushUnit(void); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -82.72% · 16.95% · 0% · 0.33% +86.57% · 13.11% · 0% · 0.33% - - + + @@ -1347,7 +1347,7 @@ int32_t __cdecl Requester_Display(REQUEST_INFO *req, int32_t des, int32_t backgrounds); void __cdecl ExtractSaveGameInfo(void); void __cdecl Camera_SmartShift(GAME_VECTOR *target, void (*__cdecl shift)(int32_t *x, int32_t *y, int32_t *h, int32_t target_x, int32_t target_y, int32_t target_h, int32_t left, int32_t top, int32_t right, int32_t bottom)); -void __cdecl SE_GraphicsDlgUpdate(HWND hwndDlg); +void __cdecl SE_GraphicsDlgUpdate(HWND hwndDlg); void __cdecl Output_InsertGT3_Sorted(const PHD_VBUF *vtx0, const PHD_VBUF *vtx1, const PHD_VBUF *vtx2, const PHD_TEXTURE *texture, const PHD_UV *uv0, const PHD_UV *uv1, const PHD_UV *uv2, SORT_TYPE sort_type); void __cdecl Option_Controls(INVENTORY_ITEM *item); BOOL __cdecl GF_LoadFromFile(const char *file_name); @@ -1420,7 +1420,7 @@ void __cdecl Inv_RingNotActive(INVENTORY_ITEM *inv_item); int32_t __cdecl Gun_FireWeapon(LARA_GUN_TYPE weapon_type, ITEM *target, const ITEM *src, const PHD_ANGLE *angles); int32_t __cdecl Game_Control(int32_t nframes, int32_t demo_mode); -INT_PTR __stdcall SE_GraphicsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR __stdcall SE_GraphicsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); int32_t __cdecl SE_ReadAppSettings(APP_SETTINGS *settings); void __cdecl Output_InsertSprite_Sorted(int32_t z, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t sprite_idx, int16_t shade); void __cdecl RollingBall_Control(int16_t item_num); @@ -1443,7 +1443,7 @@ int32_t __cdecl LOS_CheckZ(const GAME_VECTOR *start, GAME_VECTOR *target); int32_t __cdecl Lara_TestVault(ITEM *item, COLL_INFO *coll); void __cdecl WinPlayFMV(const char *file_name, bool is_playback); -bool __cdecl SE_ShowSetupDialog(HWND hParent, bool isDefault); +bool __cdecl SE_ShowSetupDialog(HWND hParent, bool isDefault); void __cdecl Option_Detail(INVENTORY_ITEM *item); int32_t __cdecl Collide_GetSpheres(const ITEM *item, SPHERE *spheres, bool world_space); void __cdecl Skidoo_Draw(const ITEM *item); @@ -1471,9 +1471,9 @@ int32_t __cdecl Room_GetHeight(const SECTOR *sector, int32_t x, int32_t y, int32_t z); BOOL __cdecl Level_LoadSamples(HANDLE handle); 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); +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); @@ -1481,10 +1481,10 @@ int32_t __cdecl Room_GetCeiling(const SECTOR *sector, int32_t x, int32_t y, int32_t z); void __cdecl Detonator_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); void __cdecl GameApplySettings(APP_SETTINGS *new_settings); -LRESULT __stdcall SE_SetupWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +LRESULT __stdcall SE_SetupWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void __cdecl MovableBlock_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); int32_t __cdecl Lara_TestClimbUpPos(ITEM *item, int32_t front, int32_t right, int32_t *shift, int32_t *ledge); -void __cdecl SE_OptionsDlgUpdate(HWND hwndDlg); +void __cdecl SE_OptionsDlgUpdate(HWND hwndDlg); int32_t __cdecl Skidoo_CheckGetOff(void); void __cdecl DisplayCredits(void); void __cdecl Gun_Pistols_Undraw(LARA_GUN_TYPE weapon_type); @@ -1510,11 +1510,11 @@ void __cdecl Bird_Control(int16_t item_num); void __cdecl BodyPart_Control(int16_t fx_num); void __cdecl Skidoo_BaddieCollision(const ITEM *skidoo); -void __cdecl S_DrawAirBar(int32_t percent); +void __cdecl Output_DrawAirBar(int32_t percent); void __cdecl Screenshot(LPDDS screen); void __cdecl Mine_Control(int16_t mine_num); int32_t __cdecl Box_SearchLOT(LOT_INFO *lot, int32_t expansion); -void __cdecl S_PrintShadow(int16_t radius, const BOUNDS_16 *bounds, const ITEM *item); +void __cdecl Output_InsertShadow(int16_t radius, const BOUNDS_16 *bounds, const ITEM *item); void __cdecl Lara_WaterCurrent(COLL_INFO *coll); int32_t __cdecl GF_LoadScriptFile(const char *fname); void __cdecl Matrix_RotYXZpack(uint32_t rpack); @@ -1522,7 +1522,7 @@ void __cdecl Eel_Control(int16_t item_num); void __cdecl Matrix_RotYXZ(int16_t ry, int16_t rx, int16_t rz); void __cdecl Mouse_Control(int16_t item_num); -void __cdecl SE_GraphicsDlgFullScreenModesUpdate(HWND hwndDlg); +void __cdecl SE_GraphicsDlgFullScreenModesUpdate(HWND hwndDlg); void __cdecl Creature_GetBaddieTarget(int16_t item_num, int32_t goody); void __cdecl Flare_Create(int32_t thrown); void __cdecl ShowGymStatsText(char *time_str, int32_t type); @@ -1530,7 +1530,7 @@ int32_t __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int32_t nShowCmd); const int16_t *__cdecl Output_CalcObjectVertices(const int16_t *obj_ptr); void __cdecl Matrix_GenerateW2V(PHD_3DPOS *viewpos); -void __cdecl S_DrawHealthBar(int32_t percent); +void __cdecl Output_DrawHealthBar(int32_t percent); void __cdecl Output_InsertFlatRect_ZBuffered(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t z, uint8_t color_idx); void __cdecl FadeToPal(int32_t fade_value, RGB_888 *palette); void __cdecl Room_GetBounds(void); @@ -1576,7 +1576,7 @@ void __cdecl Output_InsertFlatRect_Sorted(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t z, uint8_t color_idx); void __cdecl Twinkle_Control(int16_t fx_num); void __cdecl S_Audio_Sample_Init2(HWND hwnd); -void __cdecl SE_GraphicsDlgInit(HWND hwndDlg); +void __cdecl SE_GraphicsDlgInit(HWND hwndDlg); void __cdecl SpinningBlade_Control(int16_t item_num); void __cdecl Lift_FloorCeiling(const ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *floor, int32_t *ceiling); void __cdecl Lara_Col_Run(ITEM *item, COLL_INFO *coll); @@ -1611,7 +1611,7 @@ const int16_t *__cdecl Output_InsertRoomSprite(const int16_t *obj_ptr, int32_t vtx_count); void __cdecl Lara_Col_Climbing(ITEM *item, COLL_INFO *coll); void __cdecl Gun_DrawFlash(LARA_GUN_TYPE weapon_type, int32_t clip); -INT_PTR __stdcall SE_SoundDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR __stdcall SE_SoundDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); void __cdecl Lara_State_Stop(ITEM *item, COLL_INFO *coll); void __cdecl MovableBlock_Control(int16_t item_num); void __cdecl Effect_Draw(int16_t fx_num); @@ -1657,7 +1657,7 @@ void __cdecl Gun_InitialiseNewWeapon(void); void __cdecl Lara_Col_UpJump(ITEM *item, COLL_INFO *coll); void __cdecl Skidoo_Guns(void); -void __cdecl SE_SoundDlgUpdate(HWND hwndDlg); +void __cdecl SE_SoundDlgUpdate(HWND hwndDlg); HRESULT __stdcall EnumTextureFormatsCallback(LPDDSDESC lpDdsd, LPVOID lpContext); void __cdecl SkidooArmed_Push(const ITEM *item, ITEM *lara_item, int32_t radius); void __cdecl Jelly_Control(int16_t item_num); @@ -1683,7 +1683,7 @@ int32_t __cdecl Diver_GetWaterSurface(int32_t x, int32_t y, int32_t z, int16_t room_num); void __cdecl LOT_InitialiseSlot(int16_t item_num, int32_t slot); int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); -INT_PTR __stdcall SE_ControlsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR __stdcall SE_ControlsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); TEXTSTRING *__cdecl Text_Create(int32_t x, int32_t y, int32_t z, const char *text); void __cdecl FallingBlock_Control(int16_t item_num); void __cdecl FmvBackToGame(void); @@ -1696,7 +1696,7 @@ void __cdecl Switch_CollisionUW(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); void __cdecl Lara_Col_Back(ITEM *item, COLL_INFO *coll); void __cdecl Lara_InitialiseMeshes(int32_t level_num); -BOOL __cdecl DecompPCX(const uint8_t *pcx, size_t pcx_size, LPBYTE pic, RGB_888 *pal); +BOOL __cdecl DecompPCX(const uint8_t *pcx, size_t pcx_size, LPBYTE pic, RGB_888 *pal); int32_t __cdecl Boat_TestWaterHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); int32_t __cdecl Creature_CheckBaddieOverlap(int16_t item_num); void __cdecl Flare_DrawInAir(const ITEM *item); @@ -1739,8 +1739,8 @@ 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); -INT_PTR __stdcall SE_AdvancedDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +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); void __cdecl SpringBoard_Control(int16_t item_num); @@ -1752,7 +1752,7 @@ void __cdecl MiniCopterControl(int16_t item_num); void __cdecl Camera_Clip(int32_t *x, int32_t *y, int32_t *h, int32_t target_x, int32_t target_y, int32_t target_h, int32_t left, int32_t top, int32_t right, int32_t bottom); void __cdecl Lara_Col_ForwardJump(ITEM *item, COLL_INFO *coll); -bool __cdecl SE_GraphicsTestStart(void); +bool __cdecl SE_GraphicsTestStart(void); int16_t __cdecl Creature_Turn(ITEM *item, int16_t maximum_turn); void __cdecl WinVidSetDisplayAdapter(DISPLAY_ADAPTER *disp_adapter); void __cdecl Lift_Control(int16_t item_num); @@ -1775,7 +1775,7 @@ void __cdecl Door_Control(int16_t item_num); BYTE __cdecl FindNearestPaletteEntry(RGB_888 *palette, int32_t red, int32_t green, int32_t blue, bool ignore_sys_palette); void __cdecl Output_RotateLight(int16_t pitch, int16_t yaw); -bool __cdecl SE_SoundTestStart(void); +bool __cdecl SE_SoundTestStart(void); sub_4449D0 bool __cdecl WinVidCreateGameWindow(void); BOOL __cdecl GF_ReadStringTable(DWORD count, char **string_table, char **string_buf, LPDWORD buf_size, HANDLE handle); @@ -1784,22 +1784,22 @@ void __cdecl Window_Smash(int16_t item_num); bool __cdecl S_Audio_Sample_DSoundBufferTest(void); BOOL __cdecl S_ReloadLevelGraphics(BOOL reload_palettes, BOOL reload_tex_pages); -void __thiscall SE_LoadBitmapResource(BITMAP_RESOURCE *bmpRsrc, LPCTSTR lpName); +void __thiscall SE_LoadBitmapResource(BITMAP_RESOURCE *bmpRsrc, LPCTSTR lpName); void __cdecl Splash(ITEM *item); int32_t __cdecl Inv_GetItemOption(GAME_OBJECT_ID object_id); void __cdecl Gun_AimWeapon(WEAPON_INFO *winfo, LARA_ARM *arm); void __cdecl Requester_ChangeItem(REQUEST_INFO *req, int32_t item, const char *text1, uint32_t flags1, const char *text2, uint32_t flags2); void __cdecl Option_Compass(INVENTORY_ITEM *item); -void __cdecl AnimateTextures(int32_t ticks); +void __cdecl Output_AnimateTextures(int32_t ticks); void __cdecl Zipline_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); void __cdecl Lara_Col_StepRight(ITEM *item, COLL_INFO *coll); int32_t __cdecl Lara_TestClimbStance(ITEM *item, COLL_INFO *coll); -void __cdecl SE_SoundDlgInit(HWND hwndDlg); +void __cdecl SE_SoundDlgInit(HWND hwndDlg); void __cdecl GongBonger_Control(int16_t item_num); int32_t __cdecl Switch_Trigger(int16_t item_num, int16_t timer); void __cdecl TeethTrap_Control(int16_t item_num); HRESULT __stdcall Enum3DDevicesCallback(GUID *lpGuid, LPTSTR lpDeviceDescription, LPTSTR lpDeviceName, LPD3DDEVICEDESC lpD3DHWDeviceDesc, LPD3DDEVICEDESC lpD3DHELDeviceDesc, LPVOID lpContext); -void __cdecl SE_ControlsDlgInit(HWND hwndDlg); +void __cdecl SE_ControlsDlgInit(HWND hwndDlg); void __cdecl Lara_State_Extra_PullDagger(ITEM *item, COLL_INFO *coll); int32_t __cdecl Lara_TestClimbPos(ITEM *item, int32_t front, int32_t right, int32_t origin, int32_t height, int32_t *shift); bool __cdecl WinVidCheckGameWindowPalette(HWND hWnd); @@ -1842,7 +1842,7 @@ void __cdecl Requester_SetHeading(REQUEST_INFO *req, char *text1, uint32_t flags1, char *text2, uint32_t flags2); int32_t __cdecl Lara_CheckForLetGo(ITEM *item, COLL_INFO *coll); void __cdecl Gun_FindTargetPoint(const ITEM *item, GAME_VECTOR *target); -bool __cdecl GuidStringToBinary(LPCTSTR lpString, GUID *guid); +bool __cdecl GuidStringToBinary(LPCTSTR lpString, GUID *guid); void __cdecl Matrix_RotY(int16_t ry); void __cdecl Matrix_RotZ(int16_t rz); void __cdecl Creature_Float(int16_t item_num); @@ -1896,17 +1896,17 @@ void __cdecl Output_SetNearZ(int32_t near_z); void __cdecl Box_TargetBox(LOT_INFO *lot, int16_t box_num); void __cdecl Lara_Col_TurnRight(ITEM *item, COLL_INFO *coll); -bool __cdecl GetRegistryStringValue(LPCTSTR lpValueName, LPTSTR value, DWORD maxSize, LPCTSTR defaultValue); +bool __cdecl GetRegistryStringValue(LPCTSTR lpValueName, LPTSTR value, DWORD maxSize, LPCTSTR defaultValue); void __cdecl CreatePrimarySurface(void); void __cdecl Room_InitCinematic(void); void __cdecl Effect_NewRoom(int16_t fx_num, int16_t room_num); -void __cdecl SE_AdvancedDlgUpdate(HWND hwndDlg); +void __cdecl SE_AdvancedDlgUpdate(HWND hwndDlg); int32_t __cdecl Item_GetFrames(const ITEM *item, FRAME_INFO *frmptr[], int32_t *rate); void __cdecl Music_SetVolume(int32_t volume); const int16_t *__cdecl Output_InsertObjectGT4_ZBuffered(const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); void __cdecl Lara_State_Extra_SharkKill(ITEM *item, COLL_INFO *coll); void __cdecl Blade_Control(int16_t item_num); -bool __cdecl GetRegistryGuidValue(LPCTSTR lpValueName, GUID *value, GUID *defaultValue); +bool __cdecl GetRegistryGuidValue(LPCTSTR lpValueName, GUID *value, GUID *defaultValue); void __cdecl Lara_Col_Reach(ITEM *item, COLL_INFO *coll); int32_t __cdecl GetCollisionAnim(ITEM *skidoo, XYZ_32 *moved); void __cdecl FlameEmitter_Control(int16_t item_num); @@ -1927,7 +1927,7 @@ void __cdecl Item_RemoveActive(int16_t item_num); void __cdecl Lara_State_TurnRight(ITEM *item, COLL_INFO *coll); BOOL __cdecl Level_LoadDemo(HANDLE handle); -INT_PTR __stdcall SE_OptionsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR __stdcall SE_OptionsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); void __cdecl Bird_Initialise(int16_t item_num); void __cdecl Inv_SelectMeshes(INVENTORY_ITEM *inv_item); void __cdecl Lara_ResetLook(void); @@ -1992,7 +1992,7 @@ int16_t __cdecl Knife(int32_t x, int32_t y, int32_t z, int16_t speed, PHD_ANGLE yrot, int16_t room_num); void __cdecl DrawHair(void); void __cdecl Lara_State_Glide(ITEM *item, COLL_INFO *coll); -bool __cdecl GetRegistryBoolValue(LPCTSTR lpValueName, bool *pValue, bool defaultValue); +bool __cdecl GetRegistryBoolValue(LPCTSTR lpValueName, bool *pValue, bool defaultValue); int16_t __cdecl Lara_FloorFront(ITEM *item, PHD_ANGLE ang, int32_t dist); void __cdecl Lara_State_ClimbStance(ITEM *item, COLL_INFO *coll); void __cdecl Window_Initialise(int16_t item_num); @@ -2005,14 +2005,14 @@ void __cdecl Splash_Control(int16_t fx_num); void __thiscall WinVidGetColorBitMasks(COLOR_BIT_MASKS *bm, LPDDPIXELFORMAT pixel_format); BOOL __cdecl Level_LoadPalettes(HANDLE handle); -bool __cdecl GetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize, LPBYTE defaultValue); +bool __cdecl GetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize, LPBYTE defaultValue); void __cdecl Gun_Rifle_Ready(LARA_GUN_TYPE weapon_type); void __cdecl Lara_State_SurfSwim(ITEM *item, COLL_INFO *coll); void __cdecl CreatePictureBuffer(void); int32_t __cdecl Box_UpdateLOT(LOT_INFO *lot, int32_t expansion); void __cdecl Item_RemoveDrawn(int16_t item_num); void __cdecl Music_Legacy_Play(int16_t track_id, bool is_looped); -BOOL __cdecl UT_CenterWindow(HWND hWnd); +BOOL __cdecl UT_CenterWindow(HWND hWnd); void __cdecl UT_MemBlt(BYTE *dstBuf, DWORD dstX, DWORD dstY, DWORD width, DWORD height, DWORD dstPitch, BYTE *srcBuf, DWORD srcX, DWORD srcY, DWORD srcPitch); int32_t __cdecl Output_VisibleZClip(const PHD_VBUF *vtx0, const PHD_VBUF *vtx1, const PHD_VBUF *vtx2); void __cdecl Overlay_AddDisplayPickup(GAME_OBJECT_ID object_id); @@ -2033,7 +2033,7 @@ void __cdecl Object_SetupAllObjects(void); sub_4470F0 sub_447AC0 -void __cdecl SE_ControlsDlgUpdate(HWND hwndDlg); +void __cdecl SE_ControlsDlgUpdate(HWND hwndDlg); void __cdecl Object_Collision_Trap(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); void __cdecl AlarmSound_Control(int16_t item_num); int32_t __cdecl Lara_HitCeiling(ITEM *item, COLL_INFO *coll); @@ -2043,7 +2043,7 @@ int16_t __cdecl GunShot(int32_t x, int32_t y, int32_t z, int16_t speed, PHD_ANGLE yrot, int16_t room_num); void __cdecl CreateBubble(XYZ_32 *pos, int16_t room_num); int32_t __cdecl GameInit(bool skip_cd_init); -void __thiscall SE_DrawBitmap(BITMAP_RESOURCE *bmpRsrc, HDC hdc, int32_t x, int32_t y); +void __thiscall SE_DrawBitmap(BITMAP_RESOURCE *bmpRsrc, HDC hdc, int32_t x, int32_t y); void __cdecl FX_SwapMeshesWithMeshSwap1(ITEM *item); void __cdecl FX_SwapMeshesWithMeshSwap2(ITEM *item); void __cdecl Inv_Ring_MotionInit(RING_INFO *ring, int16_t frames, int16_t status, int16_t status_target); @@ -2054,7 +2054,7 @@ void __cdecl InitialiseGameFlags(void); DWORD __cdecl CalculateCompatibleColor(COLOR_BIT_MASKS *mask, int32_t red, int32_t green, int32_t blue, int32_t alpha); int32_t __cdecl Music_GetFrames(void); -bool __cdecl SE_RegisterSetupWindowClass(void); +bool __cdecl SE_RegisterSetupWindowClass(void); void __fastcall Output_FlatA(int32_t y0, int32_t y1, uint8_t color_idx); // actually, __watcall, which is esoteric and rarely supported void __cdecl Inv_Ring_GetView(RING_INFO *ring, PHD_3DPOS *viewer); void __cdecl Lara_State_SurfLeft(ITEM *item, COLL_INFO *coll); @@ -2067,18 +2067,18 @@ sub_444AB0 void __cdecl Lara_State_SurfBack(ITEM *item, COLL_INFO *coll); void __cdecl Sound_StopEffect(int32_t sample_id); -bool __cdecl GetRegistryDwordValue(LPCTSTR lpValueName, DWORD *pValue, DWORD defaultValue); +bool __cdecl GetRegistryDwordValue(LPCTSTR lpValueName, DWORD *pValue, DWORD defaultValue); void __cdecl Item_UpdateRoom(ITEM *item, int32_t height); void __cdecl BirdTweeter_Control(int16_t item_num); void __cdecl Inv_Ring_MotionItemSelect(RING_INFO *ring, INVENTORY_ITEM *inv_item); void __cdecl Lara_Col_ClimbLeft(ITEM *item, COLL_INFO *coll); void __cdecl BaddieBiteEffect(ITEM *item, BITE *bite); -LRESULT __stdcall SE_NewPropSheetWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +LRESULT __stdcall SE_NewPropSheetWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); int16_t __cdecl Creature_Effect(ITEM *item, BITE *bite, int16_t (*__cdecl spawn)(int32_t x, int32_t y, int32_t z, int16_t speed, int16_t y_rot, int16_t room_num)); void __cdecl Room_AddFlipItems(ROOM *r); void __cdecl Gun_Pistols_Ready(LARA_GUN_TYPE weapon_type); BOOL __cdecl S_InitialiseSystem(void); -bool __cdecl GetRegistryFloatValue(LPCTSTR lpValueName, double *value, double defaultValue); +bool __cdecl GetRegistryFloatValue(LPCTSTR lpValueName, double *value, double defaultValue); void __cdecl Lara_Col_UWDeath(ITEM *item, COLL_INFO *coll); void __cdecl Item_AddActive(int16_t item_num); void __cdecl WinInReadKeyboard(LPVOID lpInputData); @@ -2095,9 +2095,9 @@ DWORD __cdecl Sync(void); void __cdecl Lara_State_FastBack(ITEM *item, COLL_INFO *coll); void __cdecl S_Wait(int32_t timeout, BOOL input_check); -int32_t __cdecl SE_GraphicsTest(void); -int32_t __cdecl SE_SoundTest(void); -void __thiscall SE_ChangeBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd); +int32_t __cdecl SE_GraphicsTest(void); +int32_t __cdecl SE_SoundTest(void); +void __thiscall SE_ChangeBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd); void __cdecl Requester_Item_RightAlign(REQUEST_INFO *req, TEXTSTRING *txt); void __cdecl Room_GetNewRoom(int32_t x, int32_t y, int32_t z, int16_t room_num); void __cdecl Object_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); @@ -2118,7 +2118,7 @@ void __cdecl S_SetupBelowWater(BOOL underwater); void __cdecl Music_Shutdown(void); bool __cdecl TIME_Init(void); -LPCTSTR __cdecl GuidBinaryToString(GUID *guid); +LPCTSTR __cdecl GuidBinaryToString(GUID *guid); void __cdecl Creature_Underwater(ITEM *item, int32_t depth); const SECTOR *__cdecl Camera_GoodPosition(int32_t x, int32_t y, int32_t z, int16_t room_num); void __cdecl Cultist3_Initialise(int16_t item_num); @@ -2131,7 +2131,7 @@ int32_t __cdecl MovableBlock_TestDestination(ITEM *item, int32_t block_height); void __cdecl GunFlash_Control(int16_t fx_num); JOYSTICK_NODE *__cdecl GetJoystick(GUID *lpGuid); -bool __cdecl OpenGameRegistryKey(LPCTSTR key); +bool __cdecl OpenGameRegistryKey(LPCTSTR key); double __cdecl UT_Microseconds(void); void __cdecl Lara_State_Extra_StartAnim(ITEM *item, COLL_INFO *coll); void __cdecl BGND_Free(void); @@ -2144,16 +2144,16 @@ void __cdecl Lara_State_FastTurn(ITEM *item, COLL_INFO *coll); void __cdecl Flare_SetArm(int32_t frame); void __cdecl DartEffect_Control(int16_t fx_num); -void __cdecl SE_OptionsStrCat(LPTSTR *dstString, bool isEnabled, bool *isNext, LPCTSTR srcString); +void __cdecl SE_OptionsStrCat(LPTSTR *dstString, bool isEnabled, bool *isNext, LPCTSTR srcString); void __cdecl Lara_State_BackJump(ITEM *item, COLL_INFO *coll); DISPLAY_MODE *__thiscall InsertDisplayModeInListTail(DISPLAY_MODE_LIST *modeList); void __cdecl HWR_EnableColorKey(bool state); void __cdecl HWR_FreeTexturePages(void); -LONG __cdecl SetRegistryStringValue(LPCTSTR lpValueName, LPCTSTR value, int32_t length); +LONG __cdecl SetRegistryStringValue(LPCTSTR lpValueName, LPCTSTR value, int32_t length); void __cdecl Creature_Head(ITEM *item, int16_t required); void __cdecl LOT_ClearLOT(LOT_INFO *lot); void __cdecl Lara_CatchFire(void); -BOOL __cdecl ReadFileSync(HANDLE handle, LPVOID lpBuffer, DWORD nBytesToRead, LPDWORD lpnBytesRead, LPOVERLAPPED lpOverlapped); +BOOL __cdecl ReadFileSync(HANDLE handle, LPVOID lpBuffer, DWORD nBytesToRead, LPDWORD lpnBytesRead, LPOVERLAPPED lpOverlapped); void __cdecl AddDynamicLight(int32_t x, int32_t y, int32_t z, int32_t intensity, int32_t falloff); int32_t __cdecl CalculateWindowWidth(int32_t width, int32_t height); DISPLAY_ADAPTER_NODE *__cdecl WinVidGetDisplayAdapter(GUID *lpGuid); @@ -2183,7 +2183,7 @@ void __cdecl WinVidShowGameWindow(int32_t nCmdShow); void __cdecl S_FadeToBlack(void); void __cdecl Door_Shut(DOORPOS_DATA *d); -int32_t __cdecl UT_ErrorBox(UINT uID, HWND hWnd); +int32_t __cdecl UT_ErrorBox(UINT uID, HWND hWnd); void __cdecl Matrix_TranslateRel_I(int32_t x, int32_t y, int32_t z); void __cdecl Matrix_RotYXZ_I(int16_t y, int16_t x, int16_t z); void __cdecl WinVidSetMinWindowSize(int32_t width, int32_t height); @@ -2201,12 +2201,12 @@ void __cdecl FallingBlock_Floor(const ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *out_height); void __cdecl Enumerate3DDevices(DISPLAY_ADAPTER *adapter); DWORD __cdecl EncodePutPCX(BYTE value, BYTE num, BYTE *buffer); -int32_t __stdcall SE_PropSheetCallback(HWND hwndDlg, UINT uMsg, LPARAM lParam); +int32_t __stdcall SE_PropSheetCallback(HWND hwndDlg, UINT uMsg, LPARAM lParam); HWR_TEXTURE_HANDLE __cdecl GetTexturePageHandle(int32_t page_idx); void __cdecl Matrix_RotYXZsuperpack_I(const int16_t **pprot1, const int16_t **pprot2, int32_t skip); int32_t __cdecl Keyhole_Trigger(int16_t item_num); HRESULT __cdecl WinVidBufferLock(LPDDS surface, LPDDSDESC desc, DWORD flags); -int32_t __cdecl SE_SoundTestExecute(void); +int32_t __cdecl SE_SoundTestExecute(void); void __cdecl Output_DrawPolyGTMap(const int16_t *obj_ptr); void __cdecl Output_DrawPolyWGTMap(const int16_t *obj_ptr); void __cdecl Boat_Initialise(int16_t item_num); @@ -2251,15 +2251,15 @@ uint32_t __cdecl Text_GetScaleH(uint32_t value); bool __cdecl D3DIsSupported(LPD3DDEVICEDESC desc); void __cdecl S_InitialiseScreen(GAMEFLOW_LEVEL_TYPE level_type); -LONG __cdecl SetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize); -void __thiscall SE_ReleaseBitmapResource(BITMAP_RESOURCE *bmpRsrc); +LONG __cdecl SetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize); +void __thiscall SE_ReleaseBitmapResource(BITMAP_RESOURCE *bmpRsrc); void __cdecl Output_PrintPolyList(uint8_t *surface_ptr); void __cdecl Lara_Col_Default(ITEM *item, COLL_INFO *coll); void __cdecl Drawbridge_Floor(const ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *out_height); void __cdecl ChangeFileNameExtension(char *file_name, const char *file_ext); DWORD __cdecl S_DumpScreen(void); -LPVOID __cdecl UT_LoadResource(LPCTSTR lpName, LPCTSTR lpType); -LONG __cdecl SetRegistryFloatValue(LPCTSTR lpValueName, double value); +LPVOID __cdecl UT_LoadResource(LPCTSTR lpName, LPCTSTR lpType); +LONG __cdecl SetRegistryFloatValue(LPCTSTR lpValueName, double value); void __cdecl Output_DrawPolyFlat(const int16_t *obj_ptr); void __cdecl Output_DrawPolyTrans(const int16_t *obj_ptr); void __cdecl Output_DrawPolyGouraud(const int16_t *obj_ptr); @@ -2316,7 +2316,7 @@ void __cdecl BridgeTilt1_Floor(const ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *out_height); bool __cdecl BGND_Init(void); void __cdecl CleanupTextures(void); -BOOL __cdecl OpenRegistryKey(LPCTSTR lpSubKey); +BOOL __cdecl OpenRegistryKey(LPCTSTR lpSubKey); void __cdecl Creature_Initialise(int16_t item_num); int32_t __cdecl Room_FindGridShift(int32_t src, int32_t dst); void __cdecl Inv_Ring_RotateLeft(RING_INFO *ring); @@ -2340,7 +2340,7 @@ void __cdecl Drawbridge_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); void __cdecl Text_Init(void); void __cdecl S_Audio_Sample_AdjustTrackVolumeAndPan(int32_t track_id, int32_t volume, int32_t pan); -LPTSTR __cdecl UT_FindArg(LPCTSTR str); +LPTSTR __cdecl UT_FindArg(LPCTSTR str); uint32_t __fastcall Math_Sqrt(uint32_t n); void __cdecl Lara_State_Slide(ITEM *item, COLL_INFO *coll); void __cdecl Gun_Rifle_UndrawMeshes(LARA_GUN_TYPE weapon_type); @@ -2352,7 +2352,7 @@ void __cdecl S_Audio_Sample_Shutdown(void); void __cdecl S_UnloadLevelFile(void); int32_t __cdecl S_Audio_Sample_CalculateSampleVolume(int32_t volume); -LONG __cdecl SetRegistryBoolValue(LPCTSTR lpValueName, bool value); +LONG __cdecl SetRegistryBoolValue(LPCTSTR lpValueName, bool value); void __cdecl Text_AddOutline(TEXTSTRING *string, int16_t enable, int16_t color, uint16_t *gour_ptr, uint16_t flags); void __cdecl DInputKeyboardRelease(void); void __cdecl HWR_ResetTexSource(void); @@ -2368,7 +2368,7 @@ void __cdecl ScreenClear(bool is_phd_win_size); int32_t __cdecl S_Audio_Sample_CalculateSamplePan(int16_t pan); void __cdecl FreeTexturePages(void); -void __cdecl SE_PassMessageToImage(HWND hWnd, UINT uMsg, WPARAM wParam); +void __cdecl SE_PassMessageToImage(HWND hWnd, UINT uMsg, WPARAM wParam); void __cdecl Inv_Ring_MotionCameraPos(RING_INFO *ring, int16_t target); int32_t __cdecl Text_Remove(TEXTSTRING *string); HRESULT __cdecl WinVidBufferUnlock(LPDDS surface, LPDDSDESC desc); @@ -2419,7 +2419,7 @@ void __cdecl Text_AlignBottom(TEXTSTRING *string, int16_t enable); int32_t __cdecl Random_GetControl(void); int32_t __cdecl Random_GetDraw(void); -LONG __cdecl SetRegistryDwordValue(LPCTSTR lpValueName, DWORD value); +LONG __cdecl SetRegistryDwordValue(LPCTSTR lpValueName, DWORD value); void __cdecl Matrix_Push(void); void __cdecl Lara_State_Special(ITEM *item, COLL_INFO *coll); void __cdecl Lara_State_Extra_GongBong(ITEM *item, COLL_INFO *coll); @@ -2434,7 +2434,7 @@ void __cdecl S_Audio_Sample_OutSetPitch(int32_t track_id, int32_t pitch); int32_t __cdecl GetFreePaletteIndex(void); int32_t __cdecl GetFreeTexturePageIndex(void); -void __thiscall SE_UpdateBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd, HWND hSender); +void __thiscall SE_UpdateBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd, HWND hSender); void __cdecl Inv_RemoveAllItems(void); void __cdecl Requester_Item_CenterAlign(REQUEST_INFO *req, TEXTSTRING *txt); void __cdecl Lara_ControlExtra(int16_t item_num); @@ -2456,12 +2456,12 @@ sub_447A80 sub_447B30 BOOL __cdecl S_LoadLevelFile(LPCTSTR file_name, int32_t level_num, GAMEFLOW_LEVEL_TYPE level_type); -int32_t __cdecl UT_MessageBox(LPCTSTR lpText, HWND hWnd); +int32_t __cdecl UT_MessageBox(LPCTSTR lpText, HWND hWnd); void __cdecl FX_AssaultReset(ITEM *item); void __cdecl Text_SetScale(TEXTSTRING *string, int32_t scale_h, int32_t scale_v); void __cdecl WinInRunControlPanel(HWND hWnd); sub_44E860 -void __cdecl SE_GraphicsAdapterSet(HWND hwndDlg, DISPLAY_ADAPTER_NODE *adapter); +void __cdecl SE_GraphicsAdapterSet(HWND hwndDlg, DISPLAY_ADAPTER_NODE *adapter); void __cdecl S_Audio_Sample_OutCloseTrack(int32_t track_id); void __cdecl FX_Turn180(ITEM *item); void __cdecl FX_InvisibilityOff(ITEM *item); @@ -2475,7 +2475,7 @@ void __cdecl Lara_State_ClimbDown(ITEM *item, COLL_INFO *coll); void __cdecl Lara_State_Dive(ITEM *item, COLL_INFO *coll); void __cdecl S_AdjustTexelCoordinates(void); -void __cdecl SE_GraphicsTestFinish(void); +void __cdecl SE_GraphicsTestFinish(void); void __cdecl Requester_RemoveAllItems(REQUEST_INFO *req); void __cdecl Lara_State_UpJump(ITEM *item, COLL_INFO *coll); void __cdecl Lara_State_Extra_Airlock(ITEM *item, COLL_INFO *coll); @@ -2487,7 +2487,7 @@ void __thiscall S_FlaggedString_Delete(STRING_FLAGGED *string); void __cdecl WinVidFinish(void); bool __cdecl S_IntroFMV(const char *file_name1, const char *file_name2); -LONG __cdecl DeleteRegistryValue(LPCTSTR lpValueName); +LONG __cdecl DeleteRegistryValue(LPCTSTR lpValueName); sub_4449A0 DISPLAY_MODE *__thiscall InsertDisplayMode(DISPLAY_MODE_LIST *modeList, DISPLAY_MODE_NODE *before); sub_4470C0 @@ -2495,19 +2495,19 @@ void __cdecl SafeFreePalette(int32_t palette_idx); HWND __cdecl WinVidFindGameWindow(void); void __cdecl GameBuf_Shutdown(void); -HWND __cdecl SE_FindSetupDialog(void); +HWND __cdecl SE_FindSetupDialog(void); void __cdecl Text_RemoveBackground(TEXTSTRING *string); void __cdecl Text_RemoveOutline(TEXTSTRING *string); sub_44E880 void __cdecl ScreenPartialDump(void); void __cdecl WinInFinish(void); void __cdecl S_FinishInventory(void); -bool __cdecl IsNewRegistryKeyCreated(void); +bool __cdecl IsNewRegistryKeyCreated(void); bool __cdecl S_PlayFMV(const char *file_name); -void __cdecl SE_AdvancedDlgInit(HWND hwndDlg); +void __cdecl SE_AdvancedDlgInit(HWND hwndDlg); void __thiscall DisplayModeListInit(DISPLAY_MODE_LIST *pList); void __cdecl ScreenDump(void); -LONG __cdecl CloseRegistryKey(void); +LONG __cdecl CloseRegistryKey(void); LPCTSTR __cdecl DecodeErrorMessage(DWORD error_code); void __cdecl FX_FinishLevel(ITEM *item); void __cdecl FX_DynamicLightOff(ITEM *item); @@ -2519,8 +2519,8 @@ void __cdecl Lara_State_Splat(ITEM *item, COLL_INFO *coll); void __cdecl Random_SeedControl(int32_t seed); void __cdecl Random_SeedDraw(int32_t seed); -void __cdecl SE_SoundAdapterSet(HWND hwndDlg, SOUND_ADAPTER_NODE *adapter); -void __cdecl SE_ControlsJoystickSet(HWND hwndDlg, JOYSTICK_NODE *joystick); +void __cdecl SE_SoundAdapterSet(HWND hwndDlg, SOUND_ADAPTER_NODE *adapter); +void __cdecl SE_ControlsJoystickSet(HWND hwndDlg, JOYSTICK_NODE *joystick); void __cdecl Sound_SetMasterVolume(int32_t volume); void __cdecl FX_InvisibilityOn(ITEM *item); void __cdecl FX_DynamicLightOn(ITEM *item); @@ -2566,10 +2566,10 @@ sub_447FA0 sub_448410 sub_4523A0 -LONG __cdecl CloseGameRegistryKey(void); -void __cdecl SE_SoundTestFinish(void); +LONG __cdecl CloseGameRegistryKey(void); +void __cdecl SE_SoundTestFinish(void); bool __cdecl RenderInit(void); -int32_t __cdecl SE_GraphicsTestExecute(void); +int32_t __cdecl SE_GraphicsTestExecute(void); void __cdecl Output_InsertInventoryBackground(const int16_t *obj_ptr); sub_444BC0 sub_448420 diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index f34330346..248f62dbe 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -1,12 +1,12 @@ # TYPES -typedef IDirect3DDevice2 *LPDIRECT3DDEVICE2; -typedef IDirect3DTexture2 *LPDIRECT3DTEXTURE2; -typedef IDirect3DViewport2 *LPDIRECT3DVIEWPORT2; -typedef IDirect3DMaterial2 *LPDIRECT3DMATERIAL2; -typedef DDSURFACEDESC DDSDESC, *LPDDSDESC; -typedef LPDIRECTDRAWSURFACE3 LPDDS; -typedef LPDIRECTDRAW3 LPDD; -typedef D3DTEXTUREHANDLE HWR_TEXTURE_HANDLE; +typedef IDirect3DDevice2 *LPDIRECT3DDEVICE2; // decompiled +typedef IDirect3DTexture2 *LPDIRECT3DTEXTURE2; // decompiled +typedef IDirect3DViewport2 *LPDIRECT3DVIEWPORT2; // decompiled +typedef IDirect3DMaterial2 *LPDIRECT3DMATERIAL2; // decompiled +typedef DDSURFACEDESC DDSDESC, *LPDDSDESC; // decompiled +typedef LPDIRECTDRAWSURFACE3 LPDDS; // decompiled +typedef LPDIRECTDRAW3 LPDD; // decompiled +typedef D3DTEXTUREHANDLE HWR_TEXTURE_HANDLE; // decompiled typedef int16_t PHD_ANGLE; @@ -51,31 +51,31 @@ typedef struct __unaligned { DWORD flags; } BITMAP_RESOURCE; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled int32_t width; int32_t height; int32_t bpp; VGA_MODE vga; } DISPLAY_MODE; -typedef struct __unaligned DISPLAY_MODE_NODE { +typedef struct __unaligned DISPLAY_MODE_NODE { // decompiled struct DISPLAY_MODE_NODE *next; struct DISPLAY_MODE_NODE *previous; DISPLAY_MODE body; } DISPLAY_MODE_NODE; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled DISPLAY_MODE_NODE *head; DISPLAY_MODE_NODE *tail; DWORD count; } DISPLAY_MODE_LIST; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled char *content; bool is_valid; } STRING_FLAGGED; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled LPGUID adapter_guid_ptr; GUID adapter_guid; STRING_FLAGGED driver_desc; @@ -101,51 +101,51 @@ typedef struct __unaligned { bool shade_restricted; } DISPLAY_ADAPTER; -typedef struct __unaligned DISPLAY_ADAPTER_NODE { +typedef struct __unaligned DISPLAY_ADAPTER_NODE { // decompiled struct DISPLAY_ADAPTER_NODE *next; struct DISPLAY_ADAPTER_NODE *previous; DISPLAY_ADAPTER body; } DISPLAY_ADAPTER_NODE; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled DISPLAY_ADAPTER_NODE *head; DISPLAY_ADAPTER_NODE *tail; DWORD count; } DISPLAY_ADAPTER_LIST; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled GUID *adapter_guid_ptr; GUID adapter_guid; STRING_FLAGGED description; STRING_FLAGGED module; } SOUND_ADAPTER; -typedef struct __unaligned SOUND_ADAPTER_NODE { +typedef struct __unaligned SOUND_ADAPTER_NODE { // decompiled struct SOUND_ADAPTER_NODE *next; struct SOUND_ADAPTER_NODE *previous; SOUND_ADAPTER body; } SOUND_ADAPTER_NODE; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled SOUND_ADAPTER_NODE *head; SOUND_ADAPTER_NODE *tail; DWORD count; } SOUND_ADAPTER_LIST; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled GUID *lpJoystickGuid; GUID joystickGuid; STRING_FLAGGED productName; STRING_FLAGGED instanceName; } JOYSTICK; -typedef struct __unaligned JOYSTICK_NODE { +typedef struct __unaligned JOYSTICK_NODE { // decompiled struct JOYSTICK_NODE *next; struct JOYSTICK_NODE *previous; JOYSTICK body; } JOYSTICK_NODE; -typedef struct __unaligned JOYSTICK_LIST { +typedef struct __unaligned JOYSTICK_LIST { // decompiled struct JOYSTICK_LIST *head; struct JOYSTICK_LIST *tail; DWORD count; @@ -167,9 +167,9 @@ typedef enum { TAM_DISABLED = 0, TAM_BILINEAR_ONLY = 1, TAM_ALWAYS = 2, -} TEX_ADJUST_MODE; +} TEXEL_ADJUST_MODE; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled DISPLAY_ADAPTER_NODE *preferred_display_adapter; SOUND_ADAPTER_NODE *preferred_sound_adapter; JOYSTICK_NODE *preferred_joystick; @@ -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; @@ -190,12 +190,12 @@ typedef struct __unaligned { bool disable_16bit_textures; bool dont_sort_primitives; bool flip_broken; - TEX_ADJUST_MODE texel_adjust_mode; + TEXEL_ADJUST_MODE texel_adjust_mode; int32_t nearest_adjustment; int32_t linear_adjustment; } APP_SETTINGS; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled LPDDS sys_mem_surface; LPDDS vid_mem_surface; LPDIRECTDRAWPALETTE palette; @@ -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 { @@ -228,11 +249,11 @@ typedef struct { } mask, depth, offset; } COLOR_BIT_MASKS; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled D3DCOLOR clr[4][4]; } GOURAUD_FILL; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled D3DCOLOR clr[9]; } GOURAUD_OUTLINE; @@ -319,7 +340,7 @@ typedef struct __unaligned { uint16_t v; } PHD_UV; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled uint16_t draw_type; uint16_t tex_page; PHD_UV uv[4]; @@ -369,7 +390,7 @@ typedef struct __unaligned { float g; } POINT_INFO; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled float x; float y; float rhw; @@ -462,7 +483,7 @@ typedef struct __unaligned { int32_t _1; } SORT_ITEM; -typedef enum { +typedef enum { // decompiled ST_AVG_Z = 0, ST_MAX_Z = 1, ST_FAR_Z = 2, @@ -2644,7 +2665,7 @@ typedef enum { ACE_WATER = 2, } ANIM_COMMAND_ENVIRONMENT; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled DDPIXELFORMAT pixel_fmt; COLOR_BIT_MASKS color_bit_masks; DWORD bpp; @@ -2694,6 +2715,14 @@ typedef struct __unaligned { int16_t mesh_rots[]; } FRAME_INFO; +typedef struct __unaligned { // decompiled + XYZ_16 pos; + int16_t radius; + int16_t poly_count; + int16_t vertex_count; + XYZ_16 vertex[32]; +} SHADOW_INFO; + typedef enum { // decompiled TO_OBJECT = 0, TO_CAMERA = 1, @@ -3789,9 +3818,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); @@ -3943,7 +3972,7 @@ typedef enum { 0x00449610 0x023A +R void __cdecl GameApplySettings(APP_SETTINGS *new_settings); 0x00449850 0x0067 +R void __cdecl UpdateGameResolution(void); 0x004498C0 0x000C +R LPCTSTR __cdecl DecodeErrorMessage(DWORD error_code); -0x004498D0 0x0049 -R BOOL __cdecl ReadFileSync(HANDLE handle, LPVOID lpBuffer, DWORD nBytesToRead, LPDWORD lpnBytesRead, LPOVERLAPPED lpOverlapped); +0x004498D0 0x0049 @R BOOL __cdecl ReadFileSync(HANDLE handle, LPVOID lpBuffer, DWORD nBytesToRead, LPDWORD lpnBytesRead, LPOVERLAPPED lpOverlapped); 0x00449920 0x0188 + BOOL __cdecl Level_LoadTexturePages(HANDLE handle); 0x00449AB0 0x03A0 + BOOL __cdecl Level_LoadRooms(HANDLE handle); 0x00449E50 0x0097 +R void __cdecl AdjustTextureUVs(bool reset_uv_add); @@ -4056,14 +4085,14 @@ typedef enum { 0x00450C80 0x0089 +R void __cdecl S_OutputPolyList(void); 0x00450CC0 0x0270 -R int32_t __cdecl S_GetObjectBounds(const BOUNDS_16 *bounds); 0x00450F30 0x0046 +R void __cdecl S_InsertBackPolygon(int32_t x0, int32_t y0, int32_t x1, int32_t y1); -0x00450F80 0x01F1 -R void __cdecl S_PrintShadow(int16_t radius, const BOUNDS_16 *bounds, const ITEM *item); +0x00450F80 0x01F1 + void __cdecl Output_InsertShadow(int16_t radius, const BOUNDS_16 *bounds, const ITEM *item); 0x00451180 0x02F6 -R void __cdecl S_CalculateLight(int32_t x, int32_t y, int32_t z, int16_t room_num); 0x00451480 0x0031 -R void __cdecl S_CalculateStaticLight(int16_t adder); 0x004514C0 0x0124 -R void __cdecl S_CalculateStaticMeshLight(int32_t x, int32_t y, int32_t z, int32_t shade_1, int32_t shade_2, ROOM *room); 0x004515F0 0x0206 -R void __cdecl S_LightRoom(ROOM *room); -0x00451800 0x01CC -R void __cdecl S_DrawHealthBar(int32_t percent); -0x004519D0 0x01F6 -R void __cdecl S_DrawAirBar(int32_t percent); -0x00451BD0 0x00C0 -R void __cdecl AnimateTextures(int32_t ticks); +0x00451800 0x01CC + void __cdecl Output_DrawHealthBar(int32_t percent); +0x004519D0 0x01F6 + void __cdecl Output_DrawAirBar(int32_t percent); +0x00451BD0 0x00C0 + void __cdecl Output_AnimateTextures(int32_t ticks); 0x00451C90 0x0051 -R void __cdecl S_SetupBelowWater(BOOL underwater); 0x00451CF0 0x0021 -R void __cdecl S_SetupAboveWater(BOOL underwater); 0x00451D20 0x00B1 -R void __cdecl S_AnimateTextures(int32_t ticks); @@ -4076,44 +4105,44 @@ typedef enum { 0x00452170 0x0026 +R void __cdecl ScreenClear(bool is_phd_win_size); 0x004521A0 0x00AB +R void __cdecl S_CopyScreenToBuffer(void); 0x00452250 0x0254 +R void __cdecl S_CopyBufferToScreen(void); -0x004522A0 0x00FA -R BOOL __cdecl DecompPCX(const uint8_t *pcx, size_t pcx_size, LPBYTE pic, RGB_888 *pal); +0x004522A0 0x00FA @R BOOL __cdecl DecompPCX(const uint8_t *pcx, size_t pcx_size, LPBYTE pic, RGB_888 *pal); 0x004523A0 0x0005 x sub_4523A0 0x004523B0 0x0001 x sub_4523B0 -0x004523C0 0x004E -R bool __cdecl OpenGameRegistryKey(LPCTSTR key); -0x00452410 0x0005 -R LONG __cdecl CloseGameRegistryKey(void); -0x00452420 0x0262 -R bool __cdecl SE_WriteAppSettings(APP_SETTINGS *settings); -0x00452690 0x0348 +R int32_t __cdecl SE_ReadAppSettings(APP_SETTINGS *settings); -0x004529E0 0x00D7 -R bool __cdecl SE_GraphicsTestStart(void); -0x00452AB0 0x0014 -R void __cdecl SE_GraphicsTestFinish(void); -0x00452AD0 0x0003 -R int32_t __cdecl SE_GraphicsTestExecute(void); -0x00452AE0 0x0057 -R int32_t __cdecl SE_GraphicsTest(void); -0x00452B40 0x00C7 -R bool __cdecl SE_SoundTestStart(void); -0x00452C00 0x0005 -R void __cdecl SE_SoundTestFinish(void); -0x00452C10 0x003D -R int32_t __cdecl SE_SoundTestExecute(void); -0x00452C50 0x0057 -R int32_t __cdecl SE_SoundTest(void); -0x00452CB0 0x003E -R int32_t __stdcall SE_PropSheetCallback(HWND hwndDlg, UINT uMsg, LPARAM lParam); -0x00452CF0 0x005D -R LRESULT __stdcall SE_NewPropSheetWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -0x00452D50 0x02DE -R bool __cdecl SE_ShowSetupDialog(HWND hParent, bool isDefault); -0x00453030 0x0351 -R INT_PTR __stdcall SE_GraphicsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -0x004533F0 0x01DC -R void __cdecl SE_GraphicsDlgFullScreenModesUpdate(HWND hwndDlg); -0x004535E0 0x0017 -R void __cdecl SE_GraphicsAdapterSet(HWND hwndDlg, DISPLAY_ADAPTER_NODE *adapter); -0x00453600 0x0735 -R void __cdecl SE_GraphicsDlgUpdate(HWND hwndDlg); -0x00453D40 0x017C -R void __cdecl SE_GraphicsDlgInit(HWND hwndDlg); -0x00453EC0 0x0149 -R INT_PTR __stdcall SE_SoundDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -0x00454050 0x000A -R void __cdecl SE_SoundAdapterSet(HWND hwndDlg, SOUND_ADAPTER_NODE *adapter); -0x00454060 0x011B -R void __cdecl SE_SoundDlgUpdate(HWND hwndDlg); -0x00454180 0x00BE -R void __cdecl SE_SoundDlgInit(HWND hwndDlg); -0x00454240 0x0106 -R INT_PTR __stdcall SE_ControlsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -0x00454350 0x000A -R void __cdecl SE_ControlsJoystickSet(HWND hwndDlg, JOYSTICK_NODE *joystick); -0x00454360 0x0068 -R void __cdecl SE_ControlsDlgUpdate(HWND hwndDlg); -0x004543D0 0x00BD -R void __cdecl SE_ControlsDlgInit(HWND hwndDlg); -0x00454490 0x008A -R INT_PTR __stdcall SE_OptionsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -0x00454520 0x0234 -R void __cdecl SE_OptionsDlgUpdate(HWND hwndDlg); -0x00454760 0x004B -R void __cdecl SE_OptionsStrCat(LPTSTR *dstString, bool isEnabled, bool *isNext, LPCTSTR srcString); -0x004547B0 0x00DC -R INT_PTR __stdcall SE_AdvancedDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -0x004548B0 0x0093 -R void __cdecl SE_AdvancedDlgUpdate(HWND hwndDlg); -0x00454950 0x000E -R void __cdecl SE_AdvancedDlgInit(HWND hwndDlg); -0x00454960 0x0011 -R HWND __cdecl SE_FindSetupDialog(void); +0x004523C0 0x004E @R bool __cdecl OpenGameRegistryKey(LPCTSTR key); +0x00452410 0x0005 @R LONG __cdecl CloseGameRegistryKey(void); +0x00452420 0x0262 @R bool __cdecl SE_WriteAppSettings(APP_SETTINGS *settings); +0x00452690 0x0348 @R int32_t __cdecl SE_ReadAppSettings(APP_SETTINGS *settings); +0x004529E0 0x00D7 @R bool __cdecl SE_GraphicsTestStart(void); +0x00452AB0 0x0014 @R void __cdecl SE_GraphicsTestFinish(void); +0x00452AD0 0x0003 @R int32_t __cdecl SE_GraphicsTestExecute(void); +0x00452AE0 0x0057 @R int32_t __cdecl SE_GraphicsTest(void); +0x00452B40 0x00C7 @R bool __cdecl SE_SoundTestStart(void); +0x00452C00 0x0005 @R void __cdecl SE_SoundTestFinish(void); +0x00452C10 0x003D @R int32_t __cdecl SE_SoundTestExecute(void); +0x00452C50 0x0057 @R int32_t __cdecl SE_SoundTest(void); +0x00452CB0 0x003E @R int32_t __stdcall SE_PropSheetCallback(HWND hwndDlg, UINT uMsg, LPARAM lParam); +0x00452CF0 0x005D @R LRESULT __stdcall SE_NewPropSheetWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +0x00452D50 0x02DE @R bool __cdecl SE_ShowSetupDialog(HWND hParent, bool isDefault); +0x00453030 0x0351 @R INT_PTR __stdcall SE_GraphicsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +0x004533F0 0x01DC @R void __cdecl SE_GraphicsDlgFullScreenModesUpdate(HWND hwndDlg); +0x004535E0 0x0017 @R void __cdecl SE_GraphicsAdapterSet(HWND hwndDlg, DISPLAY_ADAPTER_NODE *adapter); +0x00453600 0x0735 @R void __cdecl SE_GraphicsDlgUpdate(HWND hwndDlg); +0x00453D40 0x017C @R void __cdecl SE_GraphicsDlgInit(HWND hwndDlg); +0x00453EC0 0x0149 @R INT_PTR __stdcall SE_SoundDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +0x00454050 0x000A @R void __cdecl SE_SoundAdapterSet(HWND hwndDlg, SOUND_ADAPTER_NODE *adapter); +0x00454060 0x011B @R void __cdecl SE_SoundDlgUpdate(HWND hwndDlg); +0x00454180 0x00BE @R void __cdecl SE_SoundDlgInit(HWND hwndDlg); +0x00454240 0x0106 @R INT_PTR __stdcall SE_ControlsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +0x00454350 0x000A @R void __cdecl SE_ControlsJoystickSet(HWND hwndDlg, JOYSTICK_NODE *joystick); +0x00454360 0x0068 @R void __cdecl SE_ControlsDlgUpdate(HWND hwndDlg); +0x004543D0 0x00BD @R void __cdecl SE_ControlsDlgInit(HWND hwndDlg); +0x00454490 0x008A @R INT_PTR __stdcall SE_OptionsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +0x00454520 0x0234 @R void __cdecl SE_OptionsDlgUpdate(HWND hwndDlg); +0x00454760 0x004B @R void __cdecl SE_OptionsStrCat(LPTSTR *dstString, bool isEnabled, bool *isNext, LPCTSTR srcString); +0x004547B0 0x00DC @R INT_PTR __stdcall SE_AdvancedDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +0x004548B0 0x0093 @R void __cdecl SE_AdvancedDlgUpdate(HWND hwndDlg); +0x00454950 0x000E @R void __cdecl SE_AdvancedDlgInit(HWND hwndDlg); +0x00454960 0x0011 @R HWND __cdecl SE_FindSetupDialog(void); 0x00454980 0x02D0 + BOOL __cdecl Shell_Main(void); 0x00454C50 0x0110 +R int16_t __cdecl TitleSequence(void); 0x00454D60 0x032D -R void __cdecl CheckCheatMode(void); @@ -4164,38 +4193,38 @@ typedef enum { 0x00456490 0x0040 @R void __cdecl UpdateTicks(void); 0x004564D0 0x0051 @R bool __cdecl TIME_Init(void); 0x00456530 0x0058 +R DWORD __cdecl Sync(void); -0x00456590 0x0036 -R LPVOID __cdecl UT_LoadResource(LPCTSTR lpName, LPCTSTR lpType); +0x00456590 0x0036 @R LPVOID __cdecl UT_LoadResource(LPCTSTR lpName, LPCTSTR lpType); 0x004565D0 0x0060 @R void __cdecl UT_InitAccurateTimer(void); 0x00456630 0x004E @R double __cdecl UT_Microseconds(void); -0x00456680 0x006F -R BOOL __cdecl UT_CenterWindow(HWND hWnd); -0x004566F0 0x002C -R LPTSTR __cdecl UT_FindArg(LPCTSTR str); -0x00456720 0x0018 -R int32_t __cdecl UT_MessageBox(LPCTSTR lpText, HWND hWnd); -0x00456740 0x0042 -R int32_t __cdecl UT_ErrorBox(UINT uID, HWND hWnd); -0x00456790 0x0051 -R LPCTSTR __cdecl GuidBinaryToString(GUID *guid); -0x004567F0 0x00AA -R bool __cdecl GuidStringToBinary(LPCTSTR lpString, GUID *guid); -0x004568A0 0x0030 -R BOOL __cdecl OpenRegistryKey(LPCTSTR lpSubKey); -0x004568D0 0x000F -R bool __cdecl IsNewRegistryKeyCreated(void); -0x004568E0 0x000D -R LONG __cdecl CloseRegistryKey(void); -0x004568F0 0x001E -R LONG __cdecl SetRegistryDwordValue(LPCTSTR lpValueName, DWORD value); -0x00456910 0x002A -R LONG __cdecl SetRegistryBoolValue(LPCTSTR lpValueName, bool value); -0x00456940 0x0036 -R LONG __cdecl SetRegistryFloatValue(LPCTSTR lpValueName, double value); -0x00456980 0x0037 -R LONG __cdecl SetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize); -0x004569C0 0x004A -R LONG __cdecl SetRegistryStringValue(LPCTSTR lpValueName, LPCTSTR value, int32_t length); -0x00456A10 0x0013 -R LONG __cdecl DeleteRegistryValue(LPCTSTR lpValueName); -0x00456A30 0x005E -R bool __cdecl GetRegistryDwordValue(LPCTSTR lpValueName, DWORD *pValue, DWORD defaultValue); -0x00456A90 0x0076 -R bool __cdecl GetRegistryBoolValue(LPCTSTR lpValueName, bool *pValue, bool defaultValue); -0x00456B10 0x005C -R bool __cdecl GetRegistryFloatValue(LPCTSTR lpValueName, double *value, double defaultValue); -0x00456B70 0x0071 -R bool __cdecl GetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize, LPBYTE defaultValue); -0x00456BF0 0x0095 -R bool __cdecl GetRegistryStringValue(LPCTSTR lpValueName, LPTSTR value, DWORD maxSize, LPCTSTR defaultValue); -0x00456C90 0x0091 -R bool __cdecl GetRegistryGuidValue(LPCTSTR lpValueName, GUID *value, GUID *defaultValue); -0x00456D30 0x0037 -R void __thiscall SE_ReleaseBitmapResource(BITMAP_RESOURCE *bmpRsrc); -0x00456D70 0x00C4 -R void __thiscall SE_LoadBitmapResource(BITMAP_RESOURCE *bmpRsrc, LPCTSTR lpName); -0x00456E40 0x0064 -R void __thiscall SE_DrawBitmap(BITMAP_RESOURCE *bmpRsrc, HDC hdc, int32_t x, int32_t y); -0x00456EB0 0x001C -R void __thiscall SE_UpdateBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd, HWND hSender); -0x00456ED0 0x0057 -R void __thiscall SE_ChangeBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd); -0x00456F30 0x0061 -R bool __cdecl SE_RegisterSetupWindowClass(void); -0x00456FA0 0x023A -R LRESULT __stdcall SE_SetupWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -0x004571E0 0x0026 -R void __cdecl SE_PassMessageToImage(HWND hWnd, UINT uMsg, WPARAM wParam); +0x00456680 0x006F @R BOOL __cdecl UT_CenterWindow(HWND hWnd); +0x004566F0 0x002C @R LPTSTR __cdecl UT_FindArg(LPCTSTR str); +0x00456720 0x0018 @R int32_t __cdecl UT_MessageBox(LPCTSTR lpText, HWND hWnd); +0x00456740 0x0042 @R int32_t __cdecl UT_ErrorBox(UINT uID, HWND hWnd); +0x00456790 0x0051 @R LPCTSTR __cdecl GuidBinaryToString(GUID *guid); +0x004567F0 0x00AA @R bool __cdecl GuidStringToBinary(LPCTSTR lpString, GUID *guid); +0x004568A0 0x0030 @R BOOL __cdecl OpenRegistryKey(LPCTSTR lpSubKey); +0x004568D0 0x000F @R bool __cdecl IsNewRegistryKeyCreated(void); +0x004568E0 0x000D @R LONG __cdecl CloseRegistryKey(void); +0x004568F0 0x001E @R LONG __cdecl SetRegistryDwordValue(LPCTSTR lpValueName, DWORD value); +0x00456910 0x002A @R LONG __cdecl SetRegistryBoolValue(LPCTSTR lpValueName, bool value); +0x00456940 0x0036 @R LONG __cdecl SetRegistryFloatValue(LPCTSTR lpValueName, double value); +0x00456980 0x0037 @R LONG __cdecl SetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize); +0x004569C0 0x004A @R LONG __cdecl SetRegistryStringValue(LPCTSTR lpValueName, LPCTSTR value, int32_t length); +0x00456A10 0x0013 @R LONG __cdecl DeleteRegistryValue(LPCTSTR lpValueName); +0x00456A30 0x005E @R bool __cdecl GetRegistryDwordValue(LPCTSTR lpValueName, DWORD *pValue, DWORD defaultValue); +0x00456A90 0x0076 @R bool __cdecl GetRegistryBoolValue(LPCTSTR lpValueName, bool *pValue, bool defaultValue); +0x00456B10 0x005C @R bool __cdecl GetRegistryFloatValue(LPCTSTR lpValueName, double *value, double defaultValue); +0x00456B70 0x0071 @R bool __cdecl GetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize, LPBYTE defaultValue); +0x00456BF0 0x0095 @R bool __cdecl GetRegistryStringValue(LPCTSTR lpValueName, LPTSTR value, DWORD maxSize, LPCTSTR defaultValue); +0x00456C90 0x0091 @R bool __cdecl GetRegistryGuidValue(LPCTSTR lpValueName, GUID *value, GUID *defaultValue); +0x00456D30 0x0037 @R void __thiscall SE_ReleaseBitmapResource(BITMAP_RESOURCE *bmpRsrc); +0x00456D70 0x00C4 @R void __thiscall SE_LoadBitmapResource(BITMAP_RESOURCE *bmpRsrc, LPCTSTR lpName); +0x00456E40 0x0064 @R void __thiscall SE_DrawBitmap(BITMAP_RESOURCE *bmpRsrc, HDC hdc, int32_t x, int32_t y); +0x00456EB0 0x001C @R void __thiscall SE_UpdateBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd, HWND hSender); +0x00456ED0 0x0057 @R void __thiscall SE_ChangeBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd); +0x00456F30 0x0061 @R bool __cdecl SE_RegisterSetupWindowClass(void); +0x00456FA0 0x023A @R LRESULT __stdcall SE_SetupWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +0x004571E0 0x0026 @R void __cdecl SE_PassMessageToImage(HWND hWnd, UINT uMsg, WPARAM wParam); 0x00457210 0x006E -R void __cdecl UT_MemBlt(BYTE *dstBuf, DWORD dstX, DWORD dstY, DWORD width, DWORD height, DWORD dstPitch, BYTE *srcBuf, DWORD srcX, DWORD srcY, DWORD srcPitch); 0x00457280 0x001E + void __cdecl Matrix_Push(void); 0x0045729E 0x0033 + void __cdecl Matrix_PushUnit(void); @@ -4246,7 +4275,7 @@ typedef enum { 0x00464060 - uint32_t g_PerspectiveDistance = 0x3000000; 0x00464068 - void (*__cdecl g_PolyDrawRoutines[9])(const int16_t *obj_ptr); -0x0046408C - float g_RhwFactor = 335544320.0f; // 10*2**25 +0x0046408C + float g_RhwFactor = 335544320.0f; // 10*2**25 0x004640B0 - int32_t g_CineTrackID = 1; 0x004640B8 - int32_t g_CineTickRate = 0x8000; // 0x8000 = PHD_ONE/TICKS_PER_FRAME 0x004640BC + int16_t g_CD_TrackID = -1; @@ -4293,22 +4322,22 @@ typedef enum { 0x0047031C - float g_FltWinBottom; 0x00470320 - float g_FltResZBuf; 0x00470324 - float g_FltResZ; -0x00470328 - void (*__cdecl g_Output_InsertTransQuad)(int32_t x, int32_t y, int32_t width, int32_t height, int32_t z); +0x00470328 + void (*__cdecl g_Output_InsertTransQuad)(int32_t x, int32_t y, int32_t width, int32_t height, int32_t z); 0x0047032C - int32_t g_PhdWinHeight; 0x00470330 - int32_t g_PhdWinCenterX; 0x00470334 - int32_t g_PhdWinCenterY; 0x00470338 - int16_t g_LsYaw; -0x0047033C - void (*__cdecl g_Output_InsertTrans8)(const PHD_VBUF *vbuf, int16_t shade); +0x0047033C + void (*__cdecl g_Output_InsertTrans8)(const PHD_VBUF *vbuf, int16_t shade); 0x00470340 - float g_FltWinTop; 0x00470348 - SORT_ITEM g_SortBuffer[4000]; 0x00478048 - float g_FltWinLeft; -0x0047804C - int16_t g_PhdWinMinY; +0x0047804C + int16_t g_PhdWinMinY; 0x00478058 - int32_t g_PhdFarZ; 0x0047805C - float g_FltRhwOPersp; 0x00478060 - int32_t g_PhdWinBottom; 0x00478064 - int32_t g_PhdPersp; 0x00478068 - int32_t g_PhdWinLeft; -0x0047806C - void (*__cdecl g_Output_InsertFlatRect)(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t z, uint8_t color_idx); +0x0047806C + void (*__cdecl g_Output_InsertFlatRect)(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t z, uint8_t color_idx); 0x00478070 - int16_t g_Info3DBuffer[120000]; 0x004B29F0 - int32_t g_PhdWinMaxX; 0x004B29F4 - int32_t g_PhdNearZ; @@ -4316,35 +4345,35 @@ typedef enum { 0x004B29FC - float g_FltFarZ; 0x004B2A00 - float g_FltWinCenterX; 0x004B2A04 - float g_FltWinCenterY; -0x004B2A08 - int32_t g_PhdScreenHeight; -0x004B2A0C - uint8_t *g_PrintSurfacePtr; -0x004B2A10 - int16_t g_PhdWinMinX; +0x004B2A08 + int32_t g_PhdScreenHeight; +0x004B2A0C + uint8_t *g_PrintSurfacePtr; +0x004B2A10 + int16_t g_PhdWinMinX; 0x004B2A14 - float g_FltPerspONearZ; 0x004B2A18 - float g_FltRhwONearZ; 0x004B2A1C - int32_t g_PhdWinMaxY; -0x004B2A20 - void (*__cdecl g_Output_InsertSprite)(int32_t z, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t sprite_idx, int16_t shade); +0x004B2A20 + void (*__cdecl g_Output_InsertSprite)(int32_t z, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t sprite_idx, int16_t shade); 0x004B2A24 - float g_FltNearZ; 0x004B2A28 - MATRIX *g_MatrixPtr; -0x004B2A2C - const int16_t *(*__cdecl g_Output_DrawObjectGT3)(const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); -0x004B2A30 - const int16_t *(*__cdecl g_Output_DrawObjectGT4)(const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); +0x004B2A2C + const int16_t *(*__cdecl g_Output_DrawObjectGT3)(const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); +0x004B2A30 + const int16_t *(*__cdecl g_Output_DrawObjectGT4)(const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); 0x004B2A38 - int32_t g_RandomTable[32]; 0x004B2AB8 - float g_FltPersp; 0x004B2AC0 - MATRIX g_W2VMatrix; 0x004B2AF0 - int16_t *g_Info3DPtr; 0x004B2AF4 - int32_t g_PhdWinWidth; -0x004B2AF8 - void (*__cdecl g_Output_InsertLine)(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t z, uint8_t color_idx); -0x004B2B00 - PHD_TEXTURE g_PhdTextureInfo[0x800]; +0x004B2AF8 + void (*__cdecl g_Output_InsertLine)(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t z, uint8_t color_idx); +0x004B2B00 + PHD_TEXTURE g_TextureInfo[0x800]; // MAX_TEXTURES 0x004BCB00 - int32_t g_PhdViewDistance; 0x004BCB04 - int16_t g_LsPitch; -0x004BCB08 - const int16_t *(*__cdecl g_Output_DrawObjectG4)(const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); +0x004BCB08 + const int16_t *(*__cdecl g_Output_DrawObjectG4)(const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); 0x004BCB10 - int16_t g_ShadesTable[32]; -0x004BCB50 - const int16_t *(*__cdecl g_Output_DrawObjectG3)(const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); +0x004BCB50 + const int16_t *(*__cdecl g_Output_DrawObjectG3)(const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); 0x004BCB58 - MATRIX g_MatrixStack[]; 0x004BD2D8 - DEPTHQ_ENTRY g_DepthQTable[32]; -0x004BF3D8 - int32_t g_PhdScreenWidth; +0x004BF3D8 + int32_t g_PhdScreenWidth; 0x004BF3DC - int32_t g_LsDivider; 0x004BF3E0 - PHD_VBUF g_PhdVBuf[1500]; -0x004CAF60 - void *g_XBuffer; // no-dereferencing +0x004CAF60 + void *g_XBuffer; 0x004D6AE0 - uint8_t *g_TexturePageBuffer8[32]; // MAX_TEXTURE_PAGES 0x004D6B60 - float g_FltWinRight; 0x004D6B68 - XYZ_32 g_LsVectorView; @@ -4355,9 +4384,9 @@ typedef enum { 0x004D6C0C - int32_t g_WibbleOffset; 0x004D6C10 - int32_t g_IsWibbleEffect; 0x004D6C14 - int32_t g_IsWaterEffect; -0x004D6CD8 - VERTEX_INFO g_VBuffer[20]; +0x004D6CD8 + VERTEX_INFO g_VBuffer[20]; 0x004D6F78 - int8_t g_IsShadeEffect; -0x004D6F80 - D3DTLVERTEX g_VBufferD3D[32]; +0x004D6F80 + D3DTLVERTEX g_VBufferD3D[32]; 0x004D7380 - PALETTEENTRY g_GamePalette16[256]; 0x004D7780 - int32_t g_CineFrameCurrent; 0x004D778C - int32_t g_IsChunkyCamera; @@ -4365,7 +4394,7 @@ typedef enum { 0x004D7798 + BOOL g_IsResetFlag; 0x004D779C - int32_t g_FlipTimer; 0x004D77A0 - int32_t g_LOSNumRooms = 0; -0x004D77A4 - BOOL g_StopInventory; +0x004D77A4 + BOOL g_StopInventory; 0x004D77AC - BOOL g_IsDemoLevelType; 0x004D77B0 - BOOL g_IsDemoLoaded; 0x004D77C0 - int32_t g_BoundStart; @@ -4400,67 +4429,67 @@ typedef enum { 0x004D7C38 - int32_t g_LevelItemCount; 0x004D7C3C - int32_t g_HealthBarTimer; 0x004D7C80 - int32_t g_SoundTrackIds[128]; -0x004D7EBC - LPDIRECT3DDEVICE2 g_D3DDev; -0x004D7EE4 - bool g_IsGameWindowCreated; -0x004D7EE8 - bool g_IsGameWindowUpdating; -0x004D7EEC - bool g_IsDDrawGameWindowShow; +0x004D7EBC + LPDIRECT3DDEVICE2 g_D3DDev; +0x004D7EE4 + bool g_IsGameWindowCreated; +0x004D7EE8 + bool g_IsGameWindowUpdating; +0x004D7EEC + bool g_IsDDrawGameWindowShow; 0x004D7EF0 - int32_t g_MinWindowClientWidth; 0x004D7ED0 - int32_t g_MinWindowClientHeight; 0x004D8388 - int32_t g_MinWindowWidth; 0x004D838C - int32_t g_MinWindowHeight; -0x004D7EF4 - bool g_IsGameWindowShow; +0x004D7EF4 + bool g_IsGameWindowShow; 0x004D7EF8 - bool g_IsMinWindowSizeSet; 0x004D7EFC - int32_t g_MaxWindowClientWidth; -0x004D7F00 - int32_t g_GameWindowWidth; -0x004D7F04 - bool g_IsMinMaxInfoSpecial; -0x004D7F08 - bool g_IsGameFullScreen; -0x004D7F0C - bool g_IsGameWindowMaximized; +0x004D7F00 + int32_t g_GameWindowWidth; +0x004D7F04 + bool g_IsMinMaxInfoSpecial; +0x004D7F08 + bool g_IsGameFullScreen; +0x004D7F0C + bool g_IsGameWindowMaximized; 0x004D7F10 - HWND g_GameWindowHandle; -0x004D7F14 - int32_t g_GameWindowHeight; -0x004D7F18 - DISPLAY_ADAPTER_NODE* g_PrimaryDisplayAdapter; -0x004D7F20 - DISPLAY_ADAPTER g_CurrentDisplayAdapter; +0x004D7F14 + int32_t g_GameWindowHeight; +0x004D7F18 + DISPLAY_ADAPTER_NODE* g_PrimaryDisplayAdapter; +0x004D7F20 + DISPLAY_ADAPTER g_CurrentDisplayAdapter; 0x004D8338 - uint32_t g_LockedBufferCount; -0x004D833C - int32_t g_GameWindowPositionX; -0x004D8340 - int32_t g_GameWindowPositionY; +0x004D833C + int32_t g_GameWindowPositionX; +0x004D8340 + int32_t g_GameWindowPositionY; 0x004D8348 - DISPLAY_ADAPTER_LIST g_DisplayAdapterList; 0x004D8354 - int32_t g_MaxWindowClientHeight; -0x004D8358 - bool g_IsMessageLoopClosed; +0x004D8358 + bool g_IsMessageLoopClosed; 0x004D835C - int32_t g_MaxWindowWidth; 0x004D7EDC - int32_t g_MaxWindowHeight; 0x004D8360 - bool g_IsMaxWindowSizeSet; 0x004D8364 - uint32_t g_AppResultCode; -0x004D8368 - int32_t g_FullScreenWidth; -0x004D836C - int32_t g_FullScreenHeight; -0x004D8370 - int32_t g_FullScreenBPP; -0x004D8374 - int32_t g_FullScreenVGA; +0x004D8368 + int32_t g_FullScreenWidth; +0x004D836C + int32_t g_FullScreenHeight; +0x004D8370 + int32_t g_FullScreenBPP; +0x004D8374 + int32_t g_FullScreenVGA; 0x004D8378 - uint8_t g_IsGameToExit; 0x004D8568 + int32_t g_ScreenSizer; -0x004D856C - int32_t g_IsVidSizeLock; -0x004D8570 - DWORD g_SampleFreqs[256]; -0x004D8970 - SOUND_ADAPTER_LIST g_SoundAdapterList; -0x004D8980 - LPDIRECTSOUNDBUFFER g_SampleBuffers[256]; +0x004D856C + int32_t g_IsVidSizeLock; +0x004D8570 + DWORD g_SampleFreqs[256]; +0x004D8970 + SOUND_ADAPTER_LIST g_SoundAdapterList; +0x004D8980 + LPDIRECTSOUNDBUFFER g_SampleBuffers[256]; 0x004D8D80 - uint8_t g_IsSoundEnabled; -0x004D8D84 - LPDIRECTSOUND g_DSound; -0x004D8D88 - int32_t g_ChannelSamples[32]; -0x004D8E08 - LPDIRECTSOUNDBUFFER g_ChannelBuffers[32]; -0x004D8E8C - SOUND_ADAPTER g_CurrentSoundAdapter; -0x004D8EAC - SOUND_ADAPTER_NODE *g_PrimarySoundAdapter; -0x004D8EB0 - LPDDS g_RenderBufferSurface; -0x004D92B8 - LPDDS g_ThirdBufferSurface; -0x004D92BC - LPDDS g_PictureBufferSurface; -0x004D92C0 - LPDDS g_ZBufferSurface; -0x004D92C8 - LPDDS g_PrimaryBufferSurface; -0x004D9338 - int32_t g_GameVid_Width; -0x004D933C - int32_t g_GameVid_Height; -0x004D9340 - int32_t g_GameVid_BPP; -0x004D934C - int32_t g_UVAdd; -0x004D9351 - int8_t g_GameVid_IsWindowedVGA; +0x004D8D84 + LPDIRECTSOUND g_DSound; +0x004D8D88 + int32_t g_ChannelSamples[32]; +0x004D8E08 + LPDIRECTSOUNDBUFFER g_ChannelBuffers[32]; +0x004D8E8C + SOUND_ADAPTER g_CurrentSoundAdapter; +0x004D8EAC + SOUND_ADAPTER_NODE *g_PrimarySoundAdapter; +0x004D8EB0 + LPDDS g_RenderBufferSurface; +0x004D92B8 + LPDDS g_ThirdBufferSurface; +0x004D92BC + LPDDS g_PictureBufferSurface; +0x004D92C0 + LPDDS g_ZBufferSurface; +0x004D92C8 + LPDDS g_PrimaryBufferSurface; +0x004D9338 + int32_t g_GameVid_Width; +0x004D933C + int32_t g_GameVid_Height; +0x004D9340 + int32_t g_GameVid_BPP; +0x004D934C + int32_t g_UVAdd; +0x004D9351 + int8_t g_GameVid_IsWindowedVGA; 0x004D9EAC - int32_t g_IsFMVPlaying; 0x004D9EC0 - int32_t g_CurrentLevel; 0x004D9EC4 - int32_t g_LevelComplete; -0x004D9ED8 - D3DTLVERTEX g_HWR_VertexBuffer[0x2000]; // MAX_VERTICES -0x00519EE0 - HWR_TEXTURE_HANDLE g_HWR_PageHandles[32]; -0x00519F60 - D3DTLVERTEX *g_HWR_VertexPtr; +0x004D9ED8 + D3DTLVERTEX g_HWR_VertexBuffer[0x2000]; // MAX_VERTICES +0x00519EE0 + HWR_TEXTURE_HANDLE g_HWR_PageHandles[32]; +0x00519F60 + D3DTLVERTEX *g_HWR_VertexPtr; 0x0051A0CC - char *g_GameBuf_MemBase; 0x0051A0D0 + BOOL g_ConflictLayout[14]; // INPUT_ROLE_NUMBER_OF 0x0051A108 - uint8_t g_DIKeys[256]; @@ -4478,12 +4507,12 @@ typedef enum { 0x0051A238 - HINSTANCE g_GameModule; 0x0051A23C - char *g_CmdLine; 0x0051A240 - int32_t g_ScreenshotCounter; -0x0051B918 - RECT g_PhdWinRect; +0x0051B918 + RECT g_PhdWinRect; 0x0051B928 + int32_t g_HiRes; 0x0051B930 - RGB_888 g_GamePalette8[256]; -0x0051BCC0 - APP_SETTINGS g_SavedAppSettings; +0x0051BCC0 + APP_SETTINGS g_SavedAppSettings; 0x0051BD20 + char g_ErrorMessage[128]; -0x0051BDA8 - int32_t g_MasterVolume; +0x0051BDA8 + int32_t g_MasterVolume; 0x0051BDAC - MCIDEVICEID g_MciDeviceID; 0x0051BDB0 - int32_t g_CD_LoopTrack; 0x0051C820 + TEXTSTRING g_TextstringTable[64]; // MAX_TEXTSTRINGS @@ -4523,15 +4552,15 @@ typedef enum { 0x00526320 - CAMERA_INFO g_Camera; 0x005263CC - BOX_INFO *g_Boxes; 0x004D855C + LPDIRECTINPUT g_DInput; -0x004D8560 - LPDIRECTINPUTDEVICE IDID_SysKeyboard; +0x004D8560 + LPDIRECTINPUTDEVICE IDID_SysKeyboard; 0x0051BDA0 - BOOL g_IsTitleLoaded; 0x004D7980 - int32_t g_Inv_ExtraData[8]; 0x004D8394 - int32_t g_MessageLoopCounter; -0x004D8384 - bool g_IsGameWindowMinimized; +0x004D8384 + bool g_IsGameWindowMinimized; 0x004D8390 - bool g_IsGameWindowActive; -0x004D837C - int32_t g_GameWindowY; -0x004D7EE0 - LPDIRECTDRAW3 g_DDraw; -0x004D8380 - int32_t g_GameWindowX; +0x004D837C + int32_t g_GameWindowY; +0x004D7EE0 + LPDIRECTDRAW3 g_DDraw; +0x004D8380 + int32_t g_GameWindowX; 0x00463150 - GUID g_IID_IDirectDrawSurface3; 0x00463170 - GUID g_IID_IDirect3DTexture2; 0x004640A0 + BITE g_CrowBite; @@ -4555,44 +4584,44 @@ typedef enum { 0x0051E6E0 - int16_t g_SampleLUT[]; 0x0051E9C4 - SAMPLE_INFO *g_SampleInfos; 0x004D7C78 + SOUND_SLOT g_SoundSlots[32]; -0x004D9328 - RECT g_GameVid_Rect; -0x004D9358 - LPDDS g_BackBufferSurface; -0x004D9350 - bool g_GameVid_IsVga; -0x004D9344 - int32_t g_GameVid_BufWidth; -0x004D9348 - int32_t g_GameVid_BufHeight; -0x004D8EB4 - LPDIRECTDRAWCLIPPER g_DDrawClipper; -0x004D8EB8 - PALETTEENTRY g_WinVid_Palette[256]; -0x004D92C4 - LPDIRECTDRAWPALETTE g_DDrawPalette; -0x004D7EC4 - LPDIRECT3DVIEWPORT2 g_D3DView; -0x004D9355 - bool g_NeedToReloadTextures; -0x004D9352 - bool g_GameVid_IsFullscreenVGA; -0x004D9353 - bool g_IsWindowedVGA; -0x004D9354 - bool g_Is16bitTextures; -0x004D9318 - RECT g_GameVid_BufRect; -0x00466BE4 - int16_t g_DumpX; -0x00466BE6 - int16_t g_DumpY; -0x00466BE8 - int16_t g_DumpWidth; -0x00466BEA - int16_t g_DumpHeight; +0x004D9328 + RECT g_GameVid_Rect; +0x004D9358 + LPDDS g_BackBufferSurface; +0x004D9350 + bool g_GameVid_IsVga; +0x004D9344 + int32_t g_GameVid_BufWidth; +0x004D9348 + int32_t g_GameVid_BufHeight; +0x004D8EB4 + LPDIRECTDRAWCLIPPER g_DDrawClipper; +0x004D8EB8 + PALETTEENTRY g_WinVid_Palette[256]; +0x004D92C4 + LPDIRECTDRAWPALETTE g_DDrawPalette; +0x004D7EC4 + LPDIRECT3DVIEWPORT2 g_D3DView; +0x004D9355 + bool g_NeedToReloadTextures; +0x004D9352 + bool g_GameVid_IsFullscreenVGA; +0x004D9353 + bool g_IsWindowedVGA; +0x004D9354 + bool g_Is16bitTextures; +0x004D9318 + RECT g_GameVid_BufRect; +0x00466BE4 + int16_t g_DumpX; +0x00466BE6 + int16_t g_DumpY; +0x00466BE8 + int16_t g_DumpWidth; +0x00466BEA + int16_t g_DumpHeight; 0x0051C1B8 - TEXTURE_FORMAT g_TextureFormat; 0x004D92E8 - COLOR_BIT_MASKS g_ColorBitMasks; -0x0051BC30 - bool g_WinVidNeedToResetBuffers; +0x0051BC30 + bool g_WinVidNeedToResetBuffers; 0x004D7E88 - bool g_BGND_PictureIsReady; 0x004D7E90 - int32_t g_BGND_TexturePageIndexes[5]; 0x004D7EA8 - HWR_TEXTURE_HANDLE g_BGND_PageHandles[5]; -0x004D7EC0 - LPDIRECT3D2 g_D3D; -0x004D7EC8 - LPDIRECT3DMATERIAL2 g_D3DMaterial; -0x004D7ED4 - LPDIRECTDRAW g_DDrawInterface; -0x00466448 - const char g_GameClassName[]; -0x00466468 - const char g_GameWindowName[]; -0x004D7ED8 - bool g_IsGameWindowChanging; -0x00519F68 - D3DRENDERSTATETYPE g_AlphaBlendEnabler; -0x00519ED8 - D3DTEXTUREHANDLE g_CurrentTexSource; -0x00519F6C - bool g_ColorKeyState; -0x0051C20C - bool g_TexturesAlphaChannel; -0x00519F64 - bool g_ZEnableState; -0x00519F70 - bool g_ZWriteEnableState; -0x00466BDC - int32_t g_PaletteIndex; -0x00519F78 - int32_t g_HWR_TexturePageIndexes[32]; // MAX_TEXTURE_PAGES +0x004D7EC0 + LPDIRECT3D2 g_D3D; +0x004D7EC8 + LPDIRECT3DMATERIAL2 g_D3DMaterial; +0x004D7ED4 + LPDIRECTDRAW g_DDrawInterface; +0x00466448 + const char g_GameClassName[]; +0x00466468 + const char g_GameWindowName[]; +0x004D7ED8 + bool g_IsGameWindowChanging; +0x00519F68 + D3DRENDERSTATETYPE g_AlphaBlendEnabler; +0x00519ED8 + D3DTEXTUREHANDLE g_CurrentTexSource; +0x00519F6C + bool g_ColorKeyState; +0x0051C20C + bool g_TexturesAlphaChannel; +0x00519F64 + bool g_ZEnableState; +0x00519F70 + bool g_ZWriteEnableState; +0x00466BDC + int32_t g_PaletteIndex; +0x00519F78 + int32_t g_HWR_TexturePageIndexes[32]; // MAX_TEXTURE_PAGES 0x004D7790 - int32_t g_HeightType; 0x004D9D94 - int16_t *g_Legacy_FloorData; 0x00525B08 - int16_t *g_AnimCommands; @@ -4614,7 +4643,6 @@ typedef enum { 0x004D9D90 - int16_t *g_MeshBase; 0x004D9E98 - int32_t g_TextureInfoCount; 0x004D93F0 - uint8_t g_LabTextureUVFlag[2048]; // MAX_TEXTURES -0x004B2B00 - PHD_TEXTURE g_TextureInfo[]; 0x005251B0 - FRAME_INFO *g_AnimFrames; 0x0051BC38 - int32_t g_IsWet; 0x0051B308 - RGB_888 g_WaterPalette[256]; @@ -4627,7 +4655,7 @@ typedef enum { 0x0051E6C0 - int32_t g_NumSampleInfos; 0x004D9BF4 - int32_t g_LevelFilePalettesOffset; 0x004D9BF8 - int32_t g_LevelFileTexPagesOffset; -0x004D9E9C - int32_t g_LevelFileDepthQOffset; +0x004D9E9C + int32_t g_LevelFileDepthQOffset; 0x004D9D98 - char g_LevelFileName[256]; 0x005261C0 - uint16_t g_MusicTrackFlags[64]; 0x00465AE0 - WEAPON_INFO g_Weapons[]; @@ -4799,6 +4827,7 @@ typedef enum { 0x004D7E7C - int32_t g_DetonateAllMines; 0x005206A4 - int32_t g_SavegameBufPos; 0x0051E9C8 - char *g_SavegameBufPtr; -0x0051C210 - LPDIRECTDRAWPALETTE g_TexturePalettes[16]; // MAX_PALETTES -0x0051BDB8 - TEXPAGE_DESC g_TexturePages[32]; // MAX_TEXTURE_PAGES +0x0051C210 + LPDIRECTDRAWPALETTE g_TexturePalettes[16]; // MAX_PALETTES +0x0051BDB8 + TEXPAGE_DESC g_TexturePages[32]; // MAX_TEXTURE_PAGES 0x0051C20D - uint8_t g_TexturesHaveCompatibleMasks; +0x00467768 + SHADOW_INFO g_ShadowInfo; 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/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/log_windows.c b/src/libtrx/log_windows.c index f31916aa4..512d27f62 100644 --- a/src/libtrx/log_windows.c +++ b/src/libtrx/log_windows.c @@ -2,14 +2,14 @@ #include "memory.h" +#include +#include +#include #include #include #include #include #include -#include -#include -#include static char *m_MiniDumpPath = NULL; static char *M_GetMiniDumpPath(const char *log_path); diff --git a/src/tr2/config.c b/src/tr2/config.c index aaccded9c..1ccdbb459 100644 --- a/src/tr2/config.c +++ b/src/tr2/config.c @@ -9,10 +9,12 @@ #include #include +#include #include CONFIG g_Config = { 0 }; +CONFIG g_SavedConfig = { 0 }; static const char *m_ConfigPath = "cfg/TR2X.json5"; @@ -113,6 +115,8 @@ void Config_LoadFromJSON(JSON_OBJECT *root_obj) { ConfigFile_LoadOptions(root_obj, g_ConfigOptionMap); M_LoadInputConfig(root_obj); + g_Config.loaded = true; + g_SavedConfig = g_Config; } void Config_DumpToJSON(JSON_OBJECT *root_obj) @@ -126,12 +130,30 @@ void Config_Sanitize(void) CLAMP( g_Config.gameplay.turbo_speed, CLOCK_TURBO_SPEED_MIN, CLOCK_TURBO_SPEED_MAX); + CLAMP(g_Config.rendering.scaler, 1, 4); + + if (g_Config.rendering.render_mode != RM_HARDWARE + && g_Config.rendering.render_mode != RM_SOFTWARE) { + g_Config.rendering.render_mode = RM_SOFTWARE; + } + if (g_Config.rendering.aspect_mode != AM_ANY + && g_Config.rendering.aspect_mode != AM_16_9) { + g_Config.rendering.aspect_mode = AM_4_3; + } + if (g_Config.rendering.texel_adjust_mode != TAM_DISABLED + && g_Config.rendering.texel_adjust_mode != TAM_BILINEAR_ONLY) { + g_Config.rendering.texel_adjust_mode = TAM_ALWAYS; + } + CLAMP(g_Config.rendering.nearest_adjustment, 0, 256); + CLAMP(g_Config.rendering.linear_adjustment, 0, 256); } void Config_ApplyChanges(void) { Sound_SetMasterVolume(g_Config.audio.sound_volume); Music_SetVolume(g_Config.audio.music_volume); + + g_SavedConfig = g_Config; } const CONFIG_OPTION *Config_GetOptionMap(void) diff --git a/src/tr2/config.h b/src/tr2/config.h index 559a0c97f..43247f4f8 100644 --- a/src/tr2/config.h +++ b/src/tr2/config.h @@ -1,6 +1,9 @@ #pragma once +#include "global/types.h" + #include +#include #include #include @@ -15,6 +18,7 @@ typedef struct { struct { bool enable_3d_pickups; + bool enable_fade_effects; bool fix_item_rots; } visuals; @@ -30,12 +34,34 @@ typedef struct { struct { int32_t sound_volume; int32_t music_volume; + bool enable_lara_mic; } audio; struct { + bool is_fullscreen; + bool is_maximized; + int32_t x; + int32_t y; + int32_t width; + int32_t height; + } window; + + struct { + RENDER_MODE render_mode; + ASPECT_MODE aspect_mode; + bool enable_zbuffer; + bool enable_perspective_filter; + bool enable_wireframe; + float wireframe_width; + GFX_TEXTURE_FILTER texture_filter; SCREENSHOT_FORMAT screenshot_format; + TEXEL_ADJUST_MODE texel_adjust_mode; + int32_t nearest_adjustment; + int32_t linear_adjustment; + int32_t scaler; float sizer; } rendering; } CONFIG; extern CONFIG g_Config; +extern CONFIG g_SavedConfig; diff --git a/src/tr2/config_map.def b/src/tr2/config_map.def index 6ba15b694..1f5f62021 100644 --- a/src/tr2/config_map.def +++ b/src/tr2/config_map.def @@ -5,10 +5,29 @@ CFG_BOOL(g_Config, gameplay.enable_cheats, false) CFG_BOOL(g_Config, gameplay.enable_auto_item_selection, true) CFG_INT32(g_Config, gameplay.turbo_speed, 0) CFG_BOOL(g_Config, visuals.enable_3d_pickups, true) +CFG_BOOL(g_Config, visuals.enable_fade_effects, true) CFG_BOOL(g_Config, visuals.fix_item_rots, true) +CFG_ENUM(g_Config, rendering.screenshot_format, SCREENSHOT_FORMAT_JPEG, SCREENSHOT_FORMAT) +CFG_ENUM(g_Config, rendering.render_mode, RM_HARDWARE, RENDER_MODE) +CFG_ENUM(g_Config, rendering.aspect_mode, AM_ANY, ASPECT_MODE) +CFG_ENUM(g_Config, rendering.texture_filter, GFX_TF_NN, GFX_TEXTURE_FILTER) +CFG_BOOL(g_Config, rendering.enable_zbuffer, true) +CFG_BOOL(g_Config, rendering.enable_perspective_filter, true) +CFG_BOOL(g_Config, rendering.enable_wireframe, false) +CFG_FLOAT(g_Config, rendering.wireframe_width, 2.5) +CFG_ENUM(g_Config, rendering.texel_adjust_mode, TAM_BILINEAR_ONLY, TEXEL_ADJUST_MODE) +CFG_INT32(g_Config, rendering.nearest_adjustment, 1) +CFG_INT32(g_Config, rendering.linear_adjustment, 128) +CFG_INT32(g_Config, rendering.scaler, 1) +CFG_FLOAT(g_Config, rendering.sizer, 1.0f) CFG_INT32(g_Config, input.keyboard_layout, INPUT_LAYOUT_DEFAULT) CFG_INT32(g_Config, input.controller_layout, INPUT_LAYOUT_DEFAULT) +CFG_BOOL(g_Config, window.is_fullscreen, false) +CFG_BOOL(g_Config, window.is_maximized, false) +CFG_INT32(g_Config, window.x, -1) +CFG_INT32(g_Config, window.y, -1) +CFG_INT32(g_Config, window.width, 1280) +CFG_INT32(g_Config, window.height, 720) CFG_INT32(g_Config, audio.sound_volume, 10) -CFG_INT32(g_Config, audio.music_volume, 7) -CFG_ENUM(g_Config, rendering.screenshot_format, SCREENSHOT_FORMAT_JPEG, SCREENSHOT_FORMAT) -CFG_FLOAT(g_Config, rendering.sizer, 1.0f) +CFG_INT32(g_Config, audio.music_volume, 10) +CFG_BOOL(g_Config, audio.enable_lara_mic, false) diff --git a/src/tr2/decomp/decomp.c b/src/tr2/decomp/decomp.c index 68034f25d..b08e08c01 100644 --- a/src/tr2/decomp/decomp.c +++ b/src/tr2/decomp/decomp.c @@ -2,22 +2,21 @@ #include "config.h" #include "decomp/savegame.h" -#include "game/background.h" -#include "game/camera.h" #include "game/clock.h" #include "game/console/common.h" #include "game/effects.h" +#include "game/fader.h" #include "game/game.h" #include "game/gamebuf.h" #include "game/gameflow.h" #include "game/gameflow/gameflow_new.h" -#include "game/hwr.h" #include "game/input.h" #include "game/inventory/backpack.h" #include "game/inventory/common.h" #include "game/items.h" #include "game/lara/control.h" #include "game/lara/draw.h" +#include "game/level.h" #include "game/lot.h" #include "game/math.h" #include "game/music.h" @@ -28,11 +27,10 @@ #include "game/shell.h" #include "game/sound.h" #include "game/text.h" +#include "game/viewport.h" #include "global/const.h" #include "global/funcs.h" #include "global/vars.h" -#include "lib/ddraw.h" -#include "specific/s_flagged_string.h" #include #include @@ -41,196 +39,13 @@ #include #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); -static bool M_DisplayModeListCopy( - DISPLAY_MODE_LIST *dst, DISPLAY_MODE_LIST *src); -static DISPLAY_MODE *M_InsertDisplayMode( - DISPLAY_MODE_LIST *mode_list, DISPLAY_MODE_NODE *before); -static DISPLAY_MODE *M_InsertDisplayModeInListHead( - DISPLAY_MODE_LIST *mode_list); -static DISPLAY_MODE *M_InsertDisplayModeInListTail( - DISPLAY_MODE_LIST *mode_list); - -static void M_DisplayPicture( - const char *const file_name, const bool copy_palette) -{ - char *compressed_data = NULL; - size_t compressed_data_size = 0; - if (!File_Load(file_name, &compressed_data, &compressed_data_size)) { - return; - } - - const size_t width = 640; - const size_t height = 480; - uint8_t *pixels = GameBuf_Alloc(width * height, GBUF_LOAD_PICTURE_BUFFER); - DecompPCX( - (uint8_t *)compressed_data, compressed_data_size, pixels, - g_PicturePalette); - Memory_FreePointer(&compressed_data); - if (g_SavedAppSettings.render_mode == RM_SOFTWARE) { - WinVidCopyBitmapToBuffer(g_PictureBufferSurface, pixels); - } else { - BGND_Make640x480(pixels, g_PicturePalette); - } - if (copy_palette) { - CopyBitmapPalette( - g_PicturePalette, pixels, width * height, g_GamePalette8); - } - GameBuf_Free(width * height); -} - -static void M_DisplayModeListInit(DISPLAY_MODE_LIST *mode_list) -{ - mode_list->head = NULL; - mode_list->tail = NULL; - mode_list->count = 0; -} - -static void M_DisplayModeListDelete(DISPLAY_MODE_LIST *mode_list) -{ - DISPLAY_MODE_NODE *node; - DISPLAY_MODE_NODE *nextNode; - - for (node = mode_list->head; node; node = nextNode) { - nextNode = node->next; - free(node); - } - M_DisplayModeListInit(mode_list); -} - -static bool M_DisplayModeListCopy( - DISPLAY_MODE_LIST *dst, DISPLAY_MODE_LIST *src) -{ - if (dst == NULL || src == NULL || dst == src) { - return false; - } - - M_DisplayModeListDelete(dst); - for (DISPLAY_MODE_NODE *node = src->head; node != NULL; node = node->next) { - DISPLAY_MODE *dst_mode = M_InsertDisplayModeInListTail(dst); - *dst_mode = node->body; - } - return true; -} - -static DISPLAY_MODE *M_InsertDisplayMode( - DISPLAY_MODE_LIST *mode_list, DISPLAY_MODE_NODE *before) -{ - if (!before || !before->previous) { - return M_InsertDisplayModeInListHead(mode_list); - } - - DISPLAY_MODE_NODE *node = malloc(sizeof(DISPLAY_MODE_NODE)); - if (!node) { - return NULL; - } - - before->previous->next = node; - node->previous = before->previous; - - before->previous = node; - node->next = before; - - mode_list->count++; - return &node->body; -} - -static DISPLAY_MODE *M_InsertDisplayModeInListHead(DISPLAY_MODE_LIST *mode_list) -{ - DISPLAY_MODE_NODE *node = malloc(sizeof(DISPLAY_MODE_NODE)); - if (!node) { - return NULL; - } - - node->next = mode_list->head; - node->previous = NULL; - - if (mode_list->head) { - mode_list->head->previous = node; - } - - if (!mode_list->tail) { - mode_list->tail = node; - } - - mode_list->head = node; - mode_list->count++; - return &node->body; -} - -static DISPLAY_MODE *M_InsertDisplayModeInListTail(DISPLAY_MODE_LIST *mode_list) -{ - DISPLAY_MODE_NODE *node = malloc(sizeof(DISPLAY_MODE_NODE)); - if (!node) { - return NULL; - } - - node->next = NULL; - node->previous = mode_list->tail; - - if (mode_list->tail) { - mode_list->tail->next = node; - } - - if (!mode_list->head) { - mode_list->head = node; - } - - mode_list->tail = node; - mode_list->count++; - 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(); - // clang-format on -} - int32_t __stdcall WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int32_t nShowCmd) @@ -239,117 +54,35 @@ int32_t __stdcall WinMain( g_CmdLine = lpCmdLine; HWND game_window = WinVidFindGameWindow(); if (game_window) { - HWND setup_window = SE_FindSetupDialog(); - if (!setup_window) { - setup_window = game_window; - } - SetForegroundWindow(setup_window); + SetForegroundWindow(game_window); return 0; } - // TODO: install exception handler - - bool is_setup_requested = UT_FindArg("setup") != 0; - if (!GameInit()) { - UT_ErrorBox(IDS_DX5_REQUIRED, NULL); - goto cleanup; - } - - int32_t app_settings_status = SE_ReadAppSettings(&g_SavedAppSettings); - if (!app_settings_status) { - goto cleanup; - } - - if (app_settings_status == 2 || is_setup_requested) { - if (SE_ShowSetupDialog(0, app_settings_status == 2)) { - SE_WriteAppSettings(&g_SavedAppSettings); - if (is_setup_requested) { - goto cleanup; - } - } else { - goto cleanup; - } - } - - int32_t result = WinGameStart(); - if (result) { - RenderErrorBox(result); - Shell_Shutdown(); - if (!SE_ShowSetupDialog(0, 0)) { - goto cleanup; - } - SE_WriteAppSettings(&g_SavedAppSettings); - } else { - g_StopInventory = 0; - g_IsGameToExit = 0; - Shell_Main(); - Shell_Shutdown(); - SE_WriteAppSettings(&g_SavedAppSettings); - } + g_AppResultCode = 0; + g_IsGameToExit = false; + Shell_Main(); + Shell_Shutdown(); cleanup: return g_AppResultCode; } -const char *__cdecl DecodeErrorMessage(int32_t error_code) -{ - return g_ErrorMessages[error_code]; -} - -int32_t __cdecl RenderErrorBox(int32_t error_code) -{ - char buffer[128]; - const char *decoded = DecodeErrorMessage(error_code); - sprintf(buffer, "Render init failed with \"%s\"", decoded); - return UT_MessageBox(buffer, 0); -} - -bool __cdecl DInputCreate(void) -{ - return true; -} - -void __cdecl DInputRelease(void) -{ -} - -void __cdecl WinInReadKeyboard(uint8_t *input_data) -{ -} - -int32_t __cdecl WinGameStart(void) -{ - // try { - WinVidStart(); - RenderStart(true); - // } catch (int32_t error) { - // return error; - // } - return 0; -} - int16_t __cdecl TitleSequence(void) { GF_N_LoadStrings(-1); g_NoInputCounter = 0; - if (!g_IsTitleLoaded) { - if (!Level_Initialise(0, GFL_TITLE)) { - return GFD_EXIT_GAME; - } - g_IsTitleLoaded = true; + if (!Level_Initialise(0, GFL_TITLE)) { + return GFD_EXIT_GAME; } - S_DisplayPicture("data/title.pcx", true); if (g_GameFlow.title_track) { Music_Play(g_GameFlow.title_track, MPM_LOOPED); } GAME_FLOW_DIR dir = Inv_Display(INV_TITLE_MODE); - - S_FadeToBlack(); - S_DontDisplayPicture(); + Output_UnloadBackground(); Music_Stop(); if (dir == GFD_OVERRIDE) { @@ -389,498 +122,11 @@ 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) { - return 4 * height / 3; - } - if (g_SavedAppSettings.aspect_mode == AM_16_9) { - return 16 * height / 9; - } - return width; -} - -int32_t __cdecl CalculateWindowHeight(const int32_t width, const int32_t height) -{ - if (g_SavedAppSettings.aspect_mode == AM_4_3) { - return (3 * width) / 4; - } - if (g_SavedAppSettings.aspect_mode == AM_16_9) { - return (9 * width) / 16; - } - 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; - HRESULT rc = IDirectDraw_CreateSurface(g_DDraw, dsp, &sub_surface, NULL); - - if SUCCEEDED (rc) { - rc = IDirectDrawSurface_QueryInterface( - sub_surface, &g_IID_IDirectDrawSurface3, (LPVOID *)surface); - IDirectDrawSurface_Release(sub_surface); - } - - return rc; -} - -HRESULT __cdecl DDrawSurfaceRestoreLost( - LPDDS surface1, LPDDS surface2, bool blank) -{ - HRESULT rc = IDirectDrawSurface_IsLost(surface1); - if (rc != DDERR_SURFACELOST) { - return rc; - } - rc = IDirectDrawSurface_Restore(surface2 != NULL ? surface2 : surface1); - if (blank && SUCCEEDED(rc)) { - WinVidClearBuffer(surface1, 0, 0); - } - return rc; -} - -bool __cdecl WinVidClearBuffer(LPDDS surface, LPRECT rect, DWORD fill_color) -{ - DDBLTFX blt = { .dwFillColor = fill_color, .dwSize = sizeof(DDBLTFX), 0 }; - HRESULT rc = IDirectDrawSurface_Blt( - surface, rect, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &blt); - return SUCCEEDED(rc); -} - -HRESULT __cdecl WinVidBufferLock(LPDDS surface, LPDDSDESC desc, DWORD flags) -{ - memset(desc, 0, sizeof(DDSURFACEDESC)); - desc->dwSize = sizeof(DDSURFACEDESC); - HRESULT rc = IDirectDrawSurface_Lock(surface, NULL, desc, flags, NULL); - if (SUCCEEDED(rc)) { - g_LockedBufferCount++; - } - return rc; -} - -HRESULT __cdecl WinVidBufferUnlock(LPDDS surface, LPDDSDESC desc) -{ - HRESULT rc = surface->lpVtbl->Unlock(surface, desc->lpSurface); - if (SUCCEEDED(rc)) { - g_LockedBufferCount--; - } - return rc; -} - -bool __cdecl WinVidCopyBitmapToBuffer(LPDDS surface, const BYTE *bitmap) -{ - DDSURFACEDESC desc; - if (FAILED( - WinVidBufferLock(surface, &desc, DDLOCK_WRITEONLY | DDLOCK_WAIT))) { - return false; - } - - const uint8_t *src = (const uint8_t *)bitmap; - uint8_t *dst = (uint8_t *)desc.lpSurface; - for (int32_t i = 0; i < (int32_t)desc.dwHeight; i++) { - memcpy(dst, src, desc.dwWidth); - src += desc.dwWidth; - dst += desc.lPitch; - } - WinVidBufferUnlock(surface, &desc); - return true; -} - -DWORD __cdecl GetRenderBitDepth(const uint32_t rgb_bit_count) -{ - switch (rgb_bit_count) { - // clang-format off - case 1: return DDBD_1; - case 2: return DDBD_2; - case 4: return DDBD_4; - case 8: return DDBD_8; - case 0x10: return DDBD_16; - case 0x18: return DDBD_24; - case 0x20: return DDBD_32; - // clang-format on - } - return 0; -} - -void __thiscall WinVidGetColorBitMasks( - COLOR_BIT_MASKS *bm, LPDDPIXELFORMAT pixel_format) -{ - bm->mask.r = pixel_format->dwRBitMask; - bm->mask.g = pixel_format->dwGBitMask; - bm->mask.b = pixel_format->dwBBitMask; - bm->mask.a = pixel_format->dwRGBAlphaBitMask; - BitMaskGetNumberOfBits(bm->mask.r, &bm->depth.r, &bm->offset.r); - BitMaskGetNumberOfBits(bm->mask.g, &bm->depth.g, &bm->offset.g); - BitMaskGetNumberOfBits(bm->mask.b, &bm->depth.b, &bm->offset.b); - BitMaskGetNumberOfBits(bm->mask.a, &bm->depth.a, &bm->offset.a); -} - -void __cdecl BitMaskGetNumberOfBits( - uint32_t bit_mask, uint32_t *bit_depth, uint32_t *bit_offset) -{ - if (!bit_mask) { - *bit_offset = 0; - *bit_depth = 0; - return; - } - - int32_t i; - - for (i = 0; (bit_mask & 1) == 0; i++) { - bit_mask >>= 1; - } - *bit_offset = i; - - for (i = 0; bit_mask != 0; i++) { - bit_mask >>= 1; - } - *bit_depth = i; -} - -DWORD __cdecl CalculateCompatibleColor( - const COLOR_BIT_MASKS *const mask, const int32_t red, const int32_t green, - const int32_t blue, const int32_t alpha) -{ - // clang-format off - return ( - (red >> (8 - mask->depth.r) << mask->offset.r) | - (green >> (8 - mask->depth.g) << mask->offset.g) | - (blue >> (8 - mask->depth.b) << mask->offset.b) | - (alpha >> (8 - mask->depth.a) << mask->offset.a) - ); - // 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; @@ -888,8 +134,6 @@ void __cdecl Game_SetCutsceneTrack(const int32_t track) int32_t __cdecl Game_Cutscene_Start(const int32_t level_num) { - g_IsTitleLoaded = false; - S_FadeToBlack(); if (!Level_Initialise(level_num, GFL_CUTSCENE)) { return 2; } @@ -902,7 +146,6 @@ int32_t __cdecl Game_Cutscene_Start(const int32_t level_num) g_SoundIsActive = false; g_CineFrameIdx = 0; - S_ClearScreen(); if (!Music_PlaySynced(g_CineTrackID)) { return 1; @@ -917,7 +160,7 @@ int32_t __cdecl Game_Cutscene_Start(const int32_t level_num) int32_t nticks = g_CineFrameCurrent - TICKS_PER_FRAME * (g_CineFrameIdx - 4); CLAMPL(nticks, TICKS_PER_FRAME); - result = Game_Cutscene_Control(nticks); + result = Game_ControlCinematic(nticks); } while (!result); Music_SetVolume(g_Config.audio.music_volume); @@ -929,72 +172,6 @@ int32_t __cdecl Game_Cutscene_Start(const int32_t level_num) return result; } -int32_t __cdecl Game_Cutscene_Control(const int32_t nframes) -{ - g_CineTickCount += g_CineTickRate * nframes; - - if (g_CineTickCount >= 0) { - while (1) { - if (g_GF_OverrideDir != (GAME_FLOW_DIR)-1) { - return 4; - } - - Shell_ProcessEvents(); - Input_Update(); - if (g_InputDB.action) { - return 1; - } - if (g_InputDB.option) { - return 2; - } - Shell_ProcessInput(); - - g_DynamicLightCount = 0; - - for (int32_t id = g_NextItemActive; id != NO_ITEM;) { - const ITEM *const item = &g_Items[id]; - const OBJECT *obj = &g_Objects[item->object_id]; - if (obj->control != NULL) { - obj->control(id); - } - id = item->next_active; - } - - for (int32_t id = g_NextEffectActive; id != NO_ITEM;) { - const FX *const fx = &g_Effects[id]; - const OBJECT *const obj = &g_Objects[fx->object_id]; - if (obj->control != NULL) { - obj->control(id); - } - id = fx->next_active; - } - - HairControl(1); - Camera_UpdateCutscene(); - - g_CineFrameIdx++; - if (g_CineFrameIdx >= g_NumCineFrames) { - return 1; - } - - g_CineTickCount -= 0x10000; - if (g_CineTickCount < 0) { - break; - } - } - } - - if (Music_GetTimestamp() < 0.0) { - g_CineFrameCurrent++; - } else { - // sync with music - g_CineFrameCurrent = - Music_GetTimestamp() * FRAMES_PER_SECOND * TICKS_PER_FRAME / 1000.0; - } - - return 0; -} - void __cdecl CutscenePlayer_Control(const int16_t item_num) { ITEM *const item = &g_Items[item_num]; @@ -1086,7 +263,6 @@ int32_t __cdecl Level_Initialise( g_IsDemoLevelType = level_type == GFL_DEMO; InitialiseGameFlags(); g_Lara.item_num = NO_ITEM; - g_IsTitleLoaded = false; bool result; if (level_type == GFL_TITLE) { @@ -1115,7 +291,6 @@ int32_t __cdecl Level_Initialise( Inv_InitColors(); Overlay_HideGameInfo(); Overlay_InitialisePickUpDisplay(); - S_InitialiseScreen(level_type); g_HealthBarTimer = 100; Sound_StopAllSamples(); if (level_type == GFL_SAVED) { @@ -1140,1553 +315,6 @@ int32_t __cdecl Level_Initialise( return true; } -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))) { - rebuild = true; - } - - if (g_SavedAppSettings.render_mode == RM_SOFTWARE - && FAILED( - DDrawSurfaceRestoreLost(g_RenderBufferSurface, NULL, false))) { - rebuild = true; - } - - if (g_ZBufferSurface != NULL - && FAILED(DDrawSurfaceRestoreLost(g_ZBufferSurface, NULL, false))) { - rebuild = true; - } - - if (g_PictureBufferSurface != NULL - && FAILED( - DDrawSurfaceRestoreLost(g_PictureBufferSurface, NULL, false))) { - rebuild = true; - } - - if (rebuild && !g_IsGameToExit) { - ApplySettings(&g_SavedAppSettings); - if (g_SavedAppSettings.render_mode == RM_HARDWARE) - HWR_GetPageHandles(); - } -} - -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 = { - .dwSize = sizeof(DDSDESC), - .dwFlags = DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS, - .dwWidth = g_GameVid_BufWidth, - .dwHeight = g_GameVid_BufHeight, - .ddsCaps = { - .dwCaps = DDSCAPS_3DDEVICE|DDSCAPS_OFFSCREENPLAIN, - }, - }; - if (g_SavedAppSettings.render_mode == RM_HARDWARE) { - dsp.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; - } - if (FAILED(DDrawSurfaceCreate(&dsp, &g_BackBufferSurface))) { - Shell_ExitSystem("Failed to create back screen buffer"); - } - 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"); - } -} - -void __cdecl CreateZBuffer(void) -{ - if ((g_CurrentDisplayAdapter.hw_device_desc.dpcTriCaps.dwRasterCaps - & D3DPRASTERCAPS_ZBUFFERLESSHSR) - != 0) { - return; - } - - DDSDESC dsp = { - .dwSize = sizeof(DDSDESC), - .dwWidth = g_GameVid_BufWidth, - .dwHeight = g_GameVid_BufHeight, - .dwFlags = DDSD_ZBUFFERBITDEPTH | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS, - .dwZBufferBitDepth = GetZBufferDepth(), - .ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY, - }; - - if (FAILED(DDrawSurfaceCreate(&dsp, &g_ZBufferSurface))) { - Shell_ExitSystem("Failed to create z-buffer"); - } - - if (FAILED(IDirectDrawSurface_AddAttachedSurface( - g_BackBufferSurface, g_ZBufferSurface))) { - Shell_ExitSystem("Failed to attach z-buffer to the back buffer"); - } -} - -int32_t __cdecl GetZBufferDepth(void) -{ - const int32_t bit_depth_mask = - g_CurrentDisplayAdapter.hw_device_desc.dwDeviceZBufferBitDepth; - if (bit_depth_mask & DDBD_16) { - return 16; - } - if (bit_depth_mask & DDBD_24) { - return 24; - } - if (bit_depth_mask & DDBD_32) { - return 32; - } - return 8; -} - -void __cdecl CreateRenderBuffer(void) -{ - DDSDESC dsp = { - .dwSize = sizeof(DDSDESC), - .dwFlags = DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS, - .dwWidth = g_GameVid_BufWidth, - .dwHeight = g_GameVid_BufHeight, - .ddsCaps = { - .dwCaps = DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN, - }, - }; - - if (FAILED(DDrawSurfaceCreate(&dsp, &g_RenderBufferSurface))) { - Shell_ExitSystem("Failed to create render buffer"); - } - - if (!WinVidClearBuffer(g_RenderBufferSurface, NULL, 0)) { - Shell_ExitSystem("Failed to clear render buffer"); - } -} - -void __cdecl CreatePictureBuffer(void) -{ - DDSDESC dsp = { - .dwSize = sizeof(DDSDESC), - .dwFlags = DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS, - .dwWidth = 640, - .dwHeight = 480, - .ddsCaps = { - .dwCaps = DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN, - }, - }; - - if (FAILED(DDrawSurfaceCreate(&dsp, &g_PictureBufferSurface))) { - Shell_ExitSystem("Failed to create picture buffer"); - } -} - -void __cdecl ClearBuffers(DWORD flags, DWORD fill_color) -{ - RECT win_rect; - if (flags & CLRB_PHDWINSIZE) { - win_rect.left = g_PhdWinMinX; - win_rect.top = g_PhdWinMinY; - win_rect.right = g_PhdWinMinX + g_PhdWinWidth; - win_rect.bottom = g_PhdWinMinY + g_PhdWinHeight; - } else { - win_rect.left = 0; - win_rect.top = 0; - win_rect.right = g_GameVid_Width; - win_rect.bottom = g_GameVid_Height; - } - - 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_RENDER_BUFFER) { - WinVidClearBuffer(g_RenderBufferSurface, &win_rect, fill_color); - } - - if (flags & CLRB_PICTURE_BUFFER) { - win_rect.left = 0; - win_rect.top = 0; - win_rect.right = 640; - 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; -} - -void __cdecl RenderFinish(bool need_to_clear_textures) -{ - if (g_SavedAppSettings.render_mode == RM_HARDWARE) { - if (need_to_clear_textures) { - HWR_FreeTexturePages(); - CleanupTextures(); - } - - Direct3DRelease(); - if (g_ZBufferSurface != NULL) { - IDirectDrawSurface_Release(g_ZBufferSurface); - g_ZBufferSurface = NULL; - } - } else { - if (need_to_clear_textures && g_PictureBufferSurface != NULL) { - IDirectDrawSurface_Release(g_PictureBufferSurface); - g_PictureBufferSurface = NULL; - } - - if (g_RenderBufferSurface != NULL) { - IDirectDrawSurface_Release(g_RenderBufferSurface); - g_RenderBufferSurface = NULL; - } - } - - if (g_DDrawPalette != NULL) { - IDirectDrawPalette_Release(g_DDrawPalette); - g_DDrawPalette = NULL; - } - - if (g_DDrawClipper != NULL) { - IDirectDrawClipper_Release(g_DDrawClipper); - 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; - } - - if (g_PrimaryBufferSurface != NULL) { - IDirectDrawSurface_Release(g_PrimaryBufferSurface); - g_PrimaryBufferSurface = NULL; - } - - if (need_to_clear_textures) { - g_NeedToReloadTextures = false; - } -} - -bool __cdecl ApplySettings(const APP_SETTINGS *const new_settings) -{ - char mode_string[64] = { 0 }; - APP_SETTINGS old_settings = g_SavedAppSettings; - - RenderFinish(false); - - if (new_settings != &g_SavedAppSettings) - g_SavedAppSettings = *new_settings; - - RenderStart(false); - S_InitialiseScreen(GFL_NO_LEVEL); - - if (g_SavedAppSettings.render_mode != old_settings.render_mode) { - S_ReloadLevelGraphics(1, 1); - } else if ( - g_SavedAppSettings.render_mode == RM_SOFTWARE - && g_SavedAppSettings.fullscreen != old_settings.fullscreen) { - S_ReloadLevelGraphics(1, 0); - } - - 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); - } - - Overlay_DisplayModeInfo(mode_string); - return true; -} - -void __cdecl GameApplySettings(APP_SETTINGS *const new_settings) -{ - bool need_init_render_state = false; - bool need_adjust_texel = false; - bool need_rebuild_buffers = false; - - if (new_settings->preferred_display_adapter - != g_SavedAppSettings.preferred_display_adapter - || new_settings->preferred_sound_adapter - != g_SavedAppSettings.preferred_sound_adapter - || new_settings->preferred_joystick - != g_SavedAppSettings.preferred_joystick) { - return; - } - - if (new_settings->render_mode != g_SavedAppSettings.render_mode - || new_settings->video_mode != g_SavedAppSettings.video_mode - || new_settings->fullscreen != g_SavedAppSettings.fullscreen - || new_settings->zbuffer != g_SavedAppSettings.zbuffer - || new_settings->triple_buffering - != g_SavedAppSettings.triple_buffering) { - ApplySettings(new_settings); - S_AdjustTexelCoordinates(); - return; - } - - if (new_settings->perspective_correct - != g_SavedAppSettings.perspective_correct - || new_settings->dither != g_SavedAppSettings.dither - || new_settings->bilinear_filtering - != g_SavedAppSettings.bilinear_filtering) { - need_init_render_state = true; - } - - if (new_settings->bilinear_filtering - != g_SavedAppSettings.bilinear_filtering - || new_settings->render_mode != g_SavedAppSettings.render_mode) { - 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; - g_SavedAppSettings.dither = new_settings->dither; - g_SavedAppSettings.bilinear_filtering = - new_settings->bilinear_filtering; - if (g_SavedAppSettings.render_mode == RM_HARDWARE) { - HWR_InitState(); - } - } - - if (need_rebuild_buffers) { - ClearBuffers(CLRB_WINDOWED_PRIMARY_BUFFER, 0); - ApplySettings(new_settings); - } - - if (need_adjust_texel) { - S_AdjustTexelCoordinates(); - } -} - -void __cdecl UpdateGameResolution(void) -{ - APP_SETTINGS new_settings = g_SavedAppSettings; - new_settings.window_width = g_GameWindowWidth; - new_settings.window_height = g_GameWindowHeight; - GameApplySettings(&new_settings); - char mode_string[64] = { 0 }; - sprintf(mode_string, "%dx%d", g_GameVid_Width, g_GameVid_Height); - Overlay_DisplayModeInfo(mode_string); -} - -bool __cdecl D3DCreate(void) -{ - const HRESULT rc = - IDirectDraw_QueryInterface(g_DDraw, &IID_IDirect3D2, (LPVOID *)&g_D3D); - return SUCCEEDED(rc); -} - -void __cdecl D3DRelease(void) -{ - if (g_D3D != NULL) { - IDirect3D_Release(g_D3D); - g_D3D = NULL; - } -} - -void __cdecl Enumerate3DDevices(DISPLAY_ADAPTER *const adapter) -{ - if (D3DCreate()) { - g_D3D->lpVtbl->EnumDevices( - g_D3D, (void *)Enum3DDevicesCallback, (LPVOID)adapter); - D3DRelease(); - } -} - -HRESULT __stdcall Enum3DDevicesCallback( - GUID FAR *lpGuid, LPTSTR lpDeviceDescription, LPTSTR lpDeviceName, - LPD3DDEVICEDESC_V2 lpD3DHWDeviceDesc, LPD3DDEVICEDESC_V2 lpD3DHELDeviceDesc, - LPVOID lpContext) -{ - DISPLAY_ADAPTER *adapter = (DISPLAY_ADAPTER *)lpContext; - - if (lpD3DHWDeviceDesc != NULL && D3DIsSupported(lpD3DHWDeviceDesc)) { - adapter->hw_render_supported = true; - adapter->device_guid = *lpGuid; - adapter->hw_device_desc = *lpD3DHWDeviceDesc; - - adapter->perspective_correct_supported = - (lpD3DHWDeviceDesc->dpcTriCaps.dwTextureCaps - & D3DPTEXTURECAPS_PERSPECTIVE) - ? true - : false; - adapter->dither_supported = - (lpD3DHWDeviceDesc->dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_DITHER) - ? true - : false; - adapter->zbuffer_supported = - (lpD3DHWDeviceDesc->dwDeviceZBufferBitDepth) ? true : false; - adapter->linear_filter_supported = - (lpD3DHWDeviceDesc->dpcTriCaps.dwTextureFilterCaps - & D3DPTFILTERCAPS_LINEAR) - ? true - : false; - adapter->shade_restricted = - (lpD3DHWDeviceDesc->dpcTriCaps.dwShadeCaps - & (D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_ALPHAFLATBLEND)) - ? false - : true; - } - - return D3DENUMRET_OK; -} - -bool __cdecl D3DIsSupported(LPD3DDEVICEDESC_V2 desc) -{ - return (desc->dwFlags & D3DDD_COLORMODEL) - && (desc->dcmColorModel & D3DCOLOR_RGB) - && (desc->dwFlags & D3DDD_TRICAPS) - && (desc->dpcTriCaps.dwShadeCaps & D3DPSHADECAPS_COLORGOURAUDRGB) - && (desc->dpcTriCaps.dwTextureBlendCaps & D3DPTBLENDCAPS_MODULATE); -} - -bool __cdecl D3DSetViewport(void) -{ - D3DVIEWPORT2 viewPort = { - .dwSize = sizeof(D3DVIEWPORT2), - .dvClipX = 0.0, - .dvClipY = 0.0, - .dvClipWidth = (float)g_GameVid_Width, - .dvClipHeight = (float)g_GameVid_Height, - - .dwX = 0, - .dwY = 0, - .dwWidth = g_GameVid_Width, - .dwHeight = g_GameVid_Height, - - .dvMinZ = 0.0, - .dvMaxZ = 1.0, - }; - - HRESULT rc = IDirect3DViewport2_SetViewport2(g_D3DView, &viewPort); - if (FAILED(rc)) { - IDirect3DViewport2_GetViewport2(g_D3DView, &viewPort); - return false; - } - - rc = IDirect3DDevice2_SetCurrentViewport(g_D3DDev, g_D3DView); - return SUCCEEDED(rc); -} - -void __cdecl D3DDeviceCreate(LPDDS lpBackBuffer) -{ - if (g_D3D == NULL && !D3DCreate()) { - Shell_ExitSystem("Failed to create D3D"); - } - - if (FAILED(g_D3D->lpVtbl->CreateDevice( - g_D3D, &IID_IDirect3DHALDevice, (LPDIRECTDRAWSURFACE)lpBackBuffer, - &g_D3DDev))) { - Shell_ExitSystem("Failed to create device"); - } - - if (FAILED(g_D3D->lpVtbl->CreateViewport(g_D3D, &g_D3DView, NULL))) { - Shell_ExitSystem("Failed to create viewport"); - } - - if (FAILED(g_D3DDev->lpVtbl->AddViewport(g_D3DDev, g_D3DView))) { - Shell_ExitSystem("Failed to add viewport"); - } - - if (FAILED(!D3DSetViewport())) { - Shell_ExitSystem("Failed to set viewport"); - } - - if (FAILED(g_D3D->lpVtbl->CreateMaterial(g_D3D, &g_D3DMaterial, NULL))) { - Shell_ExitSystem("Failed to create material"); - } - - D3DMATERIALHANDLE mat_handle; - D3DMATERIAL mat_data = { 0 }; - mat_data.dwSize = sizeof(mat_data); - - if (FAILED(g_D3DMaterial->lpVtbl->SetMaterial(g_D3DMaterial, &mat_data))) { - Shell_ExitSystem("Failed to set material"); - } - - if (FAILED(g_D3DMaterial->lpVtbl->GetHandle( - g_D3DMaterial, g_D3DDev, &mat_handle))) { - Shell_ExitSystem("Failed to get material handle"); - } - - if (FAILED(g_D3DView->lpVtbl->SetBackground(g_D3DView, mat_handle))) { - Shell_ExitSystem("Failed to set material background"); - } -} - -void __cdecl Direct3DRelease(void) -{ - if (g_D3DMaterial != NULL) { - g_D3DMaterial->lpVtbl->Release(g_D3DMaterial); - g_D3DMaterial = NULL; - } - - if (g_D3DView != NULL) { - g_D3DView->lpVtbl->Release(g_D3DView); - g_D3DView = NULL; - } - - if (g_D3DDev != NULL) { - g_D3DDev->lpVtbl->Release(g_D3DDev); - g_D3DDev = NULL; - } - - D3DRelease(); -} - -bool __cdecl Direct3DInit(void) -{ - return true; -} - -bool __cdecl DDrawCreate(LPGUID lpGUID) -{ - if (FAILED(DirectDrawCreate(lpGUID, &g_DDrawInterface, 0))) { - return false; - } - - if (FAILED(g_DDrawInterface->lpVtbl->QueryInterface( - g_DDrawInterface, &IID_IDirectDraw2, (LPVOID *)&g_DDraw))) { - return false; - } - - if (FAILED(g_DDraw->lpVtbl->SetCooperativeLevel( - g_DDraw, g_GameWindowHandle, DDSCL_NORMAL))) { - return false; - } - - return true; -} - -void __cdecl DDrawRelease(void) -{ - if (g_DDraw != NULL) { - g_DDraw->lpVtbl->Release(g_DDraw); - g_DDraw = NULL; - } - if (g_DDrawInterface != NULL) { - g_DDrawInterface->lpVtbl->Release(g_DDrawInterface); - g_DDrawInterface = NULL; - } -} - -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 -} - -bool __cdecl WinVidGetDisplayAdapters(void) -{ - for (DISPLAY_ADAPTER_NODE *node = g_DisplayAdapterList.head, - *next_node = NULL; - node != NULL; node = next_node) { - next_node = node->next; - M_DisplayModeListDelete(&node->body.sw_disp_mode_list); - M_DisplayModeListDelete(&node->body.hw_disp_mode_list); - S_FlaggedString_Delete(&node->body.driver_name); - S_FlaggedString_Delete(&node->body.driver_desc); - free(node); - } - - g_DisplayAdapterList.head = NULL; - g_DisplayAdapterList.tail = NULL; - g_DisplayAdapterList.count = 0; - - g_PrimaryDisplayAdapter = NULL; - - if (!EnumerateDisplayAdapters(&g_DisplayAdapterList)) { - return false; - } - - for (DISPLAY_ADAPTER_NODE *node = g_DisplayAdapterList.head; node != NULL; - node = node->next) { - if (node->body.adapter_guid_ptr == NULL) { - g_PrimaryDisplayAdapter = node; - return true; - } - } - return false; -} - -bool __cdecl EnumerateDisplayAdapters( - DISPLAY_ADAPTER_LIST *display_adapter_list) -{ - return SUCCEEDED(DirectDrawEnumerate( - EnumDisplayAdaptersCallback, (LPVOID)display_adapter_list)); -} - -BOOL WINAPI EnumDisplayAdaptersCallback( - GUID FAR *lpGUID, LPTSTR lpDriverDescription, LPTSTR lpDriverName, - LPVOID lpContext) -{ - DISPLAY_ADAPTER_NODE *list_node = malloc(sizeof(DISPLAY_ADAPTER_NODE)); - DISPLAY_ADAPTER_LIST *adapter_list = (DISPLAY_ADAPTER_LIST *)lpContext; - - if (list_node == NULL || !DDrawCreate(lpGUID)) { - return TRUE; - } - - DDCAPS_DX5 driver_caps = { .dwSize = sizeof(DDCAPS_DX5), 0 }; - DDCAPS_DX5 hel_caps = { .dwSize = sizeof(DDCAPS_DX5), 0 }; - if (FAILED(g_DDraw->lpVtbl->GetCaps( - g_DDraw, (void *)&driver_caps, (void *)&hel_caps))) { - goto cleanup; - } - - list_node->next = NULL; - list_node->previous = adapter_list->tail; - - S_FlaggedString_InitAdapter(&list_node->body); - M_DisplayModeListInit(&list_node->body.hw_disp_mode_list); - M_DisplayModeListInit(&list_node->body.sw_disp_mode_list); - - if (!adapter_list->head) { - adapter_list->head = list_node; - } - - if (adapter_list->tail) { - adapter_list->tail->next = list_node; - } - - adapter_list->tail = list_node; - adapter_list->count++; - - if (lpGUID != NULL) { - list_node->body.adapter_guid = *lpGUID; - list_node->body.adapter_guid_ptr = &list_node->body.adapter_guid; - } else { - memset(&list_node->body.adapter_guid, 0, sizeof(GUID)); - list_node->body.adapter_guid_ptr = NULL; - } - - lstrcpy(list_node->body.driver_desc.content, lpDriverDescription); - lstrcpy(list_node->body.driver_name.content, lpDriverName); - - list_node->body.driver_caps = driver_caps; - list_node->body.hel_caps = hel_caps; - - list_node->body.screen_width = 0; - list_node->body.hw_render_supported = false; - list_node->body.sw_windowed_supported = false; - list_node->body.hw_windowed_supported = false; - list_node->body.is_vga_mode1_presented = false; - list_node->body.is_vga_mode2_presented = false; - - Enumerate3DDevices(&list_node->body); - -cleanup: - DDrawRelease(); - 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; - g_IsGameWindowShow = true; - g_IsDDrawGameWindowShow = false; - g_IsMessageLoopClosed = false; - g_IsGameWindowUpdating = false; - g_IsGameWindowMinimized = false; - g_IsGameWindowMaximized = false; - g_IsGameWindowCreated = false; - g_IsGameFullScreen = false; - 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( - "Error while calling SDL_Init: 0x%lx, %s", result, SDL_GetError()); - return false; - } - - g_SDLWindow = SDL_CreateWindowFrom(g_GameWindowHandle); - 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(); - - 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; - } - } - } - return g_PrimaryDisplayAdapter; -} - -void __cdecl WinVidStart(void) -{ - if (g_SavedAppSettings.preferred_display_adapter == NULL) { - Shell_ExitSystem("Can't create DirectDraw"); - } - - DISPLAY_ADAPTER *preferred = - &g_SavedAppSettings.preferred_display_adapter->body; - g_CurrentDisplayAdapter = *preferred; - - S_FlaggedString_Copy( - &g_CurrentDisplayAdapter.driver_desc, &preferred->driver_desc); - S_FlaggedString_Copy( - &g_CurrentDisplayAdapter.driver_name, &preferred->driver_name); - - M_DisplayModeListInit(&g_CurrentDisplayAdapter.hw_disp_mode_list); - M_DisplayModeListCopy( - &g_CurrentDisplayAdapter.hw_disp_mode_list, - &preferred->hw_disp_mode_list); - - M_DisplayModeListInit(&g_CurrentDisplayAdapter.sw_disp_mode_list); - M_DisplayModeListCopy( - &g_CurrentDisplayAdapter.sw_disp_mode_list, - &preferred->sw_disp_mode_list); - - if (!DDrawCreate(g_CurrentDisplayAdapter.adapter_guid_ptr)) { - Shell_ExitSystem("Can't create DirectDraw"); - } -} - -void __cdecl WinVidFinish(void) -{ - if (g_IsDDrawGameWindowShow) { - HideDDrawGameWindow(); - } - DDrawRelease(); -} - int32_t __cdecl Misc_Move3DPosTo3DPos( PHD_3DPOS *const src_pos, const PHD_3DPOS *const dst_pos, const int32_t velocity, const PHD_ANGLE ang_add) @@ -2767,12 +395,12 @@ void __cdecl S_Wait(int32_t frames, const BOOL input_check) break; } - S_InitialisePolyList(0); - S_CopyBufferToScreen(); + Output_BeginScene(); + Output_DrawBackground(); Console_Draw(); Text_Draw(); - S_OutputPolyList(); - frames -= S_DumpScreen() * TICKS_PER_FRAME; + Output_DrawPolyList(); + frames -= Output_EndScene() * TICKS_PER_FRAME; if (g_IsGameToExit) { break; @@ -2783,280 +411,55 @@ void __cdecl S_Wait(int32_t frames, const BOOL input_check) BOOL __cdecl S_InitialiseSystem(void) { Random_Seed(); - g_DumpX = 0; - g_DumpY = 0; - g_DumpHeight = g_GameVid_Height; - g_DumpWidth = g_GameVid_Width; CalculateWibbleTable(); return 1; } -void __cdecl S_DisplayPicture(const char *const file_name, const BOOL is_title) -{ - if (!is_title) { - GameBuf_Reset(); - } - M_DisplayPicture(file_name, !is_title); -} - void __cdecl DisplayCredits(void) { - S_FadeToBlack(); S_UnloadLevelFile(); if (!Level_Initialise(0, 0)) { 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); - Music_Play(MX_SKIDOO_THEME, MPM_ALWAYS); + FADER fader; for (int32_t i = 0; i < 9; i++) { char file_name[60]; sprintf(file_name, "data/credit0%d.pcx", i + 1); - FadeToPal(0, g_GamePalette8); - M_DisplayPicture(file_name, true); + Fader_InitBlackToTransparent(&fader, FRAMES_PER_SECOND / 2); + Output_LoadBackgroundFromFile(file_name); - S_InitialisePolyList(0); - S_CopyBufferToScreen(); - Console_Draw(); - Text_Draw(); - S_OutputPolyList(); - S_DumpScreen(); - FadeToPal(30, g_GamePalette8); + while (Fader_Control(&fader)) { + Output_BeginScene(); + Output_DrawBackground(); + Console_Draw(); + Text_Draw(); + Output_DrawPolyList(); + Output_DrawBlackRectangle(fader.current.value); + Output_EndScene(); + } - S_Wait(450, true); + S_Wait(15 * FRAMES_PER_SECOND, true); - S_FadeToBlack(); - S_DontDisplayPicture(); + Fader_InitTransparentToBlack(&fader, FRAMES_PER_SECOND / 2); + while (Fader_Control(&fader)) { + Output_BeginScene(); + Output_DrawBackground(); + Console_Draw(); + Text_Draw(); + Output_DrawPolyList(); + Output_DrawBlackRectangle(fader.current.value); + Output_EndScene(); + } + + Output_UnloadBackground(); if (g_IsGameToExit) { break; } } - - 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(); - return passed; -} - -int32_t __cdecl GetRenderHeight(void) -{ - return g_PhdWinHeight; -} - -int32_t __cdecl GetRenderWidth(void) -{ - return g_PhdWinWidth; -} - -void __cdecl S_InitialisePolyList(bool clear_back_buffer) -{ - CLEAR_BUFFER_FLAGS clear_buffer_flags = 0; - - if (g_WinVidNeedToResetBuffers) { - RestoreLostBuffers(); - WinVidSpinMessageLoop(0); - - 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(); - } 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; - } - } - ClearBuffers(clear_buffer_flags, 0); - clear_back_buffer = 0; - g_WinVidNeedToResetBuffers = 0; - } - - clear_buffer_flags = CLRB_PHDWINSIZE; - if (g_SavedAppSettings.render_mode == RM_SOFTWARE) { - clear_buffer_flags |= CLRB_RENDER_BUFFER; - ClearBuffers(clear_buffer_flags, 0); - } else { - if (clear_back_buffer) { - clear_buffer_flags = CLRB_BACK_BUFFER; - } - if (g_SavedAppSettings.zbuffer && g_ZBufferSurface != NULL) { - clear_buffer_flags |= CLRB_Z_BUFFER; - } - ClearBuffers(clear_buffer_flags, 0); - HWR_BeginScene(); - HWR_EnableZBuffer(true, true); - } - - Output_InitPolyList(); -} - -void __cdecl S_ClearScreen(void) -{ - ScreenClear(false); -} - -void __cdecl S_InitialiseScreen(const GAMEFLOW_LEVEL_TYPE level_type) -{ - if (level_type < 0) { - FadeToPal(0, g_GamePalette8); - } else { - FadeToPal(FRAMES_PER_SECOND, g_GamePalette8); - } - - if (g_SavedAppSettings.render_mode != RM_SOFTWARE) { - HWR_InitState(); - } -} - -void __cdecl S_OutputPolyList(void) -{ - if (g_SavedAppSettings.render_mode == RM_SOFTWARE) { - Output_SortPolyList(); - - DDSURFACEDESC desc; - const HRESULT rc = WinVidBufferLock( - g_RenderBufferSurface, &desc, DDLOCK_WRITEONLY | DDLOCK_WAIT); - if (SUCCEEDED(rc)) { - Output_PrintPolyList(desc.lpSurface); - WinVidBufferUnlock(g_RenderBufferSurface, &desc); - } - } else { - if (!g_SavedAppSettings.zbuffer - || !g_SavedAppSettings.dont_sort_primitives) { - Output_SortPolyList(); - } - HWR_DrawPolyList(); - g_D3DDev->lpVtbl->EndScene(g_D3DDev); - } -} - -void __cdecl S_InsertBackPolygon( - const int32_t x0, const int32_t y0, const int32_t x1, const int32_t y1) -{ - g_Output_InsertFlatRect( - g_PhdWinMinX + x0, g_PhdWinMinY + y0, g_PhdWinMinX + x1, - g_PhdWinMinY + y1, g_PhdFarZ + 1, g_InvColors[0]); -} - -void __cdecl S_DrawScreenLine( - const int32_t x, const int32_t y, const int32_t z, const int32_t x_len, - const int32_t y_len, const uint8_t color_idx, const D3DCOLOR *const gour, - const uint16_t flags) -{ - g_Output_InsertLine( - x, y, x + x_len, y + y_len, g_PhdNearZ + 8 * z, color_idx); -} - -void __cdecl S_DrawScreenBox( - const int32_t sx, const int32_t sy, const int32_t z, const int32_t width, - const int32_t height, const uint8_t color_idx, - const GOURAUD_OUTLINE *const gour, const uint16_t flags) -{ - const int32_t col_1 = 15; - const int32_t col_2 = 31; - S_DrawScreenLine(sx, sy - 1, z, width + 1, 0, col_1, NULL, flags); - S_DrawScreenLine(sx + 1, sy, z, width - 1, 0, col_2, NULL, flags); - S_DrawScreenLine(sx + width, sy + 1, z, 0, height - 1, col_1, NULL, flags); - S_DrawScreenLine(sx + width + 1, sy, z, 0, height + 1, col_2, NULL, flags); - S_DrawScreenLine(sx - 1, sy - 1, z, 0, height + 1, col_1, NULL, flags); - S_DrawScreenLine(sx, sy, z, 0, height - 1, col_2, NULL, flags); - S_DrawScreenLine(sx, height + sy, z, width - 1, 0, col_1, NULL, flags); - S_DrawScreenLine( - sx - 1, height + sy + 1, z, width + 1, 0, col_2, NULL, flags); -} - -void __cdecl S_DrawScreenFBox( - const int32_t sx, const int32_t sy, const int32_t z, const int32_t width, - const int32_t height, const uint8_t color_idx, - const GOURAUD_FILL *const gour, const uint16_t flags) -{ - g_Output_InsertTransQuad(sx, sy, width + 1, height + 1, g_PhdNearZ + 8 * z); -} - -void __cdecl S_FadeToBlack(void) -{ - memset(g_GamePalette8, 0, sizeof(g_GamePalette8)); - FadeToPal(10, g_GamePalette8); - ScreenClear(false); - ScreenDump(); - ScreenClear(false); - ScreenDump(); -} - -uint16_t __cdecl S_FindColor( - const int32_t red, const int32_t green, const int32_t blue) -{ - return FindNearestPaletteEntry(g_GamePalette8, red, green, blue, false); -} - -void __cdecl S_CopyBufferToScreen(void) -{ - if (g_SavedAppSettings.render_mode == RM_SOFTWARE) { - if (memcmp(g_GamePalette8, g_PicturePalette, 256 * 100) != 0) { - S_SyncPictureBufferPalette(); - } - g_RenderBufferSurface->lpVtbl->Blt( - g_RenderBufferSurface, &g_GameVid_Rect, g_PictureBufferSurface, - NULL, DDBLT_WAIT, NULL); - } else if (g_BGND_PictureIsReady) { - BGND_GetPageHandles(); - HWR_EnableZBuffer(false, false); - - const uint32_t color = 0xFFFFFFFF; - const int32_t tile_x[4] = { 0, 256, 512, 640 }; - const int32_t tile_y[3] = { 0, 256, 480 }; - int32_t x[4]; - int32_t y[3]; - - for (int32_t i = 0; i < 4; i++) { - x[i] = g_PhdWinMinX + tile_x[i] * g_PhdWinWidth / 640; - } - for (int32_t i = 0; i < 3; i++) { - y[i] = g_PhdWinMinY + tile_y[i] * g_PhdWinHeight / 480; - } - - 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( - 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( - 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( - 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( - 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( - 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); - } else { - BGND_DrawInGameBackground(); - } } void __cdecl IncreaseScreenSize(void) @@ -3064,7 +467,7 @@ void __cdecl IncreaseScreenSize(void) if (g_Config.rendering.sizer < 1.0) { g_Config.rendering.sizer += 0.08; CLAMPG(g_Config.rendering.sizer, 1.0); - setup_screen_size(); + Viewport_Reset(); } } @@ -3073,200 +476,22 @@ void __cdecl DecreaseScreenSize(void) if (g_Config.rendering.sizer > 0.44) { g_Config.rendering.sizer -= 0.08; CLAMPL(g_Config.rendering.sizer, 0.44); - setup_screen_size(); + Viewport_Reset(); } } -void __cdecl setup_screen_size(void) +BOOL __cdecl S_LoadLevelFile( + const char *const file_name, const int32_t level_num, + const GAMEFLOW_LEVEL_TYPE level_type) { - int32_t width = (double)g_GameVid_Width * g_Config.rendering.sizer; - int32_t height = (double)g_GameVid_Height * g_Config.rendering.sizer; - CLAMPG(width, g_GameVid_Width); - CLAMPG(height, g_GameVid_Height); - const int32_t x = (g_GameVid_Width - width) / 2; - const int32_t y = (g_GameVid_Height - height) / 2; - Output_Init( - x, y, width, height, VIEW_NEAR, VIEW_FAR, GAME_FOV, g_GameVid_BufWidth, - g_GameVid_BufHeight); - g_DumpY = y; - g_DumpX = x; - g_DumpWidth = width; - g_DumpHeight = height; - g_WinVidNeedToResetBuffers = true; + S_UnloadLevelFile(); + return Level_Load(file_name, level_num); } -void __cdecl S_FadeInInventory(const bool is_fade) +void __cdecl S_UnloadLevelFile(void) { - if (g_Inv_Mode != INV_TITLE_MODE) { - S_CopyScreenToBuffer(); - } - if (is_fade) { - g_FadeValue = 0x100000; - g_FadeLimit = 0x180000; - g_FadeAdder = 0x8000; - } -} - -void __cdecl S_FadeOutInventory(const bool is_fade) -{ - if (is_fade) { - g_FadeValue = 0x180000; - g_FadeLimit = 0x100000; - g_FadeAdder = -0x8000; - } -} - -void __cdecl CopyBitmapPalette( - const RGB_888 *const src_pal, const uint8_t *const src_bitmap, - const int32_t bitmap_size, RGB_888 *const out_pal) -{ - PALETTEENTRY first_sys_pal_entries[10]; - PALETTEENTRY last_sys_pal_entries[10]; - - for (int32_t i = 0; i < 256; i++) { - g_SortBuffer[i]._0 = i; - g_SortBuffer[i]._1 = 0; - } - - for (int32_t i = 0; i < bitmap_size; i++) { - g_SortBuffer[src_bitmap[i]]._1++; - } - - Output_QuickSort(0, 255); - - const HDC dc = GetDC(NULL); - GetSystemPaletteEntries(dc, 0, 10, first_sys_pal_entries); - GetSystemPaletteEntries(dc, 256, 10, last_sys_pal_entries); - ReleaseDC(NULL, dc); - - for (int32_t i = 0; i < 8; i++) { - out_pal[i].red = first_sys_pal_entries[i].peRed; - out_pal[i].green = first_sys_pal_entries[i].peGreen; - out_pal[i].blue = first_sys_pal_entries[i].peBlue; - } - for (int32_t i = 8; i < 10; i++) { - out_pal[i].red = 0; - out_pal[i].green = 0; - out_pal[i].blue = 0; - } - - for (int32_t i = 10; i < 246; i++) { - const int32_t j = i - 10; - out_pal[i] = src_pal[g_SortBuffer[j]._0]; - } - - out_pal[246].red = 0; - out_pal[246].green = 0; - out_pal[246].blue = 0; - for (int32_t i = 247; i < 10; i++) { - const int32_t j = i - 246; - out_pal[j].red = last_sys_pal_entries[j].peRed; - out_pal[j].green = last_sys_pal_entries[j].peGreen; - out_pal[j].blue = last_sys_pal_entries[j].peBlue; - } -} - -uint8_t __cdecl FindNearestPaletteEntry( - const RGB_888 *const palette, const int32_t red, const int32_t green, - const int32_t blue, const bool ignore_sys_palette) -{ - int32_t start_idx; - int32_t end_idx; - if (ignore_sys_palette) { - start_idx = 10; - end_idx = 246; - } else { - start_idx = 0; - end_idx = 256; - } - - int32_t best_idx = 0; - int32_t best_diff = INT32_MAX; - for (int32_t i = start_idx; i < end_idx; i++) { - const int32_t dr = red - palette[i].red; - const int32_t dg = green - palette[i].green; - const int32_t db = blue - palette[i].blue; - const int32_t diff = SQUARE(dr) + SQUARE(dg) + SQUARE(db); - if (diff < best_diff) { - best_diff = diff; - best_idx = i; - } - } - - return best_idx; -} - -void __cdecl SyncSurfacePalettes( - const void *const src_data, const int32_t width, const int32_t height, - const int32_t src_pitch, const RGB_888 *const src_palette, - void *const dst_data, const int32_t dst_pitch, - const RGB_888 *const dst_palette, const bool preserve_sys_palette) -{ - const uint8_t *src_ptr = src_data; - uint8_t *dst_ptr = dst_data; - uint8_t buf_palette[256]; - - for (int32_t i = 0; i < 256; i++) { - buf_palette[i] = FindNearestPaletteEntry( - dst_palette, src_palette[i].red, src_palette[i].green, - src_palette[i].blue, preserve_sys_palette); - } - - for (int32_t y = 0; y < height; y++) { - for (int32_t x = 0; x < width; x++) { - *dst_ptr++ = buf_palette[*src_ptr++]; - } - src_ptr += src_pitch - width; - dst_ptr += dst_pitch - width; - } -} - -int32_t __cdecl CreateTexturePalette(const RGB_888 *const palette) -{ - const int32_t palette_idx = GetFreePaletteIndex(); - if (palette_idx < 0) { - return -1; - } - - PALETTEENTRY pal_entries[256]; - for (int32_t i = 0; i < 256; i++) { - pal_entries[i].peRed = palette[i].red; - pal_entries[i].peGreen = palette[i].green; - pal_entries[i].peBlue = palette[i].blue; - pal_entries[i].peFlags = 0; - } - - const HRESULT rc = g_DDraw->lpVtbl->CreatePalette( - g_DDraw, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, pal_entries, - &g_TexturePalettes[palette_idx], NULL); - if (FAILED(rc)) { - return -1; - } - return palette_idx; -} - -int32_t __cdecl GetFreePaletteIndex(void) -{ - for (int32_t i = 0; i < MAX_PALETTES; i++) { - if (g_TexturePalettes[i] == NULL) { - return i; - } - } - return -1; -} - -void __cdecl FreePalette(const int32_t palette_idx) -{ - LPDIRECTDRAWPALETTE palette = g_TexturePalettes[palette_idx]; - if (palette != NULL) { - palette->lpVtbl->Release(palette); - g_TexturePalettes[palette_idx] = NULL; - } -} - -void __cdecl SafeFreePalette(const int32_t palette_idx) -{ - if (palette_idx >= 0) { - FreePalette(palette_idx); - } + strcpy(g_LevelFileName, ""); + memset(g_TexturePageBuffer8, 0, sizeof(uint8_t *) * MAX_TEXTURE_PAGES); + memset(g_TexturePageBuffer16, 0, sizeof(uint16_t *) * MAX_TEXTURE_PAGES); + g_TextureInfoCount = 0; } diff --git a/src/tr2/decomp/decomp.h b/src/tr2/decomp/decomp.h index 685182fc2..92a69458b 100644 --- a/src/tr2/decomp/decomp.h +++ b/src/tr2/decomp/decomp.h @@ -10,199 +10,28 @@ // they'll need to be properly modularized. The same applies to all files // within the decomp/ directory which are scheduled for extensive refactoring. -int32_t __cdecl GameInit(void); int32_t __stdcall WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int32_t nShowCmd); -const char *__cdecl DecodeErrorMessage(int32_t error_code); -int32_t __cdecl RenderErrorBox(int32_t error_code); -bool __cdecl DInputCreate(void); -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); -bool __cdecl WinVidClearBuffer(LPDDS surface, LPRECT rect, DWORD fill_color); -HRESULT __cdecl WinVidBufferLock(LPDDS surface, LPDDSDESC desc, DWORD flags); -HRESULT __cdecl WinVidBufferUnlock(LPDDS surface, LPDDSDESC desc); -bool __cdecl WinVidCopyBitmapToBuffer(LPDDS surface, const BYTE *bitmap); -DWORD __cdecl GetRenderBitDepth(uint32_t rgb_bit_count); -void __thiscall WinVidGetColorBitMasks( - COLOR_BIT_MASKS *bm, LPDDPIXELFORMAT pixel_format); -void __cdecl BitMaskGetNumberOfBits( - uint32_t bit_mask, uint32_t *bit_depth, uint32_t *bit_offset); -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); -int32_t __cdecl Game_Cutscene_Control(int32_t nframes); void __cdecl CutscenePlayer_Control(int16_t item_num); void __cdecl Lara_Control_Cutscene(int16_t item_num); 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); -bool __cdecl ApplySettings(const APP_SETTINGS *new_settings); -void __cdecl GameApplySettings(APP_SETTINGS *new_settings); -void __cdecl UpdateGameResolution(void); -bool __cdecl D3DCreate(void); -void __cdecl D3DRelease(void); -void __cdecl Enumerate3DDevices(DISPLAY_ADAPTER *adapter); -HRESULT __stdcall Enum3DDevicesCallback( - GUID FAR *lpGuid, LPTSTR lpDeviceDescription, LPTSTR lpDeviceName, - LPD3DDEVICEDESC_V2 lpD3DHWDeviceDesc, LPD3DDEVICEDESC_V2 lpD3DHELDeviceDesc, - LPVOID lpContext); -bool __cdecl D3DIsSupported(LPD3DDEVICEDESC_V2 desc); -bool __cdecl D3DSetViewport(void); -void __cdecl D3DDeviceCreate(LPDDS lpBackBuffer); -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( - DISPLAY_ADAPTER_LIST *display_adapter_list); -bool __cdecl WinVidRegisterGameWindowClass(void); -LRESULT CALLBACK -WinVidGameWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); -BOOL WINAPI EnumDisplayAdaptersCallback( - GUID FAR *lpGUID, LPTSTR lpDriverDescription, LPTSTR lpDriverName, - LPVOID lpContext); -void __cdecl WinVidResizeGameWindow(HWND hWnd, int32_t edge, LPRECT rect); -bool __cdecl WinVidCheckGameWindowPalette(HWND hWnd); -bool __cdecl WinVidCreateGameWindow(void); -void __cdecl WinVidFreeWindow(void); -void __cdecl WinVidExitMessage(void); -DISPLAY_ADAPTER_NODE *__cdecl WinVidGetDisplayAdapter(const GUID *guid_ptr); -void __cdecl WinVidStart(void); -void __cdecl WinVidFinish(void); int32_t __cdecl Misc_Move3DPosTo3DPos( PHD_3DPOS *src_pos, const PHD_3DPOS *dst_pos, int32_t velocity, PHD_ANGLE ang_add); int32_t __cdecl LevelCompleteSequence(void); void __cdecl S_Wait(int32_t frames, BOOL input_check); BOOL __cdecl S_InitialiseSystem(void); -void __cdecl S_DisplayPicture(const char *file_name, BOOL is_title); void __cdecl DisplayCredits(void); -DWORD __cdecl S_DumpScreen(void); -int32_t __cdecl GetRenderHeight(void); -int32_t __cdecl GetRenderWidth(void); void __cdecl S_InitialisePolyList(bool clear_back_buffer); -void __cdecl S_ClearScreen(void); -void __cdecl S_InitialiseScreen(GAMEFLOW_LEVEL_TYPE level_type); -void __cdecl S_OutputPolyList(void); -void __cdecl S_InsertBackPolygon( - int32_t x0, int32_t y0, int32_t x1, int32_t y1); -void __cdecl S_DrawScreenLine( - int32_t x, int32_t y, int32_t z, int32_t x_len, int32_t y_len, - uint8_t color_idx, const D3DCOLOR *gour, uint16_t flags); -void __cdecl S_DrawScreenBox( - int32_t sx, int32_t sy, int32_t z, int32_t width, int32_t height, - uint8_t color_idx, const GOURAUD_OUTLINE *gour, uint16_t flags); -void __cdecl S_DrawScreenFBox( - int32_t sx, int32_t sy, int32_t z, int32_t width, int32_t height, - uint8_t color_idx, const GOURAUD_FILL *gour, uint16_t flags); -void __cdecl S_FadeToBlack(void); -uint16_t __cdecl S_FindColor(int32_t red, int32_t green, int32_t blue); -void __cdecl S_CopyBufferToScreen(void); void __cdecl DecreaseScreenSize(void); void __cdecl IncreaseScreenSize(void); -void __cdecl setup_screen_size(void); -void __cdecl S_FadeInInventory(bool is_fade); -void __cdecl S_FadeOutInventory(bool is_fade); -void __cdecl CopyBitmapPalette( - const RGB_888 *src_pal, const uint8_t *src_bitmap, int32_t bitmap_size, - RGB_888 *out_pal); -uint8_t __cdecl FindNearestPaletteEntry( - const RGB_888 *palette, int32_t red, int32_t green, int32_t blue, - bool ignore_sys_palette); -void __cdecl SyncSurfacePalettes( - const void *src_data, int32_t width, int32_t height, int32_t src_pitch, - const RGB_888 *src_palette, void *dst_data, int32_t dst_pitch, - const RGB_888 *dst_palette, bool preserve_sys_palette); -int32_t __cdecl CreateTexturePalette(const RGB_888 *palette); -int32_t __cdecl GetFreePaletteIndex(void); -void __cdecl FreePalette(int32_t palette_idx); -void __cdecl SafeFreePalette(int32_t palette_idx); -int32_t __cdecl CreateTexturePage( - int32_t width, int32_t height, LPDIRECTDRAWPALETTE palette); -int32_t __cdecl GetFreeTexturePageIndex(void); -bool __cdecl CreateTexturePageSurface(TEXPAGE_DESC *desc); -bool __cdecl TexturePageInit(TEXPAGE_DESC *page); -LPDIRECT3DTEXTURE2 __cdecl Create3DTexture(const LPDDS surface); -void __cdecl SafeFreeTexturePage(int32_t page_idx); -void __cdecl FreeTexturePage(int32_t page_idx); -void __cdecl TexturePageReleaseVidMemSurface(TEXPAGE_DESC *page); -void __cdecl FreeTexturePages(void); -bool __cdecl LoadTexturePage(int32_t page_idx, bool reset); -bool __cdecl ReloadTextures(bool reset); -HWR_TEXTURE_HANDLE __cdecl GetTexturePageHandle(int32_t page_idx); -int32_t __cdecl AddTexturePage8( - int32_t width, int32_t height, const uint8_t *page_buf, int32_t pal_idx); -int32_t __cdecl AddTexturePage16( - int32_t width, int32_t height, const uint8_t *page_buf); -HRESULT __stdcall EnumTextureFormatsCallback(LPDDSDESC desc, LPVOID lpContext); -HRESULT __cdecl EnumerateTextureFormats(void); -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); -void __cdecl AdjustTextureUVs(bool reset_uv_add); -void __cdecl S_AdjustTexelCoordinates(void); BOOL __cdecl S_LoadLevelFile( const char *file_name, int32_t level_num, GAMEFLOW_LEVEL_TYPE level_type); void __cdecl S_UnloadLevelFile(void); -BOOL __cdecl S_ReloadLevelGraphics(bool reload_palettes, bool reload_tex_pages); -int32_t __cdecl SE_ReadAppSettings(APP_SETTINGS *settings); diff --git a/src/tr2/decomp/decomp2.c b/src/tr2/decomp/decomp2.c deleted file mode 100644 index 19386e1c8..000000000 --- a/src/tr2/decomp/decomp2.c +++ /dev/null @@ -1,692 +0,0 @@ -#include "decomp/decomp.h" -#include "game/background.h" -#include "game/hwr.h" -#include "game/inventory/common.h" -#include "game/level.h" -#include "global/funcs.h" -#include "global/vars.h" - -#include -#include - -int32_t __cdecl CreateTexturePage( - const int32_t width, const int32_t height, LPDIRECTDRAWPALETTE palette) -{ - const int32_t palette_idx = GetFreeTexturePageIndex(); - if (palette_idx < 0) { - return -1; - } - TEXPAGE_DESC *const page = &g_TexturePages[palette_idx]; - memset(page, 0, sizeof(TEXPAGE_DESC)); - page->status = 1; - page->width = width; - page->height = height; - page->palette = palette; - if (!CreateTexturePageSurface(page)) { - return -1; - } - - TexturePageInit((TEXPAGE_DESC *)&g_TexturePages[palette_idx]); - return palette_idx; -} - -int32_t __cdecl GetFreeTexturePageIndex(void) -{ - for (int32_t i = 0; i < MAX_TEXTURE_PAGES; i++) { - if (!(g_TexturePages[i].status & 1)) { - return i; - } - } - return -1; -} - -bool __cdecl CreateTexturePageSurface(TEXPAGE_DESC *const page) -{ - DDSURFACEDESC dsp = { 0 }; - dsp.dwSize = sizeof(dsp); - dsp.dwFlags = DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; - dsp.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY; - dsp.dwWidth = page->width; - dsp.dwHeight = page->height; - dsp.ddpfPixelFormat = g_TextureFormat.pixel_fmt; - - if (FAILED(DDrawSurfaceCreate(&dsp, &page->sys_mem_surface))) { - return false; - } - - if (page->palette != NULL - && FAILED(page->sys_mem_surface->lpVtbl->SetPalette( - page->sys_mem_surface, page->palette))) { - return false; - } - - return true; -} - -bool __cdecl TexturePageInit(TEXPAGE_DESC *const page) -{ - bool result = false; - - DDSURFACEDESC dsp = { 0 }; - dsp.dwSize = sizeof(dsp); - dsp.dwFlags = DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; - dsp.dwWidth = page->width; - dsp.dwHeight = page->height; - dsp.ddpfPixelFormat = g_TextureFormat.pixel_fmt; - dsp.ddsCaps.dwCaps = - DDSCAPS_ALLOCONLOAD | DDSCAPS_VIDEOMEMORY | DDSCAPS_TEXTURE; - - if (FAILED(DDrawSurfaceCreate(&dsp, &page->vid_mem_surface))) { - return false; - } - - if (page->palette != NULL) { - if (FAILED(page->vid_mem_surface->lpVtbl->SetPalette( - page->vid_mem_surface, page->palette))) { - goto cleanup; - } - - DDCOLORKEY color_key; - color_key.dwColorSpaceLowValue = 0; - color_key.dwColorSpaceHighValue = 0; - if (FAILED(page->vid_mem_surface->lpVtbl->SetColorKey( - page->vid_mem_surface, DDCKEY_SRCBLT, &color_key))) { - goto cleanup; - } - } - - page->texture_3d = Create3DTexture(page->vid_mem_surface); - if (page->texture_3d == NULL) { - goto cleanup; - } - - if (FAILED(page->texture_3d->lpVtbl->GetHandle( - page->texture_3d, g_D3DDev, &page->tex_handle))) { - goto cleanup; - } - - result = true; - -cleanup: - if (!result) { - if (page->texture_3d != NULL) { - page->texture_3d->lpVtbl->Release(page->texture_3d); - page->texture_3d = NULL; - } - - if (page->vid_mem_surface != NULL) { - page->vid_mem_surface->lpVtbl->Release(page->vid_mem_surface); - page->vid_mem_surface = NULL; - } - } - - return result; -} - -LPDIRECT3DTEXTURE2 __cdecl Create3DTexture(const LPDDS surface) -{ - LPDIRECT3DTEXTURE2 texture_3d = NULL; - if (FAILED(surface->lpVtbl->QueryInterface( - surface, &g_IID_IDirect3DTexture2, (LPVOID *)&texture_3d))) { - return NULL; - } - return texture_3d; -} - -void __cdecl SafeFreeTexturePage(const int32_t page_idx) -{ - if (page_idx >= 0 && (g_TexturePages[page_idx].status & 1)) { - FreeTexturePage(page_idx); - } -} - -void __cdecl FreeTexturePage(const int32_t page_idx) -{ - TEXPAGE_DESC *const page = &g_TexturePages[page_idx]; - TexturePageReleaseVidMemSurface(page); - if (page->sys_mem_surface != NULL) { - page->sys_mem_surface->lpVtbl->Release(page->sys_mem_surface); - page->sys_mem_surface = NULL; - } - page->status = 0; -} - -void __cdecl TexturePageReleaseVidMemSurface(TEXPAGE_DESC *const page) -{ - HWR_ResetTexSource(); - page->tex_handle = 0; - if (page->texture_3d != NULL) { - page->texture_3d->lpVtbl->Release(page->texture_3d); - page->texture_3d = NULL; - } - if (page->vid_mem_surface != NULL) { - page->vid_mem_surface->lpVtbl->Release(page->vid_mem_surface); - page->vid_mem_surface = NULL; - } -} - -void __cdecl FreeTexturePages(void) -{ - for (int32_t i = 0; i < MAX_TEXTURE_PAGES; i++) { - TEXPAGE_DESC *const page = &g_TexturePages[i]; - if (page->status & 1) { - FreeTexturePage(i); - } - } -} - -bool __cdecl LoadTexturePage(const int32_t page_idx, const bool reset) -{ - bool rc = false; - if (page_idx < 0) { - return false; - } - - TEXPAGE_DESC *const page = &g_TexturePages[page_idx]; - if (reset || page->vid_mem_surface == NULL) { - rc = SUCCEEDED( - DDrawSurfaceRestoreLost(page->vid_mem_surface, NULL, false)); - } - - if (!rc) { - TexturePageReleaseVidMemSurface(page); - rc = TexturePageInit(page); - } - - if (!rc) { - return false; - } - - DDrawSurfaceRestoreLost(page->sys_mem_surface, 0, 0); - LPDIRECT3DTEXTURE2 sys_mem_texture = Create3DTexture(page->sys_mem_surface); - if (sys_mem_texture == NULL) { - return false; - } - - rc = SUCCEEDED( - page->texture_3d->lpVtbl->Load(page->texture_3d, sys_mem_texture)); - sys_mem_texture->lpVtbl->Release(sys_mem_texture); - return rc; -} - -bool __cdecl ReloadTextures(const bool reset) -{ - bool result = true; - for (int32_t i = 0; i < MAX_TEXTURE_PAGES; i++) { - if (g_TexturePages[i].status & 1) { - result &= LoadTexturePage(i, reset); - } - } - return result; -} - -HWR_TEXTURE_HANDLE __cdecl GetTexturePageHandle(const int32_t page_idx) -{ - if (page_idx < 0) { - return 0; - } - - TEXPAGE_DESC *const page = &g_TexturePages[page_idx]; - if (page->vid_mem_surface != NULL) { - if (page->vid_mem_surface->lpVtbl->IsLost(page->vid_mem_surface) - == DDERR_SURFACELOST) { - LoadTexturePage(page_idx, true); - } - } - return page->tex_handle; -} - -int32_t __cdecl AddTexturePage8( - const int32_t width, const int32_t height, const uint8_t *const page_buf, - const int32_t pal_idx) -{ - if (pal_idx < 0) { - return -1; - } - - const int32_t page_idx = - CreateTexturePage(width, height, g_TexturePalettes[pal_idx]); - if (page_idx < 0) { - return -1; - } - - TEXPAGE_DESC *const page = &g_TexturePages[page_idx]; - - DDSURFACEDESC desc; - if (FAILED(WinVidBufferLock( - page->sys_mem_surface, &desc, DDLOCK_WRITEONLY | DDLOCK_WAIT))) { - return -1; - } - - const uint8_t *src = page_buf; - uint8_t *dst = desc.lpSurface; - for (int32_t y = 0; y < height; y++) { - memcpy(dst, src, width); - src += width; - dst += desc.lPitch; - } - - WinVidBufferUnlock(page->sys_mem_surface, &desc); - LoadTexturePage(page_idx, false); - - return page_idx; -} - -int32_t __cdecl AddTexturePage16( - const int32_t width, const int32_t height, const uint8_t *const page_buf) -{ - const int32_t page_idx = CreateTexturePage(width, height, NULL); - if (page_idx < 0) { - return -1; - } - - TEXPAGE_DESC *const page = &g_TexturePages[page_idx]; - - DDSURFACEDESC desc; - if (FAILED(WinVidBufferLock( - page->sys_mem_surface, &desc, DDLOCK_WRITEONLY | DDLOCK_WAIT))) { - return -1; - } - - if (g_TexturesHaveCompatibleMasks) { - const uint8_t *src = page_buf; - uint8_t *dst = (uint8_t *)desc.lpSurface; - for (int32_t y = 0; y < height; y++) { - memcpy(dst, src, 2 * width); - src += 2 * width; - dst += desc.lPitch; - } - } else { - const int32_t bytes_per_pixel = (g_TextureFormat.bpp + 7) >> 3; - - uint8_t *dst = (uint8_t *)desc.lpSurface; - uint16_t *src = (uint16_t *)page_buf; - for (int32_t y = 0; y < height; y++) { - uint8_t *subdst = dst; - for (int32_t x = 0; x < width; x++) { - uint32_t compatible_color = CalculateCompatibleColor( - &g_TextureFormat.color_bit_masks, (*src >> 7) & 0xF8, - (*src >> 2) & 0xF8, (*src << 3) & 0xF8, (*src >> 15) & 1); - src++; - - for (int32_t k = 0; k < bytes_per_pixel; k++) { - *subdst++ = compatible_color; - compatible_color >>= 8; - } - } - - dst += desc.lPitch; - } - } - - WinVidBufferUnlock(page->sys_mem_surface, &desc); - LoadTexturePage(page_idx, false); - - return page_idx; -} - -HRESULT __stdcall EnumTextureFormatsCallback(LPDDSDESC desc, LPVOID lpContext) -{ - DDPIXELFORMAT *pixel_fmt = &desc->ddpfPixelFormat; - if (pixel_fmt->dwRGBBitCount < 8) { - return D3DENUMRET_OK; - } - - if (g_SavedAppSettings.disable_16bit_textures - || pixel_fmt->dwRGBBitCount != 16) { - if (pixel_fmt->dwFlags & DDPF_PALETTEINDEXED8) { - g_TextureFormat.pixel_fmt = *pixel_fmt; - g_TextureFormat.bpp = 8; - g_TexturesAlphaChannel = 0; - g_TexturesHaveCompatibleMasks = false; - return D3DENUMRET_CANCEL; - } - } else if (pixel_fmt->dwFlags & DDPF_RGB) { - g_TextureFormat.pixel_fmt = *pixel_fmt; - g_TextureFormat.bpp = 16; - g_TexturesAlphaChannel = pixel_fmt->dwFlags & DDPF_ALPHAPIXELS; - WinVidGetColorBitMasks(&g_TextureFormat.color_bit_masks, pixel_fmt); - - if (g_TextureFormat.bpp == 16 - && g_TextureFormat.color_bit_masks.depth.a == 1 - && g_TextureFormat.color_bit_masks.depth.r == 5 - && g_TextureFormat.color_bit_masks.depth.g == 5 - && g_TextureFormat.color_bit_masks.depth.b == 5 - && g_TextureFormat.color_bit_masks.offset.a == 15 - && g_TextureFormat.color_bit_masks.offset.r == 10 - && g_TextureFormat.color_bit_masks.offset.g == 5 - && g_TextureFormat.color_bit_masks.offset.b == 0) { - g_TexturesHaveCompatibleMasks = true; - return D3DENUMRET_CANCEL; - } else { - g_TexturesHaveCompatibleMasks = false; - return D3DENUMRET_OK; - } - } - - return D3DENUMRET_OK; -} - -HRESULT __cdecl EnumerateTextureFormats(void) -{ - memset(&g_TextureFormat, 0, sizeof(g_TextureFormat)); - return g_D3DDev->lpVtbl->EnumTextureFormats( - g_D3DDev, EnumTextureFormatsCallback, NULL); -} - -void __cdecl CleanupTextures(void) -{ - FreeTexturePages(); - for (int32_t i = 0; i < MAX_PALETTES; i++) { - SafeFreePalette(i); - } -} - -bool __cdecl InitTextures(void) -{ - memset(g_TexturePages, 0, sizeof(TEXPAGE_DESC) * MAX_TEXTURE_PAGES); - memset(g_TexturePalettes, 0, sizeof(LPDIRECTDRAWPALETTE) * MAX_PALETTES); - return true; -} - -void __cdecl S_SyncPictureBufferPalette(void) -{ - if (g_PictureBufferSurface == NULL) { - return; - } - - DDSURFACEDESC desc; - if (FAILED(WinVidBufferLock( - g_PictureBufferSurface, &desc, DDLOCK_WRITEONLY | DDLOCK_WAIT))) { - return; - } - - SyncSurfacePalettes( - desc.lpSurface, 640, 480, desc.lPitch, g_PicturePalette, desc.lpSurface, - desc.lPitch, g_GamePalette8, true); - WinVidBufferUnlock(g_PictureBufferSurface, &desc); - memcpy(g_PicturePalette, g_GamePalette8, sizeof(RGB_888) * 256); -} - -void __cdecl S_DontDisplayPicture(void) -{ - if (g_SavedAppSettings.render_mode == RM_HARDWARE) { - BGND_Free(); - g_BGND_PictureIsReady = 0; - } -} - -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; - } - 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]; - } - - 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; - } - g_DDrawPalette->lpVtbl->SetEntries( - g_DDrawPalette, 0, start_idx, pal_size, - &g_WinVid_Palette[start_idx]); - S_DumpScreen(); - } -} - -void __cdecl ScreenClear(const bool is_phd_win_size) -{ - uint32_t flags = (g_SavedAppSettings.render_mode == RM_HARDWARE) - ? CLRB_BACK_BUFFER - : CLRB_RENDER_BUFFER; - - if (is_phd_win_size) { - flags |= CLRB_PHDWINSIZE; - } - - ClearBuffers(flags, 0); -} - -void __cdecl S_CopyScreenToBuffer(void) -{ - if (g_SavedAppSettings.render_mode != RM_SOFTWARE) { - return; - } - - g_PictureBufferSurface->lpVtbl->Blt( - g_PictureBufferSurface, NULL, g_RenderBufferSurface, &g_GameVid_Rect, - DDBLT_WAIT, NULL); - - DDSURFACEDESC desc; - if (SUCCEEDED(WinVidBufferLock( - g_PictureBufferSurface, &desc, DDLOCK_WRITEONLY | DDLOCK_WAIT))) { - uint8_t *dst_ptr = desc.lpSurface; - for (int32_t y = 0; y < 480; y++) { - for (int32_t x = 0; x < 640; x++) { - dst_ptr[x] = g_DepthQIndex[dst_ptr[x]]; - } - dst_ptr += desc.lPitch; - } - WinVidBufferUnlock(g_PictureBufferSurface, &desc); - } - - memcpy(g_PicturePalette, g_GamePalette8, sizeof(RGB_888) * 256); -} - -void __cdecl AdjustTextureUVs(const bool reset_uv_add) -{ - if (reset_uv_add) { - g_UVAdd = 0; - } - - int32_t adjustment = g_SavedAppSettings.nearest_adjustment; - if (g_SavedAppSettings.render_mode == RM_HARDWARE - && (g_SavedAppSettings.texel_adjust_mode == TAM_ALWAYS - || (g_SavedAppSettings.texel_adjust_mode == TAM_BILINEAR_ONLY - && g_SavedAppSettings.bilinear_filtering))) { - adjustment = g_SavedAppSettings.linear_adjustment; - } - - const int32_t offset = adjustment - g_UVAdd; - for (int32_t i = 0; i < g_TextureInfoCount; i++) { - PHD_UV *const uv = g_TextureInfo[i].uv; - int32_t uv_flags = g_LabTextureUVFlag[i]; - for (int32_t j = 0; j < 4; j++) { - uv[j].u += (uv_flags & 1) ? -offset : offset; - uv[j].v += (uv_flags & 2) ? -offset : offset; - uv_flags >>= 2; - } - } - - g_UVAdd += offset; -} - -void __cdecl S_AdjustTexelCoordinates(void) -{ - if (g_TextureInfoCount > 0) { - AdjustTextureUVs(false); - } -} - -BOOL __cdecl S_LoadLevelFile( - const char *const file_name, const int32_t level_num, - const GAMEFLOW_LEVEL_TYPE level_type) -{ - S_UnloadLevelFile(); - return Level_Load(file_name, level_num); -} - -void __cdecl S_UnloadLevelFile(void) -{ - if (g_SavedAppSettings.render_mode == RM_HARDWARE) { - HWR_FreeTexturePages(); - } - strcpy(g_LevelFileName, ""); - memset(g_TexturePageBuffer8, 0, sizeof(uint8_t *) * MAX_TEXTURE_PAGES); - g_TextureInfoCount = 0; -} - -BOOL __cdecl S_ReloadLevelGraphics( - const bool reload_palettes, const bool reload_tex_pages) -{ - if (g_LevelFileName[0] != '\0') { - VFILE *const file = VFile_CreateFromPath(g_LevelFileName); - if (file == NULL) { - return false; - } - - if (reload_palettes && g_SavedAppSettings.render_mode == RM_SOFTWARE) { - VFile_SetPos(file, g_LevelFilePalettesOffset); - Level_LoadPalettes(file); - - VFile_SetPos(file, g_LevelFileDepthQOffset); - Level_LoadDepthQ(file); - } - - if (reload_tex_pages) { - if (g_SavedAppSettings.render_mode == RM_HARDWARE) { - HWR_FreeTexturePages(); - } - VFile_SetPos(file, g_LevelFileTexPagesOffset); - Level_LoadTexturePages(file); - } - - VFile_Close(file); - } - - if (reload_palettes) { - Inv_InitColors(); - } - - return true; -} - -int32_t __cdecl SE_ReadAppSettings(APP_SETTINGS *const settings) -{ - if (!OpenGameRegistryKey("System")) { - return 0; - } - - bool rc; - GUID value; - rc = GetRegistryGuidValue("PreferredDisplayAdapterGUID", &value, 0); - settings->preferred_display_adapter = - WinVidGetDisplayAdapter(rc ? &value : 0); - - settings->preferred_sound_adapter = NULL; - settings->preferred_joystick = NULL; - - DISPLAY_MODE dm; - GetRegistryDwordValue( - "RenderMode", (DWORD *)&settings->render_mode, RM_HARDWARE); - GetRegistryBoolValue("Dither", &settings->dither, false); - GetRegistryBoolValue("ZBuffer", &settings->zbuffer, true); - GetRegistryBoolValue( - "BilinearFiltering", &settings->bilinear_filtering, true); - GetRegistryBoolValue("TripleBuffering", &settings->triple_buffering, false); - GetRegistryBoolValue("FullScreen", &settings->fullscreen, true); - GetRegistryDwordValue( - "WindowWidth", (DWORD *)&settings->window_width, 1280); - GetRegistryDwordValue( - "WindowHeight", (DWORD *)&settings->window_height, 720); - GetRegistryDwordValue( - "AspectMode", (DWORD *)&settings->aspect_mode, AM_4_3); - GetRegistryDwordValue("FullScreenWidth", (DWORD *)&dm.width, 1280); - GetRegistryDwordValue("FullScreenHeight", (DWORD *)&dm.height, 720); - GetRegistryDwordValue("FullScreenBPP", (DWORD *)&dm.bpp, 16); - GetRegistryBoolValue("SoundEnabled", &settings->sound_enabled, true); - GetRegistryBoolValue("LaraMic", &settings->lara_mic, false); - GetRegistryBoolValue("JoystickEnabled", &settings->joystick_enabled, true); - GetRegistryBoolValue( - "Disable16BitTextures", &settings->disable_16bit_textures, false); - GetRegistryBoolValue( - "DontSortPrimitives", &settings->dont_sort_primitives, false); - GetRegistryDwordValue( - "TexelAdjustMode", (DWORD *)&settings->texel_adjust_mode, TAM_ALWAYS); - GetRegistryDwordValue( - "NearestAdjustment", (DWORD *)&settings->nearest_adjustment, 16); - GetRegistryDwordValue( - "LinearAdjustment", (DWORD *)&settings->linear_adjustment, 128); - GetRegistryBoolValue("FlipBroken", &settings->flip_broken, false); - - if (settings->render_mode != RM_HARDWARE - && settings->render_mode != RM_SOFTWARE) { - settings->render_mode = RM_SOFTWARE; - } - if (settings->aspect_mode != AM_ANY && settings->aspect_mode != AM_16_9) { - settings->aspect_mode = AM_4_3; - } - if (settings->texel_adjust_mode != TAM_DISABLED - && settings->texel_adjust_mode != TAM_BILINEAR_ONLY) { - settings->texel_adjust_mode = TAM_ALWAYS; - } - CLAMP(settings->nearest_adjustment, 0, 256); - CLAMP(settings->linear_adjustment, 0, 256); - - GetRegistryBoolValue( - "PerspectiveCorrect", &settings->perspective_correct, - settings->render_mode != RM_SOFTWARE); - - DISPLAY_MODE_LIST *disp_mode_list = - &settings->preferred_display_adapter->body.hw_disp_mode_list; - if (settings->render_mode == RM_SOFTWARE) { - dm.bpp = 8; - disp_mode_list = - &settings->preferred_display_adapter->body.sw_disp_mode_list; - } - dm.vga = VGA_NO_VGA; - - const DISPLAY_MODE_NODE *head = disp_mode_list->head; - while (head != NULL) { - if (!CompareVideoModes(&head->body, &dm)) { - break; - } - head = head->next; - } - settings->video_mode = head; - - CloseGameRegistryKey(); - return IsNewRegistryKeyCreated() ? 2 : 1; -} diff --git a/src/tr2/decomp/fmv.c b/src/tr2/decomp/fmv.c index 3b67971e6..21928128e 100644 --- a/src/tr2/decomp/fmv.c +++ b/src/tr2/decomp/fmv.c @@ -1,14 +1,13 @@ #include "decomp/fmv.h" #include "config.h" -#include "decomp/decomp.h" #include "game/input.h" #include "game/music.h" +#include "game/render/common.h" #include "game/shell.h" #include "game/sound.h" #include "global/funcs.h" #include "global/vars.h" -#include "lib/ddraw.h" #include #include @@ -19,14 +18,8 @@ #include static bool m_Muted = false; -static LPDIRECTDRAWPALETTE m_DDrawPalette = NULL; -static LPDDS m_PrimaryBufferSurface = NULL; -static LPDDS m_BackBufferSurface = NULL; -static DDPIXELFORMAT m_PixelFormat; static void M_Play(const char *file_name); -static bool M_CreateScreenBuffers(void); -static void M_ReleaseScreenBuffers(void); static void *M_AllocateSurface(int32_t width, int32_t height, void *user_data); static void M_DeallocateSurface(void *surface, void *user_data); @@ -37,321 +30,105 @@ static void *M_LockSurface(void *surface, void *user_data); static void M_UnlockSurface(void *surface, void *user_data); static void M_UploadSurface(void *surface, void *user_data); -static bool M_CreateScreenBuffers(void) -{ - m_PrimaryBufferSurface = NULL; - m_BackBufferSurface = NULL; - m_DDrawPalette = NULL; - - if (g_SavedAppSettings.fullscreen) { - { - DDSDESC dsp = { - .dwSize = sizeof(DDSDESC), - .dwFlags = DDSD_BACKBUFFERCOUNT | DDSD_CAPS, - .dwBackBufferCount = 1, - .ddsCaps.dwCaps = - DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX, - }; - - HRESULT rc = DDrawSurfaceCreate(&dsp, &m_PrimaryBufferSurface); - if (FAILED(rc)) { - LOG_ERROR("Failed to create primary screen buffer: %x", rc); - return false; - } - } - - { - DDSCAPS caps = { - .dwCaps = DDSCAPS_BACKBUFFER, - }; - const HRESULT rc = - m_PrimaryBufferSurface->lpVtbl->GetAttachedSurface( - m_PrimaryBufferSurface, &caps, &m_BackBufferSurface); - if (FAILED(rc)) { - LOG_ERROR("Failed to create back screen buffer: %x", rc); - return false; - } - } - - if (g_GameVid_IsVga) { - PALETTEENTRY palette[256]; - - // Populate the palette with a palette corresponding to - // AV_PIX_FMT_RGB8 - for (int32_t i = 0; i < 256; i++) { - PALETTEENTRY *col = &palette[i]; - - col->peRed = (i >> 5) * 36; - col->peGreen = ((i >> 2) & 7) * 36; - col->peBlue = (i & 3) * 85; - } - - HRESULT rc = IDirectDraw_CreatePalette( - g_DDraw, DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE, - palette, &m_DDrawPalette, 0); - if (FAILED(rc)) { - LOG_ERROR( - "Failed to set primary screen buffer palette: %x", rc); - return false; - } - - rc = m_PrimaryBufferSurface->lpVtbl->SetPalette( - m_PrimaryBufferSurface, m_DDrawPalette); - if (FAILED(rc)) { - LOG_ERROR( - "Failed to attach palette to the primary screen buffer: %x", - rc); - return false; - } - } - - } else { - DDSDESC dsp = { - .dwSize = sizeof(DDSDESC), - .dwFlags = DDSD_CAPS, - .ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE, - }; - - const HRESULT rc = DDrawSurfaceCreate(&dsp, &m_PrimaryBufferSurface); - if (FAILED(rc)) { - LOG_ERROR("Failed to create primary screen buffer: %x", rc); - return false; - } - } - - memset(&m_PixelFormat, 0, sizeof(m_PixelFormat)); - m_PixelFormat.dwSize = sizeof(DDPIXELFORMAT); - const HRESULT rc = IDirectDrawSurface_GetPixelFormat( - m_PrimaryBufferSurface, &m_PixelFormat); - if (FAILED(rc)) { - LOG_ERROR( - "Failed to get pixel format of the primary screen buffer: %x", rc); - } - - return true; -} - -static void M_ReleaseScreenBuffers(void) -{ - if (m_PrimaryBufferSurface != NULL) { - m_PrimaryBufferSurface->lpVtbl->Release(m_PrimaryBufferSurface); - m_PrimaryBufferSurface = NULL; - } - - if (m_DDrawPalette != NULL) { - m_DDrawPalette->lpVtbl->Release(m_DDrawPalette); - } -} - static void *M_AllocateSurface( const int32_t width, const int32_t height, void *const user_data) { - VIDEO *const video = user_data; - - LPDDS surface; - DDSDESC dsp = { - .dwSize = sizeof(DDSDESC), - .dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS, - .dwWidth = width, - .dwHeight = height, - .ddsCaps = { - .dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, - }, + GFX_2D_SURFACE_DESC surface_desc = { + .width = width, + .height = height, + .tex_format = + g_Config.rendering.render_mode == RM_SOFTWARE ? GL_RED : GL_BGRA, + .tex_type = g_Config.rendering.render_mode == RM_SOFTWARE + ? GL_UNSIGNED_BYTE + : GL_UNSIGNED_INT_8_8_8_8_REV, }; - const HRESULT rc = DDrawSurfaceCreate(&dsp, &surface); - if (FAILED(rc)) { - LOG_ERROR("Failed to create render buffer: %x", rc); - } - - // Set pixel format - if (m_PixelFormat.dwFlags & DDPF_PALETTEINDEXED8) { - Video_SetSurfacePixelFormat(video, AV_PIX_FMT_RGB8); - } else if (m_PixelFormat.dwRGBBitCount == 16) { - if (m_PixelFormat.dwRBitMask == 0xF800) { - Video_SetSurfacePixelFormat(video, AV_PIX_FMT_RGB565); - } else { - Video_SetSurfacePixelFormat(video, AV_PIX_FMT_BGR565); - } - } else if (m_PixelFormat.dwRGBBitCount == 24) { - if (m_PixelFormat.dwRBitMask == 255) { - Video_SetSurfacePixelFormat(video, AV_PIX_FMT_RGB24); - } else { - Video_SetSurfacePixelFormat(video, AV_PIX_FMT_BGR24); - } - } else if (m_PixelFormat.dwRGBBitCount == 32) { - if (m_PixelFormat.dwRBitMask == 255) { - Video_SetSurfacePixelFormat(video, AV_PIX_FMT_RGB0); - } else { - Video_SetSurfacePixelFormat(video, AV_PIX_FMT_BGR0); - } - } - - // Set pitch - surface->lpVtbl->GetSurfaceDesc(surface, &dsp); - Video_SetSurfaceStride(video, dsp.lPitch); - - return surface; + return GFX_2D_Surface_Create(&surface_desc); } -static void M_DeallocateSurface(void *const surface_, void *const user_data) +static void M_DeallocateSurface(void *const surface, void *const user_data) { - LPDDS surface = surface_; - const HRESULT rc = surface->lpVtbl->Release(surface); - if (FAILED(rc)) { - LOG_ERROR("Failed to release render buffer: %x", rc); - } + GFX_2D_Surface_Free(surface); } -static void M_ClearSurface(void *const surface_, void *const user_data) +static void M_ClearSurface(void *const surface, void *const user_data) { - LPDDS surface = surface_; - WinVidClearBuffer(surface, NULL, 0); + ASSERT(surface != NULL); + GFX_2D_SURFACE *const surface_ = surface; + memset(surface_->buffer, 0, surface_->desc.pitch * surface_->desc.height); } static void M_RenderBegin(void *const surface, void *const user_data) { + GFX_Context_Clear(); } -static void M_RenderEnd(void *const surface_, void *const user_data) +static void M_RenderEnd(void *const surface, void *const user_data) { - LPDDS surface = surface_; - - if (g_SavedAppSettings.fullscreen) { - LPRECT rect = NULL; - HRESULT rc = m_BackBufferSurface->lpVtbl->Blt( - m_BackBufferSurface, rect, surface, rect, DDBLT_WAIT, NULL); - if (FAILED(rc)) { - LOG_ERROR( - "Failed to copy pixels to the primary screen buffer: %x", rc); - } - - rc = m_PrimaryBufferSurface->lpVtbl->Flip( - m_PrimaryBufferSurface, NULL, DDFLIP_WAIT); - if (FAILED(rc)) { - LOG_ERROR("Failed to flip the primary screen buffer: %x", rc); - } - } else { - LPRECT rect = &g_PhdWinRect; - RECT dst_rect = { - .left = g_GameWindowPositionX + rect->left, - .top = g_GameWindowPositionY + rect->top, - .bottom = g_GameWindowPositionY + rect->bottom, - .right = g_GameWindowPositionX + rect->right, - }; - const HRESULT rc = m_PrimaryBufferSurface->lpVtbl->Blt( - m_PrimaryBufferSurface, &dst_rect, surface, rect, DDBLT_WAIT, NULL); - if (FAILED(rc)) { - LOG_ERROR( - "Failed to copy pixels to the primary screen buffer: %x", rc); - } - } + GFX_Context_SwapBuffers(); } -static void *M_LockSurface(void *const surface_, void *const user_data) +static void *M_LockSurface(void *const surface, void *const user_data) { - LPDDS surface = surface_; - LPDDSURFACEDESC desc = user_data; - ASSERT(desc != NULL); - - HRESULT rc; - while (true) { - rc = surface->lpVtbl->Lock(surface, 0, desc, 0, 0); - if (rc != DDERR_WASSTILLDRAWING) { - break; - } - } - - if (rc == DDERR_SURFACELOST) { - surface->lpVtbl->Restore(surface); - } - - if (FAILED(rc)) { - return NULL; - } - - return desc->lpSurface; + ASSERT(surface != NULL); + GFX_2D_SURFACE *const surface_ = surface; + return surface_->buffer; } -static void M_UnlockSurface(void *const surface_, void *const user_data) +static void M_UnlockSurface(void *const surface, void *const user_data) { - LPDDS surface = surface_; - LPDDSURFACEDESC desc = user_data; - surface->lpVtbl->Unlock(surface, desc); } static void M_UploadSurface(void *const surface, void *const user_data) { + GFX_2D_RENDERER *renderer_2d = user_data; + GFX_2D_SURFACE *surface_ = surface; + GFX_2D_Renderer_Upload(renderer_2d, &surface_->desc, surface_->buffer); + GFX_2D_Renderer_Render(renderer_2d); } static bool M_EnterFMVMode(void) { - ShowCursor(false); Music_Stop(); - - RenderFinish(false); - if (!M_CreateScreenBuffers()) { - return false; - } - return true; } static void M_ExitFMVMode(void) { - M_ReleaseScreenBuffers(); - if (!g_IsGameToExit) { - RenderStart(true); + Render_Reset(RENDER_RESET_ALL); } - ShowCursor(true); } static void M_Play(const char *const file_name) { - g_IsFMVPlaying = true; const char *full_path = File_GetFullPath(file_name); - WinPlayFMV(full_path, true); - Memory_FreePointer(&full_path); - g_IsFMVPlaying = false; -} - -bool __cdecl PlayFMV(const char *const file_name) -{ - if (M_EnterFMVMode()) { - M_Play(file_name); - } - M_ExitFMVMode(); - return g_IsGameToExit; -} - -bool __cdecl IntroFMV( - const char *const file_name_1, const char *const file_name_2) -{ - if (M_EnterFMVMode()) { - M_Play(file_name_1); - M_Play(file_name_2); - } - M_ExitFMVMode(); - return g_IsGameToExit; -} - -void __cdecl WinPlayFMV(const char *const file_name, const bool is_playback) -{ - DDSURFACEDESC surface_desc = { .dwSize = sizeof(DDSURFACEDESC), 0 }; VIDEO *video = Video_Open(file_name); if (video == NULL) { return; } - Video_SetSurfaceAllocatorFunc(video, M_AllocateSurface, video); + g_IsFMVPlaying = true; + GFX_2D_RENDERER *const renderer_2d = GFX_2D_Renderer_Create(); + + // Populate the palette with a palette corresponding to + // AV_PIX_FMT_RGB8 + GFX_PALETTE_ENTRY palette[256]; + for (int32_t i = 0; i < 256; i++) { + GFX_PALETTE_ENTRY *const col = &palette[i]; + col->r = 0x24 * (i >> 5); + col->g = 0x24 * ((i >> 2) & 7); + col->b = 0x55 * (i & 3); + } + + Video_SetSurfaceAllocatorFunc(video, M_AllocateSurface, NULL); Video_SetSurfaceDeallocatorFunc(video, M_DeallocateSurface, NULL); Video_SetSurfaceClearFunc(video, M_ClearSurface, NULL); Video_SetRenderBeginFunc(video, M_RenderBegin, NULL); Video_SetRenderEndFunc(video, M_RenderEnd, NULL); - Video_SetSurfaceLockFunc(video, M_LockSurface, &surface_desc); - Video_SetSurfaceUnlockFunc(video, M_UnlockSurface, &surface_desc); - Video_SetSurfaceUploadFunc(video, M_UploadSurface, NULL); + Video_SetSurfaceLockFunc(video, M_LockSurface, NULL); + Video_SetSurfaceUnlockFunc(video, M_UnlockSurface, NULL); + Video_SetSurfaceUploadFunc(video, M_UploadSurface, renderer_2d); Video_Start(video); while (video->is_playing) { @@ -361,11 +138,19 @@ void __cdecl WinPlayFMV(const char *const file_name, const bool is_playback) ? 0 : g_Config.audio.sound_volume / (float)Sound_GetMaxVolume()); - Video_SetSurfaceSize(video, g_PhdWinWidth, g_PhdWinHeight); + Video_SetSurfaceSize( + video, Shell_GetCurrentDisplayWidth(), + Shell_GetCurrentDisplayHeight()); + if (g_Config.rendering.render_mode == RM_SOFTWARE) { + Video_SetSurfacePixelFormat(video, AV_PIX_FMT_RGB8); + GFX_2D_Renderer_SetPalette(renderer_2d, palette); + } else { + Video_SetSurfacePixelFormat(video, AV_PIX_FMT_BGRA); + GFX_2D_Renderer_SetPalette(renderer_2d, NULL); + } Video_PumpEvents(video); Shell_ProcessEvents(); - WinVidSpinMessageLoop(false); Input_Update(); Shell_ProcessInput(); @@ -375,21 +160,29 @@ void __cdecl WinPlayFMV(const char *const file_name, const bool is_playback) } } Video_Close(video); + + GFX_2D_Renderer_Destroy(renderer_2d); + Memory_FreePointer(&full_path); + g_IsFMVPlaying = false; } -void __cdecl WinStopFMV(bool is_playback) +bool FMV_Play(const char *const file_name) { + if (M_EnterFMVMode()) { + M_Play(file_name); + } + M_ExitFMVMode(); + return g_IsGameToExit; } -bool __cdecl S_PlayFMV(const char *const file_name) +bool FMV_PlayIntro(const char *const file_name_1, const char *const file_name_2) { - return PlayFMV(file_name); -} - -bool __cdecl S_IntroFMV( - const char *const file_name_1, const char *const file_name_2) -{ - return IntroFMV(file_name_1, file_name_2); + if (M_EnterFMVMode()) { + M_Play(file_name_1); + M_Play(file_name_2); + } + M_ExitFMVMode(); + return g_IsGameToExit; } bool FMV_IsPlaying(void) diff --git a/src/tr2/decomp/fmv.h b/src/tr2/decomp/fmv.h index a74c30015..a5b8f322b 100644 --- a/src/tr2/decomp/fmv.h +++ b/src/tr2/decomp/fmv.h @@ -2,10 +2,6 @@ #include -bool __cdecl PlayFMV(const char *file_name); -bool __cdecl IntroFMV(const char *file_name_1, const char *file_name_2); -void __cdecl WinPlayFMV(const char *file_name, bool is_playback); -void __cdecl WinStopFMV(bool is_playback); -bool __cdecl S_PlayFMV(const char *file_name); -bool __cdecl S_IntroFMV(const char *file_name_1, const char *file_name_2); +bool FMV_Play(const char *file_name); +bool FMV_PlayIntro(const char *file_name_1, const char *file_name_2); bool FMV_IsPlaying(void); diff --git a/src/tr2/decomp/stats.c b/src/tr2/decomp/stats.c index a8c2d9a2d..9ecd97c29 100644 --- a/src/tr2/decomp/stats.c +++ b/src/tr2/decomp/stats.c @@ -5,6 +5,7 @@ #include "game/console/common.h" #include "game/input.h" #include "game/music.h" +#include "game/output.h" #include "game/overlay.h" #include "game/requester.h" #include "game/shell.h" @@ -315,24 +316,16 @@ int32_t __cdecl LevelStats(const int32_t level_num) sprintf(buffer, "%02d:%02d:%02d", sec / 3600, (sec / 60) % 60, sec % 60); Music_Play(g_GameFlow.level_complete_track, MPM_ALWAYS); - - FadeToPal(30, g_GamePalette8); + Output_LoadBackgroundFromObject(); Overlay_HideGameInfo(); - S_CopyScreenToBuffer(); + // TODO: potential fade effects while (true) { Shell_ProcessEvents(); Input_Update(); Shell_ProcessInput(); - S_InitialisePolyList(0); - S_CopyBufferToScreen(); - - if (g_IsGameToExit) { - break; - } - - if (g_InputDB.menu_back || g_InputDB.menu_confirm) { + if (g_IsGameToExit || g_InputDB.menu_back || g_InputDB.menu_confirm) { break; } @@ -340,19 +333,21 @@ int32_t __cdecl LevelStats(const int32_t level_num) break; } + Output_BeginScene(); + Output_DrawBackground(); ShowStatsText(buffer, 0); Console_Draw(); Text_Draw(); - S_OutputPolyList(); - S_DumpScreen(); + Output_DrawPolyList(); + Output_EndScene(); } Requester_Shutdown(&g_StatsRequester); + Output_UnloadBackground(); CreateStartInfo(level_num + 1); g_SaveGame.current_level = level_num + 1; start->available = 0; - S_FadeToBlack(); return 0; } @@ -380,26 +375,20 @@ int32_t __cdecl GameStats(const int32_t level_num) Input_Update(); Shell_ProcessInput(); - S_InitialisePolyList(0); - S_CopyBufferToScreen(); - - if (g_IsGameToExit) { + if (g_IsGameToExit || g_InputDB.menu_back || g_InputDB.menu_confirm) { break; } - - if (g_InputDB.menu_back || g_InputDB.menu_confirm) { - break; - } - if (g_GF_OverrideDir != (GAME_FLOW_DIR)-1) { break; } + Output_BeginScene(); + Output_DrawBackground(); ShowEndStatsText(); Console_Draw(); Text_Draw(); - S_OutputPolyList(); - S_DumpScreen(); + Output_DrawPolyList(); + Output_EndScene(); } Requester_Shutdown(&g_StatsRequester); @@ -410,7 +399,7 @@ int32_t __cdecl GameStats(const int32_t level_num) } g_SaveGame.current_level = LV_FIRST; - S_DontDisplayPicture(); + Output_UnloadBackground(); return 0; } diff --git a/src/tr2/game/background.c b/src/tr2/game/background.c deleted file mode 100644 index e617ae67f..000000000 --- a/src/tr2/game/background.c +++ /dev/null @@ -1,295 +0,0 @@ -#include "game/background.h" - -#include "decomp/decomp.h" -#include "game/gamebuf.h" -#include "game/hwr.h" -#include "global/const.h" -#include "global/funcs.h" -#include "global/vars.h" - -#include - -#include - -#define TEXTURE_WIDTH 256 -#define TEXTURE_HEIGHT 256 - -void __cdecl BGND_Make640x480(uint8_t *bitmap, RGB_888 *palette) -{ - if (g_TextureFormat.bpp >= 16) { - g_BGND_PaletteIndex = -1; - } else { - g_BGND_PaletteIndex = CreateTexturePalette(palette); - } - - const int32_t buf_size = 640 * 480 * 2; - uint8_t *buf = GameBuf_Alloc(buf_size, GBUF_TEMP_ALLOC); - UT_MemBlt(buf, 0, 0, 256, 256, 256, bitmap, 0, 0, 640); - BGND_AddTexture(0, buf, g_BGND_PaletteIndex, palette); - - UT_MemBlt(buf, 0, 0, 256, 256, 256, bitmap, 256, 0, 640); - BGND_AddTexture(1, buf, g_BGND_PaletteIndex, palette); - - UT_MemBlt(buf, 0, 0, 128, 256, 256, bitmap, 512, 0, 640); - UT_MemBlt(buf, 128, 0, 128, 224, 256, bitmap, 512, 256, 640); - BGND_AddTexture(2, buf, g_BGND_PaletteIndex, palette); - - UT_MemBlt(buf, 0, 0, 256, 224, 256, bitmap, 0, 256, 640); - BGND_AddTexture(3, buf, g_BGND_PaletteIndex, palette); - - UT_MemBlt(buf, 0, 0, 256, 224, 256, bitmap, 256, 256, 640); - BGND_AddTexture(4, buf, g_BGND_PaletteIndex, palette); - - GameBuf_Free(buf_size); - - BGND_GetPageHandles(); - - g_BGND_PictureIsReady = true; -} - -int32_t __cdecl BGND_AddTexture( - const int32_t tile_idx, uint8_t *const bitmap, const int32_t pal_index, - const RGB_888 *const bmp_pal) -{ - int32_t page_index; - if (pal_index < 0) { - uint8_t *bmp_src = &bitmap[TEXTURE_WIDTH * TEXTURE_HEIGHT]; - uint16_t *bmp_dst = - &((uint16_t *)bitmap)[TEXTURE_WIDTH * TEXTURE_HEIGHT]; - for (int32_t i = 0; i < TEXTURE_WIDTH * TEXTURE_HEIGHT; i++) { - bmp_src--; - bmp_dst--; - - const RGB_888 *const color = &bmp_pal[*bmp_src]; - - *bmp_dst = (1 << 15) | (((uint16_t)color->red >> 3) << 10) - | (((uint16_t)color->green >> 3) << 5) - | (((uint16_t)color->blue >> 3)); - } - - page_index = AddTexturePage16(256, 256, bmp_src); - } else { - page_index = AddTexturePage8(256, 256, bitmap, pal_index); - } - - g_BGND_TexturePageIndexes[tile_idx] = page_index >= 0 ? page_index : -1; - return page_index; -} - -void __cdecl BGND_GetPageHandles(void) -{ - for (int32_t i = 0; i < BGND_MAX_TEXTURE_PAGES; i++) { - g_BGND_PageHandles[i] = g_BGND_TexturePageIndexes[i] >= 0 - ? GetTexturePageHandle(g_BGND_TexturePageIndexes[i]) - : 0; - } -} - -void __cdecl BGND_DrawInGameBlack(void) -{ - HWR_EnableZBuffer(false, false); - DrawQuad( - (float)g_PhdWinMinX, (float)g_PhdWinMinY, (float)g_PhdWinWidth, - (float)g_PhdWinHeight, 0); - HWR_EnableZBuffer(true, true); -} - -void __cdecl DrawQuad( - const float sx, const float sy, const float width, const float height, - const D3DCOLOR color) -{ - D3DTLVERTEX vertex[4]; - - vertex[0].sx = sx; - vertex[0].sy = sy; - - vertex[1].sx = sx + width; - vertex[1].sy = sy; - - vertex[2].sx = sx; - vertex[2].sy = sy + height; - - vertex[3].sx = sx + width; - vertex[3].sy = sy + height; - - for (int32_t i = 0; i < 4; i++) { - vertex[i].sz = 0; - vertex[i].rhw = g_FltRhwONearZ; - vertex[i].color = RGBA_SETALPHA(color, 0xFF); - vertex[i].specular = 0; - } - - HWR_TexSource(0); - HWR_EnableColorKey(false); - HWR_DrawPrimitive(D3DPT_TRIANGLESTRIP, &vertex, 4, true); -} - -void __cdecl BGND_DrawInGameBackground(void) -{ - const OBJECT *const obj = &g_Objects[O_INV_BACKGROUND]; - if (!obj->loaded) { - BGND_DrawInGameBlack(); - return; - } - - const int16_t *mesh_ptr = g_Meshes[obj->mesh_idx]; - mesh_ptr += 5; - const int32_t num_vertices = *mesh_ptr++; - mesh_ptr += num_vertices * 3; - - const int32_t num_normals = *mesh_ptr++; - if (num_normals >= 0) { - mesh_ptr += num_normals * 3; - } else { - mesh_ptr -= num_normals; - } - const int32_t num_quads = *mesh_ptr++; - if (num_quads < 1) { - BGND_DrawInGameBlack(); - return; - } - - mesh_ptr += 4; - const int32_t texture_idx = *mesh_ptr++; - - const PHD_TEXTURE *texture = &g_PhdTextureInfo[texture_idx]; - const HWR_TEXTURE_HANDLE tex_source = g_HWR_PageHandles[texture->tex_page]; - const int32_t tu = texture->uv[0].u / PHD_HALF; - const int32_t tv = texture->uv[0].v / PHD_HALF; - const int32_t t_width = texture->uv[2].u / PHD_HALF - tu + 1; - const int32_t t_height = texture->uv[2].v / PHD_HALF - tv + 1; - - HWR_EnableZBuffer(false, false); - - const int32_t y_count = 6; - const int32_t x_count = 8; - - int32_t y_current = 0; - for (int32_t y = 0; y < y_count; y++) { - const int32_t y_next = g_PhdWinHeight + y_current; - - int32_t x_current = 0; - for (int32_t x = 0; x < x_count; x++) { - const int32_t x_next = x_current + g_PhdWinWidth; - - const int32_t y0 = g_PhdWinMinY + y_current / y_count; - const int32_t x0 = g_PhdWinMinX + x_current / x_count; - const int32_t x1 = g_PhdWinMinX + x_next / x_count; - const int32_t y1 = g_PhdWinMinY + y_next / y_count; - - const D3DCOLOR color[4] = { - BGND_CenterLighting(x0, y0, g_PhdWinWidth, g_PhdWinHeight), - BGND_CenterLighting(x1, y0, g_PhdWinWidth, g_PhdWinHeight), - BGND_CenterLighting(x0, y1, g_PhdWinWidth, g_PhdWinHeight), - BGND_CenterLighting(x1, y1, g_PhdWinWidth, g_PhdWinHeight), - }; - - DrawTextureTile( - x0, y0, x1 - x0, y1 - y0, tex_source, tu, tv, t_width, t_height, - color[0], color[1], color[2], color[3]); - - x_current = x_next; - } - y_current = y_next; - } - - HWR_EnableZBuffer(true, true); -} - -void __cdecl 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, - const D3DCOLOR color0, const D3DCOLOR color1, const D3DCOLOR color2, - const D3DCOLOR color3) -{ - const D3DVALUE sx0 = sx; - const D3DVALUE sy0 = sy; - const D3DVALUE sx1 = sx + width; - const D3DVALUE sy1 = sy + height; - - const double uv_adjust = g_UVAdd / (double)PHD_ONE; - const D3DVALUE tu0 = tu / 256.0 + uv_adjust; - const D3DVALUE tv0 = tv / 256.0 + uv_adjust; - const D3DVALUE tu1 = (tu + t_width) / 256.0 - uv_adjust; - const D3DVALUE tv1 = (tv + t_height) / 256.0 - uv_adjust; - - D3DTLVERTEX vertex[4] = { - { - .sx = sx0, - .sy = sy0, - .tu = tu0, - .tv = tv0, - .color = color0, - }, - { - .sx = sx1, - .sy = sy0, - .tu = tu1, - .tv = tv0, - .color = color1, - }, - { - .sx = sx0, - .sy = sy1, - .tu = tu0, - .tv = tv1, - .color = color2, - }, - { - .sx = sx1, - .sy = sy1, - .tu = tu1, - .tv = tv1, - .color = color3, - }, - }; - - for (int32_t i = 0; i < 4; i++) { - vertex[i].sz = 0.995; - vertex[i].rhw = g_RhwFactor / g_FltFarZ; - vertex[i].specular = 0; - } - - HWR_TexSource(tex_source); - HWR_EnableColorKey(0); - HWR_DrawPrimitive(D3DPT_TRIANGLESTRIP, &vertex, 4, true); -} - -D3DCOLOR __cdecl BGND_CenterLighting( - const int32_t x, const int32_t y, const int32_t width, const int32_t height) -{ - const double x_dist = (double)(x - (width / 2)) / (double)width; - const double y_dist = (double)(y - (height / 2)) / (double)height; - - int32_t light = 256 - (sqrt(x_dist * x_dist + y_dist * y_dist) * 300.0); - CLAMP(light, 0, 255); - - return RGBA_MAKE(light, light, light, 0xFF); -} - -void __cdecl BGND_Free(void) -{ - for (int32_t i = 0; i < BGND_MAX_TEXTURE_PAGES; i++) { - if (g_BGND_TexturePageIndexes[i] >= 0) { - SafeFreeTexturePage(g_BGND_TexturePageIndexes[i]); - g_BGND_TexturePageIndexes[i] = -1; - } - g_BGND_PageHandles[i] = 0; - } - - if (g_BGND_PaletteIndex >= 0) { - SafeFreePalette(g_BGND_PaletteIndex); - g_BGND_PaletteIndex = -1; - } -} - -bool __cdecl BGND_Init(void) -{ - g_BGND_PictureIsReady = false; - g_BGND_PaletteIndex = -1; - for (int32_t i = 0; i < BGND_MAX_TEXTURE_PAGES; i++) { - g_BGND_TexturePageIndexes[i] = -1; - } - return true; -} diff --git a/src/tr2/game/background.h b/src/tr2/game/background.h deleted file mode 100644 index 9699f8c01..000000000 --- a/src/tr2/game/background.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "global/types.h" - -#define BGND_MAX_TEXTURE_PAGES 5 - -bool __cdecl BGND_Init(void); -void __cdecl BGND_Free(void); - -void __cdecl BGND_Make640x480(uint8_t *bitmap, RGB_888 *palette); -int32_t __cdecl BGND_AddTexture( - int32_t tile_idx, uint8_t *bitmap, int32_t pal_index, - const 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_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); -D3DCOLOR __cdecl BGND_CenterLighting( - int32_t x, int32_t y, int32_t width, int32_t height); diff --git a/src/tr2/game/camera.c b/src/tr2/game/camera.c index c5b40c237..4da1e9e37 100644 --- a/src/tr2/game/camera.c +++ b/src/tr2/game/camera.c @@ -1,7 +1,6 @@ #include "game/camera.h" #include "config.h" -#include "decomp/decomp.h" #include "game/items.h" #include "game/los.h" #include "game/math.h" diff --git a/src/tr2/game/demo.c b/src/tr2/game/demo.c index 5a4554f68..6baaca308 100644 --- a/src/tr2/game/demo.c +++ b/src/tr2/game/demo.c @@ -6,6 +6,7 @@ #include "game/input.h" #include "game/items.h" #include "game/lara/cheat.h" +#include "game/output.h" #include "game/random.h" #include "game/room.h" #include "game/shell.h" @@ -99,7 +100,7 @@ int32_t __cdecl Demo_Start(int32_t level_num) Random_SeedControl(0xD371F947); TEXTSTRING *const text = Text_Create( - 0, g_DumpHeight / 2 - 16, g_GF_PCStrings[GF_S_PC_DEMO_MODE]); + 0, g_PhdWinHeight / 2 - 16, g_GF_PCStrings[GF_S_PC_DEMO_MODE]); Text_Flash(text, true, 20); Text_CentreV(text, true); @@ -115,7 +116,6 @@ int32_t __cdecl Demo_Start(int32_t level_num) M_RestoreConfig(); *s = start; - S_FadeToBlack(); if (dir == GFD_OVERRIDE) { dir = g_GF_OverrideDir; g_GF_OverrideDir = (GAME_FLOW_DIR)-1; diff --git a/src/tr2/game/fader.c b/src/tr2/game/fader.c new file mode 100644 index 000000000..f1b7f2959 --- /dev/null +++ b/src/tr2/game/fader.c @@ -0,0 +1,77 @@ +#include "game/fader.h" + +#include "config.h" +#include "game/input.h" +#include "game/shell.h" +#include "global/const.h" + +#include + +void Fader_Init( + FADER *const fader, const int32_t initial, const int32_t target, + const int32_t duration, const int32_t debuff) +{ + fader->initial = initial; + fader->target = target; + fader->duration = duration; + // This value controls how much to keep the last frame after the animation + // is done. + fader->debuff = debuff; + fader->current.value = initial; + fader->current.frame = 0; + + if (!g_Config.visuals.enable_fade_effects) { + fader->current.frame = fader->duration + fader->debuff; + fader->current.value = target; + } +} + +void Fader_InitBlackToTransparent(FADER *const fader, const int32_t duration) +{ + Fader_Init(fader, 255, 0, duration, 0); +} + +void Fader_InitTransparentToBlack(FADER *const fader, const int32_t duration) +{ + Fader_Init(fader, 0, 255, duration, FRAMES_PER_SECOND / 6); +} + +void Fader_InitAnyToBlack(FADER *const fader, const int32_t duration) +{ + Fader_Init( + fader, fader->current.value, 255, duration, FRAMES_PER_SECOND / 6); +} + +bool Fader_IsActive(const FADER *const fader) +{ + if (!g_Config.visuals.enable_fade_effects) { + return false; + } + return fader->current.frame <= fader->duration + fader->debuff; +} + +bool Fader_Control(FADER *const fader) +{ + if (!Fader_IsActive(fader)) { + return false; + } + + fader->current.value = fader->initial + + (fader->target - fader->initial) + * (fader->current.frame / (float)MAX(1.0, fader->duration)); + CLAMP( + fader->current.value, MIN(fader->initial, fader->target), + MAX(fader->initial, fader->target)); + fader->current.frame++; + + Input_Update(); + Shell_ProcessInput(); + Shell_ProcessEvents(); + if (g_InputDB.any) { + // cancel the fade immediately + fader->current.frame = fader->duration + fader->debuff; + return false; + } + + return Fader_IsActive(fader); +} diff --git a/src/tr2/game/fader.h b/src/tr2/game/fader.h new file mode 100644 index 000000000..df11dc542 --- /dev/null +++ b/src/tr2/game/fader.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +typedef struct { + int32_t initial; + int32_t target; + int32_t debuff; + int32_t duration; + struct { + int32_t frame; + int32_t value; + } current; +} FADER; + +void Fader_Init( + FADER *fader, int32_t initial, int32_t target, int32_t frames, + int32_t debuff); +void Fader_InitBlackToTransparent(FADER *fader, int32_t frames); +void Fader_InitTransparentToBlack(FADER *fader, int32_t frames); +void Fader_InitAnyToBlack(FADER *fader, int32_t frames); +bool Fader_IsActive(const FADER *fader); +bool Fader_Control(FADER *fader); diff --git a/src/tr2/game/game.c b/src/tr2/game/game.c index 2798eecf1..a45c1473f 100644 --- a/src/tr2/game/game.c +++ b/src/tr2/game/game.c @@ -6,12 +6,14 @@ #include "game/camera.h" #include "game/console/common.h" #include "game/demo.h" +#include "game/fader.h" #include "game/gameflow/gameflow_new.h" #include "game/input.h" #include "game/inventory/backpack.h" #include "game/inventory/common.h" #include "game/lara/control.h" #include "game/music.h" +#include "game/output.h" #include "game/overlay.h" #include "game/room.h" #include "game/room_draw.h" @@ -25,9 +27,13 @@ #include static int32_t m_FrameCount = 0; +static bool m_Exiting = false; +static FADER m_ExitFader = { 0 }; int32_t __cdecl Game_Control(int32_t nframes, const bool demo_mode) { + Fader_Control(&m_ExitFader); + if (g_GF_OverrideDir != (GAME_FLOW_DIR)-1) { return GFD_OVERRIDE; } @@ -180,12 +186,84 @@ int32_t __cdecl Game_Control(int32_t nframes, const bool demo_mode) return 0; } +int32_t __cdecl Game_ControlCinematic(const int32_t nframes) +{ + Fader_Control(&m_ExitFader); + g_CineTickCount += g_CineTickRate * nframes; + + if (g_CineTickCount >= 0) { + while (1) { + if (g_GF_OverrideDir != (GAME_FLOW_DIR)-1) { + return 4; + } + + Shell_ProcessEvents(); + Input_Update(); + if (g_InputDB.action) { + return 1; + } + if (g_InputDB.option) { + return 2; + } + Shell_ProcessInput(); + + g_DynamicLightCount = 0; + + for (int32_t id = g_NextItemActive; id != NO_ITEM;) { + const ITEM *const item = &g_Items[id]; + const OBJECT *obj = &g_Objects[item->object_id]; + if (obj->control != NULL) { + obj->control(id); + } + id = item->next_active; + } + + for (int32_t id = g_NextEffectActive; id != NO_ITEM;) { + const FX *const fx = &g_Effects[id]; + const OBJECT *const obj = &g_Objects[fx->object_id]; + if (obj->control != NULL) { + obj->control(id); + } + id = fx->next_active; + } + + HairControl(1); + Camera_UpdateCutscene(); + + g_CineFrameIdx++; + if (g_CineFrameIdx >= g_NumCineFrames) { + return 1; + } + + g_CineTickCount -= 0x10000; + if (g_CineTickCount < 0) { + break; + } + } + } + + if (Music_GetTimestamp() < 0.0) { + g_CineFrameCurrent++; + } else { + // sync with music + g_CineFrameCurrent = + Music_GetTimestamp() * FRAMES_PER_SECOND * TICKS_PER_FRAME / 1000.0; + } + + return 0; +} + int32_t __cdecl Game_Draw(void) { + Output_BeginScene(); Room_DrawAllRooms(g_Camera.pos.room_num); + Output_DrawPolyList(); + Overlay_DrawGameInfo(true); - S_OutputPolyList(); - const int32_t frames = S_DumpScreen(); + Output_DrawPolyList(); + + Output_DrawBlackRectangle(m_ExitFader.current.value); + const int32_t frames = Output_EndScene(); g_Camera.num_frames = frames * TICKS_PER_FRAME; Shell_ProcessEvents(); Overlay_Animate(frames); @@ -196,11 +274,14 @@ int32_t __cdecl Game_Draw(void) int32_t __cdecl Game_DrawCinematic(void) { g_CameraUnderwater = false; + Output_BeginScene(); Room_DrawAllRooms(g_Camera.pos.room_num); + Output_DrawPolyList(); Console_Draw(); Text_Draw(); - S_OutputPolyList(); - g_Camera.num_frames = S_DumpScreen(); + Output_DrawPolyList(); + Output_DrawBlackRectangle(m_ExitFader.current.value); + g_Camera.num_frames = Output_EndScene(); Shell_ProcessEvents(); S_AnimateTextures(g_Camera.num_frames); return g_Camera.num_frames; @@ -246,15 +327,14 @@ int16_t __cdecl Game_Start( } if (g_CurrentLevel == LV_GYM) { - S_FadeToBlack(); + // TODO: fade to black return GFD_EXIT_TO_TITLE; } - S_FadeInInventory(1); return GFD_LEVEL_COMPLETE | g_CurrentLevel; } - S_FadeToBlack(); + // TODO: fade to black if (!g_Inv_Chosen) { return GFD_EXIT_TO_TITLE; } @@ -286,7 +366,10 @@ int32_t __cdecl Game_Loop(const bool demo_mode) GAME_FLOW_DIR dir = Game_Control(1, demo_mode); while (dir == 0) { const int32_t nframes = Game_Draw(); - if (g_IsGameToExit) { + if (g_IsGameToExit && !m_Exiting) { + m_Exiting = true; + Fader_InitAnyToBlack(&m_ExitFader, FRAMES_PER_SECOND / 3); + } else if (m_Exiting && !Fader_IsActive(&m_ExitFader)) { dir = GFD_EXIT_GAME; } else { dir = Game_Control(nframes, demo_mode); @@ -304,6 +387,53 @@ int32_t __cdecl Game_Loop(const bool demo_mode) return dir; } +int32_t __cdecl Game_LoopCinematic(const int32_t level_num) +{ + if (!Level_Initialise(level_num, GFL_CUTSCENE)) { + return 2; + } + + Room_InitCinematic(); + CutscenePlayer1_Initialise(g_Lara.item_num); + g_Camera.target_angle = g_CineTargetAngle; + + const bool old_sound_active = g_SoundIsActive; + g_SoundIsActive = false; + + g_CineFrameIdx = 0; + + if (!Music_PlaySynced(g_CineTrackID)) { + return 1; + } + + Music_SetVolume(10); + g_CineFrameCurrent = 0; + + int32_t result; + do { + Game_DrawCinematic(); + int32_t nticks = + g_CineFrameCurrent - TICKS_PER_FRAME * (g_CineFrameIdx - 4); + CLAMPL(nticks, TICKS_PER_FRAME); + if (g_IsGameToExit && !m_Exiting) { + m_Exiting = true; + Fader_InitAnyToBlack(&m_ExitFader, FRAMES_PER_SECOND / 3); + } else if (m_Exiting && !Fader_IsActive(&m_ExitFader)) { + result = 5; + } else { + result = Game_ControlCinematic(nticks); + } + } while (!result); + + Music_SetVolume(g_Config.audio.music_volume); + Music_Stop(); + g_SoundIsActive = old_sound_active; + Sound_StopAllSamples(); + + g_LevelComplete = true; + return result; +} + GAMEFLOW_LEVEL_TYPE Game_GetCurrentLevelType(void) { return g_GameInfo.current_level.type; diff --git a/src/tr2/game/game.h b/src/tr2/game/game.h index 4a7ff9a74..3aafed623 100644 --- a/src/tr2/game/game.h +++ b/src/tr2/game/game.h @@ -3,9 +3,11 @@ #include "global/types.h" int32_t __cdecl Game_Control(int32_t nframes, bool demo_mode); +int32_t __cdecl Game_ControlCinematic(int32_t nframes); int32_t __cdecl Game_Draw(void); int32_t __cdecl Game_DrawCinematic(void); int16_t __cdecl Game_Start(int32_t level_num, GAMEFLOW_LEVEL_TYPE level_type); int32_t __cdecl Game_Loop(bool demo_mode); +int32_t __cdecl Game_LoopCinematic(int32_t level_num); bool Game_IsPlayable(void); void Game_ProcessInput(void); diff --git a/src/tr2/game/gameflow.c b/src/tr2/game/gameflow.c index 6d7058276..20a81fe00 100644 --- a/src/tr2/game/gameflow.c +++ b/src/tr2/game/gameflow.c @@ -417,13 +417,13 @@ int32_t __cdecl GF_InterpretSequence( case GFE_PLAY_FMV: if (type != GFL_SAVED) { if (ptr[2] == GFE_PLAY_FMV) { - if (S_IntroFMV( + if (FMV_PlayIntro( g_GF_FMVFilenames[ptr[1]], g_GF_FMVFilenames[ptr[3]])) { return GFD_EXIT_GAME; } ptr += 2; - } else if (S_PlayFMV(g_GF_FMVFilenames[ptr[1]])) { + } else if (FMV_Play(g_GF_FMVFilenames[ptr[1]])) { return GFD_EXIT_GAME; } } @@ -452,9 +452,9 @@ int32_t __cdecl GF_InterpretSequence( case GFE_CUTSCENE: if (type != GFL_SAVED) { const int16_t level = g_CurrentLevel; - const int32_t result = Game_Cutscene_Start(ptr[1]); + const int32_t result = Game_LoopCinematic(ptr[1]); g_CurrentLevel = level; - // TODO: make Game_Cutscene_Start return GAME_FLOW_DIR + // TODO: make Game_LoopCinematic return GAME_FLOW_DIR if (result == 2 && (type == GFL_STORY || type == GFL_MID_STORY)) { return GFD_EXIT_TO_TITLE; diff --git a/src/tr2/game/hwr.c b/src/tr2/game/hwr.c deleted file mode 100644 index b09c6d2e3..000000000 --- a/src/tr2/game/hwr.c +++ /dev/null @@ -1,283 +0,0 @@ -#include "game/hwr.h" - -#include "decomp/decomp.h" -#include "global/funcs.h" -#include "global/vars.h" - -#include - -HRESULT HWR_DrawPrimitive( - D3DPRIMITIVETYPE primitive_type, LPVOID vertices, DWORD vtx_count, - bool is_no_clip) -{ - return g_D3DDev->lpVtbl->DrawPrimitive( - g_D3DDev, primitive_type, D3DVT_TLVERTEX, vertices, vtx_count, - is_no_clip ? D3DDP_DONOTUPDATEEXTENTS | D3DDP_DONOTCLIP : 0); -} - -void __cdecl HWR_InitState(void) -{ - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, D3DRENDERSTATE_FILLMODE, D3DFILL_SOLID); - - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, D3DRENDERSTATE_SHADEMODE, D3DSHADE_GOURAUD); - - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); - - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); - - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA); - - g_D3DDev->lpVtbl->SetRenderState( - 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; - - const DWORD texture_filter = g_SavedAppSettings.bilinear_filtering - ? D3DFILTER_LINEAR - : D3DFILTER_NEAREST; - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, D3DRENDERSTATE_TEXTUREMAG, texture_filter); - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, D3DRENDERSTATE_TEXTUREMIN, texture_filter); - - const DWORD blend_mode = - (g_CurrentDisplayAdapter.hw_device_desc.dpcTriCaps.dwTextureBlendCaps - & D3DPTBLENDCAPS_MODULATEALPHA) - ? D3DTBLEND_MODULATEALPHA - : D3DTBLEND_MODULATE; - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, D3DRENDERSTATE_TEXTUREMAPBLEND, blend_mode); - - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, D3DRENDERSTATE_TEXTUREADDRESS, D3DTADDRESS_CLAMP); - - HWR_ResetTexSource(); - HWR_ResetColorKey(); - HWR_ResetZBuffer(); -} - -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); -} - -void __cdecl HWR_ResetColorKey(void) -{ - g_ColorKeyState = FALSE; - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, - g_TexturesAlphaChannel ? D3DRENDERSTATE_ALPHABLENDENABLE - : D3DRENDERSTATE_COLORKEYENABLE, - FALSE); -} - -void __cdecl HWR_ResetZBuffer(void) -{ - g_ZEnableState = FALSE; - g_ZWriteEnableState = FALSE; - if (g_ZBufferSurface != NULL) { - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, D3DRENDERSTATE_ZFUNC, D3DCMP_ALWAYS); - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, D3DRENDERSTATE_ZENABLE, - g_SavedAppSettings.zbuffer ? TRUE : FALSE); - } else { - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL); - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, D3DRENDERSTATE_ZENABLE, FALSE); - } - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, D3DRENDERSTATE_ZWRITEENABLE, FALSE); -} - -void __cdecl HWR_TexSource(const HWR_TEXTURE_HANDLE tex_source) -{ - if (g_CurrentTexSource != tex_source) { - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, D3DRENDERSTATE_TEXTUREHANDLE, tex_source); - g_CurrentTexSource = tex_source; - } -} - -void __cdecl HWR_EnableColorKey(const bool state) -{ - if (g_ColorKeyState != state) { - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, - g_TexturesAlphaChannel ? D3DRENDERSTATE_ALPHABLENDENABLE - : D3DRENDERSTATE_COLORKEYENABLE, - state ? TRUE : FALSE); - g_ColorKeyState = state; - } -} - -void __cdecl HWR_EnableZBuffer(const bool z_write_enable, const bool z_enable) -{ - if (!g_SavedAppSettings.zbuffer) { - return; - } - - if (g_ZWriteEnableState != z_write_enable) { - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, D3DRENDERSTATE_ZWRITEENABLE, - z_write_enable ? TRUE : FALSE); - g_ZWriteEnableState = z_write_enable; - } - - if (g_ZEnableState != z_enable) { - if (g_ZBufferSurface != NULL) { - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, D3DRENDERSTATE_ZFUNC, - z_enable ? D3DCMP_LESSEQUAL : D3DCMP_ALWAYS); - } else { - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, D3DRENDERSTATE_ZENABLE, z_enable ? TRUE : FALSE); - } - g_ZEnableState = z_enable; - } -} - -void __cdecl HWR_BeginScene(void) -{ - HWR_GetPageHandles(); - WaitPrimaryBufferFlip(); - g_D3DDev->lpVtbl->BeginScene(g_D3DDev); -} - -void __cdecl HWR_DrawPolyList(void) -{ - HWR_EnableZBuffer(false, true); - - for (int32_t i = 0; i < g_SurfaceCount; i++) { - uint16_t *buf_ptr = (uint16_t *)g_SortBuffer[i]._0; - - uint16_t poly_type = *buf_ptr++; - uint16_t tex_page = - (poly_type == POLY_HWR_GTMAP || poly_type == POLY_HWR_WGTMAP) - ? *buf_ptr++ - : 0; - uint16_t vtx_count = *buf_ptr++; - D3DTLVERTEX *vtx_ptr = *(D3DTLVERTEX **)buf_ptr; - - switch (poly_type) { - // triangle fan (texture) - case POLY_HWR_GTMAP: - // triangle fan (texture + colorkey) - case POLY_HWR_WGTMAP: - HWR_TexSource(g_HWR_PageHandles[tex_page]); - HWR_EnableColorKey(poly_type == POLY_HWR_WGTMAP); - HWR_DrawPrimitive(D3DPT_TRIANGLEFAN, vtx_ptr, vtx_count, true); - break; - - // triangle fan (color) - case POLY_HWR_GOURAUD: - HWR_TexSource(0); - HWR_EnableColorKey(false); - HWR_DrawPrimitive(D3DPT_TRIANGLEFAN, vtx_ptr, vtx_count, true); - break; - - // line strip (color) - case POLY_HWR_LINE: - HWR_TexSource(0); - HWR_EnableColorKey(false); - HWR_DrawPrimitive(D3DPT_LINESTRIP, vtx_ptr, vtx_count, true); - break; - - // triangle fan (color + semitransparent) - case POLY_HWR_TRANS: { - DWORD alpha_state; - HWR_TexSource(0); - g_D3DDev->lpVtbl->GetRenderState( - g_D3DDev, g_AlphaBlendEnabler, &alpha_state); - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, g_AlphaBlendEnabler, TRUE); - HWR_DrawPrimitive(D3DPT_TRIANGLEFAN, vtx_ptr, vtx_count, true); - g_D3DDev->lpVtbl->SetRenderState( - g_D3DDev, g_AlphaBlendEnabler, alpha_state); - break; - } - } - } -} - -void __cdecl HWR_LoadTexturePages( - const int32_t pages_count, const void *const pages_buffer, - const RGB_888 *const palette) -{ - int32_t page_idx = -1; - const BYTE *buffer_ptr = (const BYTE *)pages_buffer; - - HWR_FreeTexturePages(); - - if (palette != NULL) { - g_PaletteIndex = CreateTexturePalette(palette); - } - - for (int32_t i = 0; i < pages_count; i++) { - if (palette != NULL) { - page_idx = AddTexturePage8(256, 256, buffer_ptr, g_PaletteIndex); - buffer_ptr += 256 * 256 * 1; - } else { - page_idx = AddTexturePage16(256, 256, buffer_ptr); - buffer_ptr += 256 * 256 * 2; - } - g_HWR_TexturePageIndexes[i] = page_idx < 0 ? -1 : page_idx; - } - - HWR_GetPageHandles(); -} - -void __cdecl HWR_FreeTexturePages(void) -{ - for (int32_t i = 0; i < MAX_TEXTURE_PAGES; i++) { - if (g_HWR_TexturePageIndexes[i] >= 0) { - SafeFreeTexturePage(g_HWR_TexturePageIndexes[i]); - g_HWR_TexturePageIndexes[i] = -1; - } - g_HWR_PageHandles[i] = 0; - } - if (g_PaletteIndex >= 0) { - SafeFreePalette(g_PaletteIndex); - } -} - -void __cdecl HWR_GetPageHandles(void) -{ - for (int32_t i = 0; i < MAX_TEXTURE_PAGES; i++) { - if (g_HWR_TexturePageIndexes[i] < 0) - g_HWR_PageHandles[i] = 0; - else - g_HWR_PageHandles[i] = - GetTexturePageHandle(g_HWR_TexturePageIndexes[i]); - } -} - -bool __cdecl HWR_VertexBufferFull(void) -{ - const int32_t index = g_HWR_VertexPtr - g_HWR_VertexBuffer; - return index >= MAX_VERTICES - 0x200; -} - -bool __cdecl HWR_Init(void) -{ - memset(g_HWR_VertexBuffer, 0, sizeof(g_HWR_VertexBuffer)); - memset( - g_HWR_TexturePageIndexes, (uint8_t)-1, - sizeof(g_HWR_TexturePageIndexes)); - return true; -} diff --git a/src/tr2/game/hwr.h b/src/tr2/game/hwr.h deleted file mode 100644 index 3b7c1df2e..000000000 --- a/src/tr2/game/hwr.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "global/types.h" - -#include -#include -#include - -HRESULT HWR_DrawPrimitive( - D3DPRIMITIVETYPE primitive_type, LPVOID vertices, DWORD vtx_count, - bool is_no_clip); - -void __cdecl HWR_InitState(void); -void __cdecl HWR_ResetTexSource(void); -void __cdecl HWR_ResetColorKey(void); -void __cdecl HWR_ResetZBuffer(void); -void __cdecl HWR_TexSource(HWR_TEXTURE_HANDLE tex_source); -void __cdecl HWR_EnableColorKey(bool state); -void __cdecl HWR_EnableZBuffer(bool z_write_enable, bool z_enable); -void __cdecl HWR_BeginScene(void); -void __cdecl HWR_DrawPolyList(void); -void __cdecl HWR_LoadTexturePages( - int32_t pages_count, const void *pages_buffer, const RGB_888 *palette); -void __cdecl HWR_FreeTexturePages(void); -void __cdecl HWR_GetPageHandles(void); -bool __cdecl HWR_VertexBufferFull(void); -bool __cdecl HWR_Init(void); 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 43b9f274b..e19f30117 100644 --- a/src/tr2/game/inventory/common.c +++ b/src/tr2/game/inventory/common.c @@ -5,6 +5,7 @@ #include "game/clock.h" #include "game/console/common.h" #include "game/demo.h" +#include "game/fader.h" #include "game/game.h" #include "game/input.h" #include "game/inventory/backpack.h" @@ -42,6 +43,7 @@ static void M_RemoveItemsText(void); static void M_RemoveAllText(void); static void M_ShowItemQuantity(const char *fmt, int32_t qty); static void M_ShowAmmoQuantity(const char *fmt, int32_t qty); +static void M_End(RING_INFO *ring); static void M_RemoveItemsText(void) { @@ -91,19 +93,43 @@ static void M_ShowAmmoQuantity(const char *const fmt, const int32_t qty) } } +static void M_End(RING_INFO *const ring) +{ + M_RemoveAllText(); + if (ring->list != NULL) { + INVENTORY_ITEM *const inv_item = ring->list[ring->current_object]; + if (inv_item != NULL) { + Option_Shutdown(inv_item); + } + } + Output_UnloadBackground(); +} + void __cdecl Inv_InitColors(void) { - g_InvColors[INV_COLOR_BLACK] = S_FindColor(0x00, 0x00, 0x00); - g_InvColors[INV_COLOR_GRAY] = S_FindColor(0x40, 0x40, 0x40); - g_InvColors[INV_COLOR_WHITE] = S_FindColor(0xFF, 0xFF, 0xFF); - g_InvColors[INV_COLOR_RED] = S_FindColor(0xFF, 0x00, 0x00); - g_InvColors[INV_COLOR_ORANGE] = S_FindColor(0xFF, 0x80, 0x00); - g_InvColors[INV_COLOR_YELLOW] = S_FindColor(0xFF, 0xFF, 0x00); - g_InvColors[INV_COLOR_DARK_GREEN] = S_FindColor(0x00, 0x80, 0x00); - g_InvColors[INV_COLOR_GREEN] = S_FindColor(0x00, 0xFF, 0x00); - g_InvColors[INV_COLOR_CYAN] = S_FindColor(0x00, 0xFF, 0xFF); - g_InvColors[INV_COLOR_BLUE] = S_FindColor(0x00, 0x00, 0xFF); - g_InvColors[INV_COLOR_MAGENTA] = S_FindColor(0xFF, 0x00, 0xFF); + struct { + RGB_888 rgb; + INV_COLOR inv_color; + } color_mapping[] = { + { { { 0x00 }, { 0x00 }, { 0x00 } }, INV_COLOR_BLACK }, + { { { 0x40 }, { 0x40 }, { 0x40 } }, INV_COLOR_GRAY }, + { { { 0xFF }, { 0xFF }, { 0xFF } }, INV_COLOR_WHITE }, + { { { 0xFF }, { 0x00 }, { 0x00 } }, INV_COLOR_RED }, + { { { 0xFF }, { 0x80 }, { 0x00 } }, INV_COLOR_ORANGE }, + { { { 0xFF }, { 0xFF }, { 0x00 } }, INV_COLOR_YELLOW }, + { { { 0x00 }, { 0x80 }, { 0x00 } }, INV_COLOR_DARK_GREEN }, + { { { 0x00 }, { 0xFF }, { 0x00 } }, INV_COLOR_GREEN }, + { { { 0x00 }, { 0xFF }, { 0xFF } }, INV_COLOR_CYAN }, + { { { 0x00 }, { 0x00 }, { 0xFF } }, INV_COLOR_BLUE }, + { { { 0xFF }, { 0x00 }, { 0xFF } }, INV_COLOR_MAGENTA }, + { { { 0 }, { 0 }, { 0 } }, (INV_COLOR)-1 }, + }; + + for (int32_t i = 0; color_mapping[i].inv_color != (INV_COLOR)-1; i++) { + RGB_888 rgb = color_mapping[i].rgb; + g_InvColors[color_mapping[i].inv_color] = + Output_FindColor(rgb.red, rgb.green, rgb.blue); + } } void __cdecl Inv_Construct(void) @@ -182,13 +208,287 @@ void __cdecl Inv_Construct(void) } } +static void M_DrawItem( + const RING_INFO *const ring, const IMOTION_INFO *const motion, + INVENTORY_ITEM *const inv_item, const int32_t frames) +{ + if (motion->status == RNG_DONE) { + g_LsAdder = LOW_LIGHT; + } else if (inv_item == ring->list[ring->current_object]) { + if (ring->rotating) { + g_LsAdder = LOW_LIGHT; + for (int32_t k = 0; k < frames; k++) { + if (inv_item->y_rot > 0) { + inv_item->y_rot -= 512; + } else if (inv_item->y_rot < 0) { + inv_item->y_rot += 512; + } + } + } else if ( + motion->status == RNG_SELECTED || motion->status == RNG_DESELECTING + || motion->status == RNG_SELECTING || motion->status == RNG_DESELECT + || motion->status == RNG_CLOSING_ITEM) { + g_LsAdder = HIGH_LIGHT; + for (int32_t k = 0; k < frames; k++) { + const int32_t delta = inv_item->y_rot_sel - inv_item->y_rot; + if (delta != 0) { + if (delta > 0 && delta < PHD_180) { + inv_item->y_rot += 1024; + } else { + inv_item->y_rot -= 1024; + } + inv_item->y_rot &= ~(1024 - 1); + } + } + } else if ( + ring->number_of_objects == 1 || (!g_Input.right && !g_Input.left)) { + g_LsAdder = HIGH_LIGHT; + for (int32_t k = 0; k < frames; k++) { + inv_item->y_rot += 256; + } + } + } else { + g_LsAdder = LOW_LIGHT; + for (int32_t k = 0; k < frames; k++) { + if (inv_item->y_rot < 0) { + inv_item->y_rot += 256; + } else if (inv_item->y_rot > 0) { + inv_item->y_rot -= 256; + } + } + } + + int32_t minutes; + int32_t hours; + int32_t seconds; + if (inv_item->object_id == O_COMPASS_OPTION) { + const int32_t total_seconds = + g_SaveGame.statistics.timer / FRAMES_PER_SECOND; + hours = (total_seconds % 43200) * PHD_DEGREE * -360 / 43200; + minutes = (total_seconds % 3600) * PHD_DEGREE * -360 / 3600; + seconds = (total_seconds % 60) * PHD_DEGREE * -360 / 60; + } else { + seconds = 0; + minutes = 0; + hours = 0; + } + + Matrix_TranslateRel(0, inv_item->y_trans, inv_item->z_trans); + Matrix_RotYXZ(inv_item->y_rot, inv_item->x_rot, 0); + const OBJECT *const obj = &g_Objects[inv_item->object_id]; + if ((obj->flags & 1) == 0) { + return; + } + + if (obj->mesh_count < 0) { + Output_DrawSprite(0, 0, 0, 0, obj->mesh_idx, 0, 0); + return; + } + + if (inv_item->sprite_list != NULL) { + const int32_t zv = g_MatrixPtr->_23; + const int32_t zp = zv / g_PhdPersp; + const int32_t sx = g_PhdWinCenterX + g_MatrixPtr->_03 / zp; + const int32_t sy = g_PhdWinCenterY + g_MatrixPtr->_13 / zp; + + INVENTORY_SPRITE **sprite_list = inv_item->sprite_list; + INVENTORY_SPRITE *sprite; + while ((sprite = *sprite_list++)) { + if (zv < g_PhdNearZ || zv > g_PhdFarZ) { + break; + } + + while (sprite->shape) { + switch (sprite->shape) { + case SHAPE_SPRITE: + Output_DrawScreenSprite( + sx + sprite->pos.x, sy + sprite->pos.y, sprite->pos.z, + sprite->param1, sprite->param2, + g_Objects[O_ALPHABET].mesh_idx + sprite->sprite_num, + 4096, 0); + break; + + case SHAPE_LINE: + Output_DrawScreenLine( + sx + sprite->pos.x, sy + sprite->pos.y, sprite->pos.z, + sprite->param1, sprite->param2, sprite->sprite_num, + sprite->grdptr, 0); + break; + + case SHAPE_BOX: + Output_DrawScreenBox( + sx + sprite->pos.x, sy + sprite->pos.y, sprite->pos.z, + sprite->param1, sprite->param2, sprite->sprite_num, + sprite->grdptr, 0); + break; + + case SHAPE_FBOX: + Output_DrawScreenFBox( + sx + sprite->pos.x, sy + sprite->pos.y, sprite->pos.z, + sprite->param1, sprite->param2, sprite->sprite_num, + sprite->grdptr, 0); + break; + + default: + break; + } + sprite++; + } + } + } + + FRAME_INFO *frame_ptr = (FRAME_INFO *)&obj->frame_base + [inv_item->current_frame + * (g_Anims[obj->anim_idx].interpolation >> 8)]; + + Matrix_Push(); + const int32_t clip = S_GetObjectBounds(&frame_ptr->bounds); + if (!clip) { + Matrix_Pop(); + return; + } + + const int32_t *bone = &g_AnimBones[obj->bone_idx]; + Matrix_TranslateRel( + frame_ptr->offset.x, frame_ptr->offset.y, frame_ptr->offset.z); + const int16_t *rot = frame_ptr->mesh_rots; + Matrix_RotYXZsuperpack(&rot, 0); + + for (int32_t mesh_idx = 0; mesh_idx < obj->mesh_count; mesh_idx++) { + if (mesh_idx > 0) { + const int32_t bone_flags = bone[0]; + if (bone_flags & BF_MATRIX_POP) { + Matrix_Pop(); + } + if (bone_flags & BF_MATRIX_PUSH) { + Matrix_Push(); + } + + Matrix_TranslateRel(bone[1], bone[2], bone[3]); + Matrix_RotYXZsuperpack(&rot, 0); + bone += 4; + + if (inv_item->object_id == O_COMPASS_OPTION) { + if (mesh_idx == 6) { + Matrix_RotZ(seconds); + const int32_t tmp = inv_item->reserved[0]; + inv_item->reserved[0] = seconds; + inv_item->reserved[1] = tmp; + } + if (mesh_idx == 5) { + Matrix_RotZ(minutes); + } + if (mesh_idx == 4) { + Matrix_RotZ(hours); + } + } + } + + if (inv_item->meshes_drawn & (1 << mesh_idx)) { + Output_InsertPolygons(g_Meshes[obj->mesh_idx + mesh_idx], clip); + } + } + + Matrix_Pop(); +} + +static void M_Draw( + RING_INFO *const ring, IMOTION_INFO *const motion, FADER *const fader) +{ + ring->camera.pos.z = ring->radius + 598; + + Output_BeginScene(); + if (g_Inv_Mode == INV_TITLE_MODE) { + Inv_DoInventoryPicture(); + } else { + Inv_DoInventoryBackground(); + } + S_AnimateTextures(g_Inv_NFrames); + Overlay_Animate(g_Inv_NFrames / 2); + + PHD_3DPOS view; + Inv_Ring_GetView(ring, &view); + Matrix_GenerateW2V(&view); + Inv_Ring_Light(ring); + + Matrix_Push(); + Matrix_TranslateAbs( + ring->ring_pos.pos.x, ring->ring_pos.pos.y, ring->ring_pos.pos.z); + Matrix_RotYXZ( + ring->ring_pos.rot.y, ring->ring_pos.rot.x, ring->ring_pos.rot.z); + + int32_t angle = 0; + for (int32_t i = 0; i < ring->number_of_objects; i++) { + INVENTORY_ITEM *const inv_item = ring->list[i]; + Matrix_Push(); + Matrix_RotYXZ(angle, 0, 0); + Matrix_TranslateRel(ring->radius, 0, 0); + Matrix_RotYXZ(PHD_90, inv_item->x_rot_pt, 0); + M_DrawItem(ring, motion, inv_item, g_Inv_NFrames); + angle += ring->angle_adder; + Matrix_Pop(); + } + + if (ring->list != NULL && !ring->rotating + && (motion->status == RNG_OPEN || motion->status == RNG_SELECTING + || motion->status == RNG_SELECTED + || motion->status == RNG_DESELECTING + || motion->status == RNG_DESELECT + || motion->status == RNG_CLOSING_ITEM)) { + const INVENTORY_ITEM *const inv_item = ring->list[ring->current_object]; + if (inv_item != NULL) { + switch (inv_item->object_id) { + case O_SMALL_MEDIPACK_OPTION: + case O_LARGE_MEDIPACK_OPTION: + Overlay_DrawHealthBar(); + break; + + default: + break; + } + } + } + + Matrix_Pop(); + Output_DrawPolyList(); + + if (motion->status == RNG_SELECTED) { + INVENTORY_ITEM *const inv_item = ring->list[ring->current_object]; + if (inv_item->object_id == O_PASSPORT_CLOSED) { + inv_item->object_id = O_PASSPORT_OPTION; + } + Option_Draw(inv_item); + } + + Overlay_DrawModeInfo(); + Console_Draw(); + Text_Draw(); + Output_DrawPolyList(); + + Output_DrawBlackRectangle(fader->current.value); + const int32_t frames = Output_EndScene() * TICKS_PER_FRAME; + + Sound_EndScene(); + Shell_ProcessEvents(); + g_Inv_NFrames = frames; + g_Camera.num_frames = frames; +} + int32_t __cdecl Inv_Display(int32_t inventory_mode) { + FADER fader = { 0 }; + Clock_SyncTick(); Stats_StartTimer(); RING_INFO ring = { 0 }; IMOTION_INFO imo = { 0 }; + if (inventory_mode == INV_TITLE_MODE) { + Output_LoadBackgroundFromFile("data/title.pcx"); + } else { + Output_LoadBackgroundFromObject(); + } + bool demo_needed = false; bool pass_open = false; if (inventory_mode == INV_KEYS_MODE && !g_Inv_KeyObjectsCount) { @@ -204,9 +504,11 @@ int32_t __cdecl Inv_Display(int32_t inventory_mode) Inv_Construct(); if (inventory_mode == INV_TITLE_MODE) { - S_FadeInInventory(0); - } else { - S_FadeInInventory(1); + Fader_InitBlackToTransparent(&fader, FRAMES_PER_SECOND / 3); + while (Fader_IsActive(&fader)) { + M_Draw(&ring, &imo, &fader); + Fader_Control(&fader); + } } Sound_StopAllSamples(); @@ -249,8 +551,7 @@ int32_t __cdecl Inv_Display(int32_t inventory_mode) do { if (g_GF_OverrideDir != (GAME_FLOW_DIR)-1) { INVENTORY_ITEM *inv_item = ring.list[ring.current_object]; - M_RemoveAllText(); - Option_ShutdownInventory(inv_item); + M_End(&ring); return GFD_OVERRIDE; } @@ -262,9 +563,11 @@ int32_t __cdecl Inv_Display(int32_t inventory_mode) if (g_Inv_DemoMode) { if (g_InputDB.any) { + M_End(&ring); return g_GameFlow.on_demo_interrupt; } if (!Demo_GetInput()) { + M_End(&ring); return g_GameFlow.on_demo_end; } } else if (g_InputDB.any) { @@ -280,8 +583,8 @@ int32_t __cdecl Inv_Display(int32_t inventory_mode) } } - if (g_StopInventory) { - return GFD_EXIT_TO_TITLE; + if (g_IsGameToExit) { + break; } if ((g_Inv_Mode == INV_SAVE_MODE || g_Inv_Mode == INV_LOAD_MODE @@ -301,115 +604,6 @@ int32_t __cdecl Inv_Display(int32_t inventory_mode) } Inv_Ring_DoMotions(&ring); } - ring.camera.pos.z = ring.radius + 598; - - S_InitialisePolyList(0); - if (g_Inv_Mode == INV_TITLE_MODE) { - Inv_DoInventoryPicture(); - } else { - Inv_DoInventoryBackground(); - } - S_AnimateTextures(g_Inv_NFrames); - Overlay_Animate(g_Inv_NFrames / 2); - - PHD_3DPOS view; - Inv_Ring_GetView(&ring, &view); - Matrix_GenerateW2V(&view); - Inv_Ring_Light(&ring); - - Matrix_Push(); - Matrix_TranslateAbs( - ring.ring_pos.pos.x, ring.ring_pos.pos.y, ring.ring_pos.pos.z); - Matrix_RotYXZ( - ring.ring_pos.rot.y, ring.ring_pos.rot.x, ring.ring_pos.rot.z); - - int32_t angle = 0; - for (int32_t j = 0; j < ring.number_of_objects; j++) { - INVENTORY_ITEM *inv_item = ring.list[j]; - if (j != ring.current_object) { - g_LsAdder = LOW_LIGHT; - for (int32_t k = 0; k < g_Inv_NFrames; k++) { - if (inv_item->y_rot < 0) { - inv_item->y_rot += 256; - } else if (inv_item->y_rot > 0) { - inv_item->y_rot -= 256; - } - } - } else { - for (int32_t k = 0; k < g_Inv_NFrames; k++) { - if (ring.rotating) { - g_LsAdder = LOW_LIGHT; - if (inv_item->y_rot > 0) { - inv_item->y_rot -= 512; - } else if (inv_item->y_rot < 0) { - inv_item->y_rot += 512; - } - } else if ( - imo.status == RNG_SELECTED - || imo.status == RNG_DESELECTING - || imo.status == RNG_SELECTING - || imo.status == RNG_DESELECT - || imo.status == RNG_CLOSING_ITEM) { - g_LsAdder = HIGH_LIGHT; - const int32_t delta = - inv_item->y_rot_sel - inv_item->y_rot; - if (delta != 0) { - if (delta > 0 && delta < PHD_180) { - inv_item->y_rot += 1024; - } else { - inv_item->y_rot -= 1024; - } - inv_item->y_rot &= ~(1024 - 1); - } - } else if ( - ring.number_of_objects == 1 - || (!g_Input.right && !g_Input.left)) { - g_LsAdder = HIGH_LIGHT; - inv_item->y_rot += 256; - } - } - - if ((imo.status == RNG_OPEN || imo.status == RNG_SELECTING - || imo.status == RNG_SELECTED - || imo.status == RNG_DESELECTING - || imo.status == RNG_DESELECT - || imo.status == RNG_CLOSING_ITEM) - && !ring.rotating && !g_Input.left && !g_Input.right) { - Inv_RingNotActive(inv_item); - } - } - - if (imo.status == RNG_OPEN || imo.status == RNG_SELECTING - || imo.status == RNG_SELECTED || imo.status == RNG_DESELECTING - || imo.status == RNG_DESELECT - || imo.status == RNG_CLOSING_ITEM) { - Inv_RingIsOpen(&ring); - } else { - Inv_RingIsNotOpen(&ring); - } - - if (imo.status == RNG_OPENING || imo.status == RNG_CLOSING - || imo.status == RNG_MAIN2OPTION - || imo.status == RNG_OPTION2MAIN - || imo.status == RNG_EXITING_INVENTORY || imo.status == RNG_DONE - || ring.rotating) { - Inv_RingActive(); - } - - Matrix_Push(); - Matrix_RotYXZ(angle, 0, 0); - Matrix_TranslateRel(ring.radius, 0, 0); - Matrix_RotYXZ(PHD_90, inv_item->x_rot_pt, 0); - Inv_DrawInventoryItem(inv_item); - Matrix_Pop(); - angle += ring.angle_adder; - } - - Matrix_Pop(); - Overlay_DrawModeInfo(); - Console_Draw(); - Text_Draw(); - Sound_EndScene(); if (!ring.rotating) { switch (imo.status) { @@ -436,11 +630,6 @@ int32_t __cdecl Inv_Display(int32_t inventory_mode) } else { g_Inv_MainCurrent = ring.current_object; } - if (inventory_mode == INV_TITLE_MODE) { - S_FadeOutInventory(0); - } else { - S_FadeOutInventory(1); - } Inv_Ring_MotionSetup(&ring, RNG_CLOSING, RNG_DONE, 32); Inv_Ring_MotionRadius(&ring, 0); Inv_Ring_MotionCameraPos(&ring, -1536); @@ -654,7 +843,7 @@ int32_t __cdecl Inv_Display(int32_t inventory_mode) } if (!busy && !g_Inv_IsOptionsDelay) { - Option_DoInventory(inv_item); + Option_Control(inv_item); if (g_InputDB.menu_back) { inv_item->sprite_list = NULL; @@ -728,11 +917,6 @@ int32_t __cdecl Inv_Display(int32_t inventory_mode) case RNG_EXITING_INVENTORY: if (!imo.count) { - if (inventory_mode == INV_TITLE_MODE) { - S_FadeOutInventory(0); - } else { - S_FadeOutInventory(1); - } Inv_Ring_MotionSetup(&ring, RNG_CLOSING, RNG_DONE, 32); Inv_Ring_MotionRadius(&ring, 0); Inv_Ring_MotionCameraPos(&ring, -1536); @@ -746,22 +930,50 @@ int32_t __cdecl Inv_Display(int32_t inventory_mode) } } - S_OutputPolyList(); - const int32_t frames = S_DumpScreen() * TICKS_PER_FRAME; - Shell_ProcessEvents(); - g_Inv_NFrames = frames; - g_Camera.num_frames = frames; + if (imo.status == RNG_OPEN || imo.status == RNG_SELECTING + || imo.status == RNG_SELECTED || imo.status == RNG_DESELECTING + || imo.status == RNG_DESELECT || imo.status == RNG_CLOSING_ITEM) { + if (!ring.rotating && !g_Input.menu_left && !g_Input.menu_right) { + INVENTORY_ITEM *const inv_item = ring.list[ring.current_object]; + Inv_RingNotActive(inv_item); + } + Inv_RingIsOpen(&ring); + } else { + Inv_RingIsNotOpen(&ring); + } + + if (imo.status == RNG_OPENING || imo.status == RNG_CLOSING + || imo.status == RNG_MAIN2OPTION || imo.status == RNG_OPTION2MAIN + || imo.status == RNG_EXITING_INVENTORY || imo.status == RNG_DONE + || ring.rotating) { + Inv_RingActive(); + } + if (g_CurrentLevel) { Stats_UpdateTimer(); } + + M_Draw(&ring, &imo, &fader); + Fader_Control(&fader); } while (imo.status != RNG_DONE); - M_RemoveAllText(); + if (inventory_mode == INV_TITLE_MODE || g_IsGameToExit) { + Fader_InitTransparentToBlack(&fader, FRAMES_PER_SECOND / 3); + while (Fader_IsActive(&fader)) { + M_Draw(&ring, &imo, &fader); + Fader_Control(&fader); + } + } + + M_End(&ring); g_Inv_IsActive = 0; // enable buffering g_OldInputDB = (INPUT_STATE) { 0 }; + if (g_IsGameToExit) { + return GFD_EXIT_GAME; + } if (demo_needed) { return GFD_START_DEMO; } @@ -887,142 +1099,6 @@ int32_t __cdecl Inv_AnimateInventoryItem(INVENTORY_ITEM *const inv_item) return true; } -void __cdecl Inv_DrawInventoryItem(INVENTORY_ITEM *const inv_item) -{ - int32_t minutes; - int32_t hours; - int32_t seconds; - if (inv_item->object_id == O_COMPASS_OPTION) { - const int32_t total_seconds = - g_SaveGame.statistics.timer / FRAMES_PER_SECOND; - hours = (total_seconds % 43200) * PHD_DEGREE * -360 / 43200; - minutes = (total_seconds % 3600) * PHD_DEGREE * -360 / 3600; - seconds = (total_seconds % 60) * PHD_DEGREE * -360 / 60; - } else { - seconds = 0; - minutes = 0; - hours = 0; - } - - Matrix_TranslateRel(0, inv_item->y_trans, inv_item->z_trans); - Matrix_RotYXZ(inv_item->y_rot, inv_item->x_rot, 0); - const OBJECT *const obj = &g_Objects[inv_item->object_id]; - if ((obj->flags & 1) == 0) { - return; - } - - if (obj->mesh_count < 0) { - Output_DrawSprite(0, 0, 0, 0, obj->mesh_idx, 0, 0); - return; - } - - if (inv_item->sprite_list != NULL) { - const int32_t zv = g_MatrixPtr->_23; - const int32_t zp = zv / g_PhdPersp; - const int32_t sx = g_PhdWinCenterX + g_MatrixPtr->_03 / zp; - const int32_t sy = g_PhdWinCenterY + g_MatrixPtr->_13 / zp; - - INVENTORY_SPRITE **sprite_list = inv_item->sprite_list; - INVENTORY_SPRITE *sprite; - while ((sprite = *sprite_list++)) { - if (zv < g_PhdNearZ || zv > g_PhdFarZ) { - break; - } - - while (sprite->shape) { - switch (sprite->shape) { - case SHAPE_SPRITE: - Output_DrawScreenSprite( - sx + sprite->pos.x, sy + sprite->pos.y, sprite->pos.z, - sprite->param1, sprite->param2, - g_Objects[O_ALPHABET].mesh_idx + sprite->sprite_num, - 4096, 0); - break; - - case SHAPE_LINE: - S_DrawScreenLine( - sx + sprite->pos.x, sy + sprite->pos.y, sprite->pos.z, - sprite->param1, sprite->param2, sprite->sprite_num, - sprite->grdptr, 0); - break; - - case SHAPE_BOX: - S_DrawScreenBox( - sx + sprite->pos.x, sy + sprite->pos.y, sprite->pos.z, - sprite->param1, sprite->param2, sprite->sprite_num, - sprite->grdptr, 0); - break; - - case SHAPE_FBOX: - S_DrawScreenFBox( - sx + sprite->pos.x, sy + sprite->pos.y, sprite->pos.z, - sprite->param1, sprite->param2, sprite->sprite_num, - sprite->grdptr, 0); - break; - - default: - break; - } - sprite++; - } - } - } - - FRAME_INFO *frame_ptr = (FRAME_INFO *)&obj->frame_base - [inv_item->current_frame - * (g_Anims[obj->anim_idx].interpolation >> 8)]; - - Matrix_Push(); - const int32_t clip = S_GetObjectBounds(&frame_ptr->bounds); - if (!clip) { - Matrix_Pop(); - return; - } - - const int32_t *bone = &g_AnimBones[obj->bone_idx]; - Matrix_TranslateRel( - frame_ptr->offset.x, frame_ptr->offset.y, frame_ptr->offset.z); - const int16_t *rot = frame_ptr->mesh_rots; - Matrix_RotYXZsuperpack(&rot, 0); - - for (int32_t mesh_idx = 0; mesh_idx < obj->mesh_count; mesh_idx++) { - if (mesh_idx > 0) { - const int32_t bone_flags = bone[0]; - if (bone_flags & BF_MATRIX_POP) { - Matrix_Pop(); - } - if (bone_flags & BF_MATRIX_PUSH) { - Matrix_Push(); - } - - Matrix_TranslateRel(bone[1], bone[2], bone[3]); - Matrix_RotYXZsuperpack(&rot, 0); - bone += 4; - - if (inv_item->object_id == O_COMPASS_OPTION) { - if (mesh_idx == 6) { - Matrix_RotZ(seconds); - const int32_t tmp = inv_item->reserved[0]; - inv_item->reserved[0] = seconds; - inv_item->reserved[1] = tmp; - } - if (mesh_idx == 5) { - Matrix_RotZ(minutes); - } - if (mesh_idx == 4) { - Matrix_RotZ(hours); - } - } - } - - if (inv_item->meshes_drawn & (1 << mesh_idx)) { - Output_InsertPolygons(g_Meshes[obj->mesh_idx + mesh_idx], clip); - } - } - - Matrix_Pop(); -} - GAME_OBJECT_ID Inv_GetItemOption(const GAME_OBJECT_ID object_id) { if (Object_IsObjectType(object_id, g_InvObjects)) { @@ -1034,12 +1110,12 @@ GAME_OBJECT_ID Inv_GetItemOption(const GAME_OBJECT_ID object_id) void __cdecl Inv_DoInventoryPicture(void) { - S_CopyBufferToScreen(); + Output_DrawBackground(); } void __cdecl Inv_DoInventoryBackground(void) { - S_CopyBufferToScreen(); + Output_DrawBackground(); if (!g_Objects[O_INV_BACKGROUND].loaded) { return; } diff --git a/src/tr2/game/lara/draw.c b/src/tr2/game/lara/draw.c index 4ba962dee..64933ba6c 100644 --- a/src/tr2/game/lara/draw.c +++ b/src/tr2/game/lara/draw.c @@ -51,7 +51,7 @@ void __cdecl Lara_Draw(const ITEM *const item) } if (g_Lara.skidoo == NO_ITEM) { - S_PrintShadow(object->shadow_size, &frame->bounds, item); + Output_InsertShadow(object->shadow_size, &frame->bounds, item); } saved_matrix = *g_MatrixPtr; @@ -349,7 +349,7 @@ void __cdecl Lara_Draw_I( const BOUNDS_16 *const bounds = Item_GetBoundsAccurate(item); if (g_Lara.skidoo == NO_ITEM) { - S_PrintShadow(object->shadow_size, bounds, item); + Output_InsertShadow(object->shadow_size, bounds, item); } MATRIX saved_matrix = *g_MatrixPtr; diff --git a/src/tr2/game/level.c b/src/tr2/game/level.c index 2958f7a97..0596787b7 100644 --- a/src/tr2/game/level.c +++ b/src/tr2/game/level.c @@ -3,10 +3,10 @@ #include "decomp/decomp.h" #include "game/gamebuf.h" #include "game/gameflow/gameflow_new.h" -#include "game/hwr.h" #include "game/inject.h" #include "game/items.h" #include "game/objects/setup.h" +#include "game/render/common.h" #include "game/room.h" #include "game/shell.h" #include "global/const.h" @@ -21,35 +21,33 @@ #include static void M_LoadFromFile(const char *file_name, int32_t level_num); -static void __cdecl M_LoadRooms(VFILE *file); -static void __cdecl M_LoadMeshBase(VFILE *file); -static void __cdecl M_LoadMeshes(VFILE *file); -static int32_t __cdecl M_LoadAnims(VFILE *file, int32_t **frame_pointers); -static void __cdecl M_LoadAnimChanges(VFILE *file); -static void __cdecl M_LoadAnimRanges(VFILE *file); -static void __cdecl M_LoadAnimCommands(VFILE *file); -static void __cdecl M_LoadAnimBones(VFILE *file); -static void __cdecl M_LoadAnimFrames(VFILE *file); -static void __cdecl M_LoadObjects(VFILE *file); -static void __cdecl M_LoadStaticObjects(VFILE *file); -static void __cdecl M_LoadTextures(VFILE *file); -static void __cdecl M_LoadSprites(VFILE *file); -static void __cdecl M_LoadItems(VFILE *file); -static void __cdecl M_LoadCameras(VFILE *file); -static void __cdecl M_LoadSoundEffects(VFILE *file); -static void __cdecl M_LoadBoxes(VFILE *file); -static void __cdecl M_LoadAnimatedTextures(VFILE *file); -static void __cdecl M_LoadCinematic(VFILE *file); -static void __cdecl M_LoadDemo(VFILE *file); -static void __cdecl M_LoadSamples(VFILE *file); +static void M_LoadRooms(VFILE *file); +static void M_LoadMeshBase(VFILE *file); +static void M_LoadMeshes(VFILE *file); +static int32_t M_LoadAnims(VFILE *file, int32_t **frame_pointers); +static void M_LoadAnimChanges(VFILE *file); +static void M_LoadAnimRanges(VFILE *file); +static void M_LoadAnimCommands(VFILE *file); +static void M_LoadAnimBones(VFILE *file); +static void M_LoadAnimFrames(VFILE *file); +static void M_LoadObjects(VFILE *file); +static void M_LoadStaticObjects(VFILE *file); +static void M_LoadTextures(VFILE *file); +static void M_LoadSprites(VFILE *file); +static void M_LoadItems(VFILE *file); +static void M_LoadCameras(VFILE *file); +static void M_LoadSoundEffects(VFILE *file); +static void M_LoadBoxes(VFILE *file); +static void M_LoadAnimatedTextures(VFILE *file); +static void M_LoadCinematic(VFILE *file); +static void M_LoadDemo(VFILE *file); +static void M_LoadSamples(VFILE *file); static void M_CompleteSetup(void); -void __cdecl Level_LoadTexturePages(VFILE *const file) +static void M_LoadTexturePages(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); - char *base = NULL; - const bool is_16_bit = g_TextureFormat.bpp >= 16; const int32_t texture_size = TEXTURE_PAGE_WIDTH * TEXTURE_PAGE_HEIGHT; const int32_t texture_size_8_bit = texture_size * sizeof(uint8_t); const int32_t texture_size_16_bit = texture_size * sizeof(uint16_t); @@ -57,48 +55,29 @@ void __cdecl Level_LoadTexturePages(VFILE *const file) const int32_t num_pages = VFile_ReadS32(file); LOG_INFO("texture pages: %d", num_pages); - if (g_SavedAppSettings.render_mode == RM_SOFTWARE) { - for (int32_t i = 0; i < num_pages; i++) { - if (g_TexturePageBuffer8[i] == NULL) { - g_TexturePageBuffer8[i] = - GameBuf_Alloc(texture_size, GBUF_TEXTURE_PAGES); - } - VFile_Read(file, g_TexturePageBuffer8[i], texture_size); + for (int32_t i = 0; i < num_pages; i++) { + if (g_TexturePageBuffer8[i] == NULL) { + g_TexturePageBuffer8[i] = + GameBuf_Alloc(texture_size_8_bit, GBUF_TEXTURE_PAGES); } - // skip 16-bit texture pages - VFile_Skip(file, num_pages * texture_size_16_bit); - goto finish; + VFile_Read(file, g_TexturePageBuffer8[i], texture_size_8_bit); } - - base = Memory_Alloc( - num_pages * (is_16_bit ? texture_size_16_bit : texture_size_8_bit)); - - if (is_16_bit) { - VFile_Skip(file, num_pages * texture_size_8_bit); - char *ptr = base; - for (int32_t i = 0; i < num_pages; i++) { - VFile_Read(file, ptr, texture_size_16_bit); - ptr += texture_size_16_bit; + for (int32_t i = 0; i < num_pages; i++) { + if (g_TexturePageBuffer16[i] == NULL) { + g_TexturePageBuffer16[i] = + GameBuf_Alloc(texture_size_16_bit, GBUF_TEXTURE_PAGES); } - HWR_LoadTexturePages(num_pages, base, NULL); - } else { - char *ptr = base; - for (int32_t i = 0; i < num_pages; i++) { - VFile_Read(file, ptr, texture_size_8_bit); - ptr += texture_size_8_bit; - } - VFile_Skip(file, num_pages * texture_size_16_bit); - HWR_LoadTexturePages((int32_t)num_pages, base, g_GamePalette8); + VFile_Read(file, g_TexturePageBuffer16[i], texture_size_16_bit); + LOG_DEBUG("%d", g_TexturePageBuffer16[0][0]); } g_TexturePageCount = num_pages; finish: - Memory_FreePointer(&base); Benchmark_End(benchmark, NULL); } -static void __cdecl M_LoadRooms(VFILE *const file) +static void M_LoadRooms(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); @@ -216,7 +195,7 @@ finish: Benchmark_End(benchmark, NULL); } -static void __cdecl M_LoadMeshBase(VFILE *const file) +static void M_LoadMeshBase(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); const int32_t num_meshes = VFile_ReadS32(file); @@ -226,7 +205,7 @@ static void __cdecl M_LoadMeshBase(VFILE *const file) Benchmark_End(benchmark, NULL); } -static void __cdecl M_LoadMeshes(VFILE *const file) +static void M_LoadMeshes(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); const int32_t num_mesh_ptrs = VFile_ReadS32(file); @@ -245,7 +224,7 @@ static void __cdecl M_LoadMeshes(VFILE *const file) Benchmark_End(benchmark, NULL); } -static int32_t __cdecl M_LoadAnims(VFILE *const file, int32_t **frame_pointers) +static int32_t M_LoadAnims(VFILE *const file, int32_t **frame_pointers) { BENCHMARK *const benchmark = Benchmark_Start(); const int32_t num_anims = VFile_ReadS32(file); @@ -279,7 +258,7 @@ static int32_t __cdecl M_LoadAnims(VFILE *const file, int32_t **frame_pointers) return num_anims; } -static void __cdecl M_LoadAnimChanges(VFILE *const file) +static void M_LoadAnimChanges(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); const int32_t num_anim_changes = VFile_ReadS32(file); @@ -295,7 +274,7 @@ static void __cdecl M_LoadAnimChanges(VFILE *const file) Benchmark_End(benchmark, NULL); } -static void __cdecl M_LoadAnimRanges(VFILE *const file) +static void M_LoadAnimRanges(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); const int32_t num_anim_ranges = VFile_ReadS32(file); @@ -312,7 +291,7 @@ static void __cdecl M_LoadAnimRanges(VFILE *const file) Benchmark_End(benchmark, NULL); } -static void __cdecl M_LoadAnimCommands(VFILE *const file) +static void M_LoadAnimCommands(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); const int32_t num_anim_commands = VFile_ReadS32(file); @@ -323,7 +302,7 @@ static void __cdecl M_LoadAnimCommands(VFILE *const file) Benchmark_End(benchmark, NULL); } -static void __cdecl M_LoadAnimBones(VFILE *const file) +static void M_LoadAnimBones(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); const int32_t num_anim_bones = VFile_ReadS32(file); @@ -334,7 +313,7 @@ static void __cdecl M_LoadAnimBones(VFILE *const file) Benchmark_End(benchmark, NULL); } -static void __cdecl M_LoadAnimFrames(VFILE *const file) +static void M_LoadAnimFrames(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); const int32_t anim_frame_data_size = VFile_ReadS32(file); @@ -347,7 +326,7 @@ static void __cdecl M_LoadAnimFrames(VFILE *const file) Benchmark_End(benchmark, NULL); } -static void __cdecl M_LoadObjects(VFILE *const file) +static void M_LoadObjects(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); const int32_t num_objects = VFile_ReadS32(file); @@ -366,7 +345,7 @@ static void __cdecl M_LoadObjects(VFILE *const file) Benchmark_End(benchmark, NULL); } -static void __cdecl M_LoadStaticObjects(VFILE *const file) +static void M_LoadStaticObjects(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); const int32_t num_static_objects = VFile_ReadS32(file); @@ -392,7 +371,7 @@ static void __cdecl M_LoadStaticObjects(VFILE *const file) Benchmark_End(benchmark, NULL); } -static void __cdecl M_LoadTextures(VFILE *const file) +static void M_LoadTextures(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); const int32_t num_textures = VFile_ReadS32(file); @@ -424,13 +403,16 @@ static void __cdecl M_LoadTextures(VFILE *const file) } } g_LabTextureUVFlag[i] = byte; + + for (int32_t j = 0; j < 4; j++) { + g_TextureInfo[i].uv_backup[j] = g_TextureInfo[i].uv[j]; + } } - AdjustTextureUVs(true); Benchmark_End(benchmark, NULL); } -static void __cdecl M_LoadSprites(VFILE *const file) +static void M_LoadSprites(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); const int32_t num_sprites = VFile_ReadS32(file); @@ -467,7 +449,7 @@ static void __cdecl M_LoadSprites(VFILE *const file) Benchmark_End(benchmark, NULL); } -static void __cdecl M_LoadItems(VFILE *const file) +static void M_LoadItems(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); @@ -510,7 +492,7 @@ finish: Benchmark_End(benchmark, NULL); } -void __cdecl Level_LoadDepthQ(VFILE *const file) +static void M_LoadDepthQ(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); for (int32_t i = 0; i < 32; i++) { @@ -518,25 +500,8 @@ void __cdecl Level_LoadDepthQ(VFILE *const file) g_DepthQTable[i].index[0] = 0; } - if (g_GameVid_IsWindowedVGA) { - RGB_888 palette[256]; - CopyBitmapPalette( - g_GamePalette8, g_DepthQTable[0].index, 32 * sizeof(DEPTHQ_ENTRY), - palette); - SyncSurfacePalettes( - g_DepthQTable, 256, 32, 256, g_GamePalette8, g_DepthQTable, 256, - palette, true); - memcpy(g_GamePalette8, palette, sizeof(g_GamePalette8)); - - for (int32_t i = 0; i < 256; i++) { - g_DepthQIndex[i] = S_FindColor( - g_GamePalette8[i].red, g_GamePalette8[i].green, - g_GamePalette8[i].blue); - } - } else { - for (int32_t i = 0; i < 256; i++) { - g_DepthQIndex[i] = g_DepthQTable[24].index[i]; - } + for (int32_t i = 0; i < 256; i++) { + g_DepthQIndex[i] = g_DepthQTable[24].index[i]; } for (int32_t i = 0; i < 32; i++) { @@ -555,7 +520,7 @@ void __cdecl Level_LoadDepthQ(VFILE *const file) Benchmark_End(benchmark, NULL); } -void __cdecl Level_LoadPalettes(VFILE *const file) +static void M_LoadPalettes(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); VFile_Read(file, g_GamePalette8, sizeof(RGB_888) * 256); @@ -575,7 +540,7 @@ void __cdecl Level_LoadPalettes(VFILE *const file) Benchmark_End(benchmark, NULL); } -static void __cdecl M_LoadCameras(VFILE *const file) +static void M_LoadCameras(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); g_NumCameras = VFile_ReadS32(file); @@ -599,7 +564,7 @@ finish: Benchmark_End(benchmark, NULL); } -static void __cdecl M_LoadSoundEffects(VFILE *const file) +static void M_LoadSoundEffects(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); @@ -624,7 +589,7 @@ finish: Benchmark_End(benchmark, NULL); } -static void __cdecl M_LoadBoxes(VFILE *const file) +static void M_LoadBoxes(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); g_BoxCount = VFile_ReadS32(file); @@ -669,7 +634,7 @@ static void __cdecl M_LoadBoxes(VFILE *const file) Benchmark_End(benchmark, NULL); } -static void __cdecl M_LoadAnimatedTextures(VFILE *const file) +static void M_LoadAnimatedTextures(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); const int32_t num_ranges = VFile_ReadS32(file); @@ -679,7 +644,7 @@ static void __cdecl M_LoadAnimatedTextures(VFILE *const file) Benchmark_End(benchmark, NULL); } -static void __cdecl M_LoadCinematic(VFILE *const file) +static void M_LoadCinematic(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); g_NumCineFrames = VFile_ReadS16(file); @@ -707,7 +672,7 @@ finish: Benchmark_End(benchmark, NULL); } -static void __cdecl M_LoadDemo(VFILE *const file) +static void M_LoadDemo(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); g_DemoCount = 0; @@ -728,7 +693,7 @@ static void __cdecl M_LoadDemo(VFILE *const file) Benchmark_End(benchmark, NULL); } -static void __cdecl M_LoadSamples(VFILE *const file) +static void M_LoadSamples(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); int32_t *sample_offsets = NULL; @@ -765,12 +730,10 @@ static void __cdecl M_LoadSamples(VFILE *const file) const char *const file_name = "data\\main.sfx"; const char *full_path = File_GetFullPath(file_name); LOG_DEBUG("Loading samples from %s", full_path); - HANDLE sfx_handle = CreateFileA( - full_path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, - NULL); + MYFILE *const fp = File_Open(full_path, FILE_OPEN_READ); Memory_FreePointer(&full_path); - if (sfx_handle == INVALID_HANDLE_VALUE) { + if (fp == NULL) { Shell_ExitSystemFmt( "Could not open %s file: 0x%x", file_name, GetLastError()); goto finish; @@ -780,7 +743,7 @@ static void __cdecl M_LoadSamples(VFILE *const file) int32_t sample_id = 0; for (int32_t i = 0; sample_id < num_samples; i++) { char header[0x2C]; - ReadFileSync(sfx_handle, header, 0x2C, NULL, NULL); + File_ReadData(fp, header, 0x2C); if (*(int32_t *)(header + 0) != 0x46464952 || *(int32_t *)(header + 8) != 0x45564157 || *(int32_t *)(header + 36) != 0x61746164) { @@ -791,14 +754,14 @@ static void __cdecl M_LoadSamples(VFILE *const file) const int32_t aligned_size = (data_size + 1) & ~1; if (sample_offsets[sample_id] != i) { - SetFilePointer(sfx_handle, aligned_size, NULL, FILE_CURRENT); + File_Seek(fp, aligned_size, FILE_SEEK_CUR); continue; } const size_t sample_data_size = 0x2C + aligned_size; char *sample_data = Memory_Alloc(sample_data_size); memcpy(sample_data, header, 0x2C); - ReadFileSync(sfx_handle, sample_data + 0x2C, aligned_size, NULL, NULL); + File_ReadData(fp, sample_data + 0x2C, aligned_size); const bool result = Audio_Sample_LoadSingle(sample_id, sample_data, sample_data_size); @@ -810,7 +773,7 @@ static void __cdecl M_LoadSamples(VFILE *const file) sample_id++; } - CloseHandle(sfx_handle); + File_Close(fp); finish: Memory_FreePointer(&sample_offsets); @@ -844,10 +807,10 @@ static void M_LoadFromFile(const char *const file_name, const int32_t level_num) } g_LevelFilePalettesOffset = VFile_GetPos(file); - Level_LoadPalettes(file); + M_LoadPalettes(file); g_LevelFileTexPagesOffset = VFile_GetPos(file); - Level_LoadTexturePages(file); + M_LoadTexturePages(file); VFile_Skip(file, 4); M_LoadRooms(file); @@ -883,8 +846,7 @@ static void M_LoadFromFile(const char *const file_name, const int32_t level_num) M_LoadAnimatedTextures(file); M_LoadItems(file); - g_LevelFileDepthQOffset = VFile_GetPos(file); - Level_LoadDepthQ(file); + M_LoadDepthQ(file); M_LoadCinematic(file); M_LoadDemo(file); M_LoadSamples(file); @@ -910,6 +872,8 @@ static void M_CompleteSetup(void) Item_Initialise(i); } + Render_Reset(RENDER_RESET_PALETTE | RENDER_RESET_TEXTURES); + Benchmark_End(benchmark, NULL); } diff --git a/src/tr2/game/level.h b/src/tr2/game/level.h index a79a15279..de1d2a692 100644 --- a/src/tr2/game/level.h +++ b/src/tr2/game/level.h @@ -4,8 +4,4 @@ #include -void __cdecl Level_LoadPalettes(VFILE *file); -void __cdecl Level_LoadTexturePages(VFILE *file); -void __cdecl Level_LoadDepthQ(VFILE *file); - bool __cdecl Level_Load(const char *file_name, int32_t level_num); diff --git a/src/tr2/game/objects/common.c b/src/tr2/game/objects/common.c index d58f9c356..59972d0bc 100644 --- a/src/tr2/game/objects/common.c +++ b/src/tr2/game/objects/common.c @@ -28,7 +28,7 @@ void __cdecl Object_DrawAnimatingItem(const ITEM *item) const OBJECT *const obj = Object_GetObject(item->object_id); if (obj->shadow_size != 0) { - S_PrintShadow(obj->shadow_size, &frames[0]->bounds, item); + Output_InsertShadow(obj->shadow_size, &frames[0]->bounds, item); } Matrix_Push(); diff --git a/src/tr2/game/option/option.c b/src/tr2/game/option/option.c index cd8040f7f..bcdd2f4f3 100644 --- a/src/tr2/game/option/option.c +++ b/src/tr2/game/option/option.c @@ -4,23 +4,23 @@ #include "global/funcs.h" #include "global/vars.h" -void __cdecl Option_DoInventory(INVENTORY_ITEM *const item) +void Option_Control(INVENTORY_ITEM *const item) { switch (item->object_id) { case O_PASSPORT_OPTION: - Option_Passport(item); + Option_Passport_Control(item); break; case O_COMPASS_OPTION: - Option_Compass(item); + Option_Compass_Control(item); break; case O_DETAIL_OPTION: - Option_Detail(item); + Option_Detail_Control(item); break; case O_SOUND_OPTION: - Option_Sound(item); + Option_Sound_Control(item); break; case O_CONTROL_OPTION: - Option_Controls(item); + Option_Controls_Control(item); break; case O_GAMMA_OPTION: break; @@ -65,7 +65,32 @@ void __cdecl Option_DoInventory(INVENTORY_ITEM *const item) } } -void __cdecl Option_ShutdownInventory(INVENTORY_ITEM *const item) +void Option_Draw(INVENTORY_ITEM *const item) +{ + switch (item->object_id) { + case O_PASSPORT_OPTION: + Option_Passport_Draw(item); + break; + case O_COMPASS_OPTION: + Option_Compass_Draw(item); + break; + case O_DETAIL_OPTION: + Option_Detail_Draw(item); + break; + case O_SOUND_OPTION: + Option_Sound_Draw(item); + break; + case O_CONTROL_OPTION: + Option_Controls_Draw(item); + break; + case O_GAMMA_OPTION: + break; + default: + break; + } +} + +void Option_Shutdown(INVENTORY_ITEM *const item) { switch (item->object_id) { case O_PASSPORT_OPTION: diff --git a/src/tr2/game/option/option.h b/src/tr2/game/option/option.h index 79908809f..19016be30 100644 --- a/src/tr2/game/option/option.h +++ b/src/tr2/game/option/option.h @@ -2,24 +2,30 @@ #include "global/types.h" -void __cdecl Option_DoInventory(INVENTORY_ITEM *item); -void __cdecl Option_ShutdownInventory(INVENTORY_ITEM *item); +void Option_Control(INVENTORY_ITEM *item); +void Option_Draw(INVENTORY_ITEM *item); +void Option_Shutdown(INVENTORY_ITEM *item); -void __cdecl Option_Passport(INVENTORY_ITEM *item); -void __cdecl Option_Passport_Shutdown(void); +void Option_Passport_Control(INVENTORY_ITEM *item); +void Option_Passport_Draw(INVENTORY_ITEM *item); +void Option_Passport_Shutdown(void); -void __cdecl Option_Detail(INVENTORY_ITEM *item); -void __cdecl Option_Detail_Shutdown(void); +void Option_Detail_Control(INVENTORY_ITEM *item); +void Option_Detail_Draw(INVENTORY_ITEM *item); +void Option_Detail_Shutdown(void); -void __cdecl Option_Sound(INVENTORY_ITEM *item); -void __cdecl Option_Sound_Shutdown(void); +void Option_Sound_Control(INVENTORY_ITEM *item); +void Option_Sound_Draw(INVENTORY_ITEM *item); +void Option_Sound_Shutdown(void); -void __cdecl Option_Controls_FlashConflicts(void); -void __cdecl Option_Controls_DefaultConflict(void); -void __cdecl Option_Controls(INVENTORY_ITEM *item); -void __cdecl Option_Controls_Shutdown(void); -void __cdecl Option_Controls_ShowControls(void); -void __cdecl Option_Controls_UpdateText(void); +void Option_Controls_FlashConflicts(void); +void Option_Controls_DefaultConflict(void); +void Option_Controls_Control(INVENTORY_ITEM *item); +void Option_Controls_Draw(INVENTORY_ITEM *item); +void Option_Controls_Shutdown(void); +void Option_Controls_ShowControls(void); +void Option_Controls_UpdateText(void); -void __cdecl Option_Compass(INVENTORY_ITEM *item); -void __cdecl Option_Compass_Shutdown(void); +void Option_Compass_Control(INVENTORY_ITEM *item); +void Option_Compass_Draw(INVENTORY_ITEM *item); +void Option_Compass_Shutdown(void); diff --git a/src/tr2/game/option/option_compass.c b/src/tr2/game/option/option_compass.c index eec31063b..39fa20481 100644 --- a/src/tr2/game/option/option_compass.c +++ b/src/tr2/game/option/option_compass.c @@ -8,7 +8,7 @@ #include -void __cdecl Option_Compass(INVENTORY_ITEM *const item) +void Option_Compass_Control(INVENTORY_ITEM *const item) { char buffer[32]; const int32_t sec = g_SaveGame.statistics.timer / FRAMES_PER_SECOND; @@ -28,6 +28,10 @@ void __cdecl Option_Compass(INVENTORY_ITEM *const item) Sound_Effect(SFX_MENU_STOPWATCH, 0, SPM_ALWAYS); } +void Option_Compass_Draw(INVENTORY_ITEM *const item) +{ +} + void Option_Compass_Shutdown(void) { Requester_Shutdown(&g_StatsRequester); diff --git a/src/tr2/game/option/option_controls.c b/src/tr2/game/option/option_controls.c index 0da227020..910818ac7 100644 --- a/src/tr2/game/option/option_controls.c +++ b/src/tr2/game/option/option_controls.c @@ -68,14 +68,13 @@ void Option_Controls_Shutdown(void) M_Shutdown(); } -void __cdecl Option_Controls(INVENTORY_ITEM *const item) +void Option_Controls_Control(INVENTORY_ITEM *const item) { if (m_Dialog == NULL) { M_Init(); } m_Dialog->control(m_Dialog); - m_Dialog->draw(m_Dialog); if (m_Controller.state == UI_CONTROLS_STATE_EXIT) { Option_Controls_Shutdown(); } else { @@ -83,3 +82,10 @@ void __cdecl Option_Controls(INVENTORY_ITEM *const item) g_InputDB = (INPUT_STATE) { 0 }; } } + +void Option_Controls_Draw(INVENTORY_ITEM *const item) +{ + if (m_Dialog != NULL) { + m_Dialog->draw(m_Dialog); + } +} diff --git a/src/tr2/game/option/option_detail.c b/src/tr2/game/option/option_detail.c index b2404f595..fba2779a5 100644 --- a/src/tr2/game/option/option_detail.c +++ b/src/tr2/game/option/option_detail.c @@ -4,7 +4,11 @@ #include "global/funcs.h" #include "global/vars.h" -void __cdecl Option_Detail(INVENTORY_ITEM *const item) +void Option_Detail_Control(INVENTORY_ITEM *const item) +{ +} + +void Option_Detail_Draw(INVENTORY_ITEM *const item) { } diff --git a/src/tr2/game/option/option_passport.c b/src/tr2/game/option/option_passport.c index f65d35b49..0f86ded52 100644 --- a/src/tr2/game/option/option_passport.c +++ b/src/tr2/game/option/option_passport.c @@ -13,7 +13,7 @@ typedef enum { PASSPORT_MODE_SELECT_LEVEL = 2, } PASSPORT_MODE; -void __cdecl Option_Passport(INVENTORY_ITEM *const item) +void Option_Passport_Control(INVENTORY_ITEM *const item) { Text_Remove(g_Inv_ItemText[IT_NAME]); g_Inv_ItemText[IT_NAME] = NULL; @@ -268,6 +268,10 @@ void __cdecl Option_Passport(INVENTORY_ITEM *const item) } } +void Option_Passport_Draw(INVENTORY_ITEM *const item) +{ +} + void Option_Passport_Shutdown(void) { Text_Remove(g_Inv_ItemText[IT_NAME]); diff --git a/src/tr2/game/option/option_sound.c b/src/tr2/game/option/option_sound.c index 3d87b95e4..a502678ab 100644 --- a/src/tr2/game/option/option_sound.c +++ b/src/tr2/game/option/option_sound.c @@ -55,7 +55,7 @@ void Option_Sound_Shutdown(void) M_ShutdownText(); } -void __cdecl Option_Sound(INVENTORY_ITEM *const item) +void Option_Sound_Control(INVENTORY_ITEM *const item) { char text[8]; @@ -125,3 +125,7 @@ void __cdecl Option_Sound(INVENTORY_ITEM *const item) Option_Sound_Shutdown(); } } + +void Option_Sound_Draw(INVENTORY_ITEM *const item) +{ +} diff --git a/src/tr2/game/output.c b/src/tr2/game/output.c index 004ced6dc..333df6568 100644 --- a/src/tr2/game/output.c +++ b/src/tr2/game/output.c @@ -1,309 +1,47 @@ #include "game/output.h" -#include "decomp/decomp.h" -#include "game/hwr.h" +#include "config.h" +#include "game/clock.h" #include "game/math.h" #include "game/matrix.h" +#include "game/render/common.h" +#include "game/render/priv.h" #include "game/shell.h" #include "game/viewport.h" -#include "global/const.h" -#include "global/funcs.h" #include "global/vars.h" -#include -#include #include -#include -#define VBUF_VISIBLE(a, b, c) \ - (((a).ys - (b).ys) * ((c).xs - (b).xs) \ - >= ((c).ys - (b).ys) * ((a).xs - (b).xs)) -#define MAKE_TEX_ID(v, u) ((((v >> 16) & 0xFF) << 8) | ((u >> 16) & 0xFF)) -#define MAKE_Q_ID(g) ((g >> 16) & 0xFF) -#define MAKE_ZSORT(z) ((uint32_t)(z)) - -static bool m_DiscardTransparent = false; - -static D3DCOLOR M_ShadeLight(uint32_t shade); -static D3DCOLOR M_ShadeColor( - uint32_t red, uint32_t green, uint32_t blue, uint8_t alpha); -static D3DCOLOR M_ShadeLightColor( - uint32_t shade, uint32_t red, uint32_t green, uint32_t blue, uint8_t alpha); -static double M_CalculatePolyZ( - SORT_TYPE sort_type, double z0, double z1, double z2, double z3); - -static void __fastcall M_FlatA(int32_t y1, int32_t y2, uint8_t color_idx); -static void __fastcall M_TransA(int32_t y1, int32_t y2, uint8_t depth_q); -static void __fastcall M_GourA(int32_t y1, int32_t y2, uint8_t color_idx); -static void __fastcall M_GTMapA( - int32_t y1, int32_t y2, const uint8_t *tex_page); -static void __fastcall M_WGTMapA( - int32_t y1, int32_t y2, const uint8_t *tex_page); -static inline void M_ClipG( - VERTEX_INFO *const buf, const VERTEX_INFO *const vtx1, - const VERTEX_INFO *const vtx2, const float clip); -static inline void M_ClipGUV( - VERTEX_INFO *const buf, const VERTEX_INFO *const vtx1, - const VERTEX_INFO *const vtx2, const float clip); +static int32_t m_TickComp = 0; static const int16_t *M_CalcRoomVerticesWibble(const int16_t *obj_ptr); -static D3DCOLOR M_ShadeColor( - uint32_t red, uint32_t green, uint32_t blue, uint8_t alpha) +static void M_InsertBar( + int32_t l, int32_t t, int32_t w, int32_t h, int32_t percent, + INV_COLOR bar_color_main, INV_COLOR bar_color_highlight); + +static void M_InsertBar( + const int32_t l, const int32_t t, const int32_t w, const int32_t h, + const int32_t percent, const INV_COLOR bar_color_main, + const INV_COLOR bar_color_highlight) { - if (g_IsShadeEffect) { - red /= 2; - green = green * 7 / 8; - } - return RGBA_MAKE(red, green, blue, alpha); -} + const int32_t z_offset = 8; + Render_InsertFlatRect( + l, t, l + w, t + h, g_PhdNearZ + z_offset * 5, + g_InvColors[INV_COLOR_WHITE]); + Render_InsertFlatRect( + l + 1, t + 1, l + w, t + h, g_PhdNearZ + z_offset * 4, + g_InvColors[INV_COLOR_GRAY]); + Render_InsertFlatRect( + l + 1, t + 1, l + w - 1, t + h - 1, g_PhdNearZ + z_offset * 3, + g_InvColors[INV_COLOR_BLACK]); -static D3DCOLOR M_ShadeLight(uint32_t shade) -{ - uint32_t value = (uint32_t)(0x1FFF - shade) >> 4; - CLAMPG(value, 0xFF); - return M_ShadeColor(value, value, value, 0xFF); -} - -static D3DCOLOR M_ShadeLightColor( - uint32_t shade, uint32_t red, uint32_t green, uint32_t blue, uint8_t alpha) -{ - CLAMPG(shade, 0x1FFF); - shade = 0x1FFF - shade; - red = (red * shade) >> 12; - green = (green * shade) >> 12; - blue = (blue * shade) >> 12; - CLAMPG(red, 0xFF); - CLAMPG(green, 0xFF); - CLAMPG(blue, 0xFF); - return M_ShadeColor(red, green, blue, alpha); -} - -static double M_CalculatePolyZ( - SORT_TYPE sort_type, double z0, double z1, double z2, double z3) -{ - double zv = 0.0; - switch (sort_type) { - case ST_AVG_Z: - zv = (z3 > 0.0) ? (z0 + z1 + z2 + z3) / 4.0 : (z0 + z1 + z2) / 3.0; - break; - - case ST_MAX_Z: - zv = z0; - CLAMPL(zv, z1); - CLAMPL(zv, z2); - if (z3 > 0.0) { - CLAMPL(zv, z3); - } - break; - - case ST_FAR_Z: - default: - zv = 1000000000.0; - break; - } - return zv; -} - -static void __fastcall M_FlatA(int32_t y1, int32_t y2, uint8_t color_idx) -{ - int32_t y_size = y2 - y1; - if (y_size <= 0) { - return; - } - - const int32_t stride = g_PhdScreenWidth; - const XBUF_X *xbuf = (const XBUF_X *)g_XBuffer + y1; - uint8_t *draw_ptr = g_PrintSurfacePtr + y1 * stride; - - while (y_size > 0) { - const int32_t x = xbuf->x1 / PHD_ONE; - const int32_t x_size = (xbuf->x2 / PHD_ONE) - x; - if (x_size > 0) { - memset(draw_ptr + x, color_idx, x_size); - } - y_size--; - xbuf++; - draw_ptr += stride; - } -} - -static void __fastcall M_TransA(int32_t y1, int32_t y2, uint8_t depth_q) -{ - int32_t y_size = y2 - y1; - // TODO: depth_q should be at most 32 here - if (y_size <= 0 || depth_q > 32) { - return; - } - - const int32_t stride = g_PhdScreenWidth; - const XBUF_X *xbuf = (const XBUF_X *)g_XBuffer + y1; - uint8_t *draw_ptr = g_PrintSurfacePtr + y1 * stride; - const DEPTHQ_ENTRY *qt = g_DepthQTable + depth_q; - - while (y_size > 0) { - const int32_t x = xbuf->x1 / PHD_ONE; - int32_t x_size = (xbuf->x2 / PHD_ONE) - x; - if (x_size <= 0) { - goto loop_end; - } - - uint8_t *line_ptr = draw_ptr + x; - while (x_size > 0) { - *line_ptr = qt->index[*line_ptr]; - line_ptr++; - x_size--; - } - - loop_end: - y_size--; - xbuf++; - draw_ptr += stride; - } -} - -static void __fastcall M_GourA(int32_t y1, int32_t y2, uint8_t color_idx) -{ - int32_t y_size = y2 - y1; - if (y_size <= 0) { - return; - } - - const int32_t stride = g_PhdScreenWidth; - const XBUF_XG *xbuf = (const XBUF_XG *)g_XBuffer + y1; - uint8_t *draw_ptr = g_PrintSurfacePtr + y1 * stride; - const GOURAUD_ENTRY *gt = g_GouraudTable + color_idx; - - while (y_size > 0) { - const int32_t x = xbuf->x1 / PHD_ONE; - int32_t x_size = (xbuf->x2 / PHD_ONE) - x; - if (x_size <= 0) { - goto loop_end; - } - - int32_t g = xbuf->g1; - const int32_t g_add = (xbuf->g2 - g) / x_size; - - uint8_t *line_ptr = draw_ptr + x; - while (x_size > 0) { - *line_ptr = gt->index[MAKE_Q_ID(g)]; - line_ptr++; - g += g_add; - x_size--; - } - - loop_end: - y_size--; - xbuf++; - draw_ptr += stride; - } -} - -static void __fastcall M_GTMapA(int32_t y1, int32_t y2, const uint8_t *tex_page) -{ - int32_t y_size = y2 - y1; - if (y_size <= 0) { - return; - } - - const int32_t stride = g_PhdScreenWidth; - const XBUF_XGUV *xbuf = (const XBUF_XGUV *)g_XBuffer + y1; - uint8_t *draw_ptr = g_PrintSurfacePtr + y1 * stride; - - while (y_size > 0) { - const int32_t x = xbuf->x1 / PHD_ONE; - int32_t x_size = (xbuf->x2 / PHD_ONE) - x; - if (x_size <= 0) { - goto loop_end; - } - - int32_t g = xbuf->g1; - int32_t u = xbuf->u1; - int32_t v = xbuf->v1; - const int32_t g_add = (xbuf->g2 - g) / x_size; - const int32_t u_add = (xbuf->u2 - u) / x_size; - const int32_t v_add = (xbuf->v2 - v) / x_size; - - uint8_t *line_ptr = draw_ptr + x; - while (x_size > 0) { - uint8_t color_idx = tex_page[MAKE_TEX_ID(v, u)]; - *line_ptr = g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; - line_ptr++; - g += g_add; - u += u_add; - v += v_add; - x_size--; - } - - loop_end: - y_size--; - xbuf++; - draw_ptr += stride; - } -} - -static void __fastcall M_WGTMapA( - int32_t y1, int32_t y2, const uint8_t *tex_page) -{ - int32_t y_size = y2 - y1; - if (y_size <= 0) { - return; - } - - const int32_t stride = g_PhdScreenWidth; - const XBUF_XGUV *xbuf = (const XBUF_XGUV *)g_XBuffer + y1; - uint8_t *draw_ptr = g_PrintSurfacePtr + y1 * stride; - - while (y_size > 0) { - const int32_t x = xbuf->x1 / PHD_ONE; - int32_t x_size = (xbuf->x2 / PHD_ONE) - x; - if (x_size <= 0) { - goto loop_end; - } - - int32_t g = xbuf->g1; - int32_t u = xbuf->u1; - int32_t v = xbuf->v1; - const int32_t g_add = (xbuf->g2 - g) / x_size; - const int32_t u_add = (xbuf->u2 - u) / x_size; - const int32_t v_add = (xbuf->v2 - v) / x_size; - - uint8_t *line_ptr = draw_ptr + x; - while (x_size > 0) { - const uint8_t color_idx = tex_page[MAKE_TEX_ID(v, u)]; - if (color_idx != 0) { - *line_ptr = g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; - } - line_ptr++; - g += g_add; - u += u_add; - v += v_add; - x_size--; - } - - loop_end: - y_size--; - xbuf++; - draw_ptr += stride; - } -} - -static inline void M_ClipG( - VERTEX_INFO *const buf, const VERTEX_INFO *const vtx1, - const VERTEX_INFO *const vtx2, const float clip) -{ - buf->rhw = vtx2->rhw + (vtx1->rhw - vtx2->rhw) * clip; - buf->g = vtx2->g + (vtx1->g - vtx2->g) * clip; -} - -static inline void M_ClipGUV( - VERTEX_INFO *const buf, const VERTEX_INFO *const vtx1, - const VERTEX_INFO *const vtx2, const float clip) -{ - buf->rhw = vtx2->rhw + (vtx1->rhw - vtx2->rhw) * clip; - buf->g = vtx2->g + (vtx1->g - vtx2->g) * clip; - buf->u = vtx2->u + (vtx1->u - vtx2->u) * clip; - buf->v = vtx2->v + (vtx1->v - vtx2->v) * clip; + Render_InsertFlatRect( + l + 2, t + 2, l + (w - 2) * percent / 100, t + h - 2, + g_PhdNearZ + z_offset * 2, g_InvColors[bar_color_main]); + Render_InsertFlatRect( + l + 2, t + 3, l + (w - 2) * percent / 100, t + 4, + g_PhdNearZ + z_offset * 1, g_InvColors[bar_color_highlight]); } static const int16_t *M_CalcRoomVerticesWibble(const int16_t *obj_ptr) @@ -347,75 +85,22 @@ static const int16_t *M_CalcRoomVerticesWibble(const int16_t *obj_ptr) return obj_ptr; } -void __cdecl Output_Init( - int16_t x, int16_t y, int32_t width, int32_t height, int32_t near_z, - int32_t far_z, int16_t view_angle, int32_t screen_width, - int32_t screen_height) -{ - Viewport_Init( - x, y, width, height, near_z, far_z, view_angle * PHD_DEGREE, - screen_width, screen_height); - - g_MatrixPtr = g_MatrixStack; - - switch (g_SavedAppSettings.render_mode) { - case RM_SOFTWARE: - g_PerspectiveDistance = g_SavedAppSettings.perspective_correct - ? SW_DETAIL_HIGH - : SW_DETAIL_MEDIUM; - g_Output_DrawObjectGT3 = Output_InsertObjectGT3; - g_Output_DrawObjectGT4 = Output_InsertObjectGT4; - g_Output_DrawObjectG3 = Output_InsertObjectG3; - g_Output_DrawObjectG4 = Output_InsertObjectG4; - g_Output_InsertSprite = Output_InsertSprite; - g_Output_InsertFlatRect = Output_InsertFlatRect; - g_Output_InsertLine = Output_InsertLine; - g_Output_InsertTrans8 = Output_InsertTrans8; - g_Output_InsertTransQuad = Output_InsertTransQuad; - break; - - case RM_HARDWARE: - if (g_SavedAppSettings.zbuffer) { - g_Output_DrawObjectGT3 = Output_InsertObjectGT3_ZBuffered; - g_Output_DrawObjectGT4 = Output_InsertObjectGT4_ZBuffered; - g_Output_DrawObjectG3 = Output_InsertObjectG3_ZBuffered; - g_Output_DrawObjectG4 = Output_InsertObjectG4_ZBuffered; - g_Output_InsertFlatRect = Output_InsertFlatRect_ZBuffered; - g_Output_InsertLine = Output_InsertLine_ZBuffered; - } else { - g_Output_DrawObjectGT3 = Output_InsertObjectGT3_Sorted; - g_Output_DrawObjectGT4 = Output_InsertObjectGT4_Sorted; - g_Output_DrawObjectG3 = Output_InsertObjectG3_Sorted; - g_Output_DrawObjectG4 = Output_InsertObjectG4_Sorted; - g_Output_InsertFlatRect = Output_InsertFlatRect_Sorted; - g_Output_InsertLine = Output_InsertLine_Sorted; - } - g_Output_InsertSprite = Output_InsertSprite_Sorted; - g_Output_InsertTrans8 = Output_InsertTrans8_Sorted; - g_Output_InsertTransQuad = Output_InsertTransQuad_Sorted; - break; - - default: - Shell_ExitSystem("unknown render mode"); - } -} - void __cdecl Output_InsertPolygons(const int16_t *obj_ptr, const int32_t clip) { - g_FltWinLeft = g_PhdWinMinX; - g_FltWinTop = g_PhdWinMinY; - g_FltWinRight = g_PhdWinMinX + g_PhdWinMaxX + 1; - g_FltWinBottom = g_PhdWinMinY + g_PhdWinMaxY + 1; - g_FltWinCenterX = g_PhdWinMinX + g_PhdWinCenterX; - g_FltWinCenterY = g_PhdWinMinY + g_PhdWinCenterY; + g_FltWinLeft = 0.0f; + g_FltWinTop = 0.0f; + g_FltWinRight = g_PhdWinMaxX + 1; + g_FltWinBottom = g_PhdWinMaxY + 1; + g_FltWinCenterX = g_PhdWinCenterX; + g_FltWinCenterY = g_PhdWinCenterY; obj_ptr = Output_CalcObjectVertices(obj_ptr + 4); if (obj_ptr) { obj_ptr = Output_CalcVerticeLight(obj_ptr); - obj_ptr = g_Output_DrawObjectGT4(obj_ptr + 1, *obj_ptr, ST_AVG_Z); - obj_ptr = g_Output_DrawObjectGT3(obj_ptr + 1, *obj_ptr, ST_AVG_Z); - obj_ptr = g_Output_DrawObjectG4(obj_ptr + 1, *obj_ptr, ST_AVG_Z); - obj_ptr = g_Output_DrawObjectG3(obj_ptr + 1, *obj_ptr, ST_AVG_Z); + obj_ptr = Render_InsertObjectGT4(obj_ptr + 1, *obj_ptr, ST_AVG_Z); + obj_ptr = Render_InsertObjectGT3(obj_ptr + 1, *obj_ptr, ST_AVG_Z); + obj_ptr = Render_InsertObjectG4(obj_ptr + 1, *obj_ptr, ST_AVG_Z); + obj_ptr = Render_InsertObjectG3(obj_ptr + 1, *obj_ptr, ST_AVG_Z); } } @@ -430,67 +115,58 @@ void __cdecl Output_InsertPolygons_I( void __cdecl Output_InsertRoom(const int16_t *obj_ptr, int32_t is_outside) { - g_FltWinLeft = g_PhdWinMinX + g_PhdWinLeft; - g_FltWinTop = g_PhdWinMinY + g_PhdWinTop; - g_FltWinRight = g_PhdWinMinX + g_PhdWinRight + 1; - g_FltWinBottom = g_PhdWinMinY + g_PhdWinBottom + 1; - g_FltWinCenterX = g_PhdWinMinX + g_PhdWinCenterX; - g_FltWinCenterY = g_PhdWinMinY + g_PhdWinCenterY; + g_FltWinLeft = g_PhdWinLeft; + g_FltWinTop = g_PhdWinTop; + g_FltWinRight = g_PhdWinRight + 1; + g_FltWinBottom = g_PhdWinBottom + 1; + g_FltWinCenterX = g_PhdWinCenterX; + g_FltWinCenterY = g_PhdWinCenterY; const int16_t *const old_obj_ptr = obj_ptr; obj_ptr = Output_CalcRoomVertices(obj_ptr, is_outside ? 0 : 16); if (g_IsWibbleEffect) { - if (g_SavedAppSettings.render_mode == RM_HARDWARE) { - HWR_EnableZBuffer(false, true); - } - m_DiscardTransparent = true; - obj_ptr = g_Output_DrawObjectGT4(obj_ptr + 1, *obj_ptr, ST_MAX_Z); - obj_ptr = g_Output_DrawObjectGT3(obj_ptr + 1, *obj_ptr, ST_MAX_Z); - m_DiscardTransparent = false; + Render_EnableZBuffer(false, true); + g_DiscardTransparent = true; + obj_ptr = Render_InsertObjectGT4(obj_ptr + 1, *obj_ptr, ST_MAX_Z); + obj_ptr = Render_InsertObjectGT3(obj_ptr + 1, *obj_ptr, ST_MAX_Z); + g_DiscardTransparent = false; obj_ptr = M_CalcRoomVerticesWibble(old_obj_ptr); - if (g_SavedAppSettings.render_mode == RM_HARDWARE) { - HWR_EnableZBuffer(true, true); - } + Render_EnableZBuffer(true, true); } - obj_ptr = g_Output_DrawObjectGT4(obj_ptr + 1, *obj_ptr, ST_MAX_Z); - obj_ptr = g_Output_DrawObjectGT3(obj_ptr + 1, *obj_ptr, ST_MAX_Z); + obj_ptr = Render_InsertObjectGT4(obj_ptr + 1, *obj_ptr, ST_MAX_Z); + obj_ptr = Render_InsertObjectGT3(obj_ptr + 1, *obj_ptr, ST_MAX_Z); Output_InsertRoomSprite(obj_ptr + 1, *obj_ptr); } void __cdecl Output_InsertSkybox(const int16_t *obj_ptr) { - g_FltWinLeft = g_PhdWinMinX + g_PhdWinLeft; - g_FltWinTop = g_PhdWinMinY + g_PhdWinTop; - g_FltWinRight = g_PhdWinMinX + g_PhdWinRight + 1; - g_FltWinBottom = g_PhdWinMinY + g_PhdWinBottom + 1; - g_FltWinCenterX = g_PhdWinMinX + g_PhdWinCenterX; - g_FltWinCenterY = g_PhdWinMinY + g_PhdWinCenterY; + g_FltWinLeft = g_PhdWinLeft; + g_FltWinTop = g_PhdWinTop; + g_FltWinRight = g_PhdWinRight + 1; + g_FltWinBottom = g_PhdWinBottom + 1; + g_FltWinCenterX = g_PhdWinCenterX; + g_FltWinCenterY = g_PhdWinCenterY; obj_ptr = Output_CalcObjectVertices(obj_ptr + 4); if (obj_ptr) { - if (g_SavedAppSettings.render_mode == RM_HARDWARE) { - HWR_EnableZBuffer(false, false); - } - + Render_EnableZBuffer(false, false); obj_ptr = Output_CalcSkyboxLight(obj_ptr); - obj_ptr = g_Output_DrawObjectGT4(obj_ptr + 1, *obj_ptr, ST_FAR_Z); - obj_ptr = g_Output_DrawObjectGT3(obj_ptr + 1, *obj_ptr, ST_FAR_Z); - obj_ptr = g_Output_DrawObjectG4(obj_ptr + 1, *obj_ptr, ST_FAR_Z); - obj_ptr = g_Output_DrawObjectG3(obj_ptr + 1, *obj_ptr, ST_FAR_Z); - - if (g_SavedAppSettings.render_mode == RM_HARDWARE) { - HWR_EnableZBuffer(true, true); - } + obj_ptr = Render_InsertObjectGT4(obj_ptr + 1, *obj_ptr, ST_FAR_Z); + obj_ptr = Render_InsertObjectGT3(obj_ptr + 1, *obj_ptr, ST_FAR_Z); + obj_ptr = Render_InsertObjectG4(obj_ptr + 1, *obj_ptr, ST_FAR_Z); + obj_ptr = Render_InsertObjectG3(obj_ptr + 1, *obj_ptr, ST_FAR_Z); + Render_EnableZBuffer(true, true); } } const int16_t *__cdecl Output_CalcObjectVertices(const int16_t *obj_ptr) { - const double base_z = - g_SavedAppSettings.zbuffer ? 0.0 : (g_MidSort << (W2V_SHIFT + 8)); + const double base_z = g_Config.rendering.enable_zbuffer + ? 0.0 + : (g_MidSort << (W2V_SHIFT + 8)); uint8_t total_clip = 0xFF; obj_ptr++; // skip poly counter @@ -529,10 +205,8 @@ const int16_t *__cdecl Output_CalcObjectVertices(const int16_t *obj_ptr) vbuf->zv = zv; clip_flags = 0x80; } else { - if (zv >= g_FltFarZ) { - zv = g_FltFarZ; - vbuf->zv = zv; + vbuf->zv = g_FltFarZ; } else { vbuf->zv = zv + base_z; } @@ -637,8 +311,9 @@ const int16_t *__cdecl Output_CalcVerticeLight(const int16_t *obj_ptr) const int16_t *__cdecl Output_CalcRoomVertices( const int16_t *obj_ptr, int32_t far_clip) { - const double base_z = - g_ZBufferSurface ? 0.0 : (g_MidSort << (W2V_SHIFT + 8)); + const double base_z = g_Config.rendering.enable_zbuffer + ? 0.0 + : (g_MidSort << (W2V_SHIFT + 8)); const int32_t vtx_count = *obj_ptr++; for (int32_t i = 0; i < vtx_count; i++) { @@ -693,10 +368,10 @@ const int16_t *__cdecl Output_CalcRoomVertices( } vbuf->rhw = persp * g_FltRhwOPersp; } else { - clip_flags = far_clip; + // clip_flags = far_clip; shade = 0x1FFF; vbuf->zv = g_FltFarZ; - vbuf->rhw = 0.0; // *(int32_t*)0x00478054 + vbuf->rhw = persp * g_FltRhwOPersp; } double xs = xv * persp + g_FltWinCenterX; @@ -716,7 +391,7 @@ const int16_t *__cdecl Output_CalcRoomVertices( vbuf->xs = xs; vbuf->ys = ys; - clip_flags |= (~((uint8_t)(vbuf->zv / 0x155555.p0))) << 8; + // clip_flags |= (~((uint8_t)(vbuf->zv / 0x155555.p0))) << 8; } CLAMP(shade, 0, 0x1FFF); @@ -748,3335 +423,11 @@ void __cdecl Output_RotateLight(int16_t pitch, int16_t yaw) g_LsVectorView.z = (m->_20 * x + m->_21 * y + m->_22 * z) >> W2V_SHIFT; } -void __cdecl Output_InitPolyList(void) -{ - g_SurfaceCount = 0; - g_Sort3DPtr = g_SortBuffer; - g_Info3DPtr = g_Info3DBuffer; - if (g_SavedAppSettings.render_mode != RM_SOFTWARE) { - g_HWR_VertexPtr = g_HWR_VertexBuffer; - } -} - -void __cdecl Output_SortPolyList(void) -{ - if (g_SurfaceCount) { - for (int32_t i = 0; i < g_SurfaceCount; i++) { - g_SortBuffer[i]._1 += i; - } - Output_QuickSort(0, g_SurfaceCount - 1); - } -} - -void __cdecl Output_QuickSort(int32_t left, int32_t right) -{ - int32_t compare = g_SortBuffer[(left + right) / 2]._1; - int32_t i = left; - int32_t j = right; - - do { - while ((i < right) && (g_SortBuffer[i]._1 > compare)) { - i++; - } - while ((left < j) && (compare > g_SortBuffer[j]._1)) { - j--; - } - if (i > j) { - break; - } - - SORT_ITEM tmp_item; - SWAP(g_SortBuffer[i], g_SortBuffer[j], tmp_item); - - i++; - j--; - } while (i <= j); - - if (left < j) { - Output_QuickSort(left, j); - } - if (i < right) { - Output_QuickSort(i, right); - } -} - -void __cdecl Output_PrintPolyList(uint8_t *surface_ptr) -{ - g_PrintSurfacePtr = surface_ptr; - - for (int32_t i = 0; i < g_SurfaceCount; i++) { - const int16_t *obj_ptr = (const int16_t *)g_SortBuffer[i]._0; - const int16_t poly_type = *obj_ptr++; - g_PolyDrawRoutines[poly_type](obj_ptr); - } -} - void __cdecl Output_AlterFOV(int16_t fov) { Viewport_AlterFOV(fov); } -void __cdecl Output_DrawPolyLine(const int16_t *obj_ptr) -{ - int32_t x1 = *obj_ptr++; - int32_t y1 = *obj_ptr++; - int32_t x2 = *obj_ptr++; - int32_t y2 = *obj_ptr++; - uint8_t lcolor = (uint8_t)*obj_ptr; - - if (x2 < x1) { - int32_t tmp; - SWAP(x1, x2, tmp); - SWAP(y1, y2, tmp); - } - - if (x2 < 0 || x1 > g_PhdWinMaxX) { - return; - } - - if (x1 < 0) { - y1 -= x1 * (y2 - y1) / (x2 - x1); - x1 = 0; - } - - if (x2 > g_PhdWinMaxX) { - y2 = y1 + (y2 - y1) * (g_PhdWinMaxX - x1) / (x2 - x1); - x2 = g_PhdWinMaxX; - } - - if (y2 < y1) { - int32_t tmp; - SWAP(x1, x2, tmp); - SWAP(y1, y2, tmp); - } - - if (y2 < 0 || y1 > g_PhdWinMaxY) { - return; - } - - if (y1 < 0) { - x1 -= y1 * (x2 - x1) / (y2 - y1); - y1 = 0; - } - - if (y2 > g_PhdWinMaxY) { - x2 = x1 + (x2 - x1) * (g_PhdWinMaxY - y1) / (y2 - y1); - y2 = g_PhdWinMaxY; - } - - int32_t x_size = x2 - x1; - int32_t y_size = y2 - y1; - uint8_t *draw_ptr = &g_PrintSurfacePtr[x1 + g_PhdScreenWidth * y1]; - - if (!x_size && !y_size) { - *draw_ptr = lcolor; - return; - } - - int32_t x_add = 0; - if (x_size < 0) { - x_add = -1; - x_size = -x_size; - } else { - x_add = 1; - } - - int32_t y_add; - if (y_size < 0) { - y_add = -g_PhdScreenWidth; - y_size = -y_size; - } else { - y_add = g_PhdScreenWidth; - } - - int32_t col_add; - int32_t row_add; - int32_t cols; - int32_t rows; - if (x_size >= y_size) { - col_add = x_add; - row_add = y_add; - cols = x_size + 1; - rows = y_size + 1; - } else { - col_add = y_add; - row_add = x_add; - cols = y_size + 1; - rows = x_size + 1; - } - - int32_t part_sum = 0; - int32_t part = PHD_ONE * rows / cols; - for (int32_t i = 0; i < cols; i++) { - part_sum += part; - *draw_ptr = lcolor; - draw_ptr += col_add; - if (part_sum >= PHD_ONE) { - draw_ptr += row_add; - part_sum -= PHD_ONE; - } - } -} - -void __cdecl Output_DrawPolyFlat(const int16_t *obj_ptr) -{ - if (Output_XGenX(obj_ptr + 1)) { - M_FlatA(g_XGenY1, g_XGenY2, *obj_ptr); - } -} - -void __cdecl Output_DrawPolyTrans(const int16_t *obj_ptr) -{ - if (Output_XGenX(obj_ptr + 1)) { - M_TransA(g_XGenY1, g_XGenY2, *obj_ptr); - } -} - -void __cdecl Output_DrawPolyGouraud(const int16_t *obj_ptr) -{ - if (Output_XGenXG(obj_ptr + 1)) { - M_GourA(g_XGenY1, g_XGenY2, *obj_ptr); - } -} - -void __cdecl Output_DrawPolyGTMap(const int16_t *obj_ptr) -{ - if (Output_XGenXGUV(obj_ptr + 1)) { - M_GTMapA(g_XGenY1, g_XGenY2, g_TexturePageBuffer8[*obj_ptr]); - } -} - -void __cdecl Output_DrawPolyWGTMap(const int16_t *obj_ptr) -{ - if (Output_XGenXGUV(obj_ptr + 1)) { - M_WGTMapA(g_XGenY1, g_XGenY2, g_TexturePageBuffer8[*obj_ptr]); - } -} - -void __cdecl Output_DrawPolyGTMapPersp(const int16_t *obj_ptr) -{ - if (Output_XGenXGUVPerspFP(obj_ptr + 1)) { - Output_GTMapPersp32FP( - g_XGenY1, g_XGenY2, g_TexturePageBuffer8[*obj_ptr]); - } -} - -void __cdecl Output_DrawPolyWGTMapPersp(const int16_t *obj_ptr) -{ - if (Output_XGenXGUVPerspFP(obj_ptr + 1)) { - Output_WGTMapPersp32FP( - g_XGenY1, g_XGenY2, g_TexturePageBuffer8[*obj_ptr]); - } -} - -int32_t __cdecl Output_XGenX(const int16_t *obj_ptr) -{ - int32_t pt_count = *obj_ptr++; - const XGEN_X *pt2 = (const XGEN_X *)obj_ptr; - const XGEN_X *pt1 = pt2 + (pt_count - 1); - - int32_t y_min = pt1->y; - int32_t y_max = pt1->y; - - while (pt_count--) { - const int32_t x1 = pt1->x; - const int32_t y1 = pt1->y; - const int32_t x2 = pt2->x; - const int32_t y2 = pt2->y; - pt1 = pt2++; - - if (y1 < y2) { - CLAMPG(y_min, y1); - const int32_t x_size = x2 - x1; - int32_t y_size = y2 - y1; - - XBUF_X *x_ptr = (XBUF_X *)g_XBuffer + y1; - const int32_t x_add = PHD_ONE * x_size / y_size; - int32_t x = x1 * PHD_ONE + (PHD_ONE - 1); - - while (y_size--) { - x += x_add; - x_ptr->x2 = x; - x_ptr++; - } - } else if (y2 < y1) { - CLAMPL(y_max, y1); - const int32_t x_size = x1 - x2; - int32_t y_size = y1 - y2; - - XBUF_X *x_ptr = (XBUF_X *)g_XBuffer + y2; - const int32_t x_add = PHD_ONE * x_size / y_size; - int32_t x = x2 * PHD_ONE + 1; - - while (y_size--) { - x += x_add; - x_ptr->x1 = x; - x_ptr++; - } - } - } - - if (y_min == y_max) { - return 0; - } - - g_XGenY1 = y_min; - g_XGenY2 = y_max; - return 1; -} - -int32_t __cdecl Output_XGenXG(const int16_t *obj_ptr) -{ - int32_t pt_count = *obj_ptr++; - const XGEN_XG *pt2 = (const XGEN_XG *)obj_ptr; - const XGEN_XG *pt1 = pt2 + (pt_count - 1); - - int32_t y_min = pt1->y; - int32_t y_max = pt1->y; - - while (pt_count--) { - const int32_t x1 = pt1->x; - const int32_t y1 = pt1->y; - const int32_t g1 = pt1->g; - const int32_t x2 = pt2->x; - const int32_t y2 = pt2->y; - const int32_t g2 = pt2->g; - pt1 = pt2++; - - if (y1 < y2) { - CLAMPG(y_min, y1); - const int32_t g_size = g2 - g1; - const int32_t x_size = x2 - x1; - int32_t y_size = y2 - y1; - - XBUF_XG *xg_ptr = (XBUF_XG *)g_XBuffer + y1; - const int32_t x_add = PHD_ONE * x_size / y_size; - const int32_t g_add = PHD_HALF * g_size / y_size; - int32_t x = x1 * PHD_ONE + (PHD_ONE - 1); - int32_t g = g1 * PHD_HALF; - - while (y_size--) { - x += x_add; - g += g_add; - xg_ptr->x2 = x; - xg_ptr->g2 = g; - xg_ptr++; - } - } else if (y2 < y1) { - CLAMPL(y_max, y1); - const int32_t g_size = g1 - g2; - const int32_t x_size = x1 - x2; - int32_t y_size = y1 - y2; - - XBUF_XG *xg_ptr = (XBUF_XG *)g_XBuffer + y2; - const int32_t x_add = PHD_ONE * x_size / y_size; - const int32_t g_add = PHD_HALF * g_size / y_size; - int32_t x = x2 * PHD_ONE + 1; - int32_t g = g2 * PHD_HALF; - - while (y_size--) { - x += x_add; - g += g_add; - xg_ptr->x1 = x; - xg_ptr->g1 = g; - xg_ptr++; - } - } - } - - if (y_min == y_max) { - return 0; - } - - g_XGenY1 = y_min; - g_XGenY2 = y_max; - return 1; -} - -int32_t __cdecl Output_XGenXGUV(const int16_t *obj_ptr) -{ - int32_t pt_count = *obj_ptr++; - const XGEN_XGUV *pt2 = (const XGEN_XGUV *)obj_ptr; - const XGEN_XGUV *pt1 = pt2 + (pt_count - 1); - - int32_t y_min = pt1->y; - int32_t y_max = pt1->y; - - while (pt_count--) { - const int32_t x1 = pt1->x; - const int32_t y1 = pt1->y; - const int32_t g1 = pt1->g; - const int32_t u1 = pt1->u; - const int32_t v1 = pt1->v; - const int32_t x2 = pt2->x; - const int32_t y2 = pt2->y; - const int32_t g2 = pt2->g; - const int32_t u2 = pt2->u; - const int32_t v2 = pt2->v; - pt1 = pt2++; - - if (y1 < y2) { - CLAMPG(y_min, y1); - const int32_t g_size = g2 - g1; - const int32_t u_size = u2 - u1; - const int32_t v_size = v2 - v1; - const int32_t x_size = x2 - x1; - int32_t y_size = y2 - y1; - - XBUF_XGUV *xguv_ptr = (XBUF_XGUV *)g_XBuffer + y1; - const int32_t x_add = PHD_ONE * x_size / y_size; - const int32_t g_add = PHD_HALF * g_size / y_size; - const int32_t u_add = PHD_HALF * u_size / y_size; - const int32_t v_add = PHD_HALF * v_size / y_size; - int32_t x = x1 * PHD_ONE + (PHD_ONE - 1); - int32_t g = g1 * PHD_HALF; - int32_t u = u1 * PHD_HALF; - int32_t v = v1 * PHD_HALF; - - while (y_size--) { - x += x_add; - g += g_add; - u += u_add; - v += v_add; - xguv_ptr->x2 = x; - xguv_ptr->g2 = g; - xguv_ptr->u2 = u; - xguv_ptr->v2 = v; - xguv_ptr++; - } - } else if (y2 < y1) { - CLAMPL(y_max, y1); - const int32_t g_size = g1 - g2; - const int32_t u_size = u1 - u2; - const int32_t v_size = v1 - v2; - const int32_t x_size = x1 - x2; - int32_t y_size = y1 - y2; - - XBUF_XGUV *xguv_ptr = (XBUF_XGUV *)g_XBuffer + y2; - const int32_t x_add = PHD_ONE * x_size / y_size; - const int32_t g_add = PHD_HALF * g_size / y_size; - const int32_t u_add = PHD_HALF * u_size / y_size; - const int32_t v_add = PHD_HALF * v_size / y_size; - int32_t x = x2 * PHD_ONE + 1; - int32_t g = g2 * PHD_HALF; - int32_t u = u2 * PHD_HALF; - int32_t v = v2 * PHD_HALF; - - while (y_size--) { - x += x_add; - g += g_add; - u += u_add; - v += v_add; - xguv_ptr->x1 = x; - xguv_ptr->g1 = g; - xguv_ptr->u1 = u; - xguv_ptr->v1 = v; - xguv_ptr++; - } - } - } - - if (y_min == y_max) { - return 0; - } - - g_XGenY1 = y_min; - g_XGenY2 = y_max; - return 1; -} - -int32_t __cdecl Output_XGenXGUVPerspFP(const int16_t *obj_ptr) -{ - int32_t pt_count = *obj_ptr++; - const XGEN_XGUVP *pt2 = (const XGEN_XGUVP *)obj_ptr; - const XGEN_XGUVP *pt1 = pt2 + (pt_count - 1); - - int32_t y_min = pt1->y; - int32_t y_max = pt1->y; - - while (pt_count--) { - const int32_t x1 = pt1->x; - const int32_t y1 = pt1->y; - const int32_t g1 = pt1->g; - const float u1 = pt1->u; - const float v1 = pt1->v; - - const float rhw1 = pt1->rhw; - const int32_t x2 = pt2->x; - const int32_t y2 = pt2->y; - const int32_t g2 = pt2->g; - const float u2 = pt2->u; - const float v2 = pt2->v; - const float rhw2 = pt2->rhw; - - pt1 = pt2++; - - if (y1 < y2) { - CLAMPG(y_min, y1); - const int32_t g_size = g2 - g1; - const float u_size = u2 - u1; - const float v_size = v2 - v1; - const float rhw_size = rhw2 - rhw1; - const int32_t x_size = x2 - x1; - int32_t y_size = y2 - y1; - - XBUF_XGUVP *xguv_ptr = (XBUF_XGUVP *)g_XBuffer + y1; - const int32_t x_add = PHD_ONE * x_size / y_size; - const int32_t g_add = PHD_HALF * g_size / y_size; - const float u_add = u_size / (float)y_size; - const float v_add = v_size / (float)y_size; - const float rhw_add = rhw_size / (float)y_size; - int32_t x = x1 * PHD_ONE + (PHD_ONE - 1); - int32_t g = g1 * PHD_HALF; - float u = u1; - float v = v1; - float rhw = rhw1; - - while (y_size--) { - x += x_add; - g += g_add; - u += u_add; - v += v_add; - rhw += rhw_add; - xguv_ptr->x2 = x; - xguv_ptr->g2 = g; - xguv_ptr->u2 = u; - xguv_ptr->v2 = v; - xguv_ptr->rhw2 = rhw; - xguv_ptr++; - } - } else if (y2 < y1) { - CLAMPL(y_max, y1); - const int32_t g_size = g1 - g2; - const float u_size = u1 - u2; - const float v_size = v1 - v2; - const float rhw_size = rhw1 - rhw2; - const int32_t x_size = x1 - x2; - int32_t y_size = y1 - y2; - - XBUF_XGUVP *xguv_ptr = (XBUF_XGUVP *)g_XBuffer + y2; - const int32_t x_add = PHD_ONE * x_size / y_size; - const int32_t g_add = PHD_HALF * g_size / y_size; - const float u_add = u_size / (float)y_size; - const float v_add = v_size / (float)y_size; - const float rhw_add = rhw_size / (float)y_size; - int32_t x = x2 * PHD_ONE + 1; - int32_t g = g2 * PHD_HALF; - float u = u2; - float v = v2; - float rhw = rhw2; - - while (y_size--) { - x += x_add; - g += g_add; - u += u_add; - v += v_add; - rhw += rhw_add; - xguv_ptr->x1 = x; - xguv_ptr->g1 = g; - xguv_ptr->u1 = u; - xguv_ptr->v1 = v; - xguv_ptr->rhw1 = rhw; - xguv_ptr++; - } - } - } - - if (y_min == y_max) { - return 0; - } - - g_XGenY1 = y_min; - g_XGenY2 = y_max; - return 1; -} - -void __cdecl Output_GTMapPersp32FP( - const int32_t y1, const int32_t y2, const uint8_t *const tex_page) -{ - int32_t y_size = y2 - y1; - if (y_size <= 0) { - return; - } - - const int32_t stride = g_PhdScreenWidth; - const XBUF_XGUVP *xbuf = (const XBUF_XGUVP *)g_XBuffer + y1; - uint8_t *draw_ptr = g_PrintSurfacePtr + y1 * stride; - - while (y_size > 0) { - const int32_t x = xbuf->x1 / PHD_ONE; - int32_t x_size = (xbuf->x2 / PHD_ONE) - x; - if (x_size <= 0) { - goto loop_end; - } - - int32_t g = xbuf->g1; - double u = xbuf->u1; - double v = xbuf->v1; - double rhw = xbuf->rhw1; - - const int32_t g_add = (xbuf->g2 - g) / x_size; - - int32_t u0 = PHD_HALF * u / rhw; - int32_t v0 = PHD_HALF * v / rhw; - - uint8_t *line_ptr = draw_ptr + x; - int32_t batch_size = 32; - - if (x_size >= batch_size) { - const double u_add = - (xbuf->u2 - u) / (double)x_size * (double)batch_size; - const double v_add = - (xbuf->v2 - v) / (double)x_size * (double)batch_size; - const double rhw_add = - (xbuf->rhw2 - rhw) / (double)x_size * (double)batch_size; - - while (x_size >= batch_size) { - u += u_add; - v += v_add; - rhw += rhw_add; - - const int32_t u1 = PHD_HALF * u / rhw; - const int32_t v1 = PHD_HALF * v / rhw; - - const int32_t u0_add = (u1 - u0) / batch_size; - const int32_t v0_add = (v1 - v0) / batch_size; - - if ((ABS(u0_add) + ABS(v0_add)) < (PHD_ONE / 2)) { - int32_t batch_counter = batch_size / 2; - while (batch_counter--) { - const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; - const uint8_t color = - g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; - *line_ptr++ = color; - *line_ptr++ = color; - g += g_add * 2; - u0 += u0_add * 2; - v0 += v0_add * 2; - } - } else { - int32_t batch_counter = batch_size; - while (batch_counter--) { - const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; - const uint8_t color = - g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; - *line_ptr++ = color; - g += g_add; - u0 += u0_add; - v0 += v0_add; - } - } - - u0 = u1; - v0 = v1; - x_size -= batch_size; - } - } - - if (x_size > 1) { - const int32_t u1 = PHD_HALF * xbuf->u2 / xbuf->rhw2; - const int32_t v1 = PHD_HALF * xbuf->v2 / xbuf->rhw2; - const int32_t u0_add = (u1 - u0) / x_size; - const int32_t v0_add = (v1 - v0) / x_size; - - batch_size = x_size & ~1; - x_size -= batch_size; - - if ((ABS(u0_add) + ABS(v0_add)) < (PHD_ONE / 2)) { - int32_t batch_counter = batch_size / 2; - while (batch_counter--) { - const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; - const uint8_t color = - g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; - *line_ptr++ = color; - *line_ptr++ = color; - g += g_add * 2; - u0 += u0_add * 2; - v0 += v0_add * 2; - } - } else { - int32_t batch_counter = batch_size; - while (batch_counter--) { - const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; - const uint8_t color = - g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; - *line_ptr++ = color; - g += g_add; - u0 += u0_add; - v0 += v0_add; - } - } - } - - if (x_size == 1) { - const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; - const uint8_t color = g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; - *line_ptr = color; - } - - loop_end: - y_size--; - xbuf++; - draw_ptr += stride; - } -} - -void __cdecl Output_WGTMapPersp32FP( - int32_t y1, int32_t y2, const uint8_t *const tex_page) -{ - int32_t y_size = y2 - y1; - if (y_size <= 0) { - return; - } - - const int32_t stride = g_PhdScreenWidth; - const XBUF_XGUVP *xbuf = (const XBUF_XGUVP *)g_XBuffer + y1; - uint8_t *draw_ptr = g_PrintSurfacePtr + y1 * stride; - - while (y_size > 0) { - const int32_t x = xbuf->x1 / PHD_ONE; - int32_t x_size = (xbuf->x2 / PHD_ONE) - x; - if (x_size <= 0) { - goto loop_end; - } - - int32_t g = xbuf->g1; - double u = xbuf->u1; - double v = xbuf->v1; - double rhw = xbuf->rhw1; - - const int32_t g_add = (xbuf->g2 - g) / x_size; - - int32_t u0 = PHD_HALF * u / rhw; - int32_t v0 = PHD_HALF * v / rhw; - - uint8_t *line_ptr = draw_ptr + x; - int32_t batch_size = 32; - - if (x_size >= batch_size) { - const double u_add = - (xbuf->u2 - u) / (double)x_size * (double)batch_size; - const double v_add = - (xbuf->v2 - v) / (double)x_size * (double)batch_size; - const double rhw_add = - (xbuf->rhw2 - rhw) / (double)x_size * (double)batch_size; - - while (x_size >= batch_size) { - u += u_add; - v += v_add; - rhw += rhw_add; - - const int32_t u1 = PHD_HALF * u / rhw; - const int32_t v1 = PHD_HALF * v / rhw; - - const int32_t u0_add = (u1 - u0) / batch_size; - const int32_t v0_add = (v1 - v0) / batch_size; - - if ((ABS(u0_add) + ABS(v0_add)) < (PHD_ONE / 2)) { - int32_t batch_counter = batch_size / 2; - while (batch_counter--) { - const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; - if (color_idx != 0) { - const uint8_t color = - g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; - line_ptr[0] = color; - line_ptr[1] = color; - } - line_ptr += 2; - g += g_add * 2; - u0 += u0_add * 2; - v0 += v0_add * 2; - } - } else { - int32_t batch_counter = batch_size; - while (batch_counter--) { - const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; - if (color_idx != 0) { - const uint8_t color = - g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; - *line_ptr = color; - } - line_ptr++; - g += g_add; - u0 += u0_add; - v0 += v0_add; - } - } - - u0 = u1; - v0 = v1; - x_size -= batch_size; - } - } - - if (x_size > 1) { - const int32_t u1 = PHD_HALF * xbuf->u2 / xbuf->rhw2; - const int32_t v1 = PHD_HALF * xbuf->v2 / xbuf->rhw2; - const int32_t u0_add = (u1 - u0) / x_size; - const int32_t v0_add = (v1 - v0) / x_size; - - batch_size = x_size & ~1; - x_size -= batch_size; - - if ((ABS(u0_add) + ABS(v0_add)) < (PHD_ONE / 2)) { - int32_t batch_counter = batch_size / 2; - while (batch_counter--) { - const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; - if (color_idx != 0) { - const uint8_t color = - g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; - line_ptr[0] = color; - line_ptr[1] = color; - } - line_ptr += 2; - g += g_add * 2; - u0 += u0_add * 2; - v0 += v0_add * 2; - }; - } else { - int32_t batch_counter = batch_size; - while (batch_counter--) { - const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; - if (color_idx != 0) { - const uint8_t color = - g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; - *line_ptr = color; - } - line_ptr++; - g += g_add; - u0 += u0_add; - v0 += v0_add; - } - } - } - - if (x_size == 1) { - const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; - if (color_idx != 0) { - const uint8_t color = - g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; - *line_ptr = color; - } - } - - loop_end: - y_size--; - xbuf++; - draw_ptr += stride; - } -} - -int32_t __cdecl Output_VisibleZClip( - const PHD_VBUF *const vtx0, const PHD_VBUF *const vtx1, - const PHD_VBUF *const vtx2) -{ - // clang-format off - return ( - vtx1->xv * (vtx0->yv * vtx2->zv - vtx0->zv * vtx2->yv) + - vtx1->yv * (vtx0->zv * vtx2->xv - vtx0->xv * vtx2->zv) + - vtx1->zv * (vtx0->xv * vtx2->yv - vtx0->yv * vtx2->xv) < 0.0 - ); - // clang-format on -} - -int32_t __cdecl Output_ZedClipper( - const int32_t vtx_count, const POINT_INFO *const points, - VERTEX_INFO *const vtx) -{ - int32_t j = 0; - const POINT_INFO *pts0 = &points[0]; - const POINT_INFO *pts1 = &points[vtx_count - 1]; - - for (int32_t i = 0; i < vtx_count; i++) { - int32_t diff0 = g_FltNearZ - pts0->zv; - int32_t diff1 = g_FltNearZ - pts1->zv; - if ((diff0 | diff1) >= 0) { - goto loop_end; - } - - if ((diff0 ^ diff1) < 0) { - double clip = diff0 / (pts1->zv - pts0->zv); - vtx[j].x = - (pts0->xv + (pts1->xv - pts0->xv) * clip) * g_FltPerspONearZ - + g_FltWinCenterX; - vtx[j].y = - (pts0->yv + (pts1->yv - pts0->yv) * clip) * g_FltPerspONearZ - + g_FltWinCenterY; - vtx[j].rhw = g_FltRhwONearZ; - vtx[j].g = pts0->g + (pts1->g - pts0->g) * clip; - vtx[j].u = (pts0->u + (pts1->u - pts0->u) * clip) * g_FltRhwONearZ; - vtx[j].v = (pts0->v + (pts1->v - pts0->v) * clip) * g_FltRhwONearZ; - j++; - } - - if (diff0 < 0) { - vtx[j].x = pts0->xs; - vtx[j].y = pts0->ys; - vtx[j].rhw = pts0->rhw; - vtx[j].g = pts0->g; - vtx[j].u = pts0->u * pts0->rhw; - vtx[j].v = pts0->v * pts0->rhw; - j++; - } - - loop_end: - pts1 = pts0++; - } - - return (j < 3) ? 0 : j; -} - -int32_t __cdecl Output_XYClipper(int32_t vtx_count, VERTEX_INFO *vtx) -{ - int32_t j; - VERTEX_INFO vtx_buf[20]; - const VERTEX_INFO *vtx1; - const VERTEX_INFO *vtx2; - - if (vtx_count < 3) { - return 0; - } - - // horizontal clip - j = 0; - vtx2 = &vtx[vtx_count - 1]; - for (int32_t i = 0; i < vtx_count; i++) { - vtx1 = vtx2; - vtx2 = &vtx[i]; - - if (vtx1->x < g_FltWinLeft) { - if (vtx2->x < g_FltWinLeft) { - continue; - } - const float clip = (g_FltWinLeft - vtx2->x) / (vtx1->x - vtx2->x); - vtx_buf[j].x = g_FltWinLeft; - vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; - j++; - } else if (vtx1->x > g_FltWinRight) { - if (vtx2->x > g_FltWinRight) { - continue; - } - const float clip = (g_FltWinRight - vtx2->x) / (vtx1->x - vtx2->x); - vtx_buf[j].x = g_FltWinRight; - vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; - j++; - } - - if (vtx2->x < g_FltWinLeft) { - const float clip = (g_FltWinLeft - vtx2->x) / (vtx1->x - vtx2->x); - vtx_buf[j].x = g_FltWinLeft; - vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; - j++; - } else if (vtx2->x > g_FltWinRight) { - const float clip = (g_FltWinRight - vtx2->x) / (vtx1->x - vtx2->x); - vtx_buf[j].x = g_FltWinRight; - vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; - j++; - } else { - vtx_buf[j].x = vtx2->x; - vtx_buf[j].y = vtx2->y; - j++; - } - } - - vtx_count = j; - if (vtx_count < 3) { - return 0; - } - - // vertical clip - j = 0; - vtx2 = &vtx_buf[vtx_count - 1]; - for (int32_t i = 0; i < vtx_count; i++) { - vtx1 = vtx2; - vtx2 = &vtx_buf[i]; - - if (vtx1->y < g_FltWinTop) { - if (vtx2->y < g_FltWinTop) { - continue; - } - const float clip = (g_FltWinTop - vtx2->y) / (vtx1->y - vtx2->y); - vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; - vtx[j].y = g_FltWinTop; - j++; - } else if (vtx1->y > g_FltWinBottom) { - if (vtx2->y > g_FltWinBottom) { - continue; - } - const float clip = (g_FltWinBottom - vtx2->y) / (vtx1->y - vtx2->y); - vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; - vtx[j].y = g_FltWinBottom; - j++; - } - - if (vtx2->y < g_FltWinTop) { - const float clip = (g_FltWinTop - vtx2->y) / (vtx1->y - vtx2->y); - vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; - vtx[j].y = g_FltWinTop; - j++; - } else if (vtx2->y > g_FltWinBottom) { - const float clip = (g_FltWinBottom - vtx2->y) / (vtx1->y - vtx2->y); - vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; - vtx[j].y = g_FltWinBottom; - j++; - } else { - vtx[j].x = vtx2->x; - vtx[j].y = vtx2->y; - j++; - } - } - - return (j < 3) ? 0 : j; -} - -int32_t __cdecl Output_XYGClipper(int32_t vtx_count, VERTEX_INFO *vtx) -{ - VERTEX_INFO vtx_buf[8]; - const VERTEX_INFO *vtx1; - const VERTEX_INFO *vtx2; - int32_t j; - - if (vtx_count < 3) { - return 0; - } - - // horizontal clip - j = 0; - vtx2 = &vtx[vtx_count - 1]; - for (int32_t i = 0; i < vtx_count; i++) { - vtx1 = vtx2; - vtx2 = &vtx[i]; - - if (vtx1->x < g_FltWinLeft) { - if (vtx2->x < g_FltWinLeft) { - continue; - } - const float clip = (g_FltWinLeft - vtx2->x) / (vtx1->x - vtx2->x); - vtx_buf[j].x = g_FltWinLeft; - vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; - M_ClipG(&vtx_buf[j++], vtx1, vtx2, clip); - } else if (vtx1->x > g_FltWinRight) { - if (vtx2->x > g_FltWinRight) { - continue; - } - const float clip = (g_FltWinRight - vtx2->x) / (vtx1->x - vtx2->x); - vtx_buf[j].x = g_FltWinRight; - vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; - M_ClipG(&vtx_buf[j++], vtx1, vtx2, clip); - } - - if (vtx2->x < g_FltWinLeft) { - const float clip = (g_FltWinLeft - vtx2->x) / (vtx1->x - vtx2->x); - vtx_buf[j].x = g_FltWinLeft; - vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; - M_ClipG(&vtx_buf[j++], vtx1, vtx2, clip); - } else if (vtx2->x > g_FltWinRight) { - const float clip = (g_FltWinRight - vtx2->x) / (vtx1->x - vtx2->x); - vtx_buf[j].x = g_FltWinRight; - vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; - M_ClipG(&vtx_buf[j++], vtx1, vtx2, clip); - } else { - vtx_buf[j++] = *vtx2; - } - } - - vtx_count = j; - if (vtx_count < 3) { - return 0; - } - - // vertical clip - j = 0; - vtx2 = &vtx_buf[vtx_count - 1]; - for (int32_t i = 0; i < vtx_count; i++) { - vtx1 = vtx2; - vtx2 = &vtx_buf[i]; - - if (vtx1->y < g_FltWinTop) { - if (vtx2->y < g_FltWinTop) { - continue; - } - const float clip = (g_FltWinTop - vtx2->y) / (vtx1->y - vtx2->y); - vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; - vtx[j].y = g_FltWinTop; - M_ClipG(&vtx[j++], vtx1, vtx2, clip); - } else if (vtx1->y > g_FltWinBottom) { - if (vtx2->y > g_FltWinBottom) { - continue; - } - const float clip = (g_FltWinBottom - vtx2->y) / (vtx1->y - vtx2->y); - vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; - vtx[j].y = g_FltWinBottom; - M_ClipG(&vtx[j++], vtx1, vtx2, clip); - } - - if (vtx2->y < g_FltWinTop) { - const float clip = (g_FltWinTop - vtx2->y) / (vtx1->y - vtx2->y); - vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; - vtx[j].y = g_FltWinTop; - M_ClipG(&vtx[j++], vtx1, vtx2, clip); - } else if (vtx2->y > g_FltWinBottom) { - const float clip = (g_FltWinBottom - vtx2->y) / (vtx1->y - vtx2->y); - vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; - vtx[j].y = g_FltWinBottom; - M_ClipG(&vtx[j++], vtx1, vtx2, clip); - } else { - vtx[j++] = *vtx2; - } - } - - return (j < 3) ? 0 : j; -} - -int32_t __cdecl Output_XYGUVClipper(int32_t vtx_count, VERTEX_INFO *const vtx) -{ - VERTEX_INFO vtx_buf[8]; - const VERTEX_INFO *vtx1; - const VERTEX_INFO *vtx2; - int32_t j; - - if (vtx_count < 3) { - return 0; - } - - // horizontal clip - j = 0; - vtx2 = &vtx[vtx_count - 1]; - for (int32_t i = 0; i < vtx_count; i++) { - vtx1 = vtx2; - vtx2 = &vtx[i]; - - if (vtx1->x < g_FltWinLeft) { - if (vtx2->x < g_FltWinLeft) { - continue; - } - float clip = (g_FltWinLeft - vtx2->x) / (vtx1->x - vtx2->x); - vtx_buf[j].x = g_FltWinLeft; - vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; - M_ClipGUV(&vtx_buf[j++], vtx1, vtx2, clip); - } else if (vtx1->x > g_FltWinRight) { - if (vtx2->x > g_FltWinRight) { - continue; - } - float clip = (g_FltWinRight - vtx2->x) / (vtx1->x - vtx2->x); - vtx_buf[j].x = g_FltWinRight; - vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; - M_ClipGUV(&vtx_buf[j++], vtx1, vtx2, clip); - } - - if (vtx2->x < g_FltWinLeft) { - float clip = (g_FltWinLeft - vtx2->x) / (vtx1->x - vtx2->x); - vtx_buf[j].x = g_FltWinLeft; - vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; - M_ClipGUV(&vtx_buf[j++], vtx1, vtx2, clip); - } else if (vtx2->x > g_FltWinRight) { - float clip = (g_FltWinRight - vtx2->x) / (vtx1->x - vtx2->x); - vtx_buf[j].x = g_FltWinRight; - vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; - M_ClipGUV(&vtx_buf[j++], vtx1, vtx2, clip); - } else { - vtx_buf[j++] = *vtx2; - } - } - - vtx_count = j; - if (vtx_count < 3) { - return 0; - } - - // vertical clip - j = 0; - vtx2 = &vtx_buf[vtx_count - 1]; - for (int32_t i = 0; i < vtx_count; i++) { - vtx1 = vtx2; - vtx2 = &vtx_buf[i]; - - if (vtx1->y < g_FltWinTop) { - if (vtx2->y < g_FltWinTop) { - continue; - } - const float clip = (g_FltWinTop - vtx2->y) / (vtx1->y - vtx2->y); - vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; - vtx[j].y = g_FltWinTop; - M_ClipGUV(&vtx[j++], vtx1, vtx2, clip); - } else if (vtx1->y > g_FltWinBottom) { - if (vtx2->y > g_FltWinBottom) { - continue; - } - const float clip = (g_FltWinBottom - vtx2->y) / (vtx1->y - vtx2->y); - vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; - vtx[j].y = g_FltWinBottom; - M_ClipGUV(&vtx[j++], vtx1, vtx2, clip); - } - - if (vtx2->y < g_FltWinTop) { - const float clip = (g_FltWinTop - vtx2->y) / (vtx1->y - vtx2->y); - vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; - vtx[j].y = g_FltWinTop; - M_ClipGUV(&vtx[j++], vtx1, vtx2, clip); - } else if (vtx2->y > g_FltWinBottom) { - const float clip = (g_FltWinBottom - vtx2->y) / (vtx1->y - vtx2->y); - vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; - vtx[j].y = g_FltWinBottom; - M_ClipGUV(&vtx[j++], vtx1, vtx2, clip); - } else { - vtx[j++] = *vtx2; - } - } - - return (j < 3) ? 0 : j; -} - -const int16_t *__cdecl Output_InsertObjectG3( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type) -{ - for (int32_t i = 0; i < num; i++) { - const PHD_VBUF *const vtx[3] = { - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - }; - const uint8_t color_idx = *obj_ptr++; - int32_t num_points = 3; - - int8_t clip_or = vtx[0]->clip | vtx[1]->clip | vtx[2]->clip; - int8_t clip_and = vtx[0]->clip & vtx[1]->clip & vtx[2]->clip; - - if (clip_and != 0) { - continue; - } - - if (clip_or >= 0) { - if (!VBUF_VISIBLE(*vtx[0], *vtx[1], *vtx[2])) { - continue; - } - - g_VBuffer[0].x = vtx[0]->xs; - g_VBuffer[0].y = vtx[0]->ys; - g_VBuffer[0].rhw = vtx[0]->rhw; - g_VBuffer[0].g = (float)vtx[0]->g; - - g_VBuffer[1].x = vtx[1]->xs; - g_VBuffer[1].y = vtx[1]->ys; - g_VBuffer[1].rhw = vtx[1]->rhw; - g_VBuffer[1].g = (float)vtx[1]->g; - - g_VBuffer[2].x = vtx[2]->xs; - g_VBuffer[2].y = vtx[2]->ys; - g_VBuffer[2].rhw = vtx[2]->rhw; - g_VBuffer[2].g = (float)vtx[2]->g; - } else { - if (!Output_VisibleZClip(vtx[0], vtx[1], vtx[2])) { - continue; - } - - POINT_INFO points[3] = { - { - .xv = vtx[0]->xv, - .yv = vtx[0]->yv, - .zv = vtx[0]->zv, - .rhw = vtx[0]->rhw, - .xs = vtx[0]->xs, - .ys = vtx[0]->ys, - .g = (float)vtx[0]->g, - }, - { - .xv = vtx[1]->xv, - .yv = vtx[1]->yv, - .zv = vtx[1]->zv, - .rhw = vtx[1]->rhw, - .xs = vtx[1]->xs, - .ys = vtx[1]->ys, - .g = (float)vtx[1]->g, - }, - { - .xv = vtx[2]->xv, - .yv = vtx[2]->yv, - .zv = vtx[2]->zv, - .rhw = vtx[2]->rhw, - .xs = vtx[2]->xs, - .ys = vtx[2]->ys, - .g = (float)vtx[2]->g, - }, - }; - - num_points = Output_ZedClipper(num_points, points, g_VBuffer); - if (num_points == 0) { - continue; - } - } - - num_points = Output_XYGClipper(num_points, g_VBuffer); - if (num_points == 0) { - continue; - } - - const float zv = M_CalculatePolyZ( - sort_type, vtx[0]->zv, vtx[1]->zv, vtx[2]->zv, -1.0); - g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; - g_Sort3DPtr->_1 = MAKE_ZSORT(zv); - g_Sort3DPtr++; - - *g_Info3DPtr++ = POLY_GOURAUD; - *g_Info3DPtr++ = color_idx; - *g_Info3DPtr++ = num_points; - - for (int32_t j = 0; j < num_points; j++) { - *g_Info3DPtr++ = (int32_t)g_VBuffer[j].x; - *g_Info3DPtr++ = (int32_t)g_VBuffer[j].y; - *g_Info3DPtr++ = (int32_t)g_VBuffer[j].g; - } - g_SurfaceCount++; - } - - return obj_ptr; -} - -const int16_t *__cdecl Output_InsertObjectGT3( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type) -{ - for (int32_t i = 0; i < num; i++) { - const PHD_VBUF *const vtx[3] = { - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - }; - const int16_t texture_idx = *obj_ptr++; - const PHD_TEXTURE *const texture = &g_PhdTextureInfo[texture_idx]; - const PHD_UV *const uv = texture->uv; - int32_t num_points = 3; - - if (texture->draw_type != DRAW_OPAQUE && m_DiscardTransparent) { - continue; - } - - const int8_t clip_or = vtx[0]->clip | vtx[1]->clip | vtx[2]->clip; - const int8_t clip_and = vtx[0]->clip & vtx[1]->clip & vtx[2]->clip; - - if (clip_and != 0) { - continue; - } - - if (clip_or >= 0) { - if (!VBUF_VISIBLE(*vtx[0], *vtx[1], *vtx[2])) { - continue; - } - - if (clip_or == 0) { - const float zv = M_CalculatePolyZ( - sort_type, vtx[0]->zv, vtx[1]->zv, vtx[2]->zv, -1.0); - g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; - g_Sort3DPtr->_1 = MAKE_ZSORT(zv); - g_Sort3DPtr++; - - if (zv >= (double)g_PerspectiveDistance) { - *g_Info3DPtr++ = (texture->draw_type == DRAW_OPAQUE) - ? POLY_GTMAP - : POLY_WGTMAP; - *g_Info3DPtr++ = texture->tex_page; - *g_Info3DPtr++ = 3; - - *g_Info3DPtr++ = (int32_t)vtx[0]->xs; - *g_Info3DPtr++ = (int32_t)vtx[0]->ys; - *g_Info3DPtr++ = (int32_t)vtx[0]->g; - *g_Info3DPtr++ = uv[0].u; - *g_Info3DPtr++ = uv[0].v; - - *g_Info3DPtr++ = (int32_t)vtx[1]->xs; - *g_Info3DPtr++ = (int32_t)vtx[1]->ys; - *g_Info3DPtr++ = (int32_t)vtx[1]->g; - *g_Info3DPtr++ = uv[1].u; - *g_Info3DPtr++ = uv[1].v; - - *g_Info3DPtr++ = (int32_t)vtx[2]->xs; - *g_Info3DPtr++ = (int32_t)vtx[2]->ys; - *g_Info3DPtr++ = (int32_t)vtx[2]->g; - *g_Info3DPtr++ = uv[2].u; - *g_Info3DPtr++ = uv[2].v; - } else { - *g_Info3DPtr++ = (texture->draw_type == DRAW_OPAQUE) - ? POLY_GTMAP_PERSP - : POLY_WGTMAP_PERSP; - *g_Info3DPtr++ = texture->tex_page; - *g_Info3DPtr++ = 3; - - *g_Info3DPtr++ = (int32_t)vtx[0]->xs; - *g_Info3DPtr++ = (int32_t)vtx[0]->ys; - *g_Info3DPtr++ = (int32_t)vtx[0]->g; - *(float *)g_Info3DPtr = vtx[0]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - *(float *)g_Info3DPtr = (double)uv[0].u * vtx[0]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - *(float *)g_Info3DPtr = (double)uv[0].v * vtx[0]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - - *g_Info3DPtr++ = (int32_t)vtx[1]->xs; - *g_Info3DPtr++ = (int32_t)vtx[1]->ys; - *g_Info3DPtr++ = (int32_t)vtx[1]->g; - *(float *)g_Info3DPtr = vtx[1]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - *(float *)g_Info3DPtr = (double)uv[1].u * vtx[1]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - *(float *)g_Info3DPtr = (double)uv[1].v * vtx[1]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - - *g_Info3DPtr++ = (int32_t)vtx[2]->xs; - *g_Info3DPtr++ = (int32_t)vtx[2]->ys; - *g_Info3DPtr++ = (int32_t)vtx[2]->g; - *(float *)g_Info3DPtr = vtx[2]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - *(float *)g_Info3DPtr = (double)uv[2].u * vtx[2]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - *(float *)g_Info3DPtr = (double)uv[2].v * vtx[2]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - } - g_SurfaceCount++; - continue; - } - - g_VBuffer[0].x = vtx[0]->xs; - g_VBuffer[0].y = vtx[0]->ys; - g_VBuffer[0].rhw = vtx[0]->rhw; - g_VBuffer[0].g = (float)vtx[0]->g; - g_VBuffer[0].u = (double)uv[0].u * vtx[0]->rhw; - g_VBuffer[0].v = (double)uv[0].v * vtx[0]->rhw; - - g_VBuffer[1].x = vtx[1]->xs; - g_VBuffer[1].y = vtx[1]->ys; - g_VBuffer[1].rhw = vtx[1]->rhw; - g_VBuffer[1].g = (float)vtx[1]->g; - g_VBuffer[1].u = (double)uv[1].u * vtx[1]->rhw; - g_VBuffer[1].v = (double)uv[1].v * vtx[1]->rhw; - - g_VBuffer[2].x = vtx[2]->xs; - g_VBuffer[2].y = vtx[2]->ys; - g_VBuffer[2].rhw = vtx[2]->rhw; - g_VBuffer[2].g = (float)vtx[2]->g; - g_VBuffer[2].u = (double)uv[2].u * vtx[2]->rhw; - g_VBuffer[2].v = (double)uv[2].v * vtx[2]->rhw; - } else { - if (!Output_VisibleZClip(vtx[0], vtx[1], vtx[2])) { - continue; - } - - const POINT_INFO points[3] = { - { - .xv = vtx[0]->xv, - .yv = vtx[0]->yv, - .zv = vtx[0]->zv, - .rhw = vtx[0]->rhw, - .xs = vtx[0]->xs, - .ys = vtx[0]->ys, - .g = (float)vtx[0]->g, - .u = (float)uv[0].u, - .v = (float)uv[0].v, - }, - { - .yv = vtx[1]->yv, - .xv = vtx[1]->xv, - .zv = vtx[1]->zv, - .rhw = vtx[1]->rhw, - .xs = vtx[1]->xs, - .ys = vtx[1]->ys, - .g = (float)vtx[1]->g, - .u = (float)uv[1].u, - .v = (float)uv[1].v, - }, - { - .xv = vtx[2]->xv, - .yv = vtx[2]->yv, - .zv = vtx[2]->zv, - .rhw = vtx[2]->rhw, - .xs = vtx[2]->xs, - .ys = vtx[2]->ys, - .g = (float)vtx[2]->g, - .u = (float)uv[2].u, - .v = (float)uv[2].v, - }, - }; - - num_points = Output_ZedClipper(num_points, points, g_VBuffer); - if (num_points == 0) { - continue; - } - } - - num_points = Output_XYGUVClipper(num_points, g_VBuffer); - if (num_points == 0) { - continue; - } - - const float zv = M_CalculatePolyZ( - sort_type, vtx[0]->zv, vtx[1]->zv, vtx[2]->zv, -1.0); - g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; - g_Sort3DPtr->_1 = MAKE_ZSORT(zv); - g_Sort3DPtr++; - - if (zv >= (double)g_PerspectiveDistance) { - *g_Info3DPtr++ = - (texture->draw_type == DRAW_OPAQUE) ? POLY_GTMAP : POLY_WGTMAP; - *g_Info3DPtr++ = texture->tex_page; - *g_Info3DPtr++ = num_points; - - for (int32_t j = 0; j < num_points; j++) { - *g_Info3DPtr++ = (int32_t)g_VBuffer[j].x; - *g_Info3DPtr++ = (int32_t)g_VBuffer[j].y; - *g_Info3DPtr++ = (int32_t)g_VBuffer[j].g; - *g_Info3DPtr++ = (int32_t)(g_VBuffer[j].u / g_VBuffer[j].rhw); - *g_Info3DPtr++ = (int32_t)(g_VBuffer[j].v / g_VBuffer[j].rhw); - } - } else { - *g_Info3DPtr++ = (texture->draw_type == DRAW_OPAQUE) - ? POLY_GTMAP_PERSP - : POLY_WGTMAP_PERSP; - *g_Info3DPtr++ = texture->tex_page; - *g_Info3DPtr++ = num_points; - - for (int32_t j = 0; j < num_points; j++) { - *g_Info3DPtr++ = (int32_t)g_VBuffer[j].x; - *g_Info3DPtr++ = (int32_t)g_VBuffer[j].y; - *g_Info3DPtr++ = (int32_t)g_VBuffer[j].g; - *(float *)g_Info3DPtr = g_VBuffer[j].rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - *(float *)g_Info3DPtr = g_VBuffer[j].u; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - *(float *)g_Info3DPtr = g_VBuffer[j].v; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - } - } - g_SurfaceCount++; - } - - return obj_ptr; -} - -const int16_t *__cdecl Output_InsertObjectG4( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type) -{ - for (int32_t i = 0; i < num; i++) { - const PHD_VBUF *const vtx[4] = { - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - }; - const uint8_t color_idx = *obj_ptr++; - int32_t num_points = 4; - - const int8_t clip_or = - vtx[0]->clip | vtx[1]->clip | vtx[2]->clip | vtx[3]->clip; - const int8_t clip_and = - vtx[0]->clip & vtx[1]->clip & vtx[2]->clip & vtx[3]->clip; - - if (clip_and != 0) { - continue; - } - - if (clip_or >= 0) { - if (!VBUF_VISIBLE(*vtx[0], *vtx[1], *vtx[2])) { - continue; - } - - g_VBuffer[0].x = vtx[0]->xs; - g_VBuffer[0].y = vtx[0]->ys; - g_VBuffer[0].rhw = vtx[0]->rhw; - g_VBuffer[0].g = (float)vtx[0]->g; - - g_VBuffer[1].x = vtx[1]->xs; - g_VBuffer[1].y = vtx[1]->ys; - g_VBuffer[1].rhw = vtx[1]->rhw; - g_VBuffer[1].g = (float)vtx[1]->g; - - g_VBuffer[2].x = vtx[2]->xs; - g_VBuffer[2].y = vtx[2]->ys; - g_VBuffer[2].rhw = vtx[2]->rhw; - g_VBuffer[2].g = (float)vtx[2]->g; - - g_VBuffer[3].x = vtx[3]->xs; - g_VBuffer[3].y = vtx[3]->ys; - g_VBuffer[3].rhw = vtx[3]->rhw; - g_VBuffer[3].g = (float)vtx[3]->g; - } else { - if (!Output_VisibleZClip(vtx[0], vtx[1], vtx[2])) { - continue; - } - - const POINT_INFO points[4] = { - { - .xv = vtx[0]->xv, - .yv = vtx[0]->yv, - .zv = vtx[0]->zv, - .rhw = vtx[0]->rhw, - .xs = vtx[0]->xs, - .ys = vtx[0]->ys, - .g = (float)vtx[0]->g, - }, - { - .xv = vtx[1]->xv, - .yv = vtx[1]->yv, - .zv = vtx[1]->zv, - .rhw = vtx[1]->rhw, - .xs = vtx[1]->xs, - .ys = vtx[1]->ys, - .g = (float)vtx[1]->g, - }, - { - .xv = vtx[2]->xv, - .yv = vtx[2]->yv, - .zv = vtx[2]->zv, - .rhw = vtx[2]->rhw, - .xs = vtx[2]->xs, - .ys = vtx[2]->ys, - .g = (float)vtx[2]->g, - }, - { - .xv = vtx[3]->xv, - .yv = vtx[3]->yv, - .zv = vtx[3]->zv, - .rhw = vtx[3]->rhw, - .xs = vtx[3]->xs, - .ys = vtx[3]->ys, - .g = (float)vtx[3]->g, - }, - }; - - num_points = Output_ZedClipper(num_points, points, g_VBuffer); - if (num_points == 0) { - continue; - } - } - - num_points = Output_XYGClipper(num_points, g_VBuffer); - if (num_points == 0) { - continue; - } - - const float zv = M_CalculatePolyZ( - sort_type, vtx[0]->zv, vtx[1]->zv, vtx[2]->zv, vtx[3]->zv); - g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; - g_Sort3DPtr->_1 = MAKE_ZSORT(zv); - g_Sort3DPtr++; - - *g_Info3DPtr++ = POLY_GOURAUD; - *g_Info3DPtr++ = color_idx; - *g_Info3DPtr++ = num_points; - - for (int32_t j = 0; j < num_points; j++) { - *g_Info3DPtr++ = g_VBuffer[j].x; - *g_Info3DPtr++ = g_VBuffer[j].y; - *g_Info3DPtr++ = g_VBuffer[j].g; - } - g_SurfaceCount++; - } - - return obj_ptr; -} - -const int16_t *__cdecl Output_InsertObjectGT4( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type) -{ - for (int32_t i = 0; i < num; i++) { - const PHD_VBUF *const vtx[4] = { - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - }; - const int16_t texture_idx = *obj_ptr++; - const PHD_TEXTURE *const texture = &g_PhdTextureInfo[texture_idx]; - const PHD_UV *const uv = texture->uv; - int32_t num_points = 4; - - if (texture->draw_type != DRAW_OPAQUE && m_DiscardTransparent) { - continue; - } - - const int8_t clip_or = - vtx[0]->clip | vtx[1]->clip | vtx[2]->clip | vtx[3]->clip; - const int8_t clip_and = - vtx[0]->clip & vtx[1]->clip & vtx[2]->clip & vtx[3]->clip; - - if (clip_and != 0) { - continue; - } - - if (clip_or >= 0) { - if (!VBUF_VISIBLE(*vtx[0], *vtx[1], *vtx[2])) { - continue; - } - - if (clip_or == 0) { - const float zv = M_CalculatePolyZ( - sort_type, vtx[0]->zv, vtx[1]->zv, vtx[2]->zv, vtx[3]->zv); - g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; - g_Sort3DPtr->_1 = MAKE_ZSORT(zv); - g_Sort3DPtr++; - - if (zv >= (double)g_PerspectiveDistance) { - *g_Info3DPtr++ = (texture->draw_type == DRAW_OPAQUE) - ? POLY_GTMAP - : POLY_WGTMAP; - *g_Info3DPtr++ = texture->tex_page; - *g_Info3DPtr++ = 4; - - *g_Info3DPtr++ = (int32_t)vtx[0]->xs; - *g_Info3DPtr++ = (int32_t)vtx[0]->ys; - *g_Info3DPtr++ = (int32_t)vtx[0]->g; - *g_Info3DPtr++ = uv[0].u; - *g_Info3DPtr++ = uv[0].v; - - *g_Info3DPtr++ = (int32_t)vtx[1]->xs; - *g_Info3DPtr++ = (int32_t)vtx[1]->ys; - *g_Info3DPtr++ = (int32_t)vtx[1]->g; - *g_Info3DPtr++ = uv[1].u; - *g_Info3DPtr++ = uv[1].v; - - *g_Info3DPtr++ = (int32_t)vtx[2]->xs; - *g_Info3DPtr++ = (int32_t)vtx[2]->ys; - *g_Info3DPtr++ = (int32_t)vtx[2]->g; - *g_Info3DPtr++ = uv[2].u; - *g_Info3DPtr++ = uv[2].v; - - *g_Info3DPtr++ = (int32_t)vtx[3]->xs; - *g_Info3DPtr++ = (int32_t)vtx[3]->ys; - *g_Info3DPtr++ = (int32_t)vtx[3]->g; - *g_Info3DPtr++ = uv[3].u; - *g_Info3DPtr++ = uv[3].v; - } else { - *g_Info3DPtr++ = (texture->draw_type == DRAW_OPAQUE) - ? POLY_GTMAP_PERSP - : POLY_WGTMAP_PERSP; - *g_Info3DPtr++ = texture->tex_page; - *g_Info3DPtr++ = 4; - - *g_Info3DPtr++ = (int32_t)vtx[0]->xs; - *g_Info3DPtr++ = (int32_t)vtx[0]->ys; - *g_Info3DPtr++ = (int32_t)vtx[0]->g; - *(float *)g_Info3DPtr = vtx[0]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - *(float *)g_Info3DPtr = (double)uv[0].u * vtx[0]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - *(float *)g_Info3DPtr = (double)uv[0].v * vtx[0]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - - *g_Info3DPtr++ = (int32_t)vtx[1]->xs; - *g_Info3DPtr++ = (int32_t)vtx[1]->ys; - *g_Info3DPtr++ = (int32_t)vtx[1]->g; - *(float *)g_Info3DPtr = vtx[1]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - *(float *)g_Info3DPtr = (double)uv[1].u * vtx[1]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - *(float *)g_Info3DPtr = (double)uv[1].v * vtx[1]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - - *g_Info3DPtr++ = (int32_t)vtx[2]->xs; - *g_Info3DPtr++ = (int32_t)vtx[2]->ys; - *g_Info3DPtr++ = (int32_t)vtx[2]->g; - *(float *)g_Info3DPtr = vtx[2]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - *(float *)g_Info3DPtr = (double)uv[2].u * vtx[2]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - *(float *)g_Info3DPtr = (double)uv[2].v * vtx[2]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - - *g_Info3DPtr++ = (int32_t)vtx[3]->xs; - *g_Info3DPtr++ = (int32_t)vtx[3]->ys; - *g_Info3DPtr++ = (int32_t)vtx[3]->g; - *(float *)g_Info3DPtr = vtx[3]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - *(float *)g_Info3DPtr = (double)uv[3].u * vtx[3]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - *(float *)g_Info3DPtr = (double)uv[3].v * vtx[3]->rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - } - g_SurfaceCount++; - continue; - } - - g_VBuffer[0].x = vtx[0]->xs; - g_VBuffer[0].y = vtx[0]->ys; - g_VBuffer[0].rhw = vtx[0]->rhw; - g_VBuffer[0].g = (float)vtx[0]->g; - g_VBuffer[0].u = (double)uv[0].u * vtx[0]->rhw; - g_VBuffer[0].v = (double)uv[0].v * vtx[0]->rhw; - - g_VBuffer[1].x = vtx[1]->xs; - g_VBuffer[1].y = vtx[1]->ys; - g_VBuffer[1].rhw = vtx[1]->rhw; - g_VBuffer[1].g = (float)vtx[1]->g; - g_VBuffer[1].u = (double)uv[1].u * vtx[1]->rhw; - g_VBuffer[1].v = (double)uv[1].v * vtx[1]->rhw; - - g_VBuffer[2].x = vtx[2]->xs; - g_VBuffer[2].y = vtx[2]->ys; - g_VBuffer[2].rhw = vtx[2]->rhw; - g_VBuffer[2].g = (float)vtx[2]->g; - g_VBuffer[2].u = (double)uv[2].u * vtx[2]->rhw; - g_VBuffer[2].v = (double)uv[2].v * vtx[2]->rhw; - - g_VBuffer[3].x = vtx[3]->xs; - g_VBuffer[3].y = vtx[3]->ys; - g_VBuffer[3].rhw = vtx[3]->rhw; - g_VBuffer[3].g = (float)vtx[3]->g; - g_VBuffer[3].u = (double)uv[3].u * vtx[3]->rhw; - g_VBuffer[3].v = (double)uv[3].v * vtx[3]->rhw; - } else { - if (!Output_VisibleZClip(vtx[0], vtx[1], vtx[2])) { - continue; - } - - const POINT_INFO points[4] = { - { - .xv = vtx[0]->xv, - .yv = vtx[0]->yv, - .zv = vtx[0]->zv, - .rhw = vtx[0]->rhw, - .xs = vtx[0]->xs, - .ys = vtx[0]->ys, - .g = (float)vtx[0]->g, - .u = (float)uv[0].u, - .v = (float)uv[0].v, - }, - { - .yv = vtx[1]->yv, - .xv = vtx[1]->xv, - .zv = vtx[1]->zv, - .rhw = vtx[1]->rhw, - .xs = vtx[1]->xs, - .ys = vtx[1]->ys, - .g = (float)vtx[1]->g, - .u = (float)uv[1].u, - .v = (float)uv[1].v, - }, - { - .xv = vtx[2]->xv, - .yv = vtx[2]->yv, - .zv = vtx[2]->zv, - .rhw = vtx[2]->rhw, - .xs = vtx[2]->xs, - .ys = vtx[2]->ys, - .g = (float)vtx[2]->g, - .u = (float)uv[2].u, - .v = (float)uv[2].v, - }, - { - .xv = vtx[3]->xv, - .yv = vtx[3]->yv, - .zv = vtx[3]->zv, - .rhw = vtx[3]->rhw, - .xs = vtx[3]->xs, - .ys = vtx[3]->ys, - .g = (float)vtx[3]->g, - .u = (float)uv[3].u, - .v = (float)uv[3].v, - }, - }; - - num_points = Output_ZedClipper(num_points, points, g_VBuffer); - if (num_points == 0) { - continue; - } - } - - num_points = Output_XYGUVClipper(num_points, g_VBuffer); - if (num_points == 0) { - continue; - } - - const float zv = M_CalculatePolyZ( - sort_type, vtx[0]->zv, vtx[1]->zv, vtx[2]->zv, vtx[3]->zv); - g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; - g_Sort3DPtr->_1 = MAKE_ZSORT(zv); - g_Sort3DPtr++; - - if (zv >= (double)g_PerspectiveDistance) { - *g_Info3DPtr++ = - (texture->draw_type == DRAW_OPAQUE) ? POLY_GTMAP : POLY_WGTMAP; - *g_Info3DPtr++ = texture->tex_page; - *g_Info3DPtr++ = num_points; - - for (int32_t j = 0; j < num_points; j++) { - *g_Info3DPtr++ = (int32_t)g_VBuffer[j].x; - *g_Info3DPtr++ = (int32_t)g_VBuffer[j].y; - *g_Info3DPtr++ = (int32_t)g_VBuffer[j].g; - *g_Info3DPtr++ = (int32_t)(g_VBuffer[j].u / g_VBuffer[j].rhw); - *g_Info3DPtr++ = (int32_t)(g_VBuffer[j].v / g_VBuffer[j].rhw); - } - } else { - *g_Info3DPtr++ = (texture->draw_type == DRAW_OPAQUE) - ? POLY_GTMAP_PERSP - : POLY_WGTMAP_PERSP; - *g_Info3DPtr++ = texture->tex_page; - *g_Info3DPtr++ = num_points; - - for (int32_t j = 0; j < num_points; j++) { - *g_Info3DPtr++ = (int32_t)g_VBuffer[j].x; - *g_Info3DPtr++ = (int32_t)g_VBuffer[j].y; - *g_Info3DPtr++ = (int32_t)g_VBuffer[j].g; - *(float *)g_Info3DPtr = g_VBuffer[j].rhw; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - *(float *)g_Info3DPtr = g_VBuffer[j].u; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - *(float *)g_Info3DPtr = g_VBuffer[j].v; - g_Info3DPtr += sizeof(float) / sizeof(int16_t); - } - } - g_SurfaceCount++; - } - - return obj_ptr; -} - -void __cdecl Output_InsertTrans8(const PHD_VBUF *vbuf, int16_t shade) -{ - const int32_t vtx_count = 8; - - int8_t clip_or = 0; - uint8_t clip_and = 0xFF; - for (int32_t i = 0; i < vtx_count; i++) { - clip_or |= vbuf[i].clip; - clip_and &= vbuf[i].clip; - } - - if (clip_or < 0 || clip_and || !VBUF_VISIBLE(vbuf[0], vbuf[1], vbuf[2])) { - return; - } - - int32_t num_points = vtx_count; - for (int32_t i = 0; i < num_points; i++) { - g_VBuffer[i].x = vbuf[i].xs; - g_VBuffer[i].y = vbuf[i].ys; - } - - if (clip_or != 0) { - g_FltWinTop = 0.0; - g_FltWinLeft = 0.0; - g_FltWinRight = (float)g_PhdWinMaxX; - g_FltWinBottom = (float)g_PhdWinMaxY; - - num_points = Output_XYClipper(vtx_count, g_VBuffer); - if (num_points == 0) { - return; - } - } - - double poly_z = 0.0; - for (int32_t i = 0; i < vtx_count; i++) { - poly_z += vbuf[i].zv; - } - poly_z /= vtx_count; - - g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; - g_Sort3DPtr->_1 = MAKE_ZSORT(poly_z); - g_Sort3DPtr++; - - *g_Info3DPtr++ = POLY_TRANS; - *g_Info3DPtr++ = shade; - *g_Info3DPtr++ = num_points; - for (int32_t i = 0; i < num_points; i++) { - *g_Info3DPtr++ = g_VBuffer[i].x; - *g_Info3DPtr++ = g_VBuffer[i].y; - } - g_SurfaceCount++; -} - -void __cdecl Output_InsertTransQuad( - int32_t x, int32_t y, int32_t width, int32_t height, int32_t z) -{ - g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; - g_Sort3DPtr->_1 = MAKE_ZSORT(g_PhdNearZ + 8 * z); - g_Sort3DPtr++; - - *g_Info3DPtr++ = POLY_TRANS; - *g_Info3DPtr++ = 32; - *g_Info3DPtr++ = 4; // number of vertices - *g_Info3DPtr++ = x; - *g_Info3DPtr++ = y; - *g_Info3DPtr++ = x + width; - *g_Info3DPtr++ = y; - *g_Info3DPtr++ = x + width; - *g_Info3DPtr++ = height + y; - *g_Info3DPtr++ = x; - *g_Info3DPtr++ = height + y; - - g_SurfaceCount++; -} - -void __cdecl Output_InsertFlatRect( - int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t z, - uint8_t color_idx) -{ - g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; - g_Sort3DPtr->_1 = MAKE_ZSORT(z); - g_Sort3DPtr++; - - *g_Info3DPtr++ = POLY_FLAT; - *g_Info3DPtr++ = color_idx; - *g_Info3DPtr++ = 4; - *g_Info3DPtr++ = x1; - *g_Info3DPtr++ = y1; - *g_Info3DPtr++ = x2; - *g_Info3DPtr++ = y1; - *g_Info3DPtr++ = x2; - *g_Info3DPtr++ = y2; - *g_Info3DPtr++ = x1; - *g_Info3DPtr++ = y2; - - g_SurfaceCount++; -} - -void __cdecl Output_InsertLine( - int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t z, - uint8_t color_idx) -{ - g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; - g_Sort3DPtr->_1 = MAKE_ZSORT(z); - g_Sort3DPtr++; - - *g_Info3DPtr++ = POLY_LINE; - *g_Info3DPtr++ = g_PhdWinMinX + x1; - *g_Info3DPtr++ = g_PhdWinMinY + y1; - *g_Info3DPtr++ = g_PhdWinMinX + x2; - *g_Info3DPtr++ = g_PhdWinMinY + y2; - *g_Info3DPtr++ = color_idx; - - g_SurfaceCount++; -} - -const int16_t *__cdecl Output_InsertObjectG3_ZBuffered( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type) -{ - HWR_TexSource(0); - HWR_EnableColorKey(0); - - if (num == 0) { - return obj_ptr; - } - - for (int32_t i = 0; i < num; i++) { - const PHD_VBUF *vtx[3] = { - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - }; - const int16_t color_idx = *obj_ptr++; - int32_t num_points = 3; - - const int8_t clip_or = vtx[0]->clip | vtx[1]->clip | vtx[2]->clip; - const int8_t clip_and = vtx[0]->clip & vtx[1]->clip & vtx[2]->clip; - - if (clip_and != 0) { - continue; - } - - if (clip_or >= 0) { - if (!VBUF_VISIBLE(*vtx[0], *vtx[1], *vtx[2])) { - continue; - } - - g_VBuffer[0].x = vtx[0]->xs; - g_VBuffer[0].y = vtx[0]->ys; - g_VBuffer[0].rhw = vtx[0]->rhw; - g_VBuffer[0].g = (float)vtx[0]->g; - - g_VBuffer[1].x = vtx[1]->xs; - g_VBuffer[1].y = vtx[1]->ys; - g_VBuffer[1].rhw = vtx[1]->rhw; - g_VBuffer[1].g = (float)vtx[1]->g; - - g_VBuffer[2].x = vtx[2]->xs; - g_VBuffer[2].y = vtx[2]->ys; - g_VBuffer[2].rhw = vtx[2]->rhw; - g_VBuffer[2].g = (float)vtx[2]->g; - } else { - if (!Output_VisibleZClip(vtx[0], vtx[1], vtx[2])) { - continue; - } - - const POINT_INFO points[3] = { - { - .xv = vtx[0]->xv, - .yv = vtx[0]->yv, - .zv = vtx[0]->zv, - .rhw = vtx[0]->rhw, - .xs = vtx[0]->xs, - .ys = vtx[0]->ys, - .g = (float)vtx[0]->g, - }, - { - .xv = vtx[1]->xv, - .yv = vtx[1]->yv, - .zv = vtx[1]->zv, - .rhw = vtx[1]->rhw, - .xs = vtx[1]->xs, - .ys = vtx[1]->ys, - .g = (float)vtx[1]->g, - }, - { - .xv = vtx[2]->xv, - .yv = vtx[2]->yv, - .zv = vtx[2]->zv, - .rhw = vtx[2]->rhw, - .xs = vtx[2]->xs, - .ys = vtx[2]->ys, - .g = (float)vtx[2]->g, - }, - }; - - num_points = Output_ZedClipper(num_points, points, g_VBuffer); - if (num_points == 0) { - continue; - } - } - - if (clip_or != 0) { - num_points = Output_XYGClipper(num_points, g_VBuffer); - } - if (num_points == 0) { - continue; - } - - const PALETTEENTRY *const color = &g_GamePalette16[color_idx >> 8]; - Output_DrawPoly_Gouraud( - num_points, color->peRed, color->peGreen, color->peBlue); - } - - return obj_ptr; -} - -const int16_t *__cdecl Output_InsertObjectG4_ZBuffered( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type) -{ - HWR_TexSource(0); - HWR_EnableColorKey(0); - - if (num == 0) { - return obj_ptr; - } - - for (int32_t i = 0; i < num; i++) { - const PHD_VBUF *const vtx[4] = { - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - }; - const int16_t color_idx = *obj_ptr++; - int32_t num_points = 4; - - const int8_t clip_or = - vtx[0]->clip | vtx[1]->clip | vtx[2]->clip | vtx[3]->clip; - const int8_t clip_and = - vtx[0]->clip & vtx[1]->clip & vtx[2]->clip & vtx[3]->clip; - - if (clip_and != 0) { - continue; - } - - if (clip_or >= 0) { - if (!VBUF_VISIBLE(*vtx[0], *vtx[1], *vtx[2])) { - continue; - } - - g_VBuffer[0].x = vtx[0]->xs; - g_VBuffer[0].y = vtx[0]->ys; - g_VBuffer[0].rhw = vtx[0]->rhw; - g_VBuffer[0].g = (float)vtx[0]->g; - - g_VBuffer[1].x = vtx[1]->xs; - g_VBuffer[1].y = vtx[1]->ys; - g_VBuffer[1].rhw = vtx[1]->rhw; - g_VBuffer[1].g = (float)vtx[1]->g; - - g_VBuffer[2].x = vtx[2]->xs; - g_VBuffer[2].y = vtx[2]->ys; - g_VBuffer[2].rhw = vtx[2]->rhw; - g_VBuffer[2].g = (float)vtx[2]->g; - - g_VBuffer[3].x = vtx[3]->xs; - g_VBuffer[3].y = vtx[3]->ys; - g_VBuffer[3].rhw = vtx[3]->rhw; - g_VBuffer[3].g = (float)vtx[3]->g; - } else { - if (!Output_VisibleZClip(vtx[0], vtx[1], vtx[2])) { - continue; - } - - const POINT_INFO points[4] = { - { - .xv = vtx[0]->xv, - .yv = vtx[0]->yv, - .zv = vtx[0]->zv, - .rhw = vtx[0]->rhw, - .xs = vtx[0]->xs, - .ys = vtx[0]->ys, - .g = (float)vtx[0]->g, - }, - { - .xv = vtx[1]->xv, - .yv = vtx[1]->yv, - .zv = vtx[1]->zv, - .rhw = vtx[1]->rhw, - .xs = vtx[1]->xs, - .ys = vtx[1]->ys, - .g = (float)vtx[1]->g, - }, - { - .xv = vtx[2]->xv, - .yv = vtx[2]->yv, - .zv = vtx[2]->zv, - .rhw = vtx[2]->rhw, - .xs = vtx[2]->xs, - .ys = vtx[2]->ys, - .g = (float)vtx[2]->g, - }, - { - .xv = vtx[3]->xv, - .yv = vtx[3]->yv, - .zv = vtx[3]->zv, - .rhw = vtx[3]->rhw, - .xs = vtx[3]->xs, - .ys = vtx[3]->ys, - .g = (float)vtx[3]->g, - }, - }; - - num_points = Output_ZedClipper(num_points, points, g_VBuffer); - if (num_points == 0) { - continue; - } - } - - if (clip_or != 0) { - num_points = Output_XYGClipper(num_points, g_VBuffer); - } - if (num_points == 0) { - continue; - } - - const PALETTEENTRY *const color = &g_GamePalette16[color_idx >> 8]; - Output_DrawPoly_Gouraud( - num_points, color->peRed, color->peGreen, color->peBlue); - } - - return obj_ptr; -} - -const int16_t *__cdecl Output_InsertObjectGT3_ZBuffered( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type) -{ - for (int32_t i = 0; i < num; i++) { - const PHD_VBUF *const vtx[3] = { - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - }; - const PHD_TEXTURE *const texture = &g_PhdTextureInfo[*obj_ptr++]; - const PHD_UV *const uv = texture->uv; - - if (texture->draw_type != DRAW_OPAQUE && m_DiscardTransparent) { - continue; - } - - if (texture->draw_type != DRAW_OPAQUE) { - Output_InsertGT3_Sorted( - vtx[0], vtx[1], vtx[2], texture, &uv[0], &uv[1], &uv[2], - sort_type); - } else { - Output_InsertGT3_ZBuffered( - vtx[0], vtx[1], vtx[2], texture, &uv[0], &uv[1], &uv[2]); - } - } - - return obj_ptr; -} - -const int16_t *__cdecl Output_InsertObjectGT4_ZBuffered( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type) -{ - for (int32_t i = 0; i < num; i++) { - const PHD_VBUF *const vtx[4] = { - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - }; - const PHD_TEXTURE *const texture = &g_PhdTextureInfo[*obj_ptr++]; - const PHD_UV *const uv = texture->uv; - - if (texture->draw_type != DRAW_OPAQUE && m_DiscardTransparent) { - continue; - } - - if (texture->draw_type != DRAW_OPAQUE) { - Output_InsertGT4_Sorted( - vtx[0], vtx[1], vtx[2], vtx[3], texture, sort_type); - } else { - Output_InsertGT4_ZBuffered(vtx[0], vtx[1], vtx[2], vtx[3], texture); - } - } - - return obj_ptr; -} - -void __cdecl Output_InsertGT3_ZBuffered( - const PHD_VBUF *const vtx0, const PHD_VBUF *const vtx1, - const PHD_VBUF *const vtx2, const PHD_TEXTURE *const texture, - const PHD_UV *const uv0, const PHD_UV *const uv1, const PHD_UV *const uv2) -{ - const int8_t clip_or = vtx0->clip | vtx1->clip | vtx2->clip; - const int8_t clip_and = vtx0->clip & vtx1->clip & vtx2->clip; - if (clip_and != 0) { - return; - } - - int32_t num_points = 3; - - if (clip_or >= 0) { - if (!VBUF_VISIBLE(*vtx0, *vtx1, *vtx2)) { - return; - } - - if (clip_or == 0) { - g_VBufferD3D[0].sx = vtx0->xs; - g_VBufferD3D[0].sy = vtx0->ys; - g_VBufferD3D[0].sz = g_FltResZBuf - g_FltResZORhw * vtx0->rhw; - g_VBufferD3D[0].rhw = vtx0->rhw; - g_VBufferD3D[0].color = M_ShadeLight(vtx0->g); - g_VBufferD3D[0].tu = (double)uv0->u / (double)PHD_ONE; - g_VBufferD3D[0].tv = (double)uv0->v / (double)PHD_ONE; - - g_VBufferD3D[1].sx = vtx1->xs; - g_VBufferD3D[1].sy = vtx1->ys; - g_VBufferD3D[1].sz = g_FltResZBuf - g_FltResZORhw * vtx1->rhw; - g_VBufferD3D[1].rhw = vtx1->rhw; - g_VBufferD3D[1].color = M_ShadeLight(vtx1->g); - g_VBufferD3D[1].tu = (double)uv1->u / (double)PHD_ONE; - g_VBufferD3D[1].tv = (double)uv1->v / (double)PHD_ONE; - - g_VBufferD3D[2].sx = vtx2->xs; - g_VBufferD3D[2].sy = vtx2->ys; - g_VBufferD3D[2].sz = g_FltResZBuf - g_FltResZORhw * vtx2->rhw; - g_VBufferD3D[2].rhw = vtx2->rhw; - g_VBufferD3D[2].color = M_ShadeLight(vtx2->g); - g_VBufferD3D[2].tu = (double)uv2->u / (double)PHD_ONE; - g_VBufferD3D[2].tv = (double)uv2->v / (double)PHD_ONE; - - HWR_TexSource(g_HWR_PageHandles[texture->tex_page]); - HWR_EnableColorKey(texture->draw_type != DRAW_OPAQUE); - - HWR_DrawPrimitive(D3DPT_TRIANGLELIST, g_VBufferD3D, 3, true); - return; - } - - g_VBuffer[0].x = vtx0->xs; - g_VBuffer[0].y = vtx0->ys; - g_VBuffer[0].rhw = vtx0->rhw; - g_VBuffer[0].g = (double)vtx0->g; - g_VBuffer[0].u = (double)uv0->u * vtx0->rhw; - g_VBuffer[0].v = (double)uv0->v * vtx0->rhw; - - g_VBuffer[1].x = vtx1->xs; - g_VBuffer[1].y = vtx1->ys; - g_VBuffer[1].rhw = vtx1->rhw; - g_VBuffer[1].g = (double)vtx1->g; - g_VBuffer[1].u = (double)uv1->u * vtx1->rhw; - g_VBuffer[1].v = (double)uv1->v * vtx1->rhw; - - g_VBuffer[2].x = vtx2->xs; - g_VBuffer[2].y = vtx2->ys; - g_VBuffer[2].rhw = vtx2->rhw; - g_VBuffer[2].g = (double)vtx2->g; - g_VBuffer[2].u = (double)uv2->u * vtx2->rhw; - g_VBuffer[2].v = (double)uv2->v * vtx2->rhw; - } else { - if (!Output_VisibleZClip(vtx0, vtx1, vtx2)) { - return; - } - - const POINT_INFO points[3] = { - { - .xv = vtx0->xv, - .yv = vtx0->yv, - .zv = vtx0->zv, - .rhw = vtx0->rhw, - .xs = vtx0->xs, - .ys = vtx0->ys, - .g = (float)vtx0->g, - .u = (float)uv0->u, - .v = (float)uv0->v, - }, - - { - .xv = vtx1->xv, - .yv = vtx1->yv, - .zv = vtx1->zv, - .rhw = vtx1->rhw, - .xs = vtx1->xs, - .ys = vtx1->ys, - .g = (float)vtx1->g, - .u = (float)uv1->u, - .v = (float)uv1->v, - }, - - { - .xv = vtx2->xv, - .yv = vtx2->yv, - .zv = vtx2->zv, - .rhw = vtx2->rhw, - .xs = vtx2->xs, - .ys = vtx2->ys, - .g = (float)vtx2->g, - .u = (float)uv2->u, - .v = (float)uv2->v, - }, - }; - - num_points = Output_ZedClipper(num_points, points, g_VBuffer); - if (num_points == 0) { - return; - } - } - - num_points = Output_XYGUVClipper(num_points, g_VBuffer); - if (num_points == 0) { - return; - } - - HWR_TexSource(g_HWR_PageHandles[texture->tex_page]); - HWR_EnableColorKey(texture->draw_type != DRAW_OPAQUE); - Output_DrawClippedPoly_Textured(num_points); -} - -void __cdecl Output_InsertGT4_ZBuffered( - const PHD_VBUF *const vtx0, const PHD_VBUF *const vtx1, - const PHD_VBUF *const vtx2, const PHD_VBUF *const vtx3, - const PHD_TEXTURE *const texture) -{ - const int8_t clip_and = vtx0->clip & vtx1->clip & vtx2->clip & vtx3->clip; - const int8_t clip_or = vtx0->clip | vtx1->clip | vtx2->clip | vtx3->clip; - - if (clip_and != 0) { - return; - } - - if (clip_or >= 0) { - if (!VBUF_VISIBLE(*vtx0, *vtx1, *vtx2)) { - return; - } - } else if (clip_or < 0) { - if (!Output_VisibleZClip(vtx0, vtx1, vtx2)) { - return; - } - } - - if (clip_or != 0) { - Output_InsertGT3_ZBuffered( - vtx0, vtx1, vtx2, texture, texture->uv, &texture->uv[1], - &texture->uv[2]); - Output_InsertGT3_ZBuffered( - vtx0, vtx2, vtx3, texture, texture->uv, &texture->uv[2], - &texture->uv[3]); - return; - } - - g_VBufferD3D[0].sx = vtx0->xs; - g_VBufferD3D[0].sy = vtx0->ys; - g_VBufferD3D[0].sz = g_FltResZBuf - g_FltResZORhw * vtx0->rhw; - g_VBufferD3D[0].rhw = vtx0->rhw; - g_VBufferD3D[0].color = M_ShadeLight(vtx0->g); - g_VBufferD3D[0].tu = (double)texture->uv[0].u / (double)PHD_ONE; - g_VBufferD3D[0].tv = (double)texture->uv[0].v / (double)PHD_ONE; - - g_VBufferD3D[1].sx = vtx1->xs; - g_VBufferD3D[1].sy = vtx1->ys; - g_VBufferD3D[1].sz = g_FltResZBuf - g_FltResZORhw * vtx1->rhw; - g_VBufferD3D[1].rhw = vtx1->rhw; - g_VBufferD3D[1].color = M_ShadeLight(vtx1->g); - g_VBufferD3D[1].tu = (double)texture->uv[1].u / (double)PHD_ONE; - g_VBufferD3D[1].tv = (double)texture->uv[1].v / (double)PHD_ONE; - - g_VBufferD3D[2].sx = vtx2->xs; - g_VBufferD3D[2].sy = vtx2->ys; - g_VBufferD3D[2].sz = g_FltResZBuf - g_FltResZORhw * vtx2->rhw; - g_VBufferD3D[2].rhw = vtx2->rhw; - g_VBufferD3D[2].color = M_ShadeLight(vtx2->g); - g_VBufferD3D[2].tu = (double)texture->uv[2].u / (double)PHD_ONE; - g_VBufferD3D[2].tv = (double)texture->uv[2].v / (double)PHD_ONE; - - g_VBufferD3D[3].sx = vtx3->xs; - g_VBufferD3D[3].sy = vtx3->ys; - g_VBufferD3D[3].sz = g_FltResZBuf - g_FltResZORhw * vtx3->rhw; - g_VBufferD3D[3].rhw = vtx3->rhw; - g_VBufferD3D[3].color = M_ShadeLight(vtx3->g); - g_VBufferD3D[3].tu = (double)texture->uv[3].u / (double)PHD_ONE; - g_VBufferD3D[3].tv = (double)texture->uv[3].v / (double)PHD_ONE; - - HWR_TexSource(g_HWR_PageHandles[texture->tex_page]); - HWR_EnableColorKey(texture->draw_type != DRAW_OPAQUE); - HWR_DrawPrimitive(D3DPT_TRIANGLEFAN, g_VBufferD3D, 4, true); -} - -void __cdecl Output_InsertFlatRect_ZBuffered( - int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t z, - const uint8_t color_idx) -{ - if (x2 <= x1 || y2 <= y1) { - return; - } - - CLAMPL(x1, g_PhdWinMinX); - CLAMPL(y1, g_PhdWinMinY); - CLAMPG(x2, g_PhdWinMinX + g_PhdWinWidth); - CLAMPG(y2, g_PhdWinMinY + g_PhdWinHeight); - CLAMP(z, g_PhdNearZ, g_PhdFarZ); - - const double rhw = g_RhwFactor / (double)z; - const double sz = g_FltResZBuf - rhw * g_FltResZORhw; - - const RGB_888 *const color = &g_GamePalette8[color_idx]; - const D3DCOLOR d3d_color = - M_ShadeColor(color->red, color->green, color->blue, 0xFF); - - g_VBufferD3D[0].sx = (float)x1; - g_VBufferD3D[0].sy = (float)y1; - g_VBufferD3D[1].sx = (float)x2; - g_VBufferD3D[1].sy = (float)y1; - g_VBufferD3D[2].sx = (float)x1; - g_VBufferD3D[2].sy = (float)y2; - g_VBufferD3D[3].sx = (float)x2; - g_VBufferD3D[3].sy = (float)y2; - for (int32_t i = 0; i < 4; i++) { - g_VBufferD3D[i].sz = sz; - g_VBufferD3D[i].rhw = rhw; - g_VBufferD3D[i].color = d3d_color; - } - - HWR_TexSource(0); - HWR_EnableColorKey(0); - HWR_DrawPrimitive(D3DPT_TRIANGLESTRIP, g_VBufferD3D, 4, true); -} - -void __cdecl Output_InsertLine_ZBuffered( - const int32_t x1, const int32_t y1, const int32_t x2, const int32_t y2, - int32_t z, const uint8_t color_idx) -{ - if (z >= g_PhdFarZ) { - return; - } - CLAMPL(z, g_PhdNearZ); - - const double rhw = g_RhwFactor / (double)z; - const double sz = g_FltResZBuf - rhw * g_FltResZORhw; - - const RGB_888 *const color = &g_GamePalette8[color_idx]; - const D3DCOLOR d3d_color = - M_ShadeColor(color->red, color->green, color->blue, 0xFF); - - g_VBufferD3D[0].sx = (float)(g_PhdWinMinX + x1); - g_VBufferD3D[0].sy = (float)(g_PhdWinMinY + y1); - g_VBufferD3D[1].sx = (float)(g_PhdWinMinX + x2); - g_VBufferD3D[1].sy = (float)(g_PhdWinMinY + y2); - - for (int32_t i = 0; i < 2; i++) { - g_VBufferD3D[i].sz = sz; - g_VBufferD3D[i].rhw = rhw; - g_VBufferD3D[i].color = d3d_color; - } - - HWR_TexSource(0); - HWR_EnableColorKey(0); - HWR_DrawPrimitive(D3DPT_LINESTRIP, g_VBufferD3D, 2, true); -} - -const int16_t *__cdecl Output_InsertObjectG3_Sorted( - const int16_t *obj_ptr, const int32_t num, const SORT_TYPE sort_type) -{ - for (int32_t i = 0; i < num; i++) { - if (HWR_VertexBufferFull()) { - obj_ptr += (num - i) * 4; - break; - } - - int32_t num_points = 3; - const PHD_VBUF *vtx[3] = { - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - }; - const int16_t color_idx = *obj_ptr++; - - const int8_t clip_or = vtx[0]->clip | vtx[1]->clip | vtx[2]->clip; - const int8_t clip_and = vtx[0]->clip & vtx[1]->clip & vtx[2]->clip; - if (clip_and != 0) { - continue; - } - - if (clip_or >= 0) { - if (!VBUF_VISIBLE(*vtx[0], *vtx[1], *vtx[2])) { - continue; - } - - g_VBuffer[0].x = vtx[0]->xs; - g_VBuffer[0].y = vtx[0]->ys; - g_VBuffer[0].rhw = vtx[0]->rhw; - g_VBuffer[0].g = (float)vtx[0]->g; - - g_VBuffer[1].x = vtx[1]->xs; - g_VBuffer[1].y = vtx[1]->ys; - g_VBuffer[1].rhw = vtx[1]->rhw; - g_VBuffer[1].g = (float)vtx[1]->g; - - g_VBuffer[2].x = vtx[2]->xs; - g_VBuffer[2].y = vtx[2]->ys; - g_VBuffer[2].rhw = vtx[2]->rhw; - g_VBuffer[2].g = (float)vtx[2]->g; - - if (clip_or > 0) { - num_points = Output_XYGClipper(num_points, g_VBuffer); - } - } else { - if (!Output_VisibleZClip(vtx[0], vtx[1], vtx[2])) { - continue; - } - - const POINT_INFO pts[3] = { - { - .xv = vtx[0]->xv, - .yv = vtx[0]->yv, - .zv = vtx[0]->zv, - .rhw = vtx[0]->rhw, - .xs = vtx[0]->xs, - .ys = vtx[0]->ys, - .g = (float)vtx[0]->g, - }, - - { - .xv = vtx[1]->xv, - .yv = vtx[1]->yv, - .zv = vtx[1]->zv, - .rhw = vtx[1]->rhw, - .xs = vtx[1]->xs, - .ys = vtx[1]->ys, - .g = (float)vtx[1]->g, - }, - - { - .xv = vtx[2]->xv, - .yv = vtx[2]->yv, - .zv = vtx[2]->zv, - .rhw = vtx[2]->rhw, - .xs = vtx[2]->xs, - .ys = vtx[2]->ys, - .g = (float)vtx[2]->g, - }, - }; - - num_points = Output_ZedClipper(num_points, pts, g_VBuffer); - if (num_points == 0) { - continue; - } - - num_points = Output_XYGClipper(num_points, g_VBuffer); - } - - if (num_points == 0) { - continue; - } - - const PALETTEENTRY *const color = &g_GamePalette16[color_idx >> 8]; - const double zv = M_CalculatePolyZ( - sort_type, vtx[0]->zv, vtx[1]->zv, vtx[2]->zv, -1.0); - Output_InsertPoly_Gouraud( - num_points, zv, color->peRed, color->peGreen, color->peBlue, - POLY_HWR_GOURAUD); - } - - return obj_ptr; -} - -const int16_t *__cdecl Output_InsertObjectG4_Sorted( - const int16_t *obj_ptr, const int32_t num, const SORT_TYPE sort_type) -{ - for (int32_t i = 0; i < num; i++) { - if (HWR_VertexBufferFull()) { - obj_ptr += (num - i) * 5; - break; - } - - int32_t num_points = 4; - const PHD_VBUF *const vtx[4] = { - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - }; - const int16_t color_idx = *obj_ptr++; - - const int8_t clip_or = - vtx[0]->clip | vtx[1]->clip | vtx[2]->clip | vtx[3]->clip; - const int8_t clip_and = - vtx[0]->clip & vtx[1]->clip & vtx[2]->clip & vtx[3]->clip; - if (clip_and != 0) { - continue; - } - - if (clip_or >= 0) { - if (!VBUF_VISIBLE(*vtx[0], *vtx[1], *vtx[2])) { - continue; - } - - g_VBuffer[0].x = vtx[0]->xs; - g_VBuffer[0].y = vtx[0]->ys; - g_VBuffer[0].rhw = vtx[0]->rhw; - g_VBuffer[0].g = (float)vtx[0]->g; - - g_VBuffer[1].x = vtx[1]->xs; - g_VBuffer[1].y = vtx[1]->ys; - g_VBuffer[1].rhw = vtx[1]->rhw; - g_VBuffer[1].g = (float)vtx[1]->g; - - g_VBuffer[2].x = vtx[2]->xs; - g_VBuffer[2].y = vtx[2]->ys; - g_VBuffer[2].rhw = vtx[2]->rhw; - g_VBuffer[2].g = (float)vtx[2]->g; - - g_VBuffer[3].x = vtx[3]->xs; - g_VBuffer[3].y = vtx[3]->ys; - g_VBuffer[3].rhw = vtx[3]->rhw; - g_VBuffer[3].g = (float)vtx[3]->g; - - if (clip_or > 0) { - num_points = Output_XYGClipper(num_points, g_VBuffer); - } - } else { - if (!Output_VisibleZClip(vtx[0], vtx[1], vtx[2])) { - continue; - } - - const POINT_INFO pts[4] = { - { - .xv = vtx[0]->xv, - .yv = vtx[0]->yv, - .zv = vtx[0]->zv, - .rhw = vtx[0]->rhw, - .xs = vtx[0]->xs, - .ys = vtx[0]->ys, - .g = (float)vtx[0]->g, - }, - - { - .xv = vtx[1]->xv, - .yv = vtx[1]->yv, - .zv = vtx[1]->zv, - .rhw = vtx[1]->rhw, - .xs = vtx[1]->xs, - .ys = vtx[1]->ys, - .g = (float)vtx[1]->g, - }, - - { - .xv = vtx[2]->xv, - .yv = vtx[2]->yv, - .zv = vtx[2]->zv, - .rhw = vtx[2]->rhw, - .xs = vtx[2]->xs, - .ys = vtx[2]->ys, - .g = (float)vtx[2]->g, - }, - - { - .xv = vtx[3]->xv, - .yv = vtx[3]->yv, - .zv = vtx[3]->zv, - .rhw = vtx[3]->rhw, - .xs = vtx[3]->xs, - .ys = vtx[3]->ys, - .g = (float)vtx[3]->g, - }, - }; - - num_points = Output_ZedClipper(num_points, pts, g_VBuffer); - if (num_points == 0) { - continue; - } - - num_points = Output_XYGClipper(num_points, g_VBuffer); - } - - if (num_points == 0) { - continue; - } - - const PALETTEENTRY *const color = &g_GamePalette16[color_idx >> 8]; - const double zv = M_CalculatePolyZ( - sort_type, vtx[0]->zv, vtx[1]->zv, vtx[2]->zv, vtx[3]->zv); - Output_InsertPoly_Gouraud( - num_points, zv, color->peRed, color->peGreen, color->peBlue, - POLY_HWR_GOURAUD); - } - - return obj_ptr; -} - -const int16_t *__cdecl Output_InsertObjectGT3_Sorted( - const int16_t *obj_ptr, const int32_t num, const SORT_TYPE sort_type) -{ - for (int32_t i = 0; i < num; i++) { - if (HWR_VertexBufferFull()) { - obj_ptr += (num - i) * 4; - break; - } - - const PHD_VBUF *const vtx[3] = { - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - }; - const int16_t texture_idx = *obj_ptr++; - const PHD_TEXTURE *const texture = &g_PhdTextureInfo[texture_idx]; - const PHD_UV *const uv = texture->uv; - - if (texture->draw_type != DRAW_OPAQUE && m_DiscardTransparent) { - continue; - } - - Output_InsertGT3_Sorted( - vtx[0], vtx[1], vtx[2], texture, &uv[0], &uv[1], &uv[2], sort_type); - } - - return obj_ptr; -} - -const int16_t *__cdecl Output_InsertObjectGT4_Sorted( - const int16_t *obj_ptr, const int32_t num, const SORT_TYPE sort_type) -{ - for (int32_t i = 0; i < num; i++) { - if (HWR_VertexBufferFull()) { - obj_ptr += (num - i) * 5; - break; - } - - const PHD_VBUF *const vtx[4] = { - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - &g_PhdVBuf[*obj_ptr++], - }; - const int16_t texture_idx = *obj_ptr++; - const PHD_TEXTURE *const texture = &g_PhdTextureInfo[texture_idx]; - - if (texture->draw_type != DRAW_OPAQUE && m_DiscardTransparent) { - continue; - } - - Output_InsertGT4_Sorted( - vtx[0], vtx[1], vtx[2], vtx[3], texture, sort_type); - } - - return obj_ptr; -} - -void __cdecl Output_InsertGT3_Sorted( - const PHD_VBUF *const vtx0, const PHD_VBUF *const vtx1, - const PHD_VBUF *const vtx2, const PHD_TEXTURE *const texture, - const PHD_UV *const uv0, const PHD_UV *const uv1, const PHD_UV *const uv2, - const SORT_TYPE sort_type) -{ - const int8_t clip_or = vtx0->clip | vtx1->clip | vtx2->clip; - const int8_t clip_and = vtx0->clip & vtx1->clip & vtx2->clip; - if (clip_and != 0) { - return; - } - - const double zv = - M_CalculatePolyZ(sort_type, vtx0->zv, vtx1->zv, vtx2->zv, -1.0); - const POLY_TYPE poly_type = - texture->draw_type == DRAW_OPAQUE ? POLY_HWR_GTMAP : POLY_HWR_WGTMAP; - - int32_t num_points = 3; - if (clip_or >= 0) { - if (!VBUF_VISIBLE(*vtx0, *vtx1, *vtx2)) { - return; - } - - if (clip_or == 0) { - g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; - g_Sort3DPtr->_1 = MAKE_ZSORT(zv); - g_Sort3DPtr++; - - *g_Info3DPtr++ = poly_type; - *g_Info3DPtr++ = texture->tex_page; - *g_Info3DPtr++ = num_points; - *(D3DTLVERTEX **)g_Info3DPtr = g_HWR_VertexPtr; - g_Info3DPtr += sizeof(D3DTLVERTEX *) / sizeof(int16_t); - - g_HWR_VertexPtr[0].sx = vtx0->xs; - g_HWR_VertexPtr[0].sy = vtx0->ys; - g_HWR_VertexPtr[0].rhw = vtx0->rhw; - g_HWR_VertexPtr[0].color = M_ShadeLight(vtx0->g); - g_HWR_VertexPtr[0].tu = (double)uv0->u / (double)PHD_ONE; - g_HWR_VertexPtr[0].tv = (double)uv0->v / (double)PHD_ONE; - - g_HWR_VertexPtr[1].sx = vtx1->xs; - g_HWR_VertexPtr[1].sy = vtx1->ys; - g_HWR_VertexPtr[1].rhw = vtx1->rhw; - g_HWR_VertexPtr[1].color = M_ShadeLight(vtx1->g); - g_HWR_VertexPtr[1].tu = (double)uv1->u / (double)PHD_ONE; - g_HWR_VertexPtr[1].tv = (double)uv1->v / (double)PHD_ONE; - - g_HWR_VertexPtr[2].sx = vtx2->xs; - g_HWR_VertexPtr[2].sy = vtx2->ys; - g_HWR_VertexPtr[2].rhw = vtx2->rhw; - g_HWR_VertexPtr[2].color = M_ShadeLight(vtx2->g); - g_HWR_VertexPtr[2].tu = (double)uv2->u / (double)PHD_ONE; - g_HWR_VertexPtr[2].tv = (double)uv2->v / (double)PHD_ONE; - - if (g_SavedAppSettings.zbuffer) { - g_HWR_VertexPtr[0].sz = - g_FltResZBuf - g_FltResZORhw * vtx0->rhw; - g_HWR_VertexPtr[1].sz = - g_FltResZBuf - g_FltResZORhw * vtx1->rhw; - g_HWR_VertexPtr[2].sz = - g_FltResZBuf - g_FltResZORhw * vtx2->rhw; - } - - g_HWR_VertexPtr += 3; - g_SurfaceCount++; - return; - } - - g_VBuffer[0].x = vtx0->xs; - g_VBuffer[0].y = vtx0->ys; - g_VBuffer[0].rhw = vtx0->rhw; - g_VBuffer[0].g = (double)vtx0->g; - g_VBuffer[0].u = (double)uv0->u * vtx0->rhw; - g_VBuffer[0].v = (double)uv0->v * vtx0->rhw; - - g_VBuffer[1].x = vtx1->xs; - g_VBuffer[1].y = vtx1->ys; - g_VBuffer[1].rhw = vtx1->rhw; - g_VBuffer[1].g = (double)vtx1->g; - g_VBuffer[1].u = (double)uv1->u * vtx1->rhw; - g_VBuffer[1].v = (double)uv1->v * vtx1->rhw; - - g_VBuffer[2].x = vtx2->xs; - g_VBuffer[2].y = vtx2->ys; - g_VBuffer[2].rhw = vtx2->rhw; - g_VBuffer[2].g = (double)vtx2->g; - g_VBuffer[2].u = (double)uv2->u * vtx2->rhw; - g_VBuffer[2].v = (double)uv2->v * vtx2->rhw; - } else { - if (!Output_VisibleZClip(vtx0, vtx1, vtx2)) { - return; - } - - const POINT_INFO pts[3] = { - { - .xv = vtx0->xv, - .yv = vtx0->yv, - .zv = vtx0->zv, - .rhw = vtx0->rhw, - .xs = vtx0->xs, - .ys = vtx0->ys, - .g = (float)vtx0->g, - .u = (float)uv0->u, - .v = (float)uv0->v, - }, - - { - .xv = vtx1->xv, - .yv = vtx1->yv, - .zv = vtx1->zv, - .rhw = vtx1->rhw, - .xs = vtx1->xs, - .ys = vtx1->ys, - .g = (float)vtx1->g, - .u = (float)uv1->u, - .v = (float)uv1->v, - }, - - { - .xv = vtx2->xv, - .yv = vtx2->yv, - .zv = vtx2->zv, - .rhw = vtx2->rhw, - .xs = vtx2->xs, - .ys = vtx2->ys, - .g = (float)vtx2->g, - .u = (float)uv2->u, - .v = (float)uv2->v, - }, - }; - - num_points = Output_ZedClipper(num_points, pts, g_VBuffer); - if (num_points == 0) { - return; - } - } - - num_points = Output_XYGUVClipper(num_points, g_VBuffer); - if (num_points == 0) { - return; - } - - Output_InsertClippedPoly_Textured( - num_points, zv, poly_type, texture->tex_page); -} - -void __cdecl Output_InsertGT4_Sorted( - const PHD_VBUF *const vtx0, const PHD_VBUF *const vtx1, - const PHD_VBUF *const vtx2, const PHD_VBUF *const vtx3, - const PHD_TEXTURE *const texture, const SORT_TYPE sort_type) -{ - const int8_t clip_or = vtx0->clip | vtx1->clip | vtx2->clip | vtx3->clip; - const int8_t clip_and = vtx0->clip & vtx1->clip & vtx2->clip & vtx3->clip; - if (clip_and != 0) { - return; - } - - const double zv = - M_CalculatePolyZ(sort_type, vtx0->zv, vtx1->zv, vtx2->zv, vtx3->zv); - const POLY_TYPE poly_type = - texture->draw_type == DRAW_OPAQUE ? POLY_HWR_GTMAP : POLY_HWR_WGTMAP; - - int32_t num_points = 4; - if (clip_or >= 0) { - if (!VBUF_VISIBLE(*vtx0, *vtx1, *vtx2)) { - return; - } - - if (clip_or == 0) { - g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; - g_Sort3DPtr->_1 = MAKE_ZSORT(zv); - g_Sort3DPtr++; - - g_Info3DPtr[0] = poly_type; - g_Info3DPtr[1] = texture->tex_page; - g_Info3DPtr[2] = num_points; - *(int32_t *)(&g_Info3DPtr[3]) = (int32_t)g_HWR_VertexPtr; - g_Info3DPtr += 5; - - g_HWR_VertexPtr[0].sx = vtx0->xs; - g_HWR_VertexPtr[0].sy = vtx0->ys; - g_HWR_VertexPtr[0].rhw = vtx0->rhw; - g_HWR_VertexPtr[0].color = M_ShadeLight(vtx0->g); - g_HWR_VertexPtr[0].tu = (double)texture->uv[0].u / (double)PHD_ONE; - g_HWR_VertexPtr[0].tv = (double)texture->uv[0].v / (double)PHD_ONE; - - g_HWR_VertexPtr[1].sx = vtx1->xs; - g_HWR_VertexPtr[1].sy = vtx1->ys; - g_HWR_VertexPtr[1].rhw = vtx1->rhw; - g_HWR_VertexPtr[1].color = M_ShadeLight(vtx1->g); - g_HWR_VertexPtr[1].tu = (double)texture->uv[1].u / (double)PHD_ONE; - g_HWR_VertexPtr[1].tv = (double)texture->uv[1].v / (double)PHD_ONE; - - g_HWR_VertexPtr[2].sx = vtx2->xs; - g_HWR_VertexPtr[2].sy = vtx2->ys; - g_HWR_VertexPtr[2].rhw = vtx2->rhw; - g_HWR_VertexPtr[2].color = M_ShadeLight(vtx2->g); - g_HWR_VertexPtr[2].tu = (double)texture->uv[2].u / (double)PHD_ONE; - g_HWR_VertexPtr[2].tv = (double)texture->uv[2].v / (double)PHD_ONE; - - g_HWR_VertexPtr[3].sx = vtx3->xs; - g_HWR_VertexPtr[3].sy = vtx3->ys; - g_HWR_VertexPtr[3].rhw = vtx3->rhw; - g_HWR_VertexPtr[3].color = M_ShadeLight(vtx3->g); - g_HWR_VertexPtr[3].tu = (double)texture->uv[3].u / (double)PHD_ONE; - g_HWR_VertexPtr[3].tv = (double)texture->uv[3].v / (double)PHD_ONE; - - if (g_SavedAppSettings.zbuffer) { - g_HWR_VertexPtr[0].sz = - g_FltResZBuf - g_FltResZORhw * vtx0->rhw; - g_HWR_VertexPtr[1].sz = - g_FltResZBuf - g_FltResZORhw * vtx1->rhw; - g_HWR_VertexPtr[2].sz = - g_FltResZBuf - g_FltResZORhw * vtx2->rhw; - g_HWR_VertexPtr[3].sz = - g_FltResZBuf - g_FltResZORhw * vtx3->rhw; - } - - g_HWR_VertexPtr += 4; - g_SurfaceCount++; - return; - } - - Output_InsertGT3_Sorted( - vtx0, vtx1, vtx2, texture, &texture->uv[0], &texture->uv[1], - &texture->uv[2], sort_type); - Output_InsertGT3_Sorted( - vtx0, vtx2, vtx3, texture, &texture->uv[0], &texture->uv[2], - &texture->uv[3], sort_type); - } else { - if (!Output_VisibleZClip(vtx0, vtx1, vtx2)) { - return; - } - - Output_InsertGT3_Sorted( - vtx0, vtx1, vtx2, texture, &texture->uv[0], &texture->uv[1], - &texture->uv[2], sort_type); - Output_InsertGT3_Sorted( - vtx0, vtx2, vtx3, texture, &texture->uv[0], &texture->uv[2], - &texture->uv[3], sort_type); - } -} - -void __cdecl Output_InsertFlatRect_Sorted( - int32_t x1, int32_t y1, int32_t x2, int32_t y2, const int32_t z, - const uint8_t color_idx) -{ - if (x2 <= x1 || y2 <= y1) { - return; - } - - CLAMPL(x1, g_PhdWinMinX); - CLAMPL(y1, g_PhdWinMinY); - CLAMPG(x2, g_PhdWinMinX + g_PhdWinWidth); - CLAMPG(y2, g_PhdWinMinY + g_PhdWinHeight); - - g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; - g_Sort3DPtr->_1 = MAKE_ZSORT(z); - g_Sort3DPtr++; - - *g_Info3DPtr++ = POLY_HWR_GOURAUD; - *g_Info3DPtr++ = 4; - *(D3DTLVERTEX **)g_Info3DPtr = g_HWR_VertexPtr; - g_Info3DPtr += sizeof(D3DTLVERTEX *) / sizeof(int16_t); - - const RGB_888 *const color = &g_GamePalette8[color_idx]; - const D3DCOLOR d3d_color = - M_ShadeColor(color->red, color->green, color->blue, 0xFF); - - g_HWR_VertexPtr[0].sx = (float)x1; - g_HWR_VertexPtr[0].sy = (float)y1; - g_HWR_VertexPtr[1].sx = (float)x2; - g_HWR_VertexPtr[1].sy = (float)y1; - g_HWR_VertexPtr[2].sx = (float)x2; - g_HWR_VertexPtr[2].sy = (float)y2; - g_HWR_VertexPtr[3].sx = (float)x1; - g_HWR_VertexPtr[3].sy = (float)y2; - - for (int32_t i = 0; i < 4; i++) { - g_HWR_VertexPtr[i].color = d3d_color; - // TODO: missing sz and rhw initialization - } - - g_HWR_VertexPtr += 4; - g_SurfaceCount++; -} - -void __cdecl Output_InsertLine_Sorted( - const int32_t x1, const int32_t y1, const int32_t x2, const int32_t y2, - int32_t z, const uint8_t color_idx) -{ - const RGB_888 *const color = &g_GamePalette8[color_idx]; - const D3DCOLOR d3d_color = - M_ShadeColor(color->red, color->green, color->blue, 0xFF); - - g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; - g_Sort3DPtr->_1 = MAKE_ZSORT(z); - g_Sort3DPtr++; - - *g_Info3DPtr++ = POLY_HWR_LINE; - *g_Info3DPtr++ = 2; - *(D3DTLVERTEX **)g_Info3DPtr = g_HWR_VertexPtr; - g_Info3DPtr += sizeof(D3DTLVERTEX *) / sizeof(int16_t); - - g_HWR_VertexPtr[0].sx = (float)(g_PhdWinMinX + x1); - g_HWR_VertexPtr[0].sy = (float)(g_PhdWinMinY + y1); - g_HWR_VertexPtr[1].sx = (float)(g_PhdWinMinX + x2); - g_HWR_VertexPtr[1].sy = (float)(g_PhdWinMinY + y2); - - for (int32_t i = 0; i < 2; i++) { - g_HWR_VertexPtr[i].color = d3d_color; - // TODO: missing sz and rhw initialization - } - - g_HWR_VertexPtr += 2; - g_SurfaceCount++; -} - -void __cdecl Output_InsertSprite_Sorted( - int32_t z, int32_t x0, int32_t y0, int32_t x1, int32_t y1, - const int32_t sprite_idx, const int16_t shade) -{ - if (HWR_VertexBufferFull() || x0 >= x1 || y0 >= y1 || x1 <= 0 || y1 <= 0 - || x0 >= g_PhdWinMaxX || y0 >= g_PhdWinMaxY || z >= g_PhdFarZ) { - return; - } - - x0 += g_PhdWinMinX; - x1 += g_PhdWinMinX; - y0 += g_PhdWinMinY; - y1 += g_PhdWinMinY; - - CLAMPL(z, g_PhdNearZ); - - int32_t num_points = 4; - - const PHD_SPRITE *const sprite = &g_PhdSprites[sprite_idx]; - const double rhw = g_RhwFactor / (double)z; - const int32_t u_offset = (sprite->offset & 0xFF) * 256; - const int32_t v_offset = (sprite->offset >> 8) * 256; - - const int32_t adjustment = g_UVAdd; - const double u0 = (double)(u_offset - adjustment + sprite->width) * rhw; - const double u1 = (double)(u_offset + adjustment) * rhw; - const double v1 = (double)(v_offset - adjustment + sprite->height) * rhw; - const double v0 = (double)(v_offset + adjustment) * rhw; - - g_VBuffer[0].x = (float)x0; - g_VBuffer[0].y = (float)y0; - g_VBuffer[0].u = u1; - g_VBuffer[0].v = v0; - - g_VBuffer[1].x = (float)x1; - g_VBuffer[1].y = (float)y0; - g_VBuffer[1].u = u0; - g_VBuffer[1].v = v0; - - g_VBuffer[2].x = (float)x1; - g_VBuffer[2].y = (float)y1; - g_VBuffer[2].u = u0; - g_VBuffer[2].v = v1; - - g_VBuffer[3].x = (float)x0; - g_VBuffer[3].y = (float)y1; - g_VBuffer[3].u = u1; - g_VBuffer[3].v = v1; - - for (int32_t i = 0; i < 4; i++) { - g_VBuffer[i].rhw = rhw; - g_VBuffer[i].g = (float)shade; - } - - if (x0 < g_PhdWinMinX || y0 < g_PhdWinMinY - || x1 > g_PhdWinMinX + g_PhdWinWidth - || y1 > g_PhdWinMinY + g_PhdWinHeight) { - g_FltWinLeft = (float)g_PhdWinMinX; - g_FltWinTop = (float)g_PhdWinMinY; - g_FltWinRight = (float)(g_PhdWinMinX + g_PhdWinWidth); - g_FltWinBottom = (float)(g_PhdWinMinY + g_PhdWinHeight); - num_points = Output_XYGUVClipper(num_points, g_VBuffer); - if (num_points == 0) { - return; - } - } - - const bool old_shade = g_IsShadeEffect; - g_IsShadeEffect = 0; - Output_InsertClippedPoly_Textured( - num_points, z, POLY_HWR_WGTMAP, sprite->tex_page); - g_IsShadeEffect = old_shade; -} - -void __cdecl Output_InsertTrans8_Sorted( - const PHD_VBUF *const vbuf, const int16_t shade) -{ - int8_t clip_or = 0x00; - int8_t clip_and = 0xFF; - int32_t num_vtx = 8; - - for (int32_t i = 0; i < num_vtx; i++) { - clip_or |= vbuf[i].clip; - clip_and &= vbuf[i].clip; - } - - if (clip_or < 0 || clip_and != 0 - || !VBUF_VISIBLE(vbuf[0], vbuf[1], vbuf[2])) { - return; - } - - for (int32_t i = 0; i < num_vtx; i++) { - g_VBuffer[i].x = vbuf[i].xs; - g_VBuffer[i].y = vbuf[i].ys; - g_VBuffer[i].rhw = g_RhwFactor / (double)(vbuf[i].zv - 0x20000); - } - - int32_t num_points = num_vtx; - if (clip_or != 0) { - g_FltWinLeft = (float)g_PhdWinMinX; - g_FltWinTop = (float)g_PhdWinMinY; - g_FltWinRight = (float)(g_PhdWinMinX + g_PhdWinWidth); - g_FltWinBottom = (float)(g_PhdWinMinY + g_PhdWinHeight); - num_points = Output_XYClipper(num_points, g_VBuffer); - if (num_points == 0) { - return; - } - } - - int32_t poly_z = 0; - for (int32_t i = 0; i < num_vtx; i++) { - poly_z += vbuf[i].zv; - } - poly_z /= num_vtx; - - Output_InsertPoly_Gouraud( - num_points, (double)(poly_z - 0x20000), 0, 0, 0, POLY_HWR_TRANS); -} - -void __cdecl Output_InsertTransQuad_Sorted( - const int32_t x, const int32_t y, const int32_t width, const int32_t height, - const int32_t z) -{ - const double x0 = (double)x; - const double y0 = (double)y; - const double x1 = (double)(x + width); - const double y1 = (double)(y + height); - - g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; - g_Sort3DPtr->_1 = MAKE_ZSORT(z); - g_Sort3DPtr++; - - *g_Info3DPtr++ = POLY_HWR_TRANS; - *g_Info3DPtr++ = 4; - *(D3DTLVERTEX **)g_Info3DPtr = g_HWR_VertexPtr; - g_Info3DPtr += sizeof(D3DTLVERTEX *) / sizeof(int16_t); - - g_HWR_VertexPtr[0].sx = x0; - g_HWR_VertexPtr[0].sy = y0; - g_HWR_VertexPtr[1].sx = x1; - g_HWR_VertexPtr[1].sy = y0; - g_HWR_VertexPtr[2].sx = x1; - g_HWR_VertexPtr[2].sy = y1; - g_HWR_VertexPtr[3].sx = x0; - g_HWR_VertexPtr[3].sy = y1; - - for (int32_t i = 0; i < 4; i++) { - g_HWR_VertexPtr[i].color = 0x80000000; - } - - if (g_SavedAppSettings.zbuffer) { - const double rhw = g_RhwFactor / (double)z; - const double sz = g_FltResZBuf - rhw * g_FltResZORhw; - for (int32_t i = 0; i < 4; i++) { - g_HWR_VertexPtr[i].rhw = rhw; - g_HWR_VertexPtr[i].sz = sz; - } - } - - g_HWR_VertexPtr += 4; - g_SurfaceCount++; -} - -void __cdecl Output_InsertSprite( - const int32_t z, const int32_t x0, const int32_t y0, const int32_t x1, - const int32_t y1, const int32_t sprite_idx, const int16_t shade) -{ - g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; - g_Sort3DPtr->_1 = MAKE_ZSORT(z); - g_Sort3DPtr++; - - *g_Info3DPtr++ = POLY_SPRITE; - *g_Info3DPtr++ = x0; - *g_Info3DPtr++ = y0; - *g_Info3DPtr++ = x1; - *g_Info3DPtr++ = y1; - *g_Info3DPtr++ = sprite_idx; - *g_Info3DPtr++ = shade; - g_SurfaceCount++; -} - const int16_t *__cdecl Output_InsertRoomSprite( const int16_t *obj_ptr, const int32_t vtx_count) { @@ -4099,120 +450,13 @@ const int16_t *__cdecl Output_InsertRoomSprite( g_PhdWinCenterY + (vbuf->yv + (sprite->y1 << W2V_SHIFT)) / persp; if (x1 >= g_PhdWinLeft && y1 >= g_PhdWinTop && x0 < g_PhdWinRight && y0 < g_PhdWinBottom) { - g_Output_InsertSprite( - vbuf->zv, x0, y0, x1, y1, sprite_idx, vbuf->g); + Render_InsertSprite(vbuf->zv, x0, y0, x1, y1, sprite_idx, vbuf->g); } } return obj_ptr; } -void __cdecl Output_InsertClippedPoly_Textured( - const int32_t vtx_count, const float z, const int16_t poly_type, - const int16_t tex_page) -{ - g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; - g_Sort3DPtr->_1 = MAKE_ZSORT(z); - g_Sort3DPtr++; - - *g_Info3DPtr++ = poly_type; - *g_Info3DPtr++ = tex_page; - *g_Info3DPtr++ = vtx_count; - *(D3DTLVERTEX **)g_Info3DPtr = g_HWR_VertexPtr; - g_Info3DPtr += sizeof(D3DTLVERTEX *) / sizeof(int16_t); - - for (int32_t i = 0; i < vtx_count; i++) { - double tu = g_VBuffer[i].u / (double)PHD_ONE / g_VBuffer[i].rhw; - double tv = g_VBuffer[i].v / (double)PHD_ONE / g_VBuffer[i].rhw; - CLAMP(tu, 0.0, 1.0); - CLAMP(tv, 0.0, 1.0); - - g_HWR_VertexPtr[i].sx = g_VBuffer[i].x; - g_HWR_VertexPtr[i].sy = g_VBuffer[i].y; - if (g_SavedAppSettings.zbuffer) { - g_HWR_VertexPtr[i].sz = - g_FltResZBuf - g_FltResZORhw * g_VBuffer[i].rhw; - } - g_HWR_VertexPtr[i].rhw = g_VBuffer[i].rhw; - g_HWR_VertexPtr[i].color = M_ShadeLight(g_VBuffer[i].g); - g_HWR_VertexPtr[i].tu = tu; - g_HWR_VertexPtr[i].tv = tv; - } - - g_HWR_VertexPtr += vtx_count; - g_SurfaceCount++; -} - -void __cdecl Output_InsertPoly_Gouraud( - const int32_t vtx_count, const float z, const int32_t red, - const int32_t green, const int32_t blue, const int16_t poly_type) -{ - g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; - g_Sort3DPtr->_1 = MAKE_ZSORT(z); - g_Sort3DPtr++; - - *g_Info3DPtr++ = poly_type; - *g_Info3DPtr++ = vtx_count; - *(D3DTLVERTEX **)g_Info3DPtr = g_HWR_VertexPtr; - g_Info3DPtr += sizeof(D3DTLVERTEX *) / sizeof(int16_t); - - for (int32_t i = 0; i < vtx_count; i++) { - g_HWR_VertexPtr[i].sx = g_VBuffer[i].x; - g_HWR_VertexPtr[i].sy = g_VBuffer[i].y; - if (g_SavedAppSettings.zbuffer) { - g_HWR_VertexPtr[i].sz = - g_FltResZBuf - g_FltResZORhw * g_VBuffer[i].rhw; - } - g_HWR_VertexPtr[i].rhw = g_VBuffer[i].rhw; - g_HWR_VertexPtr[i].color = M_ShadeLightColor( - g_VBuffer[i].g, red, green, blue, - poly_type == POLY_HWR_TRANS ? 0x80 : 0xFF); - } - - g_HWR_VertexPtr += vtx_count; - g_SurfaceCount++; -} - -void __cdecl Output_DrawClippedPoly_Textured(const int32_t vtx_count) -{ - for (int32_t i = 0; i < vtx_count; i++) { - const VERTEX_INFO *const vbuf = &g_VBuffer[i]; - D3DTLVERTEX *const vbuf_d3d = &g_VBufferD3D[i]; - vbuf_d3d->sx = vbuf->x; - vbuf_d3d->sy = vbuf->y; - vbuf_d3d->sz = g_FltResZBuf - g_FltResZORhw * vbuf->rhw; - vbuf_d3d->rhw = vbuf->rhw; - vbuf_d3d->color = M_ShadeLight(vbuf->g); - - double tu = vbuf->u / (double)PHD_ONE / vbuf->rhw; - double tv = vbuf->v / (double)PHD_ONE / vbuf->rhw; - CLAMP(tu, 0.0, 1.0); - CLAMP(tv, 0.0, 1.0); - - vbuf_d3d->tv = tv; - vbuf_d3d->tu = tu; - } - - HWR_DrawPrimitive(D3DPT_TRIANGLEFAN, g_VBufferD3D, vtx_count, true); -} - -void __cdecl Output_DrawPoly_Gouraud( - const int32_t vtx_count, const int32_t red, const int32_t green, - const int32_t blue) -{ - for (int32_t i = 0; i < vtx_count; i++) { - const VERTEX_INFO *vbuf = &g_VBuffer[i]; - D3DTLVERTEX *vbuf_d3d = &g_VBufferD3D[i]; - vbuf_d3d->sx = vbuf->x; - vbuf_d3d->sy = vbuf->y; - vbuf_d3d->sz = g_FltResZBuf - g_FltResZORhw * vbuf->rhw; - vbuf_d3d->rhw = vbuf->rhw; - vbuf_d3d->color = M_ShadeLightColor(vbuf->g, red, green, blue, 0xFF); - } - - HWR_DrawPrimitive(D3DPT_TRIANGLEFAN, g_VBufferD3D, vtx_count, true); -} - void __cdecl Output_DrawSprite( const uint32_t flags, int32_t x, int32_t y, int32_t z, const int16_t sprite_idx, int16_t shade, const int16_t scale) @@ -4294,7 +538,6 @@ void __cdecl Output_DrawSprite( return; } - shade; if (flags & SPRF_SHADE) { const int32_t depth = zv >> W2V_SHIFT; if (depth > FOG_START) { @@ -4307,7 +550,7 @@ void __cdecl Output_DrawSprite( shade = 0x1000; } - g_Output_InsertSprite(zv, x0, y0, x1, y1, sprite_idx, shade); + Render_InsertSprite(zv, x0, y0, x1, y1, sprite_idx, shade); } void __cdecl Output_DrawPickup( @@ -4320,7 +563,7 @@ void __cdecl Output_DrawPickup( const int32_t x1 = sx + ((sprite->x1 * scale) / PHD_ONE); const int32_t y1 = sy + ((sprite->y1 * scale) / PHD_ONE); if (x1 >= 0 && y1 >= 0 && x0 < g_PhdWinWidth && y0 < g_PhdWinHeight) { - g_Output_InsertSprite(200, x0, y0, x1, y1, sprite_idx, shade); + Render_InsertSprite(200, x0, y0, x1, y1, sprite_idx, shade); } } @@ -4336,7 +579,7 @@ void __cdecl Output_DrawScreenSprite2D( const int32_t y1 = sy + ((sprite->y1 * scale_v) / PHD_ONE); const int32_t z = g_PhdNearZ + sz * 8; if (x1 >= 0 && y1 >= 0 && x0 < g_PhdWinWidth && y0 < g_PhdWinHeight) { - g_Output_InsertSprite(z, x0, y0, x1, y1, sprite_idx, shade); + Render_InsertSprite(z, x0, y0, x1, y1, sprite_idx, shade); } } @@ -4352,203 +595,226 @@ void __cdecl Output_DrawScreenSprite( const int32_t y1 = sy + (((sprite->y1 / 8) * scale_v) / PHD_ONE); const int32_t z = sz * 8; if (x1 >= 0 && y1 >= 0 && x0 < g_PhdWinWidth && y0 < g_PhdWinHeight) { - g_Output_InsertSprite(z, x0, y0, x1, y1, sprite_idx, shade); - } -} - -void __cdecl Output_DrawScaledSpriteC(const int16_t *const obj_ptr) -{ - int32_t x0 = obj_ptr[0]; - int32_t y0 = obj_ptr[1]; - int32_t x1 = obj_ptr[2]; - int32_t y1 = obj_ptr[3]; - const int16_t sprite_idx = obj_ptr[4]; - const int16_t shade = obj_ptr[5]; - - if (x0 >= x1 || y0 >= y1 || x1 <= 0 || y1 <= 0 || x0 >= g_PhdWinMaxX - || y0 >= g_PhdWinMaxY) { - return; - } - - const DEPTHQ_ENTRY *const depth_q = &g_DepthQTable[shade >> 8]; - const PHD_SPRITE *const sprite = &g_PhdSprites[sprite_idx]; - - int32_t u_base = 0x4000; - int32_t v_base = 0x4000; - const int32_t u_add = ((sprite->width - 64) << 8) / (x1 - x0); - const int32_t v_add = ((sprite->height - 64) << 8) / (y1 - y0); - - if (x0 < 0) { - u_base -= x0 * u_add; - x0 = 0; - } - if (y0 < 0) { - v_base -= y0 * v_add; - y0 = 0; - } - CLAMPG(x1, g_PhdWinMaxX + 1); - CLAMPG(y1, g_PhdWinMaxY + 1); - - const int32_t stride = g_PhdScreenWidth; - const int32_t width = x1 - x0; - const int32_t height = y1 - y0; - - const uint8_t *const src_base = - &g_TexturePageBuffer8[sprite->tex_page][sprite->offset]; - uint8_t *dst = - &g_PrintSurfacePtr[(g_PhdWinMinY + y0) * stride + g_PhdWinMinX + x0]; - const int32_t dst_add = stride - width; - - const bool is_depth_q = - depth_q != &g_DepthQTable[16] || g_GameVid_IsWindowedVGA; - - for (int32_t i = 0; i < height; i++) { - int32_t u = u_base; - const uint8_t *const src = &src_base[(v_base >> 16) << 8]; - for (int32_t j = 0; j < width; j++) { - const uint8_t pix = src[u >> 16]; - if (pix != 0) { - *dst = is_depth_q ? depth_q->index[pix] : pix; - } - u += u_add; - dst++; - } - dst += dst_add; - v_base += v_add; + Render_InsertSprite(z, x0, y0, x1, y1, sprite_idx, shade); } } bool __cdecl Output_MakeScreenshot(const char *const path) { LOG_INFO("Taking screenshot"); - - LPDDS screen = g_SavedAppSettings.render_mode == RM_SOFTWARE - ? g_RenderBufferSurface - : g_BackBufferSurface; - - DDSURFACEDESC desc = { .dwSize = sizeof(DDSURFACEDESC) }; - HRESULT rc; - while (true) { - rc = IDirectDrawSurface_GetSurfaceDesc(screen, &desc); - if (rc != DDERR_WASSTILLDRAWING) { - break; - } - } - if (rc == DDERR_SURFACELOST) { - IDirectDrawSurface_Restore(screen); - } - if (FAILED(rc)) { - LOG_ERROR("Failed to get surface description: %x", rc); - return false; - } - - rc = WinVidBufferLock(screen, &desc, DDLOCK_WRITEONLY | DDLOCK_WAIT); - if (FAILED(rc)) { - LOG_ERROR("Failed to lock surface: %x", rc); - return false; - } - - const int32_t src_x = 0; - const int32_t src_y = 0; - const int32_t width = g_GameVid_Width; - const int32_t height = g_GameVid_Height; - IMAGE *const image = Image_Create(width, height); - - for (int32_t y = 0; y < height; y++) { - const uint8_t *src = desc.lpSurface + desc.lPitch * (y + src_y); - src += src_x * (desc.ddpfPixelFormat.dwRGBBitCount / 8); - - IMAGE_PIXEL *dst = &image->data[width * y]; - switch (desc.ddpfPixelFormat.dwRGBBitCount) { - case 8: - ASSERT(desc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8); - for (int32_t x = 0; x < width; x++) { - dst->r = g_GamePalette8[*src].red; - dst->g = g_GamePalette8[*src].green; - dst->b = g_GamePalette8[*src].blue; - src++; - dst++; - } - break; - - case 16: - if (desc.ddpfPixelFormat.dwRBitMask == 0xF800) { - for (int32_t x = 0; x < width; x++) { - dst->r = (*(uint16_t *)src & 0xF800) >> 8; - dst->g = (*(uint16_t *)src & 0x07E0) >> 3; - dst->b = (*(uint16_t *)src & 0x001F) << 3; - dst++; - src += 2; - } - } else { - for (int32_t x = 0; x < width; x++) { - dst->r = (*(uint16_t *)src & 0x001F) << 3; - dst->g = (*(uint16_t *)src & 0x07E0) >> 3; - dst->b = (*(uint16_t *)src & 0xF800) >> 8; - dst++; - src += 2; - } - } - break; - - case 24: - if (desc.ddpfPixelFormat.dwRBitMask == 255) { - for (int32_t x = 0; x < width; x++) { - dst->r = src[0]; - dst->g = src[1]; - dst->b = src[2]; - dst++; - src += 3; - } - } else { - for (int32_t x = 0; x < width; x++) { - dst->r = src[2]; - dst->g = src[1]; - dst->b = src[0]; - dst++; - src += 3; - } - } - break; - - case 32: - if (desc.ddpfPixelFormat.dwRBitMask == 255) { - for (int32_t x = 0; x < width; x++) { - dst->r = src[0]; - dst->g = src[1]; - dst->b = src[2]; - dst++; - src += 4; - } - } else { - for (int32_t x = 0; x < width; x++) { - dst->r = src[2]; - dst->g = src[1]; - dst->b = src[0]; - dst++; - src += 4; - } - } - } - } - - const bool ret = Image_SaveToFile(image, path); - Image_Free(image); - WinVidBufferUnlock(screen, &desc); - return ret; + GFX_Context_ScheduleScreenshot(path); + return true; } -void Output_ClearDepthBuffer(void) +void Output_BeginScene(void) { - if (g_SavedAppSettings.render_mode == RM_HARDWARE) { - DWORD d3dClearFlags = D3DCLEAR_ZBUFFER; + g_MatrixPtr = g_MatrixStack; + Render_BeginScene(); +} - D3DRECT d3dRect; - d3dRect.x1 = g_PhdWinRect.left; - d3dRect.y1 = g_PhdWinRect.top; - d3dRect.x2 = g_PhdWinRect.right; - d3dRect.y2 = g_PhdWinRect.bottom; +int32_t Output_EndScene(void) +{ + const int32_t passed = Clock_WaitTick(); + Render_EndScene(); + Shell_ProcessEvents(); + return passed; +} - g_D3DView->lpVtbl->Clear(g_D3DView, 1, &d3dRect, d3dClearFlags); +void Output_LoadBackgroundFromFile(const char *const file_name) +{ + IMAGE *const image = Image_CreateFromFile(file_name); + Render_LoadBackgroundFromImage(image); + Image_Free(image); +} + +void Output_LoadBackgroundFromObject(void) +{ + const OBJECT *const obj = &g_Objects[O_INV_BACKGROUND]; + if (!obj->loaded) { + return; + } + + const int16_t *mesh_ptr = g_Meshes[obj->mesh_idx]; + mesh_ptr += 5; + const int32_t num_vertices = *mesh_ptr++; + mesh_ptr += num_vertices * 3; + + const int32_t num_normals = *mesh_ptr++; + if (num_normals >= 0) { + mesh_ptr += num_normals * 3; + } else { + mesh_ptr -= num_normals; + } + const int32_t num_quads = *mesh_ptr++; + if (num_quads < 1) { + return; + } + + mesh_ptr += 4; + + const int32_t texture_idx = *mesh_ptr++; + const PHD_TEXTURE *const texture = &g_TextureInfo[texture_idx]; + Render_LoadBackgroundFromTexture(texture, 8, 6); + return; +} + +void Output_UnloadBackground(void) +{ + Render_UnloadBackground(); +} + +void Output_InsertBackPolygon( + const int32_t x0, const int32_t y0, const int32_t x1, const int32_t y1) +{ + Render_InsertFlatRect(x0, y0, x1, y1, g_PhdFarZ + 1, g_InvColors[0]); +} + +void Output_DrawBlackRectangle(int32_t opacity) +{ + Render_DrawBlackRectangle(opacity); +} + +void Output_DrawBackground(void) +{ + Render_DrawBackground(); +} + +void Output_DrawPolyList(void) +{ + Render_DrawPolyList(); +} + +void Output_DrawScreenLine( + const int32_t x, const int32_t y, const int32_t z, const int32_t x_len, + const int32_t y_len, const uint8_t color_idx, const void *const gour, + const uint16_t flags) +{ + Render_InsertLine( + x, y, x + x_len, y + y_len, g_PhdNearZ + 8 * z, color_idx); +} + +void Output_DrawScreenBox( + const int32_t sx, const int32_t sy, const int32_t z, const int32_t width, + const int32_t height, const uint8_t color_idx, const void *const gour, + const uint16_t flags) +{ + const int32_t col_1 = 15; + const int32_t col_2 = 31; + Output_DrawScreenLine(sx, sy - 1, z, width + 1, 0, col_1, NULL, flags); + Output_DrawScreenLine(sx + 1, sy, z, width - 1, 0, col_2, NULL, flags); + Output_DrawScreenLine( + sx + width, sy + 1, z, 0, height - 1, col_1, NULL, flags); + Output_DrawScreenLine( + sx + width + 1, sy, z, 0, height + 1, col_2, NULL, flags); + Output_DrawScreenLine(sx - 1, sy - 1, z, 0, height + 1, col_1, NULL, flags); + Output_DrawScreenLine(sx, sy, z, 0, height - 1, col_2, NULL, flags); + Output_DrawScreenLine(sx, height + sy, z, width - 1, 0, col_1, NULL, flags); + Output_DrawScreenLine( + sx - 1, height + sy + 1, z, width + 1, 0, col_2, NULL, flags); +} + +void Output_DrawScreenFBox( + const int32_t sx, const int32_t sy, const int32_t z, const int32_t width, + const int32_t height, const uint8_t color_idx, const void *const gour, + const uint16_t flags) +{ + Render_InsertTransQuad(sx, sy, width + 1, height + 1, g_PhdNearZ + 8 * z); +} + +void __cdecl Output_DrawHealthBar(const int32_t percent) +{ + g_IsShadeEffect = false; + M_InsertBar(6, 6, 105, 9, percent, INV_COLOR_RED, INV_COLOR_ORANGE); +} + +void __cdecl Output_DrawAirBar(const int32_t percent) +{ + g_IsShadeEffect = false; + M_InsertBar( + g_PhdWinWidth - 112, 6, 105, 9, percent, INV_COLOR_BLUE, + INV_COLOR_WHITE); +} + +int16_t Output_FindColor( + const int32_t red, const int32_t green, const int32_t blue) +{ + int32_t best_idx = 0; + int32_t best_diff = INT32_MAX; + for (int32_t i = 0; i < 256; i++) { + const int32_t dr = red - g_GamePalette8[i].red; + const int32_t dg = green - g_GamePalette8[i].green; + const int32_t db = blue - g_GamePalette8[i].blue; + const int32_t diff = SQUARE(dr) + SQUARE(dg) + SQUARE(db); + if (diff < best_diff) { + best_diff = diff; + best_idx = i; + } + } + + return best_idx; +} + +void __cdecl Output_AnimateTextures(const int32_t ticks) +{ + m_TickComp += ticks; + while (m_TickComp > TICKS_PER_FRAME * 5) { + const int16_t *ptr = g_AnimTextureRanges; + int16_t i = *(ptr++); + for (; i > 0; --i, ++ptr) { + int16_t j = *(ptr++); + const PHD_TEXTURE temp = g_TextureInfo[*ptr]; + for (; j > 0; --j, ++ptr) { + g_TextureInfo[ptr[0]] = g_TextureInfo[ptr[1]]; + } + g_TextureInfo[*ptr] = temp; + } + m_TickComp -= TICKS_PER_FRAME * 5; } } + +void __cdecl Output_InsertShadow( + int16_t radius, const BOUNDS_16 *bounds, const ITEM *item) +{ + const int32_t x1 = bounds->min_x; + const int32_t x2 = bounds->max_x; + const int32_t z1 = bounds->min_z; + const int32_t z2 = bounds->max_z; + const int32_t mid_x = (x1 + x2) / 2; + const int32_t mid_z = (z1 + z2) / 2; + const int32_t x_add = radius * (x2 - x1) / 1024; + const int32_t z_add = radius * (z2 - z1) / 1024; + + struct { + int16_t poly_count; + int16_t vertex_count; + XYZ_16 vertex[8]; + } shadow_info = { + .poly_count = 1, + .vertex_count = 8, + .vertex = { + { .x = mid_x - x_add, .z = mid_z + z_add * 2 }, + { .x = mid_x + x_add, .z = mid_z + z_add * 2 }, + { .x = mid_x + x_add * 2, .z = z_add + mid_z }, + { .x = mid_x + x_add * 2, .z = mid_z - z_add }, + { .x = mid_x + x_add, .z = mid_z - 2 * z_add }, + { .x = mid_x - x_add, .z = mid_z - 2 * z_add }, + { .x = mid_x - 2 * x_add, .z = mid_z - z_add }, + { .x = mid_x - 2 * x_add, .z = z_add + mid_z }, + }, + }; + + g_FltWinLeft = (float)(g_PhdWinLeft); + g_FltWinTop = (float)(g_PhdWinTop); + g_FltWinRight = (float)(g_PhdWinRight + 1); + g_FltWinBottom = (float)(g_PhdWinBottom + 1); + g_FltWinCenterX = (float)(g_PhdWinCenterX); + g_FltWinCenterY = (float)(g_PhdWinCenterY); + + Matrix_Push(); + Matrix_TranslateAbs(item->pos.x, item->floor, item->pos.z); + Matrix_RotY(item->rot.y); + if (Output_CalcObjectVertices((int16_t *)&shadow_info)) { + Render_InsertTransOctagon(g_PhdVBuf, 24); + } + Matrix_Pop(); +} diff --git a/src/tr2/game/output.h b/src/tr2/game/output.h index dd468bc3b..46e7ededa 100644 --- a/src/tr2/game/output.h +++ b/src/tr2/game/output.h @@ -4,10 +4,15 @@ #include -void __cdecl Output_Init( - int16_t x, int16_t y, int32_t width, int32_t height, int32_t near_z, - int32_t far_z, int16_t view_angle, int32_t screen_width, - int32_t screen_height); +typedef struct { + float x; + float y; + float z; + float rhw; + float u; + float v; + float g; +} VERTEX_INFO; void __cdecl Output_InsertPolygons(const int16_t *obj_ptr, int32_t clip); void __cdecl Output_InsertPolygons_I(const int16_t *ptr, int32_t clip); @@ -19,125 +24,8 @@ const int16_t *__cdecl Output_CalcVerticeLight(const int16_t *obj_ptr); const int16_t *__cdecl Output_CalcRoomVertices( const int16_t *obj_ptr, int32_t far_clip); void __cdecl Output_RotateLight(int16_t pitch, int16_t yaw); -void __cdecl Output_InitPolyList(void); -void __cdecl Output_SortPolyList(void); -void __cdecl Output_QuickSort(int32_t left, int32_t right); -void __cdecl Output_PrintPolyList(uint8_t *surface_ptr); void __cdecl Output_AlterFOV(int16_t fov); -void __cdecl Output_DrawPolyLine(const int16_t *obj_ptr); -void __cdecl Output_DrawPolyFlat(const int16_t *obj_ptr); -void __cdecl Output_DrawPolyTrans(const int16_t *obj_ptr); -void __cdecl Output_DrawPolyGouraud(const int16_t *obj_ptr); -void __cdecl Output_DrawPolyGTMap(const int16_t *obj_ptr); -void __cdecl Output_DrawPolyWGTMap(const int16_t *obj_ptr); -void __cdecl Output_DrawPolyGTMapPersp(const int16_t *obj_ptr); -void __cdecl Output_DrawPolyWGTMapPersp(const int16_t *obj_ptr); - -int32_t __cdecl Output_XGenX(const int16_t *obj_ptr); -int32_t __cdecl Output_XGenXG(const int16_t *obj_ptr); -int32_t __cdecl Output_XGenXGUV(const int16_t *obj_ptr); -int32_t __cdecl Output_XGenXGUVPerspFP(const int16_t *obj_ptr); -void __cdecl Output_GTMapPersp32FP( - int32_t y1, int32_t y2, const uint8_t *tex_page); -void __cdecl Output_WGTMapPersp32FP( - int32_t y1, int32_t y2, const uint8_t *tex_page); - -int32_t __cdecl Output_VisibleZClip( - const PHD_VBUF *vtx0, const PHD_VBUF *vtx1, const PHD_VBUF *vtx2); -int32_t __cdecl Output_ZedClipper( - int32_t vtx_count, const POINT_INFO *pts, VERTEX_INFO *vtx); -int32_t __cdecl Output_XYClipper(int32_t vtx_count, VERTEX_INFO *vtx); -int32_t __cdecl Output_XYGClipper(int32_t vtx_count, VERTEX_INFO *vtx); -int32_t __cdecl Output_XYGUVClipper(int32_t vtx_count, VERTEX_INFO *vtx); - -const int16_t *__cdecl Output_InsertObjectG3( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); -const int16_t *__cdecl Output_InsertObjectG4( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); -const int16_t *__cdecl Output_InsertObjectGT3( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); -const int16_t *__cdecl Output_InsertObjectGT4( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); - -void __cdecl Output_InsertTrans8(const PHD_VBUF *vbuf, int16_t shade); -void __cdecl Output_InsertTransQuad( - int32_t x, int32_t y, int32_t width, int32_t height, int32_t z); -void __cdecl Output_InsertFlatRect( - int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t z, - uint8_t color_idx); -void __cdecl Output_InsertLine( - int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t z, - uint8_t color_idx); - -const int16_t *__cdecl Output_InsertObjectG3_ZBuffered( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); -const int16_t *__cdecl Output_InsertObjectG4_ZBuffered( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); -const int16_t *__cdecl Output_InsertObjectGT3_ZBuffered( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); -const int16_t *__cdecl Output_InsertObjectGT4_ZBuffered( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); - -void __cdecl Output_InsertGT3_ZBuffered( - const PHD_VBUF *vtx0, const PHD_VBUF *vtx1, const PHD_VBUF *vtx2, - const PHD_TEXTURE *texture, const PHD_UV *uv0, const PHD_UV *uv1, - const PHD_UV *uv2); - -void __cdecl Output_InsertGT4_ZBuffered( - const PHD_VBUF *vtx0, const PHD_VBUF *vtx1, const PHD_VBUF *vtx2, - const PHD_VBUF *vtx3, const PHD_TEXTURE *texture); - -void __cdecl Output_InsertFlatRect_ZBuffered( - int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t z, - uint8_t color_idx); - -void __cdecl Output_InsertLine_ZBuffered( - int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t z, - uint8_t color_idx); - -const int16_t *__cdecl Output_InsertObjectG3_Sorted( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); - -const int16_t *__cdecl Output_InsertObjectG4_Sorted( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); - -const int16_t *__cdecl Output_InsertObjectGT3_Sorted( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); - -const int16_t *__cdecl Output_InsertObjectGT4_Sorted( - const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); - -void __cdecl Output_InsertGT3_Sorted( - const PHD_VBUF *vtx0, const PHD_VBUF *vtx1, const PHD_VBUF *vtx2, - const PHD_TEXTURE *texture, const PHD_UV *uv0, const PHD_UV *uv1, - const PHD_UV *uv2, SORT_TYPE sort_type); - -void __cdecl Output_InsertGT4_Sorted( - const PHD_VBUF *vtx0, const PHD_VBUF *vtx1, const PHD_VBUF *vtx2, - const PHD_VBUF *vtx3, const PHD_TEXTURE *texture, SORT_TYPE sort_type); - -void __cdecl Output_InsertFlatRect_Sorted( - int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t z, - uint8_t color_idx); - -void __cdecl Output_InsertLine_Sorted( - int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t z, - uint8_t color_idx); - -void __cdecl Output_InsertSprite_Sorted( - int32_t z, int32_t x0, int32_t y0, int32_t x1, int32_t y1, - int32_t sprite_idx, int16_t shade); - -void __cdecl Output_InsertTrans8_Sorted(const PHD_VBUF *vbuf, int16_t shade); - -void __cdecl Output_InsertTransQuad_Sorted( - int32_t x, int32_t y, int32_t width, int32_t height, int32_t z); - -void __cdecl Output_InsertSprite( - int32_t z, int32_t x0, int32_t y0, int32_t x1, int32_t y1, - int32_t sprite_idx, int16_t shade); - const int16_t *__cdecl Output_InsertRoomSprite( const int16_t *obj_ptr, int32_t vtx_count); @@ -173,3 +61,36 @@ void __cdecl Output_DrawScaledSpriteC(const int16_t *obj_ptr); void Output_ClearDepthBuffer(void); bool __cdecl Output_MakeScreenshot(const char *path); + +void Output_InsertBackPolygon(int32_t x0, int32_t y0, int32_t x1, int32_t y1); + +void Output_DrawBlackRectangle(int32_t opacity); +void Output_DrawBackground(void); +void Output_DrawPolyList(void); + +void Output_DrawScreenLine( + int32_t x, int32_t y, int32_t z, int32_t x_len, int32_t y_len, + uint8_t color_idx, const void *gour, uint16_t flags); + +void Output_DrawScreenBox( + int32_t sx, int32_t sy, int32_t z, int32_t width, int32_t height, + uint8_t color_idx, const void *gour, uint16_t flags); + +void Output_DrawScreenFBox( + int32_t sx, int32_t sy, int32_t z, int32_t width, int32_t height, + uint8_t color_idx, const void *gour, uint16_t flags); + +void __cdecl Output_DrawHealthBar(int32_t percent); +void __cdecl Output_DrawAirBar(int32_t percent); + +void Output_LoadBackgroundFromFile(const char *file_name); +void Output_LoadBackgroundFromObject(void); +void Output_UnloadBackground(void); + +void Output_BeginScene(void); +int32_t Output_EndScene(void); + +int16_t Output_FindColor(int32_t red, int32_t green, int32_t blue); +void __cdecl Output_AnimateTextures(int32_t ticks); +void __cdecl Output_InsertShadow( + int16_t radius, const BOUNDS_16 *bounds, const ITEM *item); diff --git a/src/tr2/game/overlay.c b/src/tr2/game/overlay.c index 556f026af..5237ed4b6 100644 --- a/src/tr2/game/overlay.c +++ b/src/tr2/game/overlay.c @@ -9,9 +9,7 @@ #include "game/music.h" #include "game/objects/common.h" #include "game/output.h" -#include "game/text.h" #include "game/viewport.h" -#include "global/const.h" #include "global/funcs.h" #include "global/vars.h" @@ -136,16 +134,6 @@ void __cdecl Overlay_DrawAssaultTimer(void) void __cdecl Overlay_DrawGameInfo(const bool pickup_state) { - S_OutputPolyList(); - Output_ClearDepthBuffer(); - // TODO: this distinction is only about preventing S_InitialisePolyList - // from clearing the buffers - if (g_SavedAppSettings.render_mode == RM_HARDWARE) { - S_InitialisePolyList(false); - } else { - Output_InitPolyList(); - } - Overlay_DrawAmmoInfo(); Overlay_DrawModeInfo(); if (g_OverlayStatus > 0) { @@ -230,9 +218,9 @@ void Overlay_DrawHealthBar(void) const int32_t percent = hit_points * 100 / LARA_MAX_HITPOINTS; if (hit_points <= LARA_MAX_HITPOINTS / 4) { - S_DrawHealthBar(m_FlashState ? percent : 0); + Output_DrawHealthBar(m_FlashState ? percent : 0); } else if (g_HealthBarTimer > 0 || g_Lara.gun_status == LGS_READY) { - S_DrawHealthBar(percent); + Output_DrawHealthBar(percent); } } @@ -247,9 +235,9 @@ void Overlay_DrawAirBar(void) CLAMP(air, 0, LARA_MAX_AIR); const int32_t percent = air * 100 / LARA_MAX_AIR; if (air <= 450) { - S_DrawAirBar(m_FlashState ? percent : 0); + Output_DrawAirBar(m_FlashState ? percent : 0); } else { - S_DrawAirBar(percent); + Output_DrawAirBar(percent); } } @@ -395,11 +383,10 @@ static void M_DrawPickup3D(const DISPLAY_PICKUP *const pickup) const int32_t vp_width = cell_width; const int32_t vp_height = cell_height; - const int32_t vp_src_x = old_vp.x + old_vp.width + offscreen_offset; - const int32_t vp_dst_x = old_vp.x + old_vp.width - - (cell_width / 2 + padding_right) - pickup->grid_x * cell_width; - const int32_t vp_src_y = - old_vp.y + old_vp.height - (cell_height / 2 + padding_bottom); + const int32_t vp_src_x = old_vp.width + offscreen_offset; + const int32_t vp_dst_x = old_vp.width - (cell_width / 2 + padding_right) + - pickup->grid_x * cell_width; + const int32_t vp_src_y = old_vp.height - (cell_height / 2 + padding_bottom); const int32_t vp_dst_y = vp_src_y - pickup->grid_y * cell_height; const int32_t vp_x = vp_src_x + (vp_dst_x - vp_src_x) * ease; const int32_t vp_y = vp_src_y + (vp_dst_y - vp_src_y) * ease; @@ -455,16 +442,16 @@ static void M_DrawPickup3D(const DISPLAY_PICKUP *const pickup) static void M_DrawPickupSprite(const DISPLAY_PICKUP *const pickup) { const int32_t sprite_height = - MIN(GetRenderWidth(), GetRenderHeight() * 640 / 480) / 10; + MIN(g_PhdWinWidth, g_PhdWinHeight * 640 / 480) / 10; const int32_t sprite_width = sprite_height * 4 / 3; const int32_t x = - GetRenderWidth() - sprite_height - sprite_width * pickup->grid_x; + g_PhdWinWidth - sprite_height - sprite_width * pickup->grid_x; const int32_t y = - GetRenderHeight() - sprite_height - sprite_height * pickup->grid_y; + g_PhdWinHeight - sprite_height - sprite_height * pickup->grid_y; // TODO: use proper scaling - const int32_t scale = 12288 * GetRenderWidth() / 640; + const int32_t scale = 12288 * g_PhdWinWidth / 640; const int16_t sprite_num = pickup->object->mesh_idx; Output_DrawPickup(x, y, scale, sprite_num, 4096); } diff --git a/src/tr2/game/render/common.c b/src/tr2/game/render/common.c new file mode 100644 index 000000000..ebd67f16c --- /dev/null +++ b/src/tr2/game/render/common.c @@ -0,0 +1,366 @@ +#include "game/render/common.h" + +#include "config.h" +#include "decomp/decomp.h" +#include "game/render/hwr.h" +#include "game/render/priv.h" +#include "game/render/swr.h" +#include "game/render/util.h" +#include "game/shell.h" +#include "global/vars.h" + +#include +#include +#include +#include +#include + +static RENDERER m_Renderer_SW = { 0 }; +static RENDERER m_Renderer_HW = { 0 }; +static RENDERER *m_PreviousRenderer = NULL; +static GFX_FADE_RENDERER *m_FadeRenderer = NULL; +static GFX_2D_RENDERER *m_BackgroundRenderer = NULL; + +static struct { + bool ready; + GFX_2D_SURFACE *surface; + const PHD_TEXTURE *texture; + int32_t repeat_x; + int32_t repeat_y; +} m_Background = { 0 }; + +static RENDERER *M_GetRenderer(void); +static void M_ReuploadBackground(void); +static void M_ResetPolyList(void); + +static RENDERER *M_GetRenderer(void) +{ + RENDERER *r = NULL; + if (g_Config.rendering.render_mode == RM_SOFTWARE) { + r = &m_Renderer_SW; + } else if (g_Config.rendering.render_mode == RM_HARDWARE) { + r = &m_Renderer_HW; + } + ASSERT(r != NULL); + return r; +} + +static void M_ReuploadBackground(void) +{ + // Toggling the bilinear filter causes the texture UVs to be readjusted + // depending on the player's settings. Because the texture UVs are cached + // on the GPU by Render_LoadBackgroundFromTexture, they need to be updated + // whenever the UVs readjust. + if (m_Background.texture != NULL) { + Render_LoadBackgroundFromTexture( + m_Background.texture, m_Background.repeat_x, m_Background.repeat_y); + } +} + +static void M_ResetPolyList(void) +{ + g_SurfaceCount = 0; + g_Sort3DPtr = g_SortBuffer; + g_Info3DPtr = g_Info3DBuffer; + + RENDERER *const r = M_GetRenderer(); + if (r->ResetPolyList != NULL) { + r->ResetPolyList(r); + } +} + +void Render_Init(void) +{ + LOG_DEBUG(""); + GFX_Context_Attach(g_SDLWindow, GFX_GL_33C); + GFX_Context_SetRenderingMode(GFX_RM_FRAMEBUFFER); + m_FadeRenderer = GFX_FadeRenderer_Create(); + m_BackgroundRenderer = GFX_2D_Renderer_Create(); + Renderer_SW_Prepare(&m_Renderer_SW); + Renderer_HW_Prepare(&m_Renderer_HW); +} + +void Render_Shutdown(void) +{ + LOG_DEBUG(""); + RENDERER *const r = M_GetRenderer(); + if (r != NULL) { + r->Close(r); + r->Shutdown(r); + } + + if (m_Background.surface != NULL) { + GFX_2D_Surface_Free(m_Background.surface); + m_Background.surface = NULL; + } + + if (m_FadeRenderer != NULL) { + GFX_FadeRenderer_Destroy(m_FadeRenderer); + m_FadeRenderer = NULL; + } + + if (m_BackgroundRenderer != NULL) { + GFX_2D_Renderer_Destroy(m_BackgroundRenderer); + m_BackgroundRenderer = NULL; + } + + GFX_Context_Detach(); +} + +void Render_Reset(const RENDER_RESET_FLAGS reset_flags) +{ + LOG_DEBUG("reset_flags=%x", reset_flags); + + if (m_PreviousRenderer != NULL) { + m_PreviousRenderer->Close(m_PreviousRenderer); + } + + RENDERER *const r = M_GetRenderer(); + if (!r->initialized) { + r->Init(r); + } + r->Open(r); + m_PreviousRenderer = r; + + r->Reset(r, reset_flags); + + if (reset_flags & (RENDER_RESET_PARAMS | RENDER_RESET_TEXTURES)) { + Render_AdjustTextureUVs(reset_flags & RENDER_RESET_TEXTURES); + M_ReuploadBackground(); + } + + if (reset_flags & RENDER_RESET_PARAMS) { + GFX_Context_SetWireframeMode(g_Config.rendering.enable_wireframe); + GFX_Context_SetLineWidth(g_Config.rendering.wireframe_width); + } + LOG_DEBUG("reset finished"); +} + +void Render_SetupDisplay( + const int32_t window_border, const int32_t window_width, + const int32_t window_height, const int32_t screen_width, + const int32_t screen_height) +{ + LOG_DEBUG("%dx%d", screen_width, screen_height); + GFX_Context_SetWindowBorder(window_border); + GFX_Context_SetWindowSize(window_width, window_height); + GFX_Context_SetDisplaySize(screen_width, screen_height); + Render_Reset(RENDER_RESET_VIEWPORT); +} + +void Render_BeginScene(void) +{ + GFX_Context_Clear(); + RENDERER *const r = M_GetRenderer(); + r->BeginScene(r); + M_ResetPolyList(); +} + +void Render_EndScene(void) +{ + RENDERER *const r = M_GetRenderer(); + r->EndScene(r); + GFX_Context_SwapBuffers(); +} + +void Render_LoadBackgroundFromTexture( + const PHD_TEXTURE *const texture, const int32_t repeat_x, + const int32_t repeat_y) +{ + if (g_TexturePageBuffer16[texture->tex_page] == NULL) { + return; + } + + if (m_Background.surface != NULL) { + GFX_2D_Surface_Free(m_Background.surface); + m_Background.surface = NULL; + } + + m_Background.ready = true; + m_Background.texture = texture; + m_Background.repeat_x = repeat_x; + m_Background.repeat_y = repeat_y; + + GFX_2D_SURFACE_DESC desc = { + .width = TEXTURE_PAGE_WIDTH, + .height = TEXTURE_PAGE_HEIGHT, + .bit_count = 16, + .tex_format = GL_BGRA, + .tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV, + .uv = { + { + texture->uv[0].u / 256.0f / TEXTURE_PAGE_WIDTH, + texture->uv[0].v / 256.0f / TEXTURE_PAGE_HEIGHT}, + { + texture->uv[1].u / 256.0f / TEXTURE_PAGE_WIDTH, + texture->uv[1].v / 256.0f / TEXTURE_PAGE_HEIGHT}, + { + texture->uv[2].u / 256.0f / TEXTURE_PAGE_WIDTH, + texture->uv[2].v / 256.0f / TEXTURE_PAGE_HEIGHT}, + { + texture->uv[3].u / 256.0f / TEXTURE_PAGE_WIDTH, + texture->uv[3].v / 256.0f / TEXTURE_PAGE_HEIGHT}, + }, + .pitch = TEXTURE_PAGE_WIDTH * 2, + }; + GFX_2D_Renderer_Upload( + m_BackgroundRenderer, &desc, + (uint8_t *)g_TexturePageBuffer16[texture->tex_page]); + GFX_2D_Renderer_SetRepeat(m_BackgroundRenderer, repeat_x, repeat_y); + GFX_2D_Renderer_SetEffect(m_BackgroundRenderer, GFX_2D_EFFECT_VIGNETTE); +} + +void Render_LoadBackgroundFromImage(const IMAGE *const image) +{ + if (m_Background.surface != NULL) { + GFX_2D_Surface_Free(m_Background.surface); + m_Background.surface = NULL; + } + ASSERT(image != NULL); + m_Background.ready = true; + m_Background.surface = GFX_2D_Surface_CreateFromImage(image); + m_Background.texture = NULL; + m_Background.repeat_x = 1; + m_Background.repeat_y = 1; + GFX_2D_Renderer_UploadSurface(m_BackgroundRenderer, m_Background.surface); + GFX_2D_Renderer_SetRepeat(m_BackgroundRenderer, 1, 1); + GFX_2D_Renderer_SetEffect(m_BackgroundRenderer, GFX_2D_EFFECT_NONE); +} + +void Render_UnloadBackground(void) +{ + if (m_Background.surface != NULL) { + GFX_2D_Surface_Free(m_Background.surface); + m_Background.surface = NULL; + } + m_Background.texture = NULL; + m_Background.ready = false; + GFX_2D_Renderer_SetRepeat(m_BackgroundRenderer, 1, 1); + GFX_2D_Renderer_SetEffect(m_BackgroundRenderer, GFX_2D_EFFECT_NONE); +} + +void Render_DrawBackground(void) +{ + if (!m_Background.ready) { + return; + } + GFX_2D_Renderer_Render(m_BackgroundRenderer); + Render_EnableZBuffer(true, true); +} + +void Render_ClearZBuffer(void) +{ + RENDERER *const r = M_GetRenderer(); + if (r->ClearZBuffer != NULL) { + r->ClearZBuffer(r); + } +} + +void Render_EnableZBuffer(const bool z_write_enable, const bool z_test_enable) +{ + RENDERER *const r = M_GetRenderer(); + if (r->EnableZBuffer != NULL) { + r->EnableZBuffer(r, z_write_enable, z_test_enable); + } +} + +void Render_DrawPolyList(void) +{ + RENDERER *const r = M_GetRenderer(); + r->DrawPolyList(r); + M_ResetPolyList(); +} + +void Render_DrawBlackRectangle(const int32_t opacity) +{ + GFX_FadeRenderer_SetOpacity(m_FadeRenderer, opacity / 255.0f); + GFX_FadeRenderer_Render(m_FadeRenderer); +} + +const int16_t *Render_InsertObjectG3( + const int16_t *const obj_ptr, const int32_t num, const SORT_TYPE sort_type) +{ + RENDERER *const r = M_GetRenderer(); + if (r->InsertObjectG3 != NULL) { + return r->InsertObjectG3(r, obj_ptr, num, sort_type); + } + return obj_ptr + num * 4; +} + +const int16_t *Render_InsertObjectG4( + const int16_t *const obj_ptr, const int32_t num, const SORT_TYPE sort_type) +{ + RENDERER *const r = M_GetRenderer(); + if (r->InsertObjectG4 != NULL) { + return r->InsertObjectG4(r, obj_ptr, num, sort_type); + } + return obj_ptr + num * 5; +} + +const int16_t *Render_InsertObjectGT3( + const int16_t *const obj_ptr, const int32_t num, const SORT_TYPE sort_type) +{ + RENDERER *const r = M_GetRenderer(); + if (r->InsertObjectGT3 != NULL) { + return r->InsertObjectGT3(r, obj_ptr, num, sort_type); + } + return obj_ptr + num * 4; +} + +const int16_t *Render_InsertObjectGT4( + const int16_t *const obj_ptr, const int32_t num, const SORT_TYPE sort_type) +{ + RENDERER *const r = M_GetRenderer(); + if (r->InsertObjectGT4 != NULL) { + return r->InsertObjectGT4(r, obj_ptr, num, sort_type); + } + return obj_ptr + num * 5; +} + +void Render_InsertLine( + const int32_t x0, const int32_t y0, const int32_t x1, const int32_t y1, + const int32_t z, const uint8_t color_idx) +{ + RENDERER *const r = M_GetRenderer(); + if (r->InsertLine != NULL) { + r->InsertLine(r, x0, y0, x1, y1, z, color_idx); + } +} + +void Render_InsertFlatRect( + const int32_t x0, const int32_t y0, const int32_t x1, const int32_t y1, + const int32_t z, const uint8_t color_idx) +{ + RENDERER *const r = M_GetRenderer(); + if (r->InsertFlatRect != NULL) { + r->InsertFlatRect(r, x0, y0, x1, y1, z, color_idx); + } +} + +void Render_InsertTransQuad( + const int32_t x, const int32_t y, const int32_t width, const int32_t height, + const int32_t z) +{ + RENDERER *const r = M_GetRenderer(); + if (r->InsertTransQuad != NULL) { + r->InsertTransQuad(r, x, y, width, height, z); + } +} + +void Render_InsertTransOctagon(const PHD_VBUF *const vbuf, const int16_t shade) +{ + RENDERER *const r = M_GetRenderer(); + if (r->InsertTransOctagon != NULL) { + r->InsertTransOctagon(r, vbuf, shade); + } +} + +void Render_InsertSprite( + const int32_t z, const int32_t x0, const int32_t y0, const int32_t x1, + const int32_t y1, const int32_t sprite_idx, const int16_t shade) +{ + RENDERER *const r = M_GetRenderer(); + if (r->InsertSprite != NULL) { + r->InsertSprite(r, z, x0, y0, x1, y1, sprite_idx, shade); + } +} diff --git a/src/tr2/game/render/common.h b/src/tr2/game/render/common.h new file mode 100644 index 000000000..44f80cda0 --- /dev/null +++ b/src/tr2/game/render/common.h @@ -0,0 +1,70 @@ +#pragma once + +#include "global/types.h" + +#include +#include + +#include +#include + +typedef enum { + ST_AVG_Z = 0, + ST_MAX_Z = 1, + ST_FAR_Z = 2, +} SORT_TYPE; + +typedef enum { + // clang-format off + RENDER_RESET_VIEWPORT = 1 << 0, + RENDER_RESET_PALETTE = 1 << 1, + RENDER_RESET_TEXTURES = 1 << 2, + RENDER_RESET_PARAMS = 1 << 3, + RENDER_RESET_ALL = INT32_MAX, + // clang-format on +} RENDER_RESET_FLAGS; + +void Render_Init(void); +void Render_Shutdown(void); + +void Render_Reset(RENDER_RESET_FLAGS reset_flags); +void Render_SetupDisplay( + int32_t window_border, int32_t window_width, int32_t window_height, + int32_t screen_width, int32_t screen_height); + +void Render_BeginScene(void); +void Render_EndScene(void); + +void Render_LoadBackgroundFromTexture( + const PHD_TEXTURE *texture, int32_t repeat_x, int32_t repeat_y); +void Render_LoadBackgroundFromImage(const IMAGE *image); +void Render_UnloadBackground(void); +void Render_DrawBackground(void); + +void Render_DrawPolyList(void); +void Render_DrawBlackRectangle(int32_t opacity); + +void Render_ClearZBuffer(void); +void Render_EnableZBuffer(bool z_write_enable, bool z_test_enable); + +// TODO: there's too much repetition for these +const int16_t *Render_InsertObjectG3( + const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); +const int16_t *Render_InsertObjectG4( + const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); +const int16_t *Render_InsertObjectGT3( + const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); +const int16_t *Render_InsertObjectGT4( + const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); +void Render_InsertLine( + int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t z, + uint8_t color_idx); +void Render_InsertFlatRect( + int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t z, + uint8_t color_idx); +void Render_InsertTransQuad( + int32_t x, int32_t y, int32_t width, int32_t height, int32_t z); +void Render_InsertTransOctagon(const PHD_VBUF *vbuf, int16_t shade); +void Render_InsertSprite( + int32_t z, int32_t x0, int32_t y0, int32_t x1, int32_t y1, + int32_t sprite_idx, int16_t shade); diff --git a/src/tr2/game/render/hwr.c b/src/tr2/game/render/hwr.c new file mode 100644 index 000000000..b7c81c356 --- /dev/null +++ b/src/tr2/game/render/hwr.c @@ -0,0 +1,1628 @@ +#include "game/render/hwr.h" + +#include "config.h" +#include "decomp/decomp.h" +#include "game/output.h" +#include "game/render/priv.h" +#include "game/render/util.h" +#include "game/shell.h" +#include "global/funcs.h" +#include "global/vars.h" + +#include +#include +#include +#include + +#define MAKE_DEPTH_FROM_RHW(rhw) (g_FltResZBuf - g_FltResZORhw * (rhw)) +#define MAKE_DEPTH(v) MAKE_DEPTH_FROM_RHW((v)->rhw) + +typedef struct { + GFX_2D_RENDERER *renderer_2d; + GFX_3D_RENDERER *renderer_3d; + GFX_2D_SURFACE *surface_pic; + GFX_2D_SURFACE *surface_tex[GFX_MAX_TEXTURES]; + int32_t texture_map[GFX_MAX_TEXTURES]; + int32_t env_map_texture; +} M_PRIV; + +static VERTEX_INFO m_VBuffer[32] = { 0 }; +static GFX_3D_VERTEX m_VBufferGL[32] = { 0 }; +static GFX_3D_VERTEX m_HWR_VertexBuffer[MAX_VERTICES] = { 0 }; +static GFX_3D_VERTEX *m_HWR_VertexPtr = NULL; + +static void M_ShadeColor( + GFX_3D_VERTEX *target, uint32_t red, uint32_t green, uint32_t blue, + uint8_t alpha); +static void M_ShadeLight(GFX_3D_VERTEX *target, uint32_t shade); +static void M_ShadeLightColor( + GFX_3D_VERTEX *target, uint32_t shade, uint32_t red, uint32_t green, + uint32_t blue, uint8_t alpha); + +static void M_ReleaseTextures(RENDERER *renderer); +static void M_LoadTexturePages( + RENDERER *renderer, int32_t pages_count, uint16_t *const *pages_buffer); +static void M_SelectTexture(RENDERER *renderer, int32_t tex_source); +static void M_EnableColorKey(RENDERER *renderer, bool state); +static bool M_VertexBufferFull(void); + +static void M_DrawPrimitive( + RENDERER *renderer, GFX_3D_PRIM_TYPE primitive_type, + const GFX_3D_VERTEX *vertices, DWORD vtx_count, bool is_no_clip); +static void M_DrawPolyTextured(RENDERER *renderer, int32_t vtx_count); +static void M_DrawPolyFlat( + RENDERER *renderer, int32_t vtx_count, int32_t red, int32_t green, + int32_t blue); + +static void M_InsertPolyTextured( + int32_t vtx_count, const float z, int16_t poly_type, int16_t tex_page); +static void M_InsertPolyFlat( + int32_t vtx_count, const float z, int32_t red, int32_t green, int32_t blue, + int16_t poly_type); + +static void M_InsertGT3_Sorted( + RENDERER *renderer, const PHD_VBUF *vtx0, const PHD_VBUF *vtx1, + const PHD_VBUF *vtx2, const PHD_TEXTURE *texture, const PHD_UV *uv0, + const PHD_UV *uv1, const PHD_UV *uv2, const SORT_TYPE sort_type); +static void M_InsertGT4_Sorted( + RENDERER *renderer, const PHD_VBUF *vtx0, const PHD_VBUF *vtx1, + const PHD_VBUF *vtx2, const PHD_VBUF *vtx3, const PHD_TEXTURE *texture, + const SORT_TYPE sort_type); +static const int16_t *M_InsertObjectG3_Sorted( + RENDERER *renderer, const int16_t *obj_ptr, int32_t num, + SORT_TYPE sort_type); +static const int16_t *M_InsertObjectG4_Sorted( + RENDERER *renderer, const int16_t *obj_ptr, int32_t num, + SORT_TYPE sort_type); +static const int16_t *M_InsertObjectGT3_Sorted( + RENDERER *renderer, const int16_t *obj_ptr, int32_t num, + SORT_TYPE sort_type); +static const int16_t *M_InsertObjectGT4_Sorted( + RENDERER *renderer, const int16_t *obj_ptr, int32_t num, + SORT_TYPE sort_type); +static void M_InsertFlatRect_Sorted( + RENDERER *renderer, int32_t x1, int32_t y1, int32_t x2, int32_t y2, + int32_t z, uint8_t color_idx); +static void M_InsertLine_Sorted( + RENDERER *renderer, int32_t x1, int32_t y1, int32_t x2, int32_t y2, + int32_t z, uint8_t color_idx); +static void M_InsertSprite_Sorted( + RENDERER *renderer, int32_t z, int32_t x0, int32_t y0, int32_t x1, + int32_t y1, int32_t sprite_idx, int16_t shade); +static void M_InsertTransQuad_Sorted( + RENDERER *renderer, int32_t x, int32_t y, int32_t width, int32_t height, + int32_t z); +static void M_InsertTransOctagon_Sorted( + RENDERER *renderer, const PHD_VBUF *vbuf, int16_t shade); + +static void M_InsertGT3_ZBuffered( + RENDERER *renderer, const PHD_VBUF *vtx0, const PHD_VBUF *vtx1, + const PHD_VBUF *vtx2, const PHD_TEXTURE *texture, const PHD_UV *uv0, + const PHD_UV *uv1, const PHD_UV *uv2); +static void M_InsertGT4_ZBuffered( + RENDERER *renderer, const PHD_VBUF *vtx0, const PHD_VBUF *vtx1, + const PHD_VBUF *vtx2, const PHD_VBUF *vtx3, const PHD_TEXTURE *texture); +static const int16_t *M_InsertObjectG3_ZBuffered( + RENDERER *renderer, const int16_t *obj_ptr, int32_t num, + SORT_TYPE sort_type); +static const int16_t *M_InsertObjectG4_ZBuffered( + RENDERER *renderer, const int16_t *obj_ptr, int32_t num, + SORT_TYPE sort_type); +static const int16_t *M_InsertObjectGT3_ZBuffered( + RENDERER *renderer, const int16_t *obj_ptr, int32_t num, + SORT_TYPE sort_type); +static const int16_t *M_InsertObjectGT4_ZBuffered( + RENDERER *renderer, const int16_t *obj_ptr, int32_t num, + SORT_TYPE sort_type); +static void M_InsertFlatRect_ZBuffered( + RENDERER *renderer, int32_t x1, int32_t y1, int32_t x2, int32_t y2, + int32_t z, uint8_t color_idx); +static void M_InsertLine_ZBuffered( + RENDERER *renderer, int32_t x1, int32_t y1, int32_t x2, int32_t y2, + int32_t z, uint8_t color_idx); + +static void M_ResetFuncPtrs(RENDERER *renderer); +static void M_Init(RENDERER *renderer); +static void M_Shutdown(RENDERER *renderer); +static void M_Open(RENDERER *renderer); +static void M_Close(RENDERER *renderer); +static void M_BeginScene(RENDERER *renderer); +static void M_EndScene(RENDERER *renderer); +static void M_Reset(RENDERER *renderer, RENDER_RESET_FLAGS flags); +static void M_ResetPolyList(RENDERER *renderer); +static void M_DrawPolyList(RENDERER *renderer); +static void M_EnableZBuffer( + RENDERER *renderer, bool z_write_enable, bool z_test_enable); +static void M_ClearZBuffer(RENDERER *renderer); + +static void M_ShadeColor( + GFX_3D_VERTEX *const target, uint32_t red, uint32_t green, + const uint32_t blue, const uint8_t alpha) +{ + if (g_IsShadeEffect) { + red /= 2; + green = green * 7 / 8; + } + target->r = red; + target->g = green; + target->b = blue; + target->a = alpha; +} + +static void M_ShadeLight(GFX_3D_VERTEX *const target, const uint32_t shade) +{ + uint32_t value = (uint32_t)(0x1FFF - shade) >> 4; + CLAMPG(value, 0xFF); + M_ShadeColor(target, value, value, value, 0xFF); +} + +static void M_ShadeLightColor( + GFX_3D_VERTEX *const target, uint32_t shade, uint32_t red, uint32_t green, + uint32_t blue, const uint8_t alpha) +{ + CLAMPG(shade, 0x1FFF); + shade = 0x1FFF - shade; + red = (red * shade) >> 12; + green = (green * shade) >> 12; + blue = (blue * shade) >> 12; + CLAMPG(red, 0xFF); + CLAMPG(green, 0xFF); + CLAMPG(blue, 0xFF); + M_ShadeColor(target, red, green, blue, alpha); +} + +static void M_ReleaseTextures(RENDERER *const renderer) +{ + M_PRIV *const priv = renderer->priv; + for (int32_t i = 0; i < GFX_MAX_TEXTURES; i++) { + if (priv->texture_map[i] != GFX_NO_TEXTURE) { + GFX_3D_Renderer_UnregisterTexturePage( + priv->renderer_3d, priv->texture_map[i]); + priv->texture_map[i] = GFX_NO_TEXTURE; + } + } + if (priv->env_map_texture != GFX_NO_TEXTURE) { + GFX_3D_Renderer_UnregisterEnvironmentMap( + priv->renderer_3d, priv->env_map_texture); + } +} + +static void M_LoadTexturePages( + RENDERER *renderer, const int32_t pages_count, + uint16_t *const *pages_buffer) +{ + M_PRIV *const priv = renderer->priv; + int32_t page_idx = -1; + + M_ReleaseTextures(renderer); + + for (int32_t i = 0; i < pages_count; i++) { + GFX_2D_SURFACE *const surface = priv->surface_tex[i]; + const uint16_t *input_ptr = pages_buffer[i]; + RGBA_8888 *output_ptr = (RGBA_8888 *)surface->buffer; + for (int32_t y = 0; y < TEXTURE_PAGE_HEIGHT; y++) { + for (int32_t x = 0; x < TEXTURE_PAGE_WIDTH; x++) { + *output_ptr++ = Render_ARGB1555To8888(*input_ptr++); + } + } + + priv->texture_map[i] = GFX_3D_Renderer_RegisterTexturePage( + priv->renderer_3d, surface->buffer, surface->desc.width, + surface->desc.height); + } + + priv->env_map_texture = + GFX_3D_Renderer_RegisterEnvironmentMap(priv->renderer_3d); +} + +static void M_SelectTexture(RENDERER *const renderer, const int32_t tex_source) +{ + M_PRIV *const priv = renderer->priv; + if (!renderer->open) { + return; + } + if (tex_source == -1) { + GFX_3D_Renderer_SetTexturingEnabled(priv->renderer_3d, false); + } else { + GFX_3D_Renderer_SelectTexture( + priv->renderer_3d, priv->texture_map[tex_source]); + GFX_3D_Renderer_SetTexturingEnabled(priv->renderer_3d, true); + } +} + +static void M_EnableColorKey(RENDERER *const renderer, const bool state) +{ + M_PRIV *const priv = renderer->priv; + GFX_3D_Renderer_SetBlendingMode( + priv->renderer_3d, state ? GFX_BLEND_MODE_NORMAL : GFX_BLEND_MODE_OFF); +} + +static bool M_VertexBufferFull(void) +{ + const int32_t index = m_HWR_VertexPtr - m_HWR_VertexBuffer; + return index >= MAX_VERTICES - 0x200; +} + +static void M_DrawPrimitive( + RENDERER *renderer, GFX_3D_PRIM_TYPE primitive_type, + const GFX_3D_VERTEX *const vertices, DWORD vtx_count, bool is_no_clip) +{ + M_PRIV *const priv = renderer->priv; + GFX_3D_Renderer_RenderPrimFan(priv->renderer_3d, vertices, vtx_count); +} + +static void M_DrawPolyTextured( + RENDERER *const renderer, const int32_t vtx_count) +{ + for (int32_t i = 0; i < vtx_count; i++) { + const VERTEX_INFO *const vbuf = &m_VBuffer[i]; + GFX_3D_VERTEX *const vbuf_gl = &m_VBufferGL[i]; + vbuf_gl->x = vbuf->x; + vbuf_gl->y = vbuf->y; + vbuf_gl->z = MAKE_DEPTH(vbuf); + vbuf_gl->w = vbuf->rhw; + vbuf_gl->t = vbuf->v / (double)PHD_ONE; + vbuf_gl->s = vbuf->u / (double)PHD_ONE; + M_ShadeLight(vbuf_gl, vbuf->g); + } + M_DrawPrimitive(renderer, GFX_3D_PRIM_TRI, m_VBufferGL, vtx_count, true); +} + +static void M_DrawPolyFlat( + RENDERER *const renderer, const int32_t vtx_count, const int32_t red, + const int32_t green, const int32_t blue) +{ + for (int32_t i = 0; i < vtx_count; i++) { + const VERTEX_INFO *const vbuf = &m_VBuffer[i]; + GFX_3D_VERTEX *const vbuf_gl = &m_VBufferGL[i]; + vbuf_gl->x = vbuf->x; + vbuf_gl->y = vbuf->y; + vbuf_gl->z = MAKE_DEPTH(vbuf); + vbuf_gl->w = vbuf->rhw; + M_ShadeLightColor(vbuf_gl, vbuf->g, red, green, blue, 0xFF); + } + M_DrawPrimitive(renderer, GFX_3D_PRIM_TRI, m_VBufferGL, vtx_count, true); +} + +static void M_InsertPolyTextured( + const int32_t vtx_count, const float z, const int16_t poly_type, + const int16_t tex_page) +{ + g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; + g_Sort3DPtr->_1 = MAKE_ZSORT(z); + g_Sort3DPtr++; + + *g_Info3DPtr++ = poly_type; + *g_Info3DPtr++ = tex_page; + *g_Info3DPtr++ = vtx_count; + *(GFX_3D_VERTEX **)g_Info3DPtr = m_HWR_VertexPtr; + g_Info3DPtr += sizeof(GFX_3D_VERTEX *) / sizeof(int16_t); + + for (int32_t i = 0; i < vtx_count; i++) { + const VERTEX_INFO *const vbuf = &m_VBuffer[i]; + GFX_3D_VERTEX *const vbuf_gl = &m_HWR_VertexPtr[i]; + vbuf_gl->x = vbuf->x; + vbuf_gl->y = vbuf->y; + vbuf_gl->z = MAKE_DEPTH(vbuf); + vbuf_gl->w = vbuf->rhw; + vbuf_gl->s = vbuf->u / (double)PHD_ONE; + vbuf_gl->t = vbuf->v / (double)PHD_ONE; + M_ShadeLight(vbuf_gl, vbuf->g); + } + + m_HWR_VertexPtr += vtx_count; + g_SurfaceCount++; +} + +static void M_InsertPolyFlat( + const int32_t vtx_count, const float z, const int32_t red, + const int32_t green, const int32_t blue, const int16_t poly_type) +{ + g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; + g_Sort3DPtr->_1 = MAKE_ZSORT(z); + g_Sort3DPtr++; + + *g_Info3DPtr++ = poly_type; + *g_Info3DPtr++ = vtx_count; + *(GFX_3D_VERTEX **)g_Info3DPtr = m_HWR_VertexPtr; + g_Info3DPtr += sizeof(GFX_3D_VERTEX *) / sizeof(int16_t); + + for (int32_t i = 0; i < vtx_count; i++) { + const VERTEX_INFO *const vbuf = &m_VBuffer[i]; + GFX_3D_VERTEX *const vbuf_gl = &m_HWR_VertexPtr[i]; + vbuf_gl->x = vbuf->x; + vbuf_gl->y = vbuf->y; + vbuf_gl->z = MAKE_DEPTH(vbuf); + vbuf_gl->w = vbuf->rhw; + M_ShadeLightColor( + vbuf_gl, vbuf->g, red, green, blue, + poly_type == POLY_HWR_TRANS ? 0x80 : 0xFF); + } + + m_HWR_VertexPtr += vtx_count; + g_SurfaceCount++; +} + +static void M_InsertGT3_Sorted( + RENDERER *const renderer, const PHD_VBUF *const vtx0, + const PHD_VBUF *const vtx1, const PHD_VBUF *const vtx2, + const PHD_TEXTURE *const texture, const PHD_UV *const uv0, + const PHD_UV *const uv1, const PHD_UV *const uv2, const SORT_TYPE sort_type) +{ + const int8_t clip_or = vtx0->clip | vtx1->clip | vtx2->clip; + const int8_t clip_and = vtx0->clip & vtx1->clip & vtx2->clip; + if (clip_and != 0) { + return; + } + + const double zv = + Render_CalculatePolyZ(sort_type, vtx0->zv, vtx1->zv, vtx2->zv, -1.0); + const POLY_TYPE poly_type = + texture->draw_type == DRAW_OPAQUE ? POLY_HWR_GTMAP : POLY_HWR_WGTMAP; + const PHD_VBUF *const vtx[3] = { vtx0, vtx1, vtx2 }; + const PHD_UV *const uv[3] = { uv0, uv1, uv2 }; + + int32_t num_points = 3; + if (clip_or >= 0) { + if (!VBUF_VISIBLE(*vtx0, *vtx1, *vtx2)) { + return; + } + + if (clip_or == 0) { + g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; + g_Sort3DPtr->_1 = MAKE_ZSORT(zv); + g_Sort3DPtr++; + + *g_Info3DPtr++ = poly_type; + *g_Info3DPtr++ = texture->tex_page; + *g_Info3DPtr++ = num_points; + *(GFX_3D_VERTEX **)g_Info3DPtr = m_HWR_VertexPtr; + g_Info3DPtr += sizeof(GFX_3D_VERTEX *) / sizeof(int16_t); + + for (int32_t i = 0; i < 3; i++) { + GFX_3D_VERTEX *const vbuf_gl = &m_HWR_VertexPtr[i]; + vbuf_gl->x = vtx[i]->xs; + vbuf_gl->y = vtx[i]->ys; + vbuf_gl->z = MAKE_DEPTH(vtx[i]); + vbuf_gl->w = vtx[i]->rhw; + vbuf_gl->s = (double)uv[i]->u * vtx[i]->rhw / (double)PHD_ONE; + vbuf_gl->t = (double)uv[i]->v * vtx[i]->rhw / (double)PHD_ONE; + M_ShadeLight(vbuf_gl, vtx[i]->g); + } + + m_HWR_VertexPtr += 3; + g_SurfaceCount++; + return; + } + + for (int32_t i = 0; i < 3; i++) { + VERTEX_INFO *const vbuf = &m_VBuffer[i]; + vbuf->x = vtx[i]->xs; + vbuf->y = vtx[i]->ys; + vbuf->z = vtx[i]->zv; + vbuf->rhw = vtx[i]->rhw; + vbuf->g = (double)vtx[i]->g; + vbuf->u = (double)uv[i]->u * vtx[i]->rhw; + vbuf->v = (double)uv[i]->v * vtx[i]->rhw; + } + } else { + if (!Render_VisibleZClip(vtx0, vtx1, vtx2)) { + return; + } + + POINT_INFO points[3]; + for (int32_t i = 0; i < 3; i++) { + points[i].xv = vtx[i]->xv; + points[i].yv = vtx[i]->yv; + points[i].zv = vtx[i]->zv; + points[i].rhw = vtx[i]->rhw; + points[i].xs = vtx[i]->xs; + points[i].ys = vtx[i]->ys; + points[i].g = vtx[i]->g; + points[i].u = uv[i]->u; + points[i].v = uv[i]->v; + } + num_points = Render_ZedClipper(num_points, points, m_VBuffer); + if (num_points == 0) { + return; + } + } + + num_points = Render_XYGUVClipper(num_points, m_VBuffer); + if (num_points == 0) { + return; + } + + M_InsertPolyTextured(num_points, zv, poly_type, texture->tex_page); +} + +static void M_InsertGT4_Sorted( + RENDERER *const renderer, const PHD_VBUF *const vtx0, + const PHD_VBUF *const vtx1, const PHD_VBUF *const vtx2, + const PHD_VBUF *const vtx3, const PHD_TEXTURE *const texture, + const SORT_TYPE sort_type) +{ + const int8_t clip_or = vtx0->clip | vtx1->clip | vtx2->clip | vtx3->clip; + const int8_t clip_and = vtx0->clip & vtx1->clip & vtx2->clip & vtx3->clip; + if (clip_and != 0) { + return; + } + + const double zv = Render_CalculatePolyZ( + sort_type, vtx0->zv, vtx1->zv, vtx2->zv, vtx3->zv); + const POLY_TYPE poly_type = + texture->draw_type == DRAW_OPAQUE ? POLY_HWR_GTMAP : POLY_HWR_WGTMAP; + const PHD_VBUF *const vtx[4] = { vtx0, vtx1, vtx2, vtx3 }; + + int32_t num_points = 4; + if (clip_or >= 0) { + if (!VBUF_VISIBLE(*vtx0, *vtx1, *vtx2)) { + return; + } + + if (clip_or == 0) { + g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; + g_Sort3DPtr->_1 = MAKE_ZSORT(zv); + g_Sort3DPtr++; + + *g_Info3DPtr++ = poly_type; + *g_Info3DPtr++ = texture->tex_page; + *g_Info3DPtr++ = num_points; + *(GFX_3D_VERTEX **)g_Info3DPtr = m_HWR_VertexPtr; + g_Info3DPtr += sizeof(GFX_3D_VERTEX *) / sizeof(int16_t); + + for (int32_t i = 0; i < 4; i++) { + GFX_3D_VERTEX *const vbuf_gl = &m_HWR_VertexPtr[i]; + vbuf_gl->x = vtx[i]->xs; + vbuf_gl->y = vtx[i]->ys; + vbuf_gl->z = MAKE_DEPTH(vtx[i]); + vbuf_gl->w = vtx[i]->rhw; + vbuf_gl->s = texture->uv[i].u * vtx[i]->rhw / (double)PHD_ONE; + vbuf_gl->t = texture->uv[i].v * vtx[i]->rhw / (double)PHD_ONE; + M_ShadeLight(vbuf_gl, vtx[i]->g); + } + + m_HWR_VertexPtr += 4; + g_SurfaceCount++; + return; + } + + M_InsertGT3_Sorted( + renderer, vtx0, vtx1, vtx2, texture, &texture->uv[0], + &texture->uv[1], &texture->uv[2], sort_type); + M_InsertGT3_Sorted( + renderer, vtx0, vtx2, vtx3, texture, &texture->uv[0], + &texture->uv[2], &texture->uv[3], sort_type); + } else { + if (!Render_VisibleZClip(vtx0, vtx1, vtx2)) { + return; + } + + M_InsertGT3_Sorted( + renderer, vtx0, vtx1, vtx2, texture, &texture->uv[0], + &texture->uv[1], &texture->uv[2], sort_type); + M_InsertGT3_Sorted( + renderer, vtx0, vtx2, vtx3, texture, &texture->uv[0], + &texture->uv[2], &texture->uv[3], sort_type); + } +} + +static const int16_t *M_InsertObjectG3_Sorted( + RENDERER *const renderer, const int16_t *obj_ptr, const int32_t num, + const SORT_TYPE sort_type) +{ + for (int32_t i = 0; i < num; i++) { + if (M_VertexBufferFull()) { + obj_ptr += (num - i) * 4; + break; + } + + int32_t num_points = 3; + const PHD_VBUF *vtx[3] = { + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + }; + const int16_t color_idx = *obj_ptr++; + + const int8_t clip_or = vtx[0]->clip | vtx[1]->clip | vtx[2]->clip; + const int8_t clip_and = vtx[0]->clip & vtx[1]->clip & vtx[2]->clip; + if (clip_and != 0) { + continue; + } + + if (clip_or >= 0) { + if (!VBUF_VISIBLE(*vtx[0], *vtx[1], *vtx[2])) { + continue; + } + + for (int32_t i = 0; i < 3; i++) { + VERTEX_INFO *const vbuf = &m_VBuffer[i]; + vbuf->x = vtx[i]->xs; + vbuf->y = vtx[i]->ys; + vbuf->z = vtx[i]->zv; + vbuf->rhw = vtx[i]->rhw; + vbuf->g = vtx[i]->g; + } + if (clip_or > 0) { + num_points = Render_XYGClipper(num_points, m_VBuffer); + } + } else { + if (!Render_VisibleZClip(vtx[0], vtx[1], vtx[2])) { + continue; + } + + POINT_INFO points[3]; + for (int32_t i = 0; i < 3; i++) { + points[i].xv = vtx[i]->xv; + points[i].yv = vtx[i]->yv; + points[i].zv = vtx[i]->zv; + points[i].rhw = vtx[i]->rhw; + points[i].xs = vtx[i]->xs; + points[i].ys = vtx[i]->ys; + points[i].g = vtx[i]->g; + } + num_points = Render_ZedClipper(num_points, points, m_VBuffer); + if (num_points == 0) { + continue; + } + + num_points = Render_XYGClipper(num_points, m_VBuffer); + } + + if (num_points == 0) { + continue; + } + + const PALETTEENTRY *const color = &g_GamePalette16[color_idx >> 8]; + const double zv = Render_CalculatePolyZ( + sort_type, vtx[0]->zv, vtx[1]->zv, vtx[2]->zv, -1.0); + M_InsertPolyFlat( + num_points, zv, color->peRed, color->peGreen, color->peBlue, + POLY_HWR_GOURAUD); + } + + return obj_ptr; +} + +static const int16_t *M_InsertObjectG4_Sorted( + RENDERER *const renderer, const int16_t *obj_ptr, const int32_t num, + const SORT_TYPE sort_type) +{ + for (int32_t i = 0; i < num; i++) { + if (M_VertexBufferFull()) { + obj_ptr += (num - i) * 5; + break; + } + + int32_t num_points = 4; + const PHD_VBUF *const vtx[4] = { + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + }; + const int16_t color_idx = *obj_ptr++; + + const int8_t clip_or = + vtx[0]->clip | vtx[1]->clip | vtx[2]->clip | vtx[3]->clip; + const int8_t clip_and = + vtx[0]->clip & vtx[1]->clip & vtx[2]->clip & vtx[3]->clip; + if (clip_and != 0) { + continue; + } + + if (clip_or >= 0) { + if (!VBUF_VISIBLE(*vtx[0], *vtx[1], *vtx[2])) { + continue; + } + + for (int32_t i = 0; i < 4; i++) { + VERTEX_INFO *const vbuf = &m_VBuffer[i]; + vbuf->x = vtx[i]->xs; + vbuf->y = vtx[i]->ys; + vbuf->z = vtx[i]->zv; + vbuf->rhw = vtx[i]->rhw; + vbuf->g = vtx[i]->g; + } + + if (clip_or > 0) { + num_points = Render_XYGClipper(num_points, m_VBuffer); + } + } else { + if (!Render_VisibleZClip(vtx[0], vtx[1], vtx[2])) { + continue; + } + + POINT_INFO points[4]; + for (int32_t i = 0; i < 4; i++) { + points[i].xv = vtx[i]->xv; + points[i].yv = vtx[i]->yv; + points[i].zv = vtx[i]->zv; + points[i].rhw = vtx[i]->rhw; + points[i].xs = vtx[i]->xs; + points[i].ys = vtx[i]->ys; + points[i].g = vtx[i]->g; + } + num_points = Render_ZedClipper(num_points, points, m_VBuffer); + if (num_points == 0) { + continue; + } + num_points = Render_XYGClipper(num_points, m_VBuffer); + } + + if (num_points == 0) { + continue; + } + + const PALETTEENTRY *const color = &g_GamePalette16[color_idx >> 8]; + const double zv = Render_CalculatePolyZ( + sort_type, vtx[0]->zv, vtx[1]->zv, vtx[2]->zv, vtx[3]->zv); + M_InsertPolyFlat( + num_points, zv, color->peRed, color->peGreen, color->peBlue, + POLY_HWR_GOURAUD); + } + + return obj_ptr; +} + +static const int16_t *M_InsertObjectGT3_Sorted( + RENDERER *const renderer, const int16_t *obj_ptr, const int32_t num, + const SORT_TYPE sort_type) +{ + for (int32_t i = 0; i < num; i++) { + if (M_VertexBufferFull()) { + obj_ptr += (num - i) * 4; + break; + } + + const PHD_VBUF *const vtx[3] = { + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + }; + const int16_t texture_idx = *obj_ptr++; + const PHD_TEXTURE *const texture = &g_TextureInfo[texture_idx]; + const PHD_UV *const uv = texture->uv; + + if (texture->draw_type != DRAW_OPAQUE && g_DiscardTransparent) { + continue; + } + + M_InsertGT3_Sorted( + renderer, vtx[0], vtx[1], vtx[2], texture, &uv[0], &uv[1], &uv[2], + sort_type); + } + + return obj_ptr; +} + +static const int16_t *M_InsertObjectGT4_Sorted( + RENDERER *const renderer, const int16_t *obj_ptr, const int32_t num, + const SORT_TYPE sort_type) +{ + for (int32_t i = 0; i < num; i++) { + if (M_VertexBufferFull()) { + obj_ptr += (num - i) * 5; + break; + } + + const PHD_VBUF *const vtx[4] = { + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + }; + const int16_t texture_idx = *obj_ptr++; + const PHD_TEXTURE *const texture = &g_TextureInfo[texture_idx]; + + if (texture->draw_type != DRAW_OPAQUE && g_DiscardTransparent) { + continue; + } + + M_InsertGT4_Sorted( + renderer, vtx[0], vtx[1], vtx[2], vtx[3], texture, sort_type); + } + + return obj_ptr; +} + +static void M_InsertFlatRect_Sorted( + RENDERER *const renderer, int32_t x1, int32_t y1, int32_t x2, int32_t y2, + const int32_t z, const uint8_t color_idx) +{ + if (x2 <= x1 || y2 <= y1) { + return; + } + + CLAMPL(x1, 0); + CLAMPL(y1, 0); + CLAMPG(x2, g_PhdWinWidth); + CLAMPG(y2, g_PhdWinHeight); + + g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; + g_Sort3DPtr->_1 = MAKE_ZSORT(z); + g_Sort3DPtr++; + + *g_Info3DPtr++ = POLY_HWR_GOURAUD; + *g_Info3DPtr++ = 4; + *(GFX_3D_VERTEX **)g_Info3DPtr = m_HWR_VertexPtr; + g_Info3DPtr += sizeof(GFX_3D_VERTEX *) / sizeof(int16_t); + + const RGB_888 *const color = &g_GamePalette8[color_idx]; + const double rhw = g_RhwFactor / (double)z; + const double sz = MAKE_DEPTH_FROM_RHW(rhw); + + m_HWR_VertexPtr[0].x = x1; + m_HWR_VertexPtr[0].y = y1; + m_HWR_VertexPtr[1].x = x2; + m_HWR_VertexPtr[1].y = y1; + m_HWR_VertexPtr[2].x = x2; + m_HWR_VertexPtr[2].y = y2; + m_HWR_VertexPtr[3].x = x1; + m_HWR_VertexPtr[3].y = y2; + + for (int32_t i = 0; i < 4; i++) { + GFX_3D_VERTEX *const vbuf_gl = &m_HWR_VertexPtr[i]; + vbuf_gl->z = sz; + vbuf_gl->w = rhw; + M_ShadeColor(vbuf_gl, color->red, color->green, color->blue, 0xFF); + } + + m_HWR_VertexPtr += 4; + g_SurfaceCount++; +} + +static void M_InsertLine_Sorted( + RENDERER *const renderer, const int32_t x1, const int32_t y1, + const int32_t x2, const int32_t y2, int32_t z, const uint8_t color_idx) +{ + const RGB_888 *const color = &g_GamePalette8[color_idx]; + const double rhw = g_RhwFactor / (double)z; + const double sz = MAKE_DEPTH_FROM_RHW(rhw); + + g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; + g_Sort3DPtr->_1 = MAKE_ZSORT(z); + g_Sort3DPtr++; + + *g_Info3DPtr++ = POLY_HWR_LINE; + *g_Info3DPtr++ = 2; + *(GFX_3D_VERTEX **)g_Info3DPtr = m_HWR_VertexPtr; + g_Info3DPtr += sizeof(GFX_3D_VERTEX *) / sizeof(int16_t); + + m_HWR_VertexPtr[0].x = x1; + m_HWR_VertexPtr[0].y = y1; + m_HWR_VertexPtr[1].x = x2; + m_HWR_VertexPtr[1].y = y2; + + for (int32_t i = 0; i < 2; i++) { + GFX_3D_VERTEX *const vbuf_gl = &m_HWR_VertexPtr[i]; + vbuf_gl->z = sz; + vbuf_gl->w = rhw; + M_ShadeColor(vbuf_gl, color->red, color->green, color->blue, 0xFF); + } + + m_HWR_VertexPtr += 2; + g_SurfaceCount++; +} + +static void M_InsertSprite_Sorted( + RENDERER *const renderer, int32_t z, int32_t x0, int32_t y0, int32_t x1, + int32_t y1, const int32_t sprite_idx, const int16_t shade) +{ + if (M_VertexBufferFull() || x0 >= x1 || y0 >= y1 || x1 <= 0 || y1 <= 0 + || x0 >= g_PhdWinMaxX || y0 >= g_PhdWinMaxY || z >= g_PhdFarZ) { + return; + } + + x0 += 0; + x1 += 0; + y0 += 0; + y1 += 0; + + CLAMPL(z, g_PhdNearZ); + + int32_t num_points = 4; + + const PHD_SPRITE *const sprite = &g_PhdSprites[sprite_idx]; + const double rhw = g_RhwFactor / (double)z; + const int32_t u_offset = (sprite->offset & 0xFF) * 256; + const int32_t v_offset = (sprite->offset >> 8) * 256; + + const int32_t offset = Render_GetUVAdjustment(); + const double u0 = (double)(u_offset + offset) * rhw; + const double v0 = (double)(v_offset + offset) * rhw; + const double u1 = (double)(u_offset - offset + sprite->width) * rhw; + const double v1 = (double)(v_offset - offset + sprite->height) * rhw; + + m_VBuffer[0].x = x0; + m_VBuffer[0].y = y0; + m_VBuffer[0].u = u0; + m_VBuffer[0].v = v0; + + m_VBuffer[1].x = x1; + m_VBuffer[1].y = y0; + m_VBuffer[1].u = u1; + m_VBuffer[1].v = v0; + + m_VBuffer[2].x = x1; + m_VBuffer[2].y = y1; + m_VBuffer[2].u = u1; + m_VBuffer[2].v = v1; + + m_VBuffer[3].x = x0; + m_VBuffer[3].y = y1; + m_VBuffer[3].u = u0; + m_VBuffer[3].v = v1; + + for (int32_t i = 0; i < 4; i++) { + VERTEX_INFO *const vbuf = &m_VBuffer[i]; + vbuf->rhw = rhw; + vbuf->z = z; + vbuf->g = shade; + } + + if (x0 < 0 || y0 < 0 || x1 > g_PhdWinWidth || y1 > g_PhdWinHeight) { + g_FltWinLeft = 0.0f; + g_FltWinTop = 0.0f; + g_FltWinRight = g_PhdWinWidth; + g_FltWinBottom = g_PhdWinHeight; + num_points = Render_XYGUVClipper(num_points, m_VBuffer); + if (num_points == 0) { + return; + } + } + + const bool old_shade = g_IsShadeEffect; + g_IsShadeEffect = 0; + M_InsertPolyTextured(num_points, z, POLY_HWR_WGTMAP, sprite->tex_page); + g_IsShadeEffect = old_shade; +} + +static void M_InsertTransQuad_Sorted( + RENDERER *const renderer, const int32_t x, const int32_t y, + const int32_t width, const int32_t height, const int32_t z) +{ + const double x0 = (double)x; + const double y0 = (double)y; + const double x1 = (double)(x + width); + const double y1 = (double)(y + height); + const double rhw = g_RhwFactor / (double)z; + const double sz = MAKE_DEPTH_FROM_RHW(rhw); + + g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; + g_Sort3DPtr->_1 = MAKE_ZSORT(z); + g_Sort3DPtr++; + + *g_Info3DPtr++ = POLY_HWR_TRANS; + *g_Info3DPtr++ = 4; + *(GFX_3D_VERTEX **)g_Info3DPtr = m_HWR_VertexPtr; + g_Info3DPtr += sizeof(GFX_3D_VERTEX *) / sizeof(int16_t); + + m_HWR_VertexPtr[0].x = x0; + m_HWR_VertexPtr[0].y = y0; + m_HWR_VertexPtr[1].x = x1; + m_HWR_VertexPtr[1].y = y0; + m_HWR_VertexPtr[2].x = x1; + m_HWR_VertexPtr[2].y = y1; + m_HWR_VertexPtr[3].x = x0; + m_HWR_VertexPtr[3].y = y1; + + for (int32_t i = 0; i < 4; i++) { + GFX_3D_VERTEX *const vbuf_gl = &m_HWR_VertexPtr[i]; + vbuf_gl->z = sz; + vbuf_gl->w = rhw; + vbuf_gl->r = 0; + vbuf_gl->g = 0; + vbuf_gl->b = 0; + vbuf_gl->a = 0x80; + } + + m_HWR_VertexPtr += 4; + g_SurfaceCount++; +} + +static void M_InsertTransOctagon_Sorted( + RENDERER *const renderer, const PHD_VBUF *const vtx, const int16_t shade) +{ + int8_t clip_or = 0x00; + int8_t clip_and = 0xFF; + int32_t num_vtx = 8; + + for (int32_t i = 0; i < num_vtx; i++) { + clip_or |= vtx[i].clip; + clip_and &= vtx[i].clip; + } + + if (clip_or < 0 || clip_and != 0 || !VBUF_VISIBLE(vtx[0], vtx[1], vtx[2])) { + return; + } + + for (int32_t i = 0; i < num_vtx; i++) { + VERTEX_INFO *const vbuf = &m_VBuffer[i]; + vbuf->x = vtx[i].xs; + vbuf->y = vtx[i].ys; + vbuf->z = vtx[i].zv; + vbuf->rhw = g_RhwFactor / (double)(vtx[i].zv - 0x20000); + } + + int32_t num_points = num_vtx; + if (clip_or != 0) { + g_FltWinLeft = 0.0f; + g_FltWinTop = 0.0f; + g_FltWinRight = g_PhdWinWidth; + g_FltWinBottom = g_PhdWinHeight; + num_points = Render_XYClipper(num_points, m_VBuffer); + if (num_points == 0) { + return; + } + } + + double poly_z = 0.0; + for (int32_t i = 0; i < num_vtx; i++) { + poly_z += vtx[i].zv; + } + poly_z /= num_vtx; + + M_InsertPolyFlat( + num_points, (double)(poly_z - 0x20000), 0, 0, 0, POLY_HWR_TRANS); +} + +static void M_InsertGT3_ZBuffered( + RENDERER *const renderer, const PHD_VBUF *const vtx0, + const PHD_VBUF *const vtx1, const PHD_VBUF *const vtx2, + const PHD_TEXTURE *const texture, const PHD_UV *const uv0, + const PHD_UV *const uv1, const PHD_UV *const uv2) +{ + const int8_t clip_or = vtx0->clip | vtx1->clip | vtx2->clip; + const int8_t clip_and = vtx0->clip & vtx1->clip & vtx2->clip; + if (clip_and != 0) { + return; + } + + const PHD_VBUF *const vtx[3] = { vtx0, vtx1, vtx2 }; + const PHD_UV *const uv[3] = { uv0, uv1, uv2 }; + int32_t num_points = 3; + + if (clip_or >= 0) { + if (!VBUF_VISIBLE(*vtx0, *vtx1, *vtx2)) { + return; + } + + if (clip_or == 0) { + for (int32_t i = 0; i < 3; i++) { + GFX_3D_VERTEX *const vbuf_gl = &m_VBufferGL[i]; + vbuf_gl->x = vtx[i]->xs; + vbuf_gl->y = vtx[i]->ys; + vbuf_gl->z = MAKE_DEPTH(vtx[i]); + vbuf_gl->w = vtx[i]->rhw; + vbuf_gl->s = (double)uv[i]->u * vtx[i]->rhw / (double)PHD_ONE; + vbuf_gl->t = (double)uv[i]->v * vtx[i]->rhw / (double)PHD_ONE; + M_ShadeLight(vbuf_gl, vtx[i]->g); + } + + M_SelectTexture(renderer, texture->tex_page); + M_EnableColorKey(renderer, texture->draw_type != DRAW_OPAQUE); + M_DrawPrimitive(renderer, GFX_3D_PRIM_TRI, m_VBufferGL, 3, true); + return; + } + + for (int32_t i = 0; i < 3; i++) { + VERTEX_INFO *const vbuf = &m_VBuffer[i]; + vbuf->x = vtx[i]->xs; + vbuf->y = vtx[i]->ys; + vbuf->z = vtx[i]->zv; + vbuf->rhw = vtx[i]->rhw; + vbuf->g = (double)vtx[i]->g; + vbuf->u = (double)uv[i]->u * vtx[i]->rhw; + vbuf->v = (double)uv[i]->v * vtx[i]->rhw; + } + } else { + if (!Render_VisibleZClip(vtx0, vtx1, vtx2)) { + return; + } + + POINT_INFO points[num_points]; + for (int32_t i = 0; i < num_points; i++) { + points[i].xv = vtx[i]->xv; + points[i].yv = vtx[i]->yv; + points[i].zv = vtx[i]->zv; + points[i].rhw = vtx[i]->rhw; + points[i].xs = vtx[i]->xs; + points[i].ys = vtx[i]->ys; + points[i].g = vtx[i]->g; + points[i].u = uv[i]->u; + points[i].v = uv[i]->v; + } + num_points = Render_ZedClipper(num_points, points, m_VBuffer); + if (num_points == 0) { + return; + } + } + + num_points = Render_XYGUVClipper(num_points, m_VBuffer); + if (num_points == 0) { + return; + } + + M_SelectTexture(renderer, texture->tex_page); + M_EnableColorKey(renderer, texture->draw_type != DRAW_OPAQUE); + M_DrawPolyTextured(renderer, num_points); +} + +static void M_InsertGT4_ZBuffered( + RENDERER *const renderer, const PHD_VBUF *const vtx0, + const PHD_VBUF *const vtx1, const PHD_VBUF *const vtx2, + const PHD_VBUF *const vtx3, const PHD_TEXTURE *const texture) +{ + const int8_t clip_and = vtx0->clip & vtx1->clip & vtx2->clip & vtx3->clip; + const int8_t clip_or = vtx0->clip | vtx1->clip | vtx2->clip | vtx3->clip; + + if (clip_and != 0) { + return; + } + + if (clip_or >= 0) { + if (!VBUF_VISIBLE(*vtx0, *vtx1, *vtx2)) { + return; + } + } else if (clip_or < 0) { + if (!Render_VisibleZClip(vtx0, vtx1, vtx2)) { + return; + } + } + + if (clip_or != 0) { + M_InsertGT3_ZBuffered( + renderer, vtx0, vtx1, vtx2, texture, texture->uv, &texture->uv[1], + &texture->uv[2]); + M_InsertGT3_ZBuffered( + renderer, vtx0, vtx2, vtx3, texture, texture->uv, &texture->uv[2], + &texture->uv[3]); + return; + } + + const PHD_VBUF *const vtx[4] = { vtx0, vtx1, vtx2, vtx3 }; + for (int32_t i = 0; i < 4; i++) { + GFX_3D_VERTEX *const vbuf_gl = &m_VBufferGL[i]; + vbuf_gl->x = vtx[i]->xs; + vbuf_gl->y = vtx[i]->ys; + vbuf_gl->z = MAKE_DEPTH(vtx[i]); + vbuf_gl->w = vtx[i]->rhw; + vbuf_gl->s = texture->uv[i].u * vtx[i]->rhw / (double)PHD_ONE; + vbuf_gl->t = texture->uv[i].v * vtx[i]->rhw / (double)PHD_ONE; + M_ShadeLight(vbuf_gl, vtx[i]->g); + } + + M_SelectTexture(renderer, texture->tex_page); + M_EnableColorKey(renderer, texture->draw_type != DRAW_OPAQUE); + M_DrawPrimitive(renderer, GFX_3D_PRIM_TRI, m_VBufferGL, 4, true); +} + +static const int16_t *M_InsertObjectG3_ZBuffered( + RENDERER *const renderer, const int16_t *obj_ptr, const int32_t num, + const SORT_TYPE sort_type) +{ + M_SelectTexture(renderer, -1); + M_EnableColorKey(renderer, false); + + if (num == 0) { + return obj_ptr; + } + + for (int32_t i = 0; i < num; i++) { + const PHD_VBUF *vtx[3] = { + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + }; + const int16_t color_idx = *obj_ptr++; + int32_t num_points = 3; + + const int8_t clip_or = vtx[0]->clip | vtx[1]->clip | vtx[2]->clip; + const int8_t clip_and = vtx[0]->clip & vtx[1]->clip & vtx[2]->clip; + + if (clip_and != 0) { + continue; + } + + if (clip_or >= 0) { + if (!VBUF_VISIBLE(*vtx[0], *vtx[1], *vtx[2])) { + continue; + } + + for (int32_t i = 0; i < 3; i++) { + VERTEX_INFO *const vbuf = &m_VBuffer[i]; + vbuf->x = vtx[i]->xs; + vbuf->y = vtx[i]->ys; + vbuf->z = vtx[i]->zv; + vbuf->rhw = vtx[i]->rhw; + vbuf->g = vtx[i]->g; + } + } else { + if (!Render_VisibleZClip(vtx[0], vtx[1], vtx[2])) { + continue; + } + + POINT_INFO points[3]; + for (int32_t i = 0; i < 3; i++) { + points[i].xv = vtx[i]->xv; + points[i].yv = vtx[i]->yv; + points[i].zv = vtx[i]->zv; + points[i].rhw = vtx[i]->rhw; + points[i].xs = vtx[i]->xs; + points[i].ys = vtx[i]->ys; + points[i].g = vtx[i]->g; + } + num_points = Render_ZedClipper(num_points, points, m_VBuffer); + if (num_points == 0) { + continue; + } + } + + if (clip_or != 0) { + num_points = Render_XYGClipper(num_points, m_VBuffer); + } + if (num_points == 0) { + continue; + } + + const PALETTEENTRY *const color = &g_GamePalette16[color_idx >> 8]; + M_DrawPolyFlat( + renderer, num_points, color->peRed, color->peGreen, color->peBlue); + } + + return obj_ptr; +} + +static const int16_t *M_InsertObjectG4_ZBuffered( + RENDERER *const renderer, const int16_t *obj_ptr, const int32_t num, + const SORT_TYPE sort_type) +{ + M_SelectTexture(renderer, -1); + M_EnableColorKey(renderer, false); + + if (num == 0) { + return obj_ptr; + } + + for (int32_t i = 0; i < num; i++) { + const PHD_VBUF *const vtx[4] = { + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + }; + const int16_t color_idx = *obj_ptr++; + int32_t num_points = 4; + + const int8_t clip_or = + vtx[0]->clip | vtx[1]->clip | vtx[2]->clip | vtx[3]->clip; + const int8_t clip_and = + vtx[0]->clip & vtx[1]->clip & vtx[2]->clip & vtx[3]->clip; + + if (clip_and != 0) { + continue; + } + + if (clip_or >= 0) { + if (!VBUF_VISIBLE(*vtx[0], *vtx[1], *vtx[2])) { + continue; + } + + for (int32_t i = 0; i < 4; i++) { + VERTEX_INFO *const vbuf = &m_VBuffer[i]; + vbuf->x = vtx[i]->xs; + vbuf->y = vtx[i]->ys; + vbuf->z = vtx[i]->zv; + vbuf->rhw = vtx[i]->rhw; + vbuf->g = vtx[i]->g; + } + } else { + if (!Render_VisibleZClip(vtx[0], vtx[1], vtx[2])) { + continue; + } + + POINT_INFO points[4]; + for (int32_t i = 0; i < 4; i++) { + points[i].xv = vtx[i]->xv; + points[i].yv = vtx[i]->yv; + points[i].zv = vtx[i]->zv; + points[i].rhw = vtx[i]->rhw; + points[i].xs = vtx[i]->xs; + points[i].ys = vtx[i]->ys; + points[i].g = vtx[i]->g; + } + num_points = Render_ZedClipper(num_points, points, m_VBuffer); + if (num_points == 0) { + continue; + } + } + + if (clip_or != 0) { + num_points = Render_XYGClipper(num_points, m_VBuffer); + } + if (num_points == 0) { + continue; + } + + const PALETTEENTRY *const color = &g_GamePalette16[color_idx >> 8]; + M_DrawPolyFlat( + renderer, num_points, color->peRed, color->peGreen, color->peBlue); + } + + return obj_ptr; +} + +static const int16_t *M_InsertObjectGT3_ZBuffered( + RENDERER *const renderer, const int16_t *obj_ptr, const int32_t num, + const SORT_TYPE sort_type) +{ + for (int32_t i = 0; i < num; i++) { + const PHD_VBUF *const vtx[3] = { + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + }; + const PHD_TEXTURE *const texture = &g_TextureInfo[*obj_ptr++]; + const PHD_UV *const uv = texture->uv; + + if (texture->draw_type != DRAW_OPAQUE && g_DiscardTransparent) { + continue; + } + + if (texture->draw_type != DRAW_OPAQUE) { + M_InsertGT3_Sorted( + renderer, vtx[0], vtx[1], vtx[2], texture, &uv[0], &uv[1], + &uv[2], sort_type); + } else { + M_InsertGT3_ZBuffered( + renderer, vtx[0], vtx[1], vtx[2], texture, &uv[0], &uv[1], + &uv[2]); + } + } + + return obj_ptr; +} + +static const int16_t *M_InsertObjectGT4_ZBuffered( + RENDERER *const renderer, const int16_t *obj_ptr, const int32_t num, + const SORT_TYPE sort_type) +{ + for (int32_t i = 0; i < num; i++) { + const PHD_VBUF *const vtx[4] = { + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + }; + const PHD_TEXTURE *const texture = &g_TextureInfo[*obj_ptr++]; + const PHD_UV *const uv = texture->uv; + + if (texture->draw_type != DRAW_OPAQUE && g_DiscardTransparent) { + continue; + } + + if (texture->draw_type != DRAW_OPAQUE) { + M_InsertGT4_Sorted( + renderer, vtx[0], vtx[1], vtx[2], vtx[3], texture, sort_type); + } else { + M_InsertGT4_ZBuffered( + renderer, vtx[0], vtx[1], vtx[2], vtx[3], texture); + } + } + + return obj_ptr; +} + +static void M_InsertFlatRect_ZBuffered( + RENDERER *const renderer, int32_t x1, int32_t y1, int32_t x2, int32_t y2, + int32_t z, const uint8_t color_idx) +{ + if (x2 <= x1 || y2 <= y1) { + return; + } + + CLAMPL(x1, 0); + CLAMPL(y1, 0); + CLAMPG(x2, g_PhdWinWidth); + CLAMPG(y2, g_PhdWinHeight); + CLAMP(z, g_PhdNearZ, g_PhdFarZ); + + const double rhw = g_RhwFactor / (double)z; + const double sz = MAKE_DEPTH_FROM_RHW(rhw); + + const RGB_888 *const color = &g_GamePalette8[color_idx]; + + m_VBufferGL[0].x = x1; + m_VBufferGL[0].y = y1; + m_VBufferGL[1].x = x2; + m_VBufferGL[1].y = y1; + m_VBufferGL[2].x = x2; + m_VBufferGL[2].y = y2; + m_VBufferGL[3].x = x1; + m_VBufferGL[3].y = y2; + for (int32_t i = 0; i < 4; i++) { + GFX_3D_VERTEX *const vbuf_gl = &m_VBufferGL[i]; + vbuf_gl->z = sz; + vbuf_gl->w = rhw; + M_ShadeColor(vbuf_gl, color->red, color->green, color->blue, 0xFF); + } + + M_SelectTexture(renderer, -1); + M_EnableColorKey(renderer, false); + M_DrawPrimitive(renderer, GFX_3D_PRIM_TRI, m_VBufferGL, 4, true); +} + +static void M_InsertLine_ZBuffered( + RENDERER *const renderer, const int32_t x1, const int32_t y1, + const int32_t x2, const int32_t y2, int32_t z, const uint8_t color_idx) +{ + if (z >= g_PhdFarZ) { + return; + } + CLAMPL(z, g_PhdNearZ); + + const double rhw = g_RhwFactor / (double)z; + const double sz = MAKE_DEPTH_FROM_RHW(rhw); + const RGB_888 *const color = &g_GamePalette8[color_idx]; + + m_VBufferGL[0].x = x1; + m_VBufferGL[0].y = y1; + m_VBufferGL[1].x = x2; + m_VBufferGL[1].y = y2; + for (int32_t i = 0; i < 2; i++) { + GFX_3D_VERTEX *const vbuf_gl = &m_VBufferGL[i]; + vbuf_gl->z = sz; + vbuf_gl->w = rhw; + M_ShadeColor(vbuf_gl, color->red, color->green, color->blue, 0xFF); + } + + M_SelectTexture(renderer, -1); + M_EnableColorKey(renderer, false); + M_DrawPrimitive(renderer, GFX_3D_PRIM_LINE, m_VBufferGL, 2, true); +} + +static void M_ResetFuncPtrs(RENDERER *const renderer) +{ + renderer->InsertTransQuad = M_InsertTransQuad_Sorted; + renderer->InsertTransOctagon = M_InsertTransOctagon_Sorted; + renderer->InsertSprite = M_InsertSprite_Sorted; + if (g_Config.rendering.enable_zbuffer) { + renderer->InsertObjectG3 = M_InsertObjectG3_ZBuffered; + renderer->InsertObjectG4 = M_InsertObjectG4_ZBuffered; + renderer->InsertObjectGT3 = M_InsertObjectGT3_ZBuffered; + renderer->InsertObjectGT4 = M_InsertObjectGT4_ZBuffered; + renderer->InsertLine = M_InsertLine_ZBuffered; + renderer->InsertFlatRect = M_InsertFlatRect_ZBuffered; + } else { + renderer->InsertObjectG3 = M_InsertObjectG3_Sorted; + renderer->InsertObjectG4 = M_InsertObjectG4_Sorted; + renderer->InsertObjectGT3 = M_InsertObjectGT3_Sorted; + renderer->InsertObjectGT4 = M_InsertObjectGT4_Sorted; + renderer->InsertLine = M_InsertLine_Sorted; + renderer->InsertFlatRect = M_InsertFlatRect_Sorted; + } +} + +static void M_Init(RENDERER *const renderer) +{ + M_PRIV *const priv = Memory_Alloc(sizeof(M_PRIV)); + priv->renderer_2d = GFX_2D_Renderer_Create(); + priv->renderer_3d = GFX_3D_Renderer_Create(); + + for (int32_t i = 0; i < GFX_MAX_TEXTURES; i++) { + priv->texture_map[i] = GFX_NO_TEXTURE; + } + priv->env_map_texture = GFX_NO_TEXTURE; + + renderer->initialized = true; + renderer->priv = priv; +} + +static void M_Shutdown(RENDERER *const renderer) +{ + M_PRIV *const priv = renderer->priv; + if (!renderer->initialized) { + return; + } + + if (priv->renderer_2d == NULL) { + GFX_2D_Renderer_Destroy(priv->renderer_2d); + priv->renderer_2d = NULL; + } + + if (priv->renderer_3d == NULL) { + GFX_3D_Renderer_Destroy(priv->renderer_3d); + priv->renderer_3d = NULL; + } + + renderer->initialized = false; +} + +static void M_Open(RENDERER *const renderer) +{ + M_PRIV *const priv = renderer->priv; + ASSERT(renderer->initialized); + if (renderer->open) { + return; + } + if (!renderer->initialized) { + renderer->Init(renderer); + } + + memset(m_HWR_VertexBuffer, 0, sizeof(m_HWR_VertexBuffer)); + + for (int32_t i = 0; i < GFX_MAX_TEXTURES; i++) { + if (priv->surface_tex[i] == NULL) { + GFX_2D_SURFACE_DESC surface_desc = { + .width = TEXTURE_PAGE_WIDTH, + .height = TEXTURE_PAGE_HEIGHT, + }; + priv->surface_tex[i] = GFX_2D_Surface_Create(&surface_desc); + } + } + + M_LoadTexturePages(renderer, g_TexturePageCount, g_TexturePageBuffer16); + renderer->open = true; +} + +static void M_Close(RENDERER *const renderer) +{ + M_PRIV *const priv = renderer->priv; + if (!renderer->open) { + return; + } + + if (priv->surface_pic != NULL) { + GFX_2D_Surface_Free(priv->surface_pic); + priv->surface_pic = NULL; + } + for (int32_t i = 0; i < GFX_MAX_TEXTURES; i++) { + if (priv->surface_tex[i] != NULL) { + GFX_2D_Surface_Free(priv->surface_tex[i]); + priv->surface_tex[i] = NULL; + } + } + + M_ReleaseTextures(renderer); + renderer->open = false; +} + +static void M_BeginScene(RENDERER *const renderer) +{ + M_PRIV *const priv = renderer->priv; + ASSERT(renderer->initialized && renderer->open); + M_EnableZBuffer(renderer, true, true); + GFX_3D_Renderer_RenderBegin(priv->renderer_3d); + GFX_3D_Renderer_SetAlphaThreshold(priv->renderer_3d, -1.0); + GFX_3D_Renderer_SetTextureFilter( + priv->renderer_3d, g_Config.rendering.texture_filter); +} + +static void M_EndScene(RENDERER *const renderer) +{ +} + +static void M_Reset(RENDERER *const renderer, const RENDER_RESET_FLAGS flags) +{ + if (!renderer->initialized) { + return; + } + if (flags & (RENDER_RESET_TEXTURES | RENDER_RESET_PALETTE)) { + LOG_DEBUG("Reloading textures"); + M_LoadTexturePages(renderer, g_TexturePageCount, g_TexturePageBuffer16); + } + M_ResetFuncPtrs(renderer); +} + +static void M_ResetPolyList(RENDERER *const renderer) +{ + M_PRIV *const priv = renderer->priv; + ASSERT(renderer->initialized && renderer->open); + m_HWR_VertexPtr = m_HWR_VertexBuffer; + M_EnableZBuffer(renderer, true, true); + M_ClearZBuffer(renderer); + GFX_3D_Renderer_SetAlphaThreshold(priv->renderer_3d, -1.0); +} + +static void M_DrawPolyList(RENDERER *const renderer) +{ + M_PRIV *const priv = renderer->priv; + ASSERT(renderer->initialized && renderer->open); + + Render_SortPolyList(); + // NOTE: depth writes only work for fully transparent pixels + M_EnableZBuffer(renderer, true, true); + GFX_3D_Renderer_SetAlphaThreshold(priv->renderer_3d, 0.1); + + for (int32_t i = 0; i < g_SurfaceCount; i++) { + uint16_t *buf_ptr = (uint16_t *)g_SortBuffer[i]._0; + + uint16_t poly_type = *buf_ptr++; + uint16_t tex_page = + (poly_type == POLY_HWR_GTMAP || poly_type == POLY_HWR_WGTMAP) + ? *buf_ptr++ + : 0; + uint16_t vtx_count = *buf_ptr++; + GFX_3D_VERTEX *vtx_ptr = *(GFX_3D_VERTEX **)buf_ptr; + + switch (poly_type) { + // triangle fan (texture) + case POLY_HWR_GTMAP: + // triangle fan (texture + colorkey) + case POLY_HWR_WGTMAP: + M_SelectTexture(renderer, tex_page); + M_EnableColorKey(renderer, poly_type == POLY_HWR_WGTMAP); + M_DrawPrimitive( + renderer, GFX_3D_PRIM_TRI, vtx_ptr, vtx_count, true); + break; + + // triangle fan (color) + case POLY_HWR_GOURAUD: + M_SelectTexture(renderer, -1); + M_EnableColorKey(renderer, false); + M_DrawPrimitive( + renderer, GFX_3D_PRIM_TRI, vtx_ptr, vtx_count, true); + break; + + // line strip (color) + case POLY_HWR_LINE: + GFX_3D_Renderer_SetPrimType(priv->renderer_3d, GFX_3D_PRIM_LINE); + M_SelectTexture(renderer, -1); + M_EnableColorKey(renderer, false); + GFX_3D_Renderer_RenderPrimList( + priv->renderer_3d, vtx_ptr, vtx_count); + GFX_3D_Renderer_SetPrimType(priv->renderer_3d, GFX_3D_PRIM_TRI); + break; + + // triangle fan (color + semitransparent) + case POLY_HWR_TRANS: { + DWORD alpha_state; + GFX_3D_Renderer_SetBlendingMode( + priv->renderer_3d, GFX_BLEND_MODE_NORMAL); + M_SelectTexture(renderer, -1); + M_DrawPrimitive( + renderer, GFX_3D_PRIM_TRI, vtx_ptr, vtx_count, true); + GFX_3D_Renderer_SetBlendingMode( + priv->renderer_3d, GFX_BLEND_MODE_OFF); + break; + } + } + } + + GFX_3D_Renderer_RenderEnd(priv->renderer_3d); +} + +static void M_EnableZBuffer( + RENDERER *const renderer, const bool z_write_enable, + const bool z_test_enable) +{ + M_PRIV *const priv = renderer->priv; + GFX_3D_Renderer_SetDepthBufferEnabled( + priv->renderer_3d, g_Config.rendering.enable_zbuffer); + GFX_3D_Renderer_SetDepthWritesEnabled(priv->renderer_3d, z_write_enable); + GFX_3D_Renderer_SetDepthTestEnabled(priv->renderer_3d, z_test_enable); +} + +static void M_ClearZBuffer(RENDERER *const renderer) +{ + M_PRIV *const priv = renderer->priv; + GFX_3D_Renderer_ClearDepth(priv->renderer_3d); +} + +void Renderer_HW_Prepare(RENDERER *const renderer) +{ + renderer->Init = M_Init; + renderer->Open = M_Open; + renderer->Close = M_Close; + renderer->Shutdown = M_Shutdown; + renderer->BeginScene = M_BeginScene; + renderer->EndScene = M_EndScene; + renderer->Reset = M_Reset; + renderer->ResetPolyList = M_ResetPolyList; + renderer->DrawPolyList = M_DrawPolyList; + renderer->EnableZBuffer = M_EnableZBuffer; + renderer->ClearZBuffer = M_ClearZBuffer; + M_ResetFuncPtrs(renderer); +} diff --git a/src/tr2/game/render/hwr.h b/src/tr2/game/render/hwr.h new file mode 100644 index 000000000..82ee8df88 --- /dev/null +++ b/src/tr2/game/render/hwr.h @@ -0,0 +1,5 @@ +#pragma once + +#include "game/render/priv.h" + +void Renderer_HW_Prepare(RENDERER *renderer); diff --git a/src/tr2/game/render/priv.c b/src/tr2/game/render/priv.c new file mode 100644 index 000000000..c93242177 --- /dev/null +++ b/src/tr2/game/render/priv.c @@ -0,0 +1,533 @@ +#include "game/render/priv.h" + +#include "config.h" +#include "global/vars.h" + +#include + +bool g_DiscardTransparent = false; + +static void M_QuickSort(int32_t left, int32_t right); +static inline void M_ClipG( + VERTEX_INFO *buf, const VERTEX_INFO *vtx1, const VERTEX_INFO *vtx2, + float clip); +static inline void M_ClipGUV( + VERTEX_INFO *buf, const VERTEX_INFO *vtx1, const VERTEX_INFO *vtx2, + float clip); + +static void M_QuickSort(const int32_t left, const int32_t right) +{ + const int32_t compare = g_SortBuffer[(left + right) / 2]._1; + int32_t i = left; + int32_t j = right; + + do { + while ((i < right) && (g_SortBuffer[i]._1 > compare)) { + i++; + } + while ((left < j) && (compare > g_SortBuffer[j]._1)) { + j--; + } + if (i > j) { + break; + } + + SORT_ITEM tmp_item; + SWAP(g_SortBuffer[i], g_SortBuffer[j], tmp_item); + + i++; + j--; + } while (i <= j); + + if (left < j) { + M_QuickSort(left, j); + } + if (i < right) { + M_QuickSort(i, right); + } +} + +static inline void M_ClipG( + VERTEX_INFO *const buf, const VERTEX_INFO *const vtx1, + const VERTEX_INFO *const vtx2, const float clip) +{ + buf->rhw = vtx2->rhw + (vtx1->rhw - vtx2->rhw) * clip; + buf->g = vtx2->g + (vtx1->g - vtx2->g) * clip; +} + +static inline void M_ClipGUV( + VERTEX_INFO *const buf, const VERTEX_INFO *const vtx1, + const VERTEX_INFO *const vtx2, const float clip) +{ + buf->rhw = vtx2->rhw + (vtx1->rhw - vtx2->rhw) * clip; + buf->g = vtx2->g + (vtx1->g - vtx2->g) * clip; + buf->u = vtx2->u + (vtx1->u - vtx2->u) * clip; + buf->v = vtx2->v + (vtx1->v - vtx2->v) * clip; +} + +double Render_CalculatePolyZ( + const SORT_TYPE sort_type, const double z0, const double z1, + const double z2, const double z3) +{ + double zv = 0.0; + switch (sort_type) { + case ST_AVG_Z: + zv = (z3 > 0.0) ? (z0 + z1 + z2 + z3) / 4.0 : (z0 + z1 + z2) / 3.0; + break; + + case ST_MAX_Z: + zv = z0; + CLAMPL(zv, z1); + CLAMPL(zv, z2); + if (z3 > 0.0) { + CLAMPL(zv, z3); + } + break; + + case ST_FAR_Z: + default: + zv = 1000000000.0; + break; + } + return zv; +} + +void Render_SortPolyList(void) +{ + if (g_SurfaceCount) { + for (int32_t i = 0; i < g_SurfaceCount; i++) { + g_SortBuffer[i]._1 += i; + } + M_QuickSort(0, g_SurfaceCount - 1); + } +} + +int32_t Render_GetUVAdjustment(void) +{ + if (g_Config.rendering.render_mode == RM_HARDWARE + && (g_Config.rendering.texel_adjust_mode == TAM_ALWAYS + || (g_Config.rendering.texel_adjust_mode == TAM_BILINEAR_ONLY + && g_Config.rendering.texture_filter == GFX_TF_BILINEAR))) { + return g_Config.rendering.linear_adjustment; + } + + return g_Config.rendering.nearest_adjustment; +} + +void Render_AdjustTextureUVs(const bool reset_uv_add) +{ + if (g_TextureInfoCount <= 0) { + return; + } + + const int32_t offset = Render_GetUVAdjustment(); + for (int32_t i = 0; i < g_TextureInfoCount; i++) { + PHD_UV *const uv = g_TextureInfo[i].uv; + const PHD_UV *const uv_backup = g_TextureInfo[i].uv_backup; + int32_t uv_flags = g_LabTextureUVFlag[i]; + for (int32_t j = 0; j < 4; j++) { + uv[j].u = uv_backup[j].u + ((uv_flags & 1) ? -offset : offset); + uv[j].v = uv_backup[j].v + ((uv_flags & 2) ? -offset : offset); + uv_flags >>= 2; + } + } +} + +int32_t Render_VisibleZClip( + const PHD_VBUF *const vtx0, const PHD_VBUF *const vtx1, + const PHD_VBUF *const vtx2) +{ + // clang-format off + return ( + vtx1->xv * (vtx0->yv * vtx2->zv - vtx0->zv * vtx2->yv) + + vtx1->yv * (vtx0->zv * vtx2->xv - vtx0->xv * vtx2->zv) + + vtx1->zv * (vtx0->xv * vtx2->yv - vtx0->yv * vtx2->xv) < 0.0 + ); + // clang-format on +} + +int32_t Render_ZedClipper( + const int32_t vtx_count, const POINT_INFO *const points, + VERTEX_INFO *const vtx) +{ + int32_t j = 0; + const POINT_INFO *pts0 = &points[0]; + const POINT_INFO *pts1 = &points[vtx_count - 1]; + + for (int32_t i = 0; i < vtx_count; i++) { + const int32_t diff0 = g_FltNearZ - pts0->zv; + const int32_t diff1 = g_FltNearZ - pts1->zv; + if ((diff0 | diff1) >= 0) { + goto loop_end; + } + + if ((diff0 ^ diff1) < 0) { + const double clip = diff0 / (pts1->zv - pts0->zv); + vtx[j].x = + (pts0->xv + (pts1->xv - pts0->xv) * clip) * g_FltPerspONearZ + + g_FltWinCenterX; + vtx[j].y = + (pts0->yv + (pts1->yv - pts0->yv) * clip) * g_FltPerspONearZ + + g_FltWinCenterY; + vtx[j].z = pts0->zv + (pts1->zv - pts0->zv) * clip; + vtx[j].rhw = g_FltRhwONearZ; + vtx[j].g = pts0->g + (pts1->g - pts0->g) * clip; + vtx[j].u = (pts0->u + (pts1->u - pts0->u) * clip) * g_FltRhwONearZ; + vtx[j].v = (pts0->v + (pts1->v - pts0->v) * clip) * g_FltRhwONearZ; + j++; + } + + if (diff0 < 0) { + vtx[j].x = pts0->xs; + vtx[j].y = pts0->ys; + vtx[j].z = pts0->zv; + vtx[j].rhw = pts0->rhw; + vtx[j].g = pts0->g; + vtx[j].u = pts0->u * pts0->rhw; + vtx[j].v = pts0->v * pts0->rhw; + j++; + } + + loop_end: + pts1 = pts0++; + } + + return (j < 3) ? 0 : j; +} + +int32_t Render_XYClipper(int32_t vtx_count, VERTEX_INFO *const vtx) +{ + int32_t j; + VERTEX_INFO vtx_buf[20]; + const VERTEX_INFO *vtx1; + const VERTEX_INFO *vtx2; + + if (vtx_count < 3) { + return 0; + } + + // horizontal clip + j = 0; + vtx2 = &vtx[vtx_count - 1]; + for (int32_t i = 0; i < vtx_count; i++) { + vtx1 = vtx2; + vtx2 = &vtx[i]; + + if (vtx1->x < g_FltWinLeft) { + if (vtx2->x < g_FltWinLeft) { + continue; + } + const float clip = (g_FltWinLeft - vtx2->x) / (vtx1->x - vtx2->x); + vtx_buf[j].x = g_FltWinLeft; + vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; + vtx_buf[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + vtx_buf[j].rhw = vtx2->rhw + (vtx1->rhw - vtx2->rhw) * clip; + j++; + } else if (vtx1->x > g_FltWinRight) { + if (vtx2->x > g_FltWinRight) { + continue; + } + const float clip = (g_FltWinRight - vtx2->x) / (vtx1->x - vtx2->x); + vtx_buf[j].x = g_FltWinRight; + vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; + vtx_buf[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + vtx_buf[j].rhw = vtx2->rhw + (vtx1->rhw - vtx2->rhw) * clip; + j++; + } + + if (vtx2->x < g_FltWinLeft) { + const float clip = (g_FltWinLeft - vtx2->x) / (vtx1->x - vtx2->x); + vtx_buf[j].x = g_FltWinLeft; + vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; + vtx_buf[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + vtx_buf[j].rhw = vtx2->rhw + (vtx1->rhw - vtx2->rhw) * clip; + j++; + } else if (vtx2->x > g_FltWinRight) { + const float clip = (g_FltWinRight - vtx2->x) / (vtx1->x - vtx2->x); + vtx_buf[j].x = g_FltWinRight; + vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; + vtx_buf[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + vtx_buf[j].rhw = vtx2->rhw + (vtx1->rhw - vtx2->rhw) * clip; + j++; + } else { + vtx_buf[j].x = vtx2->x; + vtx_buf[j].y = vtx2->y; + vtx_buf[j].z = vtx2->z; + vtx_buf[j].rhw = vtx2->rhw; + j++; + } + } + + vtx_count = j; + if (vtx_count < 3) { + return 0; + } + + // vertical clip + j = 0; + vtx2 = &vtx_buf[vtx_count - 1]; + for (int32_t i = 0; i < vtx_count; i++) { + vtx1 = vtx2; + vtx2 = &vtx_buf[i]; + + if (vtx1->y < g_FltWinTop) { + if (vtx2->y < g_FltWinTop) { + continue; + } + const float clip = (g_FltWinTop - vtx2->y) / (vtx1->y - vtx2->y); + vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; + vtx[j].y = g_FltWinTop; + vtx[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + vtx[j].rhw = vtx2->rhw + (vtx1->rhw - vtx2->rhw) * clip; + j++; + } else if (vtx1->y > g_FltWinBottom) { + if (vtx2->y > g_FltWinBottom) { + continue; + } + const float clip = (g_FltWinBottom - vtx2->y) / (vtx1->y - vtx2->y); + vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; + vtx[j].y = g_FltWinBottom; + vtx[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + vtx[j].rhw = vtx2->rhw + (vtx1->rhw - vtx2->rhw) * clip; + j++; + } + + if (vtx2->y < g_FltWinTop) { + const float clip = (g_FltWinTop - vtx2->y) / (vtx1->y - vtx2->y); + vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; + vtx[j].y = g_FltWinTop; + vtx[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + vtx[j].rhw = vtx2->rhw + (vtx1->rhw - vtx2->rhw) * clip; + j++; + } else if (vtx2->y > g_FltWinBottom) { + const float clip = (g_FltWinBottom - vtx2->y) / (vtx1->y - vtx2->y); + vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; + vtx[j].y = g_FltWinBottom; + vtx[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + vtx[j].rhw = vtx2->rhw + (vtx1->rhw - vtx2->rhw) * clip; + j++; + } else { + vtx[j].x = vtx2->x; + vtx[j].y = vtx2->y; + vtx[j].z = vtx2->z; + vtx[j].rhw = vtx2->rhw; + j++; + } + } + + return (j < 3) ? 0 : j; +} + +int32_t Render_XYGClipper(int32_t vtx_count, VERTEX_INFO *const vtx) +{ + VERTEX_INFO vtx_buf[8]; + const VERTEX_INFO *vtx1; + const VERTEX_INFO *vtx2; + int32_t j; + + if (vtx_count < 3) { + return 0; + } + + // horizontal clip + j = 0; + vtx2 = &vtx[vtx_count - 1]; + for (int32_t i = 0; i < vtx_count; i++) { + vtx1 = vtx2; + vtx2 = &vtx[i]; + + if (vtx1->x < g_FltWinLeft) { + if (vtx2->x < g_FltWinLeft) { + continue; + } + const float clip = (g_FltWinLeft - vtx2->x) / (vtx1->x - vtx2->x); + vtx_buf[j].x = g_FltWinLeft; + vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; + vtx_buf[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + M_ClipG(&vtx_buf[j++], vtx1, vtx2, clip); + } else if (vtx1->x > g_FltWinRight) { + if (vtx2->x > g_FltWinRight) { + continue; + } + const float clip = (g_FltWinRight - vtx2->x) / (vtx1->x - vtx2->x); + vtx_buf[j].x = g_FltWinRight; + vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; + vtx_buf[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + M_ClipG(&vtx_buf[j++], vtx1, vtx2, clip); + } + + if (vtx2->x < g_FltWinLeft) { + const float clip = (g_FltWinLeft - vtx2->x) / (vtx1->x - vtx2->x); + vtx_buf[j].x = g_FltWinLeft; + vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; + vtx_buf[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + M_ClipG(&vtx_buf[j++], vtx1, vtx2, clip); + } else if (vtx2->x > g_FltWinRight) { + const float clip = (g_FltWinRight - vtx2->x) / (vtx1->x - vtx2->x); + vtx_buf[j].x = g_FltWinRight; + vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; + vtx_buf[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + M_ClipG(&vtx_buf[j++], vtx1, vtx2, clip); + } else { + vtx_buf[j++] = *vtx2; + } + } + + vtx_count = j; + if (vtx_count < 3) { + return 0; + } + + // vertical clip + j = 0; + vtx2 = &vtx_buf[vtx_count - 1]; + for (int32_t i = 0; i < vtx_count; i++) { + vtx1 = vtx2; + vtx2 = &vtx_buf[i]; + + if (vtx1->y < g_FltWinTop) { + if (vtx2->y < g_FltWinTop) { + continue; + } + const float clip = (g_FltWinTop - vtx2->y) / (vtx1->y - vtx2->y); + vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; + vtx[j].y = g_FltWinTop; + vtx[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + M_ClipG(&vtx[j++], vtx1, vtx2, clip); + } else if (vtx1->y > g_FltWinBottom) { + if (vtx2->y > g_FltWinBottom) { + continue; + } + const float clip = (g_FltWinBottom - vtx2->y) / (vtx1->y - vtx2->y); + vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; + vtx[j].y = g_FltWinBottom; + vtx[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + M_ClipG(&vtx[j++], vtx1, vtx2, clip); + } + + if (vtx2->y < g_FltWinTop) { + const float clip = (g_FltWinTop - vtx2->y) / (vtx1->y - vtx2->y); + vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; + vtx[j].y = g_FltWinTop; + vtx[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + M_ClipG(&vtx[j++], vtx1, vtx2, clip); + } else if (vtx2->y > g_FltWinBottom) { + const float clip = (g_FltWinBottom - vtx2->y) / (vtx1->y - vtx2->y); + vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; + vtx[j].y = g_FltWinBottom; + vtx[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + M_ClipG(&vtx[j++], vtx1, vtx2, clip); + } else { + vtx[j++] = *vtx2; + } + } + + return (j < 3) ? 0 : j; +} + +int32_t Render_XYGUVClipper(int32_t vtx_count, VERTEX_INFO *const vtx) +{ + VERTEX_INFO vtx_buf[8]; + const VERTEX_INFO *vtx1; + const VERTEX_INFO *vtx2; + int32_t j; + + if (vtx_count < 3) { + return 0; + } + + // horizontal clip + j = 0; + vtx2 = &vtx[vtx_count - 1]; + for (int32_t i = 0; i < vtx_count; i++) { + vtx1 = vtx2; + vtx2 = &vtx[i]; + + if (vtx1->x < g_FltWinLeft) { + if (vtx2->x < g_FltWinLeft) { + continue; + } + float clip = (g_FltWinLeft - vtx2->x) / (vtx1->x - vtx2->x); + vtx_buf[j].x = g_FltWinLeft; + vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; + vtx_buf[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + M_ClipGUV(&vtx_buf[j++], vtx1, vtx2, clip); + } else if (vtx1->x > g_FltWinRight) { + if (vtx2->x > g_FltWinRight) { + continue; + } + float clip = (g_FltWinRight - vtx2->x) / (vtx1->x - vtx2->x); + vtx_buf[j].x = g_FltWinRight; + vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; + vtx_buf[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + M_ClipGUV(&vtx_buf[j++], vtx1, vtx2, clip); + } + + if (vtx2->x < g_FltWinLeft) { + float clip = (g_FltWinLeft - vtx2->x) / (vtx1->x - vtx2->x); + vtx_buf[j].x = g_FltWinLeft; + vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; + vtx_buf[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + M_ClipGUV(&vtx_buf[j++], vtx1, vtx2, clip); + } else if (vtx2->x > g_FltWinRight) { + float clip = (g_FltWinRight - vtx2->x) / (vtx1->x - vtx2->x); + vtx_buf[j].x = g_FltWinRight; + vtx_buf[j].y = vtx2->y + (vtx1->y - vtx2->y) * clip; + vtx_buf[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + M_ClipGUV(&vtx_buf[j++], vtx1, vtx2, clip); + } else { + vtx_buf[j++] = *vtx2; + } + } + + vtx_count = j; + if (vtx_count < 3) { + return 0; + } + + // vertical clip + j = 0; + vtx2 = &vtx_buf[vtx_count - 1]; + for (int32_t i = 0; i < vtx_count; i++) { + vtx1 = vtx2; + vtx2 = &vtx_buf[i]; + + if (vtx1->y < g_FltWinTop) { + if (vtx2->y < g_FltWinTop) { + continue; + } + const float clip = (g_FltWinTop - vtx2->y) / (vtx1->y - vtx2->y); + vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; + vtx[j].y = g_FltWinTop; + vtx[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + M_ClipGUV(&vtx[j++], vtx1, vtx2, clip); + } else if (vtx1->y > g_FltWinBottom) { + if (vtx2->y > g_FltWinBottom) { + continue; + } + const float clip = (g_FltWinBottom - vtx2->y) / (vtx1->y - vtx2->y); + vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; + vtx[j].y = g_FltWinBottom; + vtx[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + M_ClipGUV(&vtx[j++], vtx1, vtx2, clip); + } + + if (vtx2->y < g_FltWinTop) { + const float clip = (g_FltWinTop - vtx2->y) / (vtx1->y - vtx2->y); + vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; + vtx[j].y = g_FltWinTop; + vtx[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + M_ClipGUV(&vtx[j++], vtx1, vtx2, clip); + } else if (vtx2->y > g_FltWinBottom) { + const float clip = (g_FltWinBottom - vtx2->y) / (vtx1->y - vtx2->y); + vtx[j].x = vtx2->x + (vtx1->x - vtx2->x) * clip; + vtx[j].y = g_FltWinBottom; + vtx[j].z = vtx2->z + (vtx1->z - vtx2->z) * clip; + M_ClipGUV(&vtx[j++], vtx1, vtx2, clip); + } else { + vtx[j++] = *vtx2; + } + } + + return (j < 3) ? 0 : j; +} diff --git a/src/tr2/game/render/priv.h b/src/tr2/game/render/priv.h new file mode 100644 index 000000000..786cf1dcf --- /dev/null +++ b/src/tr2/game/render/priv.h @@ -0,0 +1,81 @@ +#pragma once + +#include "game/output.h" +#include "game/render/common.h" + +#define VBUF_VISIBLE(a, b, c) \ + (((a).ys - (b).ys) * ((c).xs - (b).xs) \ + >= ((c).ys - (b).ys) * ((a).xs - (b).xs)) +#define MAKE_ZSORT(z) ((uint32_t)(z)) + +typedef struct RENDERER { + void (*Init)(struct RENDERER *); + void (*Shutdown)(struct RENDERER *); + + void (*Open)(struct RENDERER *); + void (*Close)(struct RENDERER *); + + void (*Reset)(struct RENDERER *, RENDER_RESET_FLAGS source); + + void (*BeginScene)(struct RENDERER *); + void (*EndScene)(struct RENDERER *); + + void (*ResetPolyList)(struct RENDERER *); + void (*ClearZBuffer)(struct RENDERER *); + void (*EnableZBuffer)(struct RENDERER *, bool, bool); + void (*DrawPolyList)(struct RENDERER *); + + const int16_t *(*InsertGT4)( + struct RENDERER *renderer, const int16_t *obj_ptr, int32_t num, + SORT_TYPE sort_type); + + const int16_t *(*InsertObjectG3)( + struct RENDERER *renderer, const int16_t *obj_ptr, int32_t num, + SORT_TYPE sort_type); + const int16_t *(*InsertObjectG4)( + struct RENDERER *renderer, const int16_t *obj_ptr, int32_t num, + SORT_TYPE sort_type); + const int16_t *(*InsertObjectGT3)( + struct RENDERER *renderer, const int16_t *obj_ptr, int32_t num, + SORT_TYPE sort_type); + const int16_t *(*InsertObjectGT4)( + struct RENDERER *renderer, const int16_t *obj_ptr, int32_t num, + SORT_TYPE sort_type); + void (*InsertTransQuad)( + struct RENDERER *renderer, int32_t x, int32_t y, int32_t width, + int32_t height, int32_t z); + void (*InsertTransOctagon)( + struct RENDERER *renderer, const PHD_VBUF *vbuf, int16_t shade); + void (*InsertFlatRect)( + struct RENDERER *renderer, int32_t x0, int32_t y0, int32_t x1, + int32_t y1, int32_t z, uint8_t color_idx); + void (*InsertSprite)( + struct RENDERER *renderer, int32_t z, int32_t x0, int32_t y0, + int32_t x1, int32_t y1, int32_t sprite_idx, int16_t shade); + void (*InsertLine)( + struct RENDERER *renderer, int32_t x0, int32_t y0, int32_t x1, + int32_t y1, int32_t z, uint8_t color_idx); + + bool initialized; + bool open; + + void *priv; +} RENDERER; + +// TODO: don't be a global +extern bool g_DiscardTransparent; + +double Render_CalculatePolyZ( + SORT_TYPE sort_type, double z0, double z1, double z2, double z3); + +void Render_SortPolyList(void); +int32_t Render_GetUVAdjustment(void); +void Render_AdjustTextureUVs(bool reset_uv_add); + +int32_t Render_VisibleZClip( + const PHD_VBUF *vtx0, const PHD_VBUF *vtx1, const PHD_VBUF *vtx2); +int32_t Render_ZedClipper( + int32_t vtx_count, const POINT_INFO *pts, VERTEX_INFO *vtx); +int32_t Render_XYClipper(int32_t vtx_count, VERTEX_INFO *vtx); +int32_t Render_XYGClipper(int32_t vtx_count, VERTEX_INFO *vtx); +int32_t Render_XYGUVClipper(int32_t vtx_count, VERTEX_INFO *vtx); diff --git a/src/tr2/game/render/swr.c b/src/tr2/game/render/swr.c new file mode 100644 index 000000000..2c3ac9981 --- /dev/null +++ b/src/tr2/game/render/swr.c @@ -0,0 +1,2270 @@ +#include "game/render/swr.h" + +#include "decomp/decomp.h" +#include "game/output.h" +#include "game/render/priv.h" +#include "global/vars.h" + +#include +#include +#include +#include + +#define MAKE_Q_ID(g) ((g >> 16) & 0xFF) +#define MAKE_TEX_ID(v, u) ((((v >> 16) & 0xFF) << 8) | ((u >> 16) & 0xFF)) +#define MAKE_PAL_IDX(c) (c) +#define PIX_FMT uint8_t +#define PIX_FMT_GL GL_UNSIGNED_BYTE +#define ALPHA_FMT uint8_t + +typedef struct { + GFX_2D_RENDERER *renderer_2d; + GFX_2D_SURFACE *surface; + GFX_2D_SURFACE *surface_alpha; + GFX_PALETTE_ENTRY palette[256]; +} M_PRIV; + +static VERTEX_INFO m_VBuffer[32] = { 0 }; + +static void __fastcall M_FlatA( + GFX_2D_SURFACE *target_surface, int32_t y1, int32_t y2, uint8_t color_idx); +static void __fastcall M_TransA( + GFX_2D_SURFACE *target_surface, int32_t y1, int32_t y2, uint8_t depth_q); +static void __fastcall M_GourA( + GFX_2D_SURFACE *target_surface, int32_t y1, int32_t y2, uint8_t color_idx); +static void __fastcall M_GTMapA( + GFX_2D_SURFACE *target_surface, int32_t y1, int32_t y2, + const uint8_t *tex_page); +static void __fastcall M_WGTMapA( + GFX_2D_SURFACE *target_surface, int32_t y1, int32_t y2, + const uint8_t *tex_page); +static void M_GTMapPersp32FP( + GFX_2D_SURFACE *target_surface, int32_t y1, int32_t y2, + const uint8_t *tex_page); +static void M_WGTMapPersp32FP( + GFX_2D_SURFACE *target_surface, int32_t y1, int32_t y2, + const uint8_t *tex_page); + +static bool M_XGenX(const int16_t *obj_ptr); +static bool M_XGenXG(const int16_t *obj_ptr); +static bool M_XGenXGUV(const int16_t *obj_ptr); + +static void M_OccludeX(GFX_2D_SURFACE *alpha_surface, int32_t y1, int32_t y2); +static void M_OccludeXG(GFX_2D_SURFACE *alpha_surface, int32_t y1, int32_t y2); +static void M_OccludeXGUV( + GFX_2D_SURFACE *alpha_surface, int32_t y1, int32_t y2); +static void M_OccludeXGUVP( + GFX_2D_SURFACE *alpha_surface, int32_t y1, int32_t y2); + +static void M_DrawPolyFlat( + const int16_t *obj_ptr, GFX_2D_SURFACE *target_surface, + GFX_2D_SURFACE *alpha_surface); +static void M_DrawPolyTrans( + const int16_t *obj_ptr, GFX_2D_SURFACE *target_surface, + GFX_2D_SURFACE *alpha_surface); +static void M_DrawPolyGouraud( + const int16_t *obj_ptr, GFX_2D_SURFACE *target_surface, + GFX_2D_SURFACE *alpha_surface); +static void M_DrawPolyGTMap( + const int16_t *obj_ptr, GFX_2D_SURFACE *target_surface, + GFX_2D_SURFACE *alpha_surface); +static void M_DrawPolyWGTMap( + const int16_t *obj_ptr, GFX_2D_SURFACE *target_surface, + GFX_2D_SURFACE *alpha_surface); +static void M_DrawPolyGTMapPersp( + const int16_t *obj_ptr, GFX_2D_SURFACE *target_surface, + GFX_2D_SURFACE *alpha_surface); +static void M_DrawPolyWGTMapPersp( + const int16_t *obj_ptr, GFX_2D_SURFACE *target_surface, + GFX_2D_SURFACE *alpha_surface); +static void M_DrawPolyLine( + const int16_t *obj_ptr, GFX_2D_SURFACE *target_surface, + GFX_2D_SURFACE *alpha_surface); +static void M_DrawScaledSpriteC( + const int16_t *obj_ptr, GFX_2D_SURFACE *target_surface, + GFX_2D_SURFACE *alpha_surface); + +static const int16_t *M_InsertObjectG3( + RENDERER *renderer, const int16_t *obj_ptr, int32_t num, + SORT_TYPE sort_type); +static const int16_t *M_InsertObjectG4( + RENDERER *renderer, const int16_t *obj_ptr, int32_t num, + SORT_TYPE sort_type); +static const int16_t *M_InsertObjectGT3( + RENDERER *renderer, const int16_t *obj_ptr, int32_t num, + SORT_TYPE sort_type); +static const int16_t *M_InsertObjectGT4( + RENDERER *renderer, const int16_t *obj_ptr, int32_t num, + SORT_TYPE sort_type); +static void M_InsertLine( + RENDERER *renderer, int32_t x1, int32_t y1, int32_t x2, int32_t y2, + int32_t z, uint8_t color_idx); +static void M_InsertFlatRect( + RENDERER *renderer, int32_t x1, int32_t y1, int32_t x2, int32_t y2, + int32_t z, uint8_t color_idx); +static void M_InsertTransQuad( + RENDERER *renderer, int32_t x, int32_t y, int32_t width, int32_t height, + int32_t z); +static void M_InsertTransOctagon( + RENDERER *renderer, const PHD_VBUF *vbuf, int16_t shade); +static void M_InsertSprite( + RENDERER *renderer, int32_t z, int32_t x0, int32_t y0, const int32_t x1, + int32_t y1, int32_t sprite_idx, const int16_t shade); + +static void (*m_PolyDrawRoutines[])( + const int16_t *, GFX_2D_SURFACE *, GFX_2D_SURFACE *) = { + M_DrawPolyGTMap, M_DrawPolyWGTMap, M_DrawPolyGTMapPersp, + M_DrawPolyWGTMapPersp, M_DrawPolyLine, M_DrawPolyFlat, + M_DrawPolyGouraud, M_DrawPolyTrans, M_DrawScaledSpriteC, +}; + +static void __fastcall M_FlatA( + GFX_2D_SURFACE *const target_surface, int32_t y1, int32_t y2, + const uint8_t color_idx) +{ + int32_t y_size = y2 - y1; + if (y_size <= 0) { + return; + } + + const int32_t stride = target_surface->desc.pitch; + const XBUF_X *xbuf = (const XBUF_X *)g_XBuffer + y1; + PIX_FMT *draw_ptr = target_surface->buffer + y1 * stride; + + while (y_size > 0) { + const int32_t x = xbuf->x1 / PHD_ONE; + const int32_t x_size = (xbuf->x2 / PHD_ONE) - x; + if (x_size > 0) { + memset( + draw_ptr + x, MAKE_PAL_IDX(color_idx), + x_size * sizeof(PIX_FMT)); + } + y_size--; + xbuf++; + draw_ptr += stride; + } +} + +static void __fastcall M_TransA( + GFX_2D_SURFACE *const target_surface, const int32_t y1, const int32_t y2, + const uint8_t depth_q) +{ + int32_t y_size = y2 - y1; + // TODO: depth_q should be at most 32 here + if (y_size <= 0 || depth_q > 32) { + return; + } + + const int32_t stride = target_surface->desc.pitch; + const XBUF_X *xbuf = (const XBUF_X *)g_XBuffer + y1; + PIX_FMT *draw_ptr = target_surface->buffer + y1 * stride; + const DEPTHQ_ENTRY *qt = g_DepthQTable + depth_q; + + while (y_size > 0) { + const int32_t x = xbuf->x1 / PHD_ONE; + int32_t x_size = (xbuf->x2 / PHD_ONE) - x; + if (x_size <= 0) { + goto loop_end; + } + + PIX_FMT *line_ptr = draw_ptr + x; + while (x_size > 0) { + *line_ptr = MAKE_PAL_IDX(qt->index[*line_ptr]); + line_ptr++; + x_size--; + } + + loop_end: + y_size--; + xbuf++; + draw_ptr += stride; + } +} + +static void __fastcall M_GourA( + GFX_2D_SURFACE *const target_surface, const int32_t y1, const int32_t y2, + const uint8_t color_idx) +{ + int32_t y_size = y2 - y1; + if (y_size <= 0) { + return; + } + + const int32_t stride = target_surface->desc.pitch; + const XBUF_XG *xbuf = (const XBUF_XG *)g_XBuffer + y1; + PIX_FMT *draw_ptr = target_surface->buffer + y1 * stride; + const GOURAUD_ENTRY *gt = g_GouraudTable + color_idx; + + while (y_size > 0) { + const int32_t x = xbuf->x1 / PHD_ONE; + int32_t x_size = (xbuf->x2 / PHD_ONE) - x; + if (x_size <= 0) { + goto loop_end; + } + + int32_t g = xbuf->g1; + const int32_t g_add = (xbuf->g2 - g) / x_size; + + PIX_FMT *line_ptr = draw_ptr + x; + while (x_size > 0) { + *line_ptr = MAKE_PAL_IDX(gt->index[MAKE_Q_ID(g)]); + line_ptr++; + g += g_add; + x_size--; + } + + loop_end: + y_size--; + xbuf++; + draw_ptr += stride; + } +} + +static void __fastcall M_GTMapA( + GFX_2D_SURFACE *const target_surface, const int32_t y1, const int32_t y2, + const uint8_t *const tex_page) +{ + int32_t y_size = y2 - y1; + if (y_size <= 0) { + return; + } + + const int32_t stride = target_surface->desc.pitch; + const XBUF_XGUV *xbuf = (const XBUF_XGUV *)g_XBuffer + y1; + PIX_FMT *draw_ptr = target_surface->buffer + y1 * stride; + + while (y_size > 0) { + const int32_t x = xbuf->x1 / PHD_ONE; + int32_t x_size = (xbuf->x2 / PHD_ONE) - x; + if (x_size <= 0) { + goto loop_end; + } + + int32_t g = xbuf->g1; + int32_t u = xbuf->u1; + int32_t v = xbuf->v1; + const int32_t g_add = (xbuf->g2 - g) / x_size; + const int32_t u_add = (xbuf->u2 - u) / x_size; + const int32_t v_add = (xbuf->v2 - v) / x_size; + + PIX_FMT *line_ptr = draw_ptr + x; + while (x_size > 0) { + uint8_t color_idx = tex_page[MAKE_TEX_ID(v, u)]; + *line_ptr = + MAKE_PAL_IDX(g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]); + line_ptr++; + g += g_add; + u += u_add; + v += v_add; + x_size--; + } + + loop_end: + y_size--; + xbuf++; + draw_ptr += stride; + } +} + +static void __fastcall M_WGTMapA( + GFX_2D_SURFACE *target_surface, const int32_t y1, const int32_t y2, + const uint8_t *tex_page) +{ + int32_t y_size = y2 - y1; + if (y_size <= 0) { + return; + } + + const int32_t stride = target_surface->desc.pitch; + const XBUF_XGUV *xbuf = (const XBUF_XGUV *)g_XBuffer + y1; + PIX_FMT *draw_ptr = target_surface->buffer + y1 * stride; + + while (y_size > 0) { + const int32_t x = xbuf->x1 / PHD_ONE; + int32_t x_size = (xbuf->x2 / PHD_ONE) - x; + if (x_size <= 0) { + goto loop_end; + } + + int32_t g = xbuf->g1; + int32_t u = xbuf->u1; + int32_t v = xbuf->v1; + const int32_t g_add = (xbuf->g2 - g) / x_size; + const int32_t u_add = (xbuf->u2 - u) / x_size; + const int32_t v_add = (xbuf->v2 - v) / x_size; + + PIX_FMT *line_ptr = draw_ptr + x; + while (x_size > 0) { + const uint8_t color_idx = tex_page[MAKE_TEX_ID(v, u)]; + if (color_idx != 0) { + *line_ptr = + MAKE_PAL_IDX(g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]); + } + line_ptr++; + g += g_add; + u += u_add; + v += v_add; + x_size--; + } + + loop_end: + y_size--; + xbuf++; + draw_ptr += stride; + } +} + +static void M_GTMapPersp32FP( + GFX_2D_SURFACE *const target_surface, const int32_t y1, const int32_t y2, + const uint8_t *const tex_page) +{ + int32_t y_size = y2 - y1; + if (y_size <= 0) { + return; + } + + const int32_t stride = target_surface->desc.pitch; + const XBUF_XGUVP *xbuf = (const XBUF_XGUVP *)g_XBuffer + y1; + PIX_FMT *draw_ptr = target_surface->buffer + y1 * stride; + + while (y_size > 0) { + const int32_t x = xbuf->x1 / PHD_ONE; + int32_t x_size = (xbuf->x2 / PHD_ONE) - x; + if (x_size <= 0) { + goto loop_end; + } + + int32_t g = xbuf->g1; + double u = xbuf->u1; + double v = xbuf->v1; + double rhw = xbuf->rhw1; + + const int32_t g_add = (xbuf->g2 - g) / x_size; + + int32_t u0 = PHD_HALF * u / rhw; + int32_t v0 = PHD_HALF * v / rhw; + + PIX_FMT *line_ptr = draw_ptr + x; + int32_t batch_size = 32; + + if (x_size >= batch_size) { + const double u_add = + (xbuf->u2 - u) / (double)x_size * (double)batch_size; + const double v_add = + (xbuf->v2 - v) / (double)x_size * (double)batch_size; + const double rhw_add = + (xbuf->rhw2 - rhw) / (double)x_size * (double)batch_size; + + while (x_size >= batch_size) { + u += u_add; + v += v_add; + rhw += rhw_add; + + const int32_t u1 = PHD_HALF * u / rhw; + const int32_t v1 = PHD_HALF * v / rhw; + + const int32_t u0_add = (u1 - u0) / batch_size; + const int32_t v0_add = (v1 - v0) / batch_size; + + if ((ABS(u0_add) + ABS(v0_add)) < (PHD_ONE / 2)) { + int32_t batch_counter = batch_size / 2; + while (batch_counter--) { + const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; + const uint8_t color = + g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; + *line_ptr++ = MAKE_PAL_IDX(color); + *line_ptr++ = MAKE_PAL_IDX(color); + g += g_add * 2; + u0 += u0_add * 2; + v0 += v0_add * 2; + } + } else { + int32_t batch_counter = batch_size; + while (batch_counter--) { + const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; + const uint8_t color = + g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; + *line_ptr++ = MAKE_PAL_IDX(color); + g += g_add; + u0 += u0_add; + v0 += v0_add; + } + } + + u0 = u1; + v0 = v1; + x_size -= batch_size; + } + } + + if (x_size > 1) { + const int32_t u1 = PHD_HALF * xbuf->u2 / xbuf->rhw2; + const int32_t v1 = PHD_HALF * xbuf->v2 / xbuf->rhw2; + const int32_t u0_add = (u1 - u0) / x_size; + const int32_t v0_add = (v1 - v0) / x_size; + + batch_size = x_size & ~1; + x_size -= batch_size; + + if ((ABS(u0_add) + ABS(v0_add)) < (PHD_ONE / 2)) { + int32_t batch_counter = batch_size / 2; + while (batch_counter--) { + const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; + const uint8_t color = + g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; + *line_ptr++ = MAKE_PAL_IDX(color); + *line_ptr++ = MAKE_PAL_IDX(color); + g += g_add * 2; + u0 += u0_add * 2; + v0 += v0_add * 2; + } + } else { + int32_t batch_counter = batch_size; + while (batch_counter--) { + const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; + const uint8_t color = + g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; + *line_ptr++ = MAKE_PAL_IDX(color); + g += g_add; + u0 += u0_add; + v0 += v0_add; + } + } + } + + if (x_size == 1) { + const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; + const uint8_t color = g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; + *line_ptr = MAKE_PAL_IDX(color); + } + + loop_end: + y_size--; + xbuf++; + draw_ptr += stride; + } +} + +static void M_WGTMapPersp32FP( + GFX_2D_SURFACE *const target_surface, const int32_t y1, const int32_t y2, + const uint8_t *const tex_page) +{ + int32_t y_size = y2 - y1; + if (y_size <= 0) { + return; + } + + const int32_t stride = target_surface->desc.pitch; + const XBUF_XGUVP *xbuf = (const XBUF_XGUVP *)g_XBuffer + y1; + PIX_FMT *draw_ptr = target_surface->buffer + y1 * stride; + + while (y_size > 0) { + const int32_t x = xbuf->x1 / PHD_ONE; + int32_t x_size = (xbuf->x2 / PHD_ONE) - x; + if (x_size <= 0) { + goto loop_end; + } + + int32_t g = xbuf->g1; + double u = xbuf->u1; + double v = xbuf->v1; + double rhw = xbuf->rhw1; + + const int32_t g_add = (xbuf->g2 - g) / x_size; + + int32_t u0 = PHD_HALF * u / rhw; + int32_t v0 = PHD_HALF * v / rhw; + + PIX_FMT *line_ptr = draw_ptr + x; + int32_t batch_size = 32; + + if (x_size >= batch_size) { + const double u_add = + (xbuf->u2 - u) / (double)x_size * (double)batch_size; + const double v_add = + (xbuf->v2 - v) / (double)x_size * (double)batch_size; + const double rhw_add = + (xbuf->rhw2 - rhw) / (double)x_size * (double)batch_size; + + while (x_size >= batch_size) { + u += u_add; + v += v_add; + rhw += rhw_add; + + const int32_t u1 = PHD_HALF * u / rhw; + const int32_t v1 = PHD_HALF * v / rhw; + + const int32_t u0_add = (u1 - u0) / batch_size; + const int32_t v0_add = (v1 - v0) / batch_size; + + if ((ABS(u0_add) + ABS(v0_add)) < (PHD_ONE / 2)) { + int32_t batch_counter = batch_size / 2; + while (batch_counter--) { + const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; + if (color_idx != 0) { + const uint8_t color = + g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; + line_ptr[0] = MAKE_PAL_IDX(color); + line_ptr[1] = MAKE_PAL_IDX(color); + } + line_ptr += 2; + g += g_add * 2; + u0 += u0_add * 2; + v0 += v0_add * 2; + } + } else { + int32_t batch_counter = batch_size; + while (batch_counter--) { + const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; + if (color_idx != 0) { + const uint8_t color = + g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; + *line_ptr = MAKE_PAL_IDX(color); + } + line_ptr++; + g += g_add; + u0 += u0_add; + v0 += v0_add; + } + } + + u0 = u1; + v0 = v1; + x_size -= batch_size; + } + } + + if (x_size > 1) { + const int32_t u1 = PHD_HALF * xbuf->u2 / xbuf->rhw2; + const int32_t v1 = PHD_HALF * xbuf->v2 / xbuf->rhw2; + const int32_t u0_add = (u1 - u0) / x_size; + const int32_t v0_add = (v1 - v0) / x_size; + + batch_size = x_size & ~1; + x_size -= batch_size; + + if ((ABS(u0_add) + ABS(v0_add)) < (PHD_ONE / 2)) { + int32_t batch_counter = batch_size / 2; + while (batch_counter--) { + const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; + if (color_idx != 0) { + const uint8_t color = + g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; + line_ptr[0] = MAKE_PAL_IDX(color); + line_ptr[1] = MAKE_PAL_IDX(color); + } + line_ptr += 2; + g += g_add * 2; + u0 += u0_add * 2; + v0 += v0_add * 2; + }; + } else { + int32_t batch_counter = batch_size; + while (batch_counter--) { + const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; + if (color_idx != 0) { + const uint8_t color = + g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; + *line_ptr = MAKE_PAL_IDX(color); + } + line_ptr++; + g += g_add; + u0 += u0_add; + v0 += v0_add; + } + } + } + + if (x_size == 1) { + const uint8_t color_idx = tex_page[MAKE_TEX_ID(v0, u0)]; + if (color_idx != 0) { + const uint8_t color = + g_DepthQTable[MAKE_Q_ID(g)].index[color_idx]; + *line_ptr = MAKE_PAL_IDX(color); + } + } + + loop_end: + y_size--; + xbuf++; + draw_ptr += stride; + } +} + +static void M_OccludeX( + GFX_2D_SURFACE *const alpha_surface, const int32_t y1, const int32_t y2) +{ + int32_t y_size = y2 - y1; + if (y_size <= 0) { + return; + } + + const int32_t stride = alpha_surface->desc.pitch; + const XBUF_X *xbuf = (const XBUF_X *)g_XBuffer + y1; + ALPHA_FMT *alpha_ptr = alpha_surface->buffer + y1 * stride; + + while (y_size > 0) { + const int32_t x = xbuf->x1 / PHD_ONE; + const int32_t x_size = (xbuf->x2 / PHD_ONE) - x; + if (x_size > 0) { + memset(alpha_ptr + x, 255, x_size * sizeof(ALPHA_FMT)); + } + y_size--; + xbuf++; + alpha_ptr += stride; + } +} + +static void M_OccludeXG( + GFX_2D_SURFACE *const alpha_surface, const int32_t y1, const int32_t y2) +{ + int32_t y_size = y2 - y1; + if (y_size <= 0) { + return; + } + + const int32_t stride = alpha_surface->desc.pitch; + const XBUF_XG *xbuf = (const XBUF_XG *)g_XBuffer + y1; + ALPHA_FMT *alpha_ptr = alpha_surface->buffer + y1 * stride; + + while (y_size > 0) { + const int32_t x = xbuf->x1 / PHD_ONE; + const int32_t x_size = (xbuf->x2 / PHD_ONE) - x; + if (x_size > 0) { + memset(alpha_ptr + x, 255, x_size * sizeof(ALPHA_FMT)); + } + y_size--; + xbuf++; + alpha_ptr += stride; + } +} + +static void M_OccludeXGUV( + GFX_2D_SURFACE *const alpha_surface, const int32_t y1, const int32_t y2) +{ + int32_t y_size = y2 - y1; + if (y_size <= 0) { + return; + } + + const int32_t stride = alpha_surface->desc.pitch; + const XBUF_XGUV *xbuf = (const XBUF_XGUV *)g_XBuffer + y1; + ALPHA_FMT *alpha_ptr = alpha_surface->buffer + y1 * stride; + + while (y_size > 0) { + const int32_t x = xbuf->x1 / PHD_ONE; + const int32_t x_size = (xbuf->x2 / PHD_ONE) - x; + if (x_size > 0) { + memset(alpha_ptr + x, 255, x_size * sizeof(ALPHA_FMT)); + } + y_size--; + xbuf++; + alpha_ptr += stride; + } +} + +static void M_OccludeXGUVP( + GFX_2D_SURFACE *const alpha_surface, const int32_t y1, const int32_t y2) +{ + int32_t y_size = y2 - y1; + if (y_size <= 0) { + return; + } + + const int32_t stride = alpha_surface->desc.pitch; + const XBUF_XGUVP *xbuf = (const XBUF_XGUVP *)g_XBuffer + y1; + ALPHA_FMT *alpha_ptr = alpha_surface->buffer + y1 * stride; + + while (y_size > 0) { + const int32_t x = xbuf->x1 / PHD_ONE; + const int32_t x_size = (xbuf->x2 / PHD_ONE) - x; + if (x_size > 0) { + memset(alpha_ptr + x, 255, x_size * sizeof(ALPHA_FMT)); + } + y_size--; + xbuf++; + alpha_ptr += stride; + } +} + +static bool M_XGenX(const int16_t *obj_ptr) +{ + int32_t pt_count = *obj_ptr++; + const XGEN_X *pt2 = (const XGEN_X *)obj_ptr; + const XGEN_X *pt1 = pt2 + (pt_count - 1); + + int32_t y_min = pt1->y; + int32_t y_max = pt1->y; + + while (pt_count--) { + const int32_t x1 = pt1->x; + const int32_t y1 = pt1->y; + const int32_t x2 = pt2->x; + const int32_t y2 = pt2->y; + pt1 = pt2++; + + if (y1 < y2) { + CLAMPG(y_min, y1); + const int32_t x_size = x2 - x1; + int32_t y_size = y2 - y1; + + XBUF_X *x_ptr = (XBUF_X *)g_XBuffer + y1; + const int32_t x_add = PHD_ONE * x_size / y_size; + int32_t x = x1 * PHD_ONE + (PHD_ONE - 1); + + while (y_size--) { + x += x_add; + x_ptr->x2 = x; + x_ptr++; + } + } else if (y2 < y1) { + CLAMPL(y_max, y1); + const int32_t x_size = x1 - x2; + int32_t y_size = y1 - y2; + + XBUF_X *x_ptr = (XBUF_X *)g_XBuffer + y2; + const int32_t x_add = PHD_ONE * x_size / y_size; + int32_t x = x2 * PHD_ONE + 1; + + while (y_size--) { + x += x_add; + x_ptr->x1 = x; + x_ptr++; + } + } + } + + if (y_min == y_max) { + return false; + } + + g_XGenY1 = y_min; + g_XGenY2 = y_max; + return true; +} + +static bool M_XGenXG(const int16_t *obj_ptr) +{ + int32_t pt_count = *obj_ptr++; + const XGEN_XG *pt2 = (const XGEN_XG *)obj_ptr; + const XGEN_XG *pt1 = pt2 + (pt_count - 1); + + int32_t y_min = pt1->y; + int32_t y_max = pt1->y; + + while (pt_count--) { + const int32_t x1 = pt1->x; + const int32_t y1 = pt1->y; + const int32_t g1 = pt1->g; + const int32_t x2 = pt2->x; + const int32_t y2 = pt2->y; + const int32_t g2 = pt2->g; + pt1 = pt2++; + + if (y1 < y2) { + CLAMPG(y_min, y1); + const int32_t g_size = g2 - g1; + const int32_t x_size = x2 - x1; + int32_t y_size = y2 - y1; + + XBUF_XG *xg_ptr = (XBUF_XG *)g_XBuffer + y1; + const int32_t x_add = PHD_ONE * x_size / y_size; + const int32_t g_add = PHD_HALF * g_size / y_size; + int32_t x = x1 * PHD_ONE + (PHD_ONE - 1); + int32_t g = g1 * PHD_HALF; + + while (y_size--) { + x += x_add; + g += g_add; + xg_ptr->x2 = x; + xg_ptr->g2 = g; + xg_ptr++; + } + } else if (y2 < y1) { + CLAMPL(y_max, y1); + const int32_t g_size = g1 - g2; + const int32_t x_size = x1 - x2; + int32_t y_size = y1 - y2; + + XBUF_XG *xg_ptr = (XBUF_XG *)g_XBuffer + y2; + const int32_t x_add = PHD_ONE * x_size / y_size; + const int32_t g_add = PHD_HALF * g_size / y_size; + int32_t x = x2 * PHD_ONE + 1; + int32_t g = g2 * PHD_HALF; + + while (y_size--) { + x += x_add; + g += g_add; + xg_ptr->x1 = x; + xg_ptr->g1 = g; + xg_ptr++; + } + } + } + + if (y_min == y_max) { + return false; + } + + g_XGenY1 = y_min; + g_XGenY2 = y_max; + return true; +} + +static bool M_XGenXGUV(const int16_t *obj_ptr) +{ + int32_t pt_count = *obj_ptr++; + const XGEN_XGUV *pt2 = (const XGEN_XGUV *)obj_ptr; + const XGEN_XGUV *pt1 = pt2 + (pt_count - 1); + + int32_t y_min = pt1->y; + int32_t y_max = pt1->y; + + while (pt_count--) { + const int32_t x1 = pt1->x; + const int32_t y1 = pt1->y; + const int32_t g1 = pt1->g; + const int32_t u1 = pt1->u; + const int32_t v1 = pt1->v; + const int32_t x2 = pt2->x; + const int32_t y2 = pt2->y; + const int32_t g2 = pt2->g; + const int32_t u2 = pt2->u; + const int32_t v2 = pt2->v; + pt1 = pt2++; + + if (y1 < y2) { + CLAMPG(y_min, y1); + const int32_t g_size = g2 - g1; + const int32_t u_size = u2 - u1; + const int32_t v_size = v2 - v1; + const int32_t x_size = x2 - x1; + int32_t y_size = y2 - y1; + + XBUF_XGUV *xguv_ptr = (XBUF_XGUV *)g_XBuffer + y1; + const int32_t x_add = PHD_ONE * x_size / y_size; + const int32_t g_add = PHD_HALF * g_size / y_size; + const int32_t u_add = PHD_HALF * u_size / y_size; + const int32_t v_add = PHD_HALF * v_size / y_size; + int32_t x = x1 * PHD_ONE + (PHD_ONE - 1); + int32_t g = g1 * PHD_HALF; + int32_t u = u1 * PHD_HALF; + int32_t v = v1 * PHD_HALF; + + while (y_size--) { + x += x_add; + g += g_add; + u += u_add; + v += v_add; + xguv_ptr->x2 = x; + xguv_ptr->g2 = g; + xguv_ptr->u2 = u; + xguv_ptr->v2 = v; + xguv_ptr++; + } + } else if (y2 < y1) { + CLAMPL(y_max, y1); + const int32_t g_size = g1 - g2; + const int32_t u_size = u1 - u2; + const int32_t v_size = v1 - v2; + const int32_t x_size = x1 - x2; + int32_t y_size = y1 - y2; + + XBUF_XGUV *xguv_ptr = (XBUF_XGUV *)g_XBuffer + y2; + const int32_t x_add = PHD_ONE * x_size / y_size; + const int32_t g_add = PHD_HALF * g_size / y_size; + const int32_t u_add = PHD_HALF * u_size / y_size; + const int32_t v_add = PHD_HALF * v_size / y_size; + int32_t x = x2 * PHD_ONE + 1; + int32_t g = g2 * PHD_HALF; + int32_t u = u2 * PHD_HALF; + int32_t v = v2 * PHD_HALF; + + while (y_size--) { + x += x_add; + g += g_add; + u += u_add; + v += v_add; + xguv_ptr->x1 = x; + xguv_ptr->g1 = g; + xguv_ptr->u1 = u; + xguv_ptr->v1 = v; + xguv_ptr++; + } + } + } + + if (y_min == y_max) { + return false; + } + + g_XGenY1 = y_min; + g_XGenY2 = y_max; + return true; +} + +static bool M_XGenXGUVPerspFP(const int16_t *obj_ptr) +{ + const uint8_t *const old = g_TexturePageBuffer8[5]; + + int32_t pt_count = *obj_ptr++; + const XGEN_XGUVP *pt2 = (const XGEN_XGUVP *)obj_ptr; + const XGEN_XGUVP *pt1 = pt2 + (pt_count - 1); + + int32_t y_min = pt1->y; + int32_t y_max = pt1->y; + + while (pt_count--) { + const int32_t x1 = pt1->x; + const int32_t y1 = pt1->y; + const int32_t g1 = pt1->g; + const float u1 = pt1->u; + const float v1 = pt1->v; + const float rhw1 = pt1->rhw; + + const int32_t x2 = pt2->x; + const int32_t y2 = pt2->y; + const int32_t g2 = pt2->g; + const float u2 = pt2->u; + const float v2 = pt2->v; + const float rhw2 = pt2->rhw; + + pt1 = pt2++; + + if (y1 < y2) { + CLAMPG(y_min, y1); + const int32_t g_size = g2 - g1; + const float u_size = u2 - u1; + const float v_size = v2 - v1; + const float rhw_size = rhw2 - rhw1; + const int32_t x_size = x2 - x1; + int32_t y_size = y2 - y1; + + XBUF_XGUVP *xguv_ptr = (XBUF_XGUVP *)g_XBuffer + y1; + const int32_t x_add = PHD_ONE * x_size / y_size; + const int32_t g_add = PHD_HALF * g_size / y_size; + const float u_add = u_size / (float)y_size; + const float v_add = v_size / (float)y_size; + const float rhw_add = rhw_size / (float)y_size; + int32_t x = x1 * PHD_ONE + (PHD_ONE - 1); + int32_t g = g1 * PHD_HALF; + float u = u1; + float v = v1; + float rhw = rhw1; + + while (y_size--) { + x += x_add; + g += g_add; + u += u_add; + v += v_add; + rhw += rhw_add; + xguv_ptr->x2 = x; + xguv_ptr->g2 = g; + xguv_ptr->u2 = u; + xguv_ptr->v2 = v; + xguv_ptr->rhw2 = rhw; + xguv_ptr++; + } + } else if (y2 < y1) { + CLAMPL(y_max, y1); + const int32_t g_size = g1 - g2; + const float u_size = u1 - u2; + const float v_size = v1 - v2; + const float rhw_size = rhw1 - rhw2; + const int32_t x_size = x1 - x2; + int32_t y_size = y1 - y2; + + XBUF_XGUVP *xguv_ptr = (XBUF_XGUVP *)g_XBuffer + y2; + const int32_t x_add = PHD_ONE * x_size / y_size; + const int32_t g_add = PHD_HALF * g_size / y_size; + const float u_add = u_size / (float)y_size; + const float v_add = v_size / (float)y_size; + const float rhw_add = rhw_size / (float)y_size; + int32_t x = x2 * PHD_ONE + 1; + int32_t g = g2 * PHD_HALF; + float u = u2; + float v = v2; + float rhw = rhw2; + + while (y_size--) { + x += x_add; + g += g_add; + u += u_add; + v += v_add; + rhw += rhw_add; + xguv_ptr->x1 = x; + xguv_ptr->g1 = g; + xguv_ptr->u1 = u; + xguv_ptr->v1 = v; + xguv_ptr->rhw1 = rhw; + xguv_ptr++; + } + } + } + + if (y_min == y_max) { + return false; + } + + g_XGenY1 = y_min; + g_XGenY2 = y_max; + return true; +} + +static void M_DrawPolyFlat( + const int16_t *const obj_ptr, GFX_2D_SURFACE *const target_surface, + GFX_2D_SURFACE *const alpha_surface) +{ + if (M_XGenX(obj_ptr + 1)) { + M_OccludeX(alpha_surface, g_XGenY1, g_XGenY2); + M_FlatA(target_surface, g_XGenY1, g_XGenY2, *obj_ptr); + } +} + +static void M_DrawPolyTrans( + const int16_t *const obj_ptr, GFX_2D_SURFACE *const target_surface, + GFX_2D_SURFACE *const alpha_surface) +{ + if (M_XGenX(obj_ptr + 1)) { + M_OccludeX(alpha_surface, g_XGenY1, g_XGenY2); + M_TransA(target_surface, g_XGenY1, g_XGenY2, *obj_ptr); + } +} + +static void M_DrawPolyGouraud( + const int16_t *const obj_ptr, GFX_2D_SURFACE *const target_surface, + GFX_2D_SURFACE *const alpha_surface) +{ + if (M_XGenXG(obj_ptr + 1)) { + M_OccludeXG(alpha_surface, g_XGenY1, g_XGenY2); + M_GourA(target_surface, g_XGenY1, g_XGenY2, *obj_ptr); + } +} + +static void M_DrawPolyGTMap( + const int16_t *const obj_ptr, GFX_2D_SURFACE *const target_surface, + GFX_2D_SURFACE *const alpha_surface) +{ + if (M_XGenXGUV(obj_ptr + 1)) { + M_OccludeXGUV(alpha_surface, g_XGenY1, g_XGenY2); + M_GTMapA( + target_surface, g_XGenY1, g_XGenY2, g_TexturePageBuffer8[*obj_ptr]); + } +} + +static void M_DrawPolyWGTMap( + const int16_t *const obj_ptr, GFX_2D_SURFACE *const target_surface, + GFX_2D_SURFACE *const alpha_surface) +{ + if (M_XGenXGUV(obj_ptr + 1)) { + M_OccludeXGUV(alpha_surface, g_XGenY1, g_XGenY2); + M_WGTMapA( + target_surface, g_XGenY1, g_XGenY2, g_TexturePageBuffer8[*obj_ptr]); + } +} + +static void M_DrawPolyGTMapPersp( + const int16_t *const obj_ptr, GFX_2D_SURFACE *const target_surface, + GFX_2D_SURFACE *const alpha_surface) +{ + if (M_XGenXGUVPerspFP(obj_ptr + 1)) { + M_OccludeXGUVP(alpha_surface, g_XGenY1, g_XGenY2); + M_GTMapPersp32FP( + target_surface, g_XGenY1, g_XGenY2, g_TexturePageBuffer8[*obj_ptr]); + } +} + +static void M_DrawPolyWGTMapPersp( + const int16_t *const obj_ptr, GFX_2D_SURFACE *const target_surface, + GFX_2D_SURFACE *const alpha_surface) +{ + if (M_XGenXGUVPerspFP(obj_ptr + 1)) { + M_OccludeXGUVP(alpha_surface, g_XGenY1, g_XGenY2); + M_WGTMapPersp32FP( + target_surface, g_XGenY1, g_XGenY2, g_TexturePageBuffer8[*obj_ptr]); + } +} + +static void M_DrawPolyLine( + const int16_t *obj_ptr, GFX_2D_SURFACE *const target_surface, + GFX_2D_SURFACE *const alpha_surface) +{ + int32_t x1 = *obj_ptr++; + int32_t y1 = *obj_ptr++; + int32_t x2 = *obj_ptr++; + int32_t y2 = *obj_ptr++; + uint8_t lcolor = (uint8_t)*obj_ptr; + const int32_t stride = target_surface->desc.pitch; + + if (x2 < x1) { + int32_t tmp; + SWAP(x1, x2, tmp); + SWAP(y1, y2, tmp); + } + + if (x2 < 0 || x1 > g_PhdWinMaxX) { + return; + } + + if (x1 < 0) { + y1 -= x1 * (y2 - y1) / (x2 - x1); + x1 = 0; + } + + if (x2 > g_PhdWinMaxX) { + y2 = y1 + (y2 - y1) * (g_PhdWinMaxX - x1) / (x2 - x1); + x2 = g_PhdWinMaxX; + } + + if (y2 < y1) { + int32_t tmp; + SWAP(x1, x2, tmp); + SWAP(y1, y2, tmp); + } + + if (y2 < 0 || y1 > g_PhdWinMaxY) { + return; + } + + if (y1 < 0) { + x1 -= y1 * (x2 - x1) / (y2 - y1); + y1 = 0; + } + + if (y2 > g_PhdWinMaxY) { + x2 = x1 + (x2 - x1) * (g_PhdWinMaxY - y1) / (y2 - y1); + y2 = g_PhdWinMaxY; + } + + int32_t x_size = x2 - x1; + int32_t y_size = y2 - y1; + PIX_FMT *draw_ptr = &target_surface->buffer[x1 + stride * y1]; + ALPHA_FMT *alpha_ptr = &alpha_surface->buffer[x1 + stride * y1]; + + if (!x_size && !y_size) { + *draw_ptr = lcolor; + //*alpha_ptr = 255; + return; + } + + int32_t x_add = 0; + if (x_size < 0) { + x_add = -1; + x_size = -x_size; + } else { + x_add = 1; + } + + int32_t y_add; + if (y_size < 0) { + y_add = -stride; + y_size = -y_size; + } else { + y_add = stride; + } + + int32_t col_add; + int32_t row_add; + int32_t cols; + int32_t rows; + if (x_size >= y_size) { + col_add = x_add; + row_add = y_add; + cols = x_size + 1; + rows = y_size + 1; + } else { + col_add = y_add; + row_add = x_add; + cols = y_size + 1; + rows = x_size + 1; + } + + int32_t part_sum = 0; + int32_t part = PHD_ONE * rows / cols; + for (int32_t i = 0; i < cols; i++) { + part_sum += part; + *draw_ptr = lcolor; + draw_ptr += col_add; + //*alpha_ptr = 255; + // alpha_ptr += col_add; + if (part_sum >= PHD_ONE) { + draw_ptr += row_add; + // alpha_ptr += row_add; + part_sum -= PHD_ONE; + } + } +} + +static void M_DrawScaledSpriteC( + const int16_t *const obj_ptr, GFX_2D_SURFACE *const target_surface, + GFX_2D_SURFACE *const alpha_surface) +{ + int32_t x0 = obj_ptr[0]; + int32_t y0 = obj_ptr[1]; + int32_t x1 = obj_ptr[2]; + int32_t y1 = obj_ptr[3]; + const int16_t sprite_idx = obj_ptr[4]; + const int16_t shade = obj_ptr[5]; + + if (x0 >= x1 || y0 >= y1 || x1 <= 0 || y1 <= 0 || x0 >= g_PhdWinMaxX + || y0 >= g_PhdWinMaxY) { + return; + } + + const DEPTHQ_ENTRY *const depth_q = &g_DepthQTable[shade >> 8]; + const PHD_SPRITE *const sprite = &g_PhdSprites[sprite_idx]; + + int32_t u_base = 0x4000; + int32_t v_base = 0x4000; + const int32_t u_add = ((sprite->width - 64) << 8) / (x1 - x0); + const int32_t v_add = ((sprite->height - 64) << 8) / (y1 - y0); + + if (x0 < 0) { + u_base -= x0 * u_add; + x0 = 0; + } + if (y0 < 0) { + v_base -= y0 * v_add; + y0 = 0; + } + CLAMPG(x1, g_PhdWinMaxX + 1); + CLAMPG(y1, g_PhdWinMaxY + 1); + + const int32_t stride = target_surface->desc.pitch; + const int32_t width = x1 - x0; + const int32_t height = y1 - y0; + + const uint8_t *const src_base = + &g_TexturePageBuffer8[sprite->tex_page][sprite->offset]; + PIX_FMT *draw_ptr = &target_surface->buffer[y0 * stride + x0]; + ALPHA_FMT *alpha_ptr = &alpha_surface->buffer[y0 * stride + x0]; + const int32_t dst_add = stride - width; + + const bool is_depth_q = depth_q != &g_DepthQTable[16]; + + for (int32_t i = 0; i < height; i++) { + int32_t u = u_base; + const uint8_t *const src = &src_base[(v_base >> 16) << 8]; + for (int32_t j = 0; j < width; j++) { + const uint8_t pix = src[u >> 16]; + if (pix != 0) { + *draw_ptr = is_depth_q ? depth_q->index[pix] : pix; + *alpha_ptr = 255; + } + u += u_add; + draw_ptr++; + alpha_ptr++; + } + draw_ptr += dst_add; + alpha_ptr += dst_add; + v_base += v_add; + } +} + +static void M_Init(RENDERER *const renderer) +{ + M_PRIV *const priv = Memory_Alloc(sizeof(M_PRIV)); + priv->renderer_2d = GFX_2D_Renderer_Create(); + renderer->priv = priv; + renderer->initialized = true; +} + +static void M_Open(RENDERER *const renderer) +{ + M_PRIV *const priv = renderer->priv; + ASSERT(renderer->initialized); + if (renderer->open) { + return; + } + + g_XBuffer = Memory_Realloc(g_XBuffer, sizeof(XBUF_XGUVP) * g_PhdWinHeight); + + { + GFX_2D_Surface_Free(priv->surface); + GFX_2D_SURFACE_DESC surface_desc = { + .width = g_PhdWinWidth, + .height = g_PhdWinHeight, + .pitch = g_PhdWinWidth * sizeof(PIX_FMT), + .bit_count = sizeof(PIX_FMT) * 8, + .tex_format = GL_RED, + .tex_type = PIX_FMT_GL, + }; + priv->surface = GFX_2D_Surface_Create(&surface_desc); + ASSERT(priv->surface != NULL); + } + + { + GFX_2D_SURFACE_DESC surface_desc = { + .width = g_PhdWinWidth, + .height = g_PhdWinHeight, + .pitch = g_PhdWinWidth, + .bit_count = 8, + .tex_format = GL_RED, + .tex_type = GL_UNSIGNED_BYTE, + }; + priv->surface_alpha = GFX_2D_Surface_Create(&surface_desc); + ASSERT(priv->surface_alpha != NULL); + } + + renderer->open = true; +} + +static void M_Close(RENDERER *const renderer) +{ + M_PRIV *const priv = renderer->priv; + if (!renderer->initialized || !renderer->open) { + return; + } + + Memory_FreePointer(&g_XBuffer); + + if (priv->surface != NULL) { + GFX_2D_Surface_Free(priv->surface); + priv->surface = NULL; + } + + if (priv->surface_alpha != NULL) { + GFX_2D_Surface_Free(priv->surface_alpha); + priv->surface_alpha = NULL; + } + + renderer->open = false; +} + +static void M_Shutdown(RENDERER *const renderer) +{ + M_PRIV *const priv = renderer->priv; + if (!renderer->initialized) { + return; + } + if (priv->renderer_2d != NULL) { + GFX_2D_Renderer_Destroy(priv->renderer_2d); + priv->renderer_2d = NULL; + } + renderer->initialized = false; +} + +static void M_Reset(RENDERER *const renderer, const RENDER_RESET_FLAGS flags) +{ + M_PRIV *const priv = renderer->priv; + if (!renderer->initialized) { + return; + } + + if (flags & RENDER_RESET_PALETTE) { + for (int32_t i = 0; i < 256; i++) { + priv->palette[i].r = g_GamePalette8[i].r; + priv->palette[i].g = g_GamePalette8[i].g; + priv->palette[i].b = g_GamePalette8[i].b; + } + GFX_2D_Renderer_SetPalette(priv->renderer_2d, priv->palette); + } +} + +static void M_BeginScene(RENDERER *const renderer) +{ + M_PRIV *const priv = renderer->priv; + ASSERT(renderer->initialized); + ASSERT(renderer->open); + + memset( + priv->surface_alpha->buffer, 0, + priv->surface_alpha->desc.width * priv->surface_alpha->desc.height); +} + +static void M_EndScene(RENDERER *const renderer) +{ +} + +static void M_ResetPolyList(RENDERER *const renderer) +{ +} + +static void M_DrawPolyList(RENDERER *const renderer) +{ + M_PRIV *const priv = renderer->priv; + ASSERT(renderer->initialized); + ASSERT(renderer->open); + ASSERT(priv->surface != NULL); + + Render_SortPolyList(); + + for (int32_t i = 0; i < g_SurfaceCount; i++) { + const int16_t *obj_ptr = (const int16_t *)g_SortBuffer[i]._0; + const int16_t poly_type = *obj_ptr++; + m_PolyDrawRoutines[poly_type]( + obj_ptr, priv->surface, priv->surface_alpha); + } + + GFX_2D_Renderer_UploadSurface(priv->renderer_2d, priv->surface); + GFX_2D_Renderer_UploadAlphaSurface(priv->renderer_2d, priv->surface_alpha); + GFX_2D_Renderer_Render(priv->renderer_2d); +} + +static const int16_t *M_InsertObjectG3( + RENDERER *const renderer, const int16_t *obj_ptr, const int32_t num, + const SORT_TYPE sort_type) +{ + for (int32_t i = 0; i < num; i++) { + const PHD_VBUF *const vtx[3] = { + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + }; + const uint8_t color_idx = *obj_ptr++; + int32_t num_points = 3; + + int8_t clip_or = vtx[0]->clip | vtx[1]->clip | vtx[2]->clip; + int8_t clip_and = vtx[0]->clip & vtx[1]->clip & vtx[2]->clip; + + if (clip_and != 0) { + continue; + } + + if (clip_or >= 0) { + if (!VBUF_VISIBLE(*vtx[0], *vtx[1], *vtx[2])) { + continue; + } + + m_VBuffer[0].x = vtx[0]->xs; + m_VBuffer[0].y = vtx[0]->ys; + m_VBuffer[0].rhw = vtx[0]->rhw; + m_VBuffer[0].g = vtx[0]->g; + + m_VBuffer[1].x = vtx[1]->xs; + m_VBuffer[1].y = vtx[1]->ys; + m_VBuffer[1].rhw = vtx[1]->rhw; + m_VBuffer[1].g = vtx[1]->g; + + m_VBuffer[2].x = vtx[2]->xs; + m_VBuffer[2].y = vtx[2]->ys; + m_VBuffer[2].rhw = vtx[2]->rhw; + m_VBuffer[2].g = vtx[2]->g; + } else { + if (!Render_VisibleZClip(vtx[0], vtx[1], vtx[2])) { + continue; + } + + POINT_INFO points[3] = { + { + .xv = vtx[0]->xv, + .yv = vtx[0]->yv, + .zv = vtx[0]->zv, + .rhw = vtx[0]->rhw, + .xs = vtx[0]->xs, + .ys = vtx[0]->ys, + .g = vtx[0]->g, + }, + { + .xv = vtx[1]->xv, + .yv = vtx[1]->yv, + .zv = vtx[1]->zv, + .rhw = vtx[1]->rhw, + .xs = vtx[1]->xs, + .ys = vtx[1]->ys, + .g = vtx[1]->g, + }, + { + .xv = vtx[2]->xv, + .yv = vtx[2]->yv, + .zv = vtx[2]->zv, + .rhw = vtx[2]->rhw, + .xs = vtx[2]->xs, + .ys = vtx[2]->ys, + .g = vtx[2]->g, + }, + }; + + num_points = Render_ZedClipper(num_points, points, m_VBuffer); + if (num_points == 0) { + continue; + } + } + + num_points = Render_XYGClipper(num_points, m_VBuffer); + if (num_points == 0) { + continue; + } + + const float zv = Render_CalculatePolyZ( + sort_type, vtx[0]->zv, vtx[1]->zv, vtx[2]->zv, -1.0); + g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; + g_Sort3DPtr->_1 = MAKE_ZSORT(zv); + g_Sort3DPtr++; + + *g_Info3DPtr++ = POLY_GOURAUD; + *g_Info3DPtr++ = color_idx; + *g_Info3DPtr++ = num_points; + + for (int32_t j = 0; j < num_points; j++) { + *g_Info3DPtr++ = (int32_t)m_VBuffer[j].x; + *g_Info3DPtr++ = (int32_t)m_VBuffer[j].y; + *g_Info3DPtr++ = (int32_t)m_VBuffer[j].g; + } + g_SurfaceCount++; + } + + return obj_ptr; +} + +static const int16_t *M_InsertObjectG4( + RENDERER *const renderer, const int16_t *obj_ptr, const int32_t num, + const SORT_TYPE sort_type) +{ + for (int32_t i = 0; i < num; i++) { + const PHD_VBUF *const vtx[4] = { + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + }; + const uint8_t color_idx = *obj_ptr++; + int32_t num_points = 4; + + const int8_t clip_or = + vtx[0]->clip | vtx[1]->clip | vtx[2]->clip | vtx[3]->clip; + const int8_t clip_and = + vtx[0]->clip & vtx[1]->clip & vtx[2]->clip & vtx[3]->clip; + + if (clip_and != 0) { + continue; + } + + if (clip_or >= 0) { + if (!VBUF_VISIBLE(*vtx[0], *vtx[1], *vtx[2])) { + continue; + } + + m_VBuffer[0].x = vtx[0]->xs; + m_VBuffer[0].y = vtx[0]->ys; + m_VBuffer[0].rhw = vtx[0]->rhw; + m_VBuffer[0].g = vtx[0]->g; + + m_VBuffer[1].x = vtx[1]->xs; + m_VBuffer[1].y = vtx[1]->ys; + m_VBuffer[1].rhw = vtx[1]->rhw; + m_VBuffer[1].g = vtx[1]->g; + + m_VBuffer[2].x = vtx[2]->xs; + m_VBuffer[2].y = vtx[2]->ys; + m_VBuffer[2].rhw = vtx[2]->rhw; + m_VBuffer[2].g = vtx[2]->g; + + m_VBuffer[3].x = vtx[3]->xs; + m_VBuffer[3].y = vtx[3]->ys; + m_VBuffer[3].rhw = vtx[3]->rhw; + m_VBuffer[3].g = vtx[3]->g; + } else { + if (!Render_VisibleZClip(vtx[0], vtx[1], vtx[2])) { + continue; + } + + const POINT_INFO points[4] = { + { + .xv = vtx[0]->xv, + .yv = vtx[0]->yv, + .zv = vtx[0]->zv, + .rhw = vtx[0]->rhw, + .xs = vtx[0]->xs, + .ys = vtx[0]->ys, + .g = vtx[0]->g, + }, + { + .xv = vtx[1]->xv, + .yv = vtx[1]->yv, + .zv = vtx[1]->zv, + .rhw = vtx[1]->rhw, + .xs = vtx[1]->xs, + .ys = vtx[1]->ys, + .g = vtx[1]->g, + }, + { + .xv = vtx[2]->xv, + .yv = vtx[2]->yv, + .zv = vtx[2]->zv, + .rhw = vtx[2]->rhw, + .xs = vtx[2]->xs, + .ys = vtx[2]->ys, + .g = vtx[2]->g, + }, + { + .xv = vtx[3]->xv, + .yv = vtx[3]->yv, + .zv = vtx[3]->zv, + .rhw = vtx[3]->rhw, + .xs = vtx[3]->xs, + .ys = vtx[3]->ys, + .g = vtx[3]->g, + }, + }; + + num_points = Render_ZedClipper(num_points, points, m_VBuffer); + if (num_points == 0) { + continue; + } + } + + num_points = Render_XYGClipper(num_points, m_VBuffer); + if (num_points == 0) { + continue; + } + + const float zv = Render_CalculatePolyZ( + sort_type, vtx[0]->zv, vtx[1]->zv, vtx[2]->zv, vtx[3]->zv); + g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; + g_Sort3DPtr->_1 = MAKE_ZSORT(zv); + g_Sort3DPtr++; + + *g_Info3DPtr++ = POLY_GOURAUD; + *g_Info3DPtr++ = color_idx; + *g_Info3DPtr++ = num_points; + + for (int32_t j = 0; j < num_points; j++) { + *g_Info3DPtr++ = m_VBuffer[j].x; + *g_Info3DPtr++ = m_VBuffer[j].y; + *g_Info3DPtr++ = m_VBuffer[j].g; + } + g_SurfaceCount++; + } + + return obj_ptr; +} + +static const int16_t *M_InsertObjectGT3( + RENDERER *const renderer, const int16_t *obj_ptr, const int32_t num, + const SORT_TYPE sort_type) +{ + for (int32_t i = 0; i < num; i++) { + const PHD_VBUF *const vtx[3] = { + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + }; + const int16_t texture_idx = *obj_ptr++; + const PHD_TEXTURE *const texture = &g_TextureInfo[texture_idx]; + const PHD_UV *const uv = texture->uv; + int32_t num_points = 3; + + if (texture->draw_type != DRAW_OPAQUE && g_DiscardTransparent) { + continue; + } + + const int8_t clip_or = vtx[0]->clip | vtx[1]->clip | vtx[2]->clip; + const int8_t clip_and = vtx[0]->clip & vtx[1]->clip & vtx[2]->clip; + + if (clip_and != 0) { + continue; + } + + if (clip_or >= 0) { + if (!VBUF_VISIBLE(*vtx[0], *vtx[1], *vtx[2])) { + continue; + } + + if (clip_or == 0) { + const float zv = Render_CalculatePolyZ( + sort_type, vtx[0]->zv, vtx[1]->zv, vtx[2]->zv, -1.0); + g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; + g_Sort3DPtr->_1 = MAKE_ZSORT(zv); + g_Sort3DPtr++; + + if (zv >= (double)g_PerspectiveDistance) { + *g_Info3DPtr++ = (texture->draw_type == DRAW_OPAQUE) + ? POLY_GTMAP + : POLY_WGTMAP; + *g_Info3DPtr++ = texture->tex_page; + *g_Info3DPtr++ = 3; + + *g_Info3DPtr++ = (int32_t)vtx[0]->xs; + *g_Info3DPtr++ = (int32_t)vtx[0]->ys; + *g_Info3DPtr++ = (int32_t)vtx[0]->g; + *g_Info3DPtr++ = uv[0].u; + *g_Info3DPtr++ = uv[0].v; + + *g_Info3DPtr++ = (int32_t)vtx[1]->xs; + *g_Info3DPtr++ = (int32_t)vtx[1]->ys; + *g_Info3DPtr++ = (int32_t)vtx[1]->g; + *g_Info3DPtr++ = uv[1].u; + *g_Info3DPtr++ = uv[1].v; + + *g_Info3DPtr++ = (int32_t)vtx[2]->xs; + *g_Info3DPtr++ = (int32_t)vtx[2]->ys; + *g_Info3DPtr++ = (int32_t)vtx[2]->g; + *g_Info3DPtr++ = uv[2].u; + *g_Info3DPtr++ = uv[2].v; + } else { + *g_Info3DPtr++ = (texture->draw_type == DRAW_OPAQUE) + ? POLY_GTMAP_PERSP + : POLY_WGTMAP_PERSP; + *g_Info3DPtr++ = texture->tex_page; + *g_Info3DPtr++ = 3; + + *g_Info3DPtr++ = (int32_t)vtx[0]->xs; + *g_Info3DPtr++ = (int32_t)vtx[0]->ys; + *g_Info3DPtr++ = (int32_t)vtx[0]->g; + *(float *)g_Info3DPtr = vtx[0]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + *(float *)g_Info3DPtr = (double)uv[0].u * vtx[0]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + *(float *)g_Info3DPtr = (double)uv[0].v * vtx[0]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + + *g_Info3DPtr++ = (int32_t)vtx[1]->xs; + *g_Info3DPtr++ = (int32_t)vtx[1]->ys; + *g_Info3DPtr++ = (int32_t)vtx[1]->g; + *(float *)g_Info3DPtr = vtx[1]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + *(float *)g_Info3DPtr = (double)uv[1].u * vtx[1]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + *(float *)g_Info3DPtr = (double)uv[1].v * vtx[1]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + + *g_Info3DPtr++ = (int32_t)vtx[2]->xs; + *g_Info3DPtr++ = (int32_t)vtx[2]->ys; + *g_Info3DPtr++ = (int32_t)vtx[2]->g; + *(float *)g_Info3DPtr = vtx[2]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + *(float *)g_Info3DPtr = (double)uv[2].u * vtx[2]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + *(float *)g_Info3DPtr = (double)uv[2].v * vtx[2]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + } + g_SurfaceCount++; + continue; + } + + m_VBuffer[0].x = vtx[0]->xs; + m_VBuffer[0].y = vtx[0]->ys; + m_VBuffer[0].rhw = vtx[0]->rhw; + m_VBuffer[0].g = vtx[0]->g; + m_VBuffer[0].u = (double)uv[0].u * vtx[0]->rhw; + m_VBuffer[0].v = (double)uv[0].v * vtx[0]->rhw; + + m_VBuffer[1].x = vtx[1]->xs; + m_VBuffer[1].y = vtx[1]->ys; + m_VBuffer[1].rhw = vtx[1]->rhw; + m_VBuffer[1].g = vtx[1]->g; + m_VBuffer[1].u = (double)uv[1].u * vtx[1]->rhw; + m_VBuffer[1].v = (double)uv[1].v * vtx[1]->rhw; + + m_VBuffer[2].x = vtx[2]->xs; + m_VBuffer[2].y = vtx[2]->ys; + m_VBuffer[2].rhw = vtx[2]->rhw; + m_VBuffer[2].g = vtx[2]->g; + m_VBuffer[2].u = (double)uv[2].u * vtx[2]->rhw; + m_VBuffer[2].v = (double)uv[2].v * vtx[2]->rhw; + } else { + if (!Render_VisibleZClip(vtx[0], vtx[1], vtx[2])) { + continue; + } + + const POINT_INFO points[3] = { + { + .xv = vtx[0]->xv, + .yv = vtx[0]->yv, + .zv = vtx[0]->zv, + .rhw = vtx[0]->rhw, + .xs = vtx[0]->xs, + .ys = vtx[0]->ys, + .g = vtx[0]->g, + .u = uv[0].u, + .v = uv[0].v, + }, + { + .yv = vtx[1]->yv, + .xv = vtx[1]->xv, + .zv = vtx[1]->zv, + .rhw = vtx[1]->rhw, + .xs = vtx[1]->xs, + .ys = vtx[1]->ys, + .g = vtx[1]->g, + .u = uv[1].u, + .v = uv[1].v, + }, + { + .xv = vtx[2]->xv, + .yv = vtx[2]->yv, + .zv = vtx[2]->zv, + .rhw = vtx[2]->rhw, + .xs = vtx[2]->xs, + .ys = vtx[2]->ys, + .g = vtx[2]->g, + .u = uv[2].u, + .v = uv[2].v, + }, + }; + + num_points = Render_ZedClipper(num_points, points, m_VBuffer); + if (num_points == 0) { + continue; + } + } + + num_points = Render_XYGUVClipper(num_points, m_VBuffer); + if (num_points == 0) { + continue; + } + + const float zv = Render_CalculatePolyZ( + sort_type, vtx[0]->zv, vtx[1]->zv, vtx[2]->zv, -1.0); + g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; + g_Sort3DPtr->_1 = MAKE_ZSORT(zv); + g_Sort3DPtr++; + + if (zv >= (double)g_PerspectiveDistance) { + *g_Info3DPtr++ = + (texture->draw_type == DRAW_OPAQUE) ? POLY_GTMAP : POLY_WGTMAP; + *g_Info3DPtr++ = texture->tex_page; + *g_Info3DPtr++ = num_points; + + for (int32_t j = 0; j < num_points; j++) { + *g_Info3DPtr++ = (int32_t)m_VBuffer[j].x; + *g_Info3DPtr++ = (int32_t)m_VBuffer[j].y; + *g_Info3DPtr++ = (int32_t)m_VBuffer[j].g; + *g_Info3DPtr++ = (int32_t)(m_VBuffer[j].u / m_VBuffer[j].rhw); + *g_Info3DPtr++ = (int32_t)(m_VBuffer[j].v / m_VBuffer[j].rhw); + } + } else { + *g_Info3DPtr++ = (texture->draw_type == DRAW_OPAQUE) + ? POLY_GTMAP_PERSP + : POLY_WGTMAP_PERSP; + *g_Info3DPtr++ = texture->tex_page; + *g_Info3DPtr++ = num_points; + + for (int32_t j = 0; j < num_points; j++) { + *g_Info3DPtr++ = (int32_t)m_VBuffer[j].x; + *g_Info3DPtr++ = (int32_t)m_VBuffer[j].y; + *g_Info3DPtr++ = (int32_t)m_VBuffer[j].g; + *(float *)g_Info3DPtr = m_VBuffer[j].rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + *(float *)g_Info3DPtr = m_VBuffer[j].u; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + *(float *)g_Info3DPtr = m_VBuffer[j].v; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + } + } + g_SurfaceCount++; + } + + return obj_ptr; +} + +static const int16_t *M_InsertObjectGT4( + RENDERER *const renderer, const int16_t *obj_ptr, const int32_t num, + const SORT_TYPE sort_type) +{ + for (int32_t i = 0; i < num; i++) { + const PHD_VBUF *const vtx[4] = { + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + &g_PhdVBuf[*obj_ptr++], + }; + const int16_t texture_idx = *obj_ptr++; + const PHD_TEXTURE *const texture = &g_TextureInfo[texture_idx]; + const PHD_UV *const uv = texture->uv; + int32_t num_points = 4; + + if (texture->draw_type != DRAW_OPAQUE && g_DiscardTransparent) { + continue; + } + + const int8_t clip_or = + vtx[0]->clip | vtx[1]->clip | vtx[2]->clip | vtx[3]->clip; + const int8_t clip_and = + vtx[0]->clip & vtx[1]->clip & vtx[2]->clip & vtx[3]->clip; + + if (clip_and != 0) { + continue; + } + + if (clip_or >= 0) { + if (!VBUF_VISIBLE(*vtx[0], *vtx[1], *vtx[2])) { + continue; + } + + if (clip_or == 0) { + const float zv = Render_CalculatePolyZ( + sort_type, vtx[0]->zv, vtx[1]->zv, vtx[2]->zv, vtx[3]->zv); + g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; + g_Sort3DPtr->_1 = MAKE_ZSORT(zv); + g_Sort3DPtr++; + + if (zv >= (double)g_PerspectiveDistance) { + *g_Info3DPtr++ = (texture->draw_type == DRAW_OPAQUE) + ? POLY_GTMAP + : POLY_WGTMAP; + *g_Info3DPtr++ = texture->tex_page; + *g_Info3DPtr++ = 4; + + *g_Info3DPtr++ = (int32_t)vtx[0]->xs; + *g_Info3DPtr++ = (int32_t)vtx[0]->ys; + *g_Info3DPtr++ = (int32_t)vtx[0]->g; + *g_Info3DPtr++ = uv[0].u; + *g_Info3DPtr++ = uv[0].v; + + *g_Info3DPtr++ = (int32_t)vtx[1]->xs; + *g_Info3DPtr++ = (int32_t)vtx[1]->ys; + *g_Info3DPtr++ = (int32_t)vtx[1]->g; + *g_Info3DPtr++ = uv[1].u; + *g_Info3DPtr++ = uv[1].v; + + *g_Info3DPtr++ = (int32_t)vtx[2]->xs; + *g_Info3DPtr++ = (int32_t)vtx[2]->ys; + *g_Info3DPtr++ = (int32_t)vtx[2]->g; + *g_Info3DPtr++ = uv[2].u; + *g_Info3DPtr++ = uv[2].v; + + *g_Info3DPtr++ = (int32_t)vtx[3]->xs; + *g_Info3DPtr++ = (int32_t)vtx[3]->ys; + *g_Info3DPtr++ = (int32_t)vtx[3]->g; + *g_Info3DPtr++ = uv[3].u; + *g_Info3DPtr++ = uv[3].v; + } else { + *g_Info3DPtr++ = (texture->draw_type == DRAW_OPAQUE) + ? POLY_GTMAP_PERSP + : POLY_WGTMAP_PERSP; + *g_Info3DPtr++ = texture->tex_page; + *g_Info3DPtr++ = 4; + + *g_Info3DPtr++ = (int32_t)vtx[0]->xs; + *g_Info3DPtr++ = (int32_t)vtx[0]->ys; + *g_Info3DPtr++ = (int32_t)vtx[0]->g; + *(float *)g_Info3DPtr = vtx[0]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + *(float *)g_Info3DPtr = (double)uv[0].u * vtx[0]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + *(float *)g_Info3DPtr = (double)uv[0].v * vtx[0]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + + *g_Info3DPtr++ = (int32_t)vtx[1]->xs; + *g_Info3DPtr++ = (int32_t)vtx[1]->ys; + *g_Info3DPtr++ = (int32_t)vtx[1]->g; + *(float *)g_Info3DPtr = vtx[1]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + *(float *)g_Info3DPtr = (double)uv[1].u * vtx[1]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + *(float *)g_Info3DPtr = (double)uv[1].v * vtx[1]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + + *g_Info3DPtr++ = (int32_t)vtx[2]->xs; + *g_Info3DPtr++ = (int32_t)vtx[2]->ys; + *g_Info3DPtr++ = (int32_t)vtx[2]->g; + *(float *)g_Info3DPtr = vtx[2]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + *(float *)g_Info3DPtr = (double)uv[2].u * vtx[2]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + *(float *)g_Info3DPtr = (double)uv[2].v * vtx[2]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + + *g_Info3DPtr++ = (int32_t)vtx[3]->xs; + *g_Info3DPtr++ = (int32_t)vtx[3]->ys; + *g_Info3DPtr++ = (int32_t)vtx[3]->g; + *(float *)g_Info3DPtr = vtx[3]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + *(float *)g_Info3DPtr = (double)uv[3].u * vtx[3]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + *(float *)g_Info3DPtr = (double)uv[3].v * vtx[3]->rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + } + g_SurfaceCount++; + continue; + } + + m_VBuffer[0].x = vtx[0]->xs; + m_VBuffer[0].y = vtx[0]->ys; + m_VBuffer[0].rhw = vtx[0]->rhw; + m_VBuffer[0].g = vtx[0]->g; + m_VBuffer[0].u = (double)uv[0].u * vtx[0]->rhw; + m_VBuffer[0].v = (double)uv[0].v * vtx[0]->rhw; + + m_VBuffer[1].x = vtx[1]->xs; + m_VBuffer[1].y = vtx[1]->ys; + m_VBuffer[1].rhw = vtx[1]->rhw; + m_VBuffer[1].g = vtx[1]->g; + m_VBuffer[1].u = (double)uv[1].u * vtx[1]->rhw; + m_VBuffer[1].v = (double)uv[1].v * vtx[1]->rhw; + + m_VBuffer[2].x = vtx[2]->xs; + m_VBuffer[2].y = vtx[2]->ys; + m_VBuffer[2].rhw = vtx[2]->rhw; + m_VBuffer[2].g = vtx[2]->g; + m_VBuffer[2].u = (double)uv[2].u * vtx[2]->rhw; + m_VBuffer[2].v = (double)uv[2].v * vtx[2]->rhw; + + m_VBuffer[3].x = vtx[3]->xs; + m_VBuffer[3].y = vtx[3]->ys; + m_VBuffer[3].rhw = vtx[3]->rhw; + m_VBuffer[3].g = vtx[3]->g; + m_VBuffer[3].u = (double)uv[3].u * vtx[3]->rhw; + m_VBuffer[3].v = (double)uv[3].v * vtx[3]->rhw; + } else { + if (!Render_VisibleZClip(vtx[0], vtx[1], vtx[2])) { + continue; + } + + const POINT_INFO points[4] = { + { + .xv = vtx[0]->xv, + .yv = vtx[0]->yv, + .zv = vtx[0]->zv, + .rhw = vtx[0]->rhw, + .xs = vtx[0]->xs, + .ys = vtx[0]->ys, + .g = vtx[0]->g, + .u = uv[0].u, + .v = uv[0].v, + }, + { + .yv = vtx[1]->yv, + .xv = vtx[1]->xv, + .zv = vtx[1]->zv, + .rhw = vtx[1]->rhw, + .xs = vtx[1]->xs, + .ys = vtx[1]->ys, + .g = vtx[1]->g, + .u = uv[1].u, + .v = uv[1].v, + }, + { + .xv = vtx[2]->xv, + .yv = vtx[2]->yv, + .zv = vtx[2]->zv, + .rhw = vtx[2]->rhw, + .xs = vtx[2]->xs, + .ys = vtx[2]->ys, + .g = vtx[2]->g, + .u = uv[2].u, + .v = uv[2].v, + }, + { + .xv = vtx[3]->xv, + .yv = vtx[3]->yv, + .zv = vtx[3]->zv, + .rhw = vtx[3]->rhw, + .xs = vtx[3]->xs, + .ys = vtx[3]->ys, + .g = vtx[3]->g, + .u = uv[3].u, + .v = uv[3].v, + }, + }; + + num_points = Render_ZedClipper(num_points, points, m_VBuffer); + if (num_points == 0) { + continue; + } + } + + num_points = Render_XYGUVClipper(num_points, m_VBuffer); + if (num_points == 0) { + continue; + } + + const float zv = Render_CalculatePolyZ( + sort_type, vtx[0]->zv, vtx[1]->zv, vtx[2]->zv, vtx[3]->zv); + g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; + g_Sort3DPtr->_1 = MAKE_ZSORT(zv); + g_Sort3DPtr++; + + if (zv >= (double)g_PerspectiveDistance) { + *g_Info3DPtr++ = + (texture->draw_type == DRAW_OPAQUE) ? POLY_GTMAP : POLY_WGTMAP; + *g_Info3DPtr++ = texture->tex_page; + *g_Info3DPtr++ = num_points; + + for (int32_t j = 0; j < num_points; j++) { + *g_Info3DPtr++ = (int32_t)m_VBuffer[j].x; + *g_Info3DPtr++ = (int32_t)m_VBuffer[j].y; + *g_Info3DPtr++ = (int32_t)m_VBuffer[j].g; + *g_Info3DPtr++ = (int32_t)(m_VBuffer[j].u / m_VBuffer[j].rhw); + *g_Info3DPtr++ = (int32_t)(m_VBuffer[j].v / m_VBuffer[j].rhw); + } + } else { + *g_Info3DPtr++ = (texture->draw_type == DRAW_OPAQUE) + ? POLY_GTMAP_PERSP + : POLY_WGTMAP_PERSP; + *g_Info3DPtr++ = texture->tex_page; + *g_Info3DPtr++ = num_points; + + for (int32_t j = 0; j < num_points; j++) { + *g_Info3DPtr++ = (int32_t)m_VBuffer[j].x; + *g_Info3DPtr++ = (int32_t)m_VBuffer[j].y; + *g_Info3DPtr++ = (int32_t)m_VBuffer[j].g; + *(float *)g_Info3DPtr = m_VBuffer[j].rhw; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + *(float *)g_Info3DPtr = m_VBuffer[j].u; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + *(float *)g_Info3DPtr = m_VBuffer[j].v; + g_Info3DPtr += sizeof(float) / sizeof(int16_t); + } + } + g_SurfaceCount++; + } + + return obj_ptr; +} + +static void M_InsertLine( + RENDERER *const renderer, const int32_t x1, const int32_t y1, + const int32_t x2, const int32_t y2, const int32_t z, + const uint8_t color_idx) +{ + g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; + g_Sort3DPtr->_1 = MAKE_ZSORT(z); + g_Sort3DPtr++; + + *g_Info3DPtr++ = POLY_LINE; + *g_Info3DPtr++ = x1; + *g_Info3DPtr++ = y1; + *g_Info3DPtr++ = x2; + *g_Info3DPtr++ = y2; + *g_Info3DPtr++ = color_idx; + + g_SurfaceCount++; +} + +static void M_InsertFlatRect( + RENDERER *const renderer, const int32_t x1, const int32_t y1, + const int32_t x2, const int32_t y2, int32_t z, uint8_t color_idx) +{ + g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; + g_Sort3DPtr->_1 = MAKE_ZSORT(z); + g_Sort3DPtr++; + + *g_Info3DPtr++ = POLY_FLAT; + *g_Info3DPtr++ = color_idx; + *g_Info3DPtr++ = 4; + *g_Info3DPtr++ = x1; + *g_Info3DPtr++ = y1; + *g_Info3DPtr++ = x2; + *g_Info3DPtr++ = y1; + *g_Info3DPtr++ = x2; + *g_Info3DPtr++ = y2; + *g_Info3DPtr++ = x1; + *g_Info3DPtr++ = y2; + + g_SurfaceCount++; +} + +static void M_InsertTransOctagon( + RENDERER *const renderer, const PHD_VBUF *vbuf, const int16_t shade) +{ + const int32_t vtx_count = 8; + + int8_t clip_or = 0; + uint8_t clip_and = 0xFF; + for (int32_t i = 0; i < vtx_count; i++) { + clip_or |= vbuf[i].clip; + clip_and &= vbuf[i].clip; + } + + if (clip_or < 0 || clip_and || !VBUF_VISIBLE(vbuf[0], vbuf[1], vbuf[2])) { + return; + } + + int32_t num_points = vtx_count; + for (int32_t i = 0; i < num_points; i++) { + m_VBuffer[i].x = vbuf[i].xs; + m_VBuffer[i].y = vbuf[i].ys; + } + + if (clip_or != 0) { + g_FltWinTop = 0.0f; + g_FltWinLeft = 0.0f; + g_FltWinRight = g_PhdWinMaxX; + g_FltWinBottom = g_PhdWinMaxY; + + num_points = Render_XYClipper(vtx_count, m_VBuffer); + if (num_points == 0) { + return; + } + } + + double poly_z = 0.0; + for (int32_t i = 0; i < vtx_count; i++) { + poly_z += vbuf[i].zv; + } + poly_z /= vtx_count; + + g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; + g_Sort3DPtr->_1 = MAKE_ZSORT(poly_z); + g_Sort3DPtr++; + + *g_Info3DPtr++ = POLY_TRANS; + *g_Info3DPtr++ = shade; + *g_Info3DPtr++ = num_points; + for (int32_t i = 0; i < num_points; i++) { + *g_Info3DPtr++ = m_VBuffer[i].x; + *g_Info3DPtr++ = m_VBuffer[i].y; + } + g_SurfaceCount++; +} + +static void M_InsertTransQuad( + RENDERER *const renderer, const int32_t x, const int32_t y, + const int32_t width, int32_t height, const int32_t z) +{ + g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; + g_Sort3DPtr->_1 = MAKE_ZSORT(g_PhdNearZ + 8 * z); + g_Sort3DPtr++; + + *g_Info3DPtr++ = POLY_TRANS; + *g_Info3DPtr++ = 32; + *g_Info3DPtr++ = 4; // number of vertices + *g_Info3DPtr++ = x; + *g_Info3DPtr++ = y; + *g_Info3DPtr++ = x + width; + *g_Info3DPtr++ = y; + *g_Info3DPtr++ = x + width; + *g_Info3DPtr++ = height + y; + *g_Info3DPtr++ = x; + *g_Info3DPtr++ = height + y; + + g_SurfaceCount++; +} + +static void M_InsertSprite( + RENDERER *const renderer, const int32_t z, const int32_t x0, + const int32_t y0, const int32_t x1, const int32_t y1, + const int32_t sprite_idx, const int16_t shade) +{ + g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr; + g_Sort3DPtr->_1 = MAKE_ZSORT(z); + g_Sort3DPtr++; + + *g_Info3DPtr++ = POLY_SPRITE; + *g_Info3DPtr++ = x0; + *g_Info3DPtr++ = y0; + *g_Info3DPtr++ = x1; + *g_Info3DPtr++ = y1; + *g_Info3DPtr++ = sprite_idx; + *g_Info3DPtr++ = shade; + g_SurfaceCount++; +} + +void Renderer_SW_Prepare(RENDERER *const renderer) +{ + renderer->Init = M_Init; + renderer->Open = M_Open; + renderer->Close = M_Close; + renderer->Shutdown = M_Shutdown; + renderer->BeginScene = M_BeginScene; + renderer->EndScene = M_EndScene; + renderer->Reset = M_Reset; + renderer->ResetPolyList = M_ResetPolyList; + renderer->DrawPolyList = M_DrawPolyList; + renderer->ResetPolyList = NULL; + renderer->EnableZBuffer = NULL; + renderer->ClearZBuffer = NULL; + + renderer->InsertObjectG3 = M_InsertObjectG3; + renderer->InsertObjectG4 = M_InsertObjectG4; + renderer->InsertObjectGT3 = M_InsertObjectGT3; + renderer->InsertObjectGT4 = M_InsertObjectGT4; + renderer->InsertLine = M_InsertLine; + renderer->InsertFlatRect = M_InsertFlatRect; + renderer->InsertTransQuad = M_InsertTransQuad; + renderer->InsertTransOctagon = M_InsertTransOctagon; + renderer->InsertSprite = M_InsertSprite; +} diff --git a/src/tr2/game/render/swr.h b/src/tr2/game/render/swr.h new file mode 100644 index 000000000..d32042f4e --- /dev/null +++ b/src/tr2/game/render/swr.h @@ -0,0 +1,5 @@ +#pragma once + +#include "game/render/priv.h" + +void Renderer_SW_Prepare(RENDERER *renderer); diff --git a/src/tr2/game/render/util.c b/src/tr2/game/render/util.c new file mode 100644 index 000000000..18341cb09 --- /dev/null +++ b/src/tr2/game/render/util.c @@ -0,0 +1,23 @@ +#include "game/render/util.h" + +RGBA_8888 Render_ARGB1555To8888(const uint16_t argb1555) +{ + // Extract 5-bit values for each ARGB component + uint8_t a1 = (argb1555 >> 15) & 0x01; + uint8_t r5 = (argb1555 >> 10) & 0x1F; + uint8_t g5 = (argb1555 >> 5) & 0x1F; + uint8_t b5 = argb1555 & 0x1F; + + // Expand 5-bit color components to 8-bit + uint8_t a8 = a1 * 255; // 1-bit alpha (either 0 or 255) + uint8_t r8 = (r5 << 3) | (r5 >> 2); + uint8_t g8 = (g5 << 3) | (g5 >> 2); + uint8_t b8 = (b5 << 3) | (b5 >> 2); + + return (RGBA_8888) { + .r = r8, + .g = g8, + .b = b8, + .a = a8, + }; +} diff --git a/src/tr2/game/render/util.h b/src/tr2/game/render/util.h new file mode 100644 index 000000000..b1bb4e0b6 --- /dev/null +++ b/src/tr2/game/render/util.h @@ -0,0 +1,5 @@ +#pragma once + +#include "global/types.h" + +RGBA_8888 Render_ARGB1555To8888(uint16_t argb1555); diff --git a/src/tr2/game/requester.c b/src/tr2/game/requester.c index 1a91eacfc..6a78ceb43 100644 --- a/src/tr2/game/requester.c +++ b/src/tr2/game/requester.c @@ -62,8 +62,8 @@ void __cdecl Requester_Init(REQUEST_INFO *const req) req->pitem_flags1 = g_RequesterFlags1; req->pitem_flags2 = g_RequesterFlags2; - req->render_width = GetRenderWidth(); - req->render_height = GetRenderHeight(); + req->render_width = g_PhdWinWidth; + req->render_height = g_PhdWinHeight; } void __cdecl Requester_Shutdown(REQUEST_INFO *const req) @@ -79,8 +79,8 @@ int32_t __cdecl Requester_Display( const int32_t lines_height = line_qty * req->line_height + 10; const int32_t line_one_off = req->y_pos - lines_height; - const uint32_t render_width = GetRenderWidth(); - const uint32_t render_height = GetRenderHeight(); + const uint32_t render_width = g_PhdWinWidth; + const uint32_t render_height = g_PhdWinHeight; if (render_width != req->render_width || render_height != req->render_height) { Requester_Shutdown(req); @@ -466,7 +466,7 @@ void __cdecl Requester_AddItem( void __cdecl Requester_SetSize( REQUEST_INFO *const req, const int32_t max_lines, const int32_t y_pos) { - int32_t visible_lines = GetRenderHeight() / 2 / 18; + int32_t visible_lines = g_PhdWinHeight / 2 / 18; CLAMPG(visible_lines, max_lines); req->y_pos = y_pos; req->visible_count = visible_lines; diff --git a/src/tr2/game/room_draw.c b/src/tr2/game/room_draw.c index 138ad4ffb..87111f9cd 100644 --- a/src/tr2/game/room_draw.c +++ b/src/tr2/game/room_draw.c @@ -118,7 +118,6 @@ void __cdecl Room_SetBounds( PORTAL_VBUF portal_vbuf[4]; int32_t z_behind = 0; - int32_t z_too_far = 0; for (int32_t i = 0; i < 4; i++) { PORTAL_VBUF *const dvbuf = &portal_vbuf[i]; @@ -138,10 +137,6 @@ void __cdecl Room_SetBounds( continue; } - if (zv > g_PhdFarZ) { - z_too_far++; - } - int32_t xs; int32_t ys; const int32_t zp = zv / g_PhdPersp; @@ -167,7 +162,7 @@ void __cdecl Room_SetBounds( } } - if (z_behind == 4 || z_too_far == 4) { + if (z_behind == 4) { return; } @@ -360,7 +355,7 @@ void __cdecl Room_Clip(const ROOM *const r) CLAMPL(min_y, g_PhdWinTop); CLAMPG(max_x, g_PhdWinRight); CLAMPG(max_y, g_PhdWinBottom); - S_InsertBackPolygon(min_x, min_y, max_x, max_y); + Output_InsertBackPolygon(min_x, min_y, max_x, max_y); } void __cdecl Room_DrawSingleRoomGeometry(const int16_t room_num) @@ -512,15 +507,11 @@ void __cdecl Room_DrawAllRooms(const int16_t current_room) const int16_t *frame = g_Anims[g_Objects[O_SKYBOX].anim_idx].frame_ptr + FBBOX_ROT; Matrix_RotYXZsuperpack(&frame, 0); - S_InitialisePolyList(0); Output_InsertSkybox(g_Meshes[g_Objects[O_SKYBOX].mesh_idx]); Matrix_Pop(); } else { - S_InitialisePolyList(1); g_Outside = -1; } - } else { - S_InitialisePolyList(0); } if (g_Objects[O_LARA].loaded && !(g_LaraItem->flags & IF_ONE_SHOT)) { 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 0d145613b..0acd0f37d 100644 --- a/src/tr2/game/shell/common.c +++ b/src/tr2/game/shell/common.c @@ -4,33 +4,325 @@ #include "decomp/decomp.h" #include "decomp/fmv.h" #include "decomp/savegame.h" -#include "game/background.h" #include "game/clock.h" #include "game/console/common.h" #include "game/demo.h" +#include "game/fader.h" +#include "game/game.h" #include "game/game_string.h" #include "game/gamebuf.h" #include "game/gameflow.h" #include "game/gameflow/reader.h" #include "game/input.h" #include "game/music.h" +#include "game/output.h" +#include "game/render/common.h" #include "game/sound.h" #include "game/text.h" +#include "game/viewport.h" #include "global/funcs.h" #include "global/vars.h" #include +#include #include +#include #include #include #include #include -#define GAMEBUF_MEM_CAP 0x380000 +#define GAMEBUF_MEM_CAP 0x780000 +static Uint64 m_UpdateDebounce = 0; static const char *m_CurrentGameflowPath = "cfg/TR2X_gameflow.json5"; +static void M_SyncToWindow(void); +static void M_SanitizePosition(void); +static void M_SyncFromWindow(void); +static void M_RefreshRendererViewport(void); +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 bool M_CreateGameWindow(void); + +static struct { + bool is_fullscreen; + bool is_maximized; + int32_t x; + int32_t y; + int32_t width; + int32_t height; +} m_LastWindowState = { 0 }; + +static void M_SyncToWindow(void) +{ + m_UpdateDebounce = SDL_GetTicks(); + + LOG_DEBUG( + "is_fullscreen=%d is_maximized=%d x=%d y=%d width=%d height=%d", + g_Config.window.is_fullscreen, g_Config.window.is_maximized, + g_Config.window.x, g_Config.window.y, g_Config.window.width, + g_Config.window.height); + + if (g_Config.window.is_fullscreen) { + SDL_SetWindowFullscreen(g_SDLWindow, SDL_WINDOW_FULLSCREEN_DESKTOP); + SDL_ShowCursor(SDL_DISABLE); + } else if (g_Config.window.is_maximized) { + SDL_SetWindowFullscreen(g_SDLWindow, 0); + SDL_MaximizeWindow(g_SDLWindow); + SDL_ShowCursor(SDL_ENABLE); + } else { + int32_t x = g_Config.window.x; + int32_t y = g_Config.window.y; + int32_t width = g_Config.window.width; + int32_t height = g_Config.window.height; + if (width <= 0 || height <= 0) { + width = 1280; + height = 720; + } + if (x <= 0 || y <= 0) { + x = (Shell_GetCurrentDisplayWidth() - width) / 2; + y = (Shell_GetCurrentDisplayHeight() - height) / 2; + } + + SDL_SetWindowFullscreen(g_SDLWindow, 0); + SDL_SetWindowPosition(g_SDLWindow, x, y); + SDL_SetWindowSize(g_SDLWindow, width, height); + SDL_ShowCursor(SDL_ENABLE); + } +} + +static void M_RefreshRendererViewport(void) +{ + Viewport_Reset(); +} + +static void M_SyncFromWindow(void) +{ + if (SDL_GetTicks() - m_UpdateDebounce < 1000) { + // Setting the size programatically triggers resize events. + // Additionally, SDL_GetWindowSize() is not guaranteed to return the + // same values as passed to SDL_SetWindowSize(). In order to avoid + // infinite loops where the window dimensions are continuously updated, + // resize events are debounced. + return; + } + + const Uint32 window_flags = SDL_GetWindowFlags(g_SDLWindow); + const bool is_maximized = window_flags & SDL_WINDOW_MAXIMIZED; + + int32_t width; + int32_t height; + SDL_GetWindowSize(g_SDLWindow, &width, &height); + + int32_t x; + int32_t y; + SDL_GetWindowPosition(g_SDLWindow, &x, &y); + + LOG_INFO("%dx%d+%d,%d (maximized: %d)", width, height, x, y, is_maximized); + + g_Config.window.is_maximized = is_maximized; + if (!is_maximized && !g_Config.window.is_fullscreen) { + g_Config.window.x = x; + g_Config.window.y = y; + g_Config.window.width = width; + g_Config.window.height = height; + } + + // Save the updated config, but ensure it was loaded first + if (g_Config.loaded) { + Config_Write(); + } + + M_RefreshRendererViewport(); +} + +static void M_HandleFocusGained(void) +{ + g_IsGameWindowActive = true; +} + +static void M_HandleFocusLost(void) +{ + g_IsGameWindowActive = false; +} + +static void M_HandleWindowShown(void) +{ + LOG_DEBUG(""); +} + +static void M_HandleWindowRestored(void) +{ + M_SyncFromWindow(); +} + +static void M_HandleWindowMinimized(void) +{ + LOG_DEBUG(""); +} + +static void M_HandleWindowMaximized(void) +{ + M_SyncFromWindow(); +} + +static void M_HandleWindowMoved(const int32_t x, const int32_t y) +{ + M_SyncFromWindow(); +} + +static void M_HandleWindowResized(int32_t width, int32_t height) +{ + M_SyncFromWindow(); +} + +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_IsGameToExit = true; +} + +static void M_ConfigureOpenGL(void) +{ + // Setup minimum properties of GL context + struct { + SDL_GLattr attr; + int value; + } attrs[] = { + { SDL_GL_RED_SIZE, 8 }, { SDL_GL_RED_SIZE, 8 }, + { SDL_GL_GREEN_SIZE, 8 }, { SDL_GL_BLUE_SIZE, 8 }, + { SDL_GL_ALPHA_SIZE, 8 }, { SDL_GL_DEPTH_SIZE, 24 }, + { SDL_GL_DOUBLEBUFFER, 1 }, { (SDL_GLattr)-1, 0 }, + }; + + for (int32_t i = 0; attrs[i].attr != (SDL_GLattr)-1; i++) { + if (SDL_GL_SetAttribute(attrs[i].attr, attrs[i].value) != 0) { + LOG_ERROR( + "Failed to set attribute %x: %s", attrs[i].attr, + SDL_GetError()); + } + } +} + +static bool M_CreateGameWindow(void) +{ + g_IsGameWindowActive = true; + + int32_t result = SDL_Init(SDL_INIT_EVENTS | SDL_INIT_VIDEO); + if (result < 0) { + Shell_ExitSystemFmt( + "Error while calling SDL_Init: 0x%lx, %s", result, SDL_GetError()); + return false; + } + + LOG_DEBUG( + "%d,%d -> %dx%d", g_Config.window.x, g_Config.window.y, + g_Config.window.width, g_Config.window.height); + g_SDLWindow = SDL_CreateWindow( + "TR2X", g_Config.window.x, g_Config.window.y, g_Config.window.width, + g_Config.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; + } + + return true; +} + +static void M_HandleConfigChange(const EVENT *const event, void *const data) +{ + const CONFIG *const old = &g_Config; + const CONFIG *const new = &g_SavedConfig; + if (old->window.is_fullscreen != new->window.is_fullscreen + || old->window.is_maximized != new->window.is_maximized + || old->window.x != new->window.x || old->window.y != new->window.y + || old->window.width != new->window.width + || old->window.height != new->window.height + || old->rendering.scaler != new->rendering.scaler + || old->rendering.sizer != new->rendering.sizer + || old->rendering.aspect_mode != new->rendering.aspect_mode) { + LOG_DEBUG("Change in settings detected"); + M_SyncToWindow(); + M_RefreshRendererViewport(); + } + + if (old->rendering.render_mode != new->rendering.render_mode) { + Render_Reset(RENDER_RESET_ALL); + } else if ( + old->rendering.enable_zbuffer != new->rendering.enable_zbuffer + || old->rendering.enable_perspective_filter + != new->rendering.enable_perspective_filter + || old->rendering.enable_wireframe != new->rendering.enable_wireframe + || old->rendering.texture_filter != new->rendering.texture_filter) { + Render_Reset(RENDER_RESET_PARAMS); + } +} + +static void M_DisplayLegal(void) +{ + Output_LoadBackgroundFromFile("data\\legal.pcx"); + FADER fader; + Fader_InitBlackToTransparent(&fader, FRAMES_PER_SECOND); + while (Fader_Control(&fader)) { + Output_BeginScene(); + Output_DrawBackground(); + Output_DrawPolyList(); + Output_DrawBlackRectangle(fader.current.value); + Output_EndScene(); + } + + if (!g_Input.any) { + S_Wait(6 * FRAMES_PER_SECOND, true); + } + + Fader_InitAnyToBlack(&fader, FRAMES_PER_SECOND / 3); + while (Fader_Control(&fader)) { + Output_BeginScene(); + Output_DrawBackground(); + Output_DrawPolyList(); + Output_DrawBlackRectangle(fader.current.value); + Output_EndScene(); + } + Output_UnloadBackground(); +} + // TODO: refactor the hell out of me void __cdecl Shell_Main(void) { @@ -41,12 +333,23 @@ void __cdecl Shell_Main(void) UI_Init(); Console_Init(); + Input_Init(); Clock_Init(); Sound_Init(); Music_Init(); - Input_Init(); Config_Read(); + Config_SubscribeChanges(M_HandleConfigChange, NULL); + + if (!M_CreateGameWindow()) { + Shell_ExitSystem("Failed to create game window"); + return; + } + + Shell_Start(); + Viewport_AlterFOV(GAME_FOV * PHD_DEGREE); + Viewport_Reset(); + if (!S_InitialiseSystem()) { return; } @@ -65,20 +368,8 @@ void __cdecl Shell_Main(void) S_FrontEndCheck(); GameBuf_Init(GAMEBUF_MEM_CAP); - - g_IsVidModeLock = 1; - - S_DisplayPicture("data\\legal.pcx", 0); - S_InitialisePolyList(0); - S_CopyBufferToScreen(); - S_OutputPolyList(); - S_DumpScreen(); - Shell_ProcessEvents(); - FadeToPal(30, g_GamePalette8); - S_Wait(180, true); - S_FadeToBlack(); - S_DontDisplayPicture(); - g_IsVidModeLock = 0; + GameBuf_Reset(); + M_DisplayLegal(); const bool is_frontend_fail = GF_DoFrontendSequence(); if (g_IsGameToExit) { @@ -91,7 +382,6 @@ void __cdecl Shell_Main(void) return; } - S_FadeToBlack(); int16_t gf_option = g_GameFlow.first_option; g_NoInputCounter = 0; @@ -128,8 +418,11 @@ void __cdecl Shell_Main(void) break; case GFD_START_CINE: - Game_Cutscene_Start(gf_param); - gf_option = GFD_EXIT_TO_TITLE; + if (Game_LoopCinematic(gf_param) == 3) { + gf_option = GFD_EXIT_GAME; + } else { + gf_option = GFD_EXIT_TO_TITLE; + } break; case GFD_START_DEMO: @@ -169,10 +462,7 @@ void __cdecl Shell_Shutdown(void) { GameString_Shutdown(); Console_Shutdown(); - BGND_Free(); - RenderFinish(false); - WinVidFinish(); - WinVidHideGameWindow(); + Render_Shutdown(); Text_Shutdown(); UI_Shutdown(); GameBuf_Shutdown(); @@ -184,6 +474,60 @@ const char *Shell_GetGameflowPath(void) return m_CurrentGameflowPath; } +void Shell_Start(void) +{ + M_ConfigureOpenGL(); + Render_Init(); + M_SyncToWindow(); + + SDL_ShowWindow(g_SDLWindow); + SDL_RaiseWindow(g_SDLWindow); + M_RefreshRendererViewport(); +} + +bool Shell_IsFullscreen(void) +{ + const Uint32 flags = SDL_GetWindowFlags(g_SDLWindow); + return (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; +} + +void Shell_GoFullscreen(void) +{ + g_Config.window.is_fullscreen = true; + g_Config.window.is_maximized = false; + M_SyncToWindow(); + M_RefreshRendererViewport(); + if (g_Config.loaded) { + Config_Write(); + } +} + +void Shell_GoMaximized(void) +{ + g_Config.window.is_fullscreen = false; + g_Config.window.is_maximized = true; + M_SyncToWindow(); + M_RefreshRendererViewport(); + if (g_Config.loaded) { + Config_Write(); + } +} + +void Shell_GoWindowed(int32_t x, int32_t y, int32_t width, int32_t height) +{ + g_Config.window.is_fullscreen = false; + g_Config.window.is_maximized = false; + g_Config.window.x = x; + g_Config.window.y = y; + g_Config.window.width = width; + g_Config.window.height = height; + M_SyncToWindow(); + M_RefreshRendererViewport(); + if (g_Config.loaded) { + Config_Write(); + } +} + // TODO: try to call this function in a single place after introducing phasers. void Shell_ProcessEvents(void) { @@ -191,33 +535,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: @@ -237,6 +564,42 @@ 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; } } } diff --git a/src/tr2/game/shell/common.h b/src/tr2/game/shell/common.h index e903c190c..eb65230b1 100644 --- a/src/tr2/game/shell/common.h +++ b/src/tr2/game/shell/common.h @@ -2,10 +2,16 @@ #include "global/types.h" +#include + void __cdecl Shell_Main(void); -void __cdecl Shell_Shutdown(void); -void __cdecl Shell_ExitSystem(const char *message); -void __cdecl Shell_ExitSystemFmt(const char *fmt, ...); +void Shell_Start(); const char *Shell_GetGameflowPath(void); void Shell_ProcessEvents(void); + +bool Shell_IsFullscreen(void); + +void Shell_GoFullscreen(void); +void Shell_GoMaximized(void); +void Shell_GoWindowed(int32_t x, int32_t y, int32_t width, int32_t height); diff --git a/src/tr2/game/shell/input.c b/src/tr2/game/shell/input.c index 2c3946061..2d453ee1b 100644 --- a/src/tr2/game/shell/input.c +++ b/src/tr2/game/shell/input.c @@ -8,6 +8,7 @@ #include "game/input.h" #include "game/inventory/backpack.h" #include "game/lara/control.h" +#include "game/overlay.h" #include "global/const.h" #include "global/funcs.h" #include "global/vars.h" @@ -18,8 +19,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); @@ -29,215 +28,93 @@ static void M_IncreaseInternalScreenSize(void); static void M_ToggleBilinearFiltering(void) { - APP_SETTINGS new_settings = g_SavedAppSettings; - new_settings.bilinear_filtering = !new_settings.bilinear_filtering; - GameApplySettings(&new_settings); + g_Config.rendering.texture_filter = + g_Config.rendering.texture_filter == GFX_TF_BILINEAR ? GFX_TF_NN + : GFX_TF_BILINEAR; + Overlay_DisplayModeInfo( + g_Config.rendering.texture_filter == GFX_TF_BILINEAR ? "Bilinear On" + : "Bilinear Off"); + Config_Write(); } static void M_TogglePerspectiveCorrection(void) { - APP_SETTINGS new_settings = g_SavedAppSettings; - new_settings.perspective_correct = !new_settings.perspective_correct; - g_PerspectiveDistance = g_SavedAppSettings.perspective_correct + g_Config.rendering.enable_perspective_filter = + !g_Config.rendering.enable_perspective_filter; + g_PerspectiveDistance = g_Config.rendering.enable_perspective_filter ? SW_DETAIL_HIGH : SW_DETAIL_MEDIUM; - GameApplySettings(&new_settings); + Overlay_DisplayModeInfo( + g_Config.rendering.enable_perspective_filter + ? "Perspective correction enabled" + : "Perspective correction disabled"); + Config_Write(); } static void M_ToggleZBuffer(void) { - APP_SETTINGS new_settings = g_SavedAppSettings; - new_settings.zbuffer = !new_settings.zbuffer; - GameApplySettings(&new_settings); -} - -static void M_ToggleTripleBuffering(void) -{ - if (g_SavedAppSettings.fullscreen) { - return; + if (g_Input.slow) { + g_Config.rendering.enable_wireframe = + !g_Config.rendering.enable_wireframe; + Overlay_DisplayModeInfo( + g_Config.rendering.enable_wireframe ? "Wireframe On" + : "Wireframe Off"); + } else { + g_Config.rendering.enable_zbuffer = !g_Config.rendering.enable_zbuffer; + Overlay_DisplayModeInfo( + g_Config.rendering.enable_zbuffer ? "Z-Buffer On" : "Z-Buffer Off"); } - - 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); + Config_Write(); } static void M_ToggleFullscreen(void) { - if (g_IsVidModeLock) { - return; - } - - APP_SETTINGS new_settings = g_SavedAppSettings; - new_settings.fullscreen = !new_settings.fullscreen; - 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); - setup_screen_size(); - } else { - const DISPLAY_MODE_LIST *const mode_list = - new_settings.render_mode == RM_HARDWARE - ? &g_CurrentDisplayAdapter.hw_disp_mode_list - : &g_CurrentDisplayAdapter.sw_disp_mode_list; - - if (mode_list->count > 0) { - const DISPLAY_MODE target_mode = { - .width = g_GameVid_Width, - .height = g_GameVid_Height, - .bpp = g_GameVid_BPP, - .vga = VGA_NO_VGA, - }; - - const DISPLAY_MODE_NODE *mode = NULL; - for (mode = mode_list->head; mode != NULL; mode = mode->next) { - if (!CompareVideoModes(&mode->body, &target_mode)) { - break; - } - } - - if (mode == NULL) { - mode = mode_list->tail; - } - - new_settings.video_mode = mode; - GameApplySettings(&new_settings); - } - } + g_Config.window.is_fullscreen = !g_Config.window.is_fullscreen; + Config_Write(); } 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; - - const DISPLAY_MODE_LIST *const mode_list = - new_settings.render_mode == RM_HARDWARE - ? &g_CurrentDisplayAdapter.hw_disp_mode_list - : &g_CurrentDisplayAdapter.sw_disp_mode_list; - - if (mode_list->count == 0) { - return; - } - - const DISPLAY_MODE target_mode = { - .width = g_GameVid_Width, - .height = g_GameVid_Height, - .bpp = new_settings.render_mode == RM_HARDWARE ? 16 : 8, - .vga = VGA_NO_VGA, - }; - - const DISPLAY_MODE_NODE *mode = NULL; - for (mode = mode_list->head; mode != NULL; mode = mode->next) { - if (!CompareVideoModes(&mode->body, &target_mode)) { - break; - } - } - - if (mode == NULL) { - mode = mode_list->tail; - } - - new_settings.video_mode = mode; - new_settings.fullscreen = 1; - GameApplySettings(&new_settings); + g_Config.rendering.render_mode = + g_Config.rendering.render_mode == RM_HARDWARE ? RM_SOFTWARE + : RM_HARDWARE; + Overlay_DisplayModeInfo( + g_Config.rendering.render_mode == RM_HARDWARE ? "Hardware Rendering" + : "Software Rendering"); + Config_Write(); } 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; } - APP_SETTINGS new_settings = g_SavedAppSettings; - const DISPLAY_MODE_NODE *const current_mode = new_settings.video_mode; - const DISPLAY_MODE_NODE *mode = current_mode; - if (mode != NULL) { - mode = mode->previous; - } - - if (new_settings.render_mode == RM_HARDWARE) { - for (; mode != NULL; mode = mode->previous) { - if (g_Input.slow) { - if (mode->body.width == current_mode->body.width - && mode->body.height == current_mode->body.height - && mode->body.vga == current_mode->body.vga - && mode->body.bpp < current_mode->body.bpp) { - break; - } - } else if ( - mode->body.vga == current_mode->body.vga - && mode->body.bpp == current_mode->body.bpp) { - break; - } - } - } - - if (mode != NULL) { - new_settings.video_mode = mode; - GameApplySettings(&new_settings); - } + g_Config.rendering.scaler--; + Config_Sanitize(); + char mode_string[64] = { 0 }; + sprintf(mode_string, "Scaler: %d", g_Config.rendering.scaler); + Overlay_DisplayModeInfo(mode_string); + Config_Write(); } 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; } - APP_SETTINGS new_settings = g_SavedAppSettings; - const DISPLAY_MODE_NODE *const current_mode = new_settings.video_mode; - const DISPLAY_MODE_NODE *mode = current_mode; - if (mode != NULL) { - mode = mode->next; - } - - if (new_settings.render_mode == RM_HARDWARE) { - for (; mode != NULL; mode = mode->next) { - if (g_Input.slow) { - if (mode->body.width == current_mode->body.width - && mode->body.height == current_mode->body.height - && mode->body.vga == current_mode->body.vga - && mode->body.bpp > current_mode->body.bpp) { - break; - } - } else if ( - mode->body.vga == current_mode->body.vga - && mode->body.bpp == current_mode->body.bpp) { - break; - } - } - } - if (mode != NULL) { - new_settings.video_mode = mode; - GameApplySettings(&new_settings); - } + g_Config.rendering.scaler++; + Config_Sanitize(); + char mode_string[64] = { 0 }; + sprintf(mode_string, "Scaler: %d", g_Config.rendering.scaler); + Overlay_DisplayModeInfo(mode_string); + Config_Write(); } 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; } @@ -246,9 +123,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; } @@ -271,9 +146,9 @@ void Shell_ProcessInput(void) if (g_InputDB.switch_internal_screen_size) { if (g_Input.slow) { - M_DecreaseInternalScreenSize(); - } else { M_IncreaseInternalScreenSize(); + } else { + M_DecreaseInternalScreenSize(); } } @@ -289,10 +164,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/game/text.c b/src/tr2/game/text.c index a00d622ff..d5a58f262 100644 --- a/src/tr2/game/text.c +++ b/src/tr2/game/text.c @@ -64,15 +64,15 @@ void __cdecl Text_DrawText(TEXTSTRING *const text) Text_GetWidth(text) * Text_GetScaleH(TEXT_BASE_SCALE) / TEXT_BASE_SCALE; if (text->flags.centre_h) { - x += (GetRenderWidth() - text_width) / 2; + x += (g_PhdWinWidth - text_width) / 2; } else if (text->flags.right) { - x += GetRenderWidth() - text_width; + x += g_PhdWinWidth - text_width; } if (text->flags.centre_v) { - y += GetRenderHeight() / 2; + y += g_PhdWinHeight / 2; } else if (text->flags.bottom) { - y += GetRenderHeight(); + y += g_PhdWinHeight; } int32_t box_x = x @@ -110,7 +110,7 @@ void __cdecl Text_DrawText(TEXTSTRING *const text) continue; } - if (x >= 0 && x < GetRenderWidth() && y >= 0 && y < GetRenderHeight()) { + if (x >= 0 && x < g_PhdWinWidth && y >= 0 && y < g_PhdWinHeight) { Output_DrawScreenSprite2D( x, y, z, scale_h, scale_v, g_Objects[O_ALPHABET].mesh_idx + (*glyph_ptr)->mesh_idx, 4096, @@ -141,7 +141,7 @@ void __cdecl Text_DrawText(TEXTSTRING *const text) } if (text->flags.background) { - S_DrawScreenFBox( + Output_DrawScreenFBox( box_x, box_y, z + text->background.offset.z, box_w, box_h, 0, NULL, 0); } @@ -153,17 +153,12 @@ void __cdecl Text_DrawText(TEXTSTRING *const text) int32_t __cdecl Text_GetScaleH(const uint32_t value) { - const int32_t render_width = GetRenderWidth(); - const int32_t render_scale = MAX(render_width, 640) * TEXT_BASE_SCALE / 640; - return (value / PHD_HALF) * (render_scale / PHD_HALF); + return value * g_PhdWinWidth / 640; } int32_t __cdecl Text_GetScaleV(const uint32_t value) { - const int32_t render_height = GetRenderHeight(); - const int32_t render_scale = - MAX(render_height, 480) * TEXT_BASE_SCALE / 480; - return (value / PHD_HALF) * (render_scale / PHD_HALF); + return value * g_PhdWinHeight / 480; } int32_t Text_GetMaxLineLength(void) diff --git a/src/tr2/game/ui/common.c b/src/tr2/game/ui/common.c index aad47d9f8..4cb9611ad 100644 --- a/src/tr2/game/ui/common.c +++ b/src/tr2/game/ui/common.c @@ -1,3 +1,5 @@ +#include "config.h" + #include #include diff --git a/src/tr2/game/viewport.c b/src/tr2/game/viewport.c index 029cf5056..cf2867613 100644 --- a/src/tr2/game/viewport.c +++ b/src/tr2/game/viewport.c @@ -3,12 +3,12 @@ #include "config.h" #include "game/math.h" #include "game/output.h" +#include "game/render/common.h" +#include "game/shell/common.h" #include "global/const.h" #include "global/vars.h" #define MAP_GAME_VARS() \ - MAP_GAME_VAR(win_min_x, g_PhdWinMinX); \ - MAP_GAME_VAR(win_min_y, g_PhdWinMinY); \ MAP_GAME_VAR(win_max_x, g_PhdWinMaxX); \ MAP_GAME_VAR(win_max_y, g_PhdWinMaxY); \ MAP_GAME_VAR(win_width, g_PhdWinWidth); \ @@ -19,10 +19,6 @@ MAP_GAME_VAR(win_top, g_PhdWinTop); \ MAP_GAME_VAR(win_right, g_PhdWinRight); \ MAP_GAME_VAR(win_bottom, g_PhdWinBottom); \ - MAP_GAME_VAR(win_rect.left, g_PhdWinRect.left); \ - MAP_GAME_VAR(win_rect.bottom, g_PhdWinRect.bottom); \ - MAP_GAME_VAR(win_rect.top, g_PhdWinRect.top); \ - MAP_GAME_VAR(win_rect.right, g_PhdWinRect.right); \ MAP_GAME_VAR(near_z, g_PhdNearZ); \ MAP_GAME_VAR(far_z, g_PhdFarZ); \ MAP_GAME_VAR(flt_near_z, g_FltNearZ); \ @@ -36,8 +32,6 @@ MAP_GAME_VAR(flt_persp, g_FltPersp); \ MAP_GAME_VAR(flt_persp_o_near_z, g_FltPerspONearZ); \ MAP_GAME_VAR(view_distance, g_PhdViewDistance); \ - MAP_GAME_VAR(screen_width, g_PhdScreenWidth); \ - MAP_GAME_VAR(screen_height, g_PhdScreenHeight); \ MAP_GAME_VAR(flt_win_left, g_FltWinLeft); \ MAP_GAME_VAR(flt_win_top, g_FltWinTop); \ MAP_GAME_VAR(flt_win_right, g_FltWinRight); \ @@ -55,28 +49,22 @@ static void M_ApplyGameVars(const VIEWPORT *vp); static void M_AlterFov(VIEWPORT *const vp) { - vp->game_vars.persp = vp->game_vars.win_width / 2 - * Math_Cos(vp->view_angle / 2) / Math_Sin(vp->view_angle / 2); + if (vp->view_angle == 0) { + return; + } + + const int16_t view_angle = vp->view_angle; + vp->game_vars.persp = vp->game_vars.win_width / 2 * Math_Cos(view_angle / 2) + / Math_Sin(view_angle / 2); vp->game_vars.flt_persp = vp->game_vars.persp; vp->game_vars.flt_rhw_o_persp = g_RhwFactor / vp->game_vars.flt_persp; vp->game_vars.flt_persp_o_near_z = vp->game_vars.flt_persp / vp->game_vars.flt_near_z; - - double window_aspect_ratio = 4.0 / 3.0; - if (!g_SavedAppSettings.fullscreen - && g_SavedAppSettings.aspect_mode == AM_16_9) { - window_aspect_ratio = 16.0 / 9.0; - } - - vp->game_vars.viewport_aspect_ratio = window_aspect_ratio - / ((double)vp->game_vars.win_width / (double)vp->game_vars.win_height); } static void M_InitGameVars(VIEWPORT *const vp) { - vp->game_vars.win_min_x = vp->x; - vp->game_vars.win_min_y = vp->y; vp->game_vars.win_max_x = vp->width - 1; vp->game_vars.win_max_y = vp->height - 1; vp->game_vars.win_width = vp->width; @@ -89,24 +77,12 @@ static void M_InitGameVars(VIEWPORT *const vp) vp->game_vars.win_right = vp->game_vars.win_max_x; vp->game_vars.win_bottom = vp->game_vars.win_max_y; - vp->game_vars.win_rect.left = vp->game_vars.win_min_x; - vp->game_vars.win_rect.bottom = - vp->game_vars.win_min_y + vp->game_vars.win_height; - vp->game_vars.win_rect.top = vp->game_vars.win_min_y; - vp->game_vars.win_rect.right = - vp->game_vars.win_min_x + vp->game_vars.win_width; - - vp->game_vars.flt_win_left = - vp->game_vars.win_min_x + vp->game_vars.win_left; - vp->game_vars.flt_win_top = vp->game_vars.win_min_y + vp->game_vars.win_top; - vp->game_vars.flt_win_right = - vp->game_vars.win_min_x + vp->game_vars.win_right + 1; - vp->game_vars.flt_win_bottom = - vp->game_vars.win_min_y + vp->game_vars.win_bottom + 1; - vp->game_vars.flt_win_center_x = - vp->game_vars.win_min_x + vp->game_vars.win_center_x; - vp->game_vars.flt_win_center_y = - vp->game_vars.win_min_y + vp->game_vars.win_center_y; + vp->game_vars.flt_win_left = vp->game_vars.win_left; + vp->game_vars.flt_win_top = vp->game_vars.win_top; + vp->game_vars.flt_win_right = vp->game_vars.win_right + 1; + vp->game_vars.flt_win_bottom = vp->game_vars.win_bottom + 1; + vp->game_vars.flt_win_center_x = vp->game_vars.win_center_x; + vp->game_vars.flt_win_center_y = vp->game_vars.win_center_y; vp->game_vars.near_z = vp->near_z << W2V_SHIFT; vp->game_vars.far_z = vp->far_z << W2V_SHIFT; @@ -121,13 +97,13 @@ static void M_InitGameVars(VIEWPORT *const vp) vp->game_vars.flt_res_z_o_rhw = res_z / g_RhwFactor; vp->game_vars.flt_res_z_buf = 0.005 + res_z / vp->game_vars.flt_near_z; vp->game_vars.flt_rhw_o_near_z = g_RhwFactor / vp->game_vars.flt_near_z; - vp->game_vars.flt_persp = vp->game_vars.flt_persp; + vp->game_vars.flt_persp = vp->game_vars.persp; vp->game_vars.flt_persp_o_near_z = vp->game_vars.flt_persp / vp->game_vars.flt_near_z; vp->game_vars.view_distance = vp->far_z; - vp->game_vars.screen_width = vp->screen_width; - vp->game_vars.screen_height = vp->screen_height; + vp->game_vars.viewport_aspect_ratio = + vp->render_ar / ((double)vp->width / (double)vp->height); M_AlterFov(vp); } @@ -146,23 +122,61 @@ static void M_ApplyGameVars(const VIEWPORT *const vp) MAP_GAME_VARS(); } -void Viewport_Init( - int16_t x, int16_t y, int32_t width, int32_t height, int32_t near_z, - int32_t far_z, int16_t view_angle, int32_t screen_width, - int32_t screen_height) +void Viewport_Reset(void) { - m_Viewport.x = x; - m_Viewport.y = y; - m_Viewport.width = width; - m_Viewport.height = height; - m_Viewport.near_z = near_z; - m_Viewport.far_z = far_z; - m_Viewport.view_angle = view_angle; - m_Viewport.screen_width = screen_width; - m_Viewport.screen_height = screen_height; + int32_t win_width; + int32_t win_height; + if (Shell_IsFullscreen()) { + win_width = Shell_GetCurrentDisplayWidth(); + win_height = Shell_GetCurrentDisplayHeight(); + } else { + SDL_GetWindowSize(g_SDLWindow, &win_width, &win_height); + } + + VIEWPORT *const vp = &m_Viewport; + switch (g_Config.rendering.aspect_mode) { + case AM_4_3: + vp->render_ar = 4.0 / 3.0; + break; + case AM_16_9: + vp->render_ar = 16.0 / 9.0; + break; + case AM_ANY: + vp->render_ar = win_width / (double)win_height; + break; + } + + vp->width = win_width / g_Config.rendering.scaler; + vp->height = win_height / g_Config.rendering.scaler; + if (g_Config.rendering.aspect_mode != AM_ANY) { + vp->width = vp->height * vp->render_ar; + } + + vp->near_z = VIEW_NEAR; + vp->far_z = VIEW_FAR; + // Do not mess with the FOV upon plain reset requests. + // vp->view_angle = GAME_FOV * PHD_DEGREE; + + switch (g_Config.rendering.render_mode) { + case RM_SOFTWARE: + g_PerspectiveDistance = g_Config.rendering.enable_perspective_filter + ? SW_DETAIL_HIGH + : SW_DETAIL_MEDIUM; + break; + + case RM_HARDWARE: + break; + + default: + Shell_ExitSystem("unknown render mode"); + } M_InitGameVars(&m_Viewport); M_ApplyGameVars(&m_Viewport); + + const int32_t win_border = win_height * (1.0 - g_Config.rendering.sizer); + Render_SetupDisplay( + win_border, win_width, win_height, vp->width, vp->height); } const VIEWPORT *Viewport_Get(void) diff --git a/src/tr2/game/viewport.h b/src/tr2/game/viewport.h index 8c8cd704b..d44101ca7 100644 --- a/src/tr2/game/viewport.h +++ b/src/tr2/game/viewport.h @@ -3,20 +3,15 @@ #include typedef struct { - int32_t x; - int32_t y; int32_t width; int32_t height; int32_t near_z; int32_t far_z; int16_t view_angle; - int32_t screen_width; - int32_t screen_height; + double render_ar; // TODO: remove most of these variables if possible struct { - int32_t win_min_x; - int32_t win_min_y; int32_t win_max_x; int32_t win_max_y; int32_t win_width; @@ -29,13 +24,6 @@ typedef struct { int32_t win_right; int32_t win_bottom; - struct { - int32_t left; - int32_t bottom; - int32_t top; - int32_t right; - } win_rect; - int32_t persp; int32_t near_z; int32_t far_z; @@ -56,16 +44,11 @@ typedef struct { float flt_win_center_x; float flt_win_center_y; int32_t view_distance; - int32_t screen_width; - int32_t screen_height; float viewport_aspect_ratio; } game_vars; } VIEWPORT; -void Viewport_Init( - int16_t x, int16_t y, int32_t width, int32_t height, int32_t near_z, - int32_t far_z, int16_t view_angle, int32_t screen_width, - int32_t screen_height); +void Viewport_Reset(void); void Viewport_Restore(const VIEWPORT *ref_vp); diff --git a/src/tr2/global/enum_map.c b/src/tr2/global/enum_map.c index 28c90eb70..f4047b6df 100644 --- a/src/tr2/global/enum_map.c +++ b/src/tr2/global/enum_map.c @@ -1,6 +1,9 @@ +#include "global/types.h" + #include #include #include +#include #include void EnumMap_Init(void) diff --git a/src/tr2/global/enum_map.def b/src/tr2/global/enum_map.def index 12270e03c..cfc891f7c 100644 --- a/src/tr2/global/enum_map.def +++ b/src/tr2/global/enum_map.def @@ -1,3 +1,17 @@ ENUM_MAP_DEFINE(SCREENSHOT_FORMAT, SCREENSHOT_FORMAT_JPEG, "jpg") ENUM_MAP_DEFINE(SCREENSHOT_FORMAT, SCREENSHOT_FORMAT_JPEG, "jpeg") ENUM_MAP_DEFINE(SCREENSHOT_FORMAT, SCREENSHOT_FORMAT_PNG, "png") + +ENUM_MAP_DEFINE(TEXEL_ADJUST_MODE, TAM_DISABLED, "never") +ENUM_MAP_DEFINE(TEXEL_ADJUST_MODE, TAM_BILINEAR_ONLY, "bilinear-only") +ENUM_MAP_DEFINE(TEXEL_ADJUST_MODE, TAM_ALWAYS, "always") + +ENUM_MAP_DEFINE(RENDER_MODE, RM_SOFTWARE, "software") +ENUM_MAP_DEFINE(RENDER_MODE, RM_HARDWARE, "hardware") + +ENUM_MAP_DEFINE(ASPECT_MODE, AM_ANY, "any") +ENUM_MAP_DEFINE(ASPECT_MODE, AM_4_3, "4:3") +ENUM_MAP_DEFINE(ASPECT_MODE, AM_16_9, "16:9") + +ENUM_MAP_DEFINE(GFX_TEXTURE_FILTER, GFX_TF_BILINEAR, "bilinear") +ENUM_MAP_DEFINE(GFX_TEXTURE_FILTER, GFX_TF_NN, "point") diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index fe9c64877..ce1420a4f 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -134,86 +134,16 @@ #define DartEffect_Control ((void __cdecl (*)(int16_t fx_num))0x00442AE0) #define GiantYeti_Control ((void __cdecl (*)(int16_t item_num))0x00443050) #define Yeti_Control ((void __cdecl (*)(int16_t item_num))0x00443350) -#define ReadFileSync ((BOOL __cdecl (*)(HANDLE handle, LPVOID lpBuffer, DWORD nBytesToRead, LPDWORD lpnBytesRead, LPOVERLAPPED lpOverlapped))0x004498D0) #define GetValidLevelsList ((void __cdecl (*)(REQUEST_INFO *req))0x0044C9D0) #define CalculateWibbleTable ((void __cdecl (*)(void))0x0044D780) #define S_GetObjectBounds ((int32_t __cdecl (*)(const BOUNDS_16 *bounds))0x00450CC0) -#define S_PrintShadow ((void __cdecl (*)(int16_t radius, const BOUNDS_16 *bounds, const ITEM *item))0x00450F80) #define S_CalculateLight ((void __cdecl (*)(int32_t x, int32_t y, int32_t z, int16_t room_num))0x00451180) #define S_CalculateStaticLight ((void __cdecl (*)(int16_t adder))0x00451480) #define S_CalculateStaticMeshLight ((void __cdecl (*)(int32_t x, int32_t y, int32_t z, int32_t shade_1, int32_t shade_2, ROOM *room))0x004514C0) #define S_LightRoom ((void __cdecl (*)(ROOM *room))0x004515F0) -#define S_DrawHealthBar ((void __cdecl (*)(int32_t percent))0x00451800) -#define S_DrawAirBar ((void __cdecl (*)(int32_t percent))0x004519D0) -#define AnimateTextures ((void __cdecl (*)(int32_t ticks))0x00451BD0) #define S_SetupBelowWater ((void __cdecl (*)(BOOL underwater))0x00451C90) #define S_SetupAboveWater ((void __cdecl (*)(BOOL underwater))0x00451CF0) #define S_AnimateTextures ((void __cdecl (*)(int32_t ticks))0x00451D20) -#define DecompPCX ((BOOL __cdecl (*)(const uint8_t *pcx, size_t pcx_size, LPBYTE pic, RGB_888 *pal))0x004522A0) -#define OpenGameRegistryKey ((bool __cdecl (*)(LPCTSTR key))0x004523C0) -#define CloseGameRegistryKey ((LONG __cdecl (*)(void))0x00452410) -#define SE_WriteAppSettings ((bool __cdecl (*)(APP_SETTINGS *settings))0x00452420) -#define SE_GraphicsTestStart ((bool __cdecl (*)(void))0x004529E0) -#define SE_GraphicsTestFinish ((void __cdecl (*)(void))0x00452AB0) -#define SE_GraphicsTestExecute ((int32_t __cdecl (*)(void))0x00452AD0) -#define SE_GraphicsTest ((int32_t __cdecl (*)(void))0x00452AE0) -#define SE_SoundTestStart ((bool __cdecl (*)(void))0x00452B40) -#define SE_SoundTestFinish ((void __cdecl (*)(void))0x00452C00) -#define SE_SoundTestExecute ((int32_t __cdecl (*)(void))0x00452C10) -#define SE_SoundTest ((int32_t __cdecl (*)(void))0x00452C50) -#define SE_PropSheetCallback ((int32_t __stdcall (*)(HWND hwndDlg, UINT uMsg, LPARAM lParam))0x00452CB0) -#define SE_NewPropSheetWndProc ((LRESULT __stdcall (*)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam))0x00452CF0) -#define SE_ShowSetupDialog ((bool __cdecl (*)(HWND hParent, bool isDefault))0x00452D50) -#define SE_GraphicsDlgProc ((INT_PTR __stdcall (*)(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam))0x00453030) -#define SE_GraphicsDlgFullScreenModesUpdate ((void __cdecl (*)(HWND hwndDlg))0x004533F0) -#define SE_GraphicsAdapterSet ((void __cdecl (*)(HWND hwndDlg, DISPLAY_ADAPTER_NODE *adapter))0x004535E0) -#define SE_GraphicsDlgUpdate ((void __cdecl (*)(HWND hwndDlg))0x00453600) -#define SE_GraphicsDlgInit ((void __cdecl (*)(HWND hwndDlg))0x00453D40) -#define SE_SoundDlgProc ((INT_PTR __stdcall (*)(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam))0x00453EC0) -#define SE_SoundAdapterSet ((void __cdecl (*)(HWND hwndDlg, SOUND_ADAPTER_NODE *adapter))0x00454050) -#define SE_SoundDlgUpdate ((void __cdecl (*)(HWND hwndDlg))0x00454060) -#define SE_SoundDlgInit ((void __cdecl (*)(HWND hwndDlg))0x00454180) -#define SE_ControlsDlgProc ((INT_PTR __stdcall (*)(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam))0x00454240) -#define SE_ControlsJoystickSet ((void __cdecl (*)(HWND hwndDlg, JOYSTICK_NODE *joystick))0x00454350) -#define SE_ControlsDlgUpdate ((void __cdecl (*)(HWND hwndDlg))0x00454360) -#define SE_ControlsDlgInit ((void __cdecl (*)(HWND hwndDlg))0x004543D0) -#define SE_OptionsDlgProc ((INT_PTR __stdcall (*)(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam))0x00454490) -#define SE_OptionsDlgUpdate ((void __cdecl (*)(HWND hwndDlg))0x00454520) -#define SE_OptionsStrCat ((void __cdecl (*)(LPTSTR *dstString, bool isEnabled, bool *isNext, LPCTSTR srcString))0x00454760) -#define SE_AdvancedDlgProc ((INT_PTR __stdcall (*)(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam))0x004547B0) -#define SE_AdvancedDlgUpdate ((void __cdecl (*)(HWND hwndDlg))0x004548B0) -#define SE_AdvancedDlgInit ((void __cdecl (*)(HWND hwndDlg))0x00454950) -#define SE_FindSetupDialog ((HWND __cdecl (*)(void))0x00454960) #define CheckCheatMode ((void __cdecl (*)(void))0x00454D60) -#define UT_LoadResource ((LPVOID __cdecl (*)(LPCTSTR lpName, LPCTSTR lpType))0x00456590) -#define UT_CenterWindow ((BOOL __cdecl (*)(HWND hWnd))0x00456680) -#define UT_FindArg ((LPTSTR __cdecl (*)(LPCTSTR str))0x004566F0) -#define UT_MessageBox ((int32_t __cdecl (*)(LPCTSTR lpText, HWND hWnd))0x00456720) -#define UT_ErrorBox ((int32_t __cdecl (*)(UINT uID, HWND hWnd))0x00456740) -#define GuidBinaryToString ((LPCTSTR __cdecl (*)(GUID *guid))0x00456790) -#define GuidStringToBinary ((bool __cdecl (*)(LPCTSTR lpString, GUID *guid))0x004567F0) -#define OpenRegistryKey ((BOOL __cdecl (*)(LPCTSTR lpSubKey))0x004568A0) -#define IsNewRegistryKeyCreated ((bool __cdecl (*)(void))0x004568D0) -#define CloseRegistryKey ((LONG __cdecl (*)(void))0x004568E0) -#define SetRegistryDwordValue ((LONG __cdecl (*)(LPCTSTR lpValueName, DWORD value))0x004568F0) -#define SetRegistryBoolValue ((LONG __cdecl (*)(LPCTSTR lpValueName, bool value))0x00456910) -#define SetRegistryFloatValue ((LONG __cdecl (*)(LPCTSTR lpValueName, double value))0x00456940) -#define SetRegistryBinaryValue ((LONG __cdecl (*)(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize))0x00456980) -#define SetRegistryStringValue ((LONG __cdecl (*)(LPCTSTR lpValueName, LPCTSTR value, int32_t length))0x004569C0) -#define DeleteRegistryValue ((LONG __cdecl (*)(LPCTSTR lpValueName))0x00456A10) -#define GetRegistryDwordValue ((bool __cdecl (*)(LPCTSTR lpValueName, DWORD *pValue, DWORD defaultValue))0x00456A30) -#define GetRegistryBoolValue ((bool __cdecl (*)(LPCTSTR lpValueName, bool *pValue, bool defaultValue))0x00456A90) -#define GetRegistryFloatValue ((bool __cdecl (*)(LPCTSTR lpValueName, double *value, double defaultValue))0x00456B10) -#define GetRegistryBinaryValue ((bool __cdecl (*)(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize, LPBYTE defaultValue))0x00456B70) -#define GetRegistryStringValue ((bool __cdecl (*)(LPCTSTR lpValueName, LPTSTR value, DWORD maxSize, LPCTSTR defaultValue))0x00456BF0) -#define GetRegistryGuidValue ((bool __cdecl (*)(LPCTSTR lpValueName, GUID *value, GUID *defaultValue))0x00456C90) -#define SE_ReleaseBitmapResource ((void __thiscall (*)(BITMAP_RESOURCE *bmpRsrc))0x00456D30) -#define SE_LoadBitmapResource ((void __thiscall (*)(BITMAP_RESOURCE *bmpRsrc, LPCTSTR lpName))0x00456D70) -#define SE_DrawBitmap ((void __thiscall (*)(BITMAP_RESOURCE *bmpRsrc, HDC hdc, int32_t x, int32_t y))0x00456E40) -#define SE_UpdateBitmapPalette ((void __thiscall (*)(BITMAP_RESOURCE *bmpRsrc, HWND hWnd, HWND hSender))0x00456EB0) -#define SE_ChangeBitmapPalette ((void __thiscall (*)(BITMAP_RESOURCE *bmpRsrc, HWND hWnd))0x00456ED0) -#define SE_RegisterSetupWindowClass ((bool __cdecl (*)(void))0x00456F30) -#define SE_SetupWindowProc ((LRESULT __stdcall (*)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam))0x00456FA0) -#define SE_PassMessageToImage ((void __cdecl (*)(HWND hWnd, UINT uMsg, WPARAM wParam))0x004571E0) #define UT_MemBlt ((void __cdecl (*)(BYTE *dstBuf, DWORD dstX, DWORD dstY, DWORD width, DWORD height, DWORD dstPitch, BYTE *srcBuf, DWORD srcX, DWORD srcY, DWORD srcPitch))0x00457210) // clang-format on diff --git a/src/tr2/global/types.h b/src/tr2/global/types.h index 74d0e76b0..1494418a8 100644 --- a/src/tr2/global/types.h +++ b/src/tr2/global/types.h @@ -1,1670 +1,10 @@ -// This file is autogenerated. To update it, run tools/generate_funcs. - #pragma once -#include "const.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#pragma pack(push, 1) - -// clang-format off -typedef IDirect3DDevice2 *LPDIRECT3DDEVICE2; -typedef IDirect3DTexture2 *LPDIRECT3DTEXTURE2; -typedef IDirect3DViewport2 *LPDIRECT3DVIEWPORT2; -typedef IDirect3DMaterial2 *LPDIRECT3DMATERIAL2; -typedef DDSURFACEDESC DDSDESC, *LPDDSDESC; -typedef LPDIRECTDRAWSURFACE3 LPDDS; -typedef LPDIRECTDRAW3 LPDD; -typedef D3DTEXTUREHANDLE HWR_TEXTURE_HANDLE; - -typedef int16_t PHD_ANGLE; - -typedef struct __unaligned { - int32_t _00; - int32_t _01; - int32_t _02; - int32_t _03; - int32_t _10; - int32_t _11; - int32_t _12; - int32_t _13; - int32_t _20; - int32_t _21; - int32_t _22; - int32_t _23; -} MATRIX; - -typedef enum { - VGA_NO_VGA = 0, - VGA_256_COLOR = 1, - VGA_MODEX = 2, - VGA_STANDARD = 3, -} VGA_MODE; - -typedef struct __unaligned { - LPBITMAPINFO bmp_info; - void *bmp_data; - HPALETTE hPalette; - DWORD flags; -} BITMAP_RESOURCE; - -typedef struct __unaligned { - int32_t width; - int32_t height; - int32_t bpp; - VGA_MODE vga; -} DISPLAY_MODE; - -typedef struct __unaligned DISPLAY_MODE_NODE { - struct DISPLAY_MODE_NODE *next; - struct DISPLAY_MODE_NODE *previous; - DISPLAY_MODE body; -} DISPLAY_MODE_NODE; - -typedef struct __unaligned { - DISPLAY_MODE_NODE *head; - DISPLAY_MODE_NODE *tail; - DWORD count; -} DISPLAY_MODE_LIST; - -typedef struct __unaligned { - char *content; - bool is_valid; -} STRING_FLAGGED; - -typedef struct __unaligned { - LPGUID adapter_guid_ptr; - GUID adapter_guid; - STRING_FLAGGED driver_desc; - STRING_FLAGGED driver_name; - DDCAPS_DX5 driver_caps; - DDCAPS_DX5 hel_caps; - GUID device_guid; - D3DDEVICEDESC_V2 hw_device_desc; - DISPLAY_MODE_LIST hw_disp_mode_list; - DISPLAY_MODE_LIST sw_disp_mode_list; - DISPLAY_MODE vga_mode1; - DISPLAY_MODE vga_mode2; - uint32_t screen_width; - bool hw_render_supported; - bool sw_windowed_supported; - bool hw_windowed_supported; - bool is_vga_mode1_presented; - bool is_vga_mode2_presented; - bool perspective_correct_supported; - bool dither_supported; - bool zbuffer_supported; - bool linear_filter_supported; - bool shade_restricted; -} DISPLAY_ADAPTER; - -typedef struct __unaligned DISPLAY_ADAPTER_NODE { - struct DISPLAY_ADAPTER_NODE *next; - struct DISPLAY_ADAPTER_NODE *previous; - DISPLAY_ADAPTER body; -} DISPLAY_ADAPTER_NODE; - -typedef struct __unaligned { - DISPLAY_ADAPTER_NODE *head; - DISPLAY_ADAPTER_NODE *tail; - DWORD count; -} DISPLAY_ADAPTER_LIST; - -typedef struct __unaligned { - GUID *adapter_guid_ptr; - GUID adapter_guid; - STRING_FLAGGED description; - STRING_FLAGGED module; -} SOUND_ADAPTER; - -typedef struct __unaligned SOUND_ADAPTER_NODE { - struct SOUND_ADAPTER_NODE *next; - struct SOUND_ADAPTER_NODE *previous; - SOUND_ADAPTER body; -} SOUND_ADAPTER_NODE; - -typedef struct __unaligned { - SOUND_ADAPTER_NODE *head; - SOUND_ADAPTER_NODE *tail; - DWORD count; -} SOUND_ADAPTER_LIST; - -typedef struct __unaligned { - GUID *lpJoystickGuid; - GUID joystickGuid; - STRING_FLAGGED productName; - STRING_FLAGGED instanceName; -} JOYSTICK; - -typedef struct __unaligned JOYSTICK_NODE { - struct JOYSTICK_NODE *next; - struct JOYSTICK_NODE *previous; - JOYSTICK body; -} JOYSTICK_NODE; - -typedef struct __unaligned JOYSTICK_LIST { - struct JOYSTICK_LIST *head; - struct JOYSTICK_LIST *tail; - DWORD count; -} JOYSTICK_LIST; - -typedef enum { - RM_UNKNOWN = 0, - RM_SOFTWARE = 1, - RM_HARDWARE = 2, -} RENDER_MODE; - -typedef enum { - AM_4_3 = 0, - AM_16_9 = 1, - AM_ANY = 2, -} ASPECT_MODE; - -typedef enum { - TAM_DISABLED = 0, - TAM_BILINEAR_ONLY = 1, - TAM_ALWAYS = 2, -} TEX_ADJUST_MODE; - -typedef struct __unaligned { - DISPLAY_ADAPTER_NODE *preferred_display_adapter; - SOUND_ADAPTER_NODE *preferred_sound_adapter; - JOYSTICK_NODE *preferred_joystick; - const DISPLAY_MODE_NODE *video_mode; - RENDER_MODE render_mode; - int32_t window_width; - int32_t window_height; - ASPECT_MODE aspect_mode; - bool perspective_correct; - bool dither; - bool zbuffer; - bool bilinear_filtering; - bool triple_buffering; - bool fullscreen; - bool sound_enabled; - bool lara_mic; - bool joystick_enabled; - bool disable_16bit_textures; - bool dont_sort_primitives; - bool flip_broken; - TEX_ADJUST_MODE texel_adjust_mode; - int32_t nearest_adjustment; - int32_t linear_adjustment; -} APP_SETTINGS; - -typedef struct __unaligned { - LPDDS sys_mem_surface; - LPDDS vid_mem_surface; - LPDIRECTDRAWPALETTE palette; - LPDIRECT3DTEXTURE2 texture_3d; - HWR_TEXTURE_HANDLE tex_handle; - int32_t width; - int32_t height; - int32_t status; -} TEXPAGE_DESC; - -typedef struct __unaligned { - uint8_t red; - uint8_t green; - uint8_t blue; -} RGB_888; - -typedef struct __unaligned { - uint8_t red; - uint8_t green; - uint8_t blue; - uint8_t alpha; -} RGBA_8888; +#include "global/types_decomp.h" typedef struct { - struct { - uint32_t r; - uint32_t g; - uint32_t b; - uint32_t a; - } mask, depth, offset; -} COLOR_BIT_MASKS; - -typedef struct __unaligned { - D3DCOLOR clr[4][4]; -} GOURAUD_FILL; - -typedef struct __unaligned { - D3DCOLOR clr[9]; -} GOURAUD_OUTLINE; - -typedef struct __unaligned { - uint8_t index[256]; -} DEPTHQ_ENTRY; - -typedef struct __unaligned { - uint8_t index[32]; -} GOURAUD_ENTRY; - -typedef struct __unaligned { - XYZ_32 pos; - XYZ_16 rot; -} PHD_3DPOS; - -typedef struct __unaligned { - int32_t x; - int32_t y; - int32_t z; - int32_t r; -} SPHERE; - -typedef struct __unaligned { - float xv; - float yv; - float zv; - float rhw; - float xs; - float ys; - int16_t clip; - int16_t g; - int16_t u; - int16_t v; -} PHD_VBUF; - -typedef struct __unaligned { - uint16_t u; - uint16_t v; -} PHD_UV; - -typedef struct __unaligned { uint16_t draw_type; uint16_t tex_page; PHD_UV uv[4]; + PHD_UV uv_backup[4]; } PHD_TEXTURE; - -typedef struct __unaligned { - uint16_t tex_page; - uint16_t offset; - uint16_t width; - uint16_t height; - int16_t x0; - int16_t y0; - int16_t x1; - int16_t y1; -} PHD_SPRITE; - -typedef enum { - SHAPE_SPRITE = 1, - SHAPE_LINE = 2, - SHAPE_BOX = 3, - SHAPE_FBOX = 4, -} SHAPE; - -typedef enum { - SPRF_RGB = 0x00FFFFFF, - SPRF_ABS = 0x01000000, - SPRF_SEMITRANS = 0x02000000, - SPRF_SCALE = 0x04000000, - SPRF_SHADE = 0x08000000, - SPRF_TINT = 0x10000000, - SPRF_BLEND_ADD = 0x20000000, - SPRF_BLEND_SUB = 0x40000000, - SPRF_BLEND_QRT = SPRF_BLEND_ADD | SPRF_BLEND_SUB, - SPRF_BLEND = SPRF_BLEND_QRT, - SPRF_ITEM = 0x80000000, -} SPRITE_FLAG; - -typedef struct __unaligned { - float xv; - float yv; - float zv; - float rhw; - float xs; - float ys; - float u; - float v; - float g; -} POINT_INFO; - -typedef struct __unaligned { - float x; - float y; - float rhw; - float u; - float v; - float g; -} VERTEX_INFO; - -typedef struct __unaligned { - uint16_t no_selector : 1; - uint16_t ready : 1; // not present in the OG - uint16_t pad : 14; - uint16_t items_count; - uint16_t selected; - uint16_t visible_count; - uint16_t line_offset; - uint16_t line_old_offset; - uint16_t pix_width; - uint16_t line_height; - int16_t x_pos; - int16_t y_pos; - int16_t z_pos; - uint16_t item_string_len; - char *pitem_strings1; - char *pitem_strings2; - uint32_t *pitem_flags1; - uint32_t *pitem_flags2; - uint32_t heading_flags1; - uint32_t heading_flags2; - uint32_t background_flags; - uint32_t moreup_flags; - uint32_t moredown_flags; - uint32_t item_flags1[24]; // MAX_REQUESTER_ITEMS - uint32_t item_flags2[24]; // MAX_REQUESTER_ITEMS - TEXTSTRING *heading_text1; - TEXTSTRING *heading_text2; - TEXTSTRING *background_text; - TEXTSTRING *moreup_text; - TEXTSTRING *moredown_text; - TEXTSTRING *item_texts1[24]; // MAX_REQUESTER_ITEMS - TEXTSTRING *item_texts2[24]; // MAX_REQUESTER_ITEMS - char heading_string1[32]; - char heading_string2[32]; - uint32_t render_width; - uint32_t render_height; -} REQUEST_INFO; - -typedef enum { - POLY_GTMAP = 0, - POLY_WGTMAP = 1, - POLY_GTMAP_PERSP = 2, - POLY_WGTMAP_PERSP = 3, - POLY_LINE = 4, - POLY_FLAT = 5, - POLY_GOURAUD = 6, - POLY_TRANS = 7, - POLY_SPRITE = 8, - POLY_HWR_GTMAP = 9, - POLY_HWR_WGTMAP = 10, - POLY_HWR_GOURAUD = 11, - POLY_HWR_LINE = 12, - POLY_HWR_TRANS = 13, -} POLY_TYPE; - -typedef struct __unaligned { - uint32_t best_time[10]; - uint32_t best_finish[10]; - uint32_t finish_count; -} ASSAULT_STATS; - -typedef struct __unaligned { - int32_t _0; - int32_t _1; -} SORT_ITEM; - -typedef enum { - ST_AVG_Z = 0, - ST_MAX_Z = 1, - ST_FAR_Z = 2, -} SORT_TYPE; - -typedef enum { - DRAW_OPAQUE = 0, - DRAW_COLOR_KEY = 1, -} DRAW_TYPE; - -typedef struct __unaligned { - int16_t mesh_idx; - uint16_t flags; - BOUNDS_16 draw_bounds; - BOUNDS_16 collision_bounds; -} STATIC_INFO; - -typedef struct __unaligned { - uint32_t timer; - uint32_t shots; - uint32_t hits; - uint32_t distance; - uint16_t kills; - uint8_t secrets; - uint8_t medipacks; -} STATISTICS_INFO; - -typedef struct __unaligned { - uint16_t pistol_ammo; - uint16_t magnum_ammo; - uint16_t uzi_ammo; - uint16_t shotgun_ammo; - uint16_t m16_ammo; - uint16_t grenade_ammo; - uint16_t harpoon_ammo; - uint8_t small_medipacks; - uint8_t large_medipacks; - uint8_t reserved1; - uint8_t flares; - uint8_t gun_status; - uint8_t gun_type; - uint16_t available: 1; // 0x01 1 - uint16_t has_pistols: 1; // 0x02 2 - uint16_t has_magnums: 1; // 0x04 4 - uint16_t has_uzis: 1; // 0x08 8 - uint16_t has_shotgun: 1; // 0x10 16 - uint16_t has_m16: 1; // 0x20 32 - uint16_t has_grenade: 1; // 0x40 64 - uint16_t has_harpoon: 1; // 0x80 128 - uint16_t pad : 8; - uint16_t reserved2; - STATISTICS_INFO statistics; -} START_INFO; - -typedef struct __unaligned { - START_INFO start[24]; - STATISTICS_INFO statistics; - int16_t current_level; - bool bonus_flag; - uint8_t num_pickup[2]; - uint8_t num_puzzle[4]; - uint8_t num_key[4]; - uint16_t reserved; - char buffer[6272]; // MAX_SG_BUFFER_SIZE -} SAVEGAME_INFO; - -typedef struct __unaligned { - int16_t lock_angles[4]; - int16_t left_angles[4]; - int16_t right_angles[4]; - int16_t aim_speed; - int16_t shot_accuracy; - int32_t gun_height; - int32_t damage; - int32_t target_dist; - int16_t recoil_frame; - int16_t flash_time; - int16_t sample_num; -} WEAPON_INFO; - -typedef struct __unaligned { - int16_t zone_num; - int16_t enemy_zone_num; - int32_t distance; - int32_t ahead; - int32_t bite; - int16_t angle; - int16_t enemy_facing; -} AI_INFO; - -typedef struct __unaligned { - int16_t timer; - int16_t sprite; -} PICKUP_INFO; - -typedef struct __unaligned { - int16_t shape; - XYZ_16 pos; - int32_t param1; - int32_t param2; - void *grdptr; - int16_t sprite_num; -} INVENTORY_SPRITE; - -typedef struct __unaligned { - char *string; - int16_t object_id; - int16_t frames_total; - int16_t current_frame; - int16_t goal_frame; - int16_t open_frame; - int16_t anim_direction; - int16_t anim_speed; - int16_t anim_count; - int16_t x_rot_pt_sel; - int16_t x_rot_pt; - int16_t x_rot_sel; - int16_t x_rot_nosel; - int16_t x_rot; - int16_t y_rot_sel; - int16_t y_rot; - int32_t y_trans_sel; - int32_t y_trans; - int32_t z_trans_sel; - int32_t z_trans; - uint32_t meshes_sel; - uint32_t meshes_drawn; - int16_t inv_pos; - INVENTORY_SPRITE **sprite_list; - int32_t reserved[4]; -} INVENTORY_ITEM; - -typedef enum { - RNG_OPENING = 0, - RNG_OPEN = 1, - RNG_CLOSING = 2, - RNG_MAIN2OPTION = 3, - RNG_MAIN2KEYS = 4, - RNG_KEYS2MAIN = 5, - RNG_OPTION2MAIN = 6, - RNG_SELECTING = 7, - RNG_SELECTED = 8, - RNG_DESELECTING = 9, - RNG_DESELECT = 10, - RNG_CLOSING_ITEM = 11, - RNG_EXITING_INVENTORY = 12, - RNG_DONE = 13, -} RING_STATUS; - -typedef struct __unaligned { - int16_t count; - int16_t status; - int16_t status_target; - int16_t radius_target; - int16_t radius_rate; - int16_t camera_y_target; - int16_t camera_y_rate; - int16_t camera_pitch_target; - int16_t camera_pitch_rate; - int16_t rotate_target; - int16_t rotate_rate; - int16_t item_pt_x_rot_target; - int16_t item_pt_x_rot_rate; - int16_t item_x_rot_target; - int16_t item_x_rot_rate; - int32_t item_y_trans_target; - int32_t item_y_trans_rate; - int32_t item_z_trans_target; - int32_t item_z_trans_rate; - int32_t misc; -} IMOTION_INFO; - -typedef enum { - PM_SPINE = 1, - PM_FRONT = 2, - PM_IN_FRONT = 4, - PM_PAGE_2 = 8, - PM_BACK = 16, - PM_IN_BACK = 32, - PM_PAGE_1 = 64, - PM_COMMON = PM_SPINE | PM_BACK | PM_FRONT, -} PASS_MESH; - -typedef struct __unaligned { - INVENTORY_ITEM **list; - int16_t type; - int16_t radius; - int16_t camera_pitch; - int16_t rotating; - int16_t rot_count; - int16_t current_object; - int16_t target_object; - int16_t number_of_objects; - int16_t angle_adder; - int16_t rot_adder; - int16_t rot_adder_l; - int16_t rot_adder_r; - PHD_3DPOS ring_pos; - PHD_3DPOS camera; - XYZ_32 light; - IMOTION_INFO *imo; -} RING_INFO; - -typedef enum { - GFE_PICTURE = 0, - GFE_LIST_START = 1, - GFE_LIST_END = 2, - GFE_PLAY_FMV = 3, - GFE_START_LEVEL = 4, - GFE_CUTSCENE = 5, - GFE_LEVEL_COMPLETE = 6, - GFE_DEMO_PLAY = 7, - GFE_JUMP_TO_SEQ = 8, - GFE_END_SEQ = 9, - GFE_SET_TRACK = 10, - GFE_SUNSET = 11, - GFE_LOADING_PIC = 12, - GFE_DEADLY_WATER = 13, - GFE_REMOVE_WEAPONS = 14, - GFE_GAME_COMPLETE = 15, - GFE_CUT_ANGLE = 16, - GFE_NO_FLOOR = 17, - GFE_ADD_TO_INV = 18, - GFE_START_ANIM = 19, - GFE_NUM_SECRETS = 20, - GFE_KILL_TO_COMPLETE = 21, - GFE_REMOVE_AMMO = 22, -} GF_EVENTS; - -typedef enum { - TARGET_NONE = 0, - TARGET_PRIMARY = 1, - TARGET_SECONDARY = 2, -} TARGET_TYPE; - -typedef struct __unaligned { - XYZ_32 pos; - int32_t mesh_num; -} BITE; - -typedef enum { - RF_UNDERWATER = 0x01, - RF_OUTSIDE = 0x08, - RF_DYNAMIC_LIT = 0x10, - RF_INSIDE = 0x40, -} ROOM_FLAG; - -typedef struct __unaligned { - SECTOR *sector; - SECTOR old_sector; - int16_t block; -} DOORPOS_DATA; - -typedef enum { - CAM_CHASE = 0, - CAM_FIXED = 1, - CAM_LOOK = 2, - CAM_COMBAT = 3, - CAM_CINEMATIC = 4, - CAM_HEAVY = 5, -} CAMERA_TYPE; - -typedef struct __unaligned { - union { - XYZ_32 pos; - struct { - int32_t x; - int32_t y; - int32_t z; - }; - }; - int16_t room_num; - int16_t box_num; -} GAME_VECTOR; - -typedef struct __unaligned { - union { - struct __unaligned { - int32_t x; - int32_t y; - int32_t z; - }; - XYZ_32 pos; - }; - int16_t data; - int16_t flags; -} OBJECT_VECTOR; - -typedef struct __unaligned { - uint8_t left; - uint8_t right; - uint8_t top; - uint8_t bottom; - int16_t height; - int16_t overlap_index; -} BOX_INFO; - -typedef enum { - LV_GYM = 0, - LV_FIRST = 1, -} LEVEL_TYPE; - -typedef enum { - RT_MAIN = 0, - RT_OPTION = 1, - RT_KEYS = 2, -} RING_TYPE; - -typedef enum { - INV_COLOR_BLACK = 0, - INV_COLOR_GRAY = 1, - INV_COLOR_WHITE = 2, - INV_COLOR_RED = 3, - INV_COLOR_ORANGE = 4, - INV_COLOR_YELLOW = 5, - INV_COLOR_DARK_GREEN = 12, - INV_COLOR_GREEN = 13, - INV_COLOR_CYAN = 14, - INV_COLOR_BLUE = 15, - INV_COLOR_MAGENTA = 16, - INV_COLOR_NUMBER_OF = 17, -} INV_COLOR; - -typedef enum { - INV_GAME_MODE = 0, - INV_TITLE_MODE = 1, - INV_KEYS_MODE = 2, - INV_SAVE_MODE = 3, - INV_LOAD_MODE = 4, - INV_DEATH_MODE = 5, -} INVENTORY_MODE; - -typedef enum { - GAMEMODE_NOT_IN_GAME, - GAMEMODE_IN_GAME, - GAMEMODE_IN_DEMO, - GAMEMODE_IN_CUTSCENE -} GAMEMODE; - -typedef enum { - TRAP_SET = 0, - TRAP_ACTIVATE = 1, - TRAP_WORKING = 2, - TRAP_FINISHED = 3, -} TRAP_ANIM; - -typedef enum { - GFD_START_GAME = 0x0000, - GFD_START_SAVED_GAME = 0x0100, - GFD_START_CINE = 0x0200, - GFD_START_FMV = 0x0300, - GFD_START_DEMO = 0x0400, - GFD_EXIT_TO_TITLE = 0x0500, - GFD_LEVEL_COMPLETE = 0x0600, - GFD_EXIT_GAME = 0x0700, - GFD_EXIT_TO_OPTION = 0x0800, - GFD_TITLE_DESELECT = 0x0900, - GFD_OVERRIDE = 0x0A00, -} GAME_FLOW_DIR; - -typedef struct __unaligned { - int32_t first_option; - int32_t title_replace; - int32_t on_death_demo_mode; - int32_t on_death_in_game; - int32_t no_input_time; - int32_t on_demo_interrupt; - int32_t on_demo_end; - uint16_t reserved1[18]; - uint16_t num_levels; - uint16_t num_pictures; - uint16_t num_titles; - uint16_t num_fmvs; - uint16_t num_cutscenes; - uint16_t num_demos; - uint16_t title_track; - int16_t single_level; - uint16_t reserved2[16]; - - uint16_t demo_version: 1; // 0x0001 - uint16_t title_disabled: 1; // 0x0002 - uint16_t cheat_mode_check_disabled: 1; // 0x0004 - uint16_t no_input_timeout: 1; // 0x0008 - uint16_t load_save_disabled: 1; // 0x0010 - uint16_t screen_sizing_disabled: 1; // 0x0020 - uint16_t lockout_option_ring: 1; // 0x0040 - uint16_t dozy_cheat_enabled: 1; // 0x0080 - uint16_t cyphered_strings: 1; // 0x0100 - uint16_t gym_enabled: 1; // 0x0200 - uint16_t play_any_level: 1; // 0x0400 - uint16_t cheat_enable: 1; // 0x0800 - - uint16_t reserved3[3]; - uint8_t cypher_code; - uint8_t language; - uint8_t secret_track; - uint8_t level_complete_track; - uint16_t reserved4[2]; -} GAME_FLOW; - -typedef struct __unaligned { - GAME_VECTOR pos; - GAME_VECTOR target; - CAMERA_TYPE type; - int32_t shift; - uint32_t flags; - int32_t fixed_camera; - int32_t num_frames; - int32_t bounce; - int32_t underwater; - int32_t target_distance; - int32_t target_square; - int16_t target_angle; - int16_t actual_angle; - int16_t target_elevation; - int16_t box; - int16_t num; - int16_t last; - int16_t timer; - int16_t speed; - ITEM *item; - ITEM *last_item; - OBJECT_VECTOR *fixed; - int32_t is_lara_mic; - XYZ_32 mic_pos; -} CAMERA_INFO; - -typedef enum { - SFX_LARA_FEET = 0, - SFX_LARA_CLIMB_2 = 1, - SFX_LARA_NO = 2, - SFX_LARA_SLIPPING = 3, - SFX_LARA_LAND = 4, - SFX_LARA_CLIMB_1 = 5, - SFX_LARA_DRAW = 6, - SFX_LARA_HOLSTER = 7, - SFX_LARA_FIRE = 8, - SFX_LARA_RELOAD = 9, - SFX_LARA_RICOCHET = 10, - SFX_LARA_FLARE_IGNITE = 11, - SFX_LARA_FLARE_BURN = 12, - SFX_LARA_HARPOON_FIRE = 15, - SFX_LARA_HARPOON_LOAD = 16, - SFX_LARA_WET_FEET = 17, - SFX_LARA_WADE = 18, - SFX_LARA_TREAD = 20, - SFX_LARA_FIRE_MAGNUMS = 21, - SFX_LARA_HARPOON_LOAD_WATER = 22, - SFX_LARA_HARPOON_FIRE_WATER = 23, - SFX_MASSIVE_CRASH = 24, - SFX_PUSH_SWITCH = 25, - SFX_LARA_CLIMB_3 = 26, - SFX_LARA_BODYSL = 27, - SFX_LARA_SHIMMY = 28, - SFX_LARA_JUMP = 29, - SFX_LARA_FALL = 30, - SFX_LARA_INJURY = 31, - SFX_LARA_ROLL = 32, - SFX_LARA_SPLASH = 33, - SFX_LARA_GETOUT = 34, - SFX_LARA_SWIM = 35, - SFX_LARA_BREATH = 36, - SFX_LARA_BUBBLES = 37, - SFX_LARA_SWITCH = 38, - SFX_LARA_KEY = 39, - SFX_LARA_OBJECT = 40, - SFX_LARA_GENERAL_DEATH = 41, - SFX_LARA_KNEES_DEATH = 42, - SFX_LARA_UZI_FIRE = 43, - SFX_LARA_UZI_STOP = 44, - SFX_LARA_SHOTGUN = 45, - SFX_LARA_BLOCK_PUSH_1 = 46, - SFX_LARA_BLOCK_PUSH_2 = 47, - SFX_CLICK = 48, - SFX_LARA_HIT = 49, - SFX_LARA_BULLETHIT = 50, - SFX_LARA_BLKPULL = 51, - SFX_LARA_FLOATING = 52, - SFX_LARA_FALLDETH = 53, - SFX_LARA_GRABHAND = 54, - SFX_LARA_GRABBODY = 55, - SFX_LARA_GRABFEET = 56, - SFX_LARA_SWITCHUP = 57, - SFX_GLASS_BREAK = 58, - SFX_WATER_LOOP = 59, - SFX_UNDERWATER = 60, - SFX_UNDERWATER_SWITCH = 61, - SFX_LARA_PICKUP = 62, - SFX_BLOCK_SOUND = 63, - SFX_DOOR = 64, - SFX_SWING = 65, - SFX_ROCK_FALL_CRUMBLE = 66, - SFX_ROCK_FALL_LAND = 67, - SFX_ROCK_FALL_SOLID = 68, - SFX_ENEMY_FEET = 69, - SFX_ENEMY_GRUNT = 70, - SFX_ENEMY_HIT_1 = 71, - SFX_ENEMY_HIT_2 = 72, - SFX_ENEMY_DEATH_1 = 73, - SFX_ENEMY_JUMP = 74, - SFX_ENEMY_CLIMBUP = 75, - SFX_ENEMY_CLIMBDOWN = 76, - SFX_WEAPON_CLATTER = 77, - SFX_M16_FIRE = 78, - SFX_WATERFALL_LOOP = 79, - SFX_SWORD_STATUE_DROP = 80, - SFX_SWORD_STATUE_LIFT = 81, - SFX_PORTCULLIS_UP = 82, - SFX_PORTCULLIS_DOWN = 83, - SFX_DOG_FEET_1 = 84, - SFX_BODY_SLAM = 85, - SFX_DOG_BARK_1 = 86, - SFX_DOG_FEET_2 = 87, - SFX_DOG_BARK_2 = 88, - SFX_DOG_DEATH = 89, - SFX_DOG_PANT = 90, - SFX_LEOPARD_FEET = 91, - SFX_LEOPARD_ROAR = 92, - SFX_LEOPARD_BITE = 93, - SFX_LEOPARD_STRIKE = 94, - SFX_LEOPARD_DEATH = 95, - SFX_LEOPARD_GROWL = 96, - SFX_RAT_ATTACK = 97, - SFX_RAT_DEATH = 98, - SFX_TIGER_ROAR = 99, - SFX_TIGER_BITE = 100, - SFX_TIGER_STRIKE = 101, - SFX_TIGER_DEATH = 102, - SFX_TIGER_GROWL = 103, - SFX_M16_STOP = 104, - SFX_EXPLOSION_1 = 105, - SFX_GROWL = 106, - SFX_SPIDER_JUMP = 107, - SFX_MENU_ROTATE = 108, - SFX_MENU_LARA_HOME = 109, - SFX_MENU_SPININ = 111, - SFX_MENU_SPINOUT = 112, - SFX_MENU_STOPWATCH = 113, - SFX_MENU_GUNS = 114, - SFX_MENU_PASSPORT = 115, - SFX_MENU_MEDI = 116, - SFX_ENEMY_HEELS = 117, - SFX_ENEMY_FIRE_SILENCER = 118, - SFX_ENEMY_AH_DYING = 119, - SFX_ENEMY_OOH_DYING = 120, - SFX_ENEMY_THUMP = 121, - SFX_SPIDER_MOVING = 122, - SFX_LARA_MINI_LOAD = 123, - SFX_LARA_MINI_LOCK = 124, - SFX_LARA_MINI_FIRE = 125, - SFX_SPIDER_BITE = 126, - SFX_SLAM_DOOR_SLIDE = 127, - SFX_SLAM_DOOR_CLOSE = 128, - SFX_EAGLE_SQUAWK = 129, - SFX_EAGLE_WING_FLAP = 130, - SFX_EAGLE_DEATH = 131, - SFX_CROW_CAW = 132, - SFX_CROW_WING_FLAP = 133, - SFX_CROW_DEATH = 134, - SFX_CROW_ATTACK = 135, - SFX_ENEMY_GUN_COCKING = 136, - SFX_ENEMY_FIRE_1 = 137, - SFX_ENEMY_FIRE_TWIRL = 138, - SFX_ENEMY_HOLSTER = 139, - SFX_ENEMY_BREATH_1 = 140, - SFX_ENEMY_CHUCKLE = 141, - SFX_MONK_POY = 142, - SFX_MONK_DEATH = 143, - SFX_LARA_SPIKE_DEATH = 145, - SFX_LARA_DEATH_3 = 146, - SFX_ROLLING_BALL = 147, - SFX_SANDBAG_SNAP = 148, - SFX_SANDBAG_HIT = 149, - SFX_LOOP_FOR_SMALL_FIRES = 150, - SFX_SKIDOO_START = 152, - SFX_SKIDOO_IDLE = 153, - SFX_SKIDOO_ACCELERATE = 154, - SFX_SKIDOO_MOVING = 155, - SFX_SKIDOO_STOP = 156, - SFX_ENEMY_FIRE_2 = 157, - SFX_ENEMY_DEATH_2 = 158, - SFX_ENEMY_BREATH_2 = 159, - SFX_STICK_TAP = 160, - SFX_TRAPDOOR_OPEN = 161, - SFX_TRAPDOOR_CLOSE = 162, - SFX_YETI_GROWL = 163, - SFX_YETI_CHEST_BEAT = 164, - SFX_YETI_THUMP = 165, - SFX_YETI_GRUNT_1 = 166, - SFX_YETI_SCREAM = 167, - SFX_YETI_DEATH = 168, - SFX_YETI_GROWL_1 = 169, - SFX_YETI_GROWL_2 = 170, - SFX_YETI_GRUNT_2 = 171, - SFX_YETI_GROWL_3 = 172, - SFX_YETI_FEET = 173, - SFX_ENEMY_HEAVY_BREATH = 174, - SFX_ENEMY_FLAMETHROWER_FIRE = 175, - SFX_ENEMY_FLAMETHROWER_SCRAPE = 176, - SFX_ENEMY_FLAMETHROWER_CLICK = 177, - SFX_ENEMY_FLAMETHROWER_DEATH = 178, - SFX_ENEMY_FLAMETHROWER_FALL = 179, - SFX_ENEMY_BELT_JINGLE = 180, - SFX_ENEMY_WRENCH = 181, - SFX_FOOTSTEP = 182, - SFX_FOOTSTEP_HIT = 183, - SFX_ENEMY_COCKING_SHOTGUN = 184, - SFX_SCUBA_DIVER_FLIPPER = 186, - SFX_SCUBA_DIVER_BREATH = 188, - SFX_PULLEY_CRANE = 190, - SFX_CURTAIN = 191, - SFX_SCUBA_DIVER_DEATH = 192, - SFX_SCUBA_DIVER_DIVING = 193, - SFX_BOAT_START = 194, - SFX_BOAT_IDLE = 195, - SFX_BOAT_ACCELERATE = 196, - SFX_BOAT_MOVING = 197, - SFX_BOAT_STOP = 198, - SFX_BOAT_SLOW_DOWN = 199, - SFX_BOAT_HIT = 200, - SFX_CLATTER_1 = 201, - SFX_CLATTER_2 = 202, - SFX_CLATTER_3 = 203, - SFX_DOOR_SLIDE = 204, - SFX_LARA_FLESH_WOUND = 205, - SFX_SAW_REVVING = 206, - SFX_SAW_STOP = 207, - SFX_DOOR_CHIME = 208, - SFX_CHAIN_CREAK_SNAP = 209, - SFX_SWINGING = 210, - SFX_BREAKING_1 = 211, - SFX_PULLEY_MOVE = 212, - SFX_AIRPLANE_IDLE = 213, - SFX_UNDERWATER_FAN_ON = 215, - SFX_SMALL_FAN_ON = 217, - SFX_SWINGING_BOX_BAG = 218, - SFX_JUMP_PAD_UP = 219, - SFX_JUMP_PAD_DOWN = 220, - SFX_BREAKING_2 = 221, - SFX_SNOWBALL_ROLL = 222, - SFX_SNOWBALL_STOP = 223, - SFX_ROLLING = 224, - SFX_ROLLING_STOP_1 = 225, - SFX_ROLLING_STOP_2 = 226, - SFX_ROLLING_2 = 227, - SFX_ROLLING_2_HIT = 228, - SFX_SIDE_BLADE_SWING = 229, - SFX_SIDE_BLADE_BACK = 230, - SFX_ROLLING_BLADE = 231, - SFX_ICILE_DETACH = 232, - SFX_ICICLE_HIT = 233, - SFX_ROTATING_HANDLE_LOOSE = 234, - SFX_ROTATING_HANDLE_TURN = 235, - SFX_ROTATING_HANDLE_OPEN = 236, - SFX_ROTATING_HANDLE_CREAK = 237, - SFX_MONK_FEET = 238, - SFX_MONK_SWORD_SWING_1 = 239, - SFX_MONK_SWORD_SWING_2 = 240, - SFX_MONK_SHOUT_1 = 241, - SFX_MONK_SHOUT_2 = 242, - SFX_MONK_SHOUT_3 = 243, - SFX_MONK_SHOUT_4 = 244, - SFX_MONK_CRUNCH = 245, - SFX_MONK_BREATH = 246, - SFX_SPLASH_SURFACE = 247, - SFX_WATERFALL_1 = 248, - SFX_ENEMY_FEET_SNOW = 249, - SFX_ENEMY_FIRE_3 = 250, - SFX_ENEMY_FIRE_SEMIAUTO = 251, - SFX_ENEMY_DEATH_3 = 252, - SFX_ENEMY_DEATH_4 = 253, - SFX_CIRCLE_BLADE = 254, - SFX_KNIFETHROWER_FEET = 255, - SFX_MONK_OYE = 256, - SFX_MONK_AWEH = 257, - SFX_CIRCLE_BLADE_HIT = 258, - SFX_KNIFETHROWER_WARRIOR_FEET = 259, - SFX_WARRIOR_BLADE_SWING_1 = 260, - SFX_WARRIOR_BLADE_SWING_2 = 261, - SFX_WARRIOR_GROWL = 262, - SFX_KNIFETHROWER_HICCUP = 263, - SFX_WARROPR_BURP = 264, - SFX_WARRIOR_GROWL_1 = 265, - SFX_WARRIOR_WAKE = 267, - SFX_WARRIOR_GROWL_2 = 268, - SFX_SMALL_SWITCH = 269, - SFX_CHAIN_PULLEY = 278, - SFX_ZIPLINE_GRAB = 279, - SFX_ZIPLINE_GO = 280, - SFX_ZIPLINE_STOP = 281, - SFX_BODY_SLUMP = 282, - SFX_BOWL_TIPPING = 283, - SFX_BOWL_POUR = 284, - SFX_WATERFALL_2 = 285, - SFX_ELEVATOR_OPEN = 286, - SFX_ELEVATOR_CLOSE = 287, - SFX_MINISUB_CLATTER_1 = 288, - SFX_MINISUB_CLATTER_2 = 289, - SFX_MINISUB_CLATTER_3 = 290, - SFX_BIRD_MONSTER_SCREAM = 291, - SFX_BIRD_MONSTER_GASP = 292, - SFX_BIRD_MONSTER_BREATH = 293, - SFX_BIRD_MONSTER_FEET = 294, - SFX_BIRD_MONSTER_DEATH = 295, - SFX_BIRD_MONSTER_SCRAPE = 296, - SFX_HELICOPTER_LOOP = 297, - SFX_DRAGON_FEET = 298, - SFX_DRAGON_GROWL_1 = 299, - SFX_DRAGON_GROWL_2 = 300, - SFX_DRAGON_FALL = 301, - SFX_DRAGON_BREATH = 302, - SFX_DRAGON_GROWL_3 = 303, - SFX_DRAGON_GRUNT = 304, - SFX_DRAGON_FIRE = 305, - SFX_DRAGON_LEG_LIFT = 306, - SFX_DRAGON_LEG_HIT = 307, - SFX_WARRIOR_BLADE_SWING_3 = 308, - SFX_WARRIOR_BLADE_SWING_FAST = 309, - SFX_WARRIOR_BREATH_ACTIVE = 311, - SFX_WARRIOR_HOVER = 312, - SFX_WARRIOR_LANDING = 313, - SFX_WARRIOR_SWORD_CLANK = 314, - SFX_WARRIOR_SWORD_SLICE = 315, - SFX_BIRDS_CHIRP = 316, - SFX_CRUNCH_1 = 317, - SFX_CRUNCH_2 = 318, - SFX_DOOR_CREAK = 319, - SFX_BREAKING_3 = 320, - SFX_BIG_SPIDER_SNARL = 321, - SFX_BIG_SPIDER_FEET = 322, - SFX_BIG_SPIDER_DEATH = 323, - SFX_T_REX_ROAR = 324, - SFX_T_REX_FEET = 325, - SFX_T_REX_GROWL_1 = 326, - SFX_T_REX_DEATH = 327, - SFX_DRIPS_REVERB = 329, - SFX_STAGE_BACKDROP = 330, - SFX_STONE_DOOR_SLIDE = 331, - SFX_PLATFORM_ALARM = 332, - SFX_TICK_TOCK = 333, - SFX_DOORBELL = 334, - SFX_BURGLAR_ALARM = 335, - SFX_BOAT_ENGINE = 336, - SFX_BOAT_INTO_WATER = 337, - SFX_UNKNOWN_1 = 338, - SFX_UNKNOWN_2 = 339, - SFX_UNKNOWN_3 = 340, - SFX_MARCO_BARTOLLI_TRANSFORM = 341, - SFX_WINSTON_SHUFFLE = 342, - SFX_WINSTON_FEET = 343, - SFX_WINSTON_GRUNT_1 = 344, - SFX_WINSTON_GRUNT_2 = 345, - SFX_WINSTON_GRUNT_3 = 346, - SFX_WINSTON_CUPS = 347, - SFX_BRITTLE_GROUND_BREAK = 348, - SFX_SPIDER_EXPLODE = 349, - SFX_SHARK_BITE = 350, - SFX_LAVA_BUBBLES = 351, - SFX_EXPLOSION_2 = 352, - SFX_BURGLARS = 353, - SFX_ZIPPER = 354, - SFX_NUMBER_OF = 370, -} SOUND_EFFECT_ID; - -typedef enum { - SPM_NORMAL = 0, - SPM_UNDERWATER = 1, - SPM_ALWAYS = 2, - SPM_PITCH = 4, -} SOUND_PLAY_MODE; - -typedef enum { - CF_NORMAL = 0, - CF_FOLLOW_CENTRE = 1, - CF_NO_CHUNKY = 2, - CF_CHASE_OBJECT = 3, -} CAMERA_FLAGS; - -typedef enum { - FBBOX_MIN_X = 0, - FBBOX_MAX_X = 1, - FBBOX_MIN_Y = 2, - FBBOX_MAX_Y = 3, - FBBOX_MIN_Z = 4, - FBBOX_MAX_Z = 5, - FBBOX_X = 6, - FBBOX_Y = 7, - FBBOX_Z = 8, - FBBOX_ROT = 9, -} FRAME_BBOX_INFO; - -typedef enum { - BF_MATRIX_POP = 1, - BF_MATRIX_PUSH = 2, - BF_ROT_X = 4, - BF_ROT_Y = 8, - BF_ROT_Z = 16, -} BONE_FLAGS; - -typedef struct __unaligned { - int16_t tx; - int16_t ty; - int16_t tz; - int16_t cx; - int16_t cy; - int16_t cz; - int16_t fov; - int16_t roll; -} CINE_FRAME; - -typedef struct __unaligned { - uint16_t key[14]; // INPUT_ROLE_NUMBER_OF -} CONTROL_LAYOUT; - -typedef enum { - MX_INACTIVE = -1, - MX_UNUSED_0 = 0, // 2.mp3 - MX_UNUSED_1 = 1, // 2.mp3 - MX_CUTSCENE_THE_GREAT_WALL = 2, // 2.mp3 - MX_UNUSED_2 = 3, // 2.mp3 - MX_CUTSCENE_OPERA_HOUSE = 4, // 3.mp3 - MX_CUTSCENE_BROTHER_CHAN = 5, // 4.mp3 - MX_GYM_HINT_1 = 6, // 5.mp3 - MX_GYM_HINT_2 = 7, // 6.mp3 - MX_GYM_HINT_3 = 8, // 7.mp3 - MX_GYM_HINT_4 = 9, // 8.mp3 - MX_GYM_HINT_5 = 10, // 9.mp3 - MX_GYM_HINT_6 = 11, // 10.mp3 - MX_GYM_HINT_7 = 12, // 11.mp3 - MX_GYM_HINT_8 = 13, // 12.mp3 - MX_GYM_HINT_9 = 14, // 13.mp3 - MX_GYM_HINT_10 = 15, // 14.mp3 - MX_GYM_HINT_11 = 16, // 15.mp3 - MX_GYM_HINT_12 = 17, // 16.mp3 - MX_GYM_HINT_13 = 18, // 17.mp3 - MX_GYM_HINT_14 = 19, // 18.mp3 - MX_UNUSED_3 = 20, // 18.mp3 - MX_UNUSED_4 = 21, // 18.mp3 - MX_GYM_HINT_15 = 22, // 19.mp3 - MX_GYM_HINT_16 = 23, // 20.mp3 - MX_GYM_HINT_17 = 24, // 21.mp3 - MX_GYM_HINT_18 = 25, // 22.mp3 - MX_UNUSED_5 = 26, // 23.mp3 - MX_CUTSCENE_BATH = 27, // 23.mp3 - MX_DAGGER_PULL = 28, // 24.mp3 - MX_GYM_HINT_20 = 29, // 25.mp3 - MX_CUTSCENE_XIAN = 30, // 26.mp3 - MX_CAVES_AMBIENCE = 31, // 27.mp3 - MX_SEWERS_AMBIENCE = 32, // 28.mp3 - MX_WINDY_AMBIENCE = 33, // 29.mp3 - MX_HEARTBEAT_AMBIENCE = 34, // 30.mp3 - MX_SURPRISE_1 = 35, // 31.mp3 - MX_SURPRISE_2 = 36, // 32.mp3 - MX_SURPRISE_3 = 37, // 33.mp3 - MX_OOH_AAH_1 = 38, // 34.mp3 - MX_OOH_AAH_2 = 39, // 35.mp3 - MX_VENICE_VIOLINS = 40, // 36.mp3 - MX_END_OF_LEVEL = 41, // 37.mp3 - MX_SPOOKY_1 = 42, // 38.mp3 - MX_SPOOKY_2 = 43, // 39.mp3 - MX_SPOOKY_3 = 44, // 40.mp3 - MX_HARP_THEME = 45, // 41.mp3 - MX_MYSTERY_1 = 46, // 42.mp3 - MX_SECRET = 47, // 43.mp3 - MX_AMBUSH_1 = 48, // 44.mp3 - MX_AMBUSH_2 = 49, // 45.mp3 - MX_AMBUSH_3 = 50, // 46.mp3 - MX_AMBUSH_4 = 51, // 47.mp3 - MX_SKIDOO_THEME = 52, // 48.mp3 - MX_BATTLE_THEME = 53, // 49.mp3 - MX_MYSTERY_2 = 54, // 50.mp3 - MX_MYSTERY_3 = 55, // 51.mp3 - MX_MYSTERY_4 = 56, // 52.mp3 - MX_MYSTERY_5 = 57, // 53.mp3 - MX_RIG_AMBIENCE = 58, // 54.mp3 - MX_TOMB_AMBIENCE = 59, // 55.mp3 - MX_OOH_AAH_3 = 60, // 56.mp3 - MX_REVEAL_1 = 61, // 57.mp3 - MX_CUTSCENE_RIG = 62, // 58.mp3 - MX_REVEAL_2 = 63, // 59.mp3 - MX_TITLE_THEME = 64, // 60.mp3 - MX_UNUSED_6 = 65, // 61.mp3 -} MUSIC_TRACK_ID; - -typedef enum { - COLL_NONE = 0x00, - COLL_FRONT = 0x01, - COLL_LEFT = 0x02, - COLL_RIGHT = 0x04, - COLL_TOP = 0x08, - COLL_TOP_FRONT = 0x10, - COLL_CLAMP = 0x20, -} COLL_TYPE; - -typedef enum { - HT_WALL = 0, - HT_SMALL_SLOPE = 1, - HT_BIG_SLOPE = 2, -} HEIGHT_TYPE; - -typedef struct __unaligned { - uint16_t x; - uint16_t y; -} XGEN_X; - -typedef struct __unaligned { - int32_t x1; - int32_t x2; -} XBUF_X; - -typedef struct __unaligned { - int16_t x; - int16_t y; - int16_t g; -} XGEN_XG; - -typedef struct __unaligned { - int32_t x1; - int32_t g1; - int32_t x2; - int32_t g2; -} XBUF_XG; - -typedef struct __unaligned { - uint16_t x; - uint16_t y; - uint16_t g; - uint16_t u; - uint16_t v; -} XGEN_XGUV; - -typedef struct __unaligned { - int32_t x1; - int32_t g1; - int32_t u1; - int32_t v1; - int32_t x2; - int32_t g2; - int32_t u2; - int32_t v2; -} XBUF_XGUV; - -typedef struct __unaligned { - uint16_t x; - uint16_t y; - uint16_t g; - float rhw; - float u; - float v; -} XGEN_XGUVP; - -typedef struct __unaligned { - int32_t x1; - int32_t g1; - float u1; - float v1; - float rhw1; - int32_t x2; - int32_t g2; - float u2; - float v2; - float rhw2; -} XBUF_XGUVP; - -typedef struct __unaligned { - uint8_t manufacturer; - uint8_t version; - uint8_t rle; - uint8_t bpp; - uint16_t x_min; - uint16_t y_min; - uint16_t x_max; - uint16_t y_max; - uint16_t h_dpi; - uint16_t v_dpi; - RGB_888 palette[16]; - uint8_t reserved; - uint8_t planes; - uint16_t bytes_per_line; - uint16_t pal_pnterpret; - uint16_t h_res; - uint16_t v_res; - uint8_t reserved_data[54]; -} PCX_HEADER; - -typedef struct __unaligned { - uint8_t id_length; - uint8_t color_map_type; - uint8_t data_type_code; - uint16_t color_map_origin; - uint16_t color_map_length; - uint8_t color_map_depth; - uint16_t x_origin; - uint16_t y_origin; - uint16_t width; - uint16_t height; - uint8_t bpp; - uint8_t image_descriptor; -} TGA_HEADER; - -typedef struct __unaligned { - int16_t number; - int16_t volume; - int16_t randomness; - int16_t flags; -} SAMPLE_INFO; - -/* -typedef struct __unaligned { - int32_t volume; - int32_t pan; - int32_t sample_num; - int32_t pitch; -} SOUND_SLOT; -*/ - -typedef enum { - SF_FLIP = 0x40, - SF_UNFLIP = 0x80, -} SOUND_FLAG; - -typedef enum { - CLRB_PRIMARY_BUFFER = 0x0001, - CLRB_BACK_BUFFER = 0x0002, - CLRB_THIRD_BUFFER = 0x0004, - CLRB_Z_BUFFER = 0x0008, - CLRB_RENDER_BUFFER = 0x0010, - CLRB_PICTURE_BUFFER = 0x0020, - CLRB_WINDOWED_PRIMARY_BUFFER = 0x0040, - CLRB_RESERVED = 0x0080, - CLRB_PHDWINSIZE = 0x0100, -} CLEAR_BUFFER_FLAGS; - -typedef enum { - AC_NULL = 0, - AC_MOVE_ORIGIN = 1, - AC_JUMP_VELOCITY = 2, - AC_ATTACK_READY = 3, - AC_DEACTIVATE = 4, - AC_SOUND_FX = 5, - AC_EFFECT = 6, -} ANIM_COMMAND; - -typedef enum { - ACE_ALL = 0, - ACE_LAND = 1, - ACE_WATER = 2, -} ANIM_COMMAND_ENVIRONMENT; - -typedef struct __unaligned { - DDPIXELFORMAT pixel_fmt; - COLOR_BIT_MASKS color_bit_masks; - DWORD bpp; -} TEXTURE_FORMAT; - -typedef struct __unaligned { - int32_t boat_turn; - int32_t left_fallspeed; - int32_t right_fallspeed; - int16_t tilt_angle; - int16_t extra_rotation; - int32_t water; - int32_t pitch; -} BOAT_INFO; - -typedef struct __unaligned { - int16_t track_mesh; - int32_t skidoo_turn; - int32_t left_fallspeed; - int32_t right_fallspeed; - int16_t momentum_angle; - int16_t extra_rotation; - int32_t pitch; -} SKIDOO_INFO; - -typedef struct __unaligned { - struct { - XYZ_16 min; - XYZ_16 max; - } shift, rot; -} OBJECT_BOUNDS; - -typedef struct __unaligned { - int32_t xv; - int32_t yv; - int32_t zv; -} PORTAL_VBUF; - -typedef struct __unaligned { - BOUNDS_16 bounds; - XYZ_16 offset; - int16_t mesh_rots[]; -} FRAME_INFO; - -typedef enum { - GF_S_PC_DETAIL_LEVELS = 0, - GF_S_PC_DEMO_MODE = 1, - GF_S_PC_SOUND = 2, - GF_S_PC_CONTROLS = 3, - GF_S_PC_GAMMA = 4, - GF_S_PC_SET_VOLUMES = 5, - GF_S_PC_USER_KEYS = 6, - GF_S_PC_SAVE_FILE_WARNING = 7, - GF_S_PC_TRY_AGAIN_QUESTION = 8, - GF_S_PC_YES = 9, - GF_S_PC_NO = 10, - GF_S_PC_SAVE_COMPLETE = 11, - GF_S_PC_NO_SAVE_GAMES = 12, - GF_S_PC_NONE_VALID = 13, - GF_S_PC_SAVE_GAME_QUESTION = 14, - GF_S_PC_EMPTY_SLOT = 15, - GF_S_PC_OFF = 16, - GF_S_PC_ON = 17, - GF_S_PC_SETUP_SOUND_CARD = 18, - GF_S_PC_DEFAULT_KEYS = 19, - GF_S_PC_DOZY = 20, - GF_S_PC_NUMBER_OF = 41, -} GF_PC_STRING; - -typedef enum { - GF_S_GAME_HEADING_INVENTORY = 0, - GF_S_GAME_HEADING_OPTION = 1, - GF_S_GAME_HEADING_ITEMS = 2, - GF_S_GAME_HEADING_GAME_OVER = 3, - GF_S_GAME_PASSPORT_LOAD_GAME = 4, - GF_S_GAME_PASSPORT_SAVE_GAME = 5, - GF_S_GAME_PASSPORT_NEW_GAME = 6, - GF_S_GAME_PASSPORT_RESTART_LEVEL = 7, - GF_S_GAME_PASSPORT_EXIT_TO_TITLE = 8, - GF_S_GAME_PASSPORT_EXIT_DEMO = 9, - GF_S_GAME_PASSPORT_EXIT_GAME = 10, - GF_S_GAME_PASSPORT_SELECT_LEVEL = 11, - GF_S_GAME_PASSPORT_SAVE_POSITION = 12, - GF_S_GAME_DETAIL_SELECT_DETAIL = 13, - GF_S_GAME_DETAIL_HIGH = 14, - GF_S_GAME_DETAIL_MEDIUM = 15, - GF_S_GAME_DETAIL_LOW = 16, - GF_S_GAME_KEYMAP_WALK = 17, - GF_S_GAME_KEYMAP_ROLL = 18, - GF_S_GAME_KEYMAP_RUN = 19, - GF_S_GAME_KEYMAP_LEFT = 20, - GF_S_GAME_KEYMAP_RIGHT = 21, - GF_S_GAME_KEYMAP_BACK = 22, - GF_S_GAME_KEYMAP_STEP_LEFT = 23, - GF_S_GAME_KEYMAP_RESERVED_1 = 24, - GF_S_GAME_KEYMAP_STEP_RIGHT = 25, - GF_S_GAME_KEYMAP_RESERVED_2 = 26, - GF_S_GAME_KEYMAP_LOOK = 27, - GF_S_GAME_KEYMAP_JUMP = 28, - GF_S_GAME_KEYMAP_ACTION = 29, - GF_S_GAME_KEYMAP_DRAW_WEAPON = 30, - GF_S_GAME_KEYMAP_RESERVED_3 = 31, - GF_S_GAME_KEYMAP_INVENTORY = 32, - GF_S_GAME_KEYMAP_FLARE = 33, - GF_S_GAME_KEYMAP_STEP = 34, - GF_S_GAME_INV_ITEM_STATISTICS = 35, - GF_S_GAME_INV_ITEM_PISTOLS = 36, - GF_S_GAME_INV_ITEM_SHOTGUN = 37, - GF_S_GAME_INV_ITEM_MAGNUMS = 38, - GF_S_GAME_INV_ITEM_UZIS = 39, - GF_S_GAME_INV_ITEM_HARPOON = 40, - GF_S_GAME_INV_ITEM_M16 = 41, - GF_S_GAME_INV_ITEM_GRENADE = 42, - GF_S_GAME_INV_ITEM_FLARE = 43, - GF_S_GAME_INV_ITEM_PISTOL_AMMO = 44, - GF_S_GAME_INV_ITEM_SHOTGUN_AMMO = 45, - GF_S_GAME_INV_ITEM_MAGNUM_AMMO = 46, - GF_S_GAME_INV_ITEM_UZI_AMMO = 47, - GF_S_GAME_INV_ITEM_HARPOON_AMMO = 48, - GF_S_GAME_INV_ITEM_M16_AMMO = 49, - GF_S_GAME_INV_ITEM_GRENADE_AMMO = 50, - GF_S_GAME_INV_ITEM_SMALL_MEDIPACK = 51, - GF_S_GAME_INV_ITEM_LARGE_MEDIPACK = 52, - GF_S_GAME_INV_ITEM_PICKUP = 53, - GF_S_GAME_INV_ITEM_PUZZLE = 54, - GF_S_GAME_INV_ITEM_KEY = 55, - GF_S_GAME_INV_ITEM_GAME = 56, - GF_S_GAME_INV_ITEM_LARA_HOME = 57, - GF_S_GAME_MISC_LOADING = 58, - GF_S_GAME_MISC_TIME_TAKEN = 59, - GF_S_GAME_MISC_SECRETS_FOUND = 60, - GF_S_GAME_MISC_LOCATION = 61, - GF_S_GAME_MISC_KILLS = 62, - GF_S_GAME_MISC_AMMO_USED = 63, - GF_S_GAME_MISC_HITS = 64, - GF_S_GAME_MISC_SAVES_PERFORMED = 65, - GF_S_GAME_MISC_DISTANCE_TRAVELLED = 66, - GF_S_GAME_MISC_HEALTH_PACKS_USED = 67, - GF_S_GAME_MISC_RELEASE_VERSION = 68, - GF_S_GAME_MISC_NONE = 69, - GF_S_GAME_MISC_FINISH = 70, - GF_S_GAME_MISC_BEST_TIMES = 71, - GF_S_GAME_MISC_NO_TIMES_SET = 72, - GF_S_GAME_MISC_NA = 73, - GF_S_GAME_MISC_CURRENT_POSITION = 74, - GF_S_GAME_MISC_FINAL_STATISTICS = 75, - GF_S_GAME_MISC_OF = 76, - GF_S_GAME_MISC_STORY_SO_FAR = 77, - GF_S_GAME_NUMBER_OF = 89, -} GF_GAME_STRING; - -typedef enum { - GF_ADD_INV_PISTOLS = 0, - GF_ADD_INV_SHOTGUN = 1, - GF_ADD_INV_MAGNUMS = 2, - GF_ADD_INV_UZIS = 3, - GF_ADD_INV_HARPOON = 4, - GF_ADD_INV_M16 = 5, - GF_ADD_INV_GRENADE = 6, - GF_ADD_INV_PISTOL_AMMO = 7, - GF_ADD_INV_SHOTGUN_AMMO = 8, - GF_ADD_INV_MAGNUM_AMMO = 9, - GF_ADD_INV_UZI_AMMO = 10, - GF_ADD_INV_HARPOON_AMMO = 11, - GF_ADD_INV_M16_AMMO = 12, - GF_ADD_INV_GRENADE_AMMO = 13, - GF_ADD_INV_FLARES = 14, - GF_ADD_INV_SMALL_MEDI = 15, - GF_ADD_INV_LARGE_MEDI = 16, - GF_ADD_INV_PICKUP_1 = 17, - GF_ADD_INV_PICKUP_2 = 18, - GF_ADD_INV_PUZZLE_1 = 19, - GF_ADD_INV_PUZZLE_2 = 20, - GF_ADD_INV_PUZZLE_3 = 21, - GF_ADD_INV_PUZZLE_4 = 22, - GF_ADD_INV_KEY_1 = 23, - GF_ADD_INV_KEY_2 = 24, - GF_ADD_INV_KEY_3 = 25, - GF_ADD_INV_KEY_4 = 26, - GF_ADD_INV_NUMBER_OF = 27, -} GF_ADD_INV; - -typedef enum { - IT_NAME = 0, - IT_QTY = 1, - IT_NUMBER_OF = 2, -} INV_TEXT; - -typedef enum { - REQ_CENTER = 0x00, - REQ_USE = 0x01, - REQ_ALIGN_LEFT = 0x02, - REQ_ALIGN_RIGHT = 0x04, - REQ_HEADING = 0x08, - REQ_BEST_TIME = 0x10, - REQ_NORMAL_TIME = 0x20, - REQ_NO_TIME = 0x40, -} REQUESTER_FLAGS; - -// clang-format on - -#pragma pack(pop) diff --git a/src/tr2/global/types_decomp.h b/src/tr2/global/types_decomp.h new file mode 100644 index 000000000..4473c9bcd --- /dev/null +++ b/src/tr2/global/types_decomp.h @@ -0,0 +1,1506 @@ +// This file is autogenerated. To update it, run tools/generate_funcs. + +#pragma once + +#include "const.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#pragma pack(push, 1) + +// clang-format off +typedef int16_t PHD_ANGLE; + +typedef struct __unaligned { + int32_t _00; + int32_t _01; + int32_t _02; + int32_t _03; + int32_t _10; + int32_t _11; + int32_t _12; + int32_t _13; + int32_t _20; + int32_t _21; + int32_t _22; + int32_t _23; +} MATRIX; + +typedef enum { + VGA_NO_VGA = 0, + VGA_256_COLOR = 1, + VGA_MODEX = 2, + VGA_STANDARD = 3, +} VGA_MODE; + +typedef struct __unaligned { + LPBITMAPINFO bmp_info; + void *bmp_data; + HPALETTE hPalette; + DWORD flags; +} BITMAP_RESOURCE; + +typedef enum { + RM_UNKNOWN = 0, + RM_SOFTWARE = 1, + RM_HARDWARE = 2, +} RENDER_MODE; + +typedef enum { + AM_4_3 = 0, + AM_16_9 = 1, + AM_ANY = 2, +} ASPECT_MODE; + +typedef enum { + TAM_DISABLED = 0, + TAM_BILINEAR_ONLY = 1, + TAM_ALWAYS = 2, +} TEXEL_ADJUST_MODE; + +typedef struct __unaligned { + 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 { + 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 { + struct { + uint32_t r; + uint32_t g; + uint32_t b; + uint32_t a; + } mask, depth, offset; +} COLOR_BIT_MASKS; + +typedef struct __unaligned { + uint8_t index[256]; +} DEPTHQ_ENTRY; + +typedef struct __unaligned { + uint8_t index[32]; +} GOURAUD_ENTRY; + +typedef struct __unaligned { + XYZ_32 pos; + XYZ_16 rot; +} PHD_3DPOS; + +typedef struct __unaligned { + int32_t x; + int32_t y; + int32_t z; + int32_t r; +} SPHERE; + +typedef struct __unaligned { + float xv; + float yv; + float zv; + float rhw; + float xs; + float ys; + int16_t clip; + int16_t g; + int16_t u; + int16_t v; +} PHD_VBUF; + +typedef struct __unaligned { + uint16_t u; + uint16_t v; +} PHD_UV; + +typedef struct __unaligned { + uint16_t tex_page; + uint16_t offset; + uint16_t width; + uint16_t height; + int16_t x0; + int16_t y0; + int16_t x1; + int16_t y1; +} PHD_SPRITE; + +typedef enum { + SHAPE_SPRITE = 1, + SHAPE_LINE = 2, + SHAPE_BOX = 3, + SHAPE_FBOX = 4, +} SHAPE; + +typedef enum { + SPRF_RGB = 0x00FFFFFF, + SPRF_ABS = 0x01000000, + SPRF_SEMITRANS = 0x02000000, + SPRF_SCALE = 0x04000000, + SPRF_SHADE = 0x08000000, + SPRF_TINT = 0x10000000, + SPRF_BLEND_ADD = 0x20000000, + SPRF_BLEND_SUB = 0x40000000, + SPRF_BLEND_QRT = SPRF_BLEND_ADD | SPRF_BLEND_SUB, + SPRF_BLEND = SPRF_BLEND_QRT, + SPRF_ITEM = 0x80000000, +} SPRITE_FLAG; + +typedef struct __unaligned { + float xv; + float yv; + float zv; + float rhw; + float xs; + float ys; + float u; + float v; + float g; +} POINT_INFO; + +typedef struct __unaligned { + uint16_t no_selector : 1; + uint16_t ready : 1; // not present in the OG + uint16_t pad : 14; + uint16_t items_count; + uint16_t selected; + uint16_t visible_count; + uint16_t line_offset; + uint16_t line_old_offset; + uint16_t pix_width; + uint16_t line_height; + int16_t x_pos; + int16_t y_pos; + int16_t z_pos; + uint16_t item_string_len; + char *pitem_strings1; + char *pitem_strings2; + uint32_t *pitem_flags1; + uint32_t *pitem_flags2; + uint32_t heading_flags1; + uint32_t heading_flags2; + uint32_t background_flags; + uint32_t moreup_flags; + uint32_t moredown_flags; + uint32_t item_flags1[24]; // MAX_REQUESTER_ITEMS + uint32_t item_flags2[24]; // MAX_REQUESTER_ITEMS + TEXTSTRING *heading_text1; + TEXTSTRING *heading_text2; + TEXTSTRING *background_text; + TEXTSTRING *moreup_text; + TEXTSTRING *moredown_text; + TEXTSTRING *item_texts1[24]; // MAX_REQUESTER_ITEMS + TEXTSTRING *item_texts2[24]; // MAX_REQUESTER_ITEMS + char heading_string1[32]; + char heading_string2[32]; + uint32_t render_width; + uint32_t render_height; +} REQUEST_INFO; + +typedef enum { + POLY_GTMAP = 0, + POLY_WGTMAP = 1, + POLY_GTMAP_PERSP = 2, + POLY_WGTMAP_PERSP = 3, + POLY_LINE = 4, + POLY_FLAT = 5, + POLY_GOURAUD = 6, + POLY_TRANS = 7, + POLY_SPRITE = 8, + POLY_HWR_GTMAP = 9, + POLY_HWR_WGTMAP = 10, + POLY_HWR_GOURAUD = 11, + POLY_HWR_LINE = 12, + POLY_HWR_TRANS = 13, +} POLY_TYPE; + +typedef struct __unaligned { + uint32_t best_time[10]; + uint32_t best_finish[10]; + uint32_t finish_count; +} ASSAULT_STATS; + +typedef struct __unaligned { + int32_t _0; + int32_t _1; +} SORT_ITEM; + +typedef enum { + DRAW_OPAQUE = 0, + DRAW_COLOR_KEY = 1, +} DRAW_TYPE; + +typedef struct __unaligned { + int16_t mesh_idx; + uint16_t flags; + BOUNDS_16 draw_bounds; + BOUNDS_16 collision_bounds; +} STATIC_INFO; + +typedef struct __unaligned { + uint32_t timer; + uint32_t shots; + uint32_t hits; + uint32_t distance; + uint16_t kills; + uint8_t secrets; + uint8_t medipacks; +} STATISTICS_INFO; + +typedef struct __unaligned { + uint16_t pistol_ammo; + uint16_t magnum_ammo; + uint16_t uzi_ammo; + uint16_t shotgun_ammo; + uint16_t m16_ammo; + uint16_t grenade_ammo; + uint16_t harpoon_ammo; + uint8_t small_medipacks; + uint8_t large_medipacks; + uint8_t reserved1; + uint8_t flares; + uint8_t gun_status; + uint8_t gun_type; + uint16_t available: 1; // 0x01 1 + uint16_t has_pistols: 1; // 0x02 2 + uint16_t has_magnums: 1; // 0x04 4 + uint16_t has_uzis: 1; // 0x08 8 + uint16_t has_shotgun: 1; // 0x10 16 + uint16_t has_m16: 1; // 0x20 32 + uint16_t has_grenade: 1; // 0x40 64 + uint16_t has_harpoon: 1; // 0x80 128 + uint16_t pad : 8; + uint16_t reserved2; + STATISTICS_INFO statistics; +} START_INFO; + +typedef struct __unaligned { + START_INFO start[24]; + STATISTICS_INFO statistics; + int16_t current_level; + bool bonus_flag; + uint8_t num_pickup[2]; + uint8_t num_puzzle[4]; + uint8_t num_key[4]; + uint16_t reserved; + char buffer[6272]; // MAX_SG_BUFFER_SIZE +} SAVEGAME_INFO; + +typedef struct __unaligned { + int16_t lock_angles[4]; + int16_t left_angles[4]; + int16_t right_angles[4]; + int16_t aim_speed; + int16_t shot_accuracy; + int32_t gun_height; + int32_t damage; + int32_t target_dist; + int16_t recoil_frame; + int16_t flash_time; + int16_t sample_num; +} WEAPON_INFO; + +typedef struct __unaligned { + int16_t zone_num; + int16_t enemy_zone_num; + int32_t distance; + int32_t ahead; + int32_t bite; + int16_t angle; + int16_t enemy_facing; +} AI_INFO; + +typedef struct __unaligned { + int16_t timer; + int16_t sprite; +} PICKUP_INFO; + +typedef struct __unaligned { + int16_t shape; + XYZ_16 pos; + int32_t param1; + int32_t param2; + void *grdptr; + int16_t sprite_num; +} INVENTORY_SPRITE; + +typedef struct __unaligned { + char *string; + int16_t object_id; + int16_t frames_total; + int16_t current_frame; + int16_t goal_frame; + int16_t open_frame; + int16_t anim_direction; + int16_t anim_speed; + int16_t anim_count; + int16_t x_rot_pt_sel; + int16_t x_rot_pt; + int16_t x_rot_sel; + int16_t x_rot_nosel; + int16_t x_rot; + int16_t y_rot_sel; + int16_t y_rot; + int32_t y_trans_sel; + int32_t y_trans; + int32_t z_trans_sel; + int32_t z_trans; + uint32_t meshes_sel; + uint32_t meshes_drawn; + int16_t inv_pos; + INVENTORY_SPRITE **sprite_list; + int32_t reserved[4]; +} INVENTORY_ITEM; + +typedef enum { + RNG_OPENING = 0, + RNG_OPEN = 1, + RNG_CLOSING = 2, + RNG_MAIN2OPTION = 3, + RNG_MAIN2KEYS = 4, + RNG_KEYS2MAIN = 5, + RNG_OPTION2MAIN = 6, + RNG_SELECTING = 7, + RNG_SELECTED = 8, + RNG_DESELECTING = 9, + RNG_DESELECT = 10, + RNG_CLOSING_ITEM = 11, + RNG_EXITING_INVENTORY = 12, + RNG_DONE = 13, +} RING_STATUS; + +typedef struct __unaligned { + int16_t count; + int16_t status; + int16_t status_target; + int16_t radius_target; + int16_t radius_rate; + int16_t camera_y_target; + int16_t camera_y_rate; + int16_t camera_pitch_target; + int16_t camera_pitch_rate; + int16_t rotate_target; + int16_t rotate_rate; + int16_t item_pt_x_rot_target; + int16_t item_pt_x_rot_rate; + int16_t item_x_rot_target; + int16_t item_x_rot_rate; + int32_t item_y_trans_target; + int32_t item_y_trans_rate; + int32_t item_z_trans_target; + int32_t item_z_trans_rate; + int32_t misc; +} IMOTION_INFO; + +typedef enum { + PM_SPINE = 1, + PM_FRONT = 2, + PM_IN_FRONT = 4, + PM_PAGE_2 = 8, + PM_BACK = 16, + PM_IN_BACK = 32, + PM_PAGE_1 = 64, + PM_COMMON = PM_SPINE | PM_BACK | PM_FRONT, +} PASS_MESH; + +typedef struct __unaligned { + INVENTORY_ITEM **list; + int16_t type; + int16_t radius; + int16_t camera_pitch; + int16_t rotating; + int16_t rot_count; + int16_t current_object; + int16_t target_object; + int16_t number_of_objects; + int16_t angle_adder; + int16_t rot_adder; + int16_t rot_adder_l; + int16_t rot_adder_r; + PHD_3DPOS ring_pos; + PHD_3DPOS camera; + XYZ_32 light; + IMOTION_INFO *imo; +} RING_INFO; + +typedef enum { + GFE_PICTURE = 0, + GFE_LIST_START = 1, + GFE_LIST_END = 2, + GFE_PLAY_FMV = 3, + GFE_START_LEVEL = 4, + GFE_CUTSCENE = 5, + GFE_LEVEL_COMPLETE = 6, + GFE_DEMO_PLAY = 7, + GFE_JUMP_TO_SEQ = 8, + GFE_END_SEQ = 9, + GFE_SET_TRACK = 10, + GFE_SUNSET = 11, + GFE_LOADING_PIC = 12, + GFE_DEADLY_WATER = 13, + GFE_REMOVE_WEAPONS = 14, + GFE_GAME_COMPLETE = 15, + GFE_CUT_ANGLE = 16, + GFE_NO_FLOOR = 17, + GFE_ADD_TO_INV = 18, + GFE_START_ANIM = 19, + GFE_NUM_SECRETS = 20, + GFE_KILL_TO_COMPLETE = 21, + GFE_REMOVE_AMMO = 22, +} GF_EVENTS; + +typedef enum { + TARGET_NONE = 0, + TARGET_PRIMARY = 1, + TARGET_SECONDARY = 2, +} TARGET_TYPE; + +typedef struct __unaligned { + XYZ_32 pos; + int32_t mesh_num; +} BITE; + +typedef enum { + RF_UNDERWATER = 0x01, + RF_OUTSIDE = 0x08, + RF_DYNAMIC_LIT = 0x10, + RF_INSIDE = 0x40, +} ROOM_FLAG; + +typedef struct __unaligned { + SECTOR *sector; + SECTOR old_sector; + int16_t block; +} DOORPOS_DATA; + +typedef enum { + CAM_CHASE = 0, + CAM_FIXED = 1, + CAM_LOOK = 2, + CAM_COMBAT = 3, + CAM_CINEMATIC = 4, + CAM_HEAVY = 5, +} CAMERA_TYPE; + +typedef struct __unaligned { + union { + XYZ_32 pos; + struct { + int32_t x; + int32_t y; + int32_t z; + }; + }; + int16_t room_num; + int16_t box_num; +} GAME_VECTOR; + +typedef struct __unaligned { + union { + struct __unaligned { + int32_t x; + int32_t y; + int32_t z; + }; + XYZ_32 pos; + }; + int16_t data; + int16_t flags; +} OBJECT_VECTOR; + +typedef struct __unaligned { + uint8_t left; + uint8_t right; + uint8_t top; + uint8_t bottom; + int16_t height; + int16_t overlap_index; +} BOX_INFO; + +typedef enum { + LV_GYM = 0, + LV_FIRST = 1, +} LEVEL_TYPE; + +typedef enum { + RT_MAIN = 0, + RT_OPTION = 1, + RT_KEYS = 2, +} RING_TYPE; + +typedef enum { + INV_COLOR_BLACK = 0, + INV_COLOR_GRAY = 1, + INV_COLOR_WHITE = 2, + INV_COLOR_RED = 3, + INV_COLOR_ORANGE = 4, + INV_COLOR_YELLOW = 5, + INV_COLOR_DARK_GREEN = 12, + INV_COLOR_GREEN = 13, + INV_COLOR_CYAN = 14, + INV_COLOR_BLUE = 15, + INV_COLOR_MAGENTA = 16, + INV_COLOR_NUMBER_OF = 17, +} INV_COLOR; + +typedef enum { + INV_GAME_MODE = 0, + INV_TITLE_MODE = 1, + INV_KEYS_MODE = 2, + INV_SAVE_MODE = 3, + INV_LOAD_MODE = 4, + INV_DEATH_MODE = 5, +} INVENTORY_MODE; + +typedef enum { + GAMEMODE_NOT_IN_GAME, + GAMEMODE_IN_GAME, + GAMEMODE_IN_DEMO, + GAMEMODE_IN_CUTSCENE +} GAMEMODE; + +typedef enum { + TRAP_SET = 0, + TRAP_ACTIVATE = 1, + TRAP_WORKING = 2, + TRAP_FINISHED = 3, +} TRAP_ANIM; + +typedef enum { + GFD_START_GAME = 0x0000, + GFD_START_SAVED_GAME = 0x0100, + GFD_START_CINE = 0x0200, + GFD_START_FMV = 0x0300, + GFD_START_DEMO = 0x0400, + GFD_EXIT_TO_TITLE = 0x0500, + GFD_LEVEL_COMPLETE = 0x0600, + GFD_EXIT_GAME = 0x0700, + GFD_EXIT_TO_OPTION = 0x0800, + GFD_TITLE_DESELECT = 0x0900, + GFD_OVERRIDE = 0x0A00, +} GAME_FLOW_DIR; + +typedef struct __unaligned { + int32_t first_option; + int32_t title_replace; + int32_t on_death_demo_mode; + int32_t on_death_in_game; + int32_t no_input_time; + int32_t on_demo_interrupt; + int32_t on_demo_end; + uint16_t reserved1[18]; + uint16_t num_levels; + uint16_t num_pictures; + uint16_t num_titles; + uint16_t num_fmvs; + uint16_t num_cutscenes; + uint16_t num_demos; + uint16_t title_track; + int16_t single_level; + uint16_t reserved2[16]; + + uint16_t demo_version: 1; // 0x0001 + uint16_t title_disabled: 1; // 0x0002 + uint16_t cheat_mode_check_disabled: 1; // 0x0004 + uint16_t no_input_timeout: 1; // 0x0008 + uint16_t load_save_disabled: 1; // 0x0010 + uint16_t screen_sizing_disabled: 1; // 0x0020 + uint16_t lockout_option_ring: 1; // 0x0040 + uint16_t dozy_cheat_enabled: 1; // 0x0080 + uint16_t cyphered_strings: 1; // 0x0100 + uint16_t gym_enabled: 1; // 0x0200 + uint16_t play_any_level: 1; // 0x0400 + uint16_t cheat_enable: 1; // 0x0800 + + uint16_t reserved3[3]; + uint8_t cypher_code; + uint8_t language; + uint8_t secret_track; + uint8_t level_complete_track; + uint16_t reserved4[2]; +} GAME_FLOW; + +typedef struct __unaligned { + GAME_VECTOR pos; + GAME_VECTOR target; + CAMERA_TYPE type; + int32_t shift; + uint32_t flags; + int32_t fixed_camera; + int32_t num_frames; + int32_t bounce; + int32_t underwater; + int32_t target_distance; + int32_t target_square; + int16_t target_angle; + int16_t actual_angle; + int16_t target_elevation; + int16_t box; + int16_t num; + int16_t last; + int16_t timer; + int16_t speed; + ITEM *item; + ITEM *last_item; + OBJECT_VECTOR *fixed; + int32_t is_lara_mic; + XYZ_32 mic_pos; +} CAMERA_INFO; + +typedef enum { + SFX_LARA_FEET = 0, + SFX_LARA_CLIMB_2 = 1, + SFX_LARA_NO = 2, + SFX_LARA_SLIPPING = 3, + SFX_LARA_LAND = 4, + SFX_LARA_CLIMB_1 = 5, + SFX_LARA_DRAW = 6, + SFX_LARA_HOLSTER = 7, + SFX_LARA_FIRE = 8, + SFX_LARA_RELOAD = 9, + SFX_LARA_RICOCHET = 10, + SFX_LARA_FLARE_IGNITE = 11, + SFX_LARA_FLARE_BURN = 12, + SFX_LARA_HARPOON_FIRE = 15, + SFX_LARA_HARPOON_LOAD = 16, + SFX_LARA_WET_FEET = 17, + SFX_LARA_WADE = 18, + SFX_LARA_TREAD = 20, + SFX_LARA_FIRE_MAGNUMS = 21, + SFX_LARA_HARPOON_LOAD_WATER = 22, + SFX_LARA_HARPOON_FIRE_WATER = 23, + SFX_MASSIVE_CRASH = 24, + SFX_PUSH_SWITCH = 25, + SFX_LARA_CLIMB_3 = 26, + SFX_LARA_BODYSL = 27, + SFX_LARA_SHIMMY = 28, + SFX_LARA_JUMP = 29, + SFX_LARA_FALL = 30, + SFX_LARA_INJURY = 31, + SFX_LARA_ROLL = 32, + SFX_LARA_SPLASH = 33, + SFX_LARA_GETOUT = 34, + SFX_LARA_SWIM = 35, + SFX_LARA_BREATH = 36, + SFX_LARA_BUBBLES = 37, + SFX_LARA_SWITCH = 38, + SFX_LARA_KEY = 39, + SFX_LARA_OBJECT = 40, + SFX_LARA_GENERAL_DEATH = 41, + SFX_LARA_KNEES_DEATH = 42, + SFX_LARA_UZI_FIRE = 43, + SFX_LARA_UZI_STOP = 44, + SFX_LARA_SHOTGUN = 45, + SFX_LARA_BLOCK_PUSH_1 = 46, + SFX_LARA_BLOCK_PUSH_2 = 47, + SFX_CLICK = 48, + SFX_LARA_HIT = 49, + SFX_LARA_BULLETHIT = 50, + SFX_LARA_BLKPULL = 51, + SFX_LARA_FLOATING = 52, + SFX_LARA_FALLDETH = 53, + SFX_LARA_GRABHAND = 54, + SFX_LARA_GRABBODY = 55, + SFX_LARA_GRABFEET = 56, + SFX_LARA_SWITCHUP = 57, + SFX_GLASS_BREAK = 58, + SFX_WATER_LOOP = 59, + SFX_UNDERWATER = 60, + SFX_UNDERWATER_SWITCH = 61, + SFX_LARA_PICKUP = 62, + SFX_BLOCK_SOUND = 63, + SFX_DOOR = 64, + SFX_SWING = 65, + SFX_ROCK_FALL_CRUMBLE = 66, + SFX_ROCK_FALL_LAND = 67, + SFX_ROCK_FALL_SOLID = 68, + SFX_ENEMY_FEET = 69, + SFX_ENEMY_GRUNT = 70, + SFX_ENEMY_HIT_1 = 71, + SFX_ENEMY_HIT_2 = 72, + SFX_ENEMY_DEATH_1 = 73, + SFX_ENEMY_JUMP = 74, + SFX_ENEMY_CLIMBUP = 75, + SFX_ENEMY_CLIMBDOWN = 76, + SFX_WEAPON_CLATTER = 77, + SFX_M16_FIRE = 78, + SFX_WATERFALL_LOOP = 79, + SFX_SWORD_STATUE_DROP = 80, + SFX_SWORD_STATUE_LIFT = 81, + SFX_PORTCULLIS_UP = 82, + SFX_PORTCULLIS_DOWN = 83, + SFX_DOG_FEET_1 = 84, + SFX_BODY_SLAM = 85, + SFX_DOG_BARK_1 = 86, + SFX_DOG_FEET_2 = 87, + SFX_DOG_BARK_2 = 88, + SFX_DOG_DEATH = 89, + SFX_DOG_PANT = 90, + SFX_LEOPARD_FEET = 91, + SFX_LEOPARD_ROAR = 92, + SFX_LEOPARD_BITE = 93, + SFX_LEOPARD_STRIKE = 94, + SFX_LEOPARD_DEATH = 95, + SFX_LEOPARD_GROWL = 96, + SFX_RAT_ATTACK = 97, + SFX_RAT_DEATH = 98, + SFX_TIGER_ROAR = 99, + SFX_TIGER_BITE = 100, + SFX_TIGER_STRIKE = 101, + SFX_TIGER_DEATH = 102, + SFX_TIGER_GROWL = 103, + SFX_M16_STOP = 104, + SFX_EXPLOSION_1 = 105, + SFX_GROWL = 106, + SFX_SPIDER_JUMP = 107, + SFX_MENU_ROTATE = 108, + SFX_MENU_LARA_HOME = 109, + SFX_MENU_SPININ = 111, + SFX_MENU_SPINOUT = 112, + SFX_MENU_STOPWATCH = 113, + SFX_MENU_GUNS = 114, + SFX_MENU_PASSPORT = 115, + SFX_MENU_MEDI = 116, + SFX_ENEMY_HEELS = 117, + SFX_ENEMY_FIRE_SILENCER = 118, + SFX_ENEMY_AH_DYING = 119, + SFX_ENEMY_OOH_DYING = 120, + SFX_ENEMY_THUMP = 121, + SFX_SPIDER_MOVING = 122, + SFX_LARA_MINI_LOAD = 123, + SFX_LARA_MINI_LOCK = 124, + SFX_LARA_MINI_FIRE = 125, + SFX_SPIDER_BITE = 126, + SFX_SLAM_DOOR_SLIDE = 127, + SFX_SLAM_DOOR_CLOSE = 128, + SFX_EAGLE_SQUAWK = 129, + SFX_EAGLE_WING_FLAP = 130, + SFX_EAGLE_DEATH = 131, + SFX_CROW_CAW = 132, + SFX_CROW_WING_FLAP = 133, + SFX_CROW_DEATH = 134, + SFX_CROW_ATTACK = 135, + SFX_ENEMY_GUN_COCKING = 136, + SFX_ENEMY_FIRE_1 = 137, + SFX_ENEMY_FIRE_TWIRL = 138, + SFX_ENEMY_HOLSTER = 139, + SFX_ENEMY_BREATH_1 = 140, + SFX_ENEMY_CHUCKLE = 141, + SFX_MONK_POY = 142, + SFX_MONK_DEATH = 143, + SFX_LARA_SPIKE_DEATH = 145, + SFX_LARA_DEATH_3 = 146, + SFX_ROLLING_BALL = 147, + SFX_SANDBAG_SNAP = 148, + SFX_SANDBAG_HIT = 149, + SFX_LOOP_FOR_SMALL_FIRES = 150, + SFX_SKIDOO_START = 152, + SFX_SKIDOO_IDLE = 153, + SFX_SKIDOO_ACCELERATE = 154, + SFX_SKIDOO_MOVING = 155, + SFX_SKIDOO_STOP = 156, + SFX_ENEMY_FIRE_2 = 157, + SFX_ENEMY_DEATH_2 = 158, + SFX_ENEMY_BREATH_2 = 159, + SFX_STICK_TAP = 160, + SFX_TRAPDOOR_OPEN = 161, + SFX_TRAPDOOR_CLOSE = 162, + SFX_YETI_GROWL = 163, + SFX_YETI_CHEST_BEAT = 164, + SFX_YETI_THUMP = 165, + SFX_YETI_GRUNT_1 = 166, + SFX_YETI_SCREAM = 167, + SFX_YETI_DEATH = 168, + SFX_YETI_GROWL_1 = 169, + SFX_YETI_GROWL_2 = 170, + SFX_YETI_GRUNT_2 = 171, + SFX_YETI_GROWL_3 = 172, + SFX_YETI_FEET = 173, + SFX_ENEMY_HEAVY_BREATH = 174, + SFX_ENEMY_FLAMETHROWER_FIRE = 175, + SFX_ENEMY_FLAMETHROWER_SCRAPE = 176, + SFX_ENEMY_FLAMETHROWER_CLICK = 177, + SFX_ENEMY_FLAMETHROWER_DEATH = 178, + SFX_ENEMY_FLAMETHROWER_FALL = 179, + SFX_ENEMY_BELT_JINGLE = 180, + SFX_ENEMY_WRENCH = 181, + SFX_FOOTSTEP = 182, + SFX_FOOTSTEP_HIT = 183, + SFX_ENEMY_COCKING_SHOTGUN = 184, + SFX_SCUBA_DIVER_FLIPPER = 186, + SFX_SCUBA_DIVER_BREATH = 188, + SFX_PULLEY_CRANE = 190, + SFX_CURTAIN = 191, + SFX_SCUBA_DIVER_DEATH = 192, + SFX_SCUBA_DIVER_DIVING = 193, + SFX_BOAT_START = 194, + SFX_BOAT_IDLE = 195, + SFX_BOAT_ACCELERATE = 196, + SFX_BOAT_MOVING = 197, + SFX_BOAT_STOP = 198, + SFX_BOAT_SLOW_DOWN = 199, + SFX_BOAT_HIT = 200, + SFX_CLATTER_1 = 201, + SFX_CLATTER_2 = 202, + SFX_CLATTER_3 = 203, + SFX_DOOR_SLIDE = 204, + SFX_LARA_FLESH_WOUND = 205, + SFX_SAW_REVVING = 206, + SFX_SAW_STOP = 207, + SFX_DOOR_CHIME = 208, + SFX_CHAIN_CREAK_SNAP = 209, + SFX_SWINGING = 210, + SFX_BREAKING_1 = 211, + SFX_PULLEY_MOVE = 212, + SFX_AIRPLANE_IDLE = 213, + SFX_UNDERWATER_FAN_ON = 215, + SFX_SMALL_FAN_ON = 217, + SFX_SWINGING_BOX_BAG = 218, + SFX_JUMP_PAD_UP = 219, + SFX_JUMP_PAD_DOWN = 220, + SFX_BREAKING_2 = 221, + SFX_SNOWBALL_ROLL = 222, + SFX_SNOWBALL_STOP = 223, + SFX_ROLLING = 224, + SFX_ROLLING_STOP_1 = 225, + SFX_ROLLING_STOP_2 = 226, + SFX_ROLLING_2 = 227, + SFX_ROLLING_2_HIT = 228, + SFX_SIDE_BLADE_SWING = 229, + SFX_SIDE_BLADE_BACK = 230, + SFX_ROLLING_BLADE = 231, + SFX_ICILE_DETACH = 232, + SFX_ICICLE_HIT = 233, + SFX_ROTATING_HANDLE_LOOSE = 234, + SFX_ROTATING_HANDLE_TURN = 235, + SFX_ROTATING_HANDLE_OPEN = 236, + SFX_ROTATING_HANDLE_CREAK = 237, + SFX_MONK_FEET = 238, + SFX_MONK_SWORD_SWING_1 = 239, + SFX_MONK_SWORD_SWING_2 = 240, + SFX_MONK_SHOUT_1 = 241, + SFX_MONK_SHOUT_2 = 242, + SFX_MONK_SHOUT_3 = 243, + SFX_MONK_SHOUT_4 = 244, + SFX_MONK_CRUNCH = 245, + SFX_MONK_BREATH = 246, + SFX_SPLASH_SURFACE = 247, + SFX_WATERFALL_1 = 248, + SFX_ENEMY_FEET_SNOW = 249, + SFX_ENEMY_FIRE_3 = 250, + SFX_ENEMY_FIRE_SEMIAUTO = 251, + SFX_ENEMY_DEATH_3 = 252, + SFX_ENEMY_DEATH_4 = 253, + SFX_CIRCLE_BLADE = 254, + SFX_KNIFETHROWER_FEET = 255, + SFX_MONK_OYE = 256, + SFX_MONK_AWEH = 257, + SFX_CIRCLE_BLADE_HIT = 258, + SFX_KNIFETHROWER_WARRIOR_FEET = 259, + SFX_WARRIOR_BLADE_SWING_1 = 260, + SFX_WARRIOR_BLADE_SWING_2 = 261, + SFX_WARRIOR_GROWL = 262, + SFX_KNIFETHROWER_HICCUP = 263, + SFX_WARROPR_BURP = 264, + SFX_WARRIOR_GROWL_1 = 265, + SFX_WARRIOR_WAKE = 267, + SFX_WARRIOR_GROWL_2 = 268, + SFX_SMALL_SWITCH = 269, + SFX_CHAIN_PULLEY = 278, + SFX_ZIPLINE_GRAB = 279, + SFX_ZIPLINE_GO = 280, + SFX_ZIPLINE_STOP = 281, + SFX_BODY_SLUMP = 282, + SFX_BOWL_TIPPING = 283, + SFX_BOWL_POUR = 284, + SFX_WATERFALL_2 = 285, + SFX_ELEVATOR_OPEN = 286, + SFX_ELEVATOR_CLOSE = 287, + SFX_MINISUB_CLATTER_1 = 288, + SFX_MINISUB_CLATTER_2 = 289, + SFX_MINISUB_CLATTER_3 = 290, + SFX_BIRD_MONSTER_SCREAM = 291, + SFX_BIRD_MONSTER_GASP = 292, + SFX_BIRD_MONSTER_BREATH = 293, + SFX_BIRD_MONSTER_FEET = 294, + SFX_BIRD_MONSTER_DEATH = 295, + SFX_BIRD_MONSTER_SCRAPE = 296, + SFX_HELICOPTER_LOOP = 297, + SFX_DRAGON_FEET = 298, + SFX_DRAGON_GROWL_1 = 299, + SFX_DRAGON_GROWL_2 = 300, + SFX_DRAGON_FALL = 301, + SFX_DRAGON_BREATH = 302, + SFX_DRAGON_GROWL_3 = 303, + SFX_DRAGON_GRUNT = 304, + SFX_DRAGON_FIRE = 305, + SFX_DRAGON_LEG_LIFT = 306, + SFX_DRAGON_LEG_HIT = 307, + SFX_WARRIOR_BLADE_SWING_3 = 308, + SFX_WARRIOR_BLADE_SWING_FAST = 309, + SFX_WARRIOR_BREATH_ACTIVE = 311, + SFX_WARRIOR_HOVER = 312, + SFX_WARRIOR_LANDING = 313, + SFX_WARRIOR_SWORD_CLANK = 314, + SFX_WARRIOR_SWORD_SLICE = 315, + SFX_BIRDS_CHIRP = 316, + SFX_CRUNCH_1 = 317, + SFX_CRUNCH_2 = 318, + SFX_DOOR_CREAK = 319, + SFX_BREAKING_3 = 320, + SFX_BIG_SPIDER_SNARL = 321, + SFX_BIG_SPIDER_FEET = 322, + SFX_BIG_SPIDER_DEATH = 323, + SFX_T_REX_ROAR = 324, + SFX_T_REX_FEET = 325, + SFX_T_REX_GROWL_1 = 326, + SFX_T_REX_DEATH = 327, + SFX_DRIPS_REVERB = 329, + SFX_STAGE_BACKDROP = 330, + SFX_STONE_DOOR_SLIDE = 331, + SFX_PLATFORM_ALARM = 332, + SFX_TICK_TOCK = 333, + SFX_DOORBELL = 334, + SFX_BURGLAR_ALARM = 335, + SFX_BOAT_ENGINE = 336, + SFX_BOAT_INTO_WATER = 337, + SFX_UNKNOWN_1 = 338, + SFX_UNKNOWN_2 = 339, + SFX_UNKNOWN_3 = 340, + SFX_MARCO_BARTOLLI_TRANSFORM = 341, + SFX_WINSTON_SHUFFLE = 342, + SFX_WINSTON_FEET = 343, + SFX_WINSTON_GRUNT_1 = 344, + SFX_WINSTON_GRUNT_2 = 345, + SFX_WINSTON_GRUNT_3 = 346, + SFX_WINSTON_CUPS = 347, + SFX_BRITTLE_GROUND_BREAK = 348, + SFX_SPIDER_EXPLODE = 349, + SFX_SHARK_BITE = 350, + SFX_LAVA_BUBBLES = 351, + SFX_EXPLOSION_2 = 352, + SFX_BURGLARS = 353, + SFX_ZIPPER = 354, + SFX_NUMBER_OF = 370, +} SOUND_EFFECT_ID; + +typedef enum { + SPM_NORMAL = 0, + SPM_UNDERWATER = 1, + SPM_ALWAYS = 2, + SPM_PITCH = 4, +} SOUND_PLAY_MODE; + +typedef enum { + CF_NORMAL = 0, + CF_FOLLOW_CENTRE = 1, + CF_NO_CHUNKY = 2, + CF_CHASE_OBJECT = 3, +} CAMERA_FLAGS; + +typedef enum { + FBBOX_MIN_X = 0, + FBBOX_MAX_X = 1, + FBBOX_MIN_Y = 2, + FBBOX_MAX_Y = 3, + FBBOX_MIN_Z = 4, + FBBOX_MAX_Z = 5, + FBBOX_X = 6, + FBBOX_Y = 7, + FBBOX_Z = 8, + FBBOX_ROT = 9, +} FRAME_BBOX_INFO; + +typedef enum { + BF_MATRIX_POP = 1, + BF_MATRIX_PUSH = 2, + BF_ROT_X = 4, + BF_ROT_Y = 8, + BF_ROT_Z = 16, +} BONE_FLAGS; + +typedef struct __unaligned { + int16_t tx; + int16_t ty; + int16_t tz; + int16_t cx; + int16_t cy; + int16_t cz; + int16_t fov; + int16_t roll; +} CINE_FRAME; + +typedef struct __unaligned { + uint16_t key[14]; // INPUT_ROLE_NUMBER_OF +} CONTROL_LAYOUT; + +typedef enum { + MX_INACTIVE = -1, + MX_UNUSED_0 = 0, // 2.mp3 + MX_UNUSED_1 = 1, // 2.mp3 + MX_CUTSCENE_THE_GREAT_WALL = 2, // 2.mp3 + MX_UNUSED_2 = 3, // 2.mp3 + MX_CUTSCENE_OPERA_HOUSE = 4, // 3.mp3 + MX_CUTSCENE_BROTHER_CHAN = 5, // 4.mp3 + MX_GYM_HINT_1 = 6, // 5.mp3 + MX_GYM_HINT_2 = 7, // 6.mp3 + MX_GYM_HINT_3 = 8, // 7.mp3 + MX_GYM_HINT_4 = 9, // 8.mp3 + MX_GYM_HINT_5 = 10, // 9.mp3 + MX_GYM_HINT_6 = 11, // 10.mp3 + MX_GYM_HINT_7 = 12, // 11.mp3 + MX_GYM_HINT_8 = 13, // 12.mp3 + MX_GYM_HINT_9 = 14, // 13.mp3 + MX_GYM_HINT_10 = 15, // 14.mp3 + MX_GYM_HINT_11 = 16, // 15.mp3 + MX_GYM_HINT_12 = 17, // 16.mp3 + MX_GYM_HINT_13 = 18, // 17.mp3 + MX_GYM_HINT_14 = 19, // 18.mp3 + MX_UNUSED_3 = 20, // 18.mp3 + MX_UNUSED_4 = 21, // 18.mp3 + MX_GYM_HINT_15 = 22, // 19.mp3 + MX_GYM_HINT_16 = 23, // 20.mp3 + MX_GYM_HINT_17 = 24, // 21.mp3 + MX_GYM_HINT_18 = 25, // 22.mp3 + MX_UNUSED_5 = 26, // 23.mp3 + MX_CUTSCENE_BATH = 27, // 23.mp3 + MX_DAGGER_PULL = 28, // 24.mp3 + MX_GYM_HINT_20 = 29, // 25.mp3 + MX_CUTSCENE_XIAN = 30, // 26.mp3 + MX_CAVES_AMBIENCE = 31, // 27.mp3 + MX_SEWERS_AMBIENCE = 32, // 28.mp3 + MX_WINDY_AMBIENCE = 33, // 29.mp3 + MX_HEARTBEAT_AMBIENCE = 34, // 30.mp3 + MX_SURPRISE_1 = 35, // 31.mp3 + MX_SURPRISE_2 = 36, // 32.mp3 + MX_SURPRISE_3 = 37, // 33.mp3 + MX_OOH_AAH_1 = 38, // 34.mp3 + MX_OOH_AAH_2 = 39, // 35.mp3 + MX_VENICE_VIOLINS = 40, // 36.mp3 + MX_END_OF_LEVEL = 41, // 37.mp3 + MX_SPOOKY_1 = 42, // 38.mp3 + MX_SPOOKY_2 = 43, // 39.mp3 + MX_SPOOKY_3 = 44, // 40.mp3 + MX_HARP_THEME = 45, // 41.mp3 + MX_MYSTERY_1 = 46, // 42.mp3 + MX_SECRET = 47, // 43.mp3 + MX_AMBUSH_1 = 48, // 44.mp3 + MX_AMBUSH_2 = 49, // 45.mp3 + MX_AMBUSH_3 = 50, // 46.mp3 + MX_AMBUSH_4 = 51, // 47.mp3 + MX_SKIDOO_THEME = 52, // 48.mp3 + MX_BATTLE_THEME = 53, // 49.mp3 + MX_MYSTERY_2 = 54, // 50.mp3 + MX_MYSTERY_3 = 55, // 51.mp3 + MX_MYSTERY_4 = 56, // 52.mp3 + MX_MYSTERY_5 = 57, // 53.mp3 + MX_RIG_AMBIENCE = 58, // 54.mp3 + MX_TOMB_AMBIENCE = 59, // 55.mp3 + MX_OOH_AAH_3 = 60, // 56.mp3 + MX_REVEAL_1 = 61, // 57.mp3 + MX_CUTSCENE_RIG = 62, // 58.mp3 + MX_REVEAL_2 = 63, // 59.mp3 + MX_TITLE_THEME = 64, // 60.mp3 + MX_UNUSED_6 = 65, // 61.mp3 +} MUSIC_TRACK_ID; + +typedef enum { + COLL_NONE = 0x00, + COLL_FRONT = 0x01, + COLL_LEFT = 0x02, + COLL_RIGHT = 0x04, + COLL_TOP = 0x08, + COLL_TOP_FRONT = 0x10, + COLL_CLAMP = 0x20, +} COLL_TYPE; + +typedef enum { + HT_WALL = 0, + HT_SMALL_SLOPE = 1, + HT_BIG_SLOPE = 2, +} HEIGHT_TYPE; + +typedef struct __unaligned { + uint16_t x; + uint16_t y; +} XGEN_X; + +typedef struct __unaligned { + int32_t x1; + int32_t x2; +} XBUF_X; + +typedef struct __unaligned { + int16_t x; + int16_t y; + int16_t g; +} XGEN_XG; + +typedef struct __unaligned { + int32_t x1; + int32_t g1; + int32_t x2; + int32_t g2; +} XBUF_XG; + +typedef struct __unaligned { + uint16_t x; + uint16_t y; + uint16_t g; + uint16_t u; + uint16_t v; +} XGEN_XGUV; + +typedef struct __unaligned { + int32_t x1; + int32_t g1; + int32_t u1; + int32_t v1; + int32_t x2; + int32_t g2; + int32_t u2; + int32_t v2; +} XBUF_XGUV; + +typedef struct __unaligned { + uint16_t x; + uint16_t y; + uint16_t g; + float rhw; + float u; + float v; +} XGEN_XGUVP; + +typedef struct __unaligned { + int32_t x1; + int32_t g1; + float u1; + float v1; + float rhw1; + int32_t x2; + int32_t g2; + float u2; + float v2; + float rhw2; +} XBUF_XGUVP; + +typedef struct __unaligned { + uint8_t manufacturer; + uint8_t version; + uint8_t rle; + uint8_t bpp; + uint16_t x_min; + uint16_t y_min; + uint16_t x_max; + uint16_t y_max; + uint16_t h_dpi; + uint16_t v_dpi; + RGB_888 palette[16]; + uint8_t reserved; + uint8_t planes; + uint16_t bytes_per_line; + uint16_t pal_pnterpret; + uint16_t h_res; + uint16_t v_res; + uint8_t reserved_data[54]; +} PCX_HEADER; + +typedef struct __unaligned { + uint8_t id_length; + uint8_t color_map_type; + uint8_t data_type_code; + uint16_t color_map_origin; + uint16_t color_map_length; + uint8_t color_map_depth; + uint16_t x_origin; + uint16_t y_origin; + uint16_t width; + uint16_t height; + uint8_t bpp; + uint8_t image_descriptor; +} TGA_HEADER; + +typedef struct __unaligned { + int16_t number; + int16_t volume; + int16_t randomness; + int16_t flags; +} SAMPLE_INFO; + +/* +typedef struct __unaligned { + int32_t volume; + int32_t pan; + int32_t sample_num; + int32_t pitch; +} SOUND_SLOT; +*/ + +typedef enum { + SF_FLIP = 0x40, + SF_UNFLIP = 0x80, +} SOUND_FLAG; + +typedef enum { + CLRB_PRIMARY_BUFFER = 0x0001, + CLRB_BACK_BUFFER = 0x0002, + CLRB_THIRD_BUFFER = 0x0004, + CLRB_Z_BUFFER = 0x0008, + CLRB_RENDER_BUFFER = 0x0010, + CLRB_PICTURE_BUFFER = 0x0020, + CLRB_WINDOWED_PRIMARY_BUFFER = 0x0040, + CLRB_RESERVED = 0x0080, + CLRB_PHDWINSIZE = 0x0100, +} CLEAR_BUFFER_FLAGS; + +typedef enum { + AC_NULL = 0, + AC_MOVE_ORIGIN = 1, + AC_JUMP_VELOCITY = 2, + AC_ATTACK_READY = 3, + AC_DEACTIVATE = 4, + AC_SOUND_FX = 5, + AC_EFFECT = 6, +} ANIM_COMMAND; + +typedef enum { + ACE_ALL = 0, + ACE_LAND = 1, + ACE_WATER = 2, +} ANIM_COMMAND_ENVIRONMENT; + +typedef struct __unaligned { + int32_t boat_turn; + int32_t left_fallspeed; + int32_t right_fallspeed; + int16_t tilt_angle; + int16_t extra_rotation; + int32_t water; + int32_t pitch; +} BOAT_INFO; + +typedef struct __unaligned { + int16_t track_mesh; + int32_t skidoo_turn; + int32_t left_fallspeed; + int32_t right_fallspeed; + int16_t momentum_angle; + int16_t extra_rotation; + int32_t pitch; +} SKIDOO_INFO; + +typedef struct __unaligned { + struct { + XYZ_16 min; + XYZ_16 max; + } shift, rot; +} OBJECT_BOUNDS; + +typedef struct __unaligned { + int32_t xv; + int32_t yv; + int32_t zv; +} PORTAL_VBUF; + +typedef struct __unaligned { + BOUNDS_16 bounds; + XYZ_16 offset; + int16_t mesh_rots[]; +} FRAME_INFO; + +typedef enum { + GF_S_PC_DETAIL_LEVELS = 0, + GF_S_PC_DEMO_MODE = 1, + GF_S_PC_SOUND = 2, + GF_S_PC_CONTROLS = 3, + GF_S_PC_GAMMA = 4, + GF_S_PC_SET_VOLUMES = 5, + GF_S_PC_USER_KEYS = 6, + GF_S_PC_SAVE_FILE_WARNING = 7, + GF_S_PC_TRY_AGAIN_QUESTION = 8, + GF_S_PC_YES = 9, + GF_S_PC_NO = 10, + GF_S_PC_SAVE_COMPLETE = 11, + GF_S_PC_NO_SAVE_GAMES = 12, + GF_S_PC_NONE_VALID = 13, + GF_S_PC_SAVE_GAME_QUESTION = 14, + GF_S_PC_EMPTY_SLOT = 15, + GF_S_PC_OFF = 16, + GF_S_PC_ON = 17, + GF_S_PC_SETUP_SOUND_CARD = 18, + GF_S_PC_DEFAULT_KEYS = 19, + GF_S_PC_DOZY = 20, + GF_S_PC_NUMBER_OF = 41, +} GF_PC_STRING; + +typedef enum { + GF_S_GAME_HEADING_INVENTORY = 0, + GF_S_GAME_HEADING_OPTION = 1, + GF_S_GAME_HEADING_ITEMS = 2, + GF_S_GAME_HEADING_GAME_OVER = 3, + GF_S_GAME_PASSPORT_LOAD_GAME = 4, + GF_S_GAME_PASSPORT_SAVE_GAME = 5, + GF_S_GAME_PASSPORT_NEW_GAME = 6, + GF_S_GAME_PASSPORT_RESTART_LEVEL = 7, + GF_S_GAME_PASSPORT_EXIT_TO_TITLE = 8, + GF_S_GAME_PASSPORT_EXIT_DEMO = 9, + GF_S_GAME_PASSPORT_EXIT_GAME = 10, + GF_S_GAME_PASSPORT_SELECT_LEVEL = 11, + GF_S_GAME_PASSPORT_SAVE_POSITION = 12, + GF_S_GAME_DETAIL_SELECT_DETAIL = 13, + GF_S_GAME_DETAIL_HIGH = 14, + GF_S_GAME_DETAIL_MEDIUM = 15, + GF_S_GAME_DETAIL_LOW = 16, + GF_S_GAME_KEYMAP_WALK = 17, + GF_S_GAME_KEYMAP_ROLL = 18, + GF_S_GAME_KEYMAP_RUN = 19, + GF_S_GAME_KEYMAP_LEFT = 20, + GF_S_GAME_KEYMAP_RIGHT = 21, + GF_S_GAME_KEYMAP_BACK = 22, + GF_S_GAME_KEYMAP_STEP_LEFT = 23, + GF_S_GAME_KEYMAP_RESERVED_1 = 24, + GF_S_GAME_KEYMAP_STEP_RIGHT = 25, + GF_S_GAME_KEYMAP_RESERVED_2 = 26, + GF_S_GAME_KEYMAP_LOOK = 27, + GF_S_GAME_KEYMAP_JUMP = 28, + GF_S_GAME_KEYMAP_ACTION = 29, + GF_S_GAME_KEYMAP_DRAW_WEAPON = 30, + GF_S_GAME_KEYMAP_RESERVED_3 = 31, + GF_S_GAME_KEYMAP_INVENTORY = 32, + GF_S_GAME_KEYMAP_FLARE = 33, + GF_S_GAME_KEYMAP_STEP = 34, + GF_S_GAME_INV_ITEM_STATISTICS = 35, + GF_S_GAME_INV_ITEM_PISTOLS = 36, + GF_S_GAME_INV_ITEM_SHOTGUN = 37, + GF_S_GAME_INV_ITEM_MAGNUMS = 38, + GF_S_GAME_INV_ITEM_UZIS = 39, + GF_S_GAME_INV_ITEM_HARPOON = 40, + GF_S_GAME_INV_ITEM_M16 = 41, + GF_S_GAME_INV_ITEM_GRENADE = 42, + GF_S_GAME_INV_ITEM_FLARE = 43, + GF_S_GAME_INV_ITEM_PISTOL_AMMO = 44, + GF_S_GAME_INV_ITEM_SHOTGUN_AMMO = 45, + GF_S_GAME_INV_ITEM_MAGNUM_AMMO = 46, + GF_S_GAME_INV_ITEM_UZI_AMMO = 47, + GF_S_GAME_INV_ITEM_HARPOON_AMMO = 48, + GF_S_GAME_INV_ITEM_M16_AMMO = 49, + GF_S_GAME_INV_ITEM_GRENADE_AMMO = 50, + GF_S_GAME_INV_ITEM_SMALL_MEDIPACK = 51, + GF_S_GAME_INV_ITEM_LARGE_MEDIPACK = 52, + GF_S_GAME_INV_ITEM_PICKUP = 53, + GF_S_GAME_INV_ITEM_PUZZLE = 54, + GF_S_GAME_INV_ITEM_KEY = 55, + GF_S_GAME_INV_ITEM_GAME = 56, + GF_S_GAME_INV_ITEM_LARA_HOME = 57, + GF_S_GAME_MISC_LOADING = 58, + GF_S_GAME_MISC_TIME_TAKEN = 59, + GF_S_GAME_MISC_SECRETS_FOUND = 60, + GF_S_GAME_MISC_LOCATION = 61, + GF_S_GAME_MISC_KILLS = 62, + GF_S_GAME_MISC_AMMO_USED = 63, + GF_S_GAME_MISC_HITS = 64, + GF_S_GAME_MISC_SAVES_PERFORMED = 65, + GF_S_GAME_MISC_DISTANCE_TRAVELLED = 66, + GF_S_GAME_MISC_HEALTH_PACKS_USED = 67, + GF_S_GAME_MISC_RELEASE_VERSION = 68, + GF_S_GAME_MISC_NONE = 69, + GF_S_GAME_MISC_FINISH = 70, + GF_S_GAME_MISC_BEST_TIMES = 71, + GF_S_GAME_MISC_NO_TIMES_SET = 72, + GF_S_GAME_MISC_NA = 73, + GF_S_GAME_MISC_CURRENT_POSITION = 74, + GF_S_GAME_MISC_FINAL_STATISTICS = 75, + GF_S_GAME_MISC_OF = 76, + GF_S_GAME_MISC_STORY_SO_FAR = 77, + GF_S_GAME_NUMBER_OF = 89, +} GF_GAME_STRING; + +typedef enum { + GF_ADD_INV_PISTOLS = 0, + GF_ADD_INV_SHOTGUN = 1, + GF_ADD_INV_MAGNUMS = 2, + GF_ADD_INV_UZIS = 3, + GF_ADD_INV_HARPOON = 4, + GF_ADD_INV_M16 = 5, + GF_ADD_INV_GRENADE = 6, + GF_ADD_INV_PISTOL_AMMO = 7, + GF_ADD_INV_SHOTGUN_AMMO = 8, + GF_ADD_INV_MAGNUM_AMMO = 9, + GF_ADD_INV_UZI_AMMO = 10, + GF_ADD_INV_HARPOON_AMMO = 11, + GF_ADD_INV_M16_AMMO = 12, + GF_ADD_INV_GRENADE_AMMO = 13, + GF_ADD_INV_FLARES = 14, + GF_ADD_INV_SMALL_MEDI = 15, + GF_ADD_INV_LARGE_MEDI = 16, + GF_ADD_INV_PICKUP_1 = 17, + GF_ADD_INV_PICKUP_2 = 18, + GF_ADD_INV_PUZZLE_1 = 19, + GF_ADD_INV_PUZZLE_2 = 20, + GF_ADD_INV_PUZZLE_3 = 21, + GF_ADD_INV_PUZZLE_4 = 22, + GF_ADD_INV_KEY_1 = 23, + GF_ADD_INV_KEY_2 = 24, + GF_ADD_INV_KEY_3 = 25, + GF_ADD_INV_KEY_4 = 26, + GF_ADD_INV_NUMBER_OF = 27, +} GF_ADD_INV; + +typedef enum { + IT_NAME = 0, + IT_QTY = 1, + IT_NUMBER_OF = 2, +} INV_TEXT; + +typedef enum { + REQ_CENTER = 0x00, + REQ_USE = 0x01, + REQ_ALIGN_LEFT = 0x02, + REQ_ALIGN_RIGHT = 0x04, + REQ_HEADING = 0x08, + REQ_BEST_TIME = 0x10, + REQ_NORMAL_TIME = 0x20, + REQ_NO_TIME = 0x40, +} REQUESTER_FLAGS; + +// clang-format on + +#pragma pack(pop) diff --git a/src/tr2/global/vars.c b/src/tr2/global/vars.c index 0de790956..623460336 100644 --- a/src/tr2/global/vars.c +++ b/src/tr2/global/vars.c @@ -9,4 +9,9 @@ GAME_FLOW_DIR g_GF_OverrideDir = (GAME_FLOW_DIR)-1; int16_t g_RoomsToDraw[MAX_ROOMS_TO_DRAW] = { 0 }; int16_t g_RoomsToDrawCount = 0; +void *g_XBuffer = NULL; +const float g_RhwFactor = 0x14000000.p0; +uint16_t *g_TexturePageBuffer16[MAX_TEXTURE_PAGES] = { 0 }; +PHD_TEXTURE g_TextureInfo[MAX_TEXTURES]; + SDL_Window *g_SDLWindow = NULL; diff --git a/src/tr2/global/vars.h b/src/tr2/global/vars.h index bf4d6e5f2..65776f5b2 100644 --- a/src/tr2/global/vars.h +++ b/src/tr2/global/vars.h @@ -2,6 +2,8 @@ #include "global/vars_decomp.h" +#include + #include extern const char *g_TR2XVersion; @@ -10,4 +12,9 @@ extern GAME_FLOW_DIR g_GF_OverrideDir; extern int16_t g_RoomsToDraw[MAX_ROOMS_TO_DRAW]; extern int16_t g_RoomsToDrawCount; +extern void *g_XBuffer; +extern const float g_RhwFactor; +extern uint16_t *g_TexturePageBuffer16[MAX_TEXTURE_PAGES]; +extern PHD_TEXTURE g_TextureInfo[MAX_TEXTURES]; + extern SDL_Window *g_SDLWindow; diff --git a/src/tr2/global/vars_decomp.h b/src/tr2/global/vars_decomp.h index 4841e999a..1060a786a 100644 --- a/src/tr2/global/vars_decomp.h +++ b/src/tr2/global/vars_decomp.h @@ -10,7 +10,6 @@ #define g_IID_IDirect3DTexture2 (*(GUID*)0x00463170) #define g_PerspectiveDistance (*(uint32_t*)0x00464060) // = 0x3000000 #define g_PolyDrawRoutines (*((void(__cdecl *(*)[9])(const int16_t *obj_ptr))0x00464068)) -#define g_RhwFactor (*(float*)0x0046408C) // = 335544320.0f #define g_CineTrackID (*(int32_t*)0x004640B0) // = 1 #define g_CineTickRate (*(int32_t*)0x004640B8) // = 0x8000 #define g_FlipEffect (*(int32_t*)0x004640C4) // = -1 @@ -96,18 +95,11 @@ #define g_PuzzleHoleBounds (*(int16_t(*)[])0x004660F0) #define g_PuzzleHolePosition (*(XYZ_32*)0x00466108) #define g_BGND_PaletteIndex (*(int32_t*)0x00466400) // = -1 -#define g_GameClassName (*(const char(*)[])0x00466448) -#define g_GameWindowName (*(const char(*)[])0x00466468) #define g_FadeValue (*(int32_t*)0x00466490) // = 0x100000 #define g_FadeLimit (*(int32_t*)0x00466494) // = 0x100000 #define g_FadeAdder (*(int32_t*)0x00466498) // = 0x8000 #define g_ErrorMessages (*(const char *(*)[43])0x004664E8) #define g_SavedLevels (*(int16_t(*)[24])0x00466B80) -#define g_PaletteIndex (*(int32_t*)0x00466BDC) -#define g_DumpX (*(int16_t*)0x00466BE4) -#define g_DumpY (*(int16_t*)0x00466BE6) -#define g_DumpWidth (*(int16_t*)0x00466BE8) -#define g_DumpHeight (*(int16_t*)0x00466BEA) #define g_MidSort (*(int32_t*)0x0046C300) // = 0 #define g_ViewportAspectRatio (*(float*)0x0046C304) // = 0.0f #define g_XGenY1 (*(int32_t*)0x0046C308) @@ -119,22 +111,18 @@ #define g_FltWinBottom (*(float*)0x0047031C) #define g_FltResZBuf (*(float*)0x00470320) #define g_FltResZ (*(float*)0x00470324) -#define g_Output_InsertTransQuad (*(void(__cdecl **)(int32_t x, int32_t y, int32_t width, int32_t height, int32_t z))0x00470328) #define g_PhdWinHeight (*(int32_t*)0x0047032C) #define g_PhdWinCenterX (*(int32_t*)0x00470330) #define g_PhdWinCenterY (*(int32_t*)0x00470334) #define g_LsYaw (*(int16_t*)0x00470338) -#define g_Output_InsertTrans8 (*(void(__cdecl **)(const PHD_VBUF *vbuf, int16_t shade))0x0047033C) #define g_FltWinTop (*(float*)0x00470340) #define g_SortBuffer (*(SORT_ITEM(*)[4000])0x00470348) #define g_FltWinLeft (*(float*)0x00478048) -#define g_PhdWinMinY (*(int16_t*)0x0047804C) #define g_PhdFarZ (*(int32_t*)0x00478058) #define g_FltRhwOPersp (*(float*)0x0047805C) #define g_PhdWinBottom (*(int32_t*)0x00478060) #define g_PhdPersp (*(int32_t*)0x00478064) #define g_PhdWinLeft (*(int32_t*)0x00478068) -#define g_Output_InsertFlatRect (*(void(__cdecl **)(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t z, uint8_t color_idx))0x0047806C) #define g_Info3DBuffer (*(int16_t(*)[120000])0x00478070) #define g_PhdWinMaxX (*(int32_t*)0x004B29F0) #define g_PhdNearZ (*(int32_t*)0x004B29F4) @@ -142,37 +130,24 @@ #define g_FltFarZ (*(float*)0x004B29FC) #define g_FltWinCenterX (*(float*)0x004B2A00) #define g_FltWinCenterY (*(float*)0x004B2A04) -#define g_PhdScreenHeight (*(int32_t*)0x004B2A08) -#define g_PrintSurfacePtr (*(uint8_t **)0x004B2A0C) -#define g_PhdWinMinX (*(int16_t*)0x004B2A10) #define g_FltPerspONearZ (*(float*)0x004B2A14) #define g_FltRhwONearZ (*(float*)0x004B2A18) #define g_PhdWinMaxY (*(int32_t*)0x004B2A1C) -#define g_Output_InsertSprite (*(void(__cdecl **)(int32_t z, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t sprite_idx, int16_t shade))0x004B2A20) #define g_FltNearZ (*(float*)0x004B2A24) #define g_MatrixPtr (*(MATRIX **)0x004B2A28) -#define g_Output_DrawObjectGT3 (*(const int16_t *(__cdecl **)(const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type))0x004B2A2C) -#define g_Output_DrawObjectGT4 (*(const int16_t *(__cdecl **)(const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type))0x004B2A30) #define g_RandomTable (*(int32_t(*)[32])0x004B2A38) #define g_FltPersp (*(float*)0x004B2AB8) #define g_W2VMatrix (*(MATRIX*)0x004B2AC0) #define g_Info3DPtr (*(int16_t **)0x004B2AF0) #define g_PhdWinWidth (*(int32_t*)0x004B2AF4) -#define g_Output_InsertLine (*(void(__cdecl **)(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t z, uint8_t color_idx))0x004B2AF8) -#define g_PhdTextureInfo (*(PHD_TEXTURE(*)[0x800])0x004B2B00) -#define g_TextureInfo (*(PHD_TEXTURE(*)[])0x004B2B00) #define g_PhdViewDistance (*(int32_t*)0x004BCB00) #define g_LsPitch (*(int16_t*)0x004BCB04) -#define g_Output_DrawObjectG4 (*(const int16_t *(__cdecl **)(const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type))0x004BCB08) #define g_ShadesTable (*(int16_t(*)[32])0x004BCB10) -#define g_Output_DrawObjectG3 (*(const int16_t *(__cdecl **)(const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type))0x004BCB50) #define g_MatrixStack (*(MATRIX(*)[])0x004BCB58) #define g_DepthQTable (*(DEPTHQ_ENTRY(*)[32])0x004BD2D8) #define g_DepthQIndex (*(uint8_t(*)[256])0x004BF2D8) -#define g_PhdScreenWidth (*(int32_t*)0x004BF3D8) #define g_LsDivider (*(int32_t*)0x004BF3DC) #define g_PhdVBuf (*(PHD_VBUF(*)[1500])0x004BF3E0) -#define g_XBuffer ((void *)0x004CAF60) #define g_TexturePageBuffer8 (*(uint8_t *(*)[32])0x004D6AE0) #define g_FltWinRight (*(float*)0x004D6B60) #define g_LsVectorView (*(XYZ_32*)0x004D6B68) @@ -183,9 +158,7 @@ #define g_WibbleOffset (*(int32_t*)0x004D6C0C) #define g_IsWibbleEffect (*(int32_t*)0x004D6C10) #define g_IsWaterEffect (*(int32_t*)0x004D6C14) -#define g_VBuffer (*(VERTEX_INFO(*)[20])0x004D6CD8) #define g_IsShadeEffect (*(int8_t*)0x004D6F78) -#define g_VBufferD3D (*(D3DTLVERTEX(*)[32])0x004D6F80) #define g_GamePalette16 (*(PALETTEENTRY(*)[256])0x004D7380) #define g_CineFrameCurrent (*(int32_t*)0x004D7780) #define g_CineTickCount (*(int32_t*)0x004D7784) @@ -195,7 +168,6 @@ #define g_NoInputCounter (*(int32_t*)0x004D7794) #define g_FlipTimer (*(int32_t*)0x004D779C) #define g_LOSNumRooms (*(int32_t*)0x004D77A0) // = 0 -#define g_StopInventory (*(BOOL*)0x004D77A4) #define g_IsDemoLevelType (*(BOOL*)0x004D77AC) #define g_IsDemoLoaded (*(BOOL*)0x004D77B0) #define g_BoundStart (*(int32_t*)0x004D77C0) @@ -247,86 +219,25 @@ #define g_BGND_PictureIsReady (*(bool*)0x004D7E88) #define g_BGND_TexturePageIndexes (*(int32_t(*)[5])0x004D7E90) #define g_BGND_PageHandles (*(HWR_TEXTURE_HANDLE(*)[5])0x004D7EA8) -#define g_D3DDev (*(LPDIRECT3DDEVICE2*)0x004D7EBC) -#define g_D3D (*(LPDIRECT3D2*)0x004D7EC0) -#define g_D3DView (*(LPDIRECT3DVIEWPORT2*)0x004D7EC4) -#define g_D3DMaterial (*(LPDIRECT3DMATERIAL2*)0x004D7EC8) #define g_MinWindowClientHeight (*(int32_t*)0x004D7ED0) -#define g_DDrawInterface (*(LPDIRECTDRAW*)0x004D7ED4) -#define g_IsGameWindowChanging (*(bool*)0x004D7ED8) #define g_MaxWindowHeight (*(int32_t*)0x004D7EDC) -#define g_DDraw (*(LPDIRECTDRAW3*)0x004D7EE0) -#define g_IsGameWindowCreated (*(bool*)0x004D7EE4) -#define g_IsGameWindowUpdating (*(bool*)0x004D7EE8) -#define g_IsDDrawGameWindowShow (*(bool*)0x004D7EEC) #define g_MinWindowClientWidth (*(int32_t*)0x004D7EF0) -#define g_IsGameWindowShow (*(bool*)0x004D7EF4) #define g_IsMinWindowSizeSet (*(bool*)0x004D7EF8) #define g_MaxWindowClientWidth (*(int32_t*)0x004D7EFC) -#define g_GameWindowWidth (*(int32_t*)0x004D7F00) -#define g_IsMinMaxInfoSpecial (*(bool*)0x004D7F04) -#define g_IsGameFullScreen (*(bool*)0x004D7F08) -#define g_IsGameWindowMaximized (*(bool*)0x004D7F0C) #define g_GameWindowHandle (*(HWND*)0x004D7F10) -#define g_GameWindowHeight (*(int32_t*)0x004D7F14) -#define g_PrimaryDisplayAdapter (*(DISPLAY_ADAPTER_NODE**)0x004D7F18) -#define g_CurrentDisplayAdapter (*(DISPLAY_ADAPTER*)0x004D7F20) #define g_LockedBufferCount (*(uint32_t*)0x004D8338) -#define g_GameWindowPositionX (*(int32_t*)0x004D833C) -#define g_GameWindowPositionY (*(int32_t*)0x004D8340) #define g_DisplayAdapterList (*(DISPLAY_ADAPTER_LIST*)0x004D8348) #define g_MaxWindowClientHeight (*(int32_t*)0x004D8354) -#define g_IsMessageLoopClosed (*(bool*)0x004D8358) #define g_MaxWindowWidth (*(int32_t*)0x004D835C) #define g_IsMaxWindowSizeSet (*(bool*)0x004D8360) #define g_AppResultCode (*(uint32_t*)0x004D8364) -#define g_FullScreenWidth (*(int32_t*)0x004D8368) -#define g_FullScreenHeight (*(int32_t*)0x004D836C) -#define g_FullScreenBPP (*(int32_t*)0x004D8370) -#define g_FullScreenVGA (*(int32_t*)0x004D8374) #define g_IsGameToExit (*(uint8_t*)0x004D8378) -#define g_GameWindowY (*(int32_t*)0x004D837C) -#define g_GameWindowX (*(int32_t*)0x004D8380) -#define g_IsGameWindowMinimized (*(bool*)0x004D8384) #define g_MinWindowWidth (*(int32_t*)0x004D8388) #define g_MinWindowHeight (*(int32_t*)0x004D838C) #define g_IsGameWindowActive (*(bool*)0x004D8390) #define g_MessageLoopCounter (*(int32_t*)0x004D8394) -#define IDID_SysKeyboard (*(LPDIRECTINPUTDEVICE*)0x004D8560) -#define g_IsVidSizeLock (*(int32_t*)0x004D856C) -#define g_SampleFreqs (*(DWORD(*)[256])0x004D8570) -#define g_SoundAdapterList (*(SOUND_ADAPTER_LIST*)0x004D8970) -#define g_SampleBuffers (*(LPDIRECTSOUNDBUFFER(*)[256])0x004D8980) #define g_IsSoundEnabled (*(uint8_t*)0x004D8D80) -#define g_DSound (*(LPDIRECTSOUND*)0x004D8D84) -#define g_ChannelSamples (*(int32_t(*)[32])0x004D8D88) -#define g_ChannelBuffers (*(LPDIRECTSOUNDBUFFER(*)[32])0x004D8E08) -#define g_CurrentSoundAdapter (*(SOUND_ADAPTER*)0x004D8E8C) -#define g_PrimarySoundAdapter (*(SOUND_ADAPTER_NODE **)0x004D8EAC) -#define g_RenderBufferSurface (*(LPDDS*)0x004D8EB0) -#define g_DDrawClipper (*(LPDIRECTDRAWCLIPPER*)0x004D8EB4) -#define g_WinVid_Palette (*(PALETTEENTRY(*)[256])0x004D8EB8) -#define g_ThirdBufferSurface (*(LPDDS*)0x004D92B8) -#define g_PictureBufferSurface (*(LPDDS*)0x004D92BC) -#define g_ZBufferSurface (*(LPDDS*)0x004D92C0) -#define g_DDrawPalette (*(LPDIRECTDRAWPALETTE*)0x004D92C4) -#define g_PrimaryBufferSurface (*(LPDDS*)0x004D92C8) #define g_ColorBitMasks (*(COLOR_BIT_MASKS*)0x004D92E8) -#define g_GameVid_BufRect (*(RECT*)0x004D9318) -#define g_GameVid_Rect (*(RECT*)0x004D9328) -#define g_GameVid_Width (*(int32_t*)0x004D9338) -#define g_GameVid_Height (*(int32_t*)0x004D933C) -#define g_GameVid_BPP (*(int32_t*)0x004D9340) -#define g_GameVid_BufWidth (*(int32_t*)0x004D9344) -#define g_GameVid_BufHeight (*(int32_t*)0x004D9348) -#define g_UVAdd (*(int32_t*)0x004D934C) -#define g_GameVid_IsVga (*(bool*)0x004D9350) -#define g_GameVid_IsWindowedVGA (*(int8_t*)0x004D9351) -#define g_GameVid_IsFullscreenVGA (*(bool*)0x004D9352) -#define g_IsWindowedVGA (*(bool*)0x004D9353) -#define g_Is16bitTextures (*(bool*)0x004D9354) -#define g_NeedToReloadTextures (*(bool*)0x004D9355) -#define g_BackBufferSurface (*(LPDDS*)0x004D9358) #define g_TexturePageCount (*(int32_t*)0x004D9360) #define g_LabTextureUVFlag (*(uint8_t(*)[2048])0x004D93F0) #define g_LevelFilePalettesOffset (*(int32_t*)0x004D9BF4) @@ -336,7 +247,6 @@ #define g_Legacy_FloorData (*(int16_t **)0x004D9D94) #define g_LevelFileName (*(char(*)[256])0x004D9D98) #define g_TextureInfoCount (*(int32_t*)0x004D9E98) -#define g_LevelFileDepthQOffset (*(int32_t*)0x004D9E9C) #define g_IsFMVPlaying (*(int32_t*)0x004D9EAC) #define g_MovieContext (*(void **)0x004D9EB0) #define g_FmvContext (*(void **)0x004D9EB4) @@ -346,15 +256,6 @@ #define g_LevelComplete (*(int32_t*)0x004D9EC4) #define g_SaveCounter (*(int32_t*)0x004D9EC8) #define g_GameMode (*(int32_t*)0x004D9ECC) -#define g_HWR_VertexBuffer (*(D3DTLVERTEX(*)[0x2000])0x004D9ED8) -#define g_CurrentTexSource (*(D3DTEXTUREHANDLE*)0x00519ED8) -#define g_HWR_PageHandles (*(HWR_TEXTURE_HANDLE(*)[32])0x00519EE0) -#define g_HWR_VertexPtr (*(D3DTLVERTEX **)0x00519F60) -#define g_ZEnableState (*(bool*)0x00519F64) -#define g_AlphaBlendEnabler (*(D3DRENDERSTATETYPE*)0x00519F68) -#define g_ColorKeyState (*(bool*)0x00519F6C) -#define g_ZWriteEnableState (*(bool*)0x00519F70) -#define g_HWR_TexturePageIndexes (*(int32_t(*)[32])0x00519F78) #define g_GameBuf_MemCap (*(size_t*)0x0051A000) #define g_GameBuf_MemPtr (*(char **)0x0051A004) #define g_GameBuf_MemUsed (*(size_t*)0x0051A008) @@ -370,21 +271,14 @@ #define g_SoundText (*(TEXTSTRING *(*)[4])0x0051A2F0) #define g_WaterPalette (*(RGB_888(*)[256])0x0051B308) #define g_PicturePalette (*(RGB_888(*)[256])0x0051B608) -#define g_PhdWinRect (*(RECT*)0x0051B918) #define g_AnimTextureRanges (*(int16_t **)0x0051B92C) #define g_GamePalette8 (*(RGB_888(*)[256])0x0051B930) -#define g_WinVidNeedToResetBuffers (*(bool*)0x0051BC30) #define g_IsWet (*(int32_t*)0x0051BC38) -#define g_SavedAppSettings (*(APP_SETTINGS*)0x0051BCC0) #define g_IsTitleLoaded (*(BOOL*)0x0051BDA0) -#define g_MasterVolume (*(int32_t*)0x0051BDA8) #define g_MciDeviceID (*(MCIDEVICEID*)0x0051BDAC) #define g_CD_LoopTrack (*(int32_t*)0x0051BDB0) -#define g_TexturePages (*(TEXPAGE_DESC(*)[32])0x0051BDB8) #define g_TextureFormat (*(TEXTURE_FORMAT*)0x0051C1B8) -#define g_TexturesAlphaChannel (*(bool*)0x0051C20C) #define g_TexturesHaveCompatibleMasks (*(uint8_t*)0x0051C20D) -#define g_TexturePalettes (*(LPDIRECTDRAWPALETTE(*)[16])0x0051C210) #define g_NumSampleInfos (*(int32_t*)0x0051E6C0) #define g_SoundIsActive (*(int32_t*)0x0051E6C4) #define g_SampleLUT (*(int16_t(*)[])0x0051E6E0) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index c0525fd95..3446c67dd 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -3,11 +3,9 @@ #include "decomp/decomp.h" #include "decomp/effects.h" #include "decomp/flares.h" -#include "decomp/fmv.h" #include "decomp/savegame.h" #include "decomp/skidoo.h" #include "decomp/stats.h" -#include "game/background.h" #include "game/box.h" #include "game/camera.h" #include "game/collide.h" @@ -21,7 +19,6 @@ #include "game/gun/gun_misc.h" #include "game/gun/gun_pistols.h" #include "game/gun/gun_rifle.h" -#include "game/hwr.h" #include "game/input.h" #include "game/inventory/backpack.h" #include "game/inventory/common.h" @@ -89,6 +86,7 @@ #include "game/output.h" #include "game/overlay.h" #include "game/random.h" +#include "game/render/hwr.h" #include "game/requester.h" #include "game/room.h" #include "game/room_draw.h" @@ -96,7 +94,6 @@ #include "game/sound.h" #include "game/text.h" #include "inject_util.h" -#include "specific/s_flagged_string.h" static void M_DecompGeneral(const bool enable); static void M_DecompFMV(const bool enable); @@ -113,7 +110,6 @@ static void M_Math(bool enable); static void M_Matrix(bool enable); static void M_Shell(bool enable); static void M_Requester(bool enable); -static void M_Option(bool enable); static void M_Text(bool enable); static void M_Input(bool enable); static void M_Output(bool enable); @@ -147,9 +143,7 @@ static void M_S_FlaggedString(bool enable); static void M_DecompGeneral(const bool enable) { INJECT(enable, 0x00411F50, Game_SetCutsceneTrack); - INJECT(enable, 0x00411F60, Game_Cutscene_Start); INJECT(enable, 0x00412080, Room_InitCinematic); - INJECT(enable, 0x00412120, Game_Cutscene_Control); INJECT(enable, 0x004123D0, Room_FindByPos); INJECT(enable, 0x00412450, CutscenePlayer_Control); INJECT(enable, 0x00412530, Lara_Control_Cutscene); @@ -157,162 +151,16 @@ static void M_DecompGeneral(const bool enable) INJECT(enable, 0x00412660, CutscenePlayerGen_Initialise); INJECT(enable, 0x00414220, Misc_Move3DPosTo3DPos); INJECT(enable, 0x0043A280, Level_Initialise); - INJECT(enable, 0x00444540, Enumerate3DDevices); - INJECT(enable, 0x00444570, D3DCreate); - INJECT(enable, 0x004445B0, Enum3DDevicesCallback); - INJECT(enable, 0x00444670, D3DIsSupported); - INJECT(enable, 0x004446B0, D3DSetViewport); - INJECT(enable, 0x00444770, D3DDeviceCreate); - INJECT(enable, 0x00444930, Direct3DRelease); - 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); - INJECT(enable, 0x004453C0, WinVidBufferLock); - INJECT(enable, 0x00445400, WinVidBufferUnlock); - INJECT(enable, 0x00445430, WinVidCopyBitmapToBuffer); - INJECT(enable, 0x004454C0, GetRenderBitDepth); - 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); - INJECT(enable, 0x00447220, DInputRelease); - INJECT(enable, 0x00447240, WinInReadKeyboard); INJECT(enable, 0x00447810, IncreaseScreenSize); INJECT(enable, 0x00447880, DecreaseScreenSize); - INJECT(enable, 0x004478F0, setup_screen_size); - 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); - INJECT(enable, 0x00448920, CreateRenderBuffer); - 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); - INJECT(enable, 0x00449610, GameApplySettings); - INJECT(enable, 0x00449850, UpdateGameResolution); - INJECT(enable, 0x004498C0, DecodeErrorMessage); - INJECT(enable, 0x00449E50, AdjustTextureUVs); INJECT(enable, 0x0044B4B0, S_LoadLevelFile); INJECT(enable, 0x0044B4D0, S_UnloadLevelFile); - INJECT(enable, 0x0044B500, S_AdjustTexelCoordinates); - INJECT(enable, 0x0044B520, S_ReloadLevelGraphics); - INJECT(enable, 0x0044C1D0, S_FindColor); - INJECT(enable, 0x0044C200, S_DrawScreenLine); - INJECT(enable, 0x0044C240, S_DrawScreenBox); - INJECT(enable, 0x0044C360, S_DrawScreenFBox); - INJECT(enable, 0x0044C3A0, S_FadeToBlack); INJECT(enable, 0x0044C3F0, S_Wait); INJECT(enable, 0x0044CA70, DisplayCredits); INJECT(enable, 0x0044D610, S_InitialiseSystem); - INJECT(enable, 0x0044E4E0, RenderErrorBox); INJECT(enable, 0x0044E520, WinMain); - INJECT(enable, 0x0044E700, GameInit); - INJECT(enable, 0x0044E7A0, WinGameStart); - INJECT(enable, 0x00450AE0, GetRenderHeight); - INJECT(enable, 0x00450AF0, GetRenderWidth); - INJECT(enable, 0x00450B00, S_InitialisePolyList); - INJECT(enable, 0x00450BF0, S_DumpScreen); - INJECT(enable, 0x00450C30, S_ClearScreen); - INJECT(enable, 0x00450C40, S_InitialiseScreen); - INJECT(enable, 0x00450C80, S_OutputPolyList); - INJECT(enable, 0x00450F30, S_InsertBackPolygon); - 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); - INJECT(enable, 0x00452250, S_CopyBufferToScreen); INJECT(enable, 0x00454C50, TitleSequence); - INJECT(enable, 0x004557A0, CopyBitmapPalette); - INJECT(enable, 0x004558E0, FindNearestPaletteEntry); - INJECT(enable, 0x004559B0, SyncSurfacePalettes); - INJECT(enable, 0x00455A60, CreateTexturePalette); - INJECT(enable, 0x00455AF0, GetFreePaletteIndex); - INJECT(enable, 0x00455B10, FreePalette); - INJECT(enable, 0x00455B40, SafeFreePalette); - INJECT(enable, 0x00455B90, CreateTexturePage); - INJECT(enable, 0x00455C00, GetFreeTexturePageIndex); - INJECT(enable, 0x00455C20, CreateTexturePageSurface); - INJECT(enable, 0x00455CC0, TexturePageInit); - INJECT(enable, 0x00455E40, Create3DTexture); - INJECT(enable, 0x00455E70, SafeFreeTexturePage); - INJECT(enable, 0x00455E90, FreeTexturePage); - INJECT(enable, 0x00455ED0, TexturePageReleaseVidMemSurface); - INJECT(enable, 0x00455F10, FreeTexturePages); - INJECT(enable, 0x00455F40, LoadTexturePage); - INJECT(enable, 0x00455FF0, ReloadTextures); - INJECT(enable, 0x00456030, GetTexturePageHandle); - INJECT(enable, 0x00456070, AddTexturePage8); - INJECT(enable, 0x00456170, AddTexturePage16); - INJECT(enable, 0x00456310, EnumTextureFormatsCallback); - INJECT(enable, 0x00456430, EnumerateTextureFormats); - INJECT(enable, 0x00456460, CleanupTextures); - INJECT(enable, 0x00456470, InitTextures); - INJECT(enable, 0x00452690, SE_ReadAppSettings); -} - -static void M_DecompFMV(const bool enable) -{ - INJECT(enable, 0x0044BDA0, PlayFMV); - INJECT(enable, 0x0044C140, IntroFMV); - INJECT(enable, 0x0044BE10, WinPlayFMV); - INJECT(enable, 0x0044C0F0, WinStopFMV); - INJECT(enable, 0x0044C450, S_PlayFMV); - INJECT(enable, 0x0044C460, S_IntroFMV); } static void M_DecompSkidoo(const bool enable) @@ -392,38 +240,6 @@ static void M_GameBuf(bool enable) INJECT(enable, 0x0044D740, GameBuf_Free); } -static void M_HWR(bool enable) -{ - INJECT(enable, 0x0044CFE0, HWR_InitState); - INJECT(enable, 0x0044D110, HWR_ResetTexSource); - INJECT(enable, 0x0044D140, HWR_ResetColorKey); - INJECT(enable, 0x0044D170, HWR_ResetZBuffer); - INJECT(enable, 0x0044D1D0, HWR_TexSource); - INJECT(enable, 0x0044D200, HWR_EnableColorKey); - INJECT(enable, 0x0044D250, HWR_EnableZBuffer); - INJECT(enable, 0x0044D2E0, HWR_BeginScene); - INJECT(enable, 0x0044D310, HWR_DrawPolyList); - INJECT(enable, 0x0044D490, HWR_LoadTexturePages); - INJECT(enable, 0x0044D520, HWR_FreeTexturePages); - INJECT(enable, 0x0044D570, HWR_GetPageHandles); - INJECT(enable, 0x0044D5B0, HWR_VertexBufferFull); - INJECT(enable, 0x0044D5E0, HWR_Init); -} - -static void M_Background(const bool enable) -{ - INJECT(enable, 0x00443990, BGND_Make640x480); - INJECT(enable, 0x00443B50, BGND_AddTexture); - INJECT(enable, 0x00443C10, BGND_GetPageHandles); - INJECT(enable, 0x00443C50, BGND_DrawInGameBlack); - INJECT(enable, 0x00443CB0, DrawQuad); - INJECT(enable, 0x00443D90, BGND_DrawInGameBackground); - INJECT(enable, 0x00443FB0, DrawTextureTile); - INJECT(enable, 0x00444210, BGND_CenterLighting); - INJECT(enable, 0x004444C0, BGND_Free); - INJECT(enable, 0x00444510, BGND_Init); -} - static void M_Camera(const bool enable) { INJECT(enable, 0x004105A0, Camera_Initialise); @@ -452,7 +268,9 @@ static void M_Collide(const bool enable) static void M_Game(const bool enable) { INJECT(enable, 0x00414390, Game_Control); + INJECT(enable, 0x00412120, Game_ControlCinematic); INJECT(enable, 0x00418990, Game_Draw); + INJECT(enable, 0x00411F60, Game_LoopCinematic); INJECT(enable, 0x00418950, Game_DrawCinematic); INJECT(enable, 0x0044C480, Game_Start); INJECT(enable, 0x0044C5D0, Game_Loop); @@ -542,16 +360,6 @@ static void M_Requester(const bool enable) INJECT(enable, 0x00426270, Requester_SetSize); } -static void M_Option(const bool enable) -{ - INJECT(enable, 0x0044EDC0, Option_DoInventory); - INJECT(enable, 0x0044EED0, Option_Passport); - INJECT(enable, 0x0044F520, Option_Detail); - INJECT(enable, 0x0044F800, Option_Sound); - INJECT(enable, 0x0044FCA0, Option_Compass); - INJECT(enable, 0x0044FE20, Option_Controls); -} - static void M_Text(const bool enable) { INJECT(enable, 0x00440450, Text_Init); @@ -591,70 +399,17 @@ static void M_Output(const bool enable) INJECT(enable, 0x00401F40, Output_CalcVerticeLight); INJECT(enable, 0x004020B0, Output_CalcRoomVertices); INJECT(enable, 0x00402330, Output_RotateLight); - INJECT(enable, 0x00402400, Output_InitPolyList); - INJECT(enable, 0x00402430, Output_SortPolyList); - INJECT(enable, 0x00402470, Output_QuickSort); - INJECT(enable, 0x00402540, Output_PrintPolyList); INJECT(enable, 0x00402580, Output_AlterFOV); - INJECT(enable, 0x00402700, Output_Init); - INJECT(enable, 0x00402970, Output_DrawPolyLine); - INJECT(enable, 0x00402B10, Output_DrawPolyFlat); - INJECT(enable, 0x00402B50, Output_DrawPolyTrans); - INJECT(enable, 0x00402B90, Output_DrawPolyGouraud); - INJECT(enable, 0x00402BD0, Output_DrawPolyGTMap); - INJECT(enable, 0x00402C10, Output_DrawPolyWGTMap); - INJECT(enable, 0x00402C50, Output_XGenX); - INJECT(enable, 0x00402D30, Output_XGenXG); - INJECT(enable, 0x00402E80, Output_XGenXGUV); - INJECT(enable, 0x004030A0, Output_XGenXGUVPerspFP); - INJECT(enable, 0x00403330, Output_GTMapPersp32FP); - INJECT(enable, 0x00404300, Output_WGTMapPersp32FP); - INJECT(enable, 0x004057D0, Output_DrawPolyGTMapPersp); - INJECT(enable, 0x00405810, Output_DrawPolyWGTMapPersp); - INJECT(enable, 0x00405850, Output_VisibleZClip); - INJECT(enable, 0x004058C0, Output_ZedClipper); - INJECT(enable, 0x00405A00, Output_XYGUVClipper); - INJECT(enable, 0x00405F20, Output_InsertObjectGT4); - INJECT(enable, 0x00406980, Output_InsertObjectGT3); - INJECT(enable, 0x00407200, Output_XYGClipper); - INJECT(enable, 0x00407630, Output_InsertObjectG4); - INJECT(enable, 0x00407A10, Output_InsertObjectG3); - INJECT(enable, 0x00407D30, Output_XYClipper); - INJECT(enable, 0x00408000, Output_InsertTrans8); - INJECT(enable, 0x004084B0, Output_InsertTransQuad); - INJECT(enable, 0x00408590, Output_InsertFlatRect); - INJECT(enable, 0x00408660, Output_InsertLine); - INJECT(enable, 0x00408720, Output_InsertGT3_ZBuffered); - INJECT(enable, 0x00408D70, Output_DrawClippedPoly_Textured); - INJECT(enable, 0x00408EB0, Output_InsertGT4_ZBuffered); - INJECT(enable, 0x00409300, Output_InsertObjectGT4_ZBuffered); - INJECT(enable, 0x004093A0, Output_InsertObjectGT3_ZBuffered); - INJECT(enable, 0x00409450, Output_InsertObjectG4_ZBuffered); - INJECT(enable, 0x004097F0, Output_DrawPoly_Gouraud); - INJECT(enable, 0x004098F0, Output_InsertObjectG3_ZBuffered); - INJECT(enable, 0x00409BD0, Output_InsertFlatRect_ZBuffered); - INJECT(enable, 0x00409DA0, Output_InsertLine_ZBuffered); - INJECT(enable, 0x00409EE0, Output_InsertGT3_Sorted); - INJECT(enable, 0x0040A5F0, Output_InsertClippedPoly_Textured); - INJECT(enable, 0x0040A7A0, Output_InsertGT4_Sorted); - INJECT(enable, 0x0040AC80, Output_InsertObjectGT4_Sorted); - INJECT(enable, 0x0040AD10, Output_InsertObjectGT3_Sorted); - INJECT(enable, 0x0040ADB0, Output_InsertObjectG4_Sorted); - INJECT(enable, 0x0040B1F0, Output_InsertPoly_Gouraud); - INJECT(enable, 0x0040B370, Output_InsertObjectG3_Sorted); - INJECT(enable, 0x0040B6C0, Output_InsertSprite_Sorted); - INJECT(enable, 0x0040BA10, Output_InsertFlatRect_Sorted); - INJECT(enable, 0x0040BB90, Output_InsertLine_Sorted); - INJECT(enable, 0x0040BCC0, Output_InsertTrans8_Sorted); - INJECT(enable, 0x0040BE60, Output_InsertTransQuad_Sorted); - INJECT(enable, 0x0040BFA0, Output_InsertSprite); INJECT(enable, 0x0040C050, Output_DrawSprite); INJECT(enable, 0x0040C320, Output_DrawPickup); INJECT(enable, 0x0040C3B0, Output_InsertRoomSprite); INJECT(enable, 0x0040C510, Output_DrawScreenSprite2D); INJECT(enable, 0x0040C5B0, Output_DrawScreenSprite); - INJECT(enable, 0x0040C650, Output_DrawScaledSpriteC); INJECT(enable, 0x0041BA50, Output_InsertPolygons_I); + INJECT(enable, 0x00450F80, Output_InsertShadow); + INJECT(enable, 0x00451800, Output_DrawHealthBar); + INJECT(enable, 0x004519D0, Output_DrawAirBar); + INJECT(enable, 0x00451BD0, Output_AnimateTextures); } static void M_Music(const bool enable) @@ -782,7 +537,6 @@ static void M_Inventory(const bool enable) INJECT(enable, 0x00423310, Inv_Construct); INJECT(enable, 0x00423470, Inv_SelectMeshes); INJECT(enable, 0x00423500, Inv_AnimateInventoryItem); - INJECT(enable, 0x00423590, Inv_DrawInventoryItem); INJECT(enable, 0x004239E0, Inv_DoInventoryPicture); INJECT(enable, 0x004239F0, Inv_DoInventoryBackground); INJECT(enable, 0x00423B30, Inv_InitColors); @@ -1200,17 +954,9 @@ static void M_Objects(const bool enable) INJECT(enable, 0x00442F40, Ember_Control); } -static void M_S_FlaggedString(const bool enable) -{ - INJECT(enable, 0x00445F00, S_FlaggedString_Delete); - INJECT(enable, 0x00446100, S_FlaggedString_InitAdapter); - INJECT(enable, 0x00447550, S_FlaggedString_Create); -} - void Inject_Exec(void) { M_DecompGeneral(true); - M_DecompFMV(true); M_DecompSkidoo(true); M_DecompStats(true); M_DecompEffects(true); @@ -1218,8 +964,6 @@ void Inject_Exec(void) M_DecompSavegame(true); M_GameBuf(true); - M_HWR(true); - M_Background(true); M_Camera(true); M_Collide(true); @@ -1229,7 +973,6 @@ void Inject_Exec(void) M_Matrix(true); M_Shell(true); M_Requester(true); - M_Option(true); M_Text(true); M_Input(true); M_Output(true); @@ -1260,6 +1003,4 @@ void Inject_Exec(void) M_Box(true); M_Lot(true); M_Objects(true); - - M_S_FlaggedString(true); } diff --git a/src/tr2/lib/cpp.h b/src/tr2/lib/cpp.h deleted file mode 100644 index 10e7e5d24..000000000 --- a/src/tr2/lib/cpp.h +++ /dev/null @@ -1,2 +0,0 @@ -#define operator_delete ((void __cdecl (*)(void *mem))0x00459050) -#define operator_new ((void *__cdecl (*)(size_t size))0x00459060) diff --git a/src/tr2/lib/ddraw.h b/src/tr2/lib/ddraw.h deleted file mode 100644 index b5568dcfa..000000000 --- a/src/tr2/lib/ddraw.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include - -#ifdef DirectDrawCreate - #undef DirectDrawCreate -#endif - -#define DirectDrawCreate \ - ((HRESULT(__stdcall *)( \ - GUID * driver_guid, LPDIRECTDRAW * ddraw, LPUNKNOWN outer))0x00458CF4) - -#ifdef DirectDrawEnumerate - #undef DirectDrawEnumerate -#endif - -#define DirectDrawEnumerate \ - ((HRESULT(__stdcall *)( \ - LPDDENUMCALLBACKA lpCallback, LPVOID lpContext))0x00458CFA) diff --git a/src/tr2/lib/dinput.h b/src/tr2/lib/dinput.h deleted file mode 100644 index cb0abd4a5..000000000 --- a/src/tr2/lib/dinput.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include - -#define DirectInputCreate \ - ((HRESULT(__stdcall *)( \ - HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUT * lpDirectInput, \ - LPUNKNOWN punkOuter))0x00457CC0) diff --git a/src/tr2/lib/dsound.h b/src/tr2/lib/dsound.h deleted file mode 100644 index 875275c46..000000000 --- a/src/tr2/lib/dsound.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include - -#define DirectSoundCreate \ - ((HRESULT(__stdcall *)( \ - LPCGUID pcGuidDevice, LPDIRECTSOUND * ppDS, \ - LPUNKNOWN pUnkOuter))0x00458CEE) -#define DirectSoundEnumerateA \ - ((HRESULT(__stdcall *)( \ - LPDSENUMCALLBACKA pDSEnumCallback, LPVOID pContext))0x00458CE8) diff --git a/src/tr2/lib/player.h b/src/tr2/lib/player.h deleted file mode 100644 index 10e13cae1..000000000 --- a/src/tr2/lib/player.h +++ /dev/null @@ -1,30 +0,0 @@ -static int(__cdecl *Movie_GetCurrentFrame)(LPVOID); -static int(__cdecl *Movie_GetFormat)(LPVOID); -static int(__cdecl *Movie_GetSoundChannels)(LPVOID); -static int(__cdecl *Movie_GetSoundPrecision)(LPVOID); -static int(__cdecl *Movie_GetSoundRate)(LPVOID); -static int(__cdecl *Movie_GetTotalFrames)(LPVOID); -static int(__cdecl *Movie_GetXSize)(LPVOID); -static int(__cdecl *Movie_GetYSize)(LPVOID); -static int(__cdecl *Movie_SetSyncAdjust)(LPVOID, LPVOID, DWORD); -static int(__cdecl *Player_BlankScreen)(DWORD, DWORD, DWORD, DWORD); -static int(__cdecl *Player_GetDSErrorCode)(); -static int(__cdecl *Player_InitMovie)(LPVOID, DWORD, DWORD, LPCTSTR, DWORD); -static int(__cdecl *Player_InitMoviePlayback)(LPVOID, LPVOID, LPVOID); -static int(__cdecl *Player_InitPlaybackMode)(HWND, LPVOID, DWORD, DWORD); -static int(__cdecl *Player_InitSound)( - LPVOID, DWORD, DWORD, BOOL, DWORD, DWORD, DWORD, DWORD, DWORD); -static int(__cdecl *Player_InitSoundSystem)(HWND); -static int(__cdecl *Player_InitVideo)( - LPVOID, LPVOID, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, - DWORD, DWORD, DWORD); -static int(__cdecl *Player_PassInDirectDrawObject)(LPDIRECTDRAW3); -static int(__cdecl *Player_PlayFrame)( - LPVOID, LPVOID, LPVOID, DWORD, LPRECT, DWORD, DWORD, DWORD); -static int(__cdecl *Player_ReturnPlaybackMode)(BOOL); -static int(__cdecl *Player_ShutDownMovie)(LPVOID); -static int(__cdecl *Player_ShutDownSound)(LPVOID); -static int(__cdecl *Player_ShutDownSoundSystem)(); -static int(__cdecl *Player_ShutDownVideo)(LPVOID); -static int(__cdecl *Player_StartTimer)(LPVOID); -static int(__cdecl *Player_StopTimer)(LPVOID); diff --git a/src/tr2/lib/winmm.c b/src/tr2/lib/winmm.c deleted file mode 100644 index 67ec3cfbe..000000000 --- a/src/tr2/lib/winmm.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "lib/winmm.h" - -MMRESULT(__stdcall *g_MM_auxGetDevCapsA) -(UINT_PTR uDeviceID, LPAUXCAPSA pac, UINT cbac) = NULL; - -UINT(__stdcall *g_MM_auxGetNumDevs)(void) = NULL; - -MMRESULT(__stdcall *g_MM_auxSetVolume)(UINT uDeviceID, DWORD dwVolume) = NULL; - -MCIERROR(__stdcall *g_MM_mciSendCommandA) -(MCIDEVICEID mciId, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2) = NULL; - -MCIERROR(__stdcall *g_MM_mciSendStringA) -(LPCSTR lpszCommand, LPSTR lpszReturnString, UINT cchReturn, - HANDLE hwndCallback) = NULL; - -void WinMM_Load(void) -{ - HANDLE winmm = LoadLibrary("winmm.dll"); - - auxGetNumDevs = (UINT(__stdcall *)())GetProcAddress(winmm, "auxGetNumDevs"); - - auxSetVolume = (MMRESULT(__stdcall *)(UINT, DWORD))GetProcAddress( - winmm, "auxSetVolume"); - - mciSendCommandA = - (MCIERROR(__stdcall *)(MCIDEVICEID, UINT, DWORD_PTR, DWORD_PTR)) - GetProcAddress(winmm, "mciSendCommandA"); - - mciSendStringA = (MCIERROR(__stdcall *)( - LPCSTR, LPSTR, UINT, HANDLE))GetProcAddress(winmm, "mciSendStringA"); -} diff --git a/src/tr2/lib/winmm.h b/src/tr2/lib/winmm.h deleted file mode 100644 index fc3bb2eeb..000000000 --- a/src/tr2/lib/winmm.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include - -extern MMRESULT(__stdcall *g_MM_auxGetDevCapsA)( - UINT_PTR uDeviceID, LPAUXCAPSA pac, UINT cbac); - -extern UINT(__stdcall *g_MM_auxGetNumDevs)(void); - -extern MMRESULT(__stdcall *g_MM_auxSetVolume)(UINT uDeviceID, DWORD dwVolume); - -extern MCIERROR(__stdcall *g_MM_mciSendCommandA)( - MCIDEVICEID mciId, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2); - -extern MCIERROR(__stdcall *g_MM_mciSendStringA)( - LPCSTR lpszCommand, LPSTR lpszReturnString, UINT cchReturn, - HANDLE hwndCallback); - -void WinMM_Load(void); - -#define auxGetDevCapsA g_MM_auxGetDevCapsA -#define auxGetNumDevs g_MM_auxGetNumDevs -#define auxSetVolume g_MM_auxSetVolume -#define mciSendCommandA g_MM_mciSendCommandA -#define mciSendStringA g_MM_mciSendStringA diff --git a/src/tr2/main_dll.c b/src/tr2/main_dll.c index 06336f7b5..5135f72ae 100644 --- a/src/tr2/main_dll.c +++ b/src/tr2/main_dll.c @@ -1,5 +1,4 @@ #include "inject_exec.h" -#include "lib/winmm.h" #include #include @@ -16,7 +15,6 @@ DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) Log_Init(File_GetFullPath("TR2X.log")); LOG_DEBUG("Injected\n"); - WinMM_Load(); Inject_Exec(); break; diff --git a/src/tr2/meson.build b/src/tr2/meson.build index 669c9f9fd..b7ecb8e5e 100644 --- a/src/tr2/meson.build +++ b/src/tr2/meson.build @@ -79,14 +79,12 @@ dll_sources = [ 'config.c', 'config_map.c', 'decomp/decomp.c', - 'decomp/decomp2.c', 'decomp/effects.c', 'decomp/flares.c', 'decomp/fmv.c', 'decomp/savegame.c', 'decomp/skidoo.c', 'decomp/stats.c', - 'game/background.c', 'game/backpack.c', 'game/box.c', 'game/camera.c', @@ -97,6 +95,7 @@ dll_sources = [ 'game/creature.c', 'game/demo.c', 'game/effects.c', + 'game/fader.c', 'game/game.c', 'game/game_string.c', 'game/gamebuf.c', @@ -107,7 +106,6 @@ dll_sources = [ 'game/gun/gun_misc.c', 'game/gun/gun_pistols.c', 'game/gun/gun_rifle.c', - 'game/hwr.c', 'game/inject.c', 'game/input.c', 'game/inventory/backpack.c', @@ -232,6 +230,11 @@ dll_sources = [ 'game/output.c', 'game/overlay.c', 'game/random.c', + 'game/render/common.c', + 'game/render/hwr.c', + 'game/render/priv.c', + 'game/render/swr.c', + 'game/render/util.c', 'game/requester.c', 'game/room.c', 'game/room_draw.c', @@ -254,9 +257,7 @@ dll_sources = [ 'global/vars.c', 'inject_exec.c', 'inject_util.c', - 'lib/winmm.c', 'main_dll.c', - 'specific/s_flagged_string.c', dll_resources, ] diff --git a/src/tr2/specific/s_flagged_string.c b/src/tr2/specific/s_flagged_string.c deleted file mode 100644 index 44833f240..000000000 --- a/src/tr2/specific/s_flagged_string.c +++ /dev/null @@ -1,49 +0,0 @@ -#include "specific/s_flagged_string.h" - -#include "global/types.h" - -void __thiscall S_FlaggedString_Create(STRING_FLAGGED *string, int32_t size) -{ - string->content = malloc(size); - if (string->content != NULL) { - *string->content = '\0'; - string->is_valid = true; - } -} - -void __thiscall S_FlaggedString_InitAdapter(DISPLAY_ADAPTER *adapter) -{ - S_FlaggedString_Create(&adapter->driver_desc, 256); - S_FlaggedString_Create(&adapter->driver_name, 256); -} - -void __thiscall S_FlaggedString_Delete(STRING_FLAGGED *string) -{ - if (string->is_valid && string->content) { - free(string->content); - string->content = NULL; - string->is_valid = false; - } -} - -bool S_FlaggedString_Copy(STRING_FLAGGED *dst, STRING_FLAGGED *src) -{ - if (dst == NULL || src == NULL || dst == src || !src->is_valid) { - return false; - } - - size_t src_len = lstrlen(src->content); - dst->is_valid = false; - dst->content = malloc(src_len + 1); - if (dst->content == NULL) { - return false; - } - - if (src_len > 0) { - lstrcpy(dst->content, src->content); - } else { - *dst->content = 0; - } - dst->is_valid = true; - return true; -} diff --git a/src/tr2/specific/s_flagged_string.h b/src/tr2/specific/s_flagged_string.h deleted file mode 100644 index 50cb325ea..000000000 --- a/src/tr2/specific/s_flagged_string.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include "global/types.h" - -#include - -void __thiscall S_FlaggedString_Create(STRING_FLAGGED *string, int32_t size); -void __thiscall S_FlaggedString_Delete(STRING_FLAGGED *string); -void __thiscall S_FlaggedString_InitAdapter(DISPLAY_ADAPTER *adapter); -bool S_FlaggedString_Copy(STRING_FLAGGED *dst, STRING_FLAGGED *src); diff --git a/tools/sort_imports b/tools/sort_imports index 11a8b8ad3..a43adce9c 100755 --- a/tools/sort_imports +++ b/tools/sort_imports @@ -58,7 +58,12 @@ def main() -> None: "game/music/music_main.c": "game/music.h", }, fix_map={}, - forced_order=["", ""], + forced_order=[ + "", + "", + "", + "" + ], ) sort_imports( @@ -80,6 +85,7 @@ def main() -> None: }, fix_map={}, forced_order=[ + "", "", "", "", diff --git a/tools/tr2/config/TR2X_ConfigTool/Resources/Lang/en.json b/tools/tr2/config/TR2X_ConfigTool/Resources/Lang/en.json index a567aa392..000603845 100644 --- a/tools/tr2/config/TR2X_ConfigTool/Resources/Lang/en.json +++ b/tools/tr2/config/TR2X_ConfigTool/Resources/Lang/en.json @@ -10,6 +10,11 @@ "screenshot_format": { "jpg": "JPEG", "png": "PNG" + }, + "aspect_mode": { + "any": "Any", + "16:9": "16:9", + "4:3": "4:3" } }, "Properties": { @@ -41,9 +46,21 @@ "Title": "Key item pre-selection", "Description": "When Lara presses action against a keyhole or puzzle slot, and she has the corresponding item in the inventory, that item will be pre-selected." }, + "aspect_mode": { + "Title": "Aspect mode", + "Description": "Set the aspect ratio of the game output." + }, "screenshot_format": { "Title": "Screenshot format", "Description": "Screenshot file format." + }, + "enable_lara_mic" : { + "Title": "Microphone at Lara", + "Description": "Set the microphone to be at Lara's position. If disabled, the microphone will be at the camera's position." + }, + "enable_fade_effects": { + "Title": "Fade effects", + "Description": "Enable fade transitions, for example between credit graphics." } } } diff --git a/tools/tr2/config/TR2X_ConfigTool/Resources/specification.json b/tools/tr2/config/TR2X_ConfigTool/Resources/specification.json index 53c991675..6fbf557af 100644 --- a/tools/tr2/config/TR2X_ConfigTool/Resources/specification.json +++ b/tools/tr2/config/TR2X_ConfigTool/Resources/specification.json @@ -3,6 +3,11 @@ "screenshot_format": [ "jpg", "png" + ], + "aspect_mode": [ + "any", + "16:9", + "4:3" ] }, "CategorisedProperties": [ @@ -70,6 +75,12 @@ "DataType": "Bool", "DefaultValue": true }, + { + "Field": "aspect_mode", + "DataType": "Enum", + "EnumKey": "aspect_mode", + "DefaultValue": "any" + }, { "Field": "screenshot_format", "DataType": "Enum", @@ -82,14 +93,22 @@ "ID": "sound", "Image": "Graphics/graphic6.jpg", "Properties": [ - + { + "Field": "enable_lara_mic", + "DataType": "Bool", + "DefaultValue": false + } ] }, { "ID": "ui", "Image": "Graphics/graphic7.jpg", "Properties": [ - + { + "Field": "enable_fade_effects", + "DataType": "Bool", + "DefaultValue": true + } ] } ] diff --git a/tools/tr2/generate_funcs b/tools/tr2/generate_funcs index 66143aa66..d0dde23ec 100755 --- a/tools/tr2/generate_funcs +++ b/tools/tr2/generate_funcs @@ -7,7 +7,7 @@ from shared.paths import TR2Paths FUNCS_H_FILE = TR2Paths.src_dir / "global/funcs.h" VARS_H_FILE = TR2Paths.src_dir / "global/vars_decomp.h" -TYPES_H_FILE = TR2Paths.src_dir / "global/types.h" +TYPES_H_FILE = TR2Paths.src_dir / "global/types_decomp.h" COMMON_HEADER = [ @@ -146,10 +146,6 @@ def make_types_h(types: list[str]) -> None: "#include ", "#include ", "", - "#include ", - "#include ", - "#include ", - "#include ", "#include ", "#include ", "#include ",