mirror of
				https://github.com/coop-deluxe/sm64coopdx.git
				synced 2025-10-30 08:01:01 +00:00 
			
		
		
		
	Enforce function pointers types in dynos
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				Build coop / build-linux (push) Has been cancelled
				
			
		
			
				
	
				Build coop / build-steamos (push) Has been cancelled
				
			
		
			
				
	
				Build coop / build-windows-opengl (push) Has been cancelled
				
			
		
			
				
	
				Build coop / build-windows-directx (push) Has been cancelled
				
			
		
			
				
	
				Build coop / build-macos-arm (push) Has been cancelled
				
			
		
			
				
	
				Build coop / build-macos-intel (push) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	Build coop / build-linux (push) Has been cancelled
				
			Build coop / build-steamos (push) Has been cancelled
				
			Build coop / build-windows-opengl (push) Has been cancelled
				
			Build coop / build-windows-directx (push) Has been cancelled
				
			Build coop / build-macos-arm (push) Has been cancelled
				
			Build coop / build-macos-intel (push) Has been cancelled
				
			geo layouts -> geo_* functions only behaviors -> bhv_* functions only level scripts -> lvl_* functions only other -> no function allowed thanks maniscat for reporting the issue
This commit is contained in:
		
							parent
							
								
									7405ae7244
								
							
						
					
					
						commit
						b671458f81
					
				
					 9 changed files with 765 additions and 669 deletions
				
			
		|  | @ -17,6 +17,10 @@ extern "C" { | |||
| #define LUA_VAR_CODE    (u32) 0x5641554C | ||||
| #define TEX_REF_CODE    (u32) 0x52584554 | ||||
| 
 | ||||
| #define FUNCTION_GEO    1 | ||||
| #define FUNCTION_BHV    2 | ||||
| #define FUNCTION_LVL    3 | ||||
| 
 | ||||
| #define MOD_PACK_INDEX 99 | ||||
| 
 | ||||
| //
 | ||||
|  | @ -864,10 +868,13 @@ const char*      DynOS_Builtin_Tex_GetFromData(const Texture* aData); | |||
| const char*      DynOS_Builtin_Tex_GetNameFromFileName(const char* aDataName); | ||||
| const struct BuiltinTexInfo* DynOS_Builtin_Tex_GetInfoFromName(const char* aDataName); | ||||
| const struct BuiltinTexInfo* DynOS_Builtin_Tex_GetInfoFromData(const Texture* aData); | ||||
| const void*      DynOS_Builtin_Func_GetFromName(const char* aDataName); | ||||
| const void*      DynOS_Builtin_Func_GetFromIndex(s32 aIndex); | ||||
| const char *     DynOS_Builtin_Func_GetNameFromIndex(s64 aIndex); | ||||
| s32              DynOS_Builtin_Func_GetIndexFromData(const void* aData); | ||||
| const void*      DynOS_Builtin_Func_GetFromName(const char* aDataName, u8 aFuncType); | ||||
| const void*      DynOS_Builtin_Func_GetFromIndex(s32 aIndex, u8 aFuncType); | ||||
| const char *     DynOS_Builtin_Func_GetNameFromIndex(s32 aIndex, u8 aFuncType); | ||||
| s32              DynOS_Builtin_Func_GetIndexFromData(const void* aData, u8 aFuncType); | ||||
| String           DynOS_Builtin_Func_CheckMisuse(s32 aIndex, u8 aFuncType); | ||||
| String           DynOS_Builtin_Func_CheckMisuse(const char* aDataName, u8 aFuncType); | ||||
| String           DynOS_Builtin_Func_CheckMisuse(const void* aData, u8 aFuncType); | ||||
| const Gfx *      DynOS_Builtin_Gfx_GetFromName(const char *aDataName); | ||||
| const char *     DynOS_Builtin_Gfx_GetFromData(const Gfx *aData); | ||||
| 
 | ||||
|  | @ -1100,8 +1107,8 @@ void DynOS_Vtx_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Vtx> *aNode); | |||
| void DynOS_Vtx_Load(BinFile *aFile, GfxData *aGfxData); | ||||
| 
 | ||||
| void DynOS_Pointer_Lua_Write(BinFile* aFile, u32 index, GfxData* aGfxData); | ||||
| void DynOS_Pointer_Write(BinFile* aFile, const void* aPtr, GfxData* aGfxData); | ||||
| void *DynOS_Pointer_Load(BinFile *aFile, GfxData *aGfxData, u32 aValue, u8* outFlags); | ||||
| void DynOS_Pointer_Write(BinFile* aFile, const void* aPtr, GfxData* aGfxData, u8 aFuncType); | ||||
| void *DynOS_Pointer_Load(BinFile *aFile, GfxData *aGfxData, u32 aValue, u8 aFuncType, u8* outFlags); | ||||
| 
 | ||||
