@@ -428,46 +428,6 @@ void CAbstractStreaming::BuildPrevOnCdMap()
428428}
429429
430430
431- /*
432- * CAbstractStreaming::Patch
433- * Same as Patch() but called much later during game loading. This is used to
434- * improve compatibility with certain mods that modify pointer offsets.
435- */
436- void CAbstractStreaming::PatchDelayed ()
437- {
438- // Pointers
439- ms_aInfoForModel = ReadMemory<CStreamingInfo*>(0x40D014 , true );
440- LoadCdDirectory2 = ReadRelativeOffset (0x5B8310 + 1 ).get <void (const char *, int )>();
441- clothesDirectory = gvm.IsSA ()? ReadMemory<CDirectory*>(lazy_ptr<0x5A419B >(), true ) : nullptr ;
442-
443- // Part of standard models hooks
444- if (gvm.IsSA ())
445- {
446- MakeCALL (0x40CCA6 , raw_ptr (HOOK_RegisterNextModelRead));
447- MakeNOP (0x40CCA6 + 5 , 2 );
448- }
449- else if (gvm.IsVC ())
450- {
451- MakeCALL (0x40CCA6 , raw_ptr (HOOK_RegisterNextModelRead_VC));
452- MakeCALL (xVc (0x40B738 ), raw_ptr (HOOK_RegisterNextModelRead_VC));
453- MakeNOP (0x40CCA6 + 5 , 1 );
454- MakeNOP (xVc (0x40B738 ) + 5 , 1 );
455- }
456- else if (gvm.IsIII ()) // doesn't need to be delayed but keep together VC/SA hooks
457- {
458- using xcd_hook1 = function_hooker_thiscall<xIII (0x40A128 ), char (CStreamingInfo*, int *, int *)>;
459- using xcd_hook2 = function_hooker_thiscall<xIII (0x40A4F3 ), char (CStreamingInfo*, int *, int *)>;
460-
461- auto fn_register = [this ](xcd_hook1::func_type GetCdPosnAndSize, CStreamingInfo*& model, int *& pOffset, int *& pSize)
462- {
463- RegisterNextModelRead (this ->InfoForModelIndex (*model));
464- return GetCdPosnAndSize (model, pOffset, pSize);
465- };
466-
467- make_static_hook<xcd_hook1>(fn_register);
468- make_static_hook<xcd_hook2>(fn_register);
469- }
470- }
471431
472432/*
473433 * CAbstractStreaming::Patch
@@ -494,7 +454,10 @@ void CAbstractStreaming::Patch()
494454 if (!gvm.IsSA ())
495455 this ->bHasInitializedStreaming = false ;
496456
497- PatchDelayed ();
457+ // Pointers
458+ ms_aInfoForModel = ReadMemory<CStreamingInfo*>(0x40D014 , true );
459+ LoadCdDirectory2 = ReadRelativeOffset (0x5B8310 + 1 ).get <void (const char *, int )>();
460+ clothesDirectory = gvm.IsSA ()? ReadMemory<CDirectory*>(lazy_ptr<0x5A419B >(), true ) : nullptr ;
498461
499462 //
500463 this ->InitialiseStructAbstraction ();
@@ -562,7 +525,32 @@ void CAbstractStreaming::Patch()
562525 }
563526
564527 // We need to know the next model to be read before the CdStreamRead call happens
565- // XXX this hook has been moved to PatchDelayed!
528+ if (gvm.IsSA ())
529+ {
530+ MakeCALL (0x40CCA6 , raw_ptr (HOOK_RegisterNextModelRead));
531+ MakeNOP (0x40CCA6 + 5 , 2 );
532+ }
533+ else if (gvm.IsVC ())
534+ {
535+ MakeCALL (0x40CCA6 , raw_ptr (HOOK_RegisterNextModelRead_VC));
536+ MakeCALL (xVc (0x40B738 ), raw_ptr (HOOK_RegisterNextModelRead_VC));
537+ MakeNOP (0x40CCA6 + 5 , 1 );
538+ MakeNOP (xVc (0x40B738 ) + 5 , 1 );
539+ }
540+ else if (gvm.IsIII ())
541+ {
542+ using xcd_hook1 = function_hooker_thiscall<xIII (0x40A128 ), char (CStreamingInfo*, int *, int *)>;
543+ using xcd_hook2 = function_hooker_thiscall<xIII (0x40A4F3 ), char (CStreamingInfo*, int *, int *)>;
544+
545+ auto fn_register = [this ](xcd_hook1::func_type GetCdPosnAndSize, CStreamingInfo*& model, int *& pOffset, int *& pSize)
546+ {
547+ RegisterNextModelRead (this ->InfoForModelIndex (*model));
548+ return GetCdPosnAndSize (model, pOffset, pSize);
549+ };
550+
551+ make_static_hook<xcd_hook1>(fn_register);
552+ make_static_hook<xcd_hook2>(fn_register);
553+ }
566554
567555 // We need to return a new hFile if the file is on disk
568556 if (gvm.IsSA ())
@@ -707,29 +695,30 @@ void CAbstractStreaming::Patch()
707695 // Although streamed COLs exist in Vice too, they are checked, so we don't need to check ourselves
708696 if (gvm.IsSA ())
709697 {
698+ TraitsSA traits; // see comment above
699+
710700 // CColStore finding method is dummie, so we need to avoid duplicate cols by ourselves
711- make_static_hook<addcol_hook>([this ](addcol_hook::func_type AddColSlot, const char *& name)
701+ make_static_hook<addcol_hook>([this , traits ](addcol_hook::func_type AddColSlot, const char *& name)
712702 {
713- const auto col_start = TraitsSA::BaseIndexForCOL ();
714- return this ->FindOrRegisterResource (name, " col" , col_start, AddColSlot, name);
703+ return this ->FindOrRegisterResource (name, " col" , traits.col_start , AddColSlot, name);
715704 });
716705 }
717706
718707 // The following files are in SA only
719708 if (gvm.IsSA ())
720709 {
710+ TraitsSA traits;
711+
721712 // CVehicleRecording do not care about duplicates, but we should
722- make_static_hook<addr3_hook>([this ](addr3_hook::func_type RegisterRecordingFile, const char *& name)
713+ make_static_hook<addr3_hook>([this , traits ](addr3_hook::func_type RegisterRecordingFile, const char *& name)
723714 {
724- const auto rrr_start = TraitsSA::BaseIndexForRRR ();
725- return this ->FindOrRegisterResource (name, " rrr" , rrr_start, RegisterRecordingFile, name);
715+ return this ->FindOrRegisterResource (name, " rrr" , traits.rrr_start , RegisterRecordingFile, name);
726716 });
727717
728718 // CStreamedScripts do not care about duplicates but we should
729- make_static_hook<addscm_hook>([this ](addscm_hook::func_type RegisterScript, void *& self, const char *& name)
719+ make_static_hook<addscm_hook>([this , traits ](addscm_hook::func_type RegisterScript, void *& self, const char *& name)
730720 {
731- const auto scm_start = TraitsSA::BaseIndexForSCM ();
732- return this ->FindOrRegisterResource (name, " scm" , scm_start, RegisterScript, self, name);
721+ return this ->FindOrRegisterResource (name, " scm" , traits.scm_start , RegisterScript, self, name);
733722 });
734723 }
735724 }
0 commit comments