Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Ikarus/LeGo #231

Open
Try opened this issue Dec 27, 2021 · 15 comments
Open

Support for Ikarus/LeGo #231

Try opened this issue Dec 27, 2021 · 15 comments
Labels
enhancement New feature or request mod

Comments

@Try
Copy link
Owner

Try commented Dec 27, 2021

Subject

Ikarus is a popular library that provides set of DMA(direct memory access) utilities, exploring volubility in vanilla script-interpreter.
LeGo is a game framework bases on Ikarus, that provides all sort of goods, like custom-views, painting, AI, and more.

Ikarus strongly relies on how exactly original game works: addresses of oGame/zTimer/oCInformationManager are hard-coded, pointer are stored in int32 - something what is not doable on x64 platform

Goal

Create good-enough compatibility layer, to enable most popular mods: the Chronicles of Myrtana, VarusBiker Edition and others

Design

We won't provide same memory layout for most of things, so support won't be bullet-prof. Instead, OpenGothic will give access to high-level functional.
To make int-pointers work OpenGothic will provide a fake 3GB heap structure, with layout like virtual memory in win32.
Mappings:

  • MEM_Alloc/MEM_Free - just works; can be serialized
  • script bytecode - cannot handle as-is, in theory we can align internal bytecode layout, or simply skip
  • classes - VM doesn't have a support for user-defined classes; need to implement that
  • objects - current version of VM provides a managed environment(with ref-counting). That won't work as-is, if script can emplace class in allocated memory
  • Allocation should be padded to be multiple of 4 bytes, to ensure support of MEM_ReadInt/MEM_WriteInt

Memory layout should resemble Win32 heap, while be sealizable:

[0x00000000 .. 0x00001000] - nullptr page
[0x00001000 .. 0x80000000] - (2GB) user space; MEM_Alloc/MEM_Free
[0x80000000 .. 0xc0000000] - (1GB) engine mapped data
[0xc0000000 .. 0xffffffff] - (1GB) kernel space - not in use

Api(Ikarus):