| void DynOS_GfxDynCmd_Load(BinFile *aFile, GfxData *aGfxData); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1937,10 +1937,16 @@ static BehaviorScript ParseBehaviorScriptSymbolArgInternal(GfxData *aGfxData, Da | |||
|     } | ||||
| 
 | ||||
|     // Built-in functions
 | ||||
|     const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg.begin()); | ||||
|     const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg.begin(), FUNCTION_BHV); | ||||
|     if (_FunctionPtr != NULL) { | ||||
|         return (s64) _FunctionPtr; | ||||
|     } | ||||
|     String error = DynOS_Builtin_Func_CheckMisuse(_Arg.begin(), FUNCTION_BHV); | ||||
|     if (!error.Empty()) { | ||||
|         PrintDataError("  ERROR: %s", error.begin()); | ||||
|         *found = false; | ||||
|         return 0; | ||||
|     } | ||||
| 
 | ||||
|     // Built-in actors
 | ||||
|     auto builtinActor = DynOS_Builtin_Actor_GetFromName(_Arg.begin()); | ||||
|  | @ -2490,7 +2496,7 @@ static void DynOS_Bhv_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Behavior | |||
|     for (u32 i = 0; i != aNode->mSize; ++i) { | ||||
|         BehaviorScript *_Head = &aNode->mData[i]; | ||||
|         if (aGfxData->mPointerList.Find((void *) _Head) != -1) { | ||||
|             DynOS_Pointer_Write(aFile, (const void *) (*_Head), aGfxData); | ||||
|             DynOS_Pointer_Write(aFile, (const void *) (*_Head), aGfxData, FUNCTION_BHV); | ||||
|         } else if (aGfxData->mLuaPointerList.Find((void *) _Head) != -1) { | ||||
|             DynOS_Pointer_Lua_Write(aFile, *(u32 *)_Head, aGfxData); | ||||
|         } else { | ||||
|  | @ -2578,7 +2584,7 @@ static DataNode<BehaviorScript> *DynOS_Bhv_Load(BinFile *aFile, GfxData *aGfxDat | |||
|             break; | ||||
|         } | ||||
|         u32 _Value = aFile->Read<u32>(); | ||||
|         void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags); | ||||
|         void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, FUNCTION_BHV, &_Node->mFlags); | ||||
|         if (_Ptr) { | ||||
|             _Node->mData[i] = (uintptr_t) _Ptr; | ||||
|         } else { | ||||
|  |  | |||
|  | @ -105,10 +105,15 @@ static s64 ParseGeoSymbolArg(GfxData* aGfxData, DataNode<GeoLayout>* aNode, u64& | |||
|     } | ||||
| 
 | ||||
|     // Built-in functions
 | ||||
|     const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg.begin()); | ||||
|     const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg.begin(), FUNCTION_GEO); | ||||
|     if (_FunctionPtr != NULL) { | ||||
|         return (s64) _FunctionPtr; | ||||
|     } | ||||
|     String error = DynOS_Builtin_Func_CheckMisuse(_Arg.begin(), FUNCTION_GEO); | ||||
|     if (!error.Empty()) { | ||||
|         PrintDataError("  ERROR: %s", error.begin()); | ||||
|         return 0; | ||||
|     } | ||||
| 
 | ||||
|     // Constants
 | ||||
|     bool constantFound = false; | ||||
|  | @ -321,13 +326,18 @@ static void ParseGeoSymbol(GfxData* aGfxData, DataNode<GeoLayout>* aNode, GeoLay | |||
|         s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); | ||||
|         const String& _Arg1 = aNode->mTokens[aTokenIndex++]; | ||||
| 
 | ||||
