tr2: use hybrid OpenGL/DirectX rendering

This commit is contained in:
Marcin Kurczewski 2024-12-09 22:59:17 +01:00
parent f1b6a74f34
commit 8941bfdf04
No known key found for this signature in database
GPG key ID: CC65E6FD28CAE42A
93 changed files with 9117 additions and 12272 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -69,10 +69,10 @@
</g>
<g transform="translate(0 116)">
<text x="0" y="7.50">Tomb2.exe progress according to the physical function order:</text>
<text class="todo" style="font-size: 12px; " x="747" y="9"><tspan text-anchor="end"><tspan class="decompiled">80.71% (1004)</tspan> · <tspan class="known">16.88% (210)</tspan> · <tspan class="todo">0% (0)</tspan> · <tspan class="unused">2.41% (30)</tspan></tspan></text>
<text class="todo" style="font-size: 12px; " x="747" y="9"><tspan text-anchor="end"><tspan class="decompiled">86.33% (1074)</tspan> · <tspan class="known">11.25% (140)</tspan> · <tspan class="todo">0% (0)</tspan> · <tspan class="unused">2.41% (30)</tspan></tspan></text>
<g transform="translate(0 20)">
<rect width="602.88" height="6" x="0" y="0" class="decompiled"/>
<rect width="126.10" height="6" x="602.88" y="0" class="known"/>
<rect width="644.92" height="6" x="0" y="0" class="decompiled"/>
<rect width="84.07" height="6" x="644.92" y="0" class="known"/>
<rect width="18.01" height="6" x="728.99" y="0" class="unused"/>
</g>
<g transform="translate(0 31)">
@ -874,9 +874,9 @@
<rect width="12" height="12" x="675" y="225" class="decompiled"><title>int32_t __cdecl BGND_AddTexture(int32_t tile_idx, BYTE *bitmap, int32_t pal_index, RGB_888 *bmp_pal);</title></rect>
<rect width="12" height="12" x="690" y="225" class="decompiled"><title>void __cdecl BGND_GetPageHandles(void);</title></rect>
<rect width="12" height="12" x="705" y="225" class="decompiled"><title>void __cdecl BGND_DrawInGameBlack(void);</title></rect>
<rect width="12" height="12" x="720" y="225" class="decompiled"><title>void __cdecl DrawQuad(float sx, float sy, float width, float height, D3DCOLOR color);</title></rect>
<rect width="12" height="12" x="720" y="225" class="decompiled"><title>void __cdecl BGND_DrawQuad(float sx, float sy, float width, float height, D3DCOLOR color);</title></rect>
<rect width="12" height="12" x="735" y="225" class="decompiled"><title>void __cdecl BGND_DrawInGameBackground(void);</title></rect>
<rect width="12" height="12" x="0" y="240" class="decompiled"><title>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);</title></rect>
<rect width="12" height="12" x="0" y="240" class="decompiled"><title>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);</title></rect>
<rect width="12" height="12" x="15" y="240" class="decompiled"><title>D3DCOLOR __cdecl BGND_CenterLighting(int32_t x, int32_t y, int32_t width, int32_t height);</title></rect>
<rect width="12" height="12" x="30" y="240" class="decompiled"><title>void __cdecl BGND_Free(void);</title></rect>
<rect width="12" height="12" x="45" y="240" class="decompiled"><title>bool __cdecl BGND_Init(void);</title></rect>
@ -1028,7 +1028,7 @@
<rect width="12" height="12" x="735" y="270" class="decompiled"><title>void __cdecl GameApplySettings(APP_SETTINGS *new_settings);</title></rect>
<rect width="12" height="12" x="0" y="285" class="decompiled"><title>void __cdecl UpdateGameResolution(void);</title></rect>
<rect width="12" height="12" x="15" y="285" class="decompiled"><title>LPCTSTR __cdecl DecodeErrorMessage(DWORD error_code);</title></rect>
<rect width="12" height="12" x="30" y="285" class="known"><title>BOOL __cdecl ReadFileSync(HANDLE handle, LPVOID lpBuffer, DWORD nBytesToRead, LPDWORD lpnBytesRead, LPOVERLAPPED lpOverlapped);</title></rect>
<rect width="12" height="12" x="30" y="285" class="decompiled"><title>BOOL __cdecl ReadFileSync(HANDLE handle, LPVOID lpBuffer, DWORD nBytesToRead, LPDWORD lpnBytesRead, LPOVERLAPPED lpOverlapped);</title></rect>
<rect width="12" height="12" x="45" y="285" class="decompiled"><title>BOOL __cdecl Level_LoadTexturePages(HANDLE handle);</title></rect>
<rect width="12" height="12" x="60" y="285" class="decompiled"><title>BOOL __cdecl Level_LoadRooms(HANDLE handle);</title></rect>
<rect width="12" height="12" x="75" y="285" class="decompiled"><title>void __cdecl AdjustTextureUVs(bool reset_uv_add);</title></rect>
@ -1141,14 +1141,14 @@
<rect width="12" height="12" x="180" y="315" class="decompiled"><title>void __cdecl S_OutputPolyList(void);</title></rect>
<rect width="12" height="12" x="195" y="315" class="known"><title>int32_t __cdecl S_GetObjectBounds(const BOUNDS_16 *bounds);</title></rect>
<rect width="12" height="12" x="210" y="315" class="decompiled"><title>void __cdecl S_InsertBackPolygon(int32_t x0, int32_t y0, int32_t x1, int32_t y1);</title></rect>
<rect width="12" height="12" x="225" y="315" class="known"><title>void __cdecl S_PrintShadow(int16_t radius, const BOUNDS_16 *bounds, const ITEM *item);</title></rect>
<rect width="12" height="12" x="225" y="315" class="decompiled"><title>void __cdecl Output_InsertShadow(int16_t radius, const BOUNDS_16 *bounds, const ITEM *item);</title></rect>
<rect width="12" height="12" x="240" y="315" class="known"><title>void __cdecl S_CalculateLight(int32_t x, int32_t y, int32_t z, int16_t room_num);</title></rect>
<rect width="12" height="12" x="255" y="315" class="known"><title>void __cdecl S_CalculateStaticLight(int16_t adder);</title></rect>
<rect width="12" height="12" x="270" y="315" class="known"><title>void __cdecl S_CalculateStaticMeshLight(int32_t x, int32_t y, int32_t z, int32_t shade_1, int32_t shade_2, ROOM *room);</title></rect>
<rect width="12" height="12" x="285" y="315" class="known"><title>void __cdecl S_LightRoom(ROOM *room);</title></rect>
<rect width="12" height="12" x="300" y="315" class="known"><title>void __cdecl S_DrawHealthBar(int32_t percent);</title></rect>
<rect width="12" height="12" x="315" y="315" class="known"><title>void __cdecl S_DrawAirBar(int32_t percent);</title></rect>
<rect width="12" height="12" x="330" y="315" class="known"><title>void __cdecl AnimateTextures(int32_t ticks);</title></rect>
<rect width="12" height="12" x="300" y="315" class="decompiled"><title>void __cdecl Output_DrawHealthBar(int32_t percent);</title></rect>
<rect width="12" height="12" x="315" y="315" class="decompiled"><title>void __cdecl Output_DrawAirBar(int32_t percent);</title></rect>
<rect width="12" height="12" x="330" y="315" class="decompiled"><title>void __cdecl Output_AnimateTextures(int32_t ticks);</title></rect>
<rect width="12" height="12" x="345" y="315" class="known"><title>void __cdecl S_SetupBelowWater(BOOL underwater);</title></rect>
<rect width="12" height="12" x="360" y="315" class="known"><title>void __cdecl S_SetupAboveWater(BOOL underwater);</title></rect>
<rect width="12" height="12" x="375" y="315" class="known"><title>void __cdecl S_AnimateTextures(int32_t ticks);</title></rect>
@ -1161,44 +1161,44 @@
<rect width="12" height="12" x="480" y="315" class="decompiled"><title>void __cdecl ScreenClear(bool is_phd_win_size);</title></rect>
<rect width="12" height="12" x="495" y="315" class="decompiled"><title>void __cdecl S_CopyScreenToBuffer(void);</title></rect>
<rect width="12" height="12" x="510" y="315" class="decompiled"><title>void __cdecl S_CopyBufferToScreen(void);</title></rect>
<rect width="12" height="12" x="525" y="315" class="known"><title>BOOL __cdecl DecompPCX(const uint8_t *pcx, size_t pcx_size, LPBYTE pic, RGB_888 *pal);</title></rect>
<rect width="12" height="12" x="525" y="315" class="decompiled"><title>BOOL __cdecl DecompPCX(const uint8_t *pcx, size_t pcx_size, LPBYTE pic, RGB_888 *pal);</title></rect>
<rect width="12" height="12" x="540" y="315" class="unused"><title>sub_4523A0</title></rect>
<rect width="12" height="12" x="555" y="315" class="unused"><title>sub_4523B0</title></rect>
<rect width="12" height="12" x="570" y="315" class="known"><title>bool __cdecl OpenGameRegistryKey(LPCTSTR key);</title></rect>
<rect width="12" height="12" x="585" y="315" class="known"><title>LONG __cdecl CloseGameRegistryKey(void);</title></rect>
<rect width="12" height="12" x="600" y="315" class="known"><title>bool __cdecl SE_WriteAppSettings(APP_SETTINGS *settings);</title></rect>
<rect width="12" height="12" x="570" y="315" class="decompiled"><title>bool __cdecl OpenGameRegistryKey(LPCTSTR key);</title></rect>
<rect width="12" height="12" x="585" y="315" class="decompiled"><title>LONG __cdecl CloseGameRegistryKey(void);</title></rect>
<rect width="12" height="12" x="600" y="315" class="decompiled"><title>bool __cdecl SE_WriteAppSettings(APP_SETTINGS *settings);</title></rect>
<rect width="12" height="12" x="615" y="315" class="decompiled"><title>int32_t __cdecl SE_ReadAppSettings(APP_SETTINGS *settings);</title></rect>
<rect width="12" height="12" x="630" y="315" class="known"><title>bool __cdecl SE_GraphicsTestStart(void);</title></rect>
<rect width="12" height="12" x="645" y="315" class="known"><title>void __cdecl SE_GraphicsTestFinish(void);</title></rect>
<rect width="12" height="12" x="660" y="315" class="known"><title>int32_t __cdecl SE_GraphicsTestExecute(void);</title></rect>
<rect width="12" height="12" x="675" y="315" class="known"><title>int32_t __cdecl SE_GraphicsTest(void);</title></rect>
<rect width="12" height="12" x="690" y="315" class="known"><title>bool __cdecl SE_SoundTestStart(void);</title></rect>
<rect width="12" height="12" x="705" y="315" class="known"><title>void __cdecl SE_SoundTestFinish(void);</title></rect>
<rect width="12" height="12" x="720" y="315" class="known"><title>int32_t __cdecl SE_SoundTestExecute(void);</title></rect>
<rect width="12" height="12" x="735" y="315" class="known"><title>int32_t __cdecl SE_SoundTest(void);</title></rect>
<rect width="12" height="12" x="0" y="330" class="known"><title>int32_t __stdcall SE_PropSheetCallback(HWND hwndDlg, UINT uMsg, LPARAM lParam);</title></rect>
<rect width="12" height="12" x="15" y="330" class="known"><title>LRESULT __stdcall SE_NewPropSheetWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="12" height="12" x="30" y="330" class="known"><title>bool __cdecl SE_ShowSetupDialog(HWND hParent, bool isDefault);</title></rect>
<rect width="12" height="12" x="45" y="330" class="known"><title>INT_PTR __stdcall SE_GraphicsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="12" height="12" x="60" y="330" class="known"><title>void __cdecl SE_GraphicsDlgFullScreenModesUpdate(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="75" y="330" class="known"><title>void __cdecl SE_GraphicsAdapterSet(HWND hwndDlg, DISPLAY_ADAPTER_NODE *adapter);</title></rect>
<rect width="12" height="12" x="90" y="330" class="known"><title>void __cdecl SE_GraphicsDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="105" y="330" class="known"><title>void __cdecl SE_GraphicsDlgInit(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="120" y="330" class="known"><title>INT_PTR __stdcall SE_SoundDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="12" height="12" x="135" y="330" class="known"><title>void __cdecl SE_SoundAdapterSet(HWND hwndDlg, SOUND_ADAPTER_NODE *adapter);</title></rect>
<rect width="12" height="12" x="150" y="330" class="known"><title>void __cdecl SE_SoundDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="165" y="330" class="known"><title>void __cdecl SE_SoundDlgInit(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="180" y="330" class="known"><title>INT_PTR __stdcall SE_ControlsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="12" height="12" x="195" y="330" class="known"><title>void __cdecl SE_ControlsJoystickSet(HWND hwndDlg, JOYSTICK_NODE *joystick);</title></rect>
<rect width="12" height="12" x="210" y="330" class="known"><title>void __cdecl SE_ControlsDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="225" y="330" class="known"><title>void __cdecl SE_ControlsDlgInit(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="240" y="330" class="known"><title>INT_PTR __stdcall SE_OptionsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="12" height="12" x="255" y="330" class="known"><title>void __cdecl SE_OptionsDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="270" y="330" class="known"><title>void __cdecl SE_OptionsStrCat(LPTSTR *dstString, bool isEnabled, bool *isNext, LPCTSTR srcString);</title></rect>
<rect width="12" height="12" x="285" y="330" class="known"><title>INT_PTR __stdcall SE_AdvancedDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="12" height="12" x="300" y="330" class="known"><title>void __cdecl SE_AdvancedDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="315" y="330" class="known"><title>void __cdecl SE_AdvancedDlgInit(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="330" y="330" class="known"><title>HWND __cdecl SE_FindSetupDialog(void);</title></rect>
<rect width="12" height="12" x="630" y="315" class="decompiled"><title>bool __cdecl SE_GraphicsTestStart(void);</title></rect>
<rect width="12" height="12" x="645" y="315" class="decompiled"><title>void __cdecl SE_GraphicsTestFinish(void);</title></rect>
<rect width="12" height="12" x="660" y="315" class="decompiled"><title>int32_t __cdecl SE_GraphicsTestExecute(void);</title></rect>
<rect width="12" height="12" x="675" y="315" class="decompiled"><title>int32_t __cdecl SE_GraphicsTest(void);</title></rect>
<rect width="12" height="12" x="690" y="315" class="decompiled"><title>bool __cdecl SE_SoundTestStart(void);</title></rect>
<rect width="12" height="12" x="705" y="315" class="decompiled"><title>void __cdecl SE_SoundTestFinish(void);</title></rect>
<rect width="12" height="12" x="720" y="315" class="decompiled"><title>int32_t __cdecl SE_SoundTestExecute(void);</title></rect>
<rect width="12" height="12" x="735" y="315" class="decompiled"><title>int32_t __cdecl SE_SoundTest(void);</title></rect>
<rect width="12" height="12" x="0" y="330" class="decompiled"><title>int32_t __stdcall SE_PropSheetCallback(HWND hwndDlg, UINT uMsg, LPARAM lParam);</title></rect>
<rect width="12" height="12" x="15" y="330" class="decompiled"><title>LRESULT __stdcall SE_NewPropSheetWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="12" height="12" x="30" y="330" class="decompiled"><title>bool __cdecl SE_ShowSetupDialog(HWND hParent, bool isDefault);</title></rect>
<rect width="12" height="12" x="45" y="330" class="decompiled"><title>INT_PTR __stdcall SE_GraphicsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="12" height="12" x="60" y="330" class="decompiled"><title>void __cdecl SE_GraphicsDlgFullScreenModesUpdate(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="75" y="330" class="decompiled"><title>void __cdecl SE_GraphicsAdapterSet(HWND hwndDlg, DISPLAY_ADAPTER_NODE *adapter);</title></rect>
<rect width="12" height="12" x="90" y="330" class="decompiled"><title>void __cdecl SE_GraphicsDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="105" y="330" class="decompiled"><title>void __cdecl SE_GraphicsDlgInit(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="120" y="330" class="decompiled"><title>INT_PTR __stdcall SE_SoundDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="12" height="12" x="135" y="330" class="decompiled"><title>void __cdecl SE_SoundAdapterSet(HWND hwndDlg, SOUND_ADAPTER_NODE *adapter);</title></rect>
<rect width="12" height="12" x="150" y="330" class="decompiled"><title>void __cdecl SE_SoundDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="165" y="330" class="decompiled"><title>void __cdecl SE_SoundDlgInit(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="180" y="330" class="decompiled"><title>INT_PTR __stdcall SE_ControlsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="12" height="12" x="195" y="330" class="decompiled"><title>void __cdecl SE_ControlsJoystickSet(HWND hwndDlg, JOYSTICK_NODE *joystick);</title></rect>
<rect width="12" height="12" x="210" y="330" class="decompiled"><title>void __cdecl SE_ControlsDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="225" y="330" class="decompiled"><title>void __cdecl SE_ControlsDlgInit(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="240" y="330" class="decompiled"><title>INT_PTR __stdcall SE_OptionsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="12" height="12" x="255" y="330" class="decompiled"><title>void __cdecl SE_OptionsDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="270" y="330" class="decompiled"><title>void __cdecl SE_OptionsStrCat(LPTSTR *dstString, bool isEnabled, bool *isNext, LPCTSTR srcString);</title></rect>
<rect width="12" height="12" x="285" y="330" class="decompiled"><title>INT_PTR __stdcall SE_AdvancedDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="12" height="12" x="300" y="330" class="decompiled"><title>void __cdecl SE_AdvancedDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="315" y="330" class="decompiled"><title>void __cdecl SE_AdvancedDlgInit(HWND hwndDlg);</title></rect>
<rect width="12" height="12" x="330" y="330" class="decompiled"><title>HWND __cdecl SE_FindSetupDialog(void);</title></rect>
<rect width="12" height="12" x="345" y="330" class="decompiled"><title>BOOL __cdecl Shell_Main(void);</title></rect>
<rect width="12" height="12" x="360" y="330" class="decompiled"><title>int16_t __cdecl TitleSequence(void);</title></rect>
<rect width="12" height="12" x="375" y="330" class="known"><title>void __cdecl CheckCheatMode(void);</title></rect>
@ -1249,38 +1249,38 @@
<rect width="12" height="12" x="300" y="345" class="decompiled"><title>void __cdecl UpdateTicks(void);</title></rect>
<rect width="12" height="12" x="315" y="345" class="decompiled"><title>bool __cdecl TIME_Init(void);</title></rect>
<rect width="12" height="12" x="330" y="345" class="decompiled"><title>DWORD __cdecl Sync(void);</title></rect>
<rect width="12" height="12" x="345" y="345" class="known"><title>LPVOID __cdecl UT_LoadResource(LPCTSTR lpName, LPCTSTR lpType);</title></rect>
<rect width="12" height="12" x="345" y="345" class="decompiled"><title>LPVOID __cdecl UT_LoadResource(LPCTSTR lpName, LPCTSTR lpType);</title></rect>
<rect width="12" height="12" x="360" y="345" class="decompiled"><title>void __cdecl UT_InitAccurateTimer(void);</title></rect>
<rect width="12" height="12" x="375" y="345" class="decompiled"><title>double __cdecl UT_Microseconds(void);</title></rect>
<rect width="12" height="12" x="390" y="345" class="known"><title>BOOL __cdecl UT_CenterWindow(HWND hWnd);</title></rect>
<rect width="12" height="12" x="405" y="345" class="known"><title>LPTSTR __cdecl UT_FindArg(LPCTSTR str);</title></rect>
<rect width="12" height="12" x="420" y="345" class="known"><title>int32_t __cdecl UT_MessageBox(LPCTSTR lpText, HWND hWnd);</title></rect>
<rect width="12" height="12" x="435" y="345" class="known"><title>int32_t __cdecl UT_ErrorBox(UINT uID, HWND hWnd);</title></rect>
<rect width="12" height="12" x="450" y="345" class="known"><title>LPCTSTR __cdecl GuidBinaryToString(GUID *guid);</title></rect>
<rect width="12" height="12" x="465" y="345" class="known"><title>bool __cdecl GuidStringToBinary(LPCTSTR lpString, GUID *guid);</title></rect>
<rect width="12" height="12" x="480" y="345" class="known"><title>BOOL __cdecl OpenRegistryKey(LPCTSTR lpSubKey);</title></rect>
<rect width="12" height="12" x="495" y="345" class="known"><title>bool __cdecl IsNewRegistryKeyCreated(void);</title></rect>
<rect width="12" height="12" x="510" y="345" class="known"><title>LONG __cdecl CloseRegistryKey(void);</title></rect>
<rect width="12" height="12" x="525" y="345" class="known"><title>LONG __cdecl SetRegistryDwordValue(LPCTSTR lpValueName, DWORD value);</title></rect>
<rect width="12" height="12" x="540" y="345" class="known"><title>LONG __cdecl SetRegistryBoolValue(LPCTSTR lpValueName, bool value);</title></rect>
<rect width="12" height="12" x="555" y="345" class="known"><title>LONG __cdecl SetRegistryFloatValue(LPCTSTR lpValueName, double value);</title></rect>
<rect width="12" height="12" x="570" y="345" class="known"><title>LONG __cdecl SetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize);</title></rect>
<rect width="12" height="12" x="585" y="345" class="known"><title>LONG __cdecl SetRegistryStringValue(LPCTSTR lpValueName, LPCTSTR value, int32_t length);</title></rect>
<rect width="12" height="12" x="600" y="345" class="known"><title>LONG __cdecl DeleteRegistryValue(LPCTSTR lpValueName);</title></rect>
<rect width="12" height="12" x="615" y="345" class="known"><title>bool __cdecl GetRegistryDwordValue(LPCTSTR lpValueName, DWORD *pValue, DWORD defaultValue);</title></rect>
<rect width="12" height="12" x="630" y="345" class="known"><title>bool __cdecl GetRegistryBoolValue(LPCTSTR lpValueName, bool *pValue, bool defaultValue);</title></rect>
<rect width="12" height="12" x="645" y="345" class="known"><title>bool __cdecl GetRegistryFloatValue(LPCTSTR lpValueName, double *value, double defaultValue);</title></rect>
<rect width="12" height="12" x="660" y="345" class="known"><title>bool __cdecl GetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize, LPBYTE defaultValue);</title></rect>
<rect width="12" height="12" x="675" y="345" class="known"><title>bool __cdecl GetRegistryStringValue(LPCTSTR lpValueName, LPTSTR value, DWORD maxSize, LPCTSTR defaultValue);</title></rect>
<rect width="12" height="12" x="690" y="345" class="known"><title>bool __cdecl GetRegistryGuidValue(LPCTSTR lpValueName, GUID *value, GUID *defaultValue);</title></rect>
<rect width="12" height="12" x="705" y="345" class="known"><title>void __thiscall SE_ReleaseBitmapResource(BITMAP_RESOURCE *bmpRsrc);</title></rect>
<rect width="12" height="12" x="720" y="345" class="known"><title>void __thiscall SE_LoadBitmapResource(BITMAP_RESOURCE *bmpRsrc, LPCTSTR lpName);</title></rect>
<rect width="12" height="12" x="735" y="345" class="known"><title>void __thiscall SE_DrawBitmap(BITMAP_RESOURCE *bmpRsrc, HDC hdc, int32_t x, int32_t y);</title></rect>
<rect width="12" height="12" x="0" y="360" class="known"><title>void __thiscall SE_UpdateBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd, HWND hSender);</title></rect>
<rect width="12" height="12" x="15" y="360" class="known"><title>void __thiscall SE_ChangeBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd);</title></rect>
<rect width="12" height="12" x="30" y="360" class="known"><title>bool __cdecl SE_RegisterSetupWindowClass(void);</title></rect>
<rect width="12" height="12" x="45" y="360" class="known"><title>LRESULT __stdcall SE_SetupWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="12" height="12" x="60" y="360" class="known"><title>void __cdecl SE_PassMessageToImage(HWND hWnd, UINT uMsg, WPARAM wParam);</title></rect>
<rect width="12" height="12" x="390" y="345" class="decompiled"><title>BOOL __cdecl UT_CenterWindow(HWND hWnd);</title></rect>
<rect width="12" height="12" x="405" y="345" class="decompiled"><title>LPTSTR __cdecl UT_FindArg(LPCTSTR str);</title></rect>
<rect width="12" height="12" x="420" y="345" class="decompiled"><title>int32_t __cdecl UT_MessageBox(LPCTSTR lpText, HWND hWnd);</title></rect>
<rect width="12" height="12" x="435" y="345" class="decompiled"><title>int32_t __cdecl UT_ErrorBox(UINT uID, HWND hWnd);</title></rect>
<rect width="12" height="12" x="450" y="345" class="decompiled"><title>LPCTSTR __cdecl GuidBinaryToString(GUID *guid);</title></rect>
<rect width="12" height="12" x="465" y="345" class="decompiled"><title>bool __cdecl GuidStringToBinary(LPCTSTR lpString, GUID *guid);</title></rect>
<rect width="12" height="12" x="480" y="345" class="decompiled"><title>BOOL __cdecl OpenRegistryKey(LPCTSTR lpSubKey);</title></rect>
<rect width="12" height="12" x="495" y="345" class="decompiled"><title>bool __cdecl IsNewRegistryKeyCreated(void);</title></rect>
<rect width="12" height="12" x="510" y="345" class="decompiled"><title>LONG __cdecl CloseRegistryKey(void);</title></rect>
<rect width="12" height="12" x="525" y="345" class="decompiled"><title>LONG __cdecl SetRegistryDwordValue(LPCTSTR lpValueName, DWORD value);</title></rect>
<rect width="12" height="12" x="540" y="345" class="decompiled"><title>LONG __cdecl SetRegistryBoolValue(LPCTSTR lpValueName, bool value);</title></rect>
<rect width="12" height="12" x="555" y="345" class="decompiled"><title>LONG __cdecl SetRegistryFloatValue(LPCTSTR lpValueName, double value);</title></rect>
<rect width="12" height="12" x="570" y="345" class="decompiled"><title>LONG __cdecl SetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize);</title></rect>
<rect width="12" height="12" x="585" y="345" class="decompiled"><title>LONG __cdecl SetRegistryStringValue(LPCTSTR lpValueName, LPCTSTR value, int32_t length);</title></rect>
<rect width="12" height="12" x="600" y="345" class="decompiled"><title>LONG __cdecl DeleteRegistryValue(LPCTSTR lpValueName);</title></rect>
<rect width="12" height="12" x="615" y="345" class="decompiled"><title>bool __cdecl GetRegistryDwordValue(LPCTSTR lpValueName, DWORD *pValue, DWORD defaultValue);</title></rect>
<rect width="12" height="12" x="630" y="345" class="decompiled"><title>bool __cdecl GetRegistryBoolValue(LPCTSTR lpValueName, bool *pValue, bool defaultValue);</title></rect>
<rect width="12" height="12" x="645" y="345" class="decompiled"><title>bool __cdecl GetRegistryFloatValue(LPCTSTR lpValueName, double *value, double defaultValue);</title></rect>
<rect width="12" height="12" x="660" y="345" class="decompiled"><title>bool __cdecl GetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize, LPBYTE defaultValue);</title></rect>
<rect width="12" height="12" x="675" y="345" class="decompiled"><title>bool __cdecl GetRegistryStringValue(LPCTSTR lpValueName, LPTSTR value, DWORD maxSize, LPCTSTR defaultValue);</title></rect>
<rect width="12" height="12" x="690" y="345" class="decompiled"><title>bool __cdecl GetRegistryGuidValue(LPCTSTR lpValueName, GUID *value, GUID *defaultValue);</title></rect>
<rect width="12" height="12" x="705" y="345" class="decompiled"><title>void __thiscall SE_ReleaseBitmapResource(BITMAP_RESOURCE *bmpRsrc);</title></rect>
<rect width="12" height="12" x="720" y="345" class="decompiled"><title>void __thiscall SE_LoadBitmapResource(BITMAP_RESOURCE *bmpRsrc, LPCTSTR lpName);</title></rect>
<rect width="12" height="12" x="735" y="345" class="decompiled"><title>void __thiscall SE_DrawBitmap(BITMAP_RESOURCE *bmpRsrc, HDC hdc, int32_t x, int32_t y);</title></rect>
<rect width="12" height="12" x="0" y="360" class="decompiled"><title>void __thiscall SE_UpdateBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd, HWND hSender);</title></rect>
<rect width="12" height="12" x="15" y="360" class="decompiled"><title>void __thiscall SE_ChangeBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd);</title></rect>
<rect width="12" height="12" x="30" y="360" class="decompiled"><title>bool __cdecl SE_RegisterSetupWindowClass(void);</title></rect>
<rect width="12" height="12" x="45" y="360" class="decompiled"><title>LRESULT __stdcall SE_SetupWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="12" height="12" x="60" y="360" class="decompiled"><title>void __cdecl SE_PassMessageToImage(HWND hWnd, UINT uMsg, WPARAM wParam);</title></rect>
<rect width="12" height="12" x="75" y="360" class="known"><title>void __cdecl UT_MemBlt(BYTE *dstBuf, DWORD dstX, DWORD dstY, DWORD width, DWORD height, DWORD dstPitch, BYTE *srcBuf, DWORD srcX, DWORD srcY, DWORD srcPitch);</title></rect>
<rect width="12" height="12" x="90" y="360" class="decompiled"><title>void __cdecl Matrix_Push(void);</title></rect>
<rect width="12" height="12" x="105" y="360" class="decompiled"><title>void __cdecl Matrix_PushUnit(void);</title></rect>
@ -1324,10 +1324,10 @@
</g>
<g transform="translate(0 546)">
<text x="0" y="7.50">Tomb2.exe progress according to the function sizes:</text>
<text class="todo" style="font-size: 12px; " x="747" y="9"><tspan text-anchor="end"><tspan class="decompiled">82.72%</tspan> · <tspan class="known">16.95%</tspan> · <tspan class="todo">0%</tspan> · <tspan class="unused">0.33%</tspan></tspan></text>
<text class="todo" style="font-size: 12px; " x="747" y="9"><tspan text-anchor="end"><tspan class="decompiled">86.57%</tspan> · <tspan class="known">13.11%</tspan> · <tspan class="todo">0%</tspan> · <tspan class="unused">0.33%</tspan></tspan></text>
<g transform="translate(0 20)">
<rect width="617.94" height="6" x="0" y="0" class="decompiled"/>
<rect width="126.62" height="6" x="617.94" y="0" class="known"/>
<rect width="646.66" height="6" x="0" y="0" class="decompiled"/>
<rect width="97.90" height="6" x="646.66" y="0" class="known"/>
<rect width="2.44" height="6" x="744.56" y="0" class="unused"/>
</g>
<g transform="translate(0 31)">
@ -1347,7 +1347,7 @@
<rect width="40.15" height="38.34" x="60.98" y="295.51" class="decompiled"><title>int32_t __cdecl Requester_Display(REQUEST_INFO *req, int32_t des, int32_t backgrounds);</title></rect>
<rect width="40.15" height="38.15" x="60.98" y="336.85" class="decompiled"><title>void __cdecl ExtractSaveGameInfo(void);</title></rect>
<rect width="35.20" height="38.72" x="104.13" y="0" class="decompiled"><title>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));</title></rect>
<rect width="35.20" height="37.07" x="104.13" y="41.72" class="known"><title>void __cdecl SE_GraphicsDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="35.20" height="37.07" x="104.13" y="41.72" class="decompiled"><title>void __cdecl SE_GraphicsDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="35.20" height="36.05" x="104.13" y="81.80" class="decompiled"><title>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);</title></rect>
<rect width="35.20" height="35.66" x="104.13" y="120.85" class="decompiled"><title>void __cdecl Option_Controls(INVENTORY_ITEM *item);</title></rect>
<rect width="35.20" height="34.90" x="104.13" y="159.51" class="decompiled"><title>BOOL __cdecl GF_LoadFromFile(const char *file_name);</title></rect>
@ -1420,7 +1420,7 @@
<rect width="24.48" height="23.36" x="266.96" y="325.56" class="decompiled"><title>void __cdecl Inv_RingNotActive(INVENTORY_ITEM *inv_item);</title></rect>
<rect width="24.48" height="23.09" x="266.96" y="351.91" class="decompiled"><title>int32_t __cdecl Gun_FireWeapon(LARA_GUN_TYPE weapon_type, ITEM *target, const ITEM *src, const PHD_ANGLE *angles);</title></rect>
<rect width="22.45" height="24.84" x="294.45" y="0" class="decompiled"><title>int32_t __cdecl Game_Control(int32_t nframes, int32_t demo_mode);</title></rect>
<rect width="22.45" height="24.67" x="294.45" y="27.84" class="known"><title>INT_PTR __stdcall SE_GraphicsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="22.45" height="24.67" x="294.45" y="27.84" class="decompiled"><title>INT_PTR __stdcall SE_GraphicsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="22.45" height="24.38" x="294.45" y="55.51" class="decompiled"><title>int32_t __cdecl SE_ReadAppSettings(APP_SETTINGS *settings);</title></rect>
<rect width="22.45" height="24.35" x="294.45" y="82.89" class="decompiled"><title>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);</title></rect>
<rect width="22.45" height="24.35" x="294.45" y="110.24" class="decompiled"><title>void __cdecl RollingBall_Control(int16_t item_num);</title></rect>
@ -1443,7 +1443,7 @@
<rect width="21.59" height="22.20" x="319.90" y="180.11" class="decompiled"><title>int32_t __cdecl LOS_CheckZ(const GAME_VECTOR *start, GAME_VECTOR *target);</title></rect>
<rect width="21.59" height="22.07" x="319.90" y="205.31" class="decompiled"><title>int32_t __cdecl Lara_TestVault(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="21.59" height="21.83" x="319.90" y="230.38" class="decompiled"><title>void __cdecl WinPlayFMV(const char *file_name, bool is_playback);</title></rect>
<rect width="21.59" height="21.76" x="319.90" y="255.20" class="known"><title>bool __cdecl SE_ShowSetupDialog(HWND hParent, bool isDefault);</title></rect>
<rect width="21.59" height="21.76" x="319.90" y="255.20" class="decompiled"><title>bool __cdecl SE_ShowSetupDialog(HWND hParent, bool isDefault);</title></rect>
<rect width="21.59" height="21.63" x="319.90" y="279.97" class="decompiled"><title>void __cdecl Option_Detail(INVENTORY_ITEM *item);</title></rect>
<rect width="21.59" height="21.56" x="319.90" y="304.59" class="known"><title>int32_t __cdecl Collide_GetSpheres(const ITEM *item, SPHERE *spheres, bool world_space);</title></rect>
<rect width="21.59" height="21.46" x="319.90" y="329.15" class="decompiled"><title>void __cdecl Skidoo_Draw(const ITEM *item);</title></rect>
@ -1471,9 +1471,9 @@
<rect width="19.34" height="19.77" x="368.43" y="92.71" class="decompiled"><title>int32_t __cdecl Room_GetHeight(const SECTOR *sector, int32_t x, int32_t y, int32_t z);</title></rect>
<rect width="19.34" height="19.77" x="368.43" y="115.48" class="decompiled"><title>BOOL __cdecl Level_LoadSamples(HANDLE handle);</title></rect>
<rect width="19.34" height="19.69" x="368.43" y="138.24" class="decompiled"><title>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);</title></rect>
<rect width="19.34" height="19.66" x="368.43" y="160.94" class="known"><title>bool __cdecl SE_WriteAppSettings(APP_SETTINGS *settings);</title></rect>
<rect width="19.34" height="19.66" x="368.43" y="160.94" class="decompiled"><title>bool __cdecl SE_WriteAppSettings(APP_SETTINGS *settings);</title></rect>
<rect width="19.34" height="19.14" x="368.43" y="183.60" class="decompiled"><title>void __cdecl S_CopyBufferToScreen(void);</title></rect>
<rect width="19.34" height="19.03" x="368.43" y="205.73" class="decompiled"><title>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);</title></rect>
<rect width="19.34" height="19.03" x="368.43" y="205.73" class="decompiled"><title>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);</title></rect>
<rect width="19.34" height="18.77" x="368.43" y="227.76" class="decompiled"><title>void __cdecl RollingBall_Collision(int16_t item_num, ITEM *litem, COLL_INFO *coll);</title></rect>
<rect width="19.34" height="18.77" x="368.43" y="249.52" class="decompiled"><title>bool __cdecl Level_Load(const char *file_name, int32_t level_num);</title></rect>
<rect width="19.34" height="18.58" x="368.43" y="271.29" class="decompiled"><title>void __cdecl Camera_LoadCutsceneFrame(void);</title></rect>
@ -1481,10 +1481,10 @@
<rect width="19.34" height="18.28" x="368.43" y="314.34" class="decompiled"><title>int32_t __cdecl Room_GetCeiling(const SECTOR *sector, int32_t x, int32_t y, int32_t z);</title></rect>
<rect width="19.34" height="18.21" x="368.43" y="335.62" class="decompiled"><title>void __cdecl Detonator_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll);</title></rect>
<rect width="19.34" height="18.17" x="368.43" y="356.83" class="decompiled"><title>void __cdecl GameApplySettings(APP_SETTINGS *new_settings);</title></rect>
<rect width="18.82" height="18.68" x="390.77" y="0" class="known"><title>LRESULT __stdcall SE_SetupWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="18.82" height="18.68" x="390.77" y="0" class="decompiled"><title>LRESULT __stdcall SE_SetupWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="18.78" height="18.68" x="412.58" y="0" class="decompiled"><title>void __cdecl MovableBlock_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll);</title></rect>
<rect width="18.62" height="18.68" x="434.36" y="0" class="decompiled"><title>int32_t __cdecl Lara_TestClimbUpPos(ITEM *item, int32_t front, int32_t right, int32_t *shift, int32_t *ledge);</title></rect>
<rect width="18.59" height="18.68" x="455.98" y="0" class="known"><title>void __cdecl SE_OptionsDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="18.59" height="18.68" x="455.98" y="0" class="decompiled"><title>void __cdecl SE_OptionsDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="18.55" height="18.68" x="477.57" y="0" class="decompiled"><title>int32_t __cdecl Skidoo_CheckGetOff(void);</title></rect>
<rect width="18.55" height="18.68" x="499.12" y="0" class="decompiled"><title>void __cdecl DisplayCredits(void);</title></rect>
<rect width="18.01" height="18.68" x="520.67" y="0" class="decompiled"><title>void __cdecl Gun_Pistols_Undraw(LARA_GUN_TYPE weapon_type);</title></rect>
@ -1510,11 +1510,11 @@
<rect width="17.35" height="17.87" x="390.77" y="213.78" class="decompiled"><title>void __cdecl Bird_Control(int16_t item_num);</title></rect>
<rect width="17.35" height="17.87" x="390.77" y="234.66" class="decompiled"><title>void __cdecl BodyPart_Control(int16_t fx_num);</title></rect>
<rect width="17.35" height="17.59" x="390.77" y="255.53" class="decompiled"><title>void __cdecl Skidoo_BaddieCollision(const ITEM *skidoo);</title></rect>
<rect width="17.35" height="17.47" x="390.77" y="276.12" class="known"><title>void __cdecl S_DrawAirBar(int32_t percent);</title></rect>
<rect width="17.35" height="17.47" x="390.77" y="276.12" class="decompiled"><title>void __cdecl Output_DrawAirBar(int32_t percent);</title></rect>
<rect width="17.35" height="17.43" x="390.77" y="296.58" class="decompiled"><title>void __cdecl Screenshot(LPDDS screen);</title></rect>
<rect width="17.35" height="17.38" x="390.77" y="317.01" class="decompiled"><title>void __cdecl Mine_Control(int16_t mine_num);</title></rect>
<rect width="17.35" height="17.34" x="390.77" y="337.39" class="decompiled"><title>int32_t __cdecl Box_SearchLOT(LOT_INFO *lot, int32_t expansion);</title></rect>
<rect width="17.35" height="17.26" x="390.77" y="357.74" class="known"><title>void __cdecl S_PrintShadow(int16_t radius, const BOUNDS_16 *bounds, const ITEM *item);</title></rect>
<rect width="17.35" height="17.26" x="390.77" y="357.74" class="decompiled"><title>void __cdecl Output_InsertShadow(int16_t radius, const BOUNDS_16 *bounds, const ITEM *item);</title></rect>
<rect width="17.67" height="16.75" x="411.12" y="21.68" class="decompiled"><title>void __cdecl Lara_WaterCurrent(COLL_INFO *coll);</title></rect>
<rect width="17.55" height="16.75" x="431.79" y="21.68" class="decompiled"><title>int32_t __cdecl GF_LoadScriptFile(const char *fname);</title></rect>
<rect width="17.46" height="16.75" x="452.34" y="21.68" class="decompiled"><title>void __cdecl Matrix_RotYXZpack(uint32_t rpack);</title></rect>
@ -1522,7 +1522,7 @@
<rect width="17.21" height="16.75" x="493.05" y="21.68" class="known"><title>void __cdecl Eel_Control(int16_t item_num);</title></rect>
<rect width="17" height="16.75" x="513.27" y="21.68" class="decompiled"><title>void __cdecl Matrix_RotYXZ(int16_t ry, int16_t rx, int16_t rz);</title></rect>
<rect width="17" height="16.75" x="533.27" y="21.68" class="known"><title>void __cdecl Mouse_Control(int16_t item_num);</title></rect>
<rect width="17" height="16.75" x="553.27" y="21.68" class="known"><title>void __cdecl SE_GraphicsDlgFullScreenModesUpdate(HWND hwndDlg);</title></rect>
<rect width="17" height="16.75" x="553.27" y="21.68" class="decompiled"><title>void __cdecl SE_GraphicsDlgFullScreenModesUpdate(HWND hwndDlg);</title></rect>
<rect width="16.96" height="16.75" x="573.27" y="21.68" class="decompiled"><title>void __cdecl Creature_GetBaddieTarget(int16_t item_num, int32_t goody);</title></rect>
<rect width="16.79" height="16.75" x="593.23" y="21.68" class="decompiled"><title>void __cdecl Flare_Create(int32_t thrown);</title></rect>
<rect width="16.75" height="16.75" x="613.02" y="21.68" class="decompiled"><title>void __cdecl ShowGymStatsText(char *time_str, int32_t type);</title></rect>
@ -1530,7 +1530,7 @@
<rect width="16.75" height="16.75" x="652.52" y="21.68" class="decompiled"><title>int32_t __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int32_t nShowCmd);</title></rect>
<rect width="16.71" height="16.75" x="672.27" y="21.68" class="decompiled"><title>const int16_t *__cdecl Output_CalcObjectVertices(const int16_t *obj_ptr);</title></rect>
<rect width="16.50" height="16.75" x="691.97" y="21.68" class="decompiled"><title>void __cdecl Matrix_GenerateW2V(PHD_3DPOS *viewpos);</title></rect>
<rect width="16.33" height="16.75" x="711.47" y="21.68" class="known"><title>void __cdecl S_DrawHealthBar(int32_t percent);</title></rect>
<rect width="16.33" height="16.75" x="711.47" y="21.68" class="decompiled"><title>void __cdecl Output_DrawHealthBar(int32_t percent);</title></rect>
<rect width="16.20" height="16.75" x="730.80" y="21.68" class="decompiled"><title>void __cdecl Output_InsertFlatRect_ZBuffered(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t z, uint8_t color_idx);</title></rect>
<rect width="16.42" height="16.52" x="411.12" y="41.42" class="decompiled"><title>void __cdecl FadeToPal(int32_t fade_value, RGB_888 *palette);</title></rect>
<rect width="16.42" height="16.40" x="411.12" y="60.95" class="decompiled"><title>void __cdecl Room_GetBounds(void);</title></rect>
@ -1576,7 +1576,7 @@
<rect width="14.86" height="14.79" x="430.54" y="168.48" class="decompiled"><title>void __cdecl Output_InsertFlatRect_Sorted(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t z, uint8_t color_idx);</title></rect>
<rect width="14.86" height="14.79" x="430.54" y="186.27" class="decompiled"><title>void __cdecl Twinkle_Control(int16_t fx_num);</title></rect>
<rect width="14.86" height="14.65" x="430.54" y="204.06" class="decompiled"><title>void __cdecl S_Audio_Sample_Init2(HWND hwnd);</title></rect>
<rect width="14.86" height="14.65" x="430.54" y="221.71" class="known"><title>void __cdecl SE_GraphicsDlgInit(HWND hwndDlg);</title></rect>
<rect width="14.86" height="14.65" x="430.54" y="221.71" class="decompiled"><title>void __cdecl SE_GraphicsDlgInit(HWND hwndDlg);</title></rect>
<rect width="14.86" height="14.60" x="430.54" y="239.36" class="known"><title>void __cdecl SpinningBlade_Control(int16_t item_num);</title></rect>
<rect width="14.86" height="14.51" x="430.54" y="256.96" class="decompiled"><title>void __cdecl Lift_FloorCeiling(const ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *floor, int32_t *ceiling);</title></rect>
<rect width="14.86" height="14.37" x="430.54" y="274.47" class="decompiled"><title>void __cdecl Lara_Col_Run(ITEM *item, COLL_INFO *coll);</title></rect>
@ -1611,7 +1611,7 @@
<rect width="14.02" height="13.47" x="551.96" y="76.15" class="decompiled"><title>const int16_t *__cdecl Output_InsertRoomSprite(const int16_t *obj_ptr, int32_t vtx_count);</title></rect>
<rect width="13.77" height="13.47" x="568.98" y="76.15" class="decompiled"><title>void __cdecl Lara_Col_Climbing(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="13.67" height="13.47" x="585.75" y="76.15" class="known"><title>void __cdecl Gun_DrawFlash(LARA_GUN_TYPE weapon_type, int32_t clip);</title></rect>
<rect width="13.57" height="13.47" x="602.42" y="76.15" class="known"><title>INT_PTR __stdcall SE_SoundDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="13.57" height="13.47" x="602.42" y="76.15" class="decompiled"><title>INT_PTR __stdcall SE_SoundDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="13.52" height="13.47" x="618.99" y="76.15" class="decompiled"><title>void __cdecl Lara_State_Stop(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="13.52" height="13.47" x="635.52" y="76.15" class="decompiled"><title>void __cdecl MovableBlock_Control(int16_t item_num);</title></rect>
<rect width="13.47" height="13.47" x="652.04" y="76.15" class="decompiled"><title>void __cdecl Effect_Draw(int16_t fx_num);</title></rect>
@ -1657,7 +1657,7 @@
<rect width="12.14" height="12.56" x="719.78" y="92.62" class="decompiled"><title>void __cdecl Gun_InitialiseNewWeapon(void);</title></rect>
<rect width="12.09" height="12.56" x="734.91" y="92.62" class="decompiled"><title>void __cdecl Lara_Col_UpJump(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="12.24" height="12.41" x="464.87" y="108.19" class="decompiled"><title>void __cdecl Skidoo_Guns(void);</title></rect>
<rect width="12.24" height="12.41" x="464.87" y="123.60" class="known"><title>void __cdecl SE_SoundDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="12.24" height="12.41" x="464.87" y="123.60" class="decompiled"><title>void __cdecl SE_SoundDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="12.24" height="12.36" x="464.87" y="139.01" class="decompiled"><title>HRESULT __stdcall EnumTextureFormatsCallback(LPDDSDESC lpDdsd, LPVOID lpContext);</title></rect>
<rect width="12.24" height="12.30" x="464.87" y="154.36" class="decompiled"><title>void __cdecl SkidooArmed_Push(const ITEM *item, ITEM *lara_item, int32_t radius);</title></rect>
<rect width="12.24" height="12.14" x="464.87" y="169.66" class="known"><title>void __cdecl Jelly_Control(int16_t item_num);</title></rect>
@ -1683,7 +1683,7 @@
<rect width="11.49" height="12" x="480.11" y="199.44" class="decompiled"><title>int32_t __cdecl Diver_GetWaterSurface(int32_t x, int32_t y, int32_t z, int16_t room_num);</title></rect>
<rect width="11.49" height="12" x="480.11" y="214.44" class="decompiled"><title>void __cdecl LOT_InitialiseSlot(int16_t item_num, int32_t slot);</title></rect>
<rect width="11.49" height="12" x="480.11" y="229.44" class="decompiled"><title>int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction);</title></rect>
<rect width="11.49" height="12" x="480.11" y="244.44" class="known"><title>INT_PTR __stdcall SE_ControlsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="11.49" height="12" x="480.11" y="244.44" class="decompiled"><title>INT_PTR __stdcall SE_ControlsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="11.49" height="11.94" x="480.11" y="259.44" class="decompiled"><title>TEXTSTRING *__cdecl Text_Create(int32_t x, int32_t y, int32_t z, const char *text);</title></rect>
<rect width="11.49" height="11.94" x="480.11" y="274.38" class="decompiled"><title>void __cdecl FallingBlock_Control(int16_t item_num);</title></rect>
<rect width="11.49" height="11.94" x="480.11" y="289.32" class="decompiled"><title>void __cdecl FmvBackToGame(void);</title></rect>
@ -1696,7 +1696,7 @@
<rect width="11.49" height="11.43" x="509.09" y="108.19" class="decompiled"><title>void __cdecl Switch_CollisionUW(int16_t item_num, ITEM *lara_item, COLL_INFO *coll);</title></rect>
<rect width="11.43" height="11.43" x="523.57" y="108.19" class="decompiled"><title>void __cdecl Lara_Col_Back(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="11.37" height="11.43" x="538" y="108.19" class="decompiled"><title>void __cdecl Lara_InitialiseMeshes(int32_t level_num);</title></rect>
<rect width="11.37" height="11.43" x="552.37" y="108.19" class="known"><title>BOOL __cdecl DecompPCX(const uint8_t *pcx, size_t pcx_size, LPBYTE pic, RGB_888 *pal);</title></rect>
<rect width="11.37" height="11.43" x="552.37" y="108.19" class="decompiled"><title>BOOL __cdecl DecompPCX(const uint8_t *pcx, size_t pcx_size, LPBYTE pic, RGB_888 *pal);</title></rect>
<rect width="11.26" height="11.43" x="566.74" y="108.19" class="decompiled"><title>int32_t __cdecl Boat_TestWaterHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos);</title></rect>
<rect width="11.26" height="11.43" x="581" y="108.19" class="decompiled"><title>int32_t __cdecl Creature_CheckBaddieOverlap(int16_t item_num);</title></rect>
<rect width="11.26" height="11.43" x="595.25" y="108.19" class="decompiled"><title>void __cdecl Flare_DrawInAir(const ITEM *item);</title></rect>
@ -1739,8 +1739,8 @@
<rect width="10.42" height="10.72" x="617.24" y="122.62" class="known"><title>void __cdecl HotLiquid_Control(int16_t fx_num);</title></rect>
<rect width="10.30" height="10.72" x="630.66" y="122.62" class="decompiled"><title>void __cdecl CutscenePlayer_Control(int16_t item_num);</title></rect>
<rect width="10.30" height="10.72" x="643.96" y="122.62" class="decompiled"><title>void __cdecl Window_2_Control(int16_t item_num);</title></rect>
<rect width="10.30" height="10.72" x="657.26" y="122.62" class="decompiled"><title>void __cdecl DrawQuad(float sx, float sy, float width, float height, D3DCOLOR color);</title></rect>
<rect width="10.30" height="10.72" x="670.56" y="122.62" class="known"><title>INT_PTR __stdcall SE_AdvancedDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="10.30" height="10.72" x="657.26" y="122.62" class="decompiled"><title>void __cdecl BGND_DrawQuad(float sx, float sy, float width, float height, D3DCOLOR color);</title></rect>
<rect width="10.30" height="10.72" x="670.56" y="122.62" class="decompiled"><title>INT_PTR __stdcall SE_AdvancedDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="10.24" height="10.72" x="683.86" y="122.62" class="known"><title>void __cdecl Earthquake_Control(int16_t item_num);</title></rect>
<rect width="10.24" height="10.72" x="697.10" y="122.62" class="decompiled"><title>void __cdecl ModifyStartInfo(int32_t level_num);</title></rect>
<rect width="10.24" height="10.72" x="710.34" y="122.62" class="known"><title>void __cdecl SpringBoard_Control(int16_t item_num);</title></rect>
@ -1752,7 +1752,7 @@
<rect width="10.16" height="10.68" x="508.24" y="177.45" class="known"><title>void __cdecl MiniCopterControl(int16_t item_num);</title></rect>
<rect width="10.16" height="10.55" x="508.24" y="191.13" class="decompiled"><title>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);</title></rect>
<rect width="10.16" height="10.55" x="508.24" y="204.69" class="decompiled"><title>void __cdecl Lara_Col_ForwardJump(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="10.16" height="10.55" x="508.24" y="218.24" class="known"><title>bool __cdecl SE_GraphicsTestStart(void);</title></rect>
<rect width="10.16" height="10.55" x="508.24" y="218.24" class="decompiled"><title>bool __cdecl SE_GraphicsTestStart(void);</title></rect>
<rect width="10.16" height="10.43" x="508.24" y="231.80" class="decompiled"><title>int16_t __cdecl Creature_Turn(ITEM *item, int16_t maximum_turn);</title></rect>
<rect width="10.16" height="10.43" x="508.24" y="245.23" class="decompiled"><title>void __cdecl WinVidSetDisplayAdapter(DISPLAY_ADAPTER *disp_adapter);</title></rect>
<rect width="10.16" height="10.37" x="508.24" y="258.65" class="decompiled"><title>void __cdecl Lift_Control(int16_t item_num);</title></rect>
@ -1775,7 +1775,7 @@
<rect width="9.67" height="10.10" x="624.42" y="136.34" class="decompiled"><title>void __cdecl Door_Control(int16_t item_num);</title></rect>
<rect width="9.67" height="10.10" x="637.09" y="136.34" class="decompiled"><title>BYTE __cdecl FindNearestPaletteEntry(RGB_888 *palette, int32_t red, int32_t green, int32_t blue, bool ignore_sys_palette);</title></rect>
<rect width="9.61" height="10.10" x="649.77" y="136.34" class="decompiled"><title>void __cdecl Output_RotateLight(int16_t pitch, int16_t yaw);</title></rect>
<rect width="9.61" height="10.10" x="662.38" y="136.34" class="known"><title>bool __cdecl SE_SoundTestStart(void);</title></rect>
<rect width="9.61" height="10.10" x="662.38" y="136.34" class="decompiled"><title>bool __cdecl SE_SoundTestStart(void);</title></rect>
<rect width="9.55" height="10.10" x="674.98" y="136.34" class="unused"><title>sub_4449D0</title></rect>
<rect width="9.55" height="10.10" x="687.53" y="136.34" class="decompiled"><title>bool __cdecl WinVidCreateGameWindow(void);</title></rect>
<rect width="9.55" height="10.10" x="700.07" y="136.34" class="decompiled"><title>BOOL __cdecl GF_ReadStringTable(DWORD count, char **string_table, char **string_buf, LPDWORD buf_size, HANDLE handle);</title></rect>
@ -1784,22 +1784,22 @@
<rect width="9.42" height="10.10" x="737.58" y="136.34" class="decompiled"><title>void __cdecl Window_Smash(int16_t item_num);</title></rect>
<rect width="9.52" height="9.98" x="521.40" y="149.44" class="decompiled"><title>bool __cdecl S_Audio_Sample_DSoundBufferTest(void);</title></rect>
<rect width="9.52" height="9.98" x="521.40" y="162.42" class="decompiled"><title>BOOL __cdecl S_ReloadLevelGraphics(BOOL reload_palettes, BOOL reload_tex_pages);</title></rect>
<rect width="9.52" height="9.98" x="521.40" y="175.41" class="known"><title>void __thiscall SE_LoadBitmapResource(BITMAP_RESOURCE *bmpRsrc, LPCTSTR lpName);</title></rect>
<rect width="9.52" height="9.98" x="521.40" y="175.41" class="decompiled"><title>void __thiscall SE_LoadBitmapResource(BITMAP_RESOURCE *bmpRsrc, LPCTSTR lpName);</title></rect>
<rect width="9.52" height="9.85" x="521.40" y="188.39" class="decompiled"><title>void __cdecl Splash(ITEM *item);</title></rect>
<rect width="9.52" height="9.79" x="521.40" y="201.25" class="decompiled"><title>int32_t __cdecl Inv_GetItemOption(GAME_OBJECT_ID object_id);</title></rect>
<rect width="9.52" height="9.79" x="521.40" y="214.03" class="decompiled"><title>void __cdecl Gun_AimWeapon(WEAPON_INFO *winfo, LARA_ARM *arm);</title></rect>
<rect width="9.52" height="9.72" x="521.40" y="226.82" class="decompiled"><title>void __cdecl Requester_ChangeItem(REQUEST_INFO *req, int32_t item, const char *text1, uint32_t flags1, const char *text2, uint32_t flags2);</title></rect>
<rect width="9.52" height="9.72" x="521.40" y="239.54" class="decompiled"><title>void __cdecl Option_Compass(INVENTORY_ITEM *item);</title></rect>
<rect width="9.52" height="9.72" x="521.40" y="252.26" class="known"><title>void __cdecl AnimateTextures(int32_t ticks);</title></rect>
<rect width="9.52" height="9.72" x="521.40" y="252.26" class="decompiled"><title>void __cdecl Output_AnimateTextures(int32_t ticks);</title></rect>
<rect width="9.52" height="9.65" x="521.40" y="264.98" class="decompiled"><title>void __cdecl Zipline_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll);</title></rect>
<rect width="9.52" height="9.59" x="521.40" y="277.63" class="decompiled"><title>void __cdecl Lara_Col_StepRight(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="9.52" height="9.59" x="521.40" y="290.22" class="decompiled"><title>int32_t __cdecl Lara_TestClimbStance(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="9.52" height="9.59" x="521.40" y="302.81" class="known"><title>void __cdecl SE_SoundDlgInit(HWND hwndDlg);</title></rect>
<rect width="9.52" height="9.59" x="521.40" y="302.81" class="decompiled"><title>void __cdecl SE_SoundDlgInit(HWND hwndDlg);</title></rect>
<rect width="9.52" height="9.52" x="521.40" y="315.39" class="decompiled"><title>void __cdecl GongBonger_Control(int16_t item_num);</title></rect>
<rect width="9.52" height="9.52" x="521.40" y="327.92" class="decompiled"><title>int32_t __cdecl Switch_Trigger(int16_t item_num, int16_t timer);</title></rect>
<rect width="9.52" height="9.52" x="521.40" y="340.44" class="known"><title>void __cdecl TeethTrap_Control(int16_t item_num);</title></rect>
<rect width="9.52" height="9.52" x="521.40" y="352.96" class="decompiled"><title>HRESULT __stdcall Enum3DDevicesCallback(GUID *lpGuid, LPTSTR lpDeviceDescription, LPTSTR lpDeviceName, LPD3DDEVICEDESC lpD3DHWDeviceDesc, LPD3DDEVICEDESC lpD3DHELDeviceDesc, LPVOID lpContext);</title></rect>
<rect width="9.52" height="9.52" x="521.40" y="365.48" class="known"><title>void __cdecl SE_ControlsDlgInit(HWND hwndDlg);</title></rect>
<rect width="9.52" height="9.52" x="521.40" y="365.48" class="decompiled"><title>void __cdecl SE_ControlsDlgInit(HWND hwndDlg);</title></rect>
<rect width="9.97" height="9.03" x="533.93" y="149.44" class="decompiled"><title>void __cdecl Lara_State_Extra_PullDagger(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="9.97" height="9.03" x="546.89" y="149.44" class="decompiled"><title>int32_t __cdecl Lara_TestClimbPos(ITEM *item, int32_t front, int32_t right, int32_t origin, int32_t height, int32_t *shift);</title></rect>
<rect width="9.97" height="9.03" x="559.86" y="149.44" class="decompiled"><title>bool __cdecl WinVidCheckGameWindowPalette(HWND hWnd);</title></rect>
@ -1842,7 +1842,7 @@
<rect width="8.64" height="9.12" x="533.93" y="222.13" class="decompiled"><title>void __cdecl Requester_SetHeading(REQUEST_INFO *req, char *text1, uint32_t flags1, char *text2, uint32_t flags2);</title></rect>
<rect width="8.64" height="9.12" x="533.93" y="234.25" class="decompiled"><title>int32_t __cdecl Lara_CheckForLetGo(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="8.64" height="9.12" x="533.93" y="246.36" class="decompiled"><title>void __cdecl Gun_FindTargetPoint(const ITEM *item, GAME_VECTOR *target);</title></rect>
<rect width="8.64" height="9.12" x="533.93" y="258.48" class="known"><title>bool __cdecl GuidStringToBinary(LPCTSTR lpString, GUID *guid);</title></rect>
<rect width="8.64" height="9.12" x="533.93" y="258.48" class="decompiled"><title>bool __cdecl GuidStringToBinary(LPCTSTR lpString, GUID *guid);</title></rect>
<rect width="8.64" height="8.97" x="533.93" y="270.60" class="decompiled"><title>void __cdecl Matrix_RotY(int16_t ry);</title></rect>
<rect width="8.64" height="8.97" x="533.93" y="282.57" class="decompiled"><title>void __cdecl Matrix_RotZ(int16_t rz);</title></rect>
<rect width="8.64" height="8.97" x="533.93" y="294.54" class="decompiled"><title>void __cdecl Creature_Float(int16_t item_num);</title></rect>
@ -1896,17 +1896,17 @@
<rect width="7.86" height="8.39" x="556.72" y="254.04" class="decompiled"><title>void __cdecl Output_SetNearZ(int32_t near_z);</title></rect>
<rect width="7.86" height="8.39" x="556.72" y="265.42" class="decompiled"><title>void __cdecl Box_TargetBox(LOT_INFO *lot, int16_t box_num);</title></rect>
<rect width="7.86" height="8.39" x="556.72" y="276.81" class="decompiled"><title>void __cdecl Lara_Col_TurnRight(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="7.86" height="8.39" x="556.72" y="288.20" class="known"><title>bool __cdecl GetRegistryStringValue(LPCTSTR lpValueName, LPTSTR value, DWORD maxSize, LPCTSTR defaultValue);</title></rect>
<rect width="7.86" height="8.39" x="556.72" y="288.20" class="decompiled"><title>bool __cdecl GetRegistryStringValue(LPCTSTR lpValueName, LPTSTR value, DWORD maxSize, LPCTSTR defaultValue);</title></rect>
<rect width="7.86" height="8.31" x="556.72" y="299.59" class="decompiled"><title>void __cdecl CreatePrimarySurface(void);</title></rect>
<rect width="7.86" height="8.23" x="556.72" y="310.90" class="decompiled"><title>void __cdecl Room_InitCinematic(void);</title></rect>
<rect width="7.86" height="8.23" x="556.72" y="322.13" class="decompiled"><title>void __cdecl Effect_NewRoom(int16_t fx_num, int16_t room_num);</title></rect>
<rect width="7.86" height="8.23" x="556.72" y="333.37" class="known"><title>void __cdecl SE_AdvancedDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="7.86" height="8.23" x="556.72" y="333.37" class="decompiled"><title>void __cdecl SE_AdvancedDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="7.86" height="8.16" x="556.72" y="344.60" class="decompiled"><title>int32_t __cdecl Item_GetFrames(const ITEM *item, FRAME_INFO *frmptr[], int32_t *rate);</title></rect>
<rect width="7.86" height="8.16" x="556.72" y="355.76" class="decompiled"><title>void __cdecl Music_SetVolume(int32_t volume);</title></rect>
<rect width="7.86" height="8.08" x="556.72" y="366.92" class="decompiled"><title>const int16_t *__cdecl Output_InsertObjectGT4_ZBuffered(const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type);</title></rect>
<rect width="7.93" height="8.01" x="567.57" y="185.25" class="decompiled"><title>void __cdecl Lara_State_Extra_SharkKill(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="7.93" height="8.01" x="578.50" y="185.25" class="known"><title>void __cdecl Blade_Control(int16_t item_num);</title></rect>
<rect width="7.93" height="8.01" x="589.43" y="185.25" class="known"><title>bool __cdecl GetRegistryGuidValue(LPCTSTR lpValueName, GUID *value, GUID *defaultValue);</title></rect>
<rect width="7.93" height="8.01" x="589.43" y="185.25" class="decompiled"><title>bool __cdecl GetRegistryGuidValue(LPCTSTR lpValueName, GUID *value, GUID *defaultValue);</title></rect>
<rect width="7.86" height="8.01" x="600.36" y="185.25" class="decompiled"><title>void __cdecl Lara_Col_Reach(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="7.86" height="8.01" x="611.22" y="185.25" class="known"><title>int32_t __cdecl GetCollisionAnim(ITEM *skidoo, XYZ_32 *moved);</title></rect>
<rect width="7.86" height="8.01" x="622.07" y="185.25" class="decompiled"><title>void __cdecl FlameEmitter_Control(int16_t item_num);</title></rect>
@ -1927,7 +1927,7 @@
<rect width="7.64" height="7.76" x="567.57" y="228.77" class="decompiled"><title>void __cdecl Item_RemoveActive(int16_t item_num);</title></rect>
<rect width="7.64" height="7.76" x="567.57" y="239.53" class="decompiled"><title>void __cdecl Lara_State_TurnRight(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="7.64" height="7.76" x="567.57" y="250.29" class="decompiled"><title>BOOL __cdecl Level_LoadDemo(HANDLE handle);</title></rect>
<rect width="7.64" height="7.76" x="567.57" y="261.05" class="known"><title>INT_PTR __stdcall SE_OptionsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="7.64" height="7.76" x="567.57" y="261.05" class="decompiled"><title>INT_PTR __stdcall SE_OptionsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="7.64" height="7.68" x="567.57" y="271.81" class="decompiled"><title>void __cdecl Bird_Initialise(int16_t item_num);</title></rect>
<rect width="7.64" height="7.68" x="567.57" y="282.49" class="decompiled"><title>void __cdecl Inv_SelectMeshes(INVENTORY_ITEM *inv_item);</title></rect>
<rect width="7.64" height="7.68" x="567.57" y="293.17" class="decompiled"><title>void __cdecl Lara_ResetLook(void);</title></rect>
@ -1992,7 +1992,7 @@
<rect width="7.22" height="6.58" x="609.23" y="216.45" class="known"><title>int16_t __cdecl Knife(int32_t x, int32_t y, int32_t z, int16_t speed, PHD_ANGLE yrot, int16_t room_num);</title></rect>
<rect width="7.22" height="6.58" x="619.45" y="216.45" class="known"><title>void __cdecl DrawHair(void);</title></rect>
<rect width="7.22" height="6.58" x="629.68" y="216.45" class="decompiled"><title>void __cdecl Lara_State_Glide(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="7.22" height="6.58" x="639.90" y="216.45" class="known"><title>bool __cdecl GetRegistryBoolValue(LPCTSTR lpValueName, bool *pValue, bool defaultValue);</title></rect>
<rect width="7.22" height="6.58" x="639.90" y="216.45" class="decompiled"><title>bool __cdecl GetRegistryBoolValue(LPCTSTR lpValueName, bool *pValue, bool defaultValue);</title></rect>
<rect width="7.14" height="6.58" x="650.12" y="216.45" class="decompiled"><title>int16_t __cdecl Lara_FloorFront(ITEM *item, PHD_ANGLE ang, int32_t dist);</title></rect>
<rect width="7.14" height="6.58" x="660.25" y="216.45" class="decompiled"><title>void __cdecl Lara_State_ClimbStance(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="7.14" height="6.58" x="670.39" y="216.45" class="decompiled"><title>void __cdecl Window_Initialise(int16_t item_num);</title></rect>
@ -2005,14 +2005,14 @@
<rect width="6.79" height="6.58" x="740.21" y="216.45" class="decompiled"><title>void __cdecl Splash_Control(int16_t fx_num);</title></rect>
<rect width="6.65" height="6.71" x="588.61" y="226.03" class="decompiled"><title>void __thiscall WinVidGetColorBitMasks(COLOR_BIT_MASKS *bm, LPDDPIXELFORMAT pixel_format);</title></rect>
<rect width="6.65" height="6.71" x="588.61" y="235.74" class="decompiled"><title>BOOL __cdecl Level_LoadPalettes(HANDLE handle);</title></rect>
<rect width="6.65" height="6.71" x="588.61" y="245.45" class="known"><title>bool __cdecl GetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize, LPBYTE defaultValue);</title></rect>
<rect width="6.65" height="6.71" x="588.61" y="245.45" class="decompiled"><title>bool __cdecl GetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize, LPBYTE defaultValue);</title></rect>
<rect width="6.65" height="6.63" x="588.61" y="255.17" class="decompiled"><title>void __cdecl Gun_Rifle_Ready(LARA_GUN_TYPE weapon_type);</title></rect>
<rect width="6.65" height="6.63" x="588.61" y="264.79" class="decompiled"><title>void __cdecl Lara_State_SurfSwim(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="6.65" height="6.63" x="588.61" y="274.42" class="decompiled"><title>void __cdecl CreatePictureBuffer(void);</title></rect>
<rect width="6.65" height="6.54" x="588.61" y="284.05" class="decompiled"><title>int32_t __cdecl Box_UpdateLOT(LOT_INFO *lot, int32_t expansion);</title></rect>
<rect width="6.65" height="6.54" x="588.61" y="293.59" class="decompiled"><title>void __cdecl Item_RemoveDrawn(int16_t item_num);</title></rect>
<rect width="6.65" height="6.54" x="588.61" y="303.13" class="decompiled"><title>void __cdecl Music_Legacy_Play(int16_t track_id, bool is_looped);</title></rect>
<rect width="6.65" height="6.54" x="588.61" y="312.67" class="known"><title>BOOL __cdecl UT_CenterWindow(HWND hWnd);</title></rect>
<rect width="6.65" height="6.54" x="588.61" y="312.67" class="decompiled"><title>BOOL __cdecl UT_CenterWindow(HWND hWnd);</title></rect>
<rect width="6.65" height="6.46" x="588.61" y="322.21" class="known"><title>void __cdecl UT_MemBlt(BYTE *dstBuf, DWORD dstX, DWORD dstY, DWORD width, DWORD height, DWORD dstPitch, BYTE *srcBuf, DWORD srcX, DWORD srcY, DWORD srcPitch);</title></rect>
<rect width="6.65" height="6.28" x="588.61" y="331.67" class="decompiled"><title>int32_t __cdecl Output_VisibleZClip(const PHD_VBUF *vtx0, const PHD_VBUF *vtx1, const PHD_VBUF *vtx2);</title></rect>
<rect width="6.65" height="6.28" x="588.61" y="340.95" class="decompiled"><title>void __cdecl Overlay_AddDisplayPickup(GAME_OBJECT_ID object_id);</title></rect>
@ -2033,7 +2033,7 @@
<rect width="6.39" height="6.19" x="703.15" y="226.03" class="decompiled"><title>void __cdecl Object_SetupAllObjects(void);</title></rect>
<rect width="6.39" height="6.19" x="712.54" y="226.03" class="unused"><title>sub_4470F0</title></rect>
<rect width="6.39" height="6.19" x="721.93" y="226.03" class="unused"><title>sub_447AC0</title></rect>
<rect width="6.39" height="6.19" x="731.32" y="226.03" class="known"><title>void __cdecl SE_ControlsDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="6.39" height="6.19" x="731.32" y="226.03" class="decompiled"><title>void __cdecl SE_ControlsDlgUpdate(HWND hwndDlg);</title></rect>
<rect width="6.30" height="6.19" x="740.70" y="226.03" class="decompiled"><title>void __cdecl Object_Collision_Trap(int16_t item_num, ITEM *lara_item, COLL_INFO *coll);</title></rect>
<rect width="6.33" height="6.16" x="598.27" y="235.22" class="known"><title>void __cdecl AlarmSound_Control(int16_t item_num);</title></rect>
<rect width="6.33" height="6.16" x="598.27" y="244.38" class="decompiled"><title>int32_t __cdecl Lara_HitCeiling(ITEM *item, COLL_INFO *coll);</title></rect>
@ -2043,7 +2043,7 @@
<rect width="6.33" height="6.07" x="598.27" y="280.86" class="known"><title>int16_t __cdecl GunShot(int32_t x, int32_t y, int32_t z, int16_t speed, PHD_ANGLE yrot, int16_t room_num);</title></rect>
<rect width="6.33" height="5.90" x="598.27" y="289.93" class="decompiled"><title>void __cdecl CreateBubble(XYZ_32 *pos, int16_t room_num);</title></rect>
<rect width="6.33" height="5.90" x="598.27" y="298.83" class="decompiled"><title>int32_t __cdecl GameInit(bool skip_cd_init);</title></rect>
<rect width="6.33" height="5.90" x="598.27" y="307.72" class="known"><title>void __thiscall SE_DrawBitmap(BITMAP_RESOURCE *bmpRsrc, HDC hdc, int32_t x, int32_t y);</title></rect>
<rect width="6.33" height="5.90" x="598.27" y="307.72" class="decompiled"><title>void __thiscall SE_DrawBitmap(BITMAP_RESOURCE *bmpRsrc, HDC hdc, int32_t x, int32_t y);</title></rect>
<rect width="6.33" height="5.81" x="598.27" y="316.62" class="known"><title>void __cdecl FX_SwapMeshesWithMeshSwap1(ITEM *item);</title></rect>
<rect width="6.33" height="5.81" x="598.27" y="325.42" class="known"><title>void __cdecl FX_SwapMeshesWithMeshSwap2(ITEM *item);</title></rect>
<rect width="6.33" height="5.81" x="598.27" y="334.23" class="decompiled"><title>void __cdecl Inv_Ring_MotionInit(RING_INFO *ring, int16_t frames, int16_t status, int16_t status_target);</title></rect>
@ -2054,7 +2054,7 @@
<rect width="6" height="5.94" x="607.59" y="235.22" class="known"><title>void __cdecl InitialiseGameFlags(void);</title></rect>
<rect width="6" height="5.94" x="616.60" y="235.22" class="decompiled"><title>DWORD __cdecl CalculateCompatibleColor(COLOR_BIT_MASKS *mask, int32_t red, int32_t green, int32_t blue, int32_t alpha);</title></rect>
<rect width="6" height="5.94" x="625.60" y="235.22" class="decompiled"><title>int32_t __cdecl Music_GetFrames(void);</title></rect>
<rect width="6" height="5.94" x="634.61" y="235.22" class="known"><title>bool __cdecl SE_RegisterSetupWindowClass(void);</title></rect>
<rect width="6" height="5.94" x="634.61" y="235.22" class="decompiled"><title>bool __cdecl SE_RegisterSetupWindowClass(void);</title></rect>
<rect width="6" height="5.94" x="643.61" y="235.22" class="decompiled"><title>void __fastcall Output_FlatA(int32_t y0, int32_t y1, uint8_t color_idx); // actually, __watcall, which is esoteric and rarely supported</title></rect>
<rect width="5.91" height="5.94" x="652.62" y="235.22" class="decompiled"><title>void __cdecl Inv_Ring_GetView(RING_INFO *ring, PHD_3DPOS *viewer);</title></rect>
<rect width="5.91" height="5.94" x="661.53" y="235.22" class="decompiled"><title>void __cdecl Lara_State_SurfLeft(ITEM *item, COLL_INFO *coll);</title></rect>
@ -2067,18 +2067,18 @@
<rect width="5.82" height="5.94" x="723.73" y="235.22" class="unused"><title>sub_444AB0</title></rect>
<rect width="5.73" height="5.94" x="732.55" y="235.22" class="decompiled"><title>void __cdecl Lara_State_SurfBack(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="5.73" height="5.94" x="741.27" y="235.22" class="decompiled"><title>void __cdecl Sound_StopEffect(int32_t sample_id);</title></rect>
<rect width="5.57" height="6.10" x="607.59" y="244.16" class="known"><title>bool __cdecl GetRegistryDwordValue(LPCTSTR lpValueName, DWORD *pValue, DWORD defaultValue);</title></rect>
<rect width="5.57" height="6.10" x="607.59" y="244.16" class="decompiled"><title>bool __cdecl GetRegistryDwordValue(LPCTSTR lpValueName, DWORD *pValue, DWORD defaultValue);</title></rect>
<rect width="5.57" height="6" x="607.59" y="253.25" class="decompiled"><title>void __cdecl Item_UpdateRoom(ITEM *item, int32_t height);</title></rect>
<rect width="5.57" height="6" x="607.59" y="262.25" class="known"><title>void __cdecl BirdTweeter_Control(int16_t item_num);</title></rect>
<rect width="5.57" height="6" x="607.59" y="271.25" class="decompiled"><title>void __cdecl Inv_Ring_MotionItemSelect(RING_INFO *ring, INVENTORY_ITEM *inv_item);</title></rect>
<rect width="5.57" height="6" x="607.59" y="280.25" class="decompiled"><title>void __cdecl Lara_Col_ClimbLeft(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="5.57" height="6" x="607.59" y="289.25" class="known"><title>void __cdecl BaddieBiteEffect(ITEM *item, BITE *bite);</title></rect>
<rect width="5.57" height="6" x="607.59" y="298.26" class="known"><title>LRESULT __stdcall SE_NewPropSheetWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="5.57" height="6" x="607.59" y="298.26" class="decompiled"><title>LRESULT __stdcall SE_NewPropSheetWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);</title></rect>
<rect width="5.57" height="5.90" x="607.59" y="307.26" class="decompiled"><title>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));</title></rect>
<rect width="5.57" height="5.90" x="607.59" y="316.16" class="decompiled"><title>void __cdecl Room_AddFlipItems(ROOM *r);</title></rect>
<rect width="5.57" height="5.90" x="607.59" y="325.06" class="decompiled"><title>void __cdecl Gun_Pistols_Ready(LARA_GUN_TYPE weapon_type);</title></rect>
<rect width="5.57" height="5.90" x="607.59" y="333.97" class="decompiled"><title>BOOL __cdecl S_InitialiseSystem(void);</title></rect>
<rect width="5.57" height="5.90" x="607.59" y="342.87" class="known"><title>bool __cdecl GetRegistryFloatValue(LPCTSTR lpValueName, double *value, double defaultValue);</title></rect>
<rect width="5.57" height="5.90" x="607.59" y="342.87" class="decompiled"><title>bool __cdecl GetRegistryFloatValue(LPCTSTR lpValueName, double *value, double defaultValue);</title></rect>
<rect width="5.57" height="5.81" x="607.59" y="351.77" class="decompiled"><title>void __cdecl Lara_Col_UWDeath(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="5.57" height="5.71" x="607.59" y="360.58" class="decompiled"><title>void __cdecl Item_AddActive(int16_t item_num);</title></rect>
<rect width="5.57" height="5.71" x="607.59" y="369.29" class="decompiled"><title>void __cdecl WinInReadKeyboard(LPVOID lpInputData);</title></rect>
@ -2095,9 +2095,9 @@
<rect width="5.36" height="5.73" x="700.32" y="244.16" class="decompiled"><title>DWORD __cdecl Sync(void);</title></rect>
<rect width="5.26" height="5.73" x="708.68" y="244.16" class="decompiled"><title>void __cdecl Lara_State_FastBack(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="5.26" height="5.73" x="716.95" y="244.16" class="decompiled"><title>void __cdecl S_Wait(int32_t timeout, BOOL input_check);</title></rect>
<rect width="5.26" height="5.73" x="725.21" y="244.16" class="known"><title>int32_t __cdecl SE_GraphicsTest(void);</title></rect>
<rect width="5.26" height="5.73" x="733.47" y="244.16" class="known"><title>int32_t __cdecl SE_SoundTest(void);</title></rect>
<rect width="5.26" height="5.73" x="741.74" y="244.16" class="known"><title>void __thiscall SE_ChangeBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd);</title></rect>
<rect width="5.26" height="5.73" x="725.21" y="244.16" class="decompiled"><title>int32_t __cdecl SE_GraphicsTest(void);</title></rect>
<rect width="5.26" height="5.73" x="733.47" y="244.16" class="decompiled"><title>int32_t __cdecl SE_SoundTest(void);</title></rect>
<rect width="5.26" height="5.73" x="741.74" y="244.16" class="decompiled"><title>void __thiscall SE_ChangeBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd);</title></rect>
<rect width="5.35" height="5.55" x="616.17" y="252.89" class="decompiled"><title>void __cdecl Requester_Item_RightAlign(REQUEST_INFO *req, TEXTSTRING *txt);</title></rect>
<rect width="5.35" height="5.45" x="616.17" y="261.44" class="decompiled"><title>void __cdecl Room_GetNewRoom(int32_t x, int32_t y, int32_t z, int16_t room_num);</title></rect>
<rect width="5.35" height="5.45" x="616.17" y="269.88" class="decompiled"><title>void __cdecl Object_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll);</title></rect>
@ -2118,7 +2118,7 @@
<rect width="4.94" height="5.47" x="624.52" y="269.82" class="known"><title>void __cdecl S_SetupBelowWater(BOOL underwater);</title></rect>
<rect width="4.94" height="5.47" x="624.52" y="278.29" class="decompiled"><title>void __cdecl Music_Shutdown(void);</title></rect>
<rect width="4.94" height="5.47" x="624.52" y="286.76" class="decompiled"><title>bool __cdecl TIME_Init(void);</title></rect>
<rect width="4.94" height="5.47" x="624.52" y="295.22" class="known"><title>LPCTSTR __cdecl GuidBinaryToString(GUID *guid);</title></rect>
<rect width="4.94" height="5.47" x="624.52" y="295.22" class="decompiled"><title>LPCTSTR __cdecl GuidBinaryToString(GUID *guid);</title></rect>
<rect width="4.94" height="5.36" x="624.52" y="303.69" class="decompiled"><title>void __cdecl Creature_Underwater(ITEM *item, int32_t depth);</title></rect>
<rect width="4.94" height="5.36" x="624.52" y="312.05" class="decompiled"><title>const SECTOR *__cdecl Camera_GoodPosition(int32_t x, int32_t y, int32_t z, int16_t room_num);</title></rect>
<rect width="4.94" height="5.36" x="624.52" y="320.41" class="known"><title>void __cdecl Cultist3_Initialise(int16_t item_num);</title></rect>
@ -2131,7 +2131,7 @@
<rect width="4.97" height="5.12" x="632.45" y="252.89" class="decompiled"><title>int32_t __cdecl MovableBlock_TestDestination(ITEM *item, int32_t block_height);</title></rect>
<rect width="4.97" height="5.12" x="640.42" y="252.89" class="known"><title>void __cdecl GunFlash_Control(int16_t fx_num);</title></rect>
<rect width="4.97" height="5.12" x="648.39" y="252.89" class="decompiled"><title>JOYSTICK_NODE *__cdecl GetJoystick(GUID *lpGuid);</title></rect>
<rect width="4.97" height="5.12" x="656.35" y="252.89" class="known"><title>bool __cdecl OpenGameRegistryKey(LPCTSTR key);</title></rect>
<rect width="4.97" height="5.12" x="656.35" y="252.89" class="decompiled"><title>bool __cdecl OpenGameRegistryKey(LPCTSTR key);</title></rect>
<rect width="4.97" height="5.12" x="664.32" y="252.89" class="decompiled"><title>double __cdecl UT_Microseconds(void);</title></rect>
<rect width="4.86" height="5.12" x="672.28" y="252.89" class="decompiled"><title>void __cdecl Lara_State_Extra_StartAnim(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="4.86" height="5.12" x="680.15" y="252.89" class="decompiled"><title>void __cdecl BGND_Free(void);</title></rect>
@ -2144,16 +2144,16 @@
<rect width="4.66" height="5.12" x="734.68" y="252.89" class="decompiled"><title>void __cdecl Lara_State_FastTurn(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="4.66" height="5.12" x="742.34" y="252.89" class="decompiled"><title>void __cdecl Flare_SetArm(int32_t frame);</title></rect>
<rect width="4.80" height="4.98" x="632.45" y="261.02" class="known"><title>void __cdecl DartEffect_Control(int16_t fx_num);</title></rect>
<rect width="4.80" height="4.98" x="632.45" y="268.99" class="known"><title>void __cdecl SE_OptionsStrCat(LPTSTR *dstString, bool isEnabled, bool *isNext, LPCTSTR srcString);</title></rect>
<rect width="4.80" height="4.98" x="632.45" y="268.99" class="decompiled"><title>void __cdecl SE_OptionsStrCat(LPTSTR *dstString, bool isEnabled, bool *isNext, LPCTSTR srcString);</title></rect>
<rect width="4.80" height="4.87" x="632.45" y="276.97" class="decompiled"><title>void __cdecl Lara_State_BackJump(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="4.80" height="4.87" x="632.45" y="284.84" class="decompiled"><title>DISPLAY_MODE *__thiscall InsertDisplayModeInListTail(DISPLAY_MODE_LIST *modeList);</title></rect>
<rect width="4.80" height="4.87" x="632.45" y="292.71" class="decompiled"><title>void __cdecl HWR_EnableColorKey(bool state);</title></rect>
<rect width="4.80" height="4.87" x="632.45" y="300.58" class="decompiled"><title>void __cdecl HWR_FreeTexturePages(void);</title></rect>
<rect width="4.80" height="4.87" x="632.45" y="308.45" class="known"><title>LONG __cdecl SetRegistryStringValue(LPCTSTR lpValueName, LPCTSTR value, int32_t length);</title></rect>
<rect width="4.80" height="4.87" x="632.45" y="308.45" class="decompiled"><title>LONG __cdecl SetRegistryStringValue(LPCTSTR lpValueName, LPCTSTR value, int32_t length);</title></rect>
<rect width="4.80" height="4.76" x="632.45" y="316.32" class="decompiled"><title>void __cdecl Creature_Head(ITEM *item, int16_t required);</title></rect>
<rect width="4.80" height="4.76" x="632.45" y="324.08" class="decompiled"><title>void __cdecl LOT_ClearLOT(LOT_INFO *lot);</title></rect>
<rect width="4.80" height="4.76" x="632.45" y="331.84" class="decompiled"><title>void __cdecl Lara_CatchFire(void);</title></rect>
<rect width="4.80" height="4.76" x="632.45" y="339.61" class="known"><title>BOOL __cdecl ReadFileSync(HANDLE handle, LPVOID lpBuffer, DWORD nBytesToRead, LPDWORD lpnBytesRead, LPOVERLAPPED lpOverlapped);</title></rect>
<rect width="4.80" height="4.76" x="632.45" y="339.61" class="decompiled"><title>BOOL __cdecl ReadFileSync(HANDLE handle, LPVOID lpBuffer, DWORD nBytesToRead, LPDWORD lpnBytesRead, LPOVERLAPPED lpOverlapped);</title></rect>
<rect width="4.80" height="4.66" x="632.45" y="347.37" class="known"><title>void __cdecl AddDynamicLight(int32_t x, int32_t y, int32_t z, int32_t intensity, int32_t falloff);</title></rect>
<rect width="4.80" height="4.66" x="632.45" y="355.03" class="decompiled"><title>int32_t __cdecl CalculateWindowWidth(int32_t width, int32_t height);</title></rect>
<rect width="4.80" height="4.66" x="632.45" y="362.69" class="decompiled"><title>DISPLAY_ADAPTER_NODE *__cdecl WinVidGetDisplayAdapter(GUID *lpGuid);</title></rect>
@ -2183,7 +2183,7 @@
<rect width="4.60" height="4.32" x="640.25" y="327.66" class="decompiled"><title>void __cdecl WinVidShowGameWindow(int32_t nCmdShow);</title></rect>
<rect width="4.60" height="4.32" x="640.25" y="334.98" class="decompiled"><title>void __cdecl S_FadeToBlack(void);</title></rect>
<rect width="4.60" height="4.21" x="640.25" y="342.29" class="decompiled"><title>void __cdecl Door_Shut(DOORPOS_DATA *d);</title></rect>
<rect width="4.60" height="4.21" x="640.25" y="349.50" class="known"><title>int32_t __cdecl UT_ErrorBox(UINT uID, HWND hWnd);</title></rect>
<rect width="4.60" height="4.21" x="640.25" y="349.50" class="decompiled"><title>int32_t __cdecl UT_ErrorBox(UINT uID, HWND hWnd);</title></rect>
<rect width="4.60" height="4.10" x="640.25" y="356.71" class="decompiled"><title>void __cdecl Matrix_TranslateRel_I(int32_t x, int32_t y, int32_t z);</title></rect>
<rect width="4.60" height="4.10" x="640.25" y="363.80" class="decompiled"><title>void __cdecl Matrix_RotYXZ_I(int16_t y, int16_t x, int16_t z);</title></rect>
<rect width="4.60" height="4.10" x="640.25" y="370.90" class="decompiled"><title>void __cdecl WinVidSetMinWindowSize(int32_t width, int32_t height);</title></rect>
@ -2201,12 +2201,12 @@
<rect width="4.14" height="4.20" x="728.58" y="268.48" class="decompiled"><title>void __cdecl FallingBlock_Floor(const ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *out_height);</title></rect>
<rect width="4.14" height="4.20" x="735.72" y="268.48" class="decompiled"><title>void __cdecl Enumerate3DDevices(DISPLAY_ADAPTER *adapter);</title></rect>
<rect width="4.14" height="4.20" x="742.86" y="268.48" class="decompiled"><title>DWORD __cdecl EncodePutPCX(BYTE value, BYTE num, BYTE *buffer);</title></rect>
<rect width="4.47" height="3.89" x="647.85" y="275.68" class="known"><title>int32_t __stdcall SE_PropSheetCallback(HWND hwndDlg, UINT uMsg, LPARAM lParam);</title></rect>
<rect width="4.47" height="3.89" x="647.85" y="275.68" class="decompiled"><title>int32_t __stdcall SE_PropSheetCallback(HWND hwndDlg, UINT uMsg, LPARAM lParam);</title></rect>
<rect width="4.47" height="3.89" x="655.32" y="275.68" class="decompiled"><title>HWR_TEXTURE_HANDLE __cdecl GetTexturePageHandle(int32_t page_idx);</title></rect>
<rect width="4.35" height="3.89" x="662.79" y="275.68" class="decompiled"><title>void __cdecl Matrix_RotYXZsuperpack_I(const int16_t **pprot1, const int16_t **pprot2, int32_t skip);</title></rect>
<rect width="4.35" height="3.89" x="670.14" y="275.68" class="decompiled"><title>int32_t __cdecl Keyhole_Trigger(int16_t item_num);</title></rect>
<rect width="4.35" height="3.89" x="677.49" y="275.68" class="decompiled"><title>HRESULT __cdecl WinVidBufferLock(LPDDS surface, LPDDSDESC desc, DWORD flags);</title></rect>
<rect width="4.35" height="3.89" x="684.83" y="275.68" class="known"><title>int32_t __cdecl SE_SoundTestExecute(void);</title></rect>
<rect width="4.35" height="3.89" x="684.83" y="275.68" class="decompiled"><title>int32_t __cdecl SE_SoundTestExecute(void);</title></rect>
<rect width="4.23" height="3.89" x="692.18" y="275.68" class="decompiled"><title>void __cdecl Output_DrawPolyGTMap(const int16_t *obj_ptr);</title></rect>
<rect width="4.23" height="3.89" x="699.41" y="275.68" class="decompiled"><title>void __cdecl Output_DrawPolyWGTMap(const int16_t *obj_ptr);</title></rect>
<rect width="4.23" height="3.89" x="706.64" y="275.68" class="decompiled"><title>void __cdecl Boat_Initialise(int16_t item_num);</title></rect>
@ -2251,15 +2251,15 @@
<rect width="3.68" height="3.84" x="654.99" y="323.68" class="decompiled"><title>uint32_t __cdecl Text_GetScaleH(uint32_t value);</title></rect>
<rect width="3.68" height="3.84" x="654.99" y="330.52" class="decompiled"><title>bool __cdecl D3DIsSupported(LPD3DDEVICEDESC desc);</title></rect>
<rect width="3.68" height="3.84" x="654.99" y="337.36" class="decompiled"><title>void __cdecl S_InitialiseScreen(GAMEFLOW_LEVEL_TYPE level_type);</title></rect>
<rect width="3.68" height="3.84" x="654.99" y="344.19" class="known"><title>LONG __cdecl SetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize);</title></rect>
<rect width="3.68" height="3.84" x="654.99" y="351.03" class="known"><title>void __thiscall SE_ReleaseBitmapResource(BITMAP_RESOURCE *bmpRsrc);</title></rect>
<rect width="3.68" height="3.84" x="654.99" y="344.19" class="decompiled"><title>LONG __cdecl SetRegistryBinaryValue(LPCTSTR lpValueName, LPBYTE value, DWORD valueSize);</title></rect>
<rect width="3.68" height="3.84" x="654.99" y="351.03" class="decompiled"><title>void __thiscall SE_ReleaseBitmapResource(BITMAP_RESOURCE *bmpRsrc);</title></rect>
<rect width="3.68" height="3.71" x="654.99" y="357.86" class="decompiled"><title>void __cdecl Output_PrintPolyList(uint8_t *surface_ptr);</title></rect>
<rect width="3.68" height="3.71" x="654.99" y="364.58" class="decompiled"><title>void __cdecl Lara_Col_Default(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="3.68" height="3.71" x="654.99" y="371.29" class="decompiled"><title>void __cdecl Drawbridge_Floor(const ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *out_height);</title></rect>
<rect width="3.88" height="3.51" x="661.67" y="289.50" class="decompiled"><title>void __cdecl ChangeFileNameExtension(char *file_name, const char *file_ext);</title></rect>
<rect width="3.88" height="3.51" x="668.55" y="289.50" class="decompiled"><title>DWORD __cdecl S_DumpScreen(void);</title></rect>
<rect width="3.88" height="3.51" x="675.43" y="289.50" class="known"><title>LPVOID __cdecl UT_LoadResource(LPCTSTR lpName, LPCTSTR lpType);</title></rect>
<rect width="3.88" height="3.51" x="682.32" y="289.50" class="known"><title>LONG __cdecl SetRegistryFloatValue(LPCTSTR lpValueName, double value);</title></rect>
<rect width="3.88" height="3.51" x="675.43" y="289.50" class="decompiled"><title>LPVOID __cdecl UT_LoadResource(LPCTSTR lpName, LPCTSTR lpType);</title></rect>
<rect width="3.88" height="3.51" x="682.32" y="289.50" class="decompiled"><title>LONG __cdecl SetRegistryFloatValue(LPCTSTR lpValueName, double value);</title></rect>
<rect width="3.76" height="3.51" x="689.20" y="289.50" class="decompiled"><title>void __cdecl Output_DrawPolyFlat(const int16_t *obj_ptr);</title></rect>
<rect width="3.76" height="3.51" x="695.95" y="289.50" class="decompiled"><title>void __cdecl Output_DrawPolyTrans(const int16_t *obj_ptr);</title></rect>
<rect width="3.76" height="3.51" x="702.71" y="289.50" class="decompiled"><title>void __cdecl Output_DrawPolyGouraud(const int16_t *obj_ptr);</title></rect>
@ -2316,7 +2316,7 @@
<rect width="3.36" height="3.26" x="674.66" y="346.83" class="decompiled"><title>void __cdecl BridgeTilt1_Floor(const ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *out_height);</title></rect>
<rect width="3.36" height="3.26" x="674.66" y="353.09" class="decompiled"><title>bool __cdecl BGND_Init(void);</title></rect>
<rect width="3.36" height="3.26" x="674.66" y="359.35" class="decompiled"><title>void __cdecl CleanupTextures(void);</title></rect>
<rect width="3.36" height="3.26" x="674.66" y="365.61" class="known"><title>BOOL __cdecl OpenRegistryKey(LPCTSTR lpSubKey);</title></rect>
<rect width="3.36" height="3.26" x="674.66" y="365.61" class="decompiled"><title>BOOL __cdecl OpenRegistryKey(LPCTSTR lpSubKey);</title></rect>
<rect width="3.36" height="3.13" x="674.66" y="371.87" class="decompiled"><title>void __cdecl Creature_Initialise(int16_t item_num);</title></rect>
<rect width="3.32" height="3.17" x="681.03" y="302.76" class="decompiled"><title>int32_t __cdecl Room_FindGridShift(int32_t src, int32_t dst);</title></rect>
<rect width="3.32" height="3.17" x="687.35" y="302.76" class="decompiled"><title>void __cdecl Inv_Ring_RotateLeft(RING_INFO *ring);</title></rect>
@ -2340,7 +2340,7 @@
<rect width="3.24" height="2.85" x="731.27" y="308.93" class="decompiled"><title>void __cdecl Drawbridge_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll);</title></rect>
<rect width="3.24" height="2.85" x="737.51" y="308.93" class="decompiled"><title>void __cdecl Text_Init(void);</title></rect>
<rect width="3.24" height="2.85" x="743.76" y="308.93" class="decompiled"><title>void __cdecl S_Audio_Sample_AdjustTrackVolumeAndPan(int32_t track_id, int32_t volume, int32_t pan);</title></rect>
<rect width="3.18" height="2.91" x="681.03" y="314.78" class="known"><title>LPTSTR __cdecl UT_FindArg(LPCTSTR str);</title></rect>
<rect width="3.18" height="2.91" x="681.03" y="314.78" class="decompiled"><title>LPTSTR __cdecl UT_FindArg(LPCTSTR str);</title></rect>
<rect width="3.18" height="2.91" x="681.03" y="320.68" class="decompiled"><title>uint32_t __fastcall Math_Sqrt(uint32_t n);</title></rect>
<rect width="3.18" height="2.77" x="681.03" y="326.59" class="decompiled"><title>void __cdecl Lara_State_Slide(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="3.18" height="2.77" x="681.03" y="332.36" class="decompiled"><title>void __cdecl Gun_Rifle_UndrawMeshes(LARA_GUN_TYPE weapon_type);</title></rect>
@ -2352,7 +2352,7 @@
<rect width="3.18" height="2.64" x="681.03" y="366.72" class="decompiled"><title>void __cdecl S_Audio_Sample_Shutdown(void);</title></rect>
<rect width="3.18" height="2.64" x="681.03" y="372.36" class="decompiled"><title>void __cdecl S_UnloadLevelFile(void);</title></rect>
<rect width="2.95" height="2.85" x="687.21" y="314.78" class="decompiled"><title>int32_t __cdecl S_Audio_Sample_CalculateSampleVolume(int32_t volume);</title></rect>
<rect width="2.95" height="2.85" x="693.16" y="314.78" class="known"><title>LONG __cdecl SetRegistryBoolValue(LPCTSTR lpValueName, bool value);</title></rect>
<rect width="2.95" height="2.85" x="693.16" y="314.78" class="decompiled"><title>LONG __cdecl SetRegistryBoolValue(LPCTSTR lpValueName, bool value);</title></rect>
<rect width="2.81" height="2.85" x="699.11" y="314.78" class="decompiled"><title>void __cdecl Text_AddOutline(TEXTSTRING *string, int16_t enable, int16_t color, uint16_t *gour_ptr, uint16_t flags);</title></rect>
<rect width="2.81" height="2.85" x="704.93" y="314.78" class="decompiled"><title>void __cdecl DInputKeyboardRelease(void);</title></rect>
<rect width="2.81" height="2.85" x="710.74" y="314.78" class="decompiled"><title>void __cdecl HWR_ResetTexSource(void);</title></rect>
@ -2368,7 +2368,7 @@
<rect width="2.47" height="2.77" x="687.21" y="338.08" class="decompiled"><title>void __cdecl ScreenClear(bool is_phd_win_size);</title></rect>
<rect width="2.47" height="2.77" x="687.21" y="343.85" class="decompiled"><title>int32_t __cdecl S_Audio_Sample_CalculateSamplePan(int16_t pan);</title></rect>
<rect width="2.47" height="2.77" x="687.21" y="349.62" class="decompiled"><title>void __cdecl FreeTexturePages(void);</title></rect>
<rect width="2.47" height="2.77" x="687.21" y="355.39" class="known"><title>void __cdecl SE_PassMessageToImage(HWND hWnd, UINT uMsg, WPARAM wParam);</title></rect>
<rect width="2.47" height="2.77" x="687.21" y="355.39" class="decompiled"><title>void __cdecl SE_PassMessageToImage(HWND hWnd, UINT uMsg, WPARAM wParam);</title></rect>
<rect width="2.47" height="2.62" x="687.21" y="361.15" class="decompiled"><title>void __cdecl Inv_Ring_MotionCameraPos(RING_INFO *ring, int16_t target);</title></rect>
<rect width="2.47" height="2.62" x="687.21" y="366.77" class="decompiled"><title>int32_t __cdecl Text_Remove(TEXTSTRING *string);</title></rect>
<rect width="2.47" height="2.62" x="687.21" y="372.38" class="decompiled"><title>HRESULT __cdecl WinVidBufferUnlock(LPDDS surface, LPDDSDESC desc);</title></rect>
@ -2419,7 +2419,7 @@
<rect width="1.79" height="2.19" x="703.21" y="357.23" class="decompiled"><title>void __cdecl Text_AlignBottom(TEXTSTRING *string, int16_t enable);</title></rect>
<rect width="1.79" height="2.19" x="703.21" y="362.42" class="decompiled"><title>int32_t __cdecl Random_GetControl(void);</title></rect>
<rect width="1.79" height="2.19" x="703.21" y="367.62" class="decompiled"><title>int32_t __cdecl Random_GetDraw(void);</title></rect>
<rect width="1.79" height="2.19" x="703.21" y="372.81" class="known"><title>LONG __cdecl SetRegistryDwordValue(LPCTSTR lpValueName, DWORD value);</title></rect>
<rect width="1.79" height="2.19" x="703.21" y="372.81" class="decompiled"><title>LONG __cdecl SetRegistryDwordValue(LPCTSTR lpValueName, DWORD value);</title></rect>
<rect width="1.92" height="2.06" x="708.01" y="331.27" class="decompiled"><title>void __cdecl Matrix_Push(void);</title></rect>
<rect width="1.76" height="2.06" x="712.93" y="331.27" class="decompiled"><title>void __cdecl Lara_State_Special(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="1.76" height="2.06" x="717.69" y="331.27" class="decompiled"><title>void __cdecl Lara_State_Extra_GongBong(ITEM *item, COLL_INFO *coll);</title></rect>
@ -2434,7 +2434,7 @@
<rect width="1.96" height="1.69" x="708.01" y="345.70" class="decompiled"><title>void __cdecl S_Audio_Sample_OutSetPitch(int32_t track_id, int32_t pitch);</title></rect>
<rect width="1.96" height="1.69" x="708.01" y="350.39" class="decompiled"><title>int32_t __cdecl GetFreePaletteIndex(void);</title></rect>
<rect width="1.96" height="1.69" x="708.01" y="355.07" class="decompiled"><title>int32_t __cdecl GetFreeTexturePageIndex(void);</title></rect>
<rect width="1.96" height="1.69" x="708.01" y="359.76" class="known"><title>void __thiscall SE_UpdateBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd, HWND hSender);</title></rect>
<rect width="1.96" height="1.69" x="708.01" y="359.76" class="decompiled"><title>void __thiscall SE_UpdateBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd, HWND hSender);</title></rect>
<rect width="1.96" height="1.52" x="708.01" y="364.44" class="decompiled"><title>void __cdecl Inv_RemoveAllItems(void);</title></rect>
<rect width="1.96" height="1.52" x="708.01" y="368.96" class="decompiled"><title>void __cdecl Requester_Item_CenterAlign(REQUEST_INFO *req, TEXTSTRING *txt);</title></rect>
<rect width="1.96" height="1.52" x="708.01" y="373.48" class="decompiled"><title>void __cdecl Lara_ControlExtra(int16_t item_num);</title></rect>
@ -2456,12 +2456,12 @@
<rect width="1.30" height="1.63" x="712.97" y="373.37" class="unused"><title>sub_447A80</title></rect>
<rect width="1.79" height="1.16" x="717.27" y="340.99" class="unused"><title>sub_447B30</title></rect>
<rect width="1.79" height="1.16" x="722.06" y="340.99" class="decompiled"><title>BOOL __cdecl S_LoadLevelFile(LPCTSTR file_name, int32_t level_num, GAMEFLOW_LEVEL_TYPE level_type);</title></rect>
<rect width="1.79" height="1.16" x="726.85" y="340.99" class="known"><title>int32_t __cdecl UT_MessageBox(LPCTSTR lpText, HWND hWnd);</title></rect>
<rect width="1.79" height="1.16" x="726.85" y="340.99" class="decompiled"><title>int32_t __cdecl UT_MessageBox(LPCTSTR lpText, HWND hWnd);</title></rect>
<rect width="1.59" height="1.16" x="731.64" y="340.99" class="known"><title>void __cdecl FX_AssaultReset(ITEM *item);</title></rect>
<rect width="1.59" height="1.16" x="736.23" y="340.99" class="decompiled"><title>void __cdecl Text_SetScale(TEXTSTRING *string, int32_t scale_h, int32_t scale_v);</title></rect>
<rect width="1.59" height="1.16" x="740.82" y="340.99" class="decompiled"><title>void __cdecl WinInRunControlPanel(HWND hWnd);</title></rect>
<rect width="1.59" height="1.16" x="745.41" y="340.99" class="unused"><title>sub_44E860</title></rect>
<rect width="1.28" height="1.46" x="717.27" y="345.15" class="known"><title>void __cdecl SE_GraphicsAdapterSet(HWND hwndDlg, DISPLAY_ADAPTER_NODE *adapter);</title></rect>
<rect width="1.28" height="1.46" x="717.27" y="345.15" class="decompiled"><title>void __cdecl SE_GraphicsAdapterSet(HWND hwndDlg, DISPLAY_ADAPTER_NODE *adapter);</title></rect>
<rect width="1.28" height="1.46" x="721.55" y="345.15" class="decompiled"><title>void __cdecl S_Audio_Sample_OutCloseTrack(int32_t track_id);</title></rect>
<rect width="1.09" height="1.46" x="725.82" y="345.15" class="known"><title>void __cdecl FX_Turn180(ITEM *item);</title></rect>
<rect width="1.09" height="1.46" x="729.92" y="345.15" class="known"><title>void __cdecl FX_InvisibilityOff(ITEM *item);</title></rect>
@ -2475,7 +2475,7 @@
<rect width="1.12" height="1.03" x="717.27" y="361.89" class="decompiled"><title>void __cdecl Lara_State_ClimbDown(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="1.12" height="1.03" x="717.27" y="365.92" class="decompiled"><title>void __cdecl Lara_State_Dive(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="1.12" height="1.03" x="717.27" y="369.95" class="decompiled"><title>void __cdecl S_AdjustTexelCoordinates(void);</title></rect>
<rect width="1.12" height="1.03" x="717.27" y="373.97" class="known"><title>void __cdecl SE_GraphicsTestFinish(void);</title></rect>
<rect width="1.12" height="1.03" x="717.27" y="373.97" class="decompiled"><title>void __cdecl SE_GraphicsTestFinish(void);</title></rect>
<rect width="0.89" height="1.06" x="721.39" y="349.61" class="decompiled"><title>void __cdecl Requester_RemoveAllItems(REQUEST_INFO *req);</title></rect>
<rect width="0.89" height="1.06" x="721.39" y="353.66" class="decompiled"><title>void __cdecl Lara_State_UpJump(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="0.89" height="1.06" x="721.39" y="357.72" class="decompiled"><title>void __cdecl Lara_State_Extra_Airlock(ITEM *item, COLL_INFO *coll);</title></rect>
@ -2487,7 +2487,7 @@
<rect width="1.16" height="0.79" x="729.43" y="349.61" class="decompiled"><title>void __thiscall S_FlaggedString_Delete(STRING_FLAGGED *string);</title></rect>
<rect width="1.16" height="0.79" x="733.59" y="349.61" class="decompiled"><title>void __cdecl WinVidFinish(void);</title></rect>
<rect width="1.16" height="0.79" x="737.75" y="349.61" class="decompiled"><title>bool __cdecl S_IntroFMV(const char *file_name1, const char *file_name2);</title></rect>
<rect width="1.16" height="0.79" x="741.90" y="349.61" class="known"><title>LONG __cdecl DeleteRegistryValue(LPCTSTR lpValueName);</title></rect>
<rect width="1.16" height="0.79" x="741.90" y="349.61" class="decompiled"><title>LONG __cdecl DeleteRegistryValue(LPCTSTR lpValueName);</title></rect>
<rect width="0.94" height="0.79" x="746.06" y="349.61" class="unused"><title>sub_4449A0</title></rect>
<rect width="0.58" height="1.18" x="725.28" y="353.40" class="decompiled"><title>DISPLAY_MODE *__thiscall InsertDisplayMode(DISPLAY_MODE_LIST *modeList, DISPLAY_MODE_NODE *before);</title></rect>
<rect width="0.58" height="1.18" x="725.28" y="357.58" class="unused"><title>sub_4470C0</title></rect>
@ -2495,19 +2495,19 @@
<rect width="0.58" height="1.18" x="725.28" y="365.93" class="decompiled"><title>void __cdecl SafeFreePalette(int32_t palette_idx);</title></rect>
<rect width="0.58" height="0.95" x="725.28" y="370.11" class="decompiled"><title>HWND __cdecl WinVidFindGameWindow(void);</title></rect>
<rect width="0.58" height="0.95" x="725.28" y="374.05" class="decompiled"><title>void __cdecl GameBuf_Shutdown(void);</title></rect>
<rect width="0.74" height="0.77" x="728.85" y="353.40" class="known"><title>HWND __cdecl SE_FindSetupDialog(void);</title></rect>
<rect width="0.74" height="0.77" x="728.85" y="353.40" class="decompiled"><title>HWND __cdecl SE_FindSetupDialog(void);</title></rect>
<rect width="0.52" height="0.77" x="732.60" y="353.40" class="decompiled"><title>void __cdecl Text_RemoveBackground(TEXTSTRING *string);</title></rect>
<rect width="0.52" height="0.77" x="736.12" y="353.40" class="decompiled"><title>void __cdecl Text_RemoveOutline(TEXTSTRING *string);</title></rect>
<rect width="0.52" height="0.77" x="739.65" y="353.40" class="unused"><title>sub_44E880</title></rect>
<rect width="0.52" height="0.77" x="743.17" y="353.40" class="decompiled"><title>void __cdecl ScreenPartialDump(void);</title></rect>
<rect width="0.30" height="0.77" x="746.70" y="353.40" class="decompiled"><title>void __cdecl WinInFinish(void);</title></rect>
<rect width="0.35" height="0.72" x="728.85" y="357.17" class="decompiled"><title>void __cdecl S_FinishInventory(void);</title></rect>
<rect width="0.35" height="0.72" x="728.85" y="360.89" class="known"><title>bool __cdecl IsNewRegistryKeyCreated(void);</title></rect>
<rect width="0.35" height="0.72" x="728.85" y="360.89" class="decompiled"><title>bool __cdecl IsNewRegistryKeyCreated(void);</title></rect>
<rect width="0.35" height="0.47" x="728.85" y="364.61" class="decompiled"><title>bool __cdecl S_PlayFMV(const char *file_name);</title></rect>
<rect width="0.35" height="0.47" x="728.85" y="368.08" class="known"><title>void __cdecl SE_AdvancedDlgInit(HWND hwndDlg);</title></rect>
<rect width="0.35" height="0.47" x="728.85" y="368.08" class="decompiled"><title>void __cdecl SE_AdvancedDlgInit(HWND hwndDlg);</title></rect>
<rect width="0.35" height="0.22" x="728.85" y="371.55" class="decompiled"><title>void __thiscall DisplayModeListInit(DISPLAY_MODE_LIST *pList);</title></rect>
<rect width="0.35" height="0.22" x="728.85" y="374.78" class="decompiled"><title>void __cdecl ScreenDump(void);</title></rect>
<rect width="0.35" height="0.22" x="732.20" y="357.17" class="known"><title>LONG __cdecl CloseRegistryKey(void);</title></rect>
<rect width="0.35" height="0.22" x="732.20" y="357.17" class="decompiled"><title>LONG __cdecl CloseRegistryKey(void);</title></rect>
<rect width="0.10" height="0.22" x="735.55" y="357.17" class="decompiled"><title>LPCTSTR __cdecl DecodeErrorMessage(DWORD error_code);</title></rect>
<rect width="0.10" height="0.22" x="738.65" y="357.17" class="known"><title>void __cdecl FX_FinishLevel(ITEM *item);</title></rect>
<rect width="0.10" height="0.22" x="741.49" y="357.17" class="known"><title>void __cdecl FX_DynamicLightOff(ITEM *item);</title></rect>
@ -2519,8 +2519,8 @@
<rect width="0.10" height="0.10" x="732.20" y="369.34" class="decompiled"><title>void __cdecl Lara_State_Splat(ITEM *item, COLL_INFO *coll);</title></rect>
<rect width="0.10" height="0.10" x="732.20" y="372.22" class="decompiled"><title>void __cdecl Random_SeedControl(int32_t seed);</title></rect>
<rect width="0.10" height="0.10" x="732.20" y="375.11" class="decompiled"><title>void __cdecl Random_SeedDraw(int32_t seed);</title></rect>
<rect width="0.11" height="0.10" x="735.07" y="360.38" class="known"><title>void __cdecl SE_SoundAdapterSet(HWND hwndDlg, SOUND_ADAPTER_NODE *adapter);</title></rect>
<rect width="0.11" height="0.10" x="738.18" y="360.38" class="known"><title>void __cdecl SE_ControlsJoystickSet(HWND hwndDlg, JOYSTICK_NODE *joystick);</title></rect>
<rect width="0.11" height="0.10" x="735.07" y="360.38" class="decompiled"><title>void __cdecl SE_SoundAdapterSet(HWND hwndDlg, SOUND_ADAPTER_NODE *adapter);</title></rect>
<rect width="0.11" height="0.10" x="738.18" y="360.38" class="decompiled"><title>void __cdecl SE_ControlsJoystickSet(HWND hwndDlg, JOYSTICK_NODE *joystick);</title></rect>
<rect width="0.11" height="0.10" x="741.29" y="360.38" class="decompiled"><title>void __cdecl Sound_SetMasterVolume(int32_t volume);</title></rect>
<rect width="0.10" height="0.10" x="744.40" y="360.38" class="known"><title>void __cdecl FX_InvisibilityOn(ITEM *item);</title></rect>
<rect width="0.10" height="0.10" x="747.20" y="360.38" class="known"><title>void __cdecl FX_DynamicLightOn(ITEM *item);</title></rect>
@ -2566,10 +2566,10 @@
<rect width="0.10" height="0.10" x="743.78" y="374.35" class="unused"><title>sub_447FA0</title></rect>
<rect width="0.10" height="0.10" x="743.78" y="376.18" class="unused"><title>sub_448410</title></rect>
<rect width="0.10" height="0.10" x="746.06" y="372.53" class="unused"><title>sub_4523A0</title></rect>
<rect width="0.10" height="0.10" x="748.03" y="372.53" class="known"><title>LONG __cdecl CloseGameRegistryKey(void);</title></rect>
<rect width="0.10" height="0.10" x="746.06" y="374.63" class="known"><title>void __cdecl SE_SoundTestFinish(void);</title></rect>
<rect width="0.10" height="0.10" x="748.03" y="372.53" class="decompiled"><title>LONG __cdecl CloseGameRegistryKey(void);</title></rect>
<rect width="0.10" height="0.10" x="746.06" y="374.63" class="decompiled"><title>void __cdecl SE_SoundTestFinish(void);</title></rect>
<rect width="0.10" height="0.10" x="746.06" y="376.74" class="decompiled"><title>bool __cdecl RenderInit(void);</title></rect>
<rect width="0.10" height="0.10" x="748.03" y="374.63" class="known"><title>int32_t __cdecl SE_GraphicsTestExecute(void);</title></rect>
<rect width="0.10" height="0.10" x="748.03" y="374.63" class="decompiled"><title>int32_t __cdecl SE_GraphicsTestExecute(void);</title></rect>
<rect width="0.10" height="0.10" x="748.03" y="375.90" class="unused"><title>void __cdecl Output_InsertInventoryBackground(const int16_t *obj_ptr);</title></rect>
<rect width="0.10" height="0.10" x="749.01" y="375.90" class="unused"><title>sub_444BC0</title></rect>
<rect width="0.10" height="0.10" x="748.03" y="376.74" class="unused"><title>sub_448420</title></rect>

Before

Width:  |  Height:  |  Size: 372 KiB

After

Width:  |  Height:  |  Size: 373 KiB

Before After
Before After

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -2,14 +2,14 @@
#include "memory.h"
#include <windows.h>
#include <dbghelp.h>
#include <tlhelp32.h>
#include <dwarfstack.h>
#include <process.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <dbghelp.h>
#include <tlhelp32.h>
static char *m_MiniDumpPath = NULL;
static char *M_GetMiniDumpPath(const char *log_path);

View file

@ -9,10 +9,12 @@
#include <libtrx/config/file.h>
#include <libtrx/debug.h>
#include <libtrx/log.h>
#include <stdio.h>
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)

View file

@ -1,6 +1,9 @@
#pragma once
#include "global/types.h"
#include <libtrx/config.h>
#include <libtrx/gfx/common.h>
#include <libtrx/screenshot.h>
#include <stdbool.h>
@ -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;

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

@ -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 <libtrx/utils.h>
#include <libtrx/virtual_file.h>
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;
}

View file

@ -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 <libtrx/debug.h>
#include <libtrx/engine/video.h>
@ -19,14 +18,8 @@
#include <string.h>
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)

View file

@ -2,10 +2,6 @@
#include <stdbool.h>
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);

View file

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

View file

@ -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 <libtrx/utils.h>
#include <math.h>
#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;
}

View file

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

View file

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

View file

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

77
src/tr2/game/fader.c Normal file
View file

@ -0,0 +1,77 @@
#include "game/fader.h"
#include "config.h"
#include "game/input.h"
#include "game/shell.h"
#include "global/const.h"
#include <libtrx/utils.h>
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);
}

24
src/tr2/game/fader.h Normal file
View file

@ -0,0 +1,24 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
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);

View file

@ -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 <libtrx/utils.h>
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;

View file

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

View file

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

View file

@ -1,283 +0,0 @@
#include "game/hwr.h"
#include "decomp/decomp.h"
#include "global/funcs.h"
#include "global/vars.h"
#include <d3d.h>
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;
}

View file

@ -1,27 +0,0 @@
#pragma once
#include "global/types.h"
#include <d3dtypes.h>
#include <stdbool.h>
#include <windows.h>
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);

View file

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

View file

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

View file

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

View file

@ -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 <libtrx/memory.h>
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);
}

View file

@ -4,8 +4,4 @@
#include <libtrx/virtual_file.h>
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);

