summaryrefslogtreecommitdiffhomepage
path: root/src/fixes.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fixes.c')
-rw-r--r--src/fixes.c46
1 files changed, 38 insertions, 8 deletions
diff --git a/src/fixes.c b/src/fixes.c
index 79f4e3d..84b3482 100644
--- a/src/fixes.c
+++ b/src/fixes.c
@@ -1,5 +1,5 @@
/*
- * Copyright © 2023 Michael Smith <mikesmiffy128@gmail.com>
+ * Copyright © 2024 Michael Smith <mikesmiffy128@gmail.com>
* Copyright © 2023 Hayden K <imaciidz@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
@@ -23,7 +22,13 @@
#endif
#include "con_.h"
+#include "errmsg.h"
#include "gametype.h"
+#include "langext.h"
+#include "mem.h"
+#include "os.h"
+#include "ppmagic.h"
+#include "sst.h"
static void chflags(const char *name, int unset, int set) {
struct con_var *v = con_findvar(name);
@@ -58,6 +63,7 @@ static void generalfixes(void) {
unhide("con_filter_enable");
unhide("con_filter_text");
unhide("con_filter_text_out");
+ unhide("con_logfile");
// things that could conceivably cause issues with speedrun verification
// and/or pedantic following of rules; throw on cheat flag. this could be
@@ -118,7 +124,7 @@ static void l4d2specific(void) {
// possible on these earlier versions (who knows if that breaks
// something...).
struct con_var *v = con_findvar("mat_queue_mode");
- if (v && !(v->parent->base.flags & CON_ARCHIVE)) { // not already fixed
+ if_hot (v && !(v->parent->base.flags & CON_ARCHIVE)) { // not already fixed
v->parent->base.flags = v->parent->base.flags &
~(CON_HIDDEN | CON_DEVONLY) | CON_ARCHIVE;
v->parent->hasmin = true; v->parent->minval = -1;
@@ -132,15 +138,14 @@ static void l4d2specific(void) {
// so just blanket enable it if the primary adapter is Intel, since it
// doesn't seem to break anything else anyway.
v = con_findvar("mat_tonemapping_occlusion_use_stencil");
- if (!v || con_getvari(v)) goto e;
+ if_cold (!v || con_getvari(v)) goto e;
// considered getting d3d9 object from actual game, but it's way easier
// to just create another one
IDirect3D9 *d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
- if (!d3d9) goto e;
+ if_cold (!d3d9) goto e;
D3DADAPTER_IDENTIFIER9 ident;
- if (IDirect3D9_GetAdapterIdentifier(d3d9, 0, 0, &ident) == D3D_OK &&
- ident.VendorId == 0x8086) { // neat vendor id, btw!
- con_setvari(v, 1);
+ if_hot (IDirect3D9_GetAdapterIdentifier(d3d9, 0, 0, &ident) == D3D_OK) {
+ if (ident.VendorId == 0x8086) con_setvari(v, 1); // neat vendor id, btw!
}
IDirect3D9_Release(d3d9);
e:;
@@ -181,10 +186,35 @@ static void l4d1specific(void) {
chcmdflags("update_addon_paths", 0, CON_CCMDEXEC);
}
+static void portal1specific(void) {
+#ifdef _WIN32
+ // TODO(compat): this is an absolutely atrocious way to implement this. it
+ // should only be temporary in the interests of getting 4104 working right
+ // away. since other versions also have broken demos, a more general fix
+ // should be done... eventually...
+ void *EyeAngles = mem_offset(clientlib, 0x19D1B0); // in C_PortalPlayer
+ static const char match[] =
+ HEXBYTES(56, 8B, F1, E8, 48, 50, EA, FF, 84, C0, 74, 25);
+ if (!memcmp(EyeAngles, match, sizeof(match))) {
+ char *patch = mem_offset(EyeAngles, 39);
+ if (patch[0] == 0x75 && patch[1] == 0x08) {
+ if_hot (os_mprot(patch, 2, PAGE_EXECUTE_READWRITE)) {
+ patch[0] = 0x90; patch[1] = 0x90; // replace je with nop
+ }
+ else {
+ errmsg_warnsys("unable to fix 4104 demo playback bug: "
+ "couldn't make memory writable");
+ }
+ }
+ }
+#endif
+}
+
void fixes_apply(void) {
generalfixes();
if (GAMETYPE_MATCHES(L4D1)) l4d1specific();
else if (GAMETYPE_MATCHES(L4D2x)) l4d2specific();
+ else if (GAMETYPE_MATCHES(Portal1)) portal1specific();
}
// vi: sw=4 ts=4 noet tw=80 cc=80