Skip to content
rofl0r edited this page Jul 7, 2021 · 8 revisions

private notes about possible bugfixes

sisters secret

--- globalscript.s
+++ globalscript.s.patched
@@ -298,7 +298,7 @@
        sourceline 44
        thisaddr 625
        sourceline 45
-       li ax, 0
+       li ax, 1
        li mar, glUnlock
        memwrite4 ax
        sourceline 46

gemini rue

--- globalscript.s
+++ globalscript.s.patched
@@ -4618,7 +4618,7 @@
        sourceline 301
        thisaddr 0
        sourceline 305
-       li ax, 1
+       li ax, 0
        li mar, demoVersion
        memwrite4 ax
        sourceline 312

additionally, a hexeditor needs to be used to change aMusic33 and aMusic34 to aMusic17 each (each one has one occurence), as the referenced files are missing.

kathy rain

uses an ags engine with custom tweaks. the following patches need to be applied to 3.5.x (branch ags3 at the time of writing this) in order to get it to work.

--- a/Engine/ac/mouse.cpp
+++ b/Engine/ac/mouse.cpp
@@ -419,6 +419,13 @@ int find_previous_enabled_cursor(int startwith) {
     return testing;
 }
 
+void Mouse_EnableControl(bool on)
+{
+    if (on) ; //Mouse::EnableControl(!usetup.windowed);
+    else Mouse::DisableControl();
+}
+
+
 
 //=============================================================================
 //
@@ -561,6 +568,11 @@ RuntimeScriptValue Sc_Mouse_GetControlEnabled(const RuntimeScriptValue *params,
     API_SCALL_BOOL(Mouse::IsControlEnabled);
 }
 
+RuntimeScriptValue Sc_Mouse_SetControlEnabled(const RuntimeScriptValue *params, int32_t param_count)
+{
+    API_SCALL_VOID_PINT(Mouse_EnableControl);
+}
+
 RuntimeScriptValue Sc_Mouse_GetSpeed(const RuntimeScriptValue *params, int32_t param_count)
 {
     API_SCALL_FLOAT(Mouse::GetSpeed);
@@ -593,6 +605,7 @@ void RegisterMouseAPI()
     ccAddExternalStaticFunction("Mouse::UseDefaultGraphic^0",       Sc_set_default_cursor);
     ccAddExternalStaticFunction("Mouse::UseModeGraphic^1",          Sc_set_mouse_cursor);
     ccAddExternalStaticFunction("Mouse::get_ControlEnabled",        Sc_Mouse_GetControlEnabled);
+    ccAddExternalStaticFunction("Mouse::set_ControlEnabled",        Sc_Mouse_SetControlEnabled);
     ccAddExternalStaticFunction("Mouse::get_Mode",                  Sc_GetCursorMode);
     ccAddExternalStaticFunction("Mouse::set_Mode",                  Sc_set_cursor_mode);
     ccAddExternalStaticFunction("Mouse::get_Speed",                 Sc_Mouse_GetSpeed);

and this bugfix for a segfault which is already merged

--- a/Common/font/fonts.cpp
+++ b/Common/font/fonts.cpp
@@ -101,7 +101,7 @@ IAGSFontRenderer* font_replace_renderer(size_t fontNumber, I
AGSFontRenderer* ren
 
 bool is_bitmap_font(size_t fontNumber)
 {
-    if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer)
+    if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer2)
         return false;
     return fonts[fontNumber].Renderer2->IsBitmapFont();
 }

additionally you need to compile the plugins agsspritefont which can be found in ags source tree in Plugins/, as well as agsteam which can be found here: https://github.com/onitake/agsteamstub . the latter requires the following patch:

--- a/agsteam.cpp
+++ b/agsteam.cpp
@@ -28,7 +28,7 @@ BOOL APIENTRY DllMain(HANDLE hModule, DWORD ulReason, LPVOID lpReserved) {
 #include <cstdarg>
 
 #define THIS_IS_THE_PLUGIN
-#include "agsplugin.h"
+#include "plugin/agsplugin.h"
 
 #define AGSTEAM_PLUGIN_NAME "AGSteamStub"
 #define AGSTEAM_MESSAGE_PREFIX AGSTEAM_PLUGIN_NAME ": "
@@ -258,6 +258,9 @@ static bool AGSteam_SaveDb() {
        return saved;
 }
 
+static void AGS2Client_Initialize(void* a, void* b) { }
+static void void_fn(void) {}
+
 static int AGSteam_New(IAGSEngine *engine) {
        if (!AGSteam_initialized) {
                if (engine->version < 17) {
@@ -275,6 +278,9 @@ static int AGSteam_New(IAGSEngine *engine) {
                        AGSteam_ratestats.clear();
                        AGSteam_engine->RegisterScriptFunction("AGSteam::IsAchievementAchieved^1", reinterpret_cast<void *>(AGSteam_IsAchievementAchieved));
                        AGSteam_engine->RegisterScriptFunction("AGSteam::SetAchievementAchieved^1", reinterpret_cast<void *>(AGSteam_SetAchievementAchieved));
+                       AGSteam_engine->RegisterScriptFunction("AGS2Client::SetAchievementAchieved^1", reinterpret_cast<void *>(AGSteam_SetAchievementAchieved));
+                       AGSteam_engine->RegisterScriptFunction("AGS2Client::Initialize^2", reinterpret_cast<void *>(AGS2Client_Initialize));
+                       AGSteam_engine->RegisterScriptFunction("SetLineHeightAdjust", reinterpret_cast<void *>(void_fn));
                        AGSteam_engine->RegisterScriptFunction("AGSteam::ResetAchievement^1", reinterpret_cast<void *>(AGSteam_ResetAchievement));
                        AGSteam_engine->RegisterScriptFunction("AGSteam::GetIntStat^1", reinterpret_cast<void *>(AGSteam_GetIntStat));
                        AGSteam_engine->RegisterScriptFunction("AGSteam::GetFloatStat^1", reinterpret_cast<void *>(AGSteam_GetFloatStat));

put the directory into ags/Plugins, then use the following Makefile:

UNAME := $(shell uname)

INCDIR = ../../Engine ../../Common
LIBDIR =
CC = gcc
CXX = g++
CFLAGS = -fPIC -fvisibility=hidden -O2 -g -Wall
LIBS = -lm -lstdc++

ifeq ($(UNAME), Darwin)
TARGET = libagsteam.dylib
CFLAGS += -DMAC_VERSION
else
TARGET = libagsteam.so
CFLAGS += -DLINUX_VERSION
endif

CXXFLAGS = $(CFLAGS)

OBJS := agsteam.o


CFLAGS   := $(addprefix -I,$(INCDIR)) $(CFLAGS)
CXXFLAGS := $(CFLAGS) $(CXXFLAGS)
ASFLAGS  := $(CFLAGS) $(ASFLAGS)

all: $(TARGET)

$(TARGET): $(OBJS)
	$(CC) -shared -dynamiclib -o $@ $^ $(CFLAGS) $(LDFLAGS) $(LIBS)

%.o: %.c
	@echo $@
	$(CC) $(CFLAGS) -c -o $@ $<

%.o: %.cpp
	@echo $@
	$(CXX) $(CXXFLAGS) -c -o $@ $<

clean:
	rm -f $(TARGET) $(OBJS)

.PHONY: clean

in case you have kathy rain v 1.0.3 (version shown inside the game) from gog, there's a bug which prevents the parallax scroller from working. get kathy rain demo 1.0.4 from gog (free download), then use innoextract and then agsutils to extract the script objects from both versions and then inject gamescript18.o from the demo into game28.dta of the full version, then pack it into a new executable. use that executable to start a new game and play until the scene at the cemetary starts scrolling horizontally. save a savegame. from then on you can continue playing with the original executable. it seems the savegame contains a flag that is set by the fixed scrolling code, and once it's set scrolling will continue to work as it should. also saving a game with the patched version miraculously fixed an issue with barely readable text due to usage of gray-inside-white of the main font, once the savegame is used with the original game binary. in the demo, the font issue can be fixed by re-assembling gamescript1.s and injecting it into a new game executable, which then needs to be used to play.

note that at the end of the game there's a puzzle involving noting down numerical values of scrabble letters stuck onto a fridge. this one seems to require some of the modifications the game authors did to the engine. using our custom patched mainstream engine those letters aren't visible. a walkthrough needs to be used to get the letter values instead.

quest for infamy

there's a bug in quest for infamy 1.0.1 (GOG): if you found the bastard sword in the woods additionally to the one you already have, the magician refuses to upgrade your sword to the great sword: "You need to upgrade to the bastard sword first." for the great sword update and "You already have a better sword!" for the bastard sword update. basically they check for whether you have a first generation sword (iKnife) in your inventory, and if so, refuse to upgrade your second generation sword (iSwordBastard) to a 3rd generation sword.

--- gamescript14.s
+++ gamescript14.s_fixed_clean
@@ -7061,7 +7061,7 @@
 label000000016443: ; referenced by 1 spots
        sourceline 679
        push op
-       li mar, iKnife
+       li mar, iSwordBastard
        mr ax, mar
        farpush ax
        li mar, cEgo
@@ -7073,7 +7073,8 @@
        farsubsp 1
        pop op
        push ax
-       li ax, 1
+; patch: if have_bastard_sword != 0: jump to good
+       li ax, 0
        pop bx
        cmpeq bx, ax
        mr ax, bx

cheat to start the game with more $$$

--- gamescript0.s.org
+++ gamescript0.s
@@ -270,7 +270,7 @@
 ; unref'd, assuming array member with last known size
 export int drinkLosses = 0
 ; unref'd, assuming array member with last known size
-export int coinBlythos = 314
+export int coinBlythos = 3140
 ; unref'd, assuming array member with last known size
 export int itemcost = 0
 ; unref'd, assuming array member with last known size

last n'furious

menus don't behave as expected, if you press cursordown on the last item, top item should be selected. vice versa, cursor-up on top item should select bottom item. following well commented patch fixes it.

--- OBJ/gamescript20.s.org	2019-11-21 20:03:31.221629151 +0000
+++ OBJ/gamescript20.s	2019-11-21 20:27:08.093915810 +0000
@@ -5806,64 +5806,95 @@
 	ptrstack 8
 	memread4 ax
 	push ax
+; is cursor-up pressed ?
 	li ax, 372
 	pop bx
 	cmpeq bx, ax
 	mr ax, bx
 	jzi label000000012624
+; yes
 	sourceline 483
+; probably: load current bar position into...
 	li mar, @var000012
 	memread4 ax
 	push ax
 	li ax, 0
 	pop bx
+; bx!
 	gt bx, ax
 	mr ax, bx
+; is position > 0 ? if not, jump to label000000012620
 	jzi label000000012620
 	sourceline 484
 	li mar, @var000012
 	memread4 ax
 	subi ax, 1
+label_write_ax_to_bar_pos_1:
 	memwrite4 ax
 	sourceline 485
 	li ax, UpdateSelection$0
 	call ax
-label000000012620: ; inside on_key_press$1, ; referenced by 1 spots
-	sourceline 487
+
 	jmpi label000000012834
+
+label000000012620: ; inside on_key_press$1, ; referenced by 1 spots
+; set bar pos to nitems-1
+	li mar, @var000008
+	memread4 ax
+	subi ax, 1
+	li mar, @var000012
+	jmpi label_write_ax_to_bar_pos_1
+
+; not cursor-up key...
 label000000012624: ; inside on_key_press$1, ; referenced by 1 spots
 	ptrstack 8
 	memread4 ax
 	push ax
+; is cursor-down key ?
 	li ax, 380
 	pop bx
 	cmpeq bx, ax
 	mr ax, bx
+; if not , goto label000000012703
 	jzi label000000012703
 	sourceline 488
+; load current bar pos... onto stack
 	li mar, @var000012
 	memread4 ax
 	push ax
+; load (probably) number of bar items... -> stack
 	li mar, @var000008
 	memread4 ax
 	push ax
 	li ax, 1
 	pop bx
 	sub bx, ax
+; subtract 1 from bar items -> ax
 	mr ax, bx
 	pop bx
+; bar pos (bx) < bar_items -1 ?
 	lt bx, ax
 	mr ax, bx
+; if not goto label000000012699
 	jzi label000000012699
+; yes, smaller, so "OK"
 	sourceline 489
 	li mar, @var000012
 	memread4 ax
 	addi ax, 1
+label_write_ax_to_bar_pos_2:
 	memwrite4 ax
 	sourceline 490
 	li ax, UpdateSelection$0
 	call ax
+
+	jmpi label000000012834
+
+; if bar+1 > num items
 label000000012699: ; inside on_key_press$1, ; referenced by 1 spots
+	li mar, @var000012
+	li ax, 0
+	jmpi label_write_ax_to_bar_pos_2
 	sourceline 492
 	jmpi label000000012834
 label000000012703: ; inside on_key_press$1, ; referenced by 1 spots

strangeland

detailed writeup on how to replace external non-portable plugin .dll with AGS script code compiled with ascc and injected with agsutils. https://github.com/ags-archives/gamehacks/tree/master/strangeland

Clone this wiki locally