View file

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

View file

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

View file

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

View file

@ -8,7 +8,7 @@
#include <stdio.h>
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);

View file

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

View file

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

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

@ -4,10 +4,15 @@
#include <stdint.h>
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);

View file

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

View file

@ -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 <libtrx/debug.h>
#include <libtrx/gfx/fade/fade_renderer.h>
#include <libtrx/log.h>
#include <libtrx/memory.h>
#include <libtrx/utils.h>
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);
}
}

View file

@ -0,0 +1,70 @@
#pragma once
#include "global/types.h"
#include <libtrx/engine/image.h>
#include <libtrx/gfx/2d/2d_surface.h>
#include <stdbool.h>
#include <stdint.h>
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);

1628
src/tr2/game/render/hwr.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,5 @@
#pragma once
#include "game/render/priv.h"
void Renderer_HW_Prepare(RENDERER *renderer);

533
src/tr2/game/render/priv.c Normal file
View file

@ -0,0 +1,533 @@
#include "game/render/priv.h"
#include "config.h"
#include "global/vars.h"
#include <libtrx/utils.h>
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;
}

View file

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

2270
src/tr2/game/render/swr.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,5 @@
#pragma once
#include "game/render/priv.h"
void Renderer_SW_Prepare(RENDERER *renderer);

