Skip to content

Commit

Permalink
port HWR_SetHardwareVideoMode + fix #130
Browse files Browse the repository at this point in the history
  • Loading branch information
rr- committed Oct 16, 2021
1 parent 87fcb9a commit f29c6ee
Show file tree
Hide file tree
Showing 15 changed files with 155 additions and 43 deletions.
4 changes: 4 additions & 0 deletions cfg/Tomb1Main.json5
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,8 @@

// Disables ingame cinematics.
"disable_cine": false,

// Overrides game resolution. Leave at 0 or engative values to automatically guess from the screen size.
"resolution_width": -1,
"resolution_height": -1,
}
14 changes: 7 additions & 7 deletions docs/progress.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions docs/progress.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ HWR_RenderBegin_0 0x00407804 0x00000023 +
HWR_RenderBegin 0x00407827 0x00000014 +
HWR_RenderEnd 0x0040783B 0x00000027 +
HWR_RenderToggle 0x00407862 0x0000001A +
HWR_GetSurfaceAndPitch 0x0040787C 0x00000095 -
HWR_GetSurfaceAndPitch 0x0040787C 0x00000095 *
HWR_SetupRenderContextAndRender2 0x00407911 0x0000004E -
HWR_SetupRenderContextAndRender 0x0040795F 0x0000008A +
HWR_FlipPrimaryBuffer 0x004079E9 0x00000060 +
HWR_ClearSurface 0x00407A49 0x00000048 +
HWR_ReleaseSurfaces 0x00407A91 0x00000141 *
HWR_SetHardwareVideoMode 0x00407BD2 0x00000433 *
HWR_SetHardwareVideoMode 0x00407BD2 0x00000433 +
HWR_InitialiseHardware 0x00408005 0x0000031E *
HWR_ShutdownHardware 0x00408323 0x00000029 -
HWR_PrepareFMV 0x0040834C 0x0000001C *
Expand Down
13 changes: 13 additions & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <stdlib.h>
#include <string.h>
#include <windows.h>

#define Q(x) #x
#define QUOTE(x) Q(x)
Expand Down Expand Up @@ -192,6 +193,18 @@ int8_t T1MReadConfig()

result = T1MReadConfigFromJson(cfg_data);

if (T1MConfig.resolution_width > 0) {
AvailableResolutions[RESOLUTIONS_SIZE - 1].width =
T1MConfig.resolution_width;
AvailableResolutions[RESOLUTIONS_SIZE - 1].height =
T1MConfig.resolution_height;
} else {
AvailableResolutions[RESOLUTIONS_SIZE - 1].width =
GetSystemMetrics(SM_CXSCREEN);
AvailableResolutions[RESOLUTIONS_SIZE - 1].height =
GetSystemMetrics(SM_CYSCREEN);
}

cleanup:
if (fp) {
FileClose(fp);
Expand Down
2 changes: 2 additions & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ typedef struct {
int8_t disable_demo;
int8_t disable_fmv;
int8_t disable_cine;
int32_t resolution_width;
int32_t resolution_height;
} T1MConfigStruct;

extern T1MConfigStruct T1MConfig;
Expand Down
5 changes: 5 additions & 0 deletions src/game/game.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,11 @@ void GetSavedGamesList(REQUEST_INFO *req)
req->y = -100;
req->vis_lines = 12;
break;

case 4:
req->y = -100;
req->vis_lines = 12;
break;
}

