mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Tweaked the path to load global shaders in the previous commit
* although 3.8 doesn't have the path issue as 4.x due to the lack of loading custom .dat, it's better to unify the path in this case. Refactored the code for DataLoadOrderPatch in the same way as 4.x.
This commit is contained in:
+1
-1
@@ -65,7 +65,7 @@ GraphicsWidth=0
|
||||
GraphicsHeight=0
|
||||
|
||||
;Uncomment the option to use a hardware shader (requires DX9 graphics mode 4 or 5)
|
||||
;The shader file <name>.fx must be placed in data\shaders\ and must contain one technique with one or more passes
|
||||
;The shader file <name>.fx must be placed in <GameRoot>\<master_patches>\shaders\ and must contain one technique with one or more passes
|
||||
;GlobalShaderFile=global.fx
|
||||
|
||||
;Set to 1 to do the palette conversion on the GPU
|
||||
|
||||
@@ -24,7 +24,7 @@ The input functions are only available if the user has the input hook turned on
|
||||
|
||||
The graphics functions are only available if the user is using graphics mode 4 or 5. Use graphics_funcs_available to check; it returns 1 if you can use them or 0 if you can't. Calling graphics functions when graphics_funcs_available returns 0 will do nothing.
|
||||
|
||||
load_shader takes a path relative to the data\shaders\ directory as an argument and returns a shader ID. That ID should be passed as the first argument to all other shader functions, and is valid until free_shader is called on the ID, the player loads a saved game or the player quits to the main menu.
|
||||
load_shader takes a path relative to the <GameRoot>\<master_patches>\shaders\ directory as an argument and returns a shader ID. That ID should be passed as the first argument to all other shader functions, and is valid until free_shader is called on the ID, the player loads a saved game or the player quits to the main menu.
|
||||
|
||||
get_shader_version gives you the highest shader version supported by the player's graphics cards. Possible return values are 11, 12, 13, 14, 20, 21 and 30.
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ DWORD* ptr_combat_state = reinterpret_cast<DWORD*>(_combat_state);
|
||||
DWORD* ptr_combat_turn_running = reinterpret_cast<DWORD*>(_combat_turn_running);
|
||||
DWORD* ptr_combatNumTurns = reinterpret_cast<DWORD*>(_combatNumTurns);
|
||||
DWORD* ptr_crit_succ_eff = reinterpret_cast<DWORD*>(_crit_succ_eff);
|
||||
DWORD* ptr_critter_db_handle = reinterpret_cast<DWORD*>(_critter_db_handle);
|
||||
PathNode** ptr_critter_db_handle = reinterpret_cast<PathNode**>(_critter_db_handle);
|
||||
DWORD* ptr_critterClearObj = reinterpret_cast<DWORD*>(_critterClearObj);
|
||||
DWORD* ptr_crnt_func = reinterpret_cast<DWORD*>(_crnt_func);
|
||||
DWORD* ptr_curr_font_num = reinterpret_cast<DWORD*>(_curr_font_num);
|
||||
@@ -123,7 +123,7 @@ DWORD* ptr_main_ctd = reinterpret_cast<DWORD*>(_main_ctd);
|
||||
DWORD* ptr_main_window = reinterpret_cast<DWORD*>(_main_window);
|
||||
DWORD* ptr_map_elevation = reinterpret_cast<DWORD*>(_map_elevation);
|
||||
DWORD* ptr_map_global_vars = reinterpret_cast<DWORD*>(_map_global_vars);
|
||||
DWORD* ptr_master_db_handle = reinterpret_cast<DWORD*>(_master_db_handle);
|
||||
PathNode** ptr_master_db_handle = reinterpret_cast<PathNode**>(_master_db_handle);
|
||||
DWORD* ptr_max = reinterpret_cast<DWORD*>(_max);
|
||||
long* ptr_maxScriptNum = reinterpret_cast<long*>(_maxScriptNum);
|
||||
DWORD* ptr_Meet_Frank_Horrigan = reinterpret_cast<DWORD*>(_Meet_Frank_Horrigan);
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
#define _game_global_vars 0x5186C0
|
||||
#define _game_ui_disabled 0x5186B4
|
||||
#define _game_user_wants_to_quit 0x5186CC
|
||||
#define _gconfig_file_name 0x58E978
|
||||
#define _gcsd 0x51094C
|
||||
#define _gdBarterMod 0x51873C
|
||||
#define _gDialogMusicVol 0x5187D8
|
||||
@@ -300,7 +301,7 @@ extern DWORD* ptr_combat_state;
|
||||
extern DWORD* ptr_combat_turn_running;
|
||||
extern DWORD* ptr_combatNumTurns;
|
||||
extern DWORD* ptr_crit_succ_eff;
|
||||
extern DWORD* ptr_critter_db_handle;
|
||||
extern PathNode** ptr_critter_db_handle;
|
||||
extern DWORD* ptr_critterClearObj;
|
||||
extern DWORD* ptr_crnt_func;
|
||||
extern DWORD* ptr_curr_font_num;
|
||||
@@ -377,7 +378,7 @@ extern DWORD* ptr_main_ctd;
|
||||
extern DWORD* ptr_main_window;
|
||||
extern DWORD* ptr_map_elevation;
|
||||
extern DWORD* ptr_map_global_vars;
|
||||
extern DWORD* ptr_master_db_handle;
|
||||
extern PathNode** ptr_master_db_handle;
|
||||
extern DWORD* ptr_max;
|
||||
extern long* ptr_maxScriptNum;
|
||||
extern DWORD* ptr_Meet_Frank_Horrigan;
|
||||
|
||||
+4
-4
@@ -196,8 +196,8 @@ void _stdcall SetShaderMode(DWORD d, DWORD mode) {
|
||||
int _stdcall LoadShader(const char* file) {
|
||||
if (!GraphicsMode || strstr(file, "..") || strstr(file, ":")) return -1;
|
||||
char buf[MAX_PATH];
|
||||
PathNode* pathsPtr = *ptr_paths;
|
||||
sprintf_s(buf, "%s\\shaders\\%s", pathsPtr->path, file);
|
||||
PathNode* masterPtr = *ptr_master_db_handle;
|
||||
sprintf_s(buf, "%s\\shaders\\%s", masterPtr->path, file); // *ptr_patches
|
||||
for (DWORD d = 0; d < shadersSize; d++) {
|
||||
if (!shaders[d].Effect) {
|
||||
if (FAILED(D3DXCreateEffectFromFile(d3d9Device, buf, 0, 0, 0, 0, &shaders[d].Effect, 0))) {
|
||||
@@ -218,7 +218,7 @@ int _stdcall LoadShader(const char* file) {
|
||||
|
||||
sprintf(buf, "texname%d", i);
|
||||
if (FAILED(shader.Effect->GetString(buf, &name))) break;
|
||||
sprintf_s(buf, "%s\\art\\stex\\%s", *ptr_patches, name);
|
||||
sprintf_s(buf, "%s\\art\\stex\\%s", masterPtr->path, name); // *ptr_patches
|
||||
if (FAILED(D3DXCreateTextureFromFileA(d3d9Device, buf, &tex))) continue;
|
||||
sprintf(buf, "tex%d", i);
|
||||
shader.Effect->SetTexture(buf, tex);
|
||||
@@ -1123,11 +1123,11 @@ void GraphicsInit() {
|
||||
if (!h) {
|
||||
MessageBoxA(0, "You have selected graphics mode 4 or 5, but " _DLL_NAME " is missing.\n"
|
||||
"Switch back to mode 0, or install an up to date version of DirectX.", "Error", MB_TASKMODAL | MB_ICONERROR);
|
||||
#undef _DLL_NAME
|
||||
ExitProcess(-1);
|
||||
} else {
|
||||
FreeLibrary(h);
|
||||
}
|
||||
#undef _DLL_NAME
|
||||
SafeWrite8(0x50FB6B, '2'); // Set call DirectDrawCreate2
|
||||
HookCall(0x44260C, game_init_hook);
|
||||
dlogr(" Done", DL_INIT);
|
||||
|
||||
+46
-38
@@ -21,37 +21,34 @@
|
||||
|
||||
static std::vector<int> savPrototypes;
|
||||
|
||||
static void __declspec(naked) RemoveDatabase() {
|
||||
__asm {
|
||||
cmp eax, -1;
|
||||
je end;
|
||||
mov ebx, ds:[_paths];
|
||||
mov ecx, ebx;
|
||||
nextPath:
|
||||
mov edx, [esp + 0x104 + 4 + 4]; // path_patches
|
||||
mov eax, [ebx]; // database.path
|
||||
call stricmp_;
|
||||
test eax, eax; // found path?
|
||||
jz skip; // Yes
|
||||
mov ecx, ebx;
|
||||
mov ebx, [ebx + 0xC]; // database.next
|
||||
jmp nextPath;
|
||||
skip:
|
||||
mov eax, [ebx + 0xC]; // database.next
|
||||
mov [ecx + 0xC], eax; // database.next
|
||||
xchg ebx, eax;
|
||||
cmp eax, ecx;
|
||||
jne end;
|
||||
mov ds:[_paths], ebx;
|
||||
end:
|
||||
retn;
|
||||
static PathNode* __fastcall RemoveDatabase(const char* pathPatches) {
|
||||
PathNode* paths = *ptr_paths; // curr.node (beginning of the chain of paths)
|
||||
PathNode* pPaths = paths; // prev.node
|
||||
|
||||
while (paths) {
|
||||
if (_stricmp(paths->path, pathPatches) == 0) { // found path
|
||||
PathNode* nextPaths = paths->next; // pointer to the node of the next path
|
||||
// TODO: need to check if this condition is used correctly
|
||||
if (paths != pPaths)
|
||||
pPaths->next = nextPaths; // replace the pointer in the previous node, removing the current(found) path from the chain
|
||||
else // if the current node is equal to the previous node
|
||||
*ptr_paths = nextPaths; // set the next node at the beginning of the chain
|
||||
return paths; // return the pointer of the current removed node (save the pointer)
|
||||
}
|
||||
pPaths = paths; // prev.node <- curr.node
|
||||
paths = paths->next; // take a pointer to the next path from the current node
|
||||
}
|
||||
return nullptr; // it's possible that this will create an exceptional situation for the game, although such a situation should not arise
|
||||
}
|
||||
|
||||
// Remove master_patches from the chain
|
||||
static void __declspec(naked) game_init_databases_hack1() {
|
||||
__asm {
|
||||
cmp eax, -1;
|
||||
je skip;
|
||||
mov ecx, [esp + 0x104 + 4]; // path_patches
|
||||
call RemoveDatabase;
|
||||
skip:
|
||||
mov ds:[_master_db_handle], eax; // the pointer of master_patches node will be saved here
|
||||
retn;
|
||||
}
|
||||
@@ -67,7 +64,7 @@ static void __declspec(naked) game_init_databases_hack2() {
|
||||
call xremovepath_;
|
||||
dec eax; // remove path (critter_patches == master_patches)?
|
||||
jz end; // Yes (jump if 0)
|
||||
inc eax;
|
||||
mov ecx, [esp + 0x104 + 4]; // path_patches
|
||||
call RemoveDatabase;
|
||||
end:
|
||||
mov ds:[_critter_db_handle], eax; // the pointer of critter_patches node will be saved here
|
||||
@@ -75,20 +72,29 @@ end:
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) game_init_databases_hook() {
|
||||
// eax = _master_db_handle
|
||||
__asm {
|
||||
mov ecx, ds:[_critter_db_handle];
|
||||
mov edx, ds:[_paths];
|
||||
test ecx, ecx;
|
||||
jz skip;
|
||||
mov [ecx + 0xC], edx; // critter_patches.next->_paths
|
||||
mov edx, ecx;
|
||||
skip:
|
||||
mov [eax + 0xC], edx; // master_patches.next
|
||||
mov ds:[_paths], eax;
|
||||
retn;
|
||||
static void __fastcall game_init_databases_hook() { // eax = _master_db_handle
|
||||
PathNode* master_patches = *ptr_master_db_handle;
|
||||
PathNode* critter_patches = *ptr_critter_db_handle;
|
||||
PathNode* paths = *ptr_paths; // beginning of the chain of paths
|
||||
// insert master_patches/critter_patches at the beginning of the chain of paths
|
||||
if (critter_patches) {
|
||||
critter_patches->next = paths; // critter_patches.next -> paths
|
||||
paths = critter_patches;
|
||||
}
|
||||
master_patches->next = paths; // master_patches.next -> paths
|
||||
*ptr_paths = master_patches; // set master_patches node at the beginning of the chain of paths
|
||||
}
|
||||
|
||||
static void __fastcall game_init_databases_hook1() {
|
||||
char masterPatch[MAX_PATH];
|
||||
iniGetString("system", "master_patches", "", masterPatch, MAX_PATH - 1, (const char*)_gconfig_file_name);
|
||||
|
||||
PathNode* node = *ptr_paths;
|
||||
while (node->next) {
|
||||
if (!_stricmp(node->path, masterPatch)) break;
|
||||
node = node->next;
|
||||
}
|
||||
*ptr_master_db_handle = node; // set pointer to master_patches node
|
||||
}
|
||||
|
||||
static void MultiPatchesPatch() {
|
||||
@@ -251,6 +257,8 @@ void LoadOrderInit() {
|
||||
HookCall(0x44436D, game_init_databases_hook);
|
||||
SafeWrite8(0x4DFAEC, 0x1D); // error correction (ecx > ebx)
|
||||
dlogr(" Done", DL_INIT);
|
||||
} else {
|
||||
HookCall(0x44436D, game_init_databases_hook1);
|
||||
}
|
||||
|
||||
dlog("Applying party member protos save/load patch.", DL_INIT);
|
||||
|
||||
Reference in New Issue
Block a user