View file

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

View file

@ -0,0 +1,5 @@
#pragma once
#include "global/types.h"
RGBA_8888 Render_ARGB1555To8888(uint16_t argb1555);

View file

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

View file

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

View file

@ -2,3 +2,5 @@
#include "game/shell/common.h"
#include "game/shell/input.h"
#include <libtrx/game/shell.h>

View file

@ -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 <libtrx/enum_map.h>
#include <libtrx/game/shell.h>
#include <libtrx/game/ui/common.h>
#include <libtrx/log.h>
#include <libtrx/memory.h>
#include <SDL2/SDL.h>
#include <stdarg.h>
#include <stdio.h>
#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;
}
}
}

View file

@ -2,10 +2,16 @@
#include "global/types.h"
#include <libtrx/game/shell.h>
void __cdecl Shell_Main(void);
void __cdecl Shell_Shutdown(void);
void __cdecl Shell_ExitSystem(const char *message);
void __cdecl Shell_ExitSystemFmt(const char *fmt, ...);
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);

View file

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

View file

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

View file

@ -1,3 +1,5 @@
#include "config.h"
#include <libtrx/game/ui/common.h>
#include <SDL2/SDL.h>

View file

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

View file

@ -3,20 +3,15 @@
#include <stdint.h>
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);

View file