Base on ikarus_Doc.d
JW - mean 'just works' - function does not require engine-level support.
Access will be reliable only for manually allocated memory(MEM_Alloc), engine-memory generally won't do, unless there is no alternative.

  1. Memory

    • int MEM_ReadInt(var int address)
    • void MEM_WriteInt(var int address, var int val)
    • string MEM_ReadString(var int address)
    • void MEM_WriteString(var int address, var string val)
    • int MEM_ReadIntArray (var int arrayAddress, var int offset) [JW]
    • int MEM_WriteIntArray (var int arrayAddress, var int offset, var int value) [JW]
    • int MEM_ReadByte(var int adr) [JW]
    • void MEM_WriteByte (var int adr, var int val) [JW]
  2. Parser

    • instance MEM_PtrToInst(var int ptr)
    • void MEM_AssignInst(var int inst, var int ptr)
    • instance MEM_CpyInst (var int inst)
  3. Functions & Reflection

    • void MEM_CallByString(var string fnc)
    • void MEM_CallByID(var int ID)
    • void MEM_PushIntParam(var int param)
    • void MEM_PushStringParam(var string strParam)
    • void MEM_PushInstParam(var int instance)
    • int MEM_PopIntResult()
    • string MEM_PopStringResult()
    • instance MEM_PopInstResult()
    • int MEM_GetFuncID(var func function)
    • void MEM_Call(var func function)
    • int MEM_FindParserSymbol (var string inst)
    • int MEM_GetParserSymbol (var string inst)
      Note: Symbols do exist in OpenGothic, but do not match in terms of memory-layout
  4. Jumps & Control flow

    • MEM_InitLabels
    • MEM_StackPos.position
  5. Strings

    • int STR_GetCharAt(var string str, var int pos)
    • int STR_Len (var string str)
    • int STR_Compare (var string str1, var string str2)
    • int STR_ToInt(var string str)
    • string STR_SubStr(var string str, var int start, var int count)
    • string STR_Prefix (var string str, var int count) [JW]
    • string STR_Upper(var string str)
    • int STR_SplitCount(var string str, var string Seperator)
    • string STR_Split(var string str, var string Separator, var int index)
    • int STR_IndexOf(var string str, var string tok)
  6. Menu

    • int MEM_GetMenuByString(var string menu)
    • int MEM_GetMenuItemByString(var string menuItem)
  7. Global instances

    • instance MEM_Game (oCGame);
    • instance MEM_World (oWorld);
    • instance MEM_Timer (zCTimer);
    • instance MEM_WorldTimer (oCWorldTimer);
    • instance MEM_Vobtree (zCTree);
    • instance MEM_InfoMan (oCInfoManager);
    • instance MEM_InformationMan (oCInformationManager);
    • instance MEM_Waynet (zCWaynet);
    • instance MEM_Camera (zCCamera);
    • instance MEM_SkyController (zCSkyController_Outdoor);
    • instance MEM_SpawnManager (oCSpawnManager);
    • func void MEM_InitGlobalInst()
  8. Ini file

    • string MEM_GetGothOpt (var string sectionname, var string optionname)
    • string MEM_GetModOpt (var string sectionname, var string optionname)
    • int MEM_GothOptSectionExists (var string sectionname)
    • int MEM_GothOptExists (var string sectionname, var string optionname)
    • int MEM_ModOptSectionExists (var string sectionname)
    • int MEM_ModOptExists (var string sectionname, var string optionname)
    • void MEM_SetGothOpt (var string section, var string option, var string value)
  9. Keyboard settings

    • int MEM_GetKey(var string name)
    • int MEM_GetSecondaryKey(var string name)
    • int MEM_KeyPressed(var int key)
    • int MEM_KeyState(var int key)
    • void MEM_InsertKeyEvent(var int key)
  10. Execute x86 code from memory
    Won't do

  11. Calls to engine functions

  • void CALL_IntParam(var int param)
  • void CALL_FloatParam(var int param)
  • void CALL_PtrParam(var int param)
  • void CALL_zStringPtrParam(var string param)
  • void CALL_cStringPtrParam (var string param)
  • void CALL_StructParam(var int ptr, var int words)
  • void CALL__stdcall(var int adr )
  • void CALL__thiscall(var int this, var int adr)
  • void CALL__cdecl(var int adr)
  • void CALL__fastcall(var int ecx, var int edx, var int adr)
  • int CALL_RetValAsInt()
  • int CALL_RetValAsPtr()
  • instance CALL_RetValAsStructPtr()
  • string CALL_RetValAszStringPtr()
  • void CALL_RetValIsFloat()
  • int CALL_RetValAsFloat()
  • void CALL_RetValIsStruct (var int words)
  • void CALL_RetValIszString()
  • string CALL_RetValAszString()
    Note: only fixed subset of function can be supported in individual manner
  1. External libraries
  • int LoadLibrary(var string lpFileName)
  • int GetProcAddress (var int hModule, var string lpProcName)
    Note: generally won't do, due to portability complexity.
  1. Various
  • int MEM_SearchVobByName (var string str)
  • int MEM_SearchAllVobsByName (var string str)
  • int MEM_InsertVob(var string vis, var string wp)
  • void MEM_TriggerVob (var int vobPtr)
  • void MEM_UntriggerVob (var int vobPtr)
  • void MEM_RenameVob (var int vobPtr, var string newName)
  • int Hlp_Is_oCMob(var int ptr)
  • int Hlp_Is_oCMobInter(var int ptr)
  • int Hlp_Is_oCMobLockable(var int ptr)
  • int Hlp_Is_oCMobContainer(var int ptr)
  • int Hlp_Is_oCMobDoor(var int ptr)
  • int Hlp_Is_oCNpc(var int ptr)
  • int Hlp_Is_oCItem(var int ptr)
  • int Hlp_Is_zCMover(var int ptr)
  • int Hlp_Is_oCMobFire(var int ptr)
  • void MEM_SetShowDebug (var int on)
  • string MEM_GetCommandLine()
  • int MEM_MessageBox (var string txt, var string caption, var int type)
  • void MEM_InfoBox (var string txt)
  • int MEM_GetSystemTime()
  • int MEM_BenchmarkMS(var func f)
  • int MEM_BenchmarkPC(var func f)
  • int MEM_BenchmarkMS_N(var func f, var int n)
  • int MEM_BenchmarkPC_N(var func f, var int n)
  • int MEM_ReadStatArr (var int array, var int offset)
  • void MEM_WriteStatArr (var int array, var int offset, var int value)
  • int MEM_GetStringAddress(var string s)
  • int MEM_GetFloatAddress (var float f)
  • int MEM_GetIntAddress (var int i)
  • int MEM_ArrayCreate ()
  • void MEM_ArrayFree (var int zCArray_ptr)
  • void MEM_ArrayClear (var int zCArray_ptr)
  • void MEM_ArrayInsert (var int zCArray_ptr, var int value)
  • void MEM_ArrayRemoveIndex (var int zCArray_ptr, var int index)
  • void MEM_ArrayRemoveValue (var int zCArray_ptr, var int value)
  • void MEM_ArrayRemoveValueOnce (var int zCArray_ptr, var int value)
  • void MEM_CopyBytes (var int src, var int dst, var int byteCount)
  • void MEM_CopyWords (var int src, var int dst, var int wordcount) [JW]
  • void MEM_SwapBytes (var int ptr1, var int ptr2, var int byteCount)
  • void MEM_SwapWords (var int ptr1, var int ptr2, var int wordcount)
  • int MEM_CompareBytes (var int ptr1, var int ptr2, var int byteCount)
  • int MEM_CompareWords (var int ptr1, var int ptr2, var int wordcount)
  • void MEM_InitAll()
  1. Extra low-levels
  • int MEM_GetFuncPtr(var func fnc)
  • int MEM_GetFuncOffset(var func fnc)
  • int MEM_GetClassDef (var int objPtr)
  • string MEM_GetClassName (var int objPtr)
  • int MEM_GetBufferCRC32 (var int buf, var int buflen)
  • int MEM_GetStringHash (var string str)
  • int MEM_Alloc (var int amount)
  • int MEM_Realloc (var int oldptr, var int oldsize, var int newsize)
  • void MEM_Free (var int ptr)
  • void MEM_SetParser(var int parserID)
  • void MemoryProtectionOverride (var int address, var int size) - won't do