|         const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg1.begin()); | ||||
|         const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg1.begin(), FUNCTION_GEO); | ||||
|         if (_FunctionPtr != NULL) { | ||||
|             aGfxData->mPointerList.Add(aHead + 1); | ||||
|             GeoLayout _Gl[] = { GEO_ASM(_Arg0, _FunctionPtr) }; | ||||
|             memcpy(aHead, _Gl, sizeof(_Gl)); | ||||
|             aHead += (sizeof(_Gl) / sizeof(_Gl[0])); | ||||
|         } else { | ||||
|             String error = DynOS_Builtin_Func_CheckMisuse(_Arg1.begin(), FUNCTION_GEO); | ||||
|             if (!error.Empty()) { | ||||
|                 PrintDataError("  ERROR: %s", error.begin()); | ||||
|                 return; | ||||
|             } | ||||
|             u32 _FuncIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 1, _Arg1); | ||||
|             GeoLayout _Gl[] = { GEO_ASM_EXT(_Arg0, _FuncIndex) }; | ||||
|             memcpy(aHead, _Gl, sizeof(_Gl)); | ||||
|  | @ -345,13 +355,18 @@ static void ParseGeoSymbol(GfxData* aGfxData, DataNode<GeoLayout>* aNode, GeoLay | |||
|         s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex); | ||||
|         const String& _Arg1 = aNode->mTokens[aTokenIndex++]; | ||||
| 
 | ||||
|         const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg1.begin()); | ||||
|         const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg1.begin(), FUNCTION_GEO); | ||||
|         if (_FunctionPtr != NULL) { | ||||
|             aGfxData->mPointerList.Add(aHead + 1); | ||||
|             GeoLayout _Gl[] = { GEO_SWITCH_CASE(_Arg0, _FunctionPtr) }; | ||||
|             memcpy(aHead, _Gl, sizeof(_Gl)); | ||||
|             aHead += (sizeof(_Gl) / sizeof(_Gl[0])); | ||||
|         } else { | ||||
|             String error = DynOS_Builtin_Func_CheckMisuse(_Arg1.begin(), FUNCTION_GEO); | ||||
|             if (!error.Empty()) { | ||||
|                 PrintDataError("  ERROR: %s", error.begin()); | ||||
|                 return; | ||||
|             } | ||||
|             u32 _FuncIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 1, _Arg1); | ||||
|             GeoLayout _Gl[] = { GEO_SWITCH_CASE_EXT(_Arg0, _FuncIndex) }; | ||||
|             memcpy(aHead, _Gl, sizeof(_Gl)); | ||||
|  | @ -471,7 +486,7 @@ void DynOS_Geo_Write(BinFile *aFile, GfxData *aGfxData, DataNode<GeoLayout> *aNo | |||
|     for (u32 i = 0; i != aNode->mSize; ++i) { | ||||
|         GeoLayout *_Head = &aNode->mData[i]; | ||||
|         if (aGfxData->mPointerList.Find((void *) _Head) != -1) { | ||||
|             DynOS_Pointer_Write(aFile, (const void *) (*_Head), aGfxData); | ||||
|             DynOS_Pointer_Write(aFile, (const void *) (*_Head), aGfxData, FUNCTION_GEO); | ||||
|         } else if (aGfxData->mLuaPointerList.Find((void *) _Head) != -1) { | ||||
|             DynOS_Pointer_Lua_Write(aFile, *(u32 *)_Head, aGfxData); | ||||
|         } else { | ||||
|  | @ -495,7 +510,7 @@ void DynOS_Geo_Load(BinFile *aFile, GfxData *aGfxData) { | |||
|     _Node->mData = New<GeoLayout>(_Node->mSize); | ||||
|     for (u32 i = 0; i != _Node->mSize; ++i) { | ||||
|         u32 _Value = aFile->Read<u32>(); | ||||
|         void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags); | ||||
|         void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, FUNCTION_GEO, &_Node->mFlags); | ||||
|         if (_Ptr) { | ||||
|             _Node->mData[i] = (uintptr_t) _Ptr; | ||||
|         } else { | ||||
|  |  | |||
|  | @ -1104,7 +1104,7 @@ void DynOS_Gfx_Write(BinFile *aFile, GfxData *aGfxData, DataNode<Gfx> *aNode) { | |||
|         Gfx *_Head = &aNode->mData[i]; | ||||
|         if (aGfxData->mPointerList.Find((void *) _Head) != -1) { | ||||
|             aFile->Write<u32>(_Head->words.w0); | ||||
|             DynOS_Pointer_Write(aFile, (const void *) _Head->words.w1, aGfxData); | ||||
|             DynOS_Pointer_Write(aFile, (const void *) _Head->words.w1, aGfxData, 0); | ||||
|         } else { | ||||
|             aFile->Write<u32>(_Head->words.w0); | ||||
|             aFile->Write<u32>(_Head->words.w1); | ||||
|  | @ -1127,7 +1127,7 @@ void DynOS_Gfx_Load(BinFile *aFile, GfxData *aGfxData) { | |||
|     for (u32 i = 0; i != _Node->mSize; ++i) { | ||||
|         u32 _WordsW0 = aFile->Read<u32>(); | ||||
|         u32 _WordsW1 = aFile->Read<u32>(); | ||||
|         void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _WordsW1, &_Node->mFlags); | ||||
|         void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _WordsW1, 0, &_Node->mFlags); | ||||
|         if (_Ptr) { | ||||
|             _Node->mData[i].words.w0 = (uintptr_t) _WordsW0; | ||||
|             _Node->mData[i].words.w1 = (uintptr_t) _Ptr; | ||||
|  |  | |||
|  | @ -409,10 +409,16 @@ static LevelScript ParseLevelScriptSymbolArgInternal(GfxData* aGfxData, DataNode | |||
|     } | ||||
| 
 | ||||
|     // Built-in functions
 | ||||
|     const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg.begin()); | ||||
|     const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg.begin(), FUNCTION_LVL); | ||||
|     if (_FunctionPtr != NULL) { | ||||
|         return (s64) _FunctionPtr; | ||||
|     } | ||||
|     String error = DynOS_Builtin_Func_CheckMisuse(_Arg.begin(), FUNCTION_LVL); | ||||
|     if (!error.Empty()) { | ||||
|         PrintDataError("  ERROR: %s", error.begin()); | ||||
|         *found = false; | ||||
|         return 0; | ||||
|     } | ||||
| 
 | ||||
|     bool constantFound = false; | ||||
|     s64 constantValue = DynOS_Lvl_ParseLevelScriptConstants(_Arg, &constantFound); | ||||
|  | @ -926,7 +932,7 @@ static void DynOS_Lvl_Write(BinFile* aFile, GfxData* aGfxData, DataNode<LevelScr | |||
|     for (u32 i = 0; i != aNode->mSize; ++i) { | ||||
|         LevelScript *_Head = &aNode->mData[i]; | ||||
|         if (aGfxData->mPointerList.Find((void *) _Head) != -1) { | ||||
|             DynOS_Pointer_Write(aFile, (const void *) (*_Head), aGfxData); | ||||
|             DynOS_Pointer_Write(aFile, (const void *) (*_Head), aGfxData, FUNCTION_LVL); | ||||
|         } else if (aGfxData->mLuaPointerList.Find((void *) _Head) != -1) { | ||||
|             DynOS_Pointer_Lua_Write(aFile, *(u32 *)_Head, aGfxData); | ||||
|         } else { | ||||
|  | @ -1055,7 +1061,7 @@ static DataNode<LevelScript>* DynOS_Lvl_Load(BinFile *aFile, GfxData *aGfxData) | |||
| 
 | ||||
|         bool requirePointer = DynOS_Lvl_Validate_RequirePointer(_Value); | ||||
| 
 | ||||
|         void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags); | ||||
|         void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, FUNCTION_LVL, &_Node->mFlags); | ||||
|         if (_Ptr) { | ||||
|             if (!requirePointer) { | ||||
|                 PrintError("Didn't expect a pointer while reading level script: %s, %u", _Node->mName.begin(), _Value); | ||||
|  |  | |||
|  | @ -64,7 +64,7 @@ void DynOS_MovtexQC_Write(BinFile* aFile, GfxData* aGfxData, DataNode<MovtexQC> | |||
|     aFile->Write<u32>(aNode->mSize); | ||||
|     for (u32 i = 0; i != aNode->mSize; ++i) { | ||||
|         aFile->Write<s16>(aNode->mData[i].id); | ||||
|         DynOS_Pointer_Write(aFile, (const void *) (aNode->mData[i].quadArraySegmented), aGfxData); | ||||
|         DynOS_Pointer_Write(aFile, (const void *) (aNode->mData[i].quadArraySegmented), aGfxData, 0); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -84,7 +84,7 @@ DataNode<MovtexQC>* DynOS_MovtexQC_Load(BinFile *aFile, GfxData *aGfxData) { | |||
|     for (u32 i = 0; i != _Node->mSize; ++i) { | ||||
|         _Node->mData[i].id = aFile->Read<s16>(); | ||||
|         u32 _Value = aFile->Read<u32>(); | ||||
|         void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags); | ||||
|         void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, 0, &_Node->mFlags); | ||||
|         _Node->mData[i].quadArraySegmented = (Movtex*)_Ptr; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -209,7 +209,7 @@ void DynOS_Pointer_Lua_Write(BinFile* aFile, u32 index, GfxData* aGfxData) { | |||
|     token.Write(aFile); | ||||
| } | ||||
| 
 | ||||
| void DynOS_Pointer_Write(BinFile* aFile, const void* aPtr, GfxData* aGfxData) { | ||||
| void DynOS_Pointer_Write(BinFile* aFile, const void* aPtr, GfxData* aGfxData, u8 aFuncType) { | ||||
| 
 | ||||
|     // NULL
 | ||||
|     if (!aPtr) { | ||||
|  | @ -229,10 +229,15 @@ void DynOS_Pointer_Write(BinFile* aFile, const void* aPtr, GfxData* aGfxData) { | |||
|     } | ||||
| 
 | ||||
|     // Built-in functions
 | ||||
|     s32 _GeoFunctionIndex = DynOS_Builtin_Func_GetIndexFromData(aPtr); | ||||
|     if (_GeoFunctionIndex != -1) { | ||||
|     s32 _FunctionIndex = DynOS_Builtin_Func_GetIndexFromData(aPtr, aFuncType); | ||||
|     if (_FunctionIndex != -1) { | ||||
|         aFile->Write<u32>(FUNCTION_CODE); | ||||
|         aFile->Write<s32>(_GeoFunctionIndex); | ||||
|         aFile->Write<s32>(_FunctionIndex); | ||||
|         return; | ||||
|     } | ||||
|     String error = DynOS_Builtin_Func_CheckMisuse(aPtr, aFuncType); | ||||
|     if (!error.Empty()) { | ||||
|         PrintDataError("  ERROR: %s", error.begin()); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|  | @ -451,7 +456,7 @@ static void *GetPointerFromData(GfxData *aGfxData, const String &aPtrName, u32 a | |||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| void *DynOS_Pointer_Load(BinFile *aFile, GfxData *aGfxData, u32 aValue, u8* outFlags) { | ||||
| void *DynOS_Pointer_Load(BinFile *aFile, GfxData *aGfxData, u32 aValue, u8 aFuncType, u8* outFlags) { | ||||
| 
 | ||||
|     // LUAV
 | ||||
|     if (aValue == LUA_VAR_CODE) { | ||||
|  | @ -469,13 +474,23 @@ void *DynOS_Pointer_Load(BinFile *aFile, GfxData *aGfxData, u32 aValue, u8* outF | |||
|     // FUNC
 | ||||
|     if (aValue == FUNCTION_CODE) { | ||||
|         s32 _FunctionIndex = aFile->Read<s32>(); | ||||
|         return (void*) DynOS_Builtin_Func_GetFromIndex(_FunctionIndex); | ||||
|         void *_FunctionPtr = (void*) DynOS_Builtin_Func_GetFromIndex(_FunctionIndex, aFuncType); | ||||
|         if (_FunctionPtr) { | ||||
|             return _FunctionPtr; | ||||
|         } | ||||
|         String error = DynOS_Builtin_Func_CheckMisuse(_FunctionIndex, aFuncType); | ||||
|         if (!error.Empty()) { | ||||
|             sys_fatal(error.begin()); | ||||
|             return NULL; | ||||
|         } | ||||
|         sys_fatal("Invalid function index: %d", _FunctionIndex); | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     // PNTR
 | ||||
|     if (aValue == POINTER_CODE) { | ||||
|         String _PtrName; _PtrName.Read(aFile); | ||||
|         u32   _PtrData = aFile->Read<u32>(); | ||||
|         u32 _PtrData = aFile->Read<u32>(); | ||||
|         return GetPointerFromData(aGfxData, _PtrName, _PtrData, outFlags); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -50,7 +50,7 @@ void DynOS_TexList_Write(BinFile* aFile, GfxData* aGfxData, DataNode<TexData*> * | |||
|         bool found = false; | ||||
|         for (auto& _Node : aGfxData->mTextures) { | ||||
|             if (_Node->mData == aNode->mData[i]) { | ||||
|                 DynOS_Pointer_Write(aFile, (const void *) (_Node), aGfxData); | ||||
|                 DynOS_Pointer_Write(aFile, (const void *) (_Node), aGfxData, 0); | ||||
|                 found = true; | ||||
|                 break; | ||||
|             } | ||||
|  | @ -76,7 +76,7 @@ DataNode<TexData*>* DynOS_TexList_Load(BinFile *aFile, GfxData *aGfxData) { | |||
|     _Node->mData = New<TexData*>(_Node->mSize); | ||||
|     for (u32 i = 0; i != _Node->mSize; ++i) { | ||||
|         u32 _Value = aFile->Read<u32>(); | ||||
|         void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags); | ||||
|         void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, 0, &_Node->mFlags); | ||||
|         if (_Ptr == NULL) { | ||||
|             PrintDataError("Could not read texture in texlist"); | ||||
|         } else { | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 PeachyPeachSM64
						PeachyPeachSM64