@ -1,6 +1,9 @@
#include "global/types.h"
#include <libtrx/enum_map.h>
#include <libtrx/game/input.h>
#include <libtrx/game/objects/ids.h>
#include <libtrx/gfx/common.h>
#include <libtrx/screenshot.h>
void EnumMap_Init(void)

View file

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

View file

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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

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

View file

@ -2,6 +2,8 @@
#include "global/vars_decomp.h"
#include <libtrx/gfx/context.h>
#include <SDL2/SDL.h>
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;

View file

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

View file

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

View file

@ -1,2 +0,0 @@
#define operator_delete ((void __cdecl (*)(void *mem))0x00459050)
#define operator_new ((void *__cdecl (*)(size_t size))0x00459060)

View file

@ -1,19 +0,0 @@
#pragma once
#include <windows.h>
#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)

View file

@ -1,8 +0,0 @@
#pragma once
#include <windows.h>
#define DirectInputCreate \
((HRESULT(__stdcall *)( \
HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUT * lpDirectInput, \
LPUNKNOWN punkOuter))0x00457CC0)

View file

@ -1,11 +0,0 @@
#pragma once
#include <windows.h>
#define DirectSoundCreate \
((HRESULT(__stdcall *)( \
LPCGUID pcGuidDevice, LPDIRECTSOUND * ppDS, \
LPUNKNOWN pUnkOuter))0x00458CEE)
#define DirectSoundEnumerateA \
((HRESULT(__stdcall *)( \
LPDSENUMCALLBACKA pDSEnumCallback, LPVOID pContext))0x00458CE8)

