From b85e2d34b69aabaf2960172aa65a5001bb5d7612 Mon Sep 17 00:00:00 2001 From: rr- Date: Sun, 28 Feb 2021 21:25:35 +0100 Subject: [PATCH] add fov support It's needed in order to avoid conflicts with GLRage. Basically we override the entire thing in a way that stays consistent with it. In the future it might be a subject to improvements. --- Tomb1Main.json | 12 +++++++++++- src/3dsystem/3d_gen.c | 19 +++++++++++++++++++ src/config.c | 14 +++++++++++--- src/config.h | 2 ++ src/json_utils.c | 14 ++++++++++++++ src/json_utils.h | 1 + src/util.h | 24 ++++++++++++++++++++++++ 7 files changed, 82 insertions(+), 4 deletions(-) diff --git a/Tomb1Main.json b/Tomb1Main.json index 4c77a7904..07e177c30 100644 --- a/Tomb1Main.json +++ b/Tomb1Main.json @@ -130,5 +130,15 @@ // Fixes ability to obtain pistols by running out of ammo with other guns. // (Happens if you get to shotgun before obtaining pistols in Natla's // Mines) - "fix_illegal_gun_equip": true + "fix_illegal_gun_equip": true, + + // The desired field of view in degrees, which overrides the hardcoded + // default. The default values are 80 (horizontal) and 65 (vertical). + "fov_value": 65, + + // Interprets fov_value as vertical instead of horizontal field of view. + // May be advantageous for widescreen resolutions, especially for + // multi-screen setups, since it distorts the left and right side instead + // of cropping away the top and bottom part of the screen. + "fov_vertical": true, } diff --git a/src/3dsystem/3d_gen.c b/src/3dsystem/3d_gen.c index 3f9dca2a8..e045940e2 100644 --- a/src/3dsystem/3d_gen.c +++ b/src/3dsystem/3d_gen.c @@ -1,6 +1,12 @@ #include "3dsystem/3d_gen.h" #include "3dsystem/phd_math.h" #include "game/vars.h" +#include "config.h" + +#ifdef T1M_FEAT_UI + #include "specific/output.h" + #include +#endif void phd_InitWindow( int32_t x, int32_t y, int32_t width, int32_t height, int32_t nearz, @@ -32,6 +38,19 @@ void phd_InitWindow( void AlterFOV(PHD_ANGLE fov) { +#ifdef T1M_FEAT_UI + // NOTE: every caller GAME_FOV anyway, apart from GLRage which we override + // here. + fov = T1MConfig.fov_value * PHD_DEGREE; + + if (T1MConfig.fov_vertical) { + double aspect_ratio = GetRenderWidth() / (double)GetRenderHeight(); + double fov_rad_h = fov * M_PI / 32760; + double fov_rad_v = 2 * atan(aspect_ratio * tan(fov_rad_h / 2)); + fov = round((fov_rad_v / M_PI) * 32760); + } +#endif + int16_t c = phd_cos(fov / 2); int16_t s = phd_sin(fov / 2); PhdPersp = (c * (PhdWinWidth / 2)) / s; diff --git a/src/config.c b/src/config.c index 4fdd126d6..ae57b0ecb 100644 --- a/src/config.c +++ b/src/config.c @@ -1,8 +1,9 @@ +#include "config.h" +#include "game/const.h" +#include "json_utils.h" +#include "util.h" #include #include -#include "json_utils.h" -#include "config.h" -#include "utils.h" #define Q(x) #x #define QUOTE(x) Q(x) @@ -119,6 +120,7 @@ int T1MReadConfig() READ_BOOL(fix_pyramid_secret_trigger); READ_BOOL(fix_hardcoded_secret_counts); READ_BOOL(fix_illegal_gun_equip); + READ_BOOL(fov_vertical); T1MConfig.healthbar_showing_mode = ReadBarShowingMode(json, "healthbar_showing_mode"); @@ -139,6 +141,12 @@ int T1MReadConfig() T1MConfig.enemy_healthbar_color = ReadBarColorConfig(json, "enemy_healthbar_color", T1M_BC_GREY); + T1MConfig.fov_value = JSONGetIntegerValue(json, "fov_value"); + if (!T1MConfig.fov_value) { + T1MConfig.fov_value = GAME_FOV; + } + CLAMP(T1MConfig.fov_value, 30, 255); + free(json); free(cfg_data); return 1; diff --git a/src/config.h b/src/config.h index 7b4e96aad..d653c2812 100644 --- a/src/config.h +++ b/src/config.h @@ -60,6 +60,8 @@ struct { int8_t fix_pyramid_secret_trigger; int8_t fix_hardcoded_secret_counts; int8_t fix_illegal_gun_equip; + int8_t fov_value; + int8_t fov_vertical; } T1MConfig; int T1MReadConfig(); diff --git a/src/json_utils.c b/src/json_utils.c index 4d47a93bf..cb7e9defd 100644 --- a/src/json_utils.c +++ b/src/json_utils.c @@ -1,5 +1,6 @@ #include "json_utils.h" #include +#include "util.h" struct json_value_s* JSONGetField(struct json_value_s* root, const char* name) { @@ -27,6 +28,19 @@ int8_t JSONGetBooleanValue(struct json_value_s* root, const char* name) return field->type == json_type_true; } +int32_t JSONGetIntegerValue(struct json_value_s* root, const char* name) +{ + struct json_value_s* field = JSONGetField(root, name); + if (!field) { + return 0; + } + struct json_number_s* number = json_value_as_number(field); + if (!number) { + return 0; + } + return atoi(number->number); +} + const char* JSONGetStringValue(struct json_value_s* root, const char* name) { struct json_value_s* field = JSONGetField(root, name); diff --git a/src/json_utils.h b/src/json_utils.h index a9a05d4c8..4543f24c0 100644 --- a/src/json_utils.h +++ b/src/json_utils.h @@ -5,6 +5,7 @@ struct json_value_s* JSONGetField(struct json_value_s* root, const char* name); int8_t JSONGetBooleanValue(struct json_value_s* root, const char* name); +int32_t JSONGetIntegerValue(struct json_value_s* root, const char* name); const char* JSONGetStringValue(struct json_value_s* root, const char* name); #endif diff --git a/src/util.h b/src/util.h index 0d9f3d006..c0e29c79a 100644 --- a/src/util.h +++ b/src/util.h @@ -13,6 +13,30 @@ #define CHK_ALL(a, b) (((a) & (b)) == (b)) #define CHK_ANY(a, b) (((a) & (b)) != 0) +#define CLAMPL(a, b) \ + do { \ + if ((a) < (b)) \ + (a) = (b); \ + } while (0) +#define CLAMPG(a, b) \ + do { \ + if ((a) > (b)) \ + (a) = (b); \ + } while (0) +#define CLAMP(a, b, c) \ + do { \ + if ((a) < (b)) \ + (a) = (b); \ + else if ((a) > (c)) \ + (a) = (c); \ + } while (0) +#define SWAP(a, b, c) \ + do { \ + (c) = (a); \ + (a) = (b); \ + (b) = (c); \ + } while (0) + #pragma pack(push, 1) typedef struct { uint8_t opcode; // must be 0xE9