@Try Try added the enhancement New feature or request label Dec 27, 2021
Try added a commit that referenced this issue Dec 27, 2021
@Try Try added the mod label Dec 27, 2021
Try added a commit that referenced this issue Dec 27, 2021
Try added a commit that referenced this issue Dec 27, 2021
Try added a commit that referenced this issue Dec 28, 2021
@lmichaelis
Copy link
Contributor

Hi, just to let you know: I'll be looking into this as well. I'm about to take a look at Chronicles of Myrtana so see what kind of Ikarus/LeGo functions it uses so we can more accurately determine whether this is actually feasible. Do you know if its source code is publicly available somewhere? Otherwise I'll use my custom tools :)

@Try
Copy link
Owner Author

Try commented Oct 26, 2022

Do you know if its source code is publicly available somewhere? Otherwise I'll use my custom tools :)

Haven't seen a sources anywhere, so fell free ;)

@lmichaelis
Copy link
Contributor

If anyone finds this helpful too, here's a decompilation of The Chronicles of Myrtana: Archolos :)

@hellozyemlya
Copy link

Just my 5 cents here: Is that really required to make OpenGothic compatible with all of that mem read mem write functions and anything that mess around with bytecode and/or internal class structures? Obviously due to many differences in native class structure mod code will not be able to produce same results as on original engine(and crash game in most cases).

Maybe it worth to focus on compatibility layer that will allow to dynamically replace/hook/patch VM code and implement all required functionality directly in C++?

For example, items picking while swimming in CoM: locate all places that messing with engine from VM and stub/hook them, implement feature as c++ plugin for opengothic, enjoy feature.

So it will be possible to run some of the biggest and most noticeable mods with manual patching & using original mod distro. And maybe provide normal modding api for modmakers to ensure they are creating their mods on modern engine without messing with memory patching.

@lmichaelis
Copy link
Contributor

Maybe it worth to focus on compatibility layer that will allow to dynamically replace/hook/patch VM code and implement all required functionality directly in C++?

Yeah, I was looking at that, but for now I concluded that it isn't that straightforward since we would have to replace mod-internal functions. We would have to replace all functions in CoM which do any kind of non-trivial direct memory access using Ikarus, which iirc were quite a lot, though I haven't been able to compile a full list.

Additionally, any update to the mod then has the potential to break in OpenGothic, so it would likely require constant updates to the implementation.

A more general implementation would be better, I think. I'm trying to figure out a good solution looking at CoM. Some things are trivial (like memory allocation) while others seem very hard (like mocking the ZenGin class structures).

@Try
Copy link
Owner Author

Try commented Dec 27, 2022

Hi, @lmichaelis , thank for bumping this up.

I haven't been able to compile a full list.

OK, but can you go into a few examples to illustrate problematic cases?

A more general implementation would be better, I think

I was thinking about emulating memory-mapping-unit in engine, to mock ZenGin classes (at least to some extent) and implement only a few Ikarus api's. Basically implement layer that is close-most to DMA/Winapi and assume that rest will 'just work'

@lmichaelis
Copy link
Contributor

lmichaelis commented Dec 27, 2022

Some examples:

const int OCLOGMANAGER_PTR = 11191608;
func void LOG_MOVETOTOP(var string TOPICNAME) {
    LIST = _^(OCLOGMANAGER_PTR);
    NEWLISTPTR = LIST_CREATE(0);
    NEWLIST = _^(NEWLISTPTR);
    PREVLIST = _^(OCLOGMANAGER_PTR);
    WHILE(LIST.NEXT);
    LIST = _^(LIST.NEXT);
    if (LIST.DATA) {
        if (HLP_STRCMP(MEM_READSTRING(LIST.DATA), TOPICNAME)) {
            NEWLIST.DATA = LIST.DATA;
            PREVLIST.NEXT = LIST.NEXT;
        };
    };
    PREVLIST = _^(_@(0x5446));
    if ((NEWLIST.DATA) == (0)) {
        if ((GAME_RUNTIMECONFIG) != (TARGET_SHIPPING)) {
            MEMINT_FORCEERRORBOX = TRUE;
            MEM_SENDTOSPY(ZERR_TYPE_FAULT, CS3("B_LogEntry: Error! Probably topic '", TOPICNAME, "' does not exist. Probably B_LogEntry has been called before Log_CreateTopic."));
            MEMINT_FORCEERRORBOX = FALSE;
        };
    };
    END;
    LIST = _^(OCLOGMANAGER_PTR);
    NEWLIST.NEXT = LIST.NEXT;
    LIST.NEXT = NEWLISTPTR;
}

https://github.com/lmichaelis/tcom-decompilation/blob/ef9bd1034d3e44b28f3cd9173cf52122d6c9d84e/Source/Raw/115.d#L11-L37

func void TORCHLOADFIX_CHECKTORCH() {
    if (!(HLP_ISVALIDNPC(HERO))) {
        return;
    };
    PTR = TORCH_GETSLOTITEM();
    if (PTR) {
        ITM = _^(PTR);
        if ((HLP_GETINSTANCEID(ITM)) == (0x87b7)) {
            TORCHLOADFIX_GIVETORCH = TRUE;
        };
    };
    if ((!(PTR)) || ((HLP_GETINSTANCEID(ITM)) != (0x87b7))) {
        TORCHLOADFIX_GIVETORCH = FALSE;
    };
}

(and more) https://github.com/lmichaelis/tcom-decompilation/blob/ef9bd1034d3e44b28f3cd9173cf52122d6c9d84e/Source/Raw/343.d#L94-L108

func int CATINV_NEXTNONACTIVEITEM(var int LIST, var int MAX) {
    I = 0;
    WHILE((LIST) && ((I) < (MAX)));
    L = _^(LIST);
    if (HLP_IS_OCITEM(L.DATA)) {
        ITM = _^(L.DATA);
        if (((ITM.FLAGS) & (ITEM_ACTIVE)) != (ITEM_ACTIVE)) {
            BREAK;
        };
        I += 1;
    };
    LIST = L.NEXT;
    END;
    return I;
}

(and more) https://github.com/lmichaelis/tcom-decompilation/blob/ef9bd1034d3e44b28f3cd9173cf52122d6c9d84e/Source/Raw/99.d#L1-L15

instance ITGR_MEATFRIED(C_ITEM) {
    NAME = FOODNAME_MEATFRIED;
    DESCRIPTION = NAME;
    HP = _@(ITEMGROUP_MEAT[0]);
    VALUE = MAX_IG_MEATFRIED;
}

instance ITGR_VEGETABLE(C_ITEM) {
    NAME = FOODNAME_VEGETABLES;
    DESCRIPTION = NAME;
    HP = _@(ITEMGROUP_VEGETABLE[0]);
    VALUE = MAX_IG_VEGETABLE;
}

https://github.com/lmichaelis/tcom-decompilation/blob/ef9bd1034d3e44b28f3cd9173cf52122d6c9d84e/Source/Raw/181.d#L26-L38

There are a lot more direct uses of _^, _@s and _@ everywhere in CoM. I believe it would be very hard to accurately map everything the mod might access.

This is why we can't easily just replace Ikarus and LeGo functions since usage of these _^ etc. requires a direct memory access routine to be present.

@Try
Copy link
Owner Author

Try commented Dec 27, 2022

I believe it would be very hard to accurately map everything the mod might access.

As mentioned there is a compatibility class Mem32 to simulate Win32 memory subsystem. It's conceptually similar to capture-replay in Vulkan (extension to reproduce VA, in tools).
For global stuff, like OCLOGMANAGER_PTR, memory region should be pinned upfront, with proxy c-structure or with callback(TODO).
For runtime objects, like items, they should be reflected in this heap, like:

ptr32_t at = mem.alloc(sizeof(phoenix::c_item)); // allocate fake region
mem.pin(at, this->hitem.get()); // pin it to real c++ memory
...
mem.free(at); // done

With this setup, any invalid access should be trapped in phenix (you already do have debug message there, right?) and raised to engine level, so mem can handle raw-pointer access.

@hellozyemlya
Copy link

Looks like that most of the functions can be replaced entirely(like log_movetotop). Others - some array access, which can be implemented relatively easy.

IDK if maintenance is a problem, I don't think that CoM will be changed drastically, and others actively developed mods most likely will be glad to use normal open-sourced engine and implement their features without messing around with zengin(I may be wrong, assuming how many old(and school as well) persons in gothic modding community).

Sorry if that is an offtopic.

@Try
Copy link
Owner Author

Try commented Dec 28, 2022

@hellozyemlya

  • AFAIK log_movetotop is CoM function and replacing all non-conformat in all mods is definitely not the way to go.
  • If function is part of library(Ikarus), then we can make native version in exceptional cases
  • In general case, providing environment(fake VA), so lowest level stuff, like _@ and _^ can work is preferable way

implement their features without messing around with zengin

Yes, but we still quite far away from point, when opengothic is expected to be main platform to run the game

@Try
Copy link
Owner Author

Try commented Jan 30, 2023

Done more KoM testing today:

[phoenix] vm: internal exception: illegal mutable access of const symbol WIN_GETLASTERROR.CALL
[zspy]: Could not load function from library KmLib.dll! Please reinstall application or contact with technical support. Error code: 0 func name: InitializeGamestart<<< (This is a preliminary printing variant, use MEM_InitAll to get neat 'Q:' prefixed messages.) >>>

This is a bad news, because we can't really emulate *.dll for them :/

@Elgcahlxukuth
Copy link

Elgcahlxukuth commented Jan 31, 2023

This is a bad news, because we can't really emulate *.dll for them :/

I failed to check the size of compiled Gothic scripts of KoM (files seem 0 bytes in my installation of the game), so cannot compare to the size of .dll. Maybe you will be able to do so, or maybe contacting the devs of KoM would be a good idea. What I'm getting to is, perhaps the part of KoM functionality that has been placed in .dll is relatively small in compare to the .d scripts they created. In such a case, perhaps it would be relatively small effort to translate the .dll part to something that OpenGothic can handle. For example, if OpenGothic introduces API for modders (I think I saw this being planned in the future), like LUA scripts or whatever, then maybe KoM devs or anyone could translate the .dll to OpenGothic API.

I think there could be more mods that are created partly in .d and prtly in external code that is injected to Gothic process with Ikarus. Once you introduce some modern API for moders to OpenGothic, perhaps it would be good idea to also introduce something to your dedalus VM that allows to inject scripts/code written in the API. So that .d and API can be integrated to some point. That might make it easier to switch Ikarus based mods to OpenGothic. Not sure if that makes perfect sense...

Btw. I'm curious how KoM injects the .dll code to Gothic process. I understand Ikarus is able to make Gothic execute x86 code from any memory address, but how do they load DLL code to a memory space available to Gothic? Is it also done with Ikarus, like copying bytes from file to memory?

@Try
Copy link
Owner Author

Try commented Jan 31, 2023

. What I'm getting to is, perhaps the part of KoM functionality that has been placed in .dll is relatively small in compare

Well, I can tell you exactly what is there:

_KMLIB_GAMESERVICES_UNLOCKACHIEVEMENT_PTR = KMLIB_GETPROCADDRESS("GameServices_UnlockAchievement");
_KMLIB_GAMESERVICES_GETSTAT_PTR = KMLIB_GETPROCADDRESS("GameServices_GetStat");
_KMLIB_GAMESERVICES_INCREMENTSTAT_PTR = KMLIB_GETPROCADDRESS("GameServices_IncrementStat");
_KMLIB_MUSICSYSTEM_OVERRIDETRACK_PTR = KMLIB_GETPROCADDRESS("MusicSystem_OverrideTrack");
_KMLIB_MUSICSYSTEM_DISABLETRACKOVERRIDE_PTR = KMLIB_GETPROCADDRESS("MusicSystem_DisableTrackOverride");
_KMLIB_INITIALIZEMENU_PTR = KMLIB_GETPROCADDRESS("InitializeMenu");
_KMLIB_INITIALIZEGAMESTART_PTR = KMLIB_GETPROCADDRESS("InitializeGamestart");
_KMLIB_INITIALIZEALWAYS_PTR = KMLIB_GETPROCADDRESS("InitializeAlways");

So, steam related stuff + music

Btw. I'm curious how KoM injects the .dll code to Gothic process.

Ikarus enables calls to C++ functions, so just call LoadLibrary + GetProcAddress, form winapi

For example, if OpenGothic introduces API for modders (I think I saw this being planned in the future), like LUA scripts or whatever,

This is far term stuff. introducing something like LUA as a scripting language will create segmentation in mods community, what is not good.

Try added a commit that referenced this issue Jul 25, 2023
@Try Try pinned this issue Jul 30, 2023
Try added a commit that referenced this issue Aug 1, 2023
@Try
Copy link
Owner Author

Try commented Aug 1, 2023

Some up-to date progress:
изображение

Can launch Chronicles of Myrtana, with only 7-screens of errors in log.
One big misery at this point is wrong start-point (story starts fine, if move player to the ship manually).

Only early game is playable, dialog and cut-scene when we have to leave ship does not start.

Shorten log:

GPU = NVIDIA GeForce RTX 3070 Laptop GPU
Depth format = Depth32F Shadow format = Depth16
[phoenix] vm: accessing member "OCNPC.FOCUS_VOB" without an instance set
DMA mod detected: Ikarus
DMA mod detected: LeGo
mem_ptrtoinst: address is null
mem_readint:  address translation failure: 0x000000000000120c
mem_ptrtoinst: address is null
mem_readint:  address translation failure: 0x00000000008c2958
mem_ptrtoinst: address is null
mem_replacefunc: MEM_WRITESTATARR -> MEMINT_WRITESTATARR
mem_replacefunc: MEM_READSTATARR -> MEMINT_READSTATARR
mem_replacefunc: MEM_WRITESTATSTRINGARR -> MEMINT_WRITESTATSTRINGARR
mem_replacefunc: MEM_READSTATSTRINGARR -> MEMINT_READSTATSTRINGARR
[zpy]: This will be the last Ikarus message printed with PrintDebug and prefix 'U: Skript:'. Subsequent messages will be printed with prefix 'Q:'.
mem_replacefunc: MEM_SENDTOSPY -> MEMINT_SENDTOSPY_IMPLEMENTATION
[zpy]: Ikarus log functions now print in colour with prefix 'Q:'.
mem_replacefunc: MEM_PRINTSTACKTRACE -> MEMINT_PRINTSTACKTRACE_IMPLEMENTATION
mem_replacefunc: REPEAT -> MEMINT_REPEAT
TODO: mem_getfuncidbyoffset 0
suppress LoadLibrary: KmLib.dll
suppress GetProcAddress: InitializeMenu
suppress LoadLibrary: KERNEL32.DLL
suppress GetProcAddress: VirtualProtect
mem_readint:  address translation failure: 0x000000000042ebe3
mem_writeint: address translation failure: 0x000000000042ebe3
mem_readint:  address translation failure: 0x000000000042ebe4
mem_writeint: address translation failure: 0x000000000042ebe4
mem_readint:  address translation failure: 0x000000000042ebe5
mem_writeint: address translation failure: 0x000000000042ebe5
mem_readint:  address translation failure: 0x000000000042ebe6
mem_writeint: address translation failure: 0x000000000042ebe6
mem_readint:  address translation failure: 0x000000000042ebe7
mem_writeint: address translation failure: 0x000000000042ebe7
not implemented call [HookEngineF] (0x000000000044e056 -> ZERROR_SETTARGET_HOOK)
[zpy]: 
[zpy]: Time:               00
[zpy]: Log level:          -1
[zpy]: 
not implemented call [PERC_SETRANGE]
[phoenix] world: parsing object [MeshAndBsp % 0 0]
[phoenix] bsp_tree: parsing chunk c000
[phoenix] bsp_tree: parsing chunk c010
[phoenix] bsp_tree: parsing chunk c040
[phoenix] bsp_tree: parsing chunk c045
[phoenix] bsp_tree: parsing chunk c050
[phoenix] bsp_tree: parsing chunk c0ff
[phoenix] mesh: 1 bytes remaining in section b020
[phoenix] world: parsing object [VobTree % 0 0]
[phoenix] world: parsing object [WayNet % 0 0]
[phoenix] world: parsing object [EndMarker % 0 0]
unable to load sound fx: SVM_54_DEAD
unable to load mesh "FIRE_MEDIUM.pfx"
unable to load sound fx: ENV_NIGHT_TONSOFINSECTS
unable to load sound fx: ENV_NIGHT_TONSOFINSECTS
[phoenix] model_script: unexpected value for event_tag_type: "		"
[phoenix] model_script: 4 bytes remaining in section f5a3
addNpc: invalid waypoint
addNpc: invalid waypoint
addNpc: invalid waypoint
[zpy]: 
[zpy]: Game version:       21
[zpy]: Build version:      128023
[zpy]: Save version:       1
[zpy]: Target:             0
[zpy]: Args:               
[zpy]: 
[zpy]: LeGo 2.7.0 wird initialisiert.
[zpy]: Flags: PRINTS HOOKENGINE AI_FUNCTION TRIALOGE DIALOGGESTURES FRAMEFUNCTIONS RANDOM SAVES PERMMEM ANIM8 VIEW INTERFACE BARS TIMER EVENTHANDLER SPRITE CONSOLECOMMANDS BUFFS RENDER
not implemented call [HookEngineF] (0x0000000000757ab1 -> _AI_FUNCTION_EVENT)
not implemented call [HookEngineF] (0x00000000006c86a0 -> _FF_HOOK)
not implemented call [HookEngineF] (0x00000000006cfdf8 -> _CC_HOOK)
not implemented call [CC_Register] (LeGo -> CC_LEGO)
not implemented call [HookEngineF] (0x00000000006c7290 -> _LEGO_CHANGELEVELHOOKBEGIN)
not implemented call [HookEngineF] (0x00000000006c7acb -> _LEGO_CHANGELEVELHOOKEND)
not implemented call [HookEngineF] (0x0000000000439105 -> _BW_SAVEGAME)
not implemented call [HookEngineF] (0x000000000042a040 -> _BR_SETSELECTEDSLOT)
not implemented call [HookEngineF] (0x000000000064df20 -> _SPRITE_DORENDER)
not implemented call [_RENDER_INIT]
not implemented call [HookEngineF] (0x00000000006c30f0 -> _BAR_UPDATERESOLUTION)
[zpy]: Reset ALL the handles!
[zpy]: Resetting done.
TODO: LeGo-LOCALS.
[zpy]: LeGo 2.7.0 wurde erfolgreich initialisiert.
suppress GetProcAddress: InitializeGamestart
not implemented call [HookEngineF] (0x0000000000762250 -> LOCKINVENTORY)
...
not implemented call [HookEngineF] (0x0000000000723ee2 -> HANDLE_SETPROPERPICKLOCKSTRLEN)
mem_copybytes: address translation failure: 0x0000000000000001
not implemented call [HookEngineF] (0x0000000000745fa6 -> _FIXEQUIPBESTWEAPONS)
...
not implemented call [HookEngineF] (0x000000000069d415 -> CATINV_DELAYMOBCAMERA)
TODO: mem_gothoptexists(GAME, invCatChangeOnLast)
TODO: mem_setgothopt(GAME, invCatChangeOnLast, 0)
TODO: mem_gothoptexists(GAME, invCatG1Mode)
TODO: mem_setgothopt(GAME, invCatG1Mode, 0)
not implemented call [HookEngineF] (0x0000000000735fab -> OCNPC__DROPUNCONSCIOUS_HOOK)
...
mem_writeint: address translation failure: 0x0000000000734f7a
not implemented call [HookEngineF] (0x0000000000734f4d -> OCNPC__GETNEXTENEMY_REPLACEHOOK)
...
not implemented call [HookEngineF] (0x00000000006c36db -> HIDEFOCUSFORPARTYMEMBERS_UPDATESTATUSREPLACEHOOK4)
TODO: mem_gothoptexists(KEYS, keyTorch)
TODO: mem_setgothopt(KEYS, keyTorch, )
mem_readint:  address translation failure: 0x0000000000000009
mem_copybytes: address translation failure: 0x0000000000000000
...
mem_writeint: address translation failure: 0x00000000000cb408
mem_ptrtoinst: address is null
mem_ptrtoinst: address is null
not implemented call [HookEngineF] (0x00000000006c30f0 -> _BOSSUI_UPDATERESOLUTION)
not implemented call [HookEngineF] (0x00000000006407c2 -> ONZONEMUSICCHANGEDHOOK)
not implemented call [HookEngineF] (0x000000000042926a -> APPLYSOMESETTINGSEND_HOOK)
mem_writeint: address translation failure: 0x0000000000832a34
mem_writeint: address translation failure: 0x00000000008a8ac0
not implemented call [HookEngineF] (0x00000000006c5250 -> TORCHLOADFIX_CHECKTORCH)
mem_readint:  address translation failure: 0x0000000000486a3b
...
mem_writeint: address translation failure: 0x000000000048732a
not implemented call [HookEngineF] (0x00000000007a9240 -> ZCVIEW__DIALOGMESSAGECXY_HOOK)
...
not implemented call [HookEngineF] (0x0000000000437d9f -> PATCHSAVEGAMEWORLD_HOOK)
mem_readint:  address translation failure: 0x000000000050a049
mem_writeint: address translation failure: 0x000000000050a049
suppress GetProcAddress: GameServices_UnlockAchievement
suppress GetProcAddress: GameServices_GetStat
suppress GetProcAddress: GameServices_IncrementStat
suppress GetProcAddress: InitializeAlways
mem_readint:  address translation failure: 0x0000000000ab070c
...
mem_writeint: address translation failure: 0x0000000000000011
[start of stacktrace]
[phoenix] ------- CALL STACK (MOST RECENT CALL FIRST) -------
[phoenix] in MEM_PRINTSTACKTRACE at 0x833
[phoenix] in MEMINT_HANDLEERROR at 0x833
[phoenix] in MEM_ERROR at 0x89c
[phoenix] in _LIST_ERR at 0x117f4
[phoenix] in _LIST_ERRPTR at 0x1180f
[phoenix] in LIST_FORFS at 0x12308
[phoenix] in INIT_QUIVERS_ALWAYS at 0x29f5c
[phoenix] in INIT_FEATURES_ALWAYS at 0x6618ad
[phoenix] in INIT_ALWAYS at 0x66197c
[phoenix] in INIT_GLOBAL at 0x661c24
[phoenix] ------- STACK (MOST RECENT PUSH FIRST) -------
[end of stacktrace]
[zpy]: 
[phoenix] vm: accessing member "C_ITEM.HP" without an instance set
[phoenix] vm: accessing member "C_ITEM.HP" without an instance set
[phoenix] vm: accessing member "C_ITEM.HP" without an instance set
[phoenix] vm: accessing member "C_ITEM.HP" without an instance set
mem_writeint: address translation failure: 0x0000000000ab0888
suppress GetProcAddress: MusicSystem_DisableTrackOverride
[phoenix] vm: accessing member "C_NPC.AIVAR" without an instance set
[phoenix] vm: accessing member "C_NPC.AIVAR" without an instance set
[phoenix] vm: accessing member "C_NPC.AIVAR" without an instance set
[phoenix] vm: accessing member "C_NPC.AIVAR" without an instance set
[phoenix] vm: accessing member "C_NPC.AIVAR" without an instance set
[phoenix] vm: accessing member "C_NPC.AIVAR" without an instance set
[phoenix] vm: accessing member "C_NPC.AIVAR" without an instance set
[phoenix] vm: accessing member "C_NPC.AIVAR" without an instance set
[start of stacktrace]
[phoenix] ------- CALL STACK (MOST RECENT CALL FIRST) -------
[phoenix] in MEM_PRINTSTACKTRACE at 0x833
[phoenix] in MEMINT_HANDLEERROR at 0x833
[phoenix] in MEM_WARN at 0x8b2
[phoenix] in APPLYHOUSEWALLTEXTURE at 0x1d59a2
[phoenix] in INIT_FEATURES_ALWAYS at 0x66190c
[phoenix] in INIT_ALWAYS at 0x66197c
[phoenix] in INIT_GLOBAL at 0x661c24
[phoenix] ------- STACK (MOST RECENT PUSH FIRST) -------
[end of stacktrace]
[zpy]: ApplyHouseWallTexture: Null ptr
[zpy]: New game started
mem_writeint: address translation failure: 0x00000000004b20f0
not implemented call [WLD_SETOBJECTROUTINE]
unable to recognize mobsi{, }
unable to recognize mobsi{, }
unable to recognize mobsi{MOBNAME_KM_SIGN_COLLAPSED_MINE_DO_NOT_PASS, }

Try added a commit that referenced this issue Aug 6, 2023
Try added a commit that referenced this issue Aug 12, 2023
@Try Try mentioned this issue Aug 19, 2023
Try added a commit that referenced this issue Aug 19, 2023
* CoM: initialization routine in progress

#231

* CoM: loops and more support for 32-bit memory

#231

* ikarus/lego in progress

#231

* build

* fix LeGo::create

* phoenix::func

#231

* build

* update mem-traps

* mem arrays

* fix for LeGo::create

* opaque_memory support

#231

* memory_instance in progress

* transient_instance update

* rework start-points

* Update phoenix
@Try
Copy link
Owner Author

Try commented Aug 19, 2023

finally fix start-point determination:
изображение

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request mod
Projects
None yet
Development

No branches or pull requests

4 participants