if (req->requested >= req->vis_lines) {
Expand Down
23 changes: 6 additions & 17 deletions src/game/option.c
Original file line number Diff line number Diff line change
Expand Up @@ -565,21 +565,10 @@ void DoDetailOptionHW(INVENTORY_ITEM *inv_item)
DetailTextHW[DETAIL_HW_RESOLUTION] = T_Print(0, y, " ");
max_row = DETAIL_HW_UI_BAR_SCALE;
} else {
const char *tmp;
switch (GameHiRes) {
case 0:
tmp = "320x200";
break;
case 1:
tmp = "512x384";
break;
case 3:
tmp = "800x600";
break;
default:
tmp = "640x480";
break;
}
static char tmp[10];
sprintf(
tmp, "%dx%d", AvailableResolutions[GameHiRes].width,
AvailableResolutions[GameHiRes].height);
sprintf(buf, GF.strings[GS_DETAIL_VIDEO_MODE_FMT], tmp);
DetailTextHW[DETAIL_HW_RESOLUTION] = T_Print(0, y, buf);
max_row = DETAIL_HW_RESOLUTION;
Expand Down Expand Up @@ -663,7 +652,7 @@ void DoDetailOptionHW(INVENTORY_ITEM *inv_item)
break;

case DETAIL_HW_RESOLUTION:
if (GameHiRes < 3) {
if (GameHiRes + 1 < RESOLUTIONS_SIZE) {
GameHiRes++;
reset = 1;
}
Expand Down Expand Up @@ -702,7 +691,7 @@ void DoDetailOptionHW(INVENTORY_ITEM *inv_item)
break;

case DETAIL_HW_RESOLUTION:
if (GameHiRes > 0) {
if (GameHiRes - 1 >= 0) {
GameHiRes--;
reset = 1;
}
Expand Down
5 changes: 3 additions & 2 deletions src/game/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ static int32_t S_ReadUserSettingsT1MFromJson(const char *cfg_data)
RenderSettings &= ~RSF_PERSPECTIVE;
}

GameHiRes = json_object_get_number_int(root_obj, "hi_res", 3);
CLAMP(GameHiRes, 0, 3);
GameHiRes =
json_object_get_number_int(root_obj, "hi_res", RESOLUTIONS_SIZE - 1);
CLAMP(GameHiRes, 0, RESOLUTIONS_SIZE - 1);

GameSizer = json_object_get_number_double(root_obj, "game_sizer", 1.0);

Expand Down
2 changes: 2 additions & 0 deletions src/global/const.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,4 +220,6 @@
#define SOUND_ACTION 16
#define VIDEO_ACTION 32

#define RESOLUTIONS_SIZE 5

#endif
5 changes: 5 additions & 0 deletions src/global/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1189,6 +1189,11 @@ typedef enum GAME_BONUS_FLAG {

#pragma pack(push, 1)

typedef struct HWR_Resolution {
int width;
int height;
} HWR_Resolution;

typedef struct RGB888 {
uint8_t r;
uint8_t g;
Expand Down
4 changes: 4 additions & 0 deletions src/global/vars.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,7 @@ int32_t InvExtraData[8];
int16_t InvChosen = -1;

int16_t BarOffsetY[6];

HWR_Resolution AvailableResolutions[RESOLUTIONS_SIZE] = {
{ 320, 200 }, { 512, 384 }, { 640, 480 }, { 800, 600 }, { -1, -1 },
};
2 changes: 2 additions & 0 deletions src/global/vars.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,4 +305,6 @@ extern int16_t InvChosen;

extern int16_t BarOffsetY[6];

extern HWR_Resolution AvailableResolutions[RESOLUTIONS_SIZE];

#endif
2 changes: 2 additions & 0 deletions src/global/vars_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#define Surface1 VAR_U_(0x005DA6A4, LPDIRECTDRAWSURFACE)
#define Surface2 VAR_U_(0x005DB484, LPDIRECTDRAWSURFACE)
#define Surface3 VAR_U_(0x005DA744, LPDIRECTDRAWSURFACE)
#define Surface4 VAR_U_(0x00463608, LPDIRECTDRAWSURFACE)
#define TextureSurfaces ARRAY_(0x005DA6C0, LPDIRECTDRAWSURFACE, [32])
#define Surface1DrawPtr VAR_U_(0x00463564, void*)
#define Surface2DrawPtr VAR_U_(0x005DB480, void*)
#define DDraw VAR_U_(0x0045A998, LPDIRECTDRAW)
Expand Down
109 changes: 95 additions & 14 deletions src/specific/hwr.c
Original file line number Diff line number Diff line change
Expand Up @@ -748,24 +748,104 @@ void HWR_FadeWait()

void HWR_SwitchResolution()
{
if (HiRes == 0) {
GameVidWidth = 320;
GameVidHeight = 200;
} else if (HiRes == 1) {
GameVidWidth = 512;
GameVidHeight = 384;
} else if (HiRes == 3) {
GameVidWidth = GetSystemMetrics(SM_CXSCREEN);
GameVidHeight = GetSystemMetrics(SM_CYSCREEN);
} else {
GameVidWidth = 640;
GameVidHeight = 480;
}
GameVidWidth = AvailableResolutions[HiRes].width;
GameVidHeight = AvailableResolutions[HiRes].height;

HWR_SetHardwareVideoMode();
SetupScreenSize();
}

int32_t HWR_SetHardwareVideoMode()
{
DDSURFACEDESC surface_desc;
HRESULT result;

LOG_INFO("SetHardwareVideoMode:");
HWR_ReleaseSurfaces();

DDrawSurfaceWidth = AvailableResolutions[HiRes].width;
DDrawSurfaceHeight = AvailableResolutions[HiRes].height;
DDrawSurfaceMaxX = AvailableResolutions[HiRes].width - 1.0f;
DDrawSurfaceMaxY = AvailableResolutions[HiRes].height - 1.0f;

LOG_INFO(" Switching to %dx%d", DDrawSurfaceWidth, DDrawSurfaceHeight);
result = IDirectDraw_SetDisplayMode(
DDraw, DDrawSurfaceWidth, DDrawSurfaceHeight, 16);
HWR_CheckError(result);

LOG_INFO(" Allocating front/back buffers");
memset(&surface_desc, 0, sizeof(surface_desc));
surface_desc.dwSize = sizeof(surface_desc);
surface_desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
surface_desc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP | DDSCAPS_COMPLEX;
surface_desc.dwBackBufferCount = 1;
result = IDirectDraw2_CreateSurface(DDraw, &surface_desc, &Surface1, 0);
HWR_CheckError(result);

HWR_ClearSurface(Surface1);
LOG_INFO(" Picking up back buffer");
DDSCAPS caps = { DDSCAPS_BACKBUFFER };
result = IDirectDrawSurface_GetAttachedSurface(Surface1, &caps, &Surface2);
HWR_CheckError(result);

HWR_ClearSurface(Surface2);
LOG_INFO(" Allocating Z-buffer");
memset(&surface_desc, 0, sizeof(surface_desc));
surface_desc.dwSize = sizeof(surface_desc);
surface_desc.dwFlags =
DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_ZBUFFERBITDEPTH;
surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY;
surface_desc.dwWidth = DDrawSurfaceWidth;
surface_desc.dwHeight = DDrawSurfaceHeight;
surface_desc.dwZBufferBitDepth = 16;
result = IDirectDraw2_CreateSurface(DDraw, &surface_desc, &Surface4, 0);
HWR_CheckError(result);

LOG_INFO(" Creating texture surfaces");
for (int i = 0; i < 16; i++) {
memset(&surface_desc, 0, sizeof(surface_desc));
surface_desc.dwSize = sizeof(surface_desc);
surface_desc.dwFlags =
DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
surface_desc.ddpfPixelFormat.dwSize = 32;
surface_desc.ddpfPixelFormat.dwRGBBitCount = 8;
surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
surface_desc.dwWidth = 256;
surface_desc.dwHeight = 256;
result = IDirectDraw2_CreateSurface(
DDraw, &surface_desc, &TextureSurfaces[i], 0);
HWR_CheckError(result);
}

void *surface;
int32_t pitch;
HWR_GetSurfaceAndPitch(Surface2, &Surface2DrawPtr, &pitch);
HWR_GetSurfaceAndPitch(Surface1, &Surface1DrawPtr, &pitch);
LOG_INFO(
"Pitch = %x Draw1Ptr = %x Draw2Ptr = %x", pitch, Surface1DrawPtr,
Surface2DrawPtr);
ATI3DCIF_ContextSetState(ATIRenderContext, C3D_ERS_SURF_DRAW_PITCH, &pitch);
HWR_SetupRenderContextAndRender();

HWR_RenderEnd();
HWR_GetSurfaceAndPitch(Surface4, &surface, &pitch);
HWR_RenderToggle();
ATI3DCIF_ContextSetState(ATIRenderContext, C3D_ERS_SURF_Z_PTR, &surface);
ATI3DCIF_ContextSetState(ATIRenderContext, C3D_ERS_SURF_Z_PITCH, &pitch);

C3D_RECT viewport;
viewport.top = 0;
viewport.left = 0;
viewport.right = DDrawSurfaceWidth - 1;
viewport.bottom = DDrawSurfaceHeight - 1;
ATI3DCIF_ContextSetState(ATIRenderContext, C3D_ERS_SURF_VPORT, &viewport);
ATI3DCIF_ContextSetState(ATIRenderContext, C3D_ERS_SURF_SCISSOR, &viewport);
LOG_INFO(" complete");
return 1;
}

void HWR_SetupRenderContextAndRender()
{
HWR_RenderBegin();
Expand All @@ -785,8 +865,10 @@ void T1MInjectSpecificHWR()
INJECT(0x00407827, HWR_RenderBegin);
INJECT(0x0040783B, HWR_RenderEnd);
INJECT(0x00407862, HWR_RenderToggle);
INJECT(0x0040795F, HWR_SetupRenderContextAndRender);
INJECT(0x004079E9, HWR_FlipPrimaryBuffer);
INJECT(0x00407A49, HWR_ClearSurface);
INJECT(0x00407BD2, HWR_SetHardwareVideoMode);
INJECT(0x004089F4, HWR_SwitchResolution);
INJECT(0x00408A70, HWR_DumpScreen);
INJECT(0x00408B2C, HWR_BlitSurface);
Expand All @@ -800,5 +882,4 @@ void T1MInjectSpecificHWR()
INJECT(0x0040C8E7, HWR_DrawTranslucentQuad);
INJECT(0x0040CC5D, HWR_RenderLightningSegment);
INJECT(0x0040D056, HWR_DrawLightningSegment);
INJECT(0x0040795F, HWR_SetupRenderContextAndRender);
}
4 changes: 3 additions & 1 deletion src/specific/hwr.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@
#define HWR_PrepareFMV ((void (*)())0x0040834C)
#define HWR_FMVInit ((void (*)())0x0040837F)
#define HWR_FMVDone ((void (*)())0x00408368)
#define HWR_SetHardwareVideoMode ((void (*)())0x00407BD2)
#define HWR_InitPolyList ((void (*)())0x0040D0F7)
#define HWR_OutputPolyList ((void (*)())0x0040D2E0)
#define HWR_PrintShadow ((void (*)(PHD_VBUF *vbuf, int clip))0x0040CADB)
#define HWR_InsertObjectGT4 ((const int16_t *(*)(const int16_t *obj_ptr, int32_t vertex_count))0x0040C25A)
#define HWR_InsertObjectGT3 ((const int16_t *(*)(const int16_t *obj_ptr, int32_t vertex_count))0x0040C34E)
#define HWR_InsertObjectG4 ((const int16_t *(*)(const int16_t *obj_ptr, int32_t vertex_count))0x00409F44)
#define HWR_InsertObjectG3 ((const int16_t *(*)(const int16_t *obj_ptr, int32_t vertex_count))0x0040A01D)
#define HWR_GetSurfaceAndPitch ((void (*)(LPDIRECTDRAWSURFACE surface, void **out_surface, int32_t *out_pitch))0x0040787C)
#define HWR_ReleaseSurfaces ((void (*)())0x00407A91)
// clang-format on

void HWR_CheckError(HRESULT result);
Expand Down Expand Up @@ -58,6 +59,7 @@ void HWR_DrawLightningSegment(
int32_t HWR_ClipVertices(int32_t num, C3D_VTCF *source);
int32_t HWR_ClipVertices2(int32_t num, C3D_VTCF *source);
void HWR_SwitchResolution();
int32_t HWR_SetHardwareVideoMode();
void HWR_SetupRenderContextAndRender();

void T1MInjectSpecificHWR();
Expand Down

0 comments on commit f29c6ee

Please sign in to comment.