Merge branch 'port' of https://github.com/fgsfdsfgs/perfect_dark into port-debugger

This commit is contained in:
fgsfds committed 2024-02-12 16:38:09 +01:00
commit 11fd86002b
45 files changed
+805 -110

No files matched your search

+12
View File
@@ -116,14 +116,23 @@ else
endif
VERSION_HASH := $(shell git rev-parse --short HEAD)
VERSION_BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
VERSION_TARGET := $(TARGET_PLATFORM)
VERSION_ROMID := $(ROMID)
ifeq ($(VERSION_BRANCH),)
VERSION_BRANCH := port-custom
endif
ifeq ($(VERSION_BRANCH),HEAD)
VERSION_BRANCH := port-custom
endif
DEFINES := \
VERSION=$(VERSION) \
VERSION_HASH=\"$(VERSION_HASH)\" \
VERSION_TARGET=\"$(VERSION_TARGET)\" \
VERSION_ROMID=\"$(VERSION_ROMID)\" \
VERSION_BRANCH=\"$(VERSION_BRANCH)\" \
MATCHING=0 \
PAL=$(IS_PAL) \
PIRACYCHECKS=0 \
@@ -297,6 +306,9 @@ $(G_DIR)/tiles/%.h: $(A_DIR)/tiles/%.json
$(BIN): $(O_FILES)
$(LD) $(COMMON_CFLAGS) $(OPT_LVL) -o $(BIN) $^ $(LDFLAGS)
ifneq ($(CV2PDB),)
$(CV2PDB) $(BIN)
endif
$(B_DIR)/%.o: %.c
@mkdir -p $(dir $@)
+5 -3
View File
@@ -30,9 +30,9 @@ There are minor graphics- and gameplay-related issues, and possibly occasional c
* fixes for a couple original bugs and crashes;
* basic mod support, currently enough to load a few custom levels;
* slightly expanded memory heap size;
* experimental uncapped framerate support:
* experimental high framerate support (up to 240 FPS):
* set `Game.TickRateDivisor` to `0` in `pd.ini` to activate;
* in practice the game will have issues running faster than ~150 FPS, so use VSync or `Video.FramerateLimit` to cap it.
* in practice the game will have issues running faster than ~165 FPS, so use VSync or `Video.FramerateLimit` to cap it.
Currently only 32-bit platforms are supported, namely x86 Windows and Linux.
Note that 32-bit binaries will still work on 64-bit versions of those platforms,
@@ -44,6 +44,8 @@ Latest [automatic builds](https://github.com/fgsfdsfgs/perfect_dark/actions) for
* [i686-windows](https://nightly.link/fgsfdsfgs/perfect_dark/workflows/c-cpp/port/pd-i686-windows.zip)
* [i686-linux](https://nightly.link/fgsfdsfgs/perfect_dark/workflows/c-cpp/port/pd-i686-linux.zip)
If you are looking for netplay builds (the `port-net` branch), see [this link](https://github.com/fgsfdsfgs/perfect_dark/blob/port-net/README.md#download).
## Running
You must already have a Perfect Dark ROM to run the game, as specified above.
@@ -97,7 +99,7 @@ Controls can be rebound in `pd.ini`. Default control scheme is as follows:
### Linux
1. Ensure you have gcc, g++ and 32-bit versions of SDL2, libGL and ZLib installed on your system.
1. Ensure you have gcc, g++ (version 10.0+) and 32-bit versions of SDL2 (version 2.0.12+), libGL and ZLib installed on your system.
* On a 64-bit system you also need to have `gcc-multilib` and `g++-multilib` (or your distro's analogues) installed.
2. Run the following command in the `perfect_dark` directory:
* On a 64-bit system: ```make -f Makefile.port TARGET_PLATFORM=i686-linux```
+1 -1
View File
@@ -31,7 +31,7 @@ extern float gfx_current_native_aspect; // The aspect ratio of the above mode
extern bool gfx_framebuffers_enabled;
void gfx_init(struct GfxWindowManagerAPI* wapi, struct GfxRenderingAPI* rapi, const char* game_name,
bool start_in_fullscreen, uint32_t width, uint32_t height,
bool start_in_fullscreen, bool start_maximized, uint32_t width, uint32_t height,
uint32_t posX, uint32_t posY);
void gfx_destroy(void);
struct GfxRenderingAPI* gfx_get_current_rendering_api(void);
+11 -17
View File
@@ -396,25 +396,17 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
if (cc_features.opt_blur) {
// blur filter, used for menu backgrounds
// used to be two for loops from 0 to 4, but apparently intel drivers crashed trying to unroll it
// used to have a const weight array, but apparently drivers for the GT620 don't like const array initializers
append_line(fs_buf, &fs_len, R"(
const vec4 blurOffsets = vec4(-1.5, -0.5, +0.5, +1.5);
const mat4 blurWeights = mat4(
0.009947, 0.009641, 0.008778, 0.007509,
0.009641, 0.009345, 0.008508, 0.007278,
0.008778, 0.008508, 0.007747, 0.006626,
0.007509, 0.007278, 0.006626, 0.005668
);
lowp vec4 hookTexture2D(in sampler2D tex, in vec2 texCoord, in vec2 texSize) {
lowp vec4 color = vec4(0.0);
lowp float wacc = 0.0;
for (int y = 0; y < 4; ++y) {
for (int x = 0; x < 4; ++x) {
vec2 ofs = vec2(blurOffsets[x], blurOffsets[y]) / texSize;
wacc += blurWeights[x][y];
color += texture2D(tex, texCoord + ofs) * blurWeights[x][y];
}
lowp vec4 hookTexture2D(in sampler2D t, in vec2 uv, in vec2 tsize) {
lowp vec4 cw = vec4(0.0);
for (int i = 0; i < 16; ++i) {
vec2 xy = vec2(float(i & 3), float(i >> 2));
lowp float w = 0.009947 - length(xy) * 0.001;
cw += vec4(texture2D(t, uv + (vec2(-1.5) + xy) / tsize).rgb * w, w);
}
return vec4(color.rgb / wacc, 1.0);
return vec4(cw.rgb / cw.a, 1.0);
})"
);
} else if (current_filter_mode == FILTER_THREE_POINT) {
@@ -589,6 +581,7 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &max_length);
char error_log[1024];
glGetShaderInfoLog(vertex_shader, max_length, &max_length, &error_log[0]);
sysLogPrintf(LOG_ERROR, "Failed to compile this vertex shader (ID %llx, %x):\n%s", shader_id0, shader_id1, vs_buf);
sysFatalError("Vertex shader compilation failed:\n%s", error_log);
}
@@ -601,6 +594,7 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &max_length);
char error_log[1024];
glGetShaderInfoLog(fragment_shader, max_length, &max_length, &error_log[0]);
sysLogPrintf(LOG_ERROR, "Failed to compile this fragment shader (ID %llx, %x):\n%s", shader_id0, shader_id1, fs_buf);
sysFatalError("Fragment shader compilation failed:\n%s", error_log);
}
+2 -2
View File
@@ -2699,10 +2699,10 @@ extern "C" void gfx_get_dimensions(uint32_t* width, uint32_t* height, int32_t* p
}
extern "C" void gfx_init(struct GfxWindowManagerAPI* wapi, struct GfxRenderingAPI* rapi, const char* game_name,
bool start_in_fullscreen, uint32_t width, uint32_t height, uint32_t posX, uint32_t posY) {
bool start_in_fullscreen, bool start_maximized, uint32_t width, uint32_t height, uint32_t posX, uint32_t posY) {
gfx_wapi = wapi;
gfx_rapi = rapi;
gfx_wapi->init(game_name, rapi->get_name(), start_in_fullscreen, width, height, posX, posY);
gfx_wapi->init(game_name, rapi->get_name(), start_in_fullscreen, start_maximized, width, height, posX, posY);
gfx_rapi->init();
gfx_rapi->update_framebuffer_parameters(0, width, height, 1, false, true, true, true);
gfx_current_dimensions.internal_mul = 1;
+29 -5
View File
@@ -36,6 +36,7 @@ static bool vsync_enabled = true;
static int window_width = DESIRED_SCREEN_WIDTH;
static int window_height = DESIRED_SCREEN_HEIGHT;
static bool fullscreen_state;
static bool maximized_state;
static bool is_running = true;
static void (*on_fullscreen_changed_callback)(bool is_now_fullscreen);
@@ -76,6 +77,18 @@ static void set_fullscreen(bool on, bool call_callback) {
}
}
static void set_maximize_window(bool on) {
if (maximized_state == on) {
return;
}
maximized_state = on;
if (on) {
SDL_MaximizeWindow(wnd);
} else {
SDL_RestoreWindow (wnd);
}
}
static void gfx_sdl_get_active_window_refresh_rate(uint32_t* refresh_rate) {
int display_in_use = SDL_GetWindowDisplayIndex(wnd);
@@ -84,7 +97,7 @@ static void gfx_sdl_get_active_window_refresh_rate(uint32_t* refresh_rate) {
*refresh_rate = mode.refresh_rate;
}
static void gfx_sdl_init(const char* game_name, const char* gfx_api_name, bool start_in_fullscreen, uint32_t width,
static void gfx_sdl_init(const char* game_name, const char* gfx_api_name, bool start_in_fullscreen, bool start_maximized, uint32_t width,
uint32_t height, int32_t posX, int32_t posY) {
window_width = width;
window_height = height;
@@ -111,6 +124,7 @@ static void gfx_sdl_init(const char* game_name, const char* gfx_api_name, bool s
}
const Uint32 flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_OPENGL;
wnd = SDL_CreateWindow(title, posX, posY, window_width, window_height, flags);
if (!wnd) {
sysFatalError("Could not open SDL window:\n%s", SDL_GetError());
@@ -181,6 +195,7 @@ static void gfx_sdl_init(const char* game_name, const char* gfx_api_name, bool s
}
#endif
set_maximize_window(start_maximized);
set_fullscreen(start_in_fullscreen, false);
}
@@ -196,6 +211,10 @@ static void gfx_sdl_set_fullscreen(bool enable) {
set_fullscreen(enable, true);
}
static void gfx_sdl_set_maximize_window(bool enable) {
set_maximize_window(enable);
}
static void gfx_sdl_set_cursor_visibility(bool visible) {
if (visible) {
SDL_ShowCursor(SDL_ENABLE);
@@ -291,7 +310,7 @@ static void gfx_sdl_set_target_fps(int fps) {
}
static bool gfx_sdl_can_disable_vsync(void) {
return false;
return true;
}
static void *gfx_sdl_get_window_handle(void) {
@@ -302,9 +321,13 @@ static void gfx_sdl_set_window_title(const char *title) {
SDL_SetWindowTitle(wnd, title);
}
static void gfx_sdl_set_swap_interval(int interval) {
SDL_GL_SetSwapInterval(interval);
vsync_enabled = (interval != 0);
static bool gfx_sdl_set_swap_interval(int interval) {
const bool success = SDL_GL_SetSwapInterval(interval) >= 0;
vsync_enabled = success && (interval != 0);
if (!success) {
sysLogPrintf(LOG_WARNING, "SDL: failed to set vsync %d: %s", interval, SDL_GetError());
}
return success;
}
struct GfxWindowManagerAPI gfx_sdl = {
@@ -312,6 +335,7 @@ struct GfxWindowManagerAPI gfx_sdl = {
gfx_sdl_close,
gfx_sdl_set_fullscreen_changed_callback,
gfx_sdl_set_fullscreen,
gfx_sdl_set_maximize_window,
gfx_sdl_get_active_window_refresh_rate,
gfx_sdl_set_cursor_visibility,
gfx_sdl_get_dimensions,
+3 -2
View File
@@ -5,11 +5,12 @@
#include <stdbool.h>
struct GfxWindowManagerAPI {
void (*init)(const char* game_name, const char* gfx_api_name, bool start_in_fullscreen, uint32_t width,
void (*init)(const char* game_name, const char* gfx_api_name, bool start_in_fullscreen, bool start_maximized, uint32_t width,
uint32_t height, int32_t posX, int32_t posY);
void (*close)(void);
void (*set_fullscreen_changed_callback)(void (*on_fullscreen_changed)(bool is_now_fullscreen));
void (*set_fullscreen)(bool enable);
void (*set_maximize)(bool enable);
void (*get_active_window_refresh_rate)(uint32_t* refresh_rate);
void (*set_cursor_visibility)(bool visible);
void (*get_dimensions)(uint32_t* width, uint32_t* height, int32_t* posX, int32_t* posY);
@@ -22,7 +23,7 @@ struct GfxWindowManagerAPI {
bool (*can_disable_vsync)(void);
void *(*get_window_handle)(void);
void (*set_window_title)(const char *);
void (*set_swap_interval)(int);
bool (*set_swap_interval)(int);
};
#endif
+1
View File
@@ -24,6 +24,7 @@ u64 sysGetMicroseconds(void);
void sysFatalError(const char *fmt, ...) __attribute__((noreturn));
s32 sysLogIsOpen(void);
void sysLogPrintf(s32 level, const char *fmt, ...);
void sysGetExecutablePath(char *outPath, const u32 outLen);
+9
View File
@@ -4,6 +4,13 @@
#include <PR/ultratypes.h>
#include <PR/gbi.h>
// maximum framerate; if the game runs faster than this, things will break
#if PAL
#define VIDEO_MAX_FPS 200
#else
#define VIDEO_MAX_FPS 240
#endif
s32 videoInit(void);
void videoStartFrame(void);
void videoSubmitCommands(Gfx *cmds);
@@ -20,6 +27,8 @@ s32 videoGetWidth(void);
s32 videoGetHeight(void);
f32 videoGetAspect(void);
s32 videoGetFullscreen(void);
s32 videoGetMaximizeWindow(void);
void videoSetMaximizeWindow(s32 fs);
u32 videoGetTextureFilter(void);
u32 videoGetTextureFilter2D(void);
+35 -4
View File
@@ -16,6 +16,7 @@ typedef enum {
CFG_NONE,
CFG_S32,
CFG_F32,
CFG_U32,
CFG_STR
} configtype;
@@ -27,6 +28,7 @@ struct configentry {
union {
struct { f32 min_f32, max_f32; };
struct { s32 min_s32, max_s32; };
struct { u32 min_u32, max_u32; };
u32 max_str;
};
} settings[CONFIG_MAX_SETTINGS];
@@ -38,11 +40,15 @@ static inline s32 configClampInt(s32 val, s32 min, s32 max)
return (val < min) ? min : ((val > max) ? max : val);
}
static inline f32 configClampFloat(f32 val, f32 min, f32 max)
static inline u32 configClampUInt(u32 val, u32 min, u32 max)
{
return (val < min) ? min : ((val > max) ? max : val);
}
static inline f32 configClampFloat(f32 val, f32 min, f32 max)
{
return (val < min) ? min : ((val > max) ? max : val);
}
static inline struct configentry *configFindEntry(const char *key)
{
@@ -101,6 +107,17 @@ void configRegisterInt(const char *key, s32 *var, s32 min, s32 max)
}
}
void configRegisterUInt(const char* key, u32* var, u32 min, u32 max)
{
struct configentry* cfg = configFindOrAddEntry(key);
if (cfg) {
cfg->type = CFG_U32;
cfg->ptr = var;
cfg->min_u32 = min;
cfg->max_u32 = max;
}
}
void configRegisterFloat(const char *key, f32 *var, f32 min, f32 max)
{
struct configentry *cfg = configFindOrAddEntry(key);
@@ -129,21 +146,29 @@ static void configSetFromString(const char *key, const char *val)
s32 tmp_s32;
f32 tmp_f32;
u32 tmp_u32;
switch (cfg->type) {
case CFG_S32:
tmp_s32 = atoi(val);
tmp_s32 = strtol(val, NULL, 0);
if (cfg->min_s32 < cfg->max_s32) {
tmp_f32 = configClampInt(tmp_s32, cfg->min_s32, cfg->max_s32);
tmp_s32 = configClampInt(tmp_s32, cfg->min_s32, cfg->max_s32);
}
*(s32 *)cfg->ptr = tmp_s32;
break;
case CFG_F32:
tmp_f32 = atof(val);
tmp_f32 = strtof(val, NULL);
if (cfg->min_f32 < cfg->max_f32) {
tmp_f32 = configClampFloat(tmp_f32, cfg->min_f32, cfg->max_f32);
}
*(f32 *)cfg->ptr = tmp_f32;
break;
case CFG_U32:
tmp_u32 = strtoul(val, NULL, 0);
if (cfg->min_u32 < cfg->max_u32) {
tmp_u32 = configClampUInt(tmp_u32, cfg->min_u32, cfg->max_u32);
}
*(u32*)cfg->ptr = tmp_u32;
break;
case CFG_STR:
strncpy(cfg->ptr, val, cfg->max_str ? cfg->max_str - 1 : 4096);
break;
@@ -167,6 +192,12 @@ static void configSaveEntry(struct configentry *cfg, FILE *f)
}
fprintf(f, "%s=%f\n", cfg->key + cfg->seclen + 1, *(f32 *)cfg->ptr);
break;
case CFG_U32:
if (cfg->min_u32 < cfg->max_u32) {
*(u32*)cfg->ptr = configClampUInt(*(u32*)cfg->ptr, cfg->min_u32, cfg->max_u32);
}
fprintf(f, "%s=%u\n", cfg->key + cfg->seclen + 1, *(u32 *)cfg->ptr);
break;
case CFG_STR:
fprintf(f, "%s=%s\n", cfg->key + cfg->seclen + 1, (char *)cfg->ptr);
break;
+17 -3
View File
@@ -10,7 +10,8 @@
#include "system.h"
#include "platform.h"
#define CRASH_MAX_MSG 4096
#define CRASH_LOG_FNAME "pd.crash.log"
#define CRASH_MAX_MSG 8192
#define CRASH_MAX_SYM 256
#define CRASH_MAX_FRAMES 32
#define CRASH_MSG(...) \
@@ -79,8 +80,8 @@ static void crashStackTrace(char *msg, PEXCEPTION_POINTERS exinfo)
if (SymGetLineFromAddr64(process, (uintptr_t)exinfo->ExceptionRecord->ExceptionAddress, &disp, &line)) {
CRASH_MSG(": %s:%lu+%lu", line.FileName, line.LineNumber, disp);
}
CRASH_MSG("\nMODULE: %p\n", crashGetModuleBase(exinfo->ExceptionRecord->ExceptionAddress));
CRASH_MSG("MAIN MODULE: %p\n", crashGetModuleBase(crashInit));
CRASH_MSG("\nMODULE: [%p]\n", crashGetModuleBase(exinfo->ExceptionRecord->ExceptionAddress));
CRASH_MSG("MAIN MODULE: [%p]\n", crashGetModuleBase(crashInit));
CRASH_MSG("\nBACKTRACE:\n");
char symbuf[sizeof(SYMBOL_INFO) + CRASH_MAX_SYM * sizeof(TCHAR)];
@@ -99,6 +100,10 @@ static void crashStackTrace(char *msg, PEXCEPTION_POINTERS exinfo)
if (SymFromAddr(process, stackframe.AddrPC.Offset, &disp64, sym)) {
CRASH_MSG(": %s+%llu", sym->Name, disp64);
} else if (process, stackframe.AddrPC.Offset) {
const uintptr_t modbase = (uintptr_t)crashGetModuleBase((void *)(uintptr_t)stackframe.AddrPC.Offset);
const uintptr_t modofs = (uintptr_t)stackframe.AddrPC.Offset - modbase;
CRASH_MSG(": [%p]+%p", (void *)modbase, (void *)modofs);
}
if(SymGetLineFromAddr64(process, stackframe.AddrPC.Offset, &disp, &line)) {
@@ -135,6 +140,15 @@ static long __stdcall crashHandler(PEXCEPTION_POINTERS exinfo)
crashStackTrace(msg, exinfo);
// open log file for the crash dump if one hasn't been opened yet
if (!sysLogIsOpen()) {
FILE *f = fopen(CRASH_LOG_FNAME, "wb");
if (f) {
fprintf(f, "Crash!\n\n%s", msg);
fclose(f);
}
}
sysFatalError("Crash!\n\n%s", msg);
return EXCEPTION_CONTINUE_EXECUTION;
+4
View File
@@ -851,6 +851,10 @@ void inputRumble(s32 idx, f32 strength, f32 time)
return;
}
if (padsCfg[idx].rumbleScale <= 0.f) {
return;
}
if (padsCfg[idx].rumbleOn) {
strength *= padsCfg[idx].rumbleScale;
if (strength <= 0.f) {
+11
View File
@@ -39,6 +39,8 @@ s32 g_TickRateDiv = 1;
s32 g_SkipIntro = false;
s32 g_FileAutoSelect = -1;
extern s32 g_StageNum;
s32 bootGetMemSize(void)
@@ -143,6 +145,11 @@ int main(int argc, const char **argv)
sysLogPrintf(LOG_NOTE, "boot stage set to 0x%02x", g_StageNum);
}
g_FileAutoSelect = sysArgGetInt("--profile", -1);
if (g_FileAutoSelect >= 0) {
sysLogPrintf(LOG_NOTE, "player profile set to %d", g_FileAutoSelect);
}
mainProc();
return 0;
@@ -156,6 +163,7 @@ PD_CONSTRUCTOR static void gameConfigInit(void)
configRegisterInt("Game.TickRateDivisor", &g_TickRateDiv, 0, 10);
configRegisterInt("Game.SkipIntro", &g_SkipIntro, 0, 1);
configRegisterInt("Game.DisableMpDeathMusic", &g_MusicDisableMpDeath, 0, 1);
configRegisterInt("Game.GEMuzzleFlashes", &g_BgunGeMuzzleFlashes, 0, 1);
for (s32 j = 0; j < MAX_PLAYERS; ++j) {
const s32 i = j + 1;
configRegisterFloat(strFmt("Game.Player%d.FovY", i), &g_PlayerExtCfg[j].fovy, 5.f, 175.f);
@@ -167,5 +175,8 @@ PD_CONSTRUCTOR static void gameConfigInit(void)
configRegisterFloat(strFmt("Game.Player%d.CrosshairSway", i), &g_PlayerExtCfg[j].crosshairsway, 0.f, 10.f);
configRegisterInt(strFmt("Game.Player%d.CrouchMode", i), &g_PlayerExtCfg[j].crouchmode, 0, CROUCHMODE_TOGGLE_ANALOG);
configRegisterInt(strFmt("Game.Player%d.ExtendedControls", i), &g_PlayerExtCfg[j].extcontrols, 0, 1);
configRegisterUInt(strFmt("Game.Player%d.CrosshairColour", i), &g_PlayerExtCfg[j].crosshaircolour, 0, 0xFFFFFFFF);
configRegisterUInt(strFmt("Game.Player%d.CrosshairSize", i), &g_PlayerExtCfg[j].crosshairsize, 0, 4);
configRegisterInt(strFmt("Game.Player%d.CrosshairHealth", i), &g_PlayerExtCfg[j].crosshairhealth, 0, CROSSHAIR_HEALTH_ON_WHITE);
}
}
+262
View File
@@ -652,6 +652,19 @@ static MenuItemHandlerResult menuhandlerFullScreen(s32 operation, struct menuite
return 0;
}
static MenuItemHandlerResult menuhandlerMaximizeWindow(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GET:
return videoGetMaximizeWindow();
case MENUOP_SET:
videoSetMaximizeWindow(data->checkbox.value);
break;
}
return 0;
}
static MenuItemHandlerResult menuhandlerTexFilter(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
@@ -678,6 +691,19 @@ static MenuItemHandlerResult menuhandlerTexFilter2D(s32 operation, struct menuit
return 0;
}
static MenuItemHandlerResult menuhandlerGeMuzzleFlashes(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GET:
return g_BgunGeMuzzleFlashes;
case MENUOP_SET:
g_BgunGeMuzzleFlashes = data->checkbox.value;
break;
}
return 0;
}
static MenuItemHandlerResult menuhandlerCenterHUD(s32 operation, struct menuitem *item, union handlerdata *data)
{
static const char *opts[] = {
@@ -735,6 +761,14 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
0,
menuhandlerFullScreen,
},
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LITERAL_TEXT,
(uintptr_t)"Maximize Window",
0,
menuhandlerMaximizeWindow,
},
{
MENUITEMTYPE_CHECKBOX,
0,
@@ -751,6 +785,14 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
0,
menuhandlerTexFilter2D,
},
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LITERAL_TEXT,
(uintptr_t)"GE64-style Muzzle Flashes",
0,
menuhandlerGeMuzzleFlashes,
},
{
MENUITEMTYPE_DROPDOWN,
0,
@@ -903,6 +945,202 @@ static MenuItemHandlerResult menuhandlerCrosshairSway(s32 operation, struct menu
return 0;
}
static MenuItemHandlerResult menuhandlerCrosshairR(s32 operation, struct menuitem* item, union handlerdata* data)
{
u32 newColor;
switch (operation) {
case MENUOP_GETSLIDER:
data->slider.value = (g_PlayerExtCfg[g_ExtMenuPlayer].crosshaircolour >> 24) & 0xFF;
break;
case MENUOP_SET:
newColor = (g_PlayerExtCfg[g_ExtMenuPlayer].crosshaircolour & 0xFFFFFF) | data->slider.value << 24;
g_PlayerExtCfg[g_ExtMenuPlayer].crosshaircolour = newColor;
break;
}
return 0;
}
static MenuItemHandlerResult menuhandlerCrosshairG(s32 operation, struct menuitem* item, union handlerdata* data)
{
u32 newColor;
switch (operation) {
case MENUOP_GETSLIDER:
data->slider.value = (g_PlayerExtCfg[g_ExtMenuPlayer].crosshaircolour >> 16) & 0xFF;
break;
case MENUOP_SET:
newColor = (g_PlayerExtCfg[g_ExtMenuPlayer].crosshaircolour & 0xFF00FFFF) | data->slider.value << 16;
g_PlayerExtCfg[g_ExtMenuPlayer].crosshaircolour = newColor;
break;
}
return 0;
}
static MenuItemHandlerResult menuhandlerCrosshairB(s32 operation, struct menuitem* item, union handlerdata* data)
{
u32 newColor;
switch (operation) {
case MENUOP_GETSLIDER:
data->slider.value = (g_PlayerExtCfg[g_ExtMenuPlayer].crosshaircolour >> 8) & 0xFF;
break;
case MENUOP_SET:
newColor = (g_PlayerExtCfg[g_ExtMenuPlayer].crosshaircolour & 0xFFFF00FF) | data->slider.value << 8;
g_PlayerExtCfg[g_ExtMenuPlayer].crosshaircolour = newColor;
break;
}
return 0;
}
static MenuItemHandlerResult menuhandlerCrosshairA(s32 operation, struct menuitem* item, union handlerdata* data)
{
u32 newColor;
switch (operation) {
case MENUOP_GETSLIDER:
data->slider.value = g_PlayerExtCfg[g_ExtMenuPlayer].crosshaircolour & 0xFF;
break;
case MENUOP_SET:
newColor = (g_PlayerExtCfg[g_ExtMenuPlayer].crosshaircolour & 0xFFFFFF00) | data->slider.value;
g_PlayerExtCfg[g_ExtMenuPlayer].crosshaircolour = newColor;
break;
}
return 0;
}
static MenuItemHandlerResult menuhandlerCrosshairColorPreview(s32 operation, struct menuitem* item, union handlerdata* data)
{
if (operation == MENUOP_GETCOLOUR) {
data->label.colour1 = g_PlayerExtCfg[g_ExtMenuPlayer].crosshaircolour;
}
return 0;
}
static MenuItemHandlerResult menuhandlerCrosshairSize(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GETSLIDER:
data->slider.value = g_PlayerExtCfg[g_ExtMenuPlayer].crosshairsize;
break;
case MENUOP_SET:
g_PlayerExtCfg[g_ExtMenuPlayer].crosshairsize = data->slider.value;
break;
}
return 0;
}
static MenuItemHandlerResult menuhandlerCrosshairHealth(s32 operation, struct menuitem *item, union handlerdata *data)
{
static const char *opts[] = {
"Off",
"On (Green)",
"On (White)"
};
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->dropdown.value = ARRAYCOUNT(opts);
break;
case MENUOP_GETOPTIONTEXT:
return (intptr_t)opts[data->dropdown.value];
case MENUOP_SET:
g_PlayerExtCfg[g_ExtMenuPlayer].crosshairhealth = data->dropdown.value;
break;
case MENUOP_GETSELECTEDINDEX:
data->dropdown.value = g_PlayerExtCfg[g_ExtMenuPlayer].crosshairhealth;
}
return 0;
}
struct menuitem g_ExtendedGameCrosshairColourMenuItems[] = {
{
MENUITEMTYPE_SLIDER,
0,
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
(uintptr_t)"Red",
255,
menuhandlerCrosshairR,
},
{
MENUITEMTYPE_SLIDER,
0,
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
(uintptr_t)"Green",
255,
menuhandlerCrosshairG,
},
{
MENUITEMTYPE_SLIDER,
0,
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
(uintptr_t)"Blue",
255,
menuhandlerCrosshairB,
},
{
MENUITEMTYPE_SLIDER,
0,
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
(uintptr_t)"Alpha",
255,
menuhandlerCrosshairA,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_COLORBOX,
0,
0,
0,
0,
menuhandlerCrosshairColorPreview,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_213, // "Back"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_ExtendedGameCrosshairColourMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
(uintptr_t)"Crosshair Colour",
g_ExtendedGameCrosshairColourMenuItems,
NULL,
MENUDIALOGFLAG_LITERAL_TEXT,
NULL,
};
struct menuitem g_ExtendedGameMenuItems[] = {
{
MENUITEMTYPE_DROPDOWN,
@@ -928,6 +1166,30 @@ struct menuitem g_ExtendedGameMenuItems[] = {
20,
menuhandlerCrosshairSway,
},
{
MENUITEMTYPE_SLIDER,
0,
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
(uintptr_t)"Crosshair Size",
4,
menuhandlerCrosshairSize,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
(uintptr_t)"Crosshair Colour\n",
0,
(void*)&g_ExtendedGameCrosshairColourMenuDialog,
},
{
MENUITEMTYPE_DROPDOWN,
0,
MENUITEMFLAG_LITERAL_TEXT,
(uintptr_t)"Crosshair Colour by Health",
0,
menuhandlerCrosshairHealth,
},
{
MENUITEMTYPE_SEPARATOR,
0,
+5
View File
@@ -105,6 +105,7 @@ bool g_SchedIsFirstTask = true;
s32 g_PrevFrameFb = -1;
s32 g_BlurFb = -1;
s32 g_BlurFbCapTimer = -1;
bool g_BlurFbDirty = true;
void schedSetCrashEnable1(bool enable)
{
@@ -396,8 +397,12 @@ void schedConsiderScreenshot(void)
if (g_BlurFbCapTimer == 0) {
videoCopyFramebuffer(g_BlurFb, 0, -1, -1);
g_BlurFbCapTimer = -1;
g_BlurFbDirty = false;
} else if (g_BlurFbCapTimer > 0) {
--g_BlurFbCapTimer;
} else if (g_BlurFbCapTimer < 0) {
// no blur requested this frame, mark blur fb dirty
g_BlurFbDirty = true;
}
if (g_MenuData.screenshottimer >= 2) {
+31 -1
View File
@@ -64,6 +64,13 @@ enum loadsource {
SRC_EXTERNAL
};
struct romfilepatch {
u32 ofs;
u32 len;
const char *src;
const char *dst;
};
struct romfile {
u8 **segstart;
u8 **segend;
@@ -73,9 +80,21 @@ struct romfile {
preprocessfunc preprocess;
s32 source; // enum loadsource
s32 preprocessed;
const struct romfilepatch *patches;
u32 numpatches;
};
static struct romfile fileSlots[ROMDATA_MAX_FILES];
/* patches for individual files; applied on file load, before preprocFuncs, but */
/* after unzip; only applied when loading from a ROM file */
static const struct romfilepatch filePatches[] = {
/* FILE_USETUPLUE: fixes Jon's double "if what" in Infiltration outro */
{ 0x92a2, 1, "\x6c", "\x99" },
{ 0x92b0, 1, "\x6c", "\x99" },
};
static struct romfile fileSlots[ROMDATA_MAX_FILES] = {
[FILE_USETUPLUE] = { .patches = &filePatches[0], .numpatches = 2 },
};
#define ROMSEG_START(n) _ ## n ## SegmentRomStart
#define ROMSEG_END(n) _ ## n ## SegmentRomEnd
@@ -409,6 +428,8 @@ u8 *romdataFileLoad(s32 fileNum, u32 *outSize)
fileSlots[fileNum].data = out;
fileSlots[fileNum].size = size;
fileSlots[fileNum].source = SRC_EXTERNAL;
// external file; do not apply patches to this
fileSlots[fileNum].numpatches = 0;
}
}
// tried and failed, fall back to ROM
@@ -435,6 +456,15 @@ void romdataFilePreprocess(s32 fileNum, s32 loadType, u8 *data, u32 size)
if (data && size /* && !fileSlots[fileNum].preprocessed*/) {
if (loadType && loadType < (u32)ARRAYCOUNT(filePreprocFuncs) && filePreprocFuncs[loadType]) {
// apply patches
for (u32 i = 0; i < fileSlots[fileNum].numpatches; ++i) {
const struct romfilepatch *p = &fileSlots[fileNum].patches[i];
if (!memcmp(data + p->ofs, p->src, p->len)) {
memcpy(data + p->ofs, p->dst, p->len);
sysLogPrintf(LOG_NOTE, "file %d (%s) patched at offset 0x%x", fileNum, fileSlots[fileNum].name, p->ofs);
}
}
// then preprocess
filePreprocFuncs[loadType](data, size);
// fileSlots[fileNum].preprocessed = 1;
}
+26 -14
View File
@@ -11,6 +11,7 @@
#include "system.h"
#define LOG_FNAME "pd.log"
#define CRASHLOG_FNAME "pd.crash.log"
#define USEC_IN_SEC 1000000ULL
static u64 startTick = 0;
@@ -19,6 +20,24 @@ static char logPath[2048];
static s32 sysArgc;
static const char **sysArgv;
static inline void sysLogSetPath(const char *fname)
{
// figure out where the log is and clear it
// try working dir first
snprintf(logPath, sizeof(logPath), "./%s", fname);
FILE *f = fopen(logPath, "wb");
if (!f) {
// try home dir
sysGetHomePath(logPath, sizeof(logPath) - 1);
strncat(logPath, "/", sizeof(logPath) - 1);
strncat(logPath, fname, sizeof(logPath) - 1);
f = fopen(logPath, "wb");
}
if (f) {
fclose(f);
}
}
void sysInitArgs(s32 argc, const char **argv)
{
sysArgc = argc;
@@ -30,23 +49,11 @@ void sysInit(void)
startTick = sysGetMicroseconds();
if (sysArgCheck("--log")) {
// figure out where the log is and clear it
// try working dir first
snprintf(logPath, sizeof(logPath), "./%s", LOG_FNAME);
FILE *f = fopen(logPath, "wb");
if (!f) {
// try home dir
sysGetHomePath(logPath, sizeof(logPath) - 1);
strncat(logPath, "/" LOG_FNAME, sizeof(logPath) - 1);
f = fopen(logPath, "wb");
}
if (f) {
fclose(f);
}
sysLogSetPath(LOG_FNAME);
}
#ifdef VERSION_HASH
sysLogPrintf(LOG_NOTE, "version: " VERSION_HASH " (" VERSION_TARGET ")");
sysLogPrintf(LOG_NOTE, "version: " VERSION_BRANCH " " VERSION_HASH " (" VERSION_TARGET ")");
#endif
char timestr[256];
@@ -96,6 +103,11 @@ u64 sysGetMicroseconds(void)
return ((u64)tv.tv_sec * USEC_IN_SEC + (u64)tv.tv_usec) - startTick;
}
s32 sysLogIsOpen(void)
{
return (logPath[0] != '\0');
}
void sysLogPrintf(s32 level, const char *fmt, ...)
{
static const char *prefix[3] = {
+26 -3
View File
@@ -21,6 +21,7 @@ static s32 vidWidth = 640;
static s32 vidHeight = 480;
static s32 vidFramebuffers = true;
static s32 vidFullscreen = false;
static s32 vidMaximize = false;
static s32 vidVsync = 1;
static s32 vidMSAA = 1;
static s32 vidFramerateLimit = 0;
@@ -44,9 +45,17 @@ s32 videoInit(void)
gfx_framebuffers_enabled = (bool)vidFramebuffers;
gfx_msaa_level = vidMSAA;
gfx_init(wmAPI, renderingAPI, "PD", vidFullscreen, vidWidth, vidHeight, 100, 100);
gfx_init(wmAPI, renderingAPI, "PD", vidFullscreen, vidMaximize, vidWidth, vidHeight, 100, 100);
if (!wmAPI->set_swap_interval(vidVsync)) {
vidVsync = 0;
}
if (vidVsync == 0 && vidFramerateLimit == 0) {
// cap FPS if there's no vsync to prevent the game from exploding
vidFramerateLimit = VIDEO_MAX_FPS;
}
wmAPI->set_swap_interval(vidVsync);
wmAPI->set_target_fps(vidFramerateLimit); // disabled because vsync is on
renderingAPI->set_texture_filter((enum FilteringMode)texFilter);
@@ -139,6 +148,11 @@ s32 videoGetFullscreen(void)
return vidFullscreen;
}
s32 videoGetMaximizeWindow(void)
{
return vidMaximize;
}
f32 videoGetAspect(void)
{
return gfx_current_dimensions.aspect_ratio;
@@ -168,6 +182,14 @@ void videoSetFullscreen(s32 fs)
}
}
void videoSetMaximizeWindow(s32 fs)
{
if (fs != vidMaximize) {
vidMaximize = !!fs;
wmAPI->set_maximize(vidMaximize);
}
}
void videoSetTextureFilter(u32 filter)
{
if (filter > FILTER_THREE_POINT) filter = FILTER_THREE_POINT;
@@ -224,11 +246,12 @@ void videoFreeCachedTexture(const void *texptr)
PD_CONSTRUCTOR static void videoConfigInit(void)
{
configRegisterInt("Video.DefaultFullscreen", &vidFullscreen, 0, 1);
configRegisterInt("Video.DefaultMaximize", &vidMaximize, 0, 1);
configRegisterInt("Video.DefaultWidth", &vidWidth, 0, 32767);
configRegisterInt("Video.DefaultHeight", &vidHeight, 0, 32767);
configRegisterInt("Video.VSync", &vidVsync, -1, 10);
configRegisterInt("Video.FramebufferEffects", &vidFramebuffers, 0, 1);
configRegisterInt("Video.FramerateLimit", &vidFramerateLimit, 0, 10000);
configRegisterInt("Video.FramerateLimit", &vidFramerateLimit, 0, VIDEO_MAX_FPS);
configRegisterInt("Video.MSAA", &vidMSAA, 1, 16);
configRegisterInt("Video.TextureFilter", &texFilter, 0, 2);
configRegisterInt("Video.TextureFilter2D", &texFilter2D, 0, 1);
+9 -21
View File
@@ -90,19 +90,8 @@ MenuItemHandlerResult amPickTargetMenuList(s32 operation, struct menuitem *item,
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
if (g_AmMenus[g_AmIndex].prevallbots) {
// All bots: num bot opponents + all human players
s32 count = 0;
s32 i;
struct chrdata *playerchr = g_Vars.currentplayer->prop->chr;
for (i = PLAYERCOUNT(); i < g_MpNumChrs; i++) {
if (g_MpAllChrPtrs[i]->team != playerchr->team) {
count++;
}
}
count += PLAYERCOUNT();
data->list.value = count;
// All bots
data->list.value = g_MpNumChrs;
} else {
// Single bot: All except the bot itself
data->list.value = g_MpNumChrs - 1;
@@ -125,9 +114,7 @@ MenuItemHandlerResult amPickTargetMenuList(s32 operation, struct menuitem *item,
chrindex++;
if (g_AmMenus[g_AmIndex].prevallbots) {
if (playerchr == g_MpAllChrPtrs[chrindex] || playerchr->team != g_MpAllChrPtrs[chrindex]->team) {
numremaining--;
}
numremaining--;
} else {
if (botchr != g_MpAllChrPtrs[chrindex]) {
numremaining--;
@@ -139,7 +126,9 @@ MenuItemHandlerResult amPickTargetMenuList(s32 operation, struct menuitem *item,
g_AmMenus[g_AmIndex].prevallbots = false;
for (i = 0; i < g_Vars.currentplayer->numaibuddies; i++) {
botApplyAttack(g_MpAllChrPtrs[g_Vars.currentplayer->aibuddynums[i]], g_MpAllChrPtrs[chrindex]->prop);
if (g_Vars.currentplayer->aibuddynums[i] != chrindex) {
botApplyAttack(g_MpAllChrPtrs[g_Vars.currentplayer->aibuddynums[i]], g_MpAllChrPtrs[chrindex]->prop);
}
}
} else {
botApplyAttack(botchr, g_MpAllChrPtrs[chrindex]->prop);
@@ -167,9 +156,7 @@ MenuItemHandlerResult amPickTargetMenuList(s32 operation, struct menuitem *item,
chrindex++;
if (g_AmMenus[g_AmIndex].prevallbots) {
if (playerchr == g_MpAllChrPtrs[chrindex] || playerchr->team != g_MpAllChrPtrs[chrindex]->team) {
numremaining--;
}
numremaining--;
} else {
if (botchr != g_MpAllChrPtrs[chrindex]) {
numremaining--;
@@ -1275,7 +1262,8 @@ Gfx *amRender(Gfx *gdl)
#endif
#ifndef PLATFORM_N64
if (PLAYERCOUNT() == 1) {
const s32 playercount = PLAYERCOUNT();
if (playercount < 2 || (playercount == 2 && optionsGetScreenSplit() == SCREENSPLIT_HORIZONTAL)) {
gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT);
}
#endif
+6
View File
@@ -1098,7 +1098,13 @@ void eyespyProcessInput(bool allowbuttons)
if (g_Vars.currentplayer->eyespy->bobactive || ABS(g_Vars.currentplayer->eyespy->vel.y) < 0.1f) {
g_Vars.currentplayer->eyespy->bobactive = true;
g_Vars.currentplayer->eyespy->bobtimer += g_Vars.lvupdate60;
#ifdef PLATFORM_N64
g_Vars.currentplayer->eyespy->vel.y += 0.025f * g_Vars.currentplayer->eyespy->bobdir;
#else
// HACK: how do I scale this properly?
const f32 scale = (g_Vars.lvupdate60freal <= 1.1f) ? 0.0055f : 0.0125f;
g_Vars.currentplayer->eyespy->vel.y += scale * g_Vars.lvupdate60freal * g_Vars.currentplayer->eyespy->bobdir;
#endif
if (g_Vars.currentplayer->eyespy->bobtimer > TICKS(120)) {
g_Vars.currentplayer->eyespy->bobtimer = 0;
+17 -3
View File
@@ -190,6 +190,10 @@ char var800700bc[][10] = {
{ 'x','x','x' }, // "xxx"
};
#ifndef PLATFORM_N64
s32 g_BgunGeMuzzleFlashes = false;
#endif
#if !MATCHING || VERSION >= VERSION_NTSC_1_0
void bgunRumble(s32 handnum, s32 weaponnum)
{
@@ -1911,7 +1915,17 @@ void bgun0f09a6f8(struct handweaponinfo *info, s32 handnum, struct hand *hand, s
if (func->flags & FUNCFLAG_NOMUZZLEFLASH) {
hand->flashon = false;
} else {
#ifdef PLATFORM_N64
hand->flashon = true;
#else
if (g_BgunGeMuzzleFlashes) {
if (func->type == INVENTORYFUNCTYPE_SHOOT_SINGLE || (hand->shotstotake & 1)) {
hand->flashon = true;
}
} else {
hand->flashon = true;
}
#endif
}
bgunStartSlide(handnum);
@@ -12783,7 +12797,7 @@ Gfx *bgunDrawHud(Gfx *gdl)
gdl = text0f153628(gdl);
#ifndef PLATFORM_N64
if (playercount < 2) {
if (playercount < 2 || (playercount == 2 && optionsGetScreenSplit() == SCREENSPLIT_HORIZONTAL)) {
gSPExtraGeometryModeEXT(gdl++, G_ASPECT_MODE_EXT, g_HudAlignModeR);
}
#endif
@@ -13037,7 +13051,7 @@ Gfx *bgunDrawHud(Gfx *gdl)
}
#ifndef PLATFORM_N64
if (playercount < 2) {
if (playercount < 2 || (playercount == 2 && optionsGetScreenSplit() == SCREENSPLIT_HORIZONTAL)) {
gSPExtraGeometryModeEXT(gdl++, G_ASPECT_MODE_EXT, g_HudAlignModeL);
}
#endif
@@ -13077,7 +13091,7 @@ Gfx *bgunDrawHud(Gfx *gdl)
}
#ifndef PLATFORM_N64
if (playercount < 2) {
if (playercount < 2 || (playercount == 2 && optionsGetScreenSplit() == SCREENSPLIT_HORIZONTAL)) {
gSPExtraGeometryModeEXT(gdl++, G_ASPECT_MODE_EXT, g_HudAlignModeR);
}
#endif
+16 -2
View File
@@ -289,6 +289,14 @@ Gfx *bviewDrawMotionBlur(Gfx *gdl, u32 colour, u32 alpha)
if (!videoFramebuffersSupported()) {
return gdl;
}
// capture fb at the end of this frame
g_BlurFbCapTimer = 0;
// don't render first blur frame as we haven't captured the fb yet
if (g_BlurFbDirty) {
return gdl;
}
#endif
mainOverrideVariable("sfxxx", &sfxxx);
@@ -312,7 +320,6 @@ Gfx *bviewDrawMotionBlur(Gfx *gdl, u32 colour, u32 alpha)
viewleft << 2, viewtop << 2, viewleft, viewtop,
(viewleft + viewwidth) << 2, (viewtop + viewheight) << 2, viewleft + viewwidth, viewtop + viewheight,
0, videoGetNativeWidth(), videoGetNativeHeight());
g_BlurFbCapTimer = 0;
#endif
return gdl;
@@ -521,6 +528,14 @@ Gfx *bviewDrawZoomBlur(Gfx *gdl, u32 colour, s32 alpha, f32 arg3, f32 arg4)
if (!videoFramebuffersSupported()) {
return gdl;
}
// capture fb at the end of this frame
g_BlurFbCapTimer = 0;
// don't render first blur frame as we haven't captured the fb yet
if (g_BlurFbDirty) {
return gdl;
}
#endif
strcpy(var800a41c0, "stretchBlurGfx");
@@ -550,7 +565,6 @@ Gfx *bviewDrawZoomBlur(Gfx *gdl, u32 colour, s32 alpha, f32 arg3, f32 arg4)
left << 2, top << 2, viewleft, viewtop,
right << 2, bottom << 2, viewleft + viewwidth, viewtop + viewheight,
0, videoGetNativeWidth(), videoGetNativeHeight());
g_BlurFbCapTimer = 0;
#endif
return gdl;
+11
View File
@@ -260,6 +260,17 @@ void botSpawn(struct chrdata *chr, u8 respawning)
chr->aibot->moveratex = 0;
chr->aibot->moveratey = 0;
func0f02e9a0(chr, 0);
#ifndef PLATFORM_N64
if ((g_MpSetup.options & MPOPTION_SPAWNWITHWEAPON)
&& g_MpSetup.weapons[0] != MPWEAPON_NONE
&& g_MpSetup.weapons[0] != MPWEAPON_DISABLED) {
struct mpweapon *mpweapon = &g_MpWeapons[g_MpSetup.weapons[0]];
botinvGiveSingleWeapon(chr, mpweapon->weaponnum);
botactGiveAmmoByType(aibot, mpweapon->priammotype - 1, mpweapon->priammoqty / 2);
botinvSwitchToWeapon(chr, mpweapon->weaponnum, FUNC_PRIMARY);
}
#endif
}
}
+10
View File
@@ -2592,6 +2592,16 @@ MenuItemHandlerResult filemgrChooseAgentListMenuHandler(s32 operation, struct me
}
}
}
#ifndef PLATFORM_N64
if (g_FileAutoSelect >= 0 && g_FileLists[0] && g_FileLists[0]->numfiles > 0) {
const u32 tmp = data->list.value;
data->list.value = g_FileAutoSelect;
g_FileAutoSelect = -1;
filemgrChooseAgentListMenuHandler(MENUOP_SET, item, data);
data->list.value = tmp;
}
#endif
break;
case MENUOP_GETOPTIONCOUNT:
data->list.value = g_FileLists[0]->numfiles + 1;
+2
View File
@@ -398,9 +398,11 @@ u16 weaponGetFileNum(s32 weaponnum)
}
if (weapon) {
#ifdef PLATFORM_N64
if (PLAYERCOUNT() >= 2) {
return weapon->lo_model;
}
#endif
return weapon->hi_model;
}
+4 -3
View File
@@ -190,7 +190,7 @@ Gfx *hudmsgRenderMissionTimer(Gfx *gdl, u32 alpha)
y = timery;
#ifndef PLATFORM_N64
if (PLAYERCOUNT() < 2) {
if (playercount < 2 || (playercount == 2 && optionsGetScreenSplit() == SCREENSPLIT_HORIZONTAL)) {
gSPExtraGeometryModeEXT(gdl++, G_ASPECT_MODE_EXT, g_HudAlignModeL);
}
#endif
@@ -282,7 +282,7 @@ Gfx *hudmsgRenderZoomRange(Gfx *gdl, u32 alpha)
y2 = y + textheight;
#ifndef PLATFORM_N64
if (playercount == 1) {
if (playercount < 2 || (playercount == 2 && optionsGetScreenSplit() == SCREENSPLIT_HORIZONTAL)) {
gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT);
}
#endif
@@ -1450,7 +1450,8 @@ Gfx *hudmsgsRender(Gfx *gdl)
}
#ifndef PLATFORM_N64
if (playercount < 2 && msg->state >= HUDMSGSTATE_FADINGIN) {
const bool doaspectfix = (playercount < 2) || (playercount == 2 && optionsGetScreenSplit() == SCREENSPLIT_HORIZONTAL);
if (doaspectfix && msg->state >= HUDMSGSTATE_FADINGIN) {
if (msg->alignh == HUDMSGALIGN_SCREENLEFT || msg->alignh == HUDMSGALIGN_LEFT) {
gSPExtraGeometryModeEXT(gdl++, G_ASPECT_MODE_EXT, g_HudAlignModeL);
} else if (msg->alignh == HUDMSGALIGN_RIGHT) {
+3
View File
@@ -1178,6 +1178,9 @@ bool menuIsItemFocusable(struct menuitem *item, struct menudialog *dialog, s32 a
case MENUITEMTYPE_METER:
case MENUITEMTYPE_MARQUEE:
case MENUITEMTYPE_CONTROLLER:
#ifndef PLATFORM_N64
case MENUITEMTYPE_COLORBOX:
#endif
return false;
case MENUITEMTYPE_10:
case MENUITEMTYPE_14:
+35
View File
@@ -2109,6 +2109,36 @@ Gfx *menuitemMeterRender(Gfx *gdl, struct menurendercontext *context)
return gdl;
}
#ifndef PLATFORM_N64
// Draws a colored box which fills the background of the menu item.
Gfx* menuitemColorBoxRender(Gfx *gdl, struct menurendercontext *context)
{
u32 width = context->width;
u32 height = context->height;
u32 colour1;
s32 x1;
s32 x2;
x1 = context->x;
x2 = x1 + width;
union handlerdata data;
if (context->item->handlervoid) {
context->item->handlervoid(MENUOP_GETCOLOUR, context->item, &data);
}
colour1 = data.label.colour1;
gdl = textSetPrimColour(gdl, colour1);
gDPFillRectangleScaled(gdl++, x1, context->y, x2, context->y + height);
gdl = text0f153838(gdl);
return gdl;
}
#endif
Gfx *menuitemSelectableRender(Gfx *gdl, struct menurendercontext *context)
{
u32 leftcolour;
@@ -4349,6 +4379,11 @@ Gfx *menuitemRender(Gfx *gdl, struct menurendercontext *context)
case MENUITEMTYPE_CAROUSEL: return menuitemCarouselRender(gdl, context);
case MENUITEMTYPE_MODEL: return menuitemModelRender(gdl, context);
case MENUITEMTYPE_CONTROLLER: return menuitemControllerRender(gdl, context);
#ifndef PLATFORM_N64
case MENUITEMTYPE_COLORBOX: return menuitemColorBoxRender(gdl, context);
#endif
}
return gdl;
+8
View File
@@ -122,6 +122,9 @@ struct mpweapon g_MpWeapons[NUM_MPWEAPONS] = {
.crosshairsway = 1.f, \
.crouchmode = CROUCHMODE_TOGGLE_ANALOG, \
.extcontrols = true, \
.crosshaircolour = 0x00ff0028, \
.crosshairsize = 2, \
.crosshairhealth = CROSSHAIR_HEALTH_OFF, \
}
struct extplayerconfig g_PlayerExtCfg[MAX_PLAYERS] = {
@@ -2717,6 +2720,11 @@ struct mptrack g_MpTracks[] = {
/*0x27*/ { MUSIC_SKEDARRUINS, 120, L_MISC_163, SOLOSTAGEINDEX_SKEDARRUINS }, // "Skedar Ruins"
/*0x28*/ { MUSIC_SKEDARRUINS_X, 120, L_MISC_164, SOLOSTAGEINDEX_SKEDARRUINS }, // "Skedar Ruins X"
/*0x29*/ { MUSIC_CREDITS, 120, L_MISC_165, SOLOSTAGEINDEX_SKEDARRUINS }, // "End Credits"
#if VERSION < VERSION_PAL_BETA
/*0x2a*/ { MUSIC_SKEDARRUINS_KING,120, L_MISC_261, SOLOSTAGEINDEX_SKEDARRUINS }, // "Skedar Warrior" (Skedar Leader)
#else
/*0x2a*/ { MUSIC_SKEDARRUINS_KING,120, L_MISC_041, SOLOSTAGEINDEX_SKEDARRUINS }, // "E R R O R" (can't find a good approximation for Skedar Leader)
#endif
};
bool mpIsTrackUnlocked(s32 tracknum)
@@ -60,6 +60,16 @@ struct menuitem g_CtcOptionsMenuItems[] = {
MPOPTION_NOAUTOAIM,
menuhandlerMpCheckboxOption,
},
#ifndef PLATFORM_N64
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
(uintptr_t)"Spawn With Weapon",
MPOPTION_SPAWNWITHWEAPON,
menuhandlerMpCheckboxOption,
},
#endif
{
MENUITEMTYPE_CHECKBOX,
0,
+10
View File
@@ -55,6 +55,16 @@ struct menuitem g_MpCombatOptionsMenuItems[] = {
MPOPTION_NOAUTOAIM,
menuhandlerMpCheckboxOption,
},
#ifndef PLATFORM_N64
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
(uintptr_t)"Spawn With Weapon",
MPOPTION_SPAWNWITHWEAPON,
menuhandlerMpCheckboxOption,
},
#endif
{
MENUITEMTYPE_SEPARATOR,
0,
@@ -58,6 +58,16 @@ struct menuitem g_HtmOptionsMenuItems[] = {
MPOPTION_NOAUTOAIM,
menuhandlerMpCheckboxOption,
},
#ifndef PLATFORM_N64
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
(uintptr_t)"Spawn With Weapon",
MPOPTION_SPAWNWITHWEAPON,
menuhandlerMpCheckboxOption,
},
#endif
{
MENUITEMTYPE_CHECKBOX,
0,
@@ -58,6 +58,16 @@ struct menuitem g_HtbOptionsMenuItems[] = {
MPOPTION_NOAUTOAIM,
menuhandlerMpCheckboxOption,
},
#ifndef PLATFORM_N64
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
(uintptr_t)"Spawn With Weapon",
MPOPTION_SPAWNWITHWEAPON,
menuhandlerMpCheckboxOption,
},
#endif
{
MENUITEMTYPE_CHECKBOX,
0,
@@ -417,7 +427,8 @@ Gfx *htbRenderHud(Gfx *gdl)
#endif
#ifndef PLATFORM_N64
if (PLAYERCOUNT() == 1) {
const s32 playercount = PLAYERCOUNT();
if (playercount < 2 || (playercount == 2 && optionsGetScreenSplit() == SCREENSPLIT_HORIZONTAL)) {
gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT);
}
#endif
+12 -1
View File
@@ -79,6 +79,16 @@ struct menuitem g_KohOptionsMenuItems[] = {
MPOPTION_NOAUTOAIM,
menuhandlerMpCheckboxOption,
},
#ifndef PLATFORM_N64
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
(uintptr_t)"Spawn With Weapon",
MPOPTION_SPAWNWITHWEAPON,
menuhandlerMpCheckboxOption,
},
#endif
{
MENUITEMTYPE_CHECKBOX,
0,
@@ -583,7 +593,8 @@ Gfx *kohRenderHud(Gfx *gdl)
}
#ifndef PLATFORM_N64
if (PLAYERCOUNT() == 1) {
const s32 playercount = PLAYERCOUNT();
if (playercount < 2 || (playercount == 2 && optionsGetScreenSplit() == SCREENSPLIT_HORIZONTAL)) {
gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT);
}
#endif
+12 -1
View File
@@ -56,6 +56,16 @@ struct menuitem g_PacOptionsMenuItems[] = {
MPOPTION_NOAUTOAIM,
menuhandlerMpCheckboxOption,
},
#ifndef PLATFORM_N64
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LITERAL_TEXT,
(uintptr_t)"Spawn With Weapon",
MPOPTION_SPAWNWITHWEAPON,
menuhandlerMpCheckboxOption,
},
#endif
{
MENUITEMTYPE_CHECKBOX,
0,
@@ -312,7 +322,8 @@ Gfx *pacRenderHud(Gfx *gdl)
sprintf(text, "%d:%02d", mins, secs);
#ifndef PLATFORM_N64
if (PLAYERCOUNT() == 1) {
const s32 playercount = PLAYERCOUNT();
if (playercount < 2 || (playercount == 2 && optionsGetScreenSplit() == SCREENSPLIT_HORIZONTAL)) {
gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT);
}
#endif
+15 -2
View File
@@ -1100,8 +1100,21 @@ void playerSpawn(void)
g_Vars.currentplayer->prop->chr->blurnumtimesdied = 0;
}
} else {
bgunEquipWeapon2(HAND_LEFT, g_DefaultWeapons[HAND_LEFT]);
bgunEquipWeapon2(HAND_RIGHT, g_DefaultWeapons[HAND_RIGHT]);
#ifndef PLATFORM_N64
if ((g_MpSetup.options & MPOPTION_SPAWNWITHWEAPON)
&& g_MpSetup.weapons[0] != MPWEAPON_NONE
&& g_MpSetup.weapons[0] != MPWEAPON_DISABLED) {
struct mpweapon *mpweapon = &g_MpWeapons[g_MpSetup.weapons[0]];
invGiveSingleWeapon(mpweapon->weaponnum);
bgunEquipWeapon2(HAND_LEFT, WEAPON_NONE);
bgunEquipWeapon2(HAND_RIGHT, mpweapon->weaponnum);
bgunSetAmmoQuantity(mpweapon->priammotype, mpweapon->priammoqty / 2);
} else
#endif
{
bgunEquipWeapon2(HAND_LEFT, g_DefaultWeapons[HAND_LEFT]);
bgunEquipWeapon2(HAND_RIGHT, g_DefaultWeapons[HAND_RIGHT]);
}
#if VERSION >= VERSION_NTSC_1_0
if (g_Vars.currentplayer->model00d4 == NULL
+1 -1
View File
@@ -20997,7 +20997,7 @@ Gfx *countdownTimerRender(Gfx *gdl)
ms = (s32)floorf(value60 * 1.6666666269302f) - mins * 6000 - secs * 100;
#ifndef PLATFORM_N64
if (playercount == 1) {
if (playercount < 2 || (playercount == 2 && optionsGetScreenSplit() == SCREENSPLIT_HORIZONTAL)) {
gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT);
}
#endif
+5
View File
@@ -312,6 +312,11 @@ Gfx *radarRender(Gfx *gdl)
} else if (optionsGetScreenSplit() != SCREENSPLIT_VERTICAL && playernum == 1) {
g_RadarY -= 8;
}
#ifndef PLATFORM_N64
if (optionsGetScreenSplit() == SCREENSPLIT_HORIZONTAL) {
gSPExtraGeometryModeEXT(gdl++, G_ASPECT_MODE_EXT, g_HudAlignModeR);
}
#endif
} else if (playercount >= 3) {
if (playernum >= 2) {
g_RadarY -= 8;
+83 -20
View File
@@ -23,9 +23,58 @@
#include <math.h>
#include "video.h"
#define SIGHT_COLOUR ((PLAYER_EXTCFG().crosshairhealth >= CROSSHAIR_HEALTH_ON_GREEN) ? sightGetCrosshairHealthColor(g_Vars.currentplayer->bondhealth, g_Vars.currentplayer->prop->chr->cshield * 0.125f) : PLAYER_EXTCFG().crosshaircolour)
#define SIGHT_SCALE PLAYER_EXTCFG().crosshairsize
static u32 sightGetCrosshairHealthColor(float health, float shield)
{
const float ratio = MAX(0.0f, MIN(health + shield, 2.0f));
int red = 0;
int green = 0;
int blue = 0;
if (ratio < 0.2f) {
// Red (critical health level)
red = 255;
green = 0;
blue = 0;
} else if (ratio < 0.6f) {
// Red-yellow
red = 255;
green = 255 * ((ratio - 0.2f) / 0.4f);
blue = 0;
} else if (ratio < 1.0f) {
if (PLAYER_EXTCFG().crosshairhealth == CROSSHAIR_HEALTH_ON_GREEN) {
// Yellow-green
red = 255 * ((ratio - 0.6f) / 0.4f);
green = 255;
blue = 0;
} else {
// Yellow-white
red = 255;
green = 255;
blue = 255 * ((ratio - 0.6f) / 0.4f);
}
} else {
if (PLAYER_EXTCFG().crosshairhealth == CROSSHAIR_HEALTH_ON_GREEN) {
// Green-cyan (overheal via shield)
red = 0;
green = 255;
blue = 255 * (ratio - 1.0f);
} else {
// White-green (overheal via shield)
red = 255 * (2.0f - ratio);
green = 255;
blue = 255 * (2.0f - ratio);
}
}
return (red << 24) + (green << 16) + (blue << 8) + (PLAYER_EXTCFG().crosshaircolour & 0xff);
}
static inline f32 sightGetScaleX(void)
{
return (videoGetAspect() / (4.f / 3.f));
return (videoGetAspect() / SCREEN_ASPECT);
}
static inline s32 sightGetAdjustedX(const f32 x)
@@ -36,6 +85,8 @@ static inline s32 sightGetAdjustedX(const f32 x)
#else
#define SIGHT_COLOUR 0x00ff0028
#define SIGHT_SCALE 2
#define sightGetScaleX() 1.f
#define sightGetAdjustedX(x) (x)
@@ -459,7 +510,7 @@ Gfx *sightDrawAimer(Gfx *gdl, s32 x, s32 y, s32 radius, s32 cornergap, u32 colou
s32 viewright = viewleft + viewwidth - 1;
s32 viewbottom = viewtop + viewheight - 1;
gdl = textSetPrimColour(gdl, 0x00ff0028);
gdl = textSetPrimColour(gdl, SIGHT_COLOUR);
#ifndef PLATFORM_N64
x = sightGetAdjustedX(x);
@@ -619,7 +670,7 @@ Gfx *sightDrawDelayedAimer(Gfx *gdl, s32 x, s32 y, s32 radius, s32 cornergap, u3
boxx = xpos;
boxy = ypos;
gdl = textSetPrimColour(gdl, 0x00ff0028);
gdl = textSetPrimColour(gdl, SIGHT_COLOUR);
// Fill a 3x3 box at the live crosshair
gDPHudRectangle(gdl++, x - 1, y - 1, x + 1, y - 1);
@@ -677,7 +728,7 @@ Gfx *sightDrawDefault(Gfx *gdl, bool sighton)
// SIGHTTRACKTYPE_NONE is used for unarmed, but this appears to be
// unreachable. The aimer is never drawn when unarmed.
if (sighton) {
colour = 0x00ff0028;
colour = SIGHT_COLOUR;
radius = 8;
cornergap = 5;
gdl = sightDrawAimer(gdl, x, y, radius, cornergap, colour);
@@ -687,7 +738,7 @@ Gfx *sightDrawDefault(Gfx *gdl, bool sighton)
// For most guns, render the aimer if holding R
if (sighton) {
if (g_Vars.currentplayer->lookingatprop.prop == NULL) {
colour = 0x00ff0028;
colour = SIGHT_COLOUR;
radius = 8;
cornergap = 5;
} else {
@@ -716,7 +767,7 @@ Gfx *sightDrawDefault(Gfx *gdl, bool sighton)
s32 texty;
if (g_Vars.currentplayer->lookingatprop.prop == NULL) {
colour = 0x00ff0028;
colour = SIGHT_COLOUR;
radius = 8;
cornergap = 5;
} else {
@@ -761,7 +812,7 @@ Gfx *sightDrawDefault(Gfx *gdl, bool sighton)
if (sighton) {
if (g_Vars.currentplayer->lookingatprop.prop == NULL) {
colour = 0x00ff0028;
colour = SIGHT_COLOUR;
radius = 8;
cornergap = 5;
} else {
@@ -832,7 +883,7 @@ Gfx *sightDrawDefault(Gfx *gdl, bool sighton)
if (sighton) {
if (g_Vars.currentplayer->lookingatprop.prop == NULL) {
colour = 0x00ff0028;
colour = SIGHT_COLOUR;
radius = 8;
cornergap = 5;
} else {
@@ -1252,7 +1303,7 @@ Gfx *sightDrawZoom(Gfx *gdl, bool sighton)
if (showzoomrange) {
gdl = text0f153628(gdl);
gdl = textSetPrimColour(gdl, 0x00ff0028);
gdl = textSetPrimColour(gdl, SIGHT_COLOUR);
if (frac < 0.2f) {
cornerwidth *= 0.2f;
@@ -1436,7 +1487,7 @@ Gfx *sightDrawMaian(Gfx *gdl, bool sighton)
gSPTri4(gdl++, 0, 4, 5, 5, 3, 6, 7, 6, 1, 4, 7, 2);
gdl = func0f0d49c8(gdl);
gdl = textSetPrimColour(gdl, 0x00ff0028);
gdl = textSetPrimColour(gdl, SIGHT_COLOUR);
// Draw border over inner points
gDPHudRectangle(gdl++, x - 4, y - 4, x - 4, y + 4); // left
@@ -1464,20 +1515,25 @@ Gfx *sightDrawTarget(Gfx *gdl)
mainOverrideVariable("sout", &var80070f9c);
mainOverrideVariable("sin", &var80070fa0);
gdl = textSetPrimColour(gdl, 0x00ff0028);
gdl = textSetPrimColour(gdl, SIGHT_COLOUR);
#ifndef PLATFORM_N64
gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT);
if (SIGHT_SCALE == 0) {
// Draw single rectangle to preserve intended opacity
gDPHudRectangle(gdl++, x, y, x, y);
} else
#endif
gDPHudRectangle(gdl++, x + 2, y + 0, x + 6, y + 0);
gDPHudRectangle(gdl++, x + 2, y + 0, x + 4, y + 0);
gDPHudRectangle(gdl++, x - 6, y + 0, x - 2, y + 0);
gDPHudRectangle(gdl++, x - 4, y + 0, x - 2, y + 0);
gDPHudRectangle(gdl++, x + 0, y + 2, x + 0, y + 6);
gDPHudRectangle(gdl++, x + 0, y + 2, x + 0, y + 4);
gDPHudRectangle(gdl++, x + 0, y - 6, x + 0, y - 2);
gDPHudRectangle(gdl++, x + 0, y - 4, x + 0, y - 2);
{
gDPHudRectangle(gdl++, x + 1 * SIGHT_SCALE, y + 0 * SIGHT_SCALE, x + 3 * SIGHT_SCALE, y + 0 * SIGHT_SCALE);
gDPHudRectangle(gdl++, x + 1 * SIGHT_SCALE, y + 0 * SIGHT_SCALE, x + 2 * SIGHT_SCALE, y + 0 * SIGHT_SCALE);
gDPHudRectangle(gdl++, x - 3 * SIGHT_SCALE, y + 0 * SIGHT_SCALE, x - 1 * SIGHT_SCALE, y + 0 * SIGHT_SCALE);
gDPHudRectangle(gdl++, x - 2 * SIGHT_SCALE, y + 0 * SIGHT_SCALE, x - 1 * SIGHT_SCALE, y + 0 * SIGHT_SCALE);
gDPHudRectangle(gdl++, x + 0 * SIGHT_SCALE, y + 1 * SIGHT_SCALE, x + 0 * SIGHT_SCALE, y + 3 * SIGHT_SCALE);
gDPHudRectangle(gdl++, x + 0 * SIGHT_SCALE, y + 1 * SIGHT_SCALE, x + 0 * SIGHT_SCALE, y + 2 * SIGHT_SCALE);
gDPHudRectangle(gdl++, x + 0 * SIGHT_SCALE, y - 3 * SIGHT_SCALE, x + 0 * SIGHT_SCALE, y - 1 * SIGHT_SCALE);
gDPHudRectangle(gdl++, x + 0 * SIGHT_SCALE, y - 2 * SIGHT_SCALE, x + 0 * SIGHT_SCALE, y - 1 * SIGHT_SCALE);
}
#ifndef PLATFORM_N64
gSPClearExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT);
@@ -1526,6 +1582,13 @@ Gfx *sightDraw(Gfx *gdl, bool sighton, s32 sight)
sight = SIGHT_DEFAULT;
}
#ifndef PLATFORM_N64
if (g_Vars.currentplayer->bondhealth <= 0.0f) {
// Hide crosshair during death animation
sight = SIGHT_NONE;
}
#endif
sightTick(sighton);
switch (sight) {
+3
View File
@@ -139,6 +139,9 @@ void texReset(void)
// get backend texture settings
g_TexFilter2D = videoGetTextureFilter2D() ? G_TF_BILERP : G_TF_POINT;
// notify blur code that the blur framebuffer is probably full of garbage
g_BlurFbDirty = true;
#endif
g_TexWords = mempAlloc(ALIGN16(g_TexNumConfigs * 4), MEMPOOL_STAGE);
+2
View File
@@ -372,6 +372,8 @@ Gfx *titleRenderLegal(Gfx *gdl)
elem->textptr = VERSION_HASH " (" VERSION_TARGET ")";
} else if (elem->textid == L_OPTIONS_083) {
elem->textptr = VERSION_ROMID;
} else if (elem->textid == L_OPTIONS_082) {
elem->textptr = "Perfect Dark (" VERSION_BRANCH ")";
}
#endif
break;
+9
View File
@@ -1692,6 +1692,10 @@
#define MENUITEMTYPE_CONTROLLER 0x19
#define MENUITEMTYPE_END 0x1a
#ifndef PLATFORM_N64
#define MENUITEMTYPE_COLORBOX 0x1b
#endif
#define MENUMODELFLAG_HASSCALE 0x01
#define MENUMODELFLAG_HASPOSITION 0x02
#define MENUMODELFLAG_HASROTATION 0x04
@@ -2885,6 +2889,7 @@
#define MPOPTION_HTM_SHOWONRADAR 0x00040000
#define MPOPTION_PAC_HIGHLIGHTTARGET 0x00080000
#define MPOPTION_PAC_SHOWONRADAR 0x00100000
#define MPOPTION_SPAWNWITHWEAPON 0x00200000
#define MPPAUSEMODE_UNPAUSED 0
#define MPPAUSEMODE_PAUSED 1
@@ -4714,6 +4719,10 @@ enum weaponnum {
#define CROUCHMODE_TOGGLE 2 // press the crouch buttons to toggle stance
#define CROUCHMODE_TOGGLE_ANALOG (CROUCHMODE_ANALOG | CROUCHMODE_TOGGLE)
#define CROSSHAIR_HEALTH_OFF 0
#define CROSSHAIR_HEALTH_ON_GREEN 1
#define CROSSHAIR_HEALTH_ON_WHITE 2
#endif
#endif
+3
View File
@@ -545,8 +545,11 @@ extern u32 g_HudAlignModeR;
extern s32 g_PrevFrameFb;
extern s32 g_BlurFb;
extern s32 g_BlurFbCapTimer;
extern bool g_BlurFbDirty;
extern s32 g_TickRateDiv;
extern s32 g_MusicDisableMpDeath;
extern s32 g_BgunGeMuzzleFlashes;
extern s32 g_FileAutoSelect;
#define PLAYER_EXTCFG() g_PlayerExtCfg[g_Vars.currentplayerstats->mpindex & 3]
#define PLAYER_DEFAULT_FOV (PLAYER_EXTCFG().fovy)
+4
View File
@@ -32,6 +32,10 @@ Gfx *menuitemLabelRender(Gfx *gdl, struct menurendercontext *context);
Gfx *menuitemMeterRender(Gfx *gdl, struct menurendercontext *context);
#ifndef PLATFORM_N64
Gfx *menuitemColorBoxRender(Gfx *gdl, struct menurendercontext *context);
#endif
Gfx *menuitemSelectableRender(Gfx *gdl, struct menurendercontext *context);
bool menuitemSelectableTick(struct menuitem *item, struct menuinputs *inputs, u32 tickflags);
+3
View File
@@ -6139,6 +6139,9 @@ struct extplayerconfig {
f32 radialmenuspeed;
f32 crosshairsway;
s32 extcontrols;
u32 crosshaircolour;
u32 crosshairsize;
s32 crosshairhealth;
};
#endif