Skip to content

Commit

Permalink
add UI scaling
Browse files Browse the repository at this point in the history
  • Loading branch information
rr- committed Feb 14, 2021
1 parent 986bd0c commit 1841b5a
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 61 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ Currently the following configuration options are supported:
- `enable_enemy_healthbar`: enables showing healthbar for the active enemy.
- `enable_enhanced_look`: allows the player to look while running, jumping
etc. (similar to TR2 style).
- `enable_enhanced_ui`: enables UI scaling of in-game inventory text and ammo
text (useful for 4k screens).
- `enable_numeric_keys`: enables quick weapon draws and medpack usage.
- <kbd>1</kbd>: draw pistols
- <kbd>2</kbd>: draw shotgun
Expand Down
1 change: 1 addition & 0 deletions TR1Main.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"enable_red_healthbar": true,
"enable_enemy_healthbar": true,
"enable_enhanced_look": true,
"enable_enhanced_ui": true,
"enable_numeric_keys": true,
"fix_end_of_level_freeze": true,
"fix_tihocan_secret_sound": true
Expand Down
2 changes: 1 addition & 1 deletion src/game/health.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ void __cdecl DrawPickups()
pu->duration = 0;
} else {
S_DrawUISprite(
x, y, TR1MGetOverlayScale(12288), pu->sprnum, 4096);
x, y, TR1MGetRenderScale(12288), pu->sprnum, 4096);
x -= sprite_width;
}
}
Expand Down
147 changes: 93 additions & 54 deletions src/game/text.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "util.h"
#include <string.h>

#define TEXT_BOX_OFFSET 2

static int8_t TextSpacing[110] = {
14 /*A*/, 11 /*B*/, 11 /*C*/, 11 /*D*/, 11 /*E*/, 11 /*F*/, 11 /*G*/,
13 /*H*/, 8 /*I*/, 11 /*J*/, 12 /*K*/, 11 /*L*/, 13 /*M*/, 13 /*N*/,
Expand Down Expand Up @@ -224,11 +226,7 @@ int32_t __cdecl T_GetTextWidth(TEXTSTRING* textstring)
}

if (letter == ' ') {
if (textstring->scale_h == PHD_ONE) {
width += textstring->word_spacing;
} else {
width += (textstring->word_spacing * textstring->scale_h) >> 16;
}
width += textstring->word_spacing * textstring->scale_h / PHD_ONE;
continue;
}

Expand All @@ -240,14 +238,9 @@ int32_t __cdecl T_GetTextWidth(TEXTSTRING* textstring)
letter = letter + 81;
}