View file

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

View file

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

View file

@ -1,25 +0,0 @@
#pragma once
#include <windows.h>
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

View file

@ -1,5 +1,4 @@
#include "inject_exec.h"
#include "lib/winmm.h"
#include <libtrx/filesystem.h>
#include <libtrx/log.h>
@ -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;

View file

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

View file

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

View file

@ -1,10 +0,0 @@
#pragma once
#include "global/types.h"
#include <stdbool.h>
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);

View file

@ -58,7 +58,12 @@ def main() -> None:
"game/music/music_main.c": "game/music.h",
},
fix_map={},
forced_order=["<ddrawi.h>", "<d3dhal.h>"],
forced_order=[
"<mmeapi.h>",
"<dsound.h>",
"<ddrawi.h>",
"<d3dhal.h>"
],
)
sort_imports(
@ -80,6 +85,7 @@ def main() -> None:
},
fix_map={},
forced_order=[
"<dsound.h>",
"<windows.h>",
"<dbghelp.h>",
"<tlhelp32.h>",

View file

@ -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."
}
}
}

View file

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

View file

@ -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 <libtrx/game/rooms/types.h>",
"#include <libtrx/game/text.h>",
"",
"#include <ddraw.h>",
"#include <ddrawi.h>",
"#include <d3dhal.h>",
"#include <dsound.h>",
"#include <stdbool.h>",
"#include <stdint.h>",
"#include <windows.h>",