Added support for switching the keyboard layout

(from Crafty, closes #590)

Minor edits to some documents and LoadOrder.cpp.
This commit is contained in:
NovaRain
2025-09-17 20:47:04 +08:00
parent a0967aa12a
commit 90dfe16b22
5 changed files with 110 additions and 13 deletions
+9
View File
@@ -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.
+5 -2
View File
@@ -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
+5 -1
View File
@@ -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:
+86 -4
View File
@@ -16,10 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//#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<BYTE>(code)
: static_cast<BYTE>(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<BYTE>(0x7E, {0x433ED6, 0x47F2F7}); // max ASCII code value allowed to input (was 122)
}
}
}
}
+5 -6
View File
@@ -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;
}
}