if (textstring->scale_h == PHD_ONE) {
width += textstring->letter_spacing + TextSpacing[letter];
} else {
width +=
(((int32_t)textstring->letter_spacing + TextSpacing[letter])
* textstring->scale_h)
>> 16;
}
width += ((TextSpacing[letter] + textstring->letter_spacing)
* textstring->scale_h)
/ PHD_ONE;
}
width -= textstring->letter_spacing;
width &= 0xFFFE;
Expand Down Expand Up @@ -288,7 +281,8 @@ void __cdecl T_DrawText()
} else {
int fps_x;
int fps_y;
if (TR1MGetOverlayScale(1) > 1) {
if (!TR1MConfig.enable_enhanced_ui
&& TR1MGetRenderScaleGLRage(1) > 1) {
fps_x = TR1MData.fps_x;
fps_y = TR1MData.fps_y;
} else {
Expand Down Expand Up @@ -325,6 +319,7 @@ void __cdecl T_DrawText()

void __cdecl T_DrawThisText(TEXTSTRING* textstring)
{
int sx, sy, sh, sv;
if (textstring->flags & TF_FLASH) {
textstring->flash_count -= (int16_t)Camera.number_frames;
if (textstring->flash_count <= -textstring->flash_rate) {
Expand All @@ -340,20 +335,35 @@ void __cdecl T_DrawThisText(TEXTSTRING* textstring)
int zpos = textstring->zpos;
int textwidth = T_GetTextWidth(textstring);

if (textstring->flags & TF_CENTRE_H) {
xpos += (DumpWidth - textwidth) / 2;
} else if (textstring->flags & TF_RIGHT) {
xpos += DumpWidth - textwidth;
}
if (TR1MConfig.enable_enhanced_ui) {
if (textstring->flags & TF_CENTRE_H) {
xpos += (TR1MGetRenderWidthDownscaled() - textwidth) / 2;
} else if (textstring->flags & TF_RIGHT) {
xpos += TR1MGetRenderWidthDownscaled() - textwidth;
}

if (textstring->flags & TF_CENTRE_V) {
ypos += TR1MGetRenderHeightDownscaled() / 2;
} else if (textstring->flags & TF_BOTTOM) {
ypos += TR1MGetRenderHeightDownscaled();
}
} else {
if (textstring->flags & TF_CENTRE_H) {
xpos += (DumpWidth - textwidth) / 2;
} else if (textstring->flags & TF_RIGHT) {
xpos += DumpWidth - textwidth;
}

if (textstring->flags & TF_CENTRE_V) {
ypos += DumpHeight / 2;
} else if (textstring->flags & TF_BOTTOM) {
ypos += DumpHeight;
if (textstring->flags & TF_CENTRE_V) {
ypos += DumpHeight / 2;
} else if (textstring->flags & TF_BOTTOM) {
ypos += DumpHeight;
}
}

int bxpos = textstring->bgnd_off_x + xpos - 2;
int bypos = textstring->bgnd_off_y + ypos - 4 - TEXT_HEIGHT;
int bxpos = textstring->bgnd_off_x + xpos - TEXT_BOX_OFFSET;
int bypos =
textstring->bgnd_off_y + ypos - TEXT_BOX_OFFSET * 2 - TEXT_HEIGHT;

int letter = '\0';
while (*string) {
Expand All @@ -363,7 +373,7 @@ void __cdecl T_DrawThisText(TEXTSTRING* textstring)
}

if (letter == ' ') {
xpos += (textstring->word_spacing * textstring->scale_h) >> 16;
xpos += (textstring->word_spacing * textstring->scale_h) / PHD_ONE;
continue;
}

Expand All @@ -376,22 +386,27 @@ void __cdecl T_DrawThisText(TEXTSTRING* textstring)
sprite = letter + 81;
}

sx = xpos;
sy = ypos;
sh = textstring->scale_h;
sv = textstring->scale_v;
if (TR1MConfig.enable_enhanced_ui) {
sx = TR1MGetRenderScale(sx);
sy = TR1MGetRenderScale(sy);
sh = TR1MGetRenderScale(sh);
sv = TR1MGetRenderScale(sv);
}
S_DrawScreenSprite2d(
xpos, ypos, zpos, textstring->scale_h, textstring->scale_v,
Objects[O_ALPHABET].mesh_index + sprite, 16 << 8,
textstring->text_flags, 0);
sx, sy, zpos, sh, sv, Objects[O_ALPHABET].mesh_index + sprite,
16 << 8, textstring->text_flags, 0);

if (letter == '(' || letter == ')' || letter == '$' || letter == '~') {
continue;
}

if (textstring->scale_h == PHD_ONE) {
xpos += textstring->letter_spacing + TextSpacing[sprite];
} else {
xpos += (((int32_t)textstring->letter_spacing + TextSpacing[sprite])
* textstring->scale_h)
>> 16;
}
xpos += (((int32_t)textstring->letter_spacing + TextSpacing[sprite])
* textstring->scale_h)
/ PHD_ONE;
}

int bwidth = 0;
Expand All @@ -400,9 +415,9 @@ void __cdecl T_DrawThisText(TEXTSTRING* textstring)
if (textstring->bgnd_size_x) {
bxpos += textwidth / 2;
bxpos -= textstring->bgnd_size_x / 2;
bwidth = textstring->bgnd_size_x + 4;
bwidth = textstring->bgnd_size_x + TEXT_BOX_OFFSET * 2;
} else {
bwidth = textwidth + 4;
bwidth = textwidth + TEXT_BOX_OFFSET * 2;
}
if (textstring->bgnd_size_y) {
bheight = textstring->bgnd_size_y;
Expand All @@ -411,41 +426,65 @@ void __cdecl T_DrawThisText(TEXTSTRING* textstring)
}
}

sx = bxpos;
sy = bypos;
sh = bwidth;
sv = bheight;
if (TR1MConfig.enable_enhanced_ui) {
sx = TR1MGetRenderScale(sx);
sy = TR1MGetRenderScale(sy);
sh = TR1MGetRenderScale(sh);
sv = TR1MGetRenderScale(sv);
}

if (textstring->flags & TF_BGND) {
if (textstring->bgnd_gour) {
int bhw = bwidth / 2;
int bhh = bheight / 2;
int bhw2 = bwidth - bhw;
int bhh2 = bheight - bhh;
int bhw = sh / 2;
int bhh = sv / 2;
int bhw2 = sh - bhw;
int bhh2 = sv - bhh;

S_DrawScreenFBox(
bxpos, bypos, zpos + textstring->bgnd_off_z + 8, bhw, bhh,
sx, sy, zpos + textstring->bgnd_off_z + 8, bhw, bhh,
textstring->bgnd_colour, textstring->bgnd_gour,
textstring->bgnd_flags);

S_DrawScreenFBox(
bxpos + bhw, bypos, zpos + textstring->bgnd_off_z + 8, bhw2,
bhh, textstring->bgnd_colour, textstring->bgnd_gour + 4,
sx + bhw, sy, zpos + textstring->bgnd_off_z + 8, bhw2, bhh,
textstring->bgnd_colour, textstring->bgnd_gour + 4,
textstring->bgnd_flags);

S_DrawScreenFBox(
bxpos + bhw, bypos + bhh, zpos + textstring->bgnd_off_z + 8,
bhw, bhh2, textstring->bgnd_colour, textstring->bgnd_gour + 8,
sx + bhw, sy + bhh, zpos + textstring->bgnd_off_z + 8, bhw,
bhh2, textstring->bgnd_colour, textstring->bgnd_gour + 8,
textstring->bgnd_flags);

S_DrawScreenFBox(
bxpos, bypos + bhh, zpos + textstring->bgnd_off_z + 8, bhw2,
bhh2, textstring->bgnd_colour, textstring->bgnd_gour + 12,
sx, sy + bhh, zpos + textstring->bgnd_off_z + 8, bhw2, bhh2,
textstring->bgnd_colour, textstring->bgnd_gour + 12,
textstring->bgnd_flags);
} else {
S_DrawScreenFBox(
bxpos, bypos, zpos + textstring->bgnd_off_z + 8, bwidth,
bheight, textstring->bgnd_colour, 0, textstring->bgnd_flags);
sx, sy, zpos + textstring->bgnd_off_z + 8, sh, sv,
textstring->bgnd_colour, 0, textstring->bgnd_flags);
S_DrawScreenBox(
bxpos, bypos, textstring->bgnd_off_z + zpos, bwidth, bheight, 0,
0, 0);
sx, sy, textstring->bgnd_off_z + zpos, sh, sv, 0, 0, 0);
}
}

if (textstring->flags & TF_OUTLINE) {
sx = bxpos;
sy = bypos;
sh = bwidth;
sv = bheight;
if (TR1MConfig.enable_enhanced_ui) {
sx = TR1MGetRenderScale(sx);
sy = TR1MGetRenderScale(sy);
sh = TR1MGetRenderScale(sh);
sv = TR1MGetRenderScale(sv);
}
S_DrawScreenBox(
bxpos, bypos, zpos + textstring->bgnd_off_z, bwidth, bheight,
sx, sy, zpos + textstring->bgnd_off_z, sh, sv,
textstring->outl_colour, textstring->outl_gour,
textstring->outl_flags);
}
Expand Down
2 changes: 2 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ static int TR1MReadConfig()
tr1m_json_get_boolean_value(json, "enable_enemy_healthbar");
TR1MConfig.enable_enhanced_look =
tr1m_json_get_boolean_value(json, "enable_enhanced_look");
TR1MConfig.enable_enhanced_ui =
tr1m_json_get_boolean_value(json, "enable_enhanced_ui");
TR1MConfig.enable_numeric_keys =
tr1m_json_get_boolean_value(json, "enable_numeric_keys");
TR1MConfig.fix_end_of_level_freeze =
Expand Down
52 changes: 47 additions & 5 deletions src/mod.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,57 @@
#include "mod.h"
#include <math.h>

int TR1MGetOverlayScale(int base)
int MulDiv(int x, int y, int z)
{
return (x * y) / z;
}

int TR1MGetRenderHeightDownscaled()
{
return PhdWinHeight * PHD_ONE / TR1MGetRenderScale(PHD_ONE);
}

int TR1MGetRenderWidthDownscaled()
{
return PhdWinWidth * PHD_ONE / TR1MGetRenderScale(PHD_ONE);
}

int TR1MGetRenderHeight()
{
return PhdWinHeight;
}

int TR1MGetRenderWidth()
{
return PhdWinWidth;
}

int TR1MGetRenderScale(int unit)
{
// TR2Main-style UI scaler
int baseWidth = 800;
int baseHeight = 600;
int scaleX =
(PhdWinWidth > baseWidth) ? MulDiv(PhdWinWidth, unit, baseWidth) : unit;
int scaleY = (PhdWinHeight > baseHeight)
? MulDiv(PhdWinHeight, unit, baseHeight)
: unit;
if (scaleX < scaleY) {
return scaleX;
}
return scaleY;
}

int TR1MGetRenderScaleGLRage(int unit)
{
// GLRage-style UI scaler
double result = PhdWinWidth;
result *= base;
result *= unit;
result /= 800.0;

// only scale up, not down
if (result < base) {
result = base;
if (result < unit) {
result = unit;
}

return round(result);
Expand Down Expand Up @@ -50,7 +92,7 @@ void TR1MRenderBar(int value, int value_max, int bar_type)
const int color_border_2 = 17;
const int color_bgnd = 0;

int scale = TR1MGetOverlayScale(1.0);
int scale = TR1MGetRenderScaleGLRage(1);
int width = percent_max * scale;
int height = 5 * scale;

Expand Down
8 changes: 7 additions & 1 deletion src/mod.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct {
int enable_red_healthbar;
int enable_enemy_healthbar;
int enable_enhanced_look;
int enable_enhanced_ui;
int enable_numeric_keys;
int fix_end_of_level_freeze;
int fix_tihocan_secret_sound;
Expand All @@ -32,7 +33,12 @@ struct {
int fps_y;
} TR1MData;

int TR1MGetOverlayScale(int base);
int TR1MGetRenderScale(int base);
int TR1MGetRenderScaleGLRage(int unit);
void TR1MRenderBar(int value, int value_max, int bar_type);
int TR1MGetRenderHeightDownscaled();
int TR1MGetRenderWidthDownscaled();
int TR1MGetRenderHeight();
int TR1MGetRenderWidth();

#endif

0 comments on commit 1841b5a

Please sign in to comment.