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

This commit is contained in:
fgsfds committed 2024-11-23 12:35:52 +01:00
commit 4883fde642
16 files changed
+1944 -2279

No files matched your search

+6
View File
@@ -187,6 +187,12 @@ add_compile_options($<$<COMPILE_LANGUAGE:C>:-Wno-pointer-sign>)
# C++ specific flags
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-unused-function>)
# Platform-specific flags
if (APPLE)
# Make it look for libs in the executable folder manually since CMake's rpath system is wack
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -rpath @executable_path")
endif()
# Dependencies
set(LIBS )
+102 -36
View File
@@ -57,8 +57,10 @@ static float current_noise_scale;
static FilteringMode current_filter_mode = FILTER_LINEAR;
static bool current_textures_linear_filter[2] = {false, false};
static int gl_glsl_version = 130;
static char gl_glsl_version_str[16] = "130";
static GLenum gl_mirror_clamp = GL_MIRROR_CLAMP_TO_EDGE;
static bool gl_es = false;
static bool gl_core_profile = false;
static int gfx_opengl_get_max_texture_size() {
@@ -243,15 +245,19 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
// Vertex shader
#ifdef __APPLE__
append_line(vs_buf, &vs_len, "#version 410 core");
vs_len += sprintf(vs_buf + vs_len, "#version %s\n", gl_glsl_version_str);
if (gl_es) {
append_line(vs_buf, &vs_len, "precision mediump float;");
}
if (gl_glsl_version >= 130) {
append_line(vs_buf, &vs_len, "#define INPUT in");
append_line(vs_buf, &vs_len, "#define OUTPUT out");
#else
append_line(vs_buf, &vs_len, "#version 110");
} else {
append_line(vs_buf, &vs_len, "#define INPUT attribute");
append_line(vs_buf, &vs_len, "#define OUTPUT varying");
#endif
}
append_line(vs_buf, &vs_len, "INPUT vec4 aVtxPos;");
@@ -308,22 +314,31 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
for (int i = 0; i < cc_features.num_inputs; i++) {
vs_len += sprintf(vs_buf + vs_len, " vInput%d = aInput%d;\n", i + 1, i + 1);
}
append_line(vs_buf, &vs_len, " gl_Position = aVtxPos;");
if (!GLAD_GL_ARB_depth_clamp) {
// HACK: workaround for no GL_DEPTH_CLAMP
append_line(vs_buf, &vs_len, " gl_Position.z *= 0.3f;");
}
append_line(vs_buf, &vs_len, "}");
// Fragment shader
#ifdef __APPLE__
append_line(fs_buf, &fs_len, "#version 410 core");
fs_len += sprintf(fs_buf + fs_len, "#version %s\n", gl_glsl_version_str);
if (gl_es) {
append_line(fs_buf, &fs_len, "precision mediump float;");
}
if (gl_glsl_version >= 130) {
append_line(fs_buf, &fs_len, "#define INPUT in");
append_line(fs_buf, &fs_len, "#define OUTPUT_COLOR outColor");
append_line(fs_buf, &fs_len, "#define SAMPLE_TEX(tex, uv) texture(tex, uv)");
#else
append_line(fs_buf, &fs_len, "#version 130");
} else {
append_line(fs_buf, &fs_len, "#define INPUT varying");
append_line(fs_buf, &fs_len, "#define OUTPUT_COLOR gl_FragColor");
append_line(fs_buf, &fs_len, "#define SAMPLE_TEX(tex, uv) texture2D(tex, uv)");
#endif
}
// Reference approach to color wrapping as per GLideN64
// Return wrapped value of x in interval [low, high)
@@ -351,6 +366,7 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
for (int i = 0; i < cc_features.num_inputs; i++) {
fs_len += sprintf(fs_buf + fs_len, "INPUT vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1);
}
if (cc_features.used_textures[0]) {
append_line(fs_buf, &fs_len, "uniform sampler2D uTex0;");
if (current_filter_mode == FILTER_THREE_POINT)
@@ -418,9 +434,9 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
}
}
#if __APPLE__
if (gl_glsl_version >= 130) {
append_line(fs_buf, &fs_len, "out vec4 outColor;");
#endif
}
append_line(fs_buf, &fs_len, "void main() {");
@@ -428,7 +444,7 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
if (cc_features.used_textures[i]) {
bool s = cc_features.clamp[i][0], t = cc_features.clamp[i][1];
fs_len += sprintf(fs_buf + fs_len, " vec2 texSize%d = textureSize(uTex%d, 0);\n", i, i);
fs_len += sprintf(fs_buf + fs_len, " vec2 texSize%d = vec2(textureSize(uTex%d, 0));\n", i, i);
if (!s && !t) {
fs_len += sprintf(fs_buf + fs_len, " vec2 vTexCoordAdj%d = vTexCoord%d;\n", i, i);
@@ -520,6 +536,7 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
} else {
append_line(fs_buf, &fs_len, " OUTPUT_COLOR = vec4(texel, 1.0);");
}
append_line(fs_buf, &fs_len, "}");
vs_buf[vs_len] = '\0';
@@ -744,8 +761,12 @@ static void gfx_opengl_set_depth_mode(bool depth_test, bool depth_update, bool d
}
static void gfx_opengl_set_depth_range(float znear, float zfar) {
if (glDepthRangef) {
glDepthRangef(znear, zfar);
} else {
glDepthRange(znear, zfar);
}
}
static void gfx_opengl_set_viewport(int x, int y, int width, int height) {
glViewport(x, y, width, height);
@@ -814,18 +835,6 @@ static bool gfx_opengl_supports_framebuffers(void) {
return (glad_glBlitFramebuffer && glad_glRenderbufferStorageMultisample);
}
if (GLAD_GL_EXT_framebuffer_object && GLAD_GL_EXT_framebuffer_blit && GLAD_GL_EXT_framebuffer_multisample) {
// because of the way glad works we'll have to copy the pointers over
glad_glGenFramebuffers = glad_glGenFramebuffersEXT;
glad_glGenRenderbuffers = glad_glGenRenderbuffersEXT;
glad_glDeleteFramebuffers = glad_glDeleteFramebuffersEXT;
glad_glDeleteRenderbuffers = glad_glDeleteRenderbuffersEXT;
glad_glBindFramebuffer = glad_glBindFramebufferEXT;
glad_glBindRenderbuffer = glad_glBindRenderbufferEXT;
glad_glFramebufferRenderbuffer = glad_glFramebufferRenderbufferEXT;
glad_glFramebufferTexture2D = glad_glFramebufferTexture2DEXT;
glad_glRenderbufferStorage = glad_glRenderbufferStorageEXT;
glad_glRenderbufferStorageMultisample = glad_glRenderbufferStorageMultisampleEXT;
glad_glBlitFramebuffer = glad_glBlitFramebufferEXT;
// sanity check
return (glad_glFramebufferRenderbuffer && glad_glBlitFramebuffer && glad_glRenderbufferStorageMultisample);
}
@@ -890,11 +899,52 @@ static void *gl_load_proc(const char *name) {
return NULL;
}
static void gfx_opengl_init_extensions(void) {
// patch up some extension values and pointers
if (!GLAD_GL_ARB_depth_clamp) {
if (GLAD_GL_EXT_depth_clamp || GLAD_GL_NV_depth_clamp) {
GLAD_GL_ARB_depth_clamp = 1;
} else if (!gl_es && GLVersion.major >= 3) {
// GL3.2+ should have depth_clamp as part of the spec, but some devices don't report it for some reason
GLAD_GL_ARB_depth_clamp = (GLVersion.major > 3 || (GLVersion.major == 3 && GLVersion.minor >= 2));
}
}
if (!GLAD_GL_ARB_texture_mirror_clamp_to_edge) {
GLAD_GL_ARB_texture_mirror_clamp_to_edge = GLAD_GL_EXT_texture_mirror_clamp_to_edge;
}
if (GLVersion.major < 3 && !GLAD_GL_ARB_framebuffer_object) {
if (GLAD_GL_EXT_framebuffer_object && GLAD_GL_EXT_framebuffer_blit && GLAD_GL_EXT_framebuffer_multisample) {
// because of the way glad works we'll have to copy the pointers over
glad_glGenFramebuffers = glad_glGenFramebuffersEXT;
glad_glGenRenderbuffers = glad_glGenRenderbuffersEXT;
glad_glDeleteFramebuffers = glad_glDeleteFramebuffersEXT;
glad_glDeleteRenderbuffers = glad_glDeleteRenderbuffersEXT;
glad_glBindFramebuffer = glad_glBindFramebufferEXT;
glad_glBindRenderbuffer = glad_glBindRenderbufferEXT;
glad_glFramebufferRenderbuffer = glad_glFramebufferRenderbufferEXT;
glad_glFramebufferTexture2D = glad_glFramebufferTexture2DEXT;
glad_glRenderbufferStorage = glad_glRenderbufferStorageEXT;
glad_glRenderbufferStorageMultisample = glad_glRenderbufferStorageMultisampleEXT;
glad_glBlitFramebuffer = glad_glBlitFramebufferEXT;
}
}
}
static void gfx_opengl_init(void) {
if (!gladLoadGLLoader(gl_load_proc) || glGetString == NULL || glEnable == NULL) {
sysFatalError("Could not load OpenGL.\nReported SDL error: %s", SDL_GetError());
}
// check if we're using ES or core, which have more limited feature sets
int val = 0;
SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &val);
gl_core_profile = (val == SDL_GL_CONTEXT_PROFILE_CORE);
gl_es = (val == SDL_GL_CONTEXT_PROFILE_ES);
gfx_opengl_init_extensions();
if (sysArgCheck("--debug-gl")) {
gfx_opengl_enable_debug();
// dump version info as early as possible
@@ -908,7 +958,7 @@ static void gfx_opengl_init(void) {
}
if (!gfx_opengl_supports_shaders()) {
sysLogPrintf(LOG_WARNING, "GL: GLSL 1.30 unsupported");
sysLogPrintf(LOG_WARNING, "GL: GLSL 1.30 may be unsupported");
// maybe replace this with sysFatalError, though the GLSL compiler will cause that later anyway
}
@@ -924,20 +974,35 @@ static void gfx_opengl_init(void) {
gl_mirror_clamp = GL_MIRRORED_REPEAT;
}
if ((GLVersion.major == 3 && GLVersion.minor >= 2) || GLVersion.major > 3) {
// check if we're using core profile, which is more strict
int val = 0;
SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &val);
gl_core_profile = (val == SDL_GL_CONTEXT_PROFILE_CORE);
// determine GLSL version
if (gl_es) {
// ES has its own numbering scheme, but it should support 300 even on 3.1 and 3.2
gl_glsl_version = 300;
snprintf(gl_glsl_version_str, sizeof(gl_glsl_version_str), "%d es", gl_glsl_version);
} else if (!gl_core_profile) {
// in compat profile we can just request the lowest possible
gl_glsl_version = 130;
snprintf(gl_glsl_version_str, sizeof(gl_glsl_version_str), "%d", gl_glsl_version);
} else {
// otherwise we have to pick a specific version
if (GLVersion.major == 3 && GLVersion.minor == 2) {
// 3.2core is the earliest core version and it follows the old numbering scheme
gl_glsl_version = 150;
} else {
// 3.3+ follow the new numbering scheme
gl_glsl_version = GLVersion.major * 100 + GLVersion.minor * 10;
}
snprintf(gl_glsl_version_str, sizeof(gl_glsl_version_str), "%d core", gl_glsl_version);
}
sysLogPrintf(LOG_NOTE, "GL: using GLSL version %s", gl_glsl_version_str);
glGenBuffers(1, &opengl_vbo);
glBindBuffer(GL_ARRAY_BUFFER, opengl_vbo);
if (gl_core_profile) {
if (gl_core_profile || gl_es) {
// warn user that funny things can happen
sysLogPrintf(LOG_WARNING, "GL: using core profile, watch out for errors");
// core will explode if we don't use a VAO for our VBO
sysLogPrintf(LOG_WARNING, "GL: using core profile or ES, watch out for errors");
// core/es will explode if we don't use a VAO for our VBO
glGenVertexArrays(1, &opengl_vao);
glBindVertexArray(opengl_vao);
}
@@ -1156,7 +1221,8 @@ void gfx_opengl_copy_framebuffer(int fb_dst, int fb_src, int left, int top, bool
}
if (fb_src == 0) {
glReadBuffer(use_back ? GL_BACK : GL_FRONT);
// GLES does not support GL_FRONT here
glReadBuffer((use_back || gl_es) ? GL_BACK : GL_FRONT);
} else {
glReadBuffer(GL_COLOR_ATTACHMENT0);
}
+17
View File
@@ -192,6 +192,9 @@ static struct RDP {
bool viewport_or_scissor_changed;
void* z_buf_address;
void* color_image_address;
int16_t subpixel_ofs_x;
int16_t subpixel_ofs_y;
} rdp;
static struct RenderingState {
@@ -1969,6 +1972,11 @@ static void gfx_dp_set_fill_color(uint32_t packed_color) {
rdp.fill_color.a = a * 255;
}
static void gfx_dp_set_subpixel_offset(int16_t x, int16_t y) {
rdp.subpixel_ofs_x = x;
rdp.subpixel_ofs_y = y;
}
static void gfx_draw_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int32_t lry) {
uint32_t saved_other_mode_h = rdp.other_mode_h;
uint32_t cycle_type = (rdp.other_mode_h & (3U << G_MDSFT_CYCLETYPE));
@@ -1977,6 +1985,11 @@ static void gfx_draw_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int32_t lr
rdp.other_mode_h = (rdp.other_mode_h & ~(3U << G_MDSFT_TEXTFILT)) | G_TF_POINT;
}
ulx += rdp.subpixel_ofs_x;
lrx += rdp.subpixel_ofs_x;
uly += rdp.subpixel_ofs_y;
lry += rdp.subpixel_ofs_y;
// U10.2 coordinates
float ulxf = ulx;
float ulyf = uly;
@@ -2361,6 +2374,10 @@ static void gfx_run_dl(Gfx* cmd) {
break;
// G_SETPRIMCOLOR, G_CCMUX_PRIMITIVE, G_ACMUX_PRIMITIVE, is used by Goddard
// G_CCMUX_TEXEL1, LOD_FRACTION is used in Bowser room 1
case G_SETSUBPIXELOFFSET_EXT: {
gfx_dp_set_subpixel_offset(C0(0, 16), C1(0, 16));
break;
}
case G_TEXRECT:
case G_TEXRECTFLIP: {
int32_t lrx, lry, tile, ulx, uly;
+14 -10
View File
@@ -128,20 +128,21 @@ static void gfx_sdl_init(const struct GfxWindowInitSettings *set) {
// if that doesn't work, try 3.2 core in case we're on mac, 2.1 compat as a last resort
static u32 glver[][3] = {
{ 0, 0, 0 }, // for command line override
{ 3, 0, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY },
{ 3, 2, SDL_GL_CONTEXT_PROFILE_CORE },
{ 4, 1, SDL_GL_CONTEXT_PROFILE_CORE },
{ 2, 1, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY }, // will still require GLSL130
{ 3, 0, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY }, // 3.0: default, has all the features required
{ 4, 1, SDL_GL_CONTEXT_PROFILE_CORE }, // 4.1core: macs only have core profile and this is the latest
{ 3, 2, SDL_GL_CONTEXT_PROFILE_CORE }, // 3.2core: older macs will only have this at best
{ 3, 0, SDL_GL_CONTEXT_PROFILE_ES }, // es3: don't really support ES properly, but we can try
{ 2, 1, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY }, // 2.1: absolute last resort, will still require GLSL130 as an extension
};
u32 glcore = false;
u32 verstart = 1;
const u32 verend = sizeof(glver) / sizeof(*glver);
const char *verstr = sysArgGetString("--gl-version");
if (verstr && *verstr) {
// user override
glver[0][2] = strstr(verstr, "core") ? SDL_GL_CONTEXT_PROFILE_CORE :
SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
(strstr(verstr, "es") ? SDL_GL_CONTEXT_PROFILE_ES :
SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
sscanf(verstr, "%d.%d", &glver[0][0], &glver[0][1]);
if (glver[0][0] >= 1 && glver[0][0] <= 4 && glver[0][1] < 9) {
verstart = 0;
@@ -149,18 +150,21 @@ static void gfx_sdl_init(const struct GfxWindowInitSettings *set) {
}
ctx = NULL;
u32 vmin = 0, vmaj = 0;
u32 vmin = 0, vmaj = 0, vprof = SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
const char *vprofstr = "";
for (u32 i = verstart; i < verend; ++i) {
vmaj = glver[i][0];
vmin = glver[i][1];
vprof = glver[i][2];
vprofstr = (glver[i][2] == SDL_GL_CONTEXT_PROFILE_CORE ? "core" :
(glver[i][2] == SDL_GL_CONTEXT_PROFILE_ES ? "es" : ""));
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, vmaj);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, vmin);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, glver[i][2]);
ctx = SDL_GL_CreateContext(wnd);
if (!ctx) {
sysLogPrintf(LOG_WARNING, "GL: could not create GL%d.%d context: %s", vmaj, vmin, SDL_GetError());
sysLogPrintf(LOG_WARNING, "GL: could not create GL%d.%d%s context: %s", vmaj, vmin, vprofstr, SDL_GetError());
} else {
glcore = (glver[i][2] == SDL_GL_CONTEXT_PROFILE_CORE);
break;
}
}
@@ -168,7 +172,7 @@ static void gfx_sdl_init(const struct GfxWindowInitSettings *set) {
if (!ctx) {
sysFatalError("Could not create an OpenGL context of any supported version.\nSDL error: %s", SDL_GetError());
} else {
sysLogPrintf(LOG_NOTE, "GL: created GL%d.%d%s context", vmaj, vmin, glcore ? "core" : "");
sysLogPrintf(LOG_NOTE, "GL: created GL%d.%d%s context", vmaj, vmin, vprofstr);
}
SDL_GL_MakeCurrent(wnd, ctx);
+763 -709
View File
File diff suppressed because it is too large. Load diff
+841 -1488
View File
File diff suppressed because it is too large. Load diff
+7
View File
@@ -1004,6 +1004,13 @@ const char *inputGetConnectedControllerName(s32 id)
snprintf(fullName, sizeof(fullName), "%d: %s", jidx, name);
// replace non-ascii chars with spaces
for (char *p = fullName; *p; ++p) {
if ((u32)*p >= 0x7f) {
*p = ' ';
}
}
return fullName;
}
+5
View File
@@ -1583,6 +1583,7 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
}
// Handle xbla-style crouch cycling
const s32 oldcrouchpos = g_Vars.currentplayer->crouchpos;
for (i = 0; i < numsamples; i++) {
// handle 1964GEPD style crouch setting
s32 crouchsample;
@@ -1624,6 +1625,10 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
}
}
}
// prevent uncrouching if we don't fit
while (g_Vars.currentplayer->crouchpos > oldcrouchpos && !bwalkCanUncrouch()) {
g_Vars.currentplayer->crouchpos--;
}
}
#endif
+8
View File
@@ -1109,6 +1109,10 @@ Gfx *bviewDrawEyespyMetrics(Gfx *gdl)
s32 x = viewleft + (viewwidth >> 1);
s32 y = viewtop + (viewheight >> 1);
#ifndef PLATFORM_N64
gDPSetSubpixelOffsetEXT(gdl++, -2, -2);
#endif
gDPFillRectangle(gdl++, x + 2, y + 0, x + 7, y + 1);
gDPFillRectangle(gdl++, x + 2, y + 0, x + 5, y + 1);
gDPFillRectangle(gdl++, x - 6, y + 0, x - 1, y + 1);
@@ -1117,6 +1121,10 @@ Gfx *bviewDrawEyespyMetrics(Gfx *gdl)
gDPFillRectangle(gdl++, x + 0, y + 2, x + 1, y + 5);
gDPFillRectangle(gdl++, x + 0, y - 6, x + 1, y - 1);
gDPFillRectangle(gdl++, x + 0, y - 4, x + 1, y - 1);
#ifndef PLATFORM_N64
gDPSetSubpixelOffsetEXT(gdl++, 0, 0);
#endif
}
if (g_Vars.currentplayer->eyespy->mode == EYESPYMODE_CAMSPY) {
+76
View File
@@ -237,6 +237,47 @@ s32 bwalkTryMoveUpwards(f32 amount)
return result;
}
bool bwalkCanMoveUpwards(f32 amount)
{
bool result;
struct coord newpos;
RoomNum rooms[8];
u32 stack;
u32 types;
f32 ymax;
f32 ymin;
f32 radius;
if (g_Vars.currentplayer->floorflags & GEOFLAG_SLOPE) {
g_Vars.enableslopes = false;
} else {
g_Vars.enableslopes = true;
}
newpos.x = g_Vars.currentplayer->prop->pos.x;
newpos.y = g_Vars.currentplayer->prop->pos.y + amount;
newpos.z = g_Vars.currentplayer->prop->pos.z;
types = g_Vars.bondcollisions ? CDTYPE_ALL : CDTYPE_BG;
playerGetBbox(g_Vars.currentplayer->prop, &radius, &ymax, &ymin);
func0f065e74(&g_Vars.currentplayer->prop->pos, g_Vars.currentplayer->prop->rooms, &newpos, rooms);
bmoveFindEnteredRoomsByPos(g_Vars.currentplayer, &newpos, rooms);
propSetPerimEnabled(g_Vars.currentplayer->prop, false);
ymin -= 0.1f;
result = cdTestVolume(&newpos, radius, rooms, types, CHECKVERTICAL_YES,
ymax - g_Vars.currentplayer->prop->pos.y,
ymin - g_Vars.currentplayer->prop->pos.y);
propSetPerimEnabled(g_Vars.currentplayer->prop, true);
g_Vars.enableslopes = true;
return (result == CDRESULT_NOCOLLISION);
}
bool bwalkCalculateNewPosition(struct coord *vel, f32 rotateamount, bool apply, f32 extrawidth, s32 checktypes)
{
s32 result = CDRESULT_NOCOLLISION;
@@ -1168,6 +1209,41 @@ void bwalkUpdateCrouchOffsetReal(void)
}
}
bool bwalkCanUncrouch(void)
{
f32 targetoffset = 0;
if (g_Vars.currentplayer->crouchpos == CROUCHPOS_SQUAT) {
targetoffset = -90;
} else if (g_Vars.currentplayer->crouchpos == CROUCHPOS_DUCK) {
targetoffset = -45;
}
if (targetoffset != g_Vars.currentplayer->crouchoffset) {
f32 prevcrouchoffset = g_Vars.currentplayer->crouchoffset;
f32 prevcrouchoffsetreal = g_Vars.currentplayer->crouchoffsetreal;
f32 prevcrouchoffsetsmall = g_Vars.currentplayer->crouchoffsetsmall;
f32 prevcrouchoffsetrealsmall = g_Vars.currentplayer->crouchoffsetrealsmall;
f32 prevcrouchspeed = g_Vars.currentplayer->crouchspeed;
g_Vars.currentplayer->crouchoffset = targetoffset;
bwalkUpdateCrouchOffsetReal();
const bool result = bwalkCanMoveUpwards(0);
g_Vars.currentplayer->crouchoffset = prevcrouchoffset;
g_Vars.currentplayer->crouchoffsetreal = prevcrouchoffsetreal;
g_Vars.currentplayer->crouchoffsetsmall = prevcrouchoffsetsmall;
g_Vars.currentplayer->crouchoffsetrealsmall = prevcrouchoffsetrealsmall;
g_Vars.currentplayer->crouchspeed = prevcrouchspeed;
return result;
}
return true;
}
void bwalkUpdateCrouchOffset(void)
{
f32 targetoffset = 0;
+9
View File
@@ -1620,6 +1620,15 @@ void propCalculateShadeColour(struct prop *prop, u8 *nextcol, u16 floorcol)
{
s32 shade = func0f068fc8(prop, 0);
// fix props flickering in split screen when one of the players has night vision on
if (prop->type != PROPTYPE_PLAYER || g_Vars.currentplayer->prop != prop) {
if (USINGDEVICE(DEVICE_NIGHTVISION)) {
if (prop->rooms[0] >= 0) {
shade = g_Rooms[prop->rooms[0]].br_settled_regional;
}
}
}
roomr = shade;
roomg = shade;
roomb = shade;
+3 -1
View File
@@ -80,7 +80,7 @@ Gfx *radarRenderBackground(Gfx *gdl, struct textureconfig *tconfig, s32 arg2, s3
texSelect(&gdl, tconfig, 2, 0, 0, 1, NULL);
func0f0b278c(&gdl, spb0, spa8, tconfig->width, tconfig->height,
0, 0, 1, 0, 0xff, 0, 40, tconfig->level > 0, 0);
0, 0, 0, 0, 0xff, 0, 40, tconfig->level > 0, 0);
gDPPipeSync(gdl++);
gDPSetColorDither(gdl++, G_CD_BAYER);
@@ -329,6 +329,7 @@ Gfx *radarRender(Gfx *gdl)
}
#ifndef PLATFORM_N64
gSPExtraGeometryModeEXT(gdl++, G_ASPECT_MODE_EXT, g_HudAlignModeR);
gDPSetSubpixelOffsetEXT(gdl++, -2, 2);
#endif
}
@@ -337,6 +338,7 @@ Gfx *radarRender(Gfx *gdl)
// Draw dots for human players
#ifndef PLATFORM_N64
gDPSetSubpixelOffsetEXT(gdl++, 0, 0);
if (!(g_MpSetup.options & MPOPTION_NOPLAYERONRADAR)) {
#endif
for (i = 0; i < playercount; i++) {
+75 -28
View File
@@ -515,6 +515,7 @@ Gfx *sightDrawAimer(Gfx *gdl, s32 x, s32 y, s32 radius, s32 cornergap, u32 colou
#ifndef PLATFORM_N64
x = sightGetAdjustedX(x);
gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT);
gDPSetSubpixelOffsetEXT(gdl++, -2, -2);
#endif
// Draw the lines that span most of the viewport
@@ -551,6 +552,7 @@ Gfx *sightDrawAimer(Gfx *gdl, s32 x, s32 y, s32 radius, s32 cornergap, u32 colou
#ifndef PLATFORM_N64
gSPClearExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT);
gDPSetSubpixelOffsetEXT(gdl++, 0, 0);
#endif
gdl = text0f153838(gdl);
@@ -706,13 +708,13 @@ Gfx *sightDrawDelayedAimer(Gfx *gdl, s32 x, s32 y, s32 radius, s32 cornergap, u3
return gdl;
}
Gfx *sightDrawDefault(Gfx *gdl, bool sighton)
Gfx *sightDrawDefault(Gfx *gdl, bool sighton, f32 crossx, f32 crossy)
{
s32 radius;
s32 cornergap;
u32 colour;
s32 x = (s32) g_Vars.currentplayer->crosspos[0] / g_ScaleX;
s32 y = g_Vars.currentplayer->crosspos[1];
s32 x = (s32) crossx / g_ScaleX;
s32 y = crossy;
struct trackedprop *trackedprop;
s32 i;
@@ -902,13 +904,13 @@ Gfx *sightDrawDefault(Gfx *gdl, bool sighton)
return gdl;
}
Gfx *sightDrawClassic(Gfx *gdl, bool sighton)
Gfx *sightDrawClassic(Gfx *gdl, bool sighton, f32 crossx, f32 crossy)
{
struct textureconfig *tconfig = &g_TexGeCrosshairConfigs[0];
f32 spc4[2];
f32 spbc[2];
s32 x = g_Vars.currentplayer->crosspos[0];
s32 y = g_Vars.currentplayer->crosspos[1];
s32 x = crossx;
s32 y = crossy + 1; // Plus one, to align with the laser sight.
s32 x1;
s32 x2;
s32 y1;
@@ -966,9 +968,9 @@ Gfx *sightDrawClassic(Gfx *gdl, bool sighton)
return gdl;
}
Gfx *sightDrawType2(Gfx *gdl, bool sighton)
Gfx *sightDrawType2(Gfx *gdl, bool sighton, f32 crossx, f32 crossy)
{
return sightDrawClassic(gdl, sighton);
return sightDrawClassic(gdl, sighton, crossx, crossy);
}
#define COLOUR_LIGHTRED 0xff555564
@@ -1034,6 +1036,14 @@ Gfx *sightDrawSkedarTriangle(Gfx *gdl, s32 x, s32 y, s32 dir, u32 colour)
vertices[2].y = points[5] * 10;
vertices[2].z = -10;
#ifndef PLATFORM_N64
// Center-align Skedar tris
for (int i = 0; i < 3; ++i) {
vertices[i].x -= 2;
vertices[i].y += 2;
}
#endif
// @bug: This also needs to check for COLOUR_LIGHTRED because the caller can
// use two shades of red. The second colour is used when zeroing the sight
// in on a new target. Because of this bug, targeting an ally with the
@@ -1058,7 +1068,7 @@ Gfx *sightDrawSkedarTriangle(Gfx *gdl, s32 x, s32 y, s32 dir, u32 colour)
return gdl;
}
Gfx *sightDrawSkedar(Gfx *gdl, bool sighton)
Gfx *sightDrawSkedar(Gfx *gdl, bool sighton, f32 crossx, f32 crossy)
{
s32 viewleft = viGetViewLeft() / g_ScaleX;
s32 viewtop = viGetViewTop();
@@ -1068,10 +1078,10 @@ Gfx *sightDrawSkedar(Gfx *gdl, bool sighton)
s32 viewbottom = viewtop + viewheight - 1;
s32 paddingy = viewheight / 4;
s32 paddingx = viewwidth / 4;
s32 x = (s32) (g_Vars.currentplayer->crosspos[0] / g_ScaleX);
s32 x = (s32) (crossx / g_ScaleX);
s32 trix1;
s32 trix2;
s32 y = g_Vars.currentplayer->crosspos[1];
s32 y = crossy;
s32 triy2;
s32 triy1;
u32 colour;
@@ -1251,7 +1261,7 @@ Gfx *sightDrawSkedar(Gfx *gdl, bool sighton)
return gdl;
}
Gfx *sightDrawZoom(Gfx *gdl, bool sighton)
Gfx *sightDrawZoom(Gfx *gdl, bool sighton, f32 crossx, f32 crossy)
{
s32 viewleft = viGetViewLeft() / g_ScaleX;
s32 viewtop = viGetViewTop();
@@ -1331,6 +1341,16 @@ Gfx *sightDrawZoom(Gfx *gdl, bool sighton)
marginbottom = viewhalfheight - availablebelow * frac;
margintop = viewhalfheight - availableabove * frac;
#ifndef PLATFORM_N64
// Center-align the zoom range
if (frac != 1.0f) {
viewleft += 1;
viewright += 1;
viewbottom += 1;
viewtop += 1;
}
#endif
#define BOXLEFT (viewleft + marginleft)
#define BOXRIGHT (viewright - marginright)
#define BOXBOTTOM (viewbottom - marginbottom)
@@ -1346,6 +1366,7 @@ Gfx *sightDrawZoom(Gfx *gdl, bool sighton)
#ifndef PLATFORM_N64
gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT);
gDPSetSubpixelOffsetEXT(gdl++, -2, -2);
#endif
// Top left
@@ -1387,18 +1408,19 @@ Gfx *sightDrawZoom(Gfx *gdl, bool sighton)
#ifndef PLATFORM_N64
gSPClearExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT);
gDPSetSubpixelOffsetEXT(gdl++, 0, 0);
#endif
gdl = text0f153838(gdl);
gdl = text0f153780(gdl);
}
gdl = sightDrawDefault(gdl, sighton);
gdl = sightDrawDefault(gdl, sighton, crossx, crossy);
return gdl;
}
Gfx *sightDrawMaian(Gfx *gdl, bool sighton)
Gfx *sightDrawMaian(Gfx *gdl, bool sighton, f32 crossx, f32 crossy)
{
s32 viewleft = viGetViewLeft() / g_ScaleX;
s32 viewtop = viGetViewTop();
@@ -1406,8 +1428,8 @@ Gfx *sightDrawMaian(Gfx *gdl, bool sighton)
s32 viewheight = viGetViewHeight();
s32 viewright = viewleft + viewwidth - 1;
s32 viewbottom = viewtop + viewheight - 1;
s32 x = (s32)g_Vars.currentplayer->crosspos[0] / g_ScaleX;
s32 y = g_Vars.currentplayer->crosspos[1];
s32 x = (s32)crossx / g_ScaleX;
s32 y = crossy;
Vtx *vertices;
Col *colours;
s32 inner[4];
@@ -1425,6 +1447,7 @@ Gfx *sightDrawMaian(Gfx *gdl, bool sighton)
#ifndef PLATFORM_N64
x = sightGetAdjustedX(x);
gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT);
gDPSetSubpixelOffsetEXT(gdl++, -2, -2);
#endif
vertices = gfxAllocateVertices(8);
@@ -1469,6 +1492,14 @@ Gfx *sightDrawMaian(Gfx *gdl, bool sighton)
vertices[7].y = inner[2] * 10;
vertices[7].z = -10;
#ifndef PLATFORM_N64
// Center-align Maian tris
for (int i = 0; i < 8; ++i) {
vertices[i].x -= 2;
vertices[i].y += 2;
}
#endif
colours[0].word = PD_BE32(0x00ff000f);
colours[1].word = PD_BE32(hasprop ? colour : 0x00ff0044);
@@ -1499,15 +1530,16 @@ Gfx *sightDrawMaian(Gfx *gdl, bool sighton)
#ifndef PLATFORM_N64
gSPClearExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT);
gDPSetSubpixelOffsetEXT(gdl++, 0, 0);
#endif
return gdl;
}
Gfx *sightDrawTarget(Gfx *gdl)
Gfx *sightDrawTarget(Gfx *gdl, f32 crossx, f32 crossy)
{
s32 x = sightGetAdjustedX((s32)g_Vars.currentplayer->crosspos[0] / g_ScaleX);
s32 y = g_Vars.currentplayer->crosspos[1];
s32 x = sightGetAdjustedX((s32)crossx / g_ScaleX);
s32 y = crossy;
static u32 var80070f9c = 0x00ff00ff;
static u32 var80070fa0 = 0x00ff0011;
@@ -1519,6 +1551,7 @@ Gfx *sightDrawTarget(Gfx *gdl)
#ifndef PLATFORM_N64
gSPSetExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT);
gDPSetSubpixelOffsetEXT(gdl++, -2, -2);
if (SIGHT_SCALE == 0) {
// Draw single rectangle to preserve intended opacity
gDPHudRectangle(gdl++, x, y, x, y);
@@ -1537,6 +1570,7 @@ Gfx *sightDrawTarget(Gfx *gdl)
#ifndef PLATFORM_N64
gSPClearExtraGeometryModeEXT(gdl++, G_ASPECT_CENTER_EXT);
gDPSetSubpixelOffsetEXT(gdl++, 0, 0);
#endif
gdl = text0f153838(gdl);
@@ -1568,6 +1602,19 @@ Gfx *sightDraw(Gfx *gdl, bool sighton, s32 sight)
return gdl;
}
#ifndef PLATFORM_N64
// Rounding the crosshair positions allow them to more accurately follow the
// gun's vector. Without this, the mantissa isn't factored in at all (cast
// to integer), which leads to some awkward behavior, such as the crosshair
// taking a long time to return to the center of the screen when coming from
// an up and/or left direction.
const f32 crossx = roundf(g_Vars.currentplayer->crosspos[0]);
const f32 crossy = roundf(g_Vars.currentplayer->crosspos[1]);
#else
const f32 crossx = g_Vars.currentplayer->crosspos[0];
const f32 crossy = g_Vars.currentplayer->crosspos[1];
#endif
#if PAL
g_ScaleX = 1;
#else
@@ -1593,28 +1640,28 @@ Gfx *sightDraw(Gfx *gdl, bool sighton, s32 sight)
switch (sight) {
case SIGHT_DEFAULT:
gdl = sightDrawDefault(gdl, sighton && optionsGetSightOnScreen(g_Vars.currentplayerstats->mpindex));
gdl = sightDrawDefault(gdl, sighton && optionsGetSightOnScreen(g_Vars.currentplayerstats->mpindex), crossx, crossy);
break;
case SIGHT_CLASSIC:
gdl = sightDrawClassic(gdl, sighton && optionsGetSightOnScreen(g_Vars.currentplayerstats->mpindex));
gdl = sightDrawClassic(gdl, sighton && optionsGetSightOnScreen(g_Vars.currentplayerstats->mpindex), crossx, crossy);
break;
case SIGHT_2:
gdl = sightDrawType2(gdl, sighton && optionsGetSightOnScreen(g_Vars.currentplayerstats->mpindex));
gdl = sightDrawType2(gdl, sighton && optionsGetSightOnScreen(g_Vars.currentplayerstats->mpindex), crossx, crossy);
break;
case SIGHT_3:
gdl = sightDrawDefault(gdl, sighton && optionsGetSightOnScreen(g_Vars.currentplayerstats->mpindex));
gdl = sightDrawDefault(gdl, sighton && optionsGetSightOnScreen(g_Vars.currentplayerstats->mpindex), crossx, crossy);
break;
case SIGHT_SKEDAR:
gdl = sightDrawSkedar(gdl, sighton && optionsGetSightOnScreen(g_Vars.currentplayerstats->mpindex));
gdl = sightDrawSkedar(gdl, sighton && optionsGetSightOnScreen(g_Vars.currentplayerstats->mpindex), crossx, crossy);
break;
case SIGHT_ZOOM:
gdl = sightDrawZoom(gdl, sighton && optionsGetSightOnScreen(g_Vars.currentplayerstats->mpindex));
gdl = sightDrawZoom(gdl, sighton && optionsGetSightOnScreen(g_Vars.currentplayerstats->mpindex), crossx, crossy);
break;
case SIGHT_MAIAN:
gdl = sightDrawMaian(gdl, sighton && optionsGetSightOnScreen(g_Vars.currentplayerstats->mpindex));
gdl = sightDrawMaian(gdl, sighton && optionsGetSightOnScreen(g_Vars.currentplayerstats->mpindex), crossx, crossy);
break;
default:
gdl = sightDrawDefault(gdl, sighton && optionsGetSightOnScreen(g_Vars.currentplayerstats->mpindex));
gdl = sightDrawDefault(gdl, sighton && optionsGetSightOnScreen(g_Vars.currentplayerstats->mpindex), crossx, crossy);
break;
case SIGHT_NONE:
break;
@@ -1623,7 +1670,7 @@ Gfx *sightDraw(Gfx *gdl, bool sighton, s32 sight)
if (sight != SIGHT_NONE && optionsGetSightOnScreen(g_Vars.currentplayerstats->mpindex)) {
if ((optionsGetAlwaysShowTarget(g_Vars.currentplayerstats->mpindex) && !sighton)
|| (sighton && sightHasTargetWhileAiming(sight))) {
gdl = sightDrawTarget(gdl);
gdl = sightDrawTarget(gdl, crossx, crossy);
}
}
+2
View File
@@ -10,6 +10,7 @@ void bwalkSetSwayTargetf(f32 value);
void bwalkAdjustCrouchPos(s32 value);
void bwalk0f0c3b38(struct coord *param_1, struct defaultobj *obj);
s32 bwalkTryMoveUpwards(f32 amount);
bool bwalkCanMoveUpwards(f32 amount);
bool bwalkCalculateNewPosition(struct coord *vel, f32 rotateamount, bool apply, f32 extrawidth, s32 arg4);
bool bwalkCalculateNewPositionWithPush(struct coord *delta, f32 rotateamount, bool apply, f32 extrawidth, s32 types);
s32 bwalk0f0c4764(struct coord *delta, struct coord *arg1, struct coord *arg2, s32 types);
@@ -21,6 +22,7 @@ void bwalkUpdateSpeedSideways(f32 targetspeed, f32 accelspeed, s32 mult);
void bwalkUpdateSpeedForwards(f32 targetspeed, f32 accelspeed);
void bwalkUpdateVertical(void);
void bwalkApplyCrouchSpeed(void);
bool bwalkCanUncrouch(void);
void bwalkUpdateCrouchOffsetReal(void);
void bwalkUpdateCrouchOffset(void);
void bwalkUpdateTheta(void);
+7 -7
View File
@@ -14,14 +14,14 @@ s32 sightCalculateBoxBound(s32 arg0, s32 arg1, s32 arg2, s32 arg3);
Gfx *sightDrawTargetBox(Gfx *gdl, struct trackedprop *trackedprop, s32 textid, s32 time);
Gfx *sightDrawAimer(Gfx *gdl, s32 x, s32 y, s32 radius, s32 cornergap, u32 colour);
Gfx *sightDrawDelayedAimer(Gfx *gdl, s32 x, s32 y, s32 radius, s32 cornergap, u32 colour);
Gfx *sightDrawDefault(Gfx *gdl, bool sighton);
Gfx *sightDrawClassic(Gfx *gdl, bool sighton);
Gfx *sightDrawType2(Gfx *gdl, bool sighton);
Gfx *sightDrawDefault(Gfx *gdl, bool sighton, f32 crossx, f32 crossy);
Gfx *sightDrawClassic(Gfx *gdl, bool sighton, f32 crossx, f32 crossy);
Gfx *sightDrawType2(Gfx *gdl, bool sighton, f32 crossx, f32 crossy);
Gfx *sightDrawSkedarTriangle(Gfx *gdl, s32 x, s32 y, s32 dir, u32 colour);
Gfx *sightDrawSkedar(Gfx *gdl, bool sighton);
Gfx *sightDrawZoom(Gfx *gdl, bool sighton);
Gfx *sightDrawMaian(Gfx *gdl, bool sighton);
Gfx *sightDrawTarget(Gfx *gdl);
Gfx *sightDrawSkedar(Gfx *gdl, bool sighton, f32 crossx, f32 crossy);
Gfx *sightDrawZoom(Gfx *gdl, bool sighton, f32 crossx, f32 crossy);
Gfx *sightDrawMaian(Gfx *gdl, bool sighton, f32 crossx, f32 crossy);
Gfx *sightDrawTarget(Gfx *gdl, f32 crossx, f32 crossy);
bool sightHasTargetWhileAiming(s32 sight);
Gfx *sightDraw(Gfx *gdl, bool sighton, s32 sight);
+9
View File
@@ -196,6 +196,7 @@
#define G_IMAGERECT_EXT 0x42
#define G_RDPFLUSH_EXT 0x43
#define G_CLEAR_DEPTH_EXT 0x44
#define G_SETSUBPIXELOFFSET_EXT 0x45
/* G_EXTRAGEOMETRYMODE flags */
@@ -292,6 +293,14 @@
_g->words.w1 = (u32)(s); \
}
#define gDPSetSubpixelOffsetEXT(pkt, x, y) \
{ \
Gfx *_g = (Gfx*)(pkt); \
\
_g->words.w0 = _SHIFTL(G_SETSUBPIXELOFFSET_EXT, 24, 8) | _SHIFTL((s16)(x), 0, 16); \
_g->words.w1 = _SHIFTL((s16)(y), 0, 16); \
}
#define gSPSetExtraGeometryModeEXT(pkt, word) gSPExtraGeometryModeEXT((pkt), 0, word)
#define gSPClearExtraGeometryModeEXT(pkt, word) gSPExtraGeometryModeEXT((pkt), word, 0)