diff --git a/artifacts/config_files/Translations.ini b/artifacts/config_files/Translations.ini
index 2c95cfa0..bb4a9e5c 100644
--- a/artifacts/config_files/Translations.ini
+++ b/artifacts/config_files/Translations.ini
@@ -1,4 +1,13 @@
[sfall]
+;Table for overriding ASCII codes for keyboard character input when entering the player's name and saved game descriptions
+;Only character codes in the ASCII range 33-126 can be overridden
+;Character codes that do not need to be overridden can be omitted by using commas as delimiters
+;You must also set a key for switching layouts using the XltKey option in ddraw.ini
+;Default character code table for the English layout (letter codes only)
+;XltTable=,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,,,,,,,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,,,,
+
+;##############################################################################
+
SaveInCombat=Cannot save at this time.
KarmaGain=You gained %d karma.
KarmaLoss=You lost %d karma.
diff --git a/artifacts/config_files/readme.txt b/artifacts/config_files/readme.txt
index 19006d23..b2fae678 100644
--- a/artifacts/config_files/readme.txt
+++ b/artifacts/config_files/readme.txt
@@ -1,9 +1,12 @@
sfall's main configuration options appear in ddraw.ini, but there are several other configuration files that it can read in for modding purposes.
-Books.ini: Lets you override/add books to the game (associated object PIDs, skills and text messages)
+Books.ini: Lets you override/add books to the game (associated object PIDs, skills, and text messages)
+Drugs.ini: Lets you override/add drugs to the game (associated object PIDs, addiction duration, and text messages)
Perks.ini: Lets you override the name/description/frm image/other stats of perks and traits
-Elevators.ini: Lets you override which elevators lead where
+Elevators.ini: Lets you override which elevators lead to where
CriticalOverrides.ini: Lets you make modifications to the critical hit tables
Translations.ini: Contains some text strings which sfall displays, to allow their translation
Skills.ini: Lets you change the formula used for calculating skills
Stats.ini: Lets you change the formula used to calculate the derived stats
+Tweaks.ini: Lets you override a few object PIDs used in the engine
+Unarmed.ini: Lets you configure the requirements and effects of unarmed attacks
diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini
index 9dfddd8c..15b5694f 100644
--- a/artifacts/ddraw.ini
+++ b/artifacts/ddraw.ini
@@ -228,7 +228,7 @@ SpeedKey9=0x00
;A key to hold down to move the window around when using DX9 graphics mode 5
;Set to 0 if you don't want to use a modifier key, or a DX scancode otherwise
-;Set to -1 for either ctrl key, -2 for either alt key or -3 for either shift key
+;Set to -1 for either Ctrl key, -2 for either Alt key, or -3 for either Shift key
WindowScrollKey=0
;A key to press to reload your currently equipped weapon or use the active item
@@ -254,6 +254,10 @@ ItemMoveSkipDragKey=29
;Requires sfall debugging mode and FalloutDebug.exe from the modders pack
DebugEditorKey=0
+;A key to press to switch the keyboard layout (uses character codes from the XltTable option in Translations.ini)
+;Set to 1 for Num Lock, 2 for Caps Lock, 3 for Scroll Lock, or 0 to disable
+XltKey=0
+
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[Misc]
;Changes some of Fallout 2 engine functions to Fallout 1 behavior:
diff --git a/sfall/Modules/Input.cpp b/sfall/Modules/Input.cpp
index a5ec95b6..7abe2e56 100644
--- a/sfall/Modules/Input.cpp
+++ b/sfall/Modules/Input.cpp
@@ -16,10 +16,10 @@
* along with this program. If not, see .
*/
-//#include "..\InputFuncs.h"
-#include "..\Logging.h"
-#include "..\SafeWrite.h"
-//#include "LoadGameHook.h"
+#include "..\main.h"
+#include "..\FalloutEngine\Fallout2.h"
+#include "..\InputFuncs.h"
+#include "..\Translate.h"
#include "ScriptExtender.h"
#include "Input.h"
@@ -27,12 +27,94 @@
namespace sfall
{
+#define TABLE_SIZE (94) // for ASCII code 33-126
+
+static BYTE xltTable[TABLE_SIZE];
+static signed char xltKey; // 4 = Scroll Lock, 2 = Caps Lock, 1 = Num Lock
+
+static DWORD getInputStrRet;
+
+static void __declspec(naked) get_input_str_hack() {
+ __asm { // al - key ASCII code, in range 32-126
+ pop getInputStrRet;
+ push ecx;
+ mov cl, xltKey;
+ test ds:[FO_VAR_kb_lock_flags], cl;
+ jz end;
+ and eax, 0xFF;
+ cmp eax, 32; // skip the space char
+ je end;
+ mov al, [xltTable + eax - 33];
+end:
+ mov [esp + esi + 4], al;
+ jmp getInputStrRet;
+ }
+}
+
+static void __declspec(naked) get_input_str2_hack() {
+ __asm { // al - key ASCII code, in range 32-126
+ pop getInputStrRet;
+ push edx;
+ mov dl, xltKey;
+ test byte ptr ds:[FO_VAR_kb_lock_flags], dl;
+ jz end;
+ and eax, 0xFF;
+ cmp eax, 32; // skip the space char
+ je end;
+ mov al, [xltTable + eax - 33];
+end:
+ mov [esp + edi + 4], al;
+ jmp getInputStrRet;
+ }
+}
+
+static void __declspec(naked) kb_next_ascii_English_US_hack() {
+ __asm {
+ mov dh, [eax];
+ cmp dh, DIK_LBRACKET;
+ je end;
+ cmp dh, DIK_RBRACKET;
+ je end;
+ cmp dh, DIK_SEMICOLON;
+ je end;
+ cmp dh, DIK_APOSTROPHE;
+ je end;
+ cmp dh, DIK_COMMA;
+ je end;
+ cmp dh, DIK_PERIOD;
+ je end;
+ cmp dh, DIK_B;
+end:
+ retn;
+ }
+}
+
void Input::init() {
//if (IniReader::GetConfigInt("Input", "Enable", 0)) {
dlogr("Applying input patch.", DL_INIT);
SafeWrite32(0x4DE902, 0x50FB50); // "DDRAW.DLL"
::sfall::availableGlobalScriptTypes |= 1;
//}
+
+ xltKey = IniReader::GetConfigInt("Input", "XltKey", 0);
+ if (xltKey > 0) {
+ auto codeList = Translate::GetList("sfall", "XltTable", "", ',');
+ size_t numCodes = codeList.size();
+ if (numCodes > 0) {
+ dlogr("Applying alternate keyboard character codes patch.", DL_INIT);
+ for (size_t i = 0; i < TABLE_SIZE; i++) {
+ int code = (i < numCodes) ? atoi(codeList[i].c_str()) : 0;
+ xltTable[i] = (code > 32 && code < 256)
+ ? static_cast(code)
+ : static_cast(i + 33); // invalid char code, use default
+ }
+ if (xltKey > 2) xltKey = 4;
+ MakeCall(0x433F3E, get_input_str_hack);
+ MakeCall(0x47F364, get_input_str2_hack);
+ MakeCall(0x4CC358, kb_next_ascii_English_US_hack);
+ SafeWriteBatch(0x7E, {0x433ED6, 0x47F2F7}); // max ASCII code value allowed to input (was 122)
+ }
+ }
}
}
diff --git a/sfall/Modules/LoadOrder.cpp b/sfall/Modules/LoadOrder.cpp
index a28b8e7a..52d54cfe 100644
--- a/sfall/Modules/LoadOrder.cpp
+++ b/sfall/Modules/LoadOrder.cpp
@@ -614,11 +614,11 @@ noFile:
static DWORD hrpLoadRIX_func;
static DWORD hrpLoadBMP_func;
+static DWORD hrpSplashScrnRet;
static __declspec(naked) void game_splash_screen_hook_rix_HRP() {
- static DWORD retAddr;
__asm {
- pop retAddr;
+ pop hrpSplashScrnRet;
call hrpLoadRIX_func;
test al, al
jnz end;
@@ -635,15 +635,14 @@ static __declspec(naked) void game_splash_screen_hook_rix_HRP() {
push esi; // IMAGE8 data
call hrpLoadRIX_func;
end:
- jmp retAddr;
+ jmp hrpSplashScrnRet;
}
}
static __declspec(naked) void game_splash_screen_hook_bmp_HRP() {
static const char* splashFmt = "%ssplash%d.bmp";
- static DWORD retAddr;
__asm {
- pop retAddr;
+ pop hrpSplashScrnRet;
call hrpLoadBMP_func;
test al, al
jnz end;
@@ -660,7 +659,7 @@ static __declspec(naked) void game_splash_screen_hook_bmp_HRP() {
push esi; // IMAGE8 data
call hrpLoadBMP_func;
end:
- jmp retAddr;
+ jmp hrpSplashScrnRet;
}
}