Added support for switching the keyboard layout

(from Crafty)

Minor edits to some documents and LoadOrder.cpp.
This commit is contained in:
NovaRain
2025-09-17 20:49:10 +08:00
parent 93416a9450
commit ee5cdbcd81
5 changed files with 110 additions and 11 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.
+4 -2
View File
@@ -1,9 +1,11 @@
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)
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
@@ -210,7 +210,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 toggle the highlighting of all items on the ground on the current map
@@ -263,6 +263,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:
+87 -2
View File
@@ -16,8 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "..\Logging.h"
#include "..\SafeWrite.h"
#include "..\main.h"
#include "..\FalloutEngine\Fallout2.h"
#include "..\InputFuncs.h"
#include "..\Translate.h"
#include "ScriptExtender.h"
#include "Input.h"
@@ -25,12 +27,95 @@
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) {
std::vector<std::string> 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);
const DWORD charCodeMaxAddr[] = {0x433ED6, 0x47F2F7};
SafeWriteBatch<BYTE>(0x7E, charCodeMaxAddr); // max ASCII code value allowed to input (was 122)
}
}
}
}
+5 -6
View File
@@ -606,11 +606,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;
@@ -627,15 +627,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;
@@ -652,7 +651,7 @@ static __declspec(naked) void game_splash_screen_hook_bmp_HRP() {
push esi; // IMAGE8 data
call hrpLoadBMP_func;
end:
jmp retAddr;
jmp hrpSplashScrnRet;
}
}