diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index b6711ae5..e036519b 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2166,115 +2166,213 @@ egg/prim/eggAssert.cpp: .bss start:0x80674C60 end:0x80674D68 egg/gfx/eggCamera.cpp: - .text start:0x8049C5C0 end:0x8049CAC0 + .text start:0x8049C5C0 end:0x8049CAC8 + .data start:0x8056ED00 end:0x8056ED60 + .sdata2 start:0x8057F3B8 end:0x8057F3C8 egg/gfx/eggPalette.cpp: .text start:0x8049CAD0 end:0x8049CB44 egg/gfx/eggTexture.cpp: .text start:0x8049CB50 end:0x8049CFE4 + .sdata2 start:0x8057F3C8 end:0x8057F3E0 -egg/gfx/eggUnk1.cpp: +egg/gfx/eggAnalizeDL.cpp: .text start:0x8049CFF0 end:0x8049D7C0 + .data start:0x8056ED60 end:0x8056ED70 + .sdata2 start:0x8057F3E0 end:0x8057F408 egg/gfx/eggCapTexture.cpp: - .text start:0x8049D7C0 end:0x8049D9D0 + .text start:0x8049D7C0 end:0x8049DA28 + .rodata start:0x804FBA30 end:0x804FBA48 + .data start:0x8056ED70 end:0x8056ED80 + .sdata2 start:0x8057F410 end:0x8057F418 + .sbss2 start:0x8057FFC0 end:0x8057FFC8 egg/gfx/eggCpuTexture.cpp: .text start:0x8049DA30 end:0x8049EC94 + .data start:0x8056ED80 end:0x8056EDA0 + .sdata2 start:0x8057F418 end:0x8057F440 egg/gfx/eggDrawGX.cpp: .text start:0x8049ECA0 end:0x804A0C24 .ctors start:0x804DB998 end:0x804DB99C + .rodata start:0x804FBA60 end:0x804FBC58 + .data start:0x8056EDA0 end:0x8056EE60 + .sdata start:0x80574F18 end:0x80574F20 + .sbss start:0x80576808 end:0x80576810 + .sdata2 start:0x8057F440 end:0x8057F538 + .bss start:0x80674D68 end:0x80674E48 egg/gfx/eggDrawPathBase.cpp: .text start:0x804A0C30 end:0x804A0E98 + .data start:0x8056EE60 end:0x8056EEB0 -egg/gfx/eggDrawPathUnk1.cpp: +egg/gfx/eggDrawPathBloom.cpp: .text start:0x804A0EA0 end:0x804A29B8 + .data start:0x8056EEB0 end:0x8056EF28 + .sdata2 start:0x8057F538 end:0x8057F580 egg/gfx/eggDrawPathDOF.cpp: .text start:0x804A29C0 end:0x804A4BE8 + .rodata start:0x804FBC70 end:0x804FBC88 + .data start:0x8056EF28 end:0x8056EFA0 + .sdata2 start:0x8057F580 end:0x8057F5F8 -egg/gfx/eggDrawPathUnk2.cpp: +egg/gfx/eggDrawPathLightMap.cpp: .text start:0x804A4BF0 end:0x804A54E8 + .data start:0x8056EFA0 end:0x8056EFF0 + .sdata2 start:0x8057F5F8 end:0x8057F608 egg/gfx/eggFog.cpp: - .text start:0x804A54F0 end:0x804A5F60 + .text start:0x804A54F0 end:0x804A5A08 + .data start:0x8056EFF0 end:0x8056F010 + .sdata start:0x80574F20 end:0x80574F28 + .sdata2 start:0x8057F608 end:0x8057F618 + +egg/gfx/eggFogManager.cpp: + .text start:0x804A5A10 end:0x804A5F60 + .data start:0x8056F010 end:0x8056F030 egg/gfx/eggFrustum.cpp: .text start:0x804A5F60 end:0x804A6854 .ctors start:0x804DB99C end:0x804DB9A0 + .data start:0x8056F030 end:0x8056F048 + .sbss start:0x80576810 end:0x80576820 + .sdata2 start:0x8057F618 end:0x8057F63C egg/gfx/eggG3DUtility.cpp: .text start:0x804A6860 end:0x804A75B0 egg/gfx/eggGfxEngine.cpp: .text start:0x804A75B0 end:0x804A7744 + .data start:0x8056F048 end:0x8056F058 egg/gfx/eggGlobalDrawState.cpp: .text start:0x804A7750 end:0x804A7814 .ctors start:0x804DB9A0 end:0x804DB9A4 + .sbss start:0x80576838 end:0x80576848 + .bss start:0x80674E48 end:0x80674E78 egg/gfx/eggGXUtility.cpp: .text start:0x804A7820 end:0x804A7BC0 + .sdata2 start:0x8057F640 end:0x8057F678 egg/gfx/eggIScnProc.cpp: .text start:0x804A7BC0 end:0x804A7F7C + .data start:0x8056F058 end:0x8056F068 -egg/gfx/eggLight.cpp: - .text start:0x804A7F80 end:0x804AB24C +egg/gfx/eggLightManager.cpp: + .text start:0x804A7F80 end:0x804A9808 + .data start:0x8056F068 end:0x8056F098 + .sdata start:0x80574F28 end:0x80574F30 + .sdata2 start:0x8057F678 end:0x8057F690 + +egg/gfx/eggLightObject.cpp: + .text start:0x804A9810 end:0x804AB24C + .rodata start:0x804FBC88 end:0x804FBC98 + .data start:0x8056F098 end:0x8056F0B8 + .sdata start:0x80574F30 end:0x80574F38 + .sdata2 start:0x8057F690 end:0x8057F6C0 egg/gfx/eggLightTexture.cpp: .text start:0x804AB250 end:0x804AD448 .ctors start:0x804DB9A4 end:0x804DB9A8 + .rodata start:0x804FBC98 end:0x804FBD08 + .data start:0x8056F0B8 end:0x8056F0F0 + .sdata start:0x80574F38 end:0x80574F48 + .sbss start:0x80576848 end:0x80576860 + .sdata2 start:0x8057F6C0 end:0x8057F708 + .bss start:0x80674E78 end:0x80674EF0 egg/gfx/eggLightTextureMgr.cpp: .text start:0x804AD450 end:0x804AE644 + .data start:0x8056F0F0 end:0x8056F110 + .sdata2 start:0x8057F708 end:0x8057F720 egg/gfx/eggModelEx.cpp: .text start:0x804AE650 end:0x804AEC20 + .rodata start:0x804FBD08 end:0x804FBD50 + .data start:0x8056F110 end:0x8056F120 + .sdata start:0x80574F48 end:0x80574F60 egg/gfx/eggPostEffectBase.cpp: .text start:0x804AEC20 end:0x804AF4B4 + .data start:0x8056F120 end:0x8056F170 + .sbss start:0x80576860 end:0x80576870 + .sdata2 start:0x8057F720 end:0x8057F750 + .bss start:0x80674EF0 end:0x80674F00 egg/gfx/eggPostEffectBlur.cpp: .text start:0x804AF4C0 end:0x804AFC04 + .data start:0x8056F170 end:0x8056F190 + .sdata2 start:0x8057F750 end:0x8057F788 -egg/gfx/eggPostEffectUnk1.cpp: +egg/gfx/eggPostEffectBlurGather.cpp: .text start:0x804AFC10 end:0x804B0098 + .data start:0x8056F190 end:0x8056F1AC + .sdata2 start:0x8057F788 end:0x8057F798 egg/gfx/eggPostEffectUnk2.cpp: .text start:0x804B00A0 end:0x804B0AA4 + .rodata start:0x804FBD50 end:0x804FBD88 + .data start:0x8056F1B0 end:0x8056F1D0 + .sdata2 start:0x8057F798 end:0x8057F7C4 egg/gfx/eggPostEffectMask.cpp: .text start:0x804B0AB0 end:0x804B0F60 + .data start:0x8056F1D0 end:0x8056F1F0 + .sdata2 start:0x8057F7C8 end:0x8057F7D0 egg/gfx/eggPostEffectMaskDOF.cpp: .text start:0x804B0F60 end:0x804B1BE8 + .rodata start:0x804FBD88 end:0x804FBDA0 + .data start:0x8056F1F0 end:0x8056F20C + .sdata2 start:0x8057F7D0 end:0x8057F80C + .sbss2 start:0x8057FFC8 end:0x8057FFCC egg/gfx/eggPostEffectSimple.cpp: .text start:0x804B1BF0 end:0x804B1E58 + .data start:0x8056F210 end:0x8056F230 + .sdata2 start:0x8057F810 end:0x8057F818 egg/gfx/eggScreen.cpp: .text start:0x804B1E60 end:0x804B30B4 .ctors start:0x804DB9A8 end:0x804DB9AC + .data start:0x8056F230 end:0x8056F268 + .sbss start:0x80576870 end:0x80576898 + .sdata2 start:0x8057F818 end:0x8057F840 + .bss start:0x80674F00 end:0x80674F88 egg/gfx/eggScreenEffectBase.cpp: .text start:0x804B30C0 end:0x804B30EC .ctors start:0x804DB9AC end:0x804DB9B0 + .data start:0x8056F268 end:0x8056F278 + .bss start:0x80674F88 end:0x80675010 egg/gfx/eggScreenEffectBlur.cpp: .text start:0x804B30F0 end:0x804B3D98 + .data start:0x8056F278 end:0x8056F2B0 + .sdata2 start:0x8057F840 end:0x8057F868 egg/gfx/eggStateEfb.cpp: .text start:0x804B3DA0 end:0x804B460C + .sdata start:0x80574F60 end:0x80574F68 + .sbss start:0x80576898 end:0x805768A0 + .sdata2 start:0x8057F868 end:0x8057F890 + .bss start:0x80675010 end:0x806750A0 egg/gfx/eggStateGX.cpp: .text start:0x804B4610 end:0x804B53EC + .rodata start:0x804FBDA0 end:0x804FBE08 + .sbss start:0x805768A0 end:0x805768B8 + .sdata2 start:0x8057F890 end:0x8057F8B0 + .bss start:0x806750A0 end:0x80675190 egg/gfx/eggTextureBuffer.cpp: .text start:0x804B53F0 end:0x804B59DC + .data start:0x8056F2B0 end:0x8056F2C0 + .sbss start:0x805768B8 end:0x805768D8 egg/audio/eggAudioArcPlayerMgr.cpp: .text start:0x804B59E0 end:0x804B641C diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 9fb3a09b..d14c421f 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -610,7 +610,7 @@ fn_80019780 = .text:0x80019780; // type:function size:0x6C fn_800197F0 = .text:0x800197F0; // type:function size:0x5C fn_80019850 = .text:0x80019850; // type:function size:0x58 drawXlu__Q23d3d7XluProcFv = .text:0x800198B0; // type:function size:0x17C -EGG__CapTexture____dt = .text:0x80019A30; // type:function size:0x58 +__dt__Q23EGG10CapTextureFv = .text:0x80019A30; // type:function size:0x58 fn_80019A90 = .text:0x80019A90; // type:function size:0x4C fn_80019AE0 = .text:0x80019AE0; // type:function size:0x98 fn_80019B80 = .text:0x80019B80; // type:function size:0x8 @@ -677,8 +677,8 @@ fn_8001D0C0 = .text:0x8001D0C0; // type:function size:0x35C fn_8001D420 = .text:0x8001D420; // type:function size:0x58 fn_8001D480 = .text:0x8001D480; // type:function size:0x58 fn_8001D4E0 = .text:0x8001D4E0; // type:function size:0x6C -fn_8001D550 = .text:0x8001D550; // type:function size:0x40 -fn_8001D590 = .text:0x8001D590; // type:function size:0x40 +__dt__Q23EGG14PostEffectBlurFv = .text:0x8001D550; // type:function size:0x40 +__dt__Q23EGG14PostEffectBaseFv = .text:0x8001D590; // type:function size:0x40 fn_8001D5D0 = .text:0x8001D5D0; // type:function size:0x30 fn_8001D600 = .text:0x8001D600; // type:function size:0x38 fn_8001D640 = .text:0x8001D640; // type:function size:0xE4 @@ -720,7 +720,7 @@ fn_8001F570 = .text:0x8001F570; // type:function size:0x70 fn_8001F5E0 = .text:0x8001F5E0; // type:function size:0x5C fn_8001F640 = .text:0x8001F640; // type:function size:0x40 fn_8001F680 = .text:0x8001F680; // type:function size:0x70 -fn_8001F6F0 = .text:0x8001F6F0; // type:function size:0x4 +ExecCallback_CALC_MAT__Q34nw4r3g3d15IScnObjCallbackFQ44nw4r3g3d6ScnObj6TimingPQ34nw4r3g3d6ScnObjUlPv = .text:0x8001F6F0; // type:function size:0x4 fn_8001F700 = .text:0x8001F700; // type:function size:0xA8 fn_8001F7B0 = .text:0x8001F7B0; // type:function size:0x64 sprintf__15SizedString<32>FPCce = .text:0x8001F820; // type:function size:0xD0 @@ -9780,8 +9780,8 @@ fn_80171B70 = .text:0x80171B70; // type:function size:0x5C fn_80171BD0 = .text:0x80171BD0; // type:function size:0xA90 fn_80172660 = .text:0x80172660; // type:function size:0x4C fn_801726B0 = .text:0x801726B0; // type:function size:0x218 -EGG__DrawPathBase____dt = .text:0x801728D0; // type:function size:0x5C -fn_80172930 = .text:0x80172930; // type:function size:0x40 +__dt__Q23EGG12DrawPathBaseFv = .text:0x801728D0; // type:function size:0x5C +__dt__Q23EGG16ScreenEffectBaseFv = .text:0x80172930; // type:function size:0x40 fn_80172970 = .text:0x80172970; // type:function size:0xB4 fn_80172A30 = .text:0x80172A30; // type:function size:0x40 fn_80172A70 = .text:0x80172A70; // type:function size:0x10DC @@ -9790,14 +9790,14 @@ fn_80173FA0 = .text:0x80173FA0; // type:function size:0x128 fn_801740D0 = .text:0x801740D0; // type:function size:0x60 fn_80174130 = .text:0x80174130; // type:function size:0x1D8 fn_80174310 = .text:0x80174310; // type:function size:0x5F0 -fn_80174900 = .text:0x80174900; // type:function size:0x4 +internalResetForDraw__Q23EGG12DrawPathBaseFv = .text:0x80174900; // type:function size:0x4 fn_80174910 = .text:0x80174910; // type:function size:0x8 -fn_80174920 = .text:0x80174920; // type:function size:0x4 +setMaterialInternal__Q23EGG14PostEffectBaseFv = .text:0x80174920; // type:function size:0x4 fn_80174930 = .text:0x80174930; // type:function size:0x8 fn_80174940 = .text:0x80174940; // type:function size:0x14 fn_80174960 = .text:0x80174960; // type:function size:0x8 -fn_80174970 = .text:0x80174970; // type:function size:0x8 -fn_80174980 = .text:0x80174980; // type:function size:0x8 +@8@scnProcDraw__Q23EGG12DrawPathBaseFUs = .text:0x80174970; // type:function size:0x8 scope:weak +@20@ExecCallback_CALC_VIEW__Q23EGG12DrawPathBaseFQ44nw4r3g3d6ScnObj6TimingPQ34nw4r3g3d6ScnObjUlPv = .text:0x80174980; // type:function size:0x8 scope:weak fn_80174990 = .text:0x80174990; // type:function size:0x8 fn_801749A0 = .text:0x801749A0; // type:function size:0x8 fn_801749B0 = .text:0x801749B0; // type:function size:0x8 @@ -10523,7 +10523,7 @@ __ct__11dStageMgr_cFv = .text:0x80197730; // type:function size:0x39C fn_80197AD0 = .text:0x80197AD0; // type:function size:0x4C fn_80197B20 = .text:0x80197B20; // type:function size:0x54 __dt__Q23EGG6ScreenFv = .text:0x80197B80; // type:function size:0x40 -fn_80197BC0 = .text:0x80197BC0; // type:function size:0x40 +__dt__Q23EGG7FrustumFv = .text:0x80197BC0; // type:function size:0x40 fn_80197C00 = .text:0x80197C00; // type:function size:0x64 fn_80197C70 = .text:0x80197C70; // type:function size:0x5C __dt__22sFPhase<11dStageMgr_c>Fv = .text:0x80197CD0; // type:function size:0x58 @@ -10535,7 +10535,7 @@ fn_80197F50 = .text:0x80197F50; // type:function size:0x5C fn_80197FB0 = .text:0x80197FB0; // type:function size:0x5C fn_80198010 = .text:0x80198010; // type:function size:0x60 fn_80198070 = .text:0x80198070; // type:function size:0x64 -EGG__DrawPathShadowVolume____dt = .text:0x801980E0; // type:function size:0x60 +__dt__Q23EGG16DrawPathLightMapFv = .text:0x801980E0; // type:function size:0x60 scope:weak fn_80198140 = .text:0x80198140; // type:function size:0x58 fn_801981A0 = .text:0x801981A0; // type:function size:0x58 fn_80198200 = .text:0x80198200; // type:function size:0x58 @@ -10646,7 +10646,7 @@ addArcnToStage = .text:0x8019BF80; // type:function size:0x17C ArcnObjnManager__doLoad = .text:0x8019C100; // type:function size:0x64 ArcnObjnManager__checkLoaded = .text:0x8019C170; // type:function size:0x44 fn_8019C1C0 = .text:0x8019C1C0; // type:function size:0x44 -fn_8019C210 = .text:0x8019C210; // type:function size:0x8 +getNumStep__Q23EGG16DrawPathLightMapCFv = .text:0x8019C210; // type:function size:0x8 scope:weak fn_8019C220 = .text:0x8019C220; // type:function size:0x4 fn_8019C230 = .text:0x8019C230; // type:function size:0x4 fn_8019C240 = .text:0x8019C240; // type:function size:0x4 @@ -10654,8 +10654,8 @@ fn_8019C250 = .text:0x8019C250; // type:function size:0x4 fn_8019C260 = .text:0x8019C260; // type:function size:0x4 fn_8019C270 = .text:0x8019C270; // type:function size:0x4 fn_8019C280 = .text:0x8019C280; // type:function size:0x4 -fn_8019C290 = .text:0x8019C290; // type:function size:0x8 -fn_8019C2A0 = .text:0x8019C2A0; // type:function size:0x8 +getNumStep__Q23EGG13DrawPathBloomCFv = .text:0x8019C290; // type:function size:0x8 +getNumStep__Q23EGG11DrawPathDOFCFv = .text:0x8019C2A0; // type:function size:0x8 build__27sFStateFct_c<11dStageMgr_c>FRC12sStateIDIf_c = .text:0x8019C2B0; // type:function size:0x60 dispose__27sFStateFct_c<11dStageMgr_c>FRP10sStateIf_c = .text:0x8019C310; // type:function size:0xC initialize__24sFState_c<11dStageMgr_c>Fv = .text:0x8019C320; // type:function size:0x1C @@ -10673,10 +10673,10 @@ nextPhase__22sFPhase<11dStageMgr_c>Fv = .text:0x8019C420; // type:function size: hasReachedEnd__22sFPhase<11dStageMgr_c>CFv = .text:0x8019C430; // type:function size:0x2C fn_8019C460 = .text:0x8019C460; // type:function size:0x10 fn_8019C470 = .text:0x8019C470; // type:function size:0x10 -fn_8019C480 = .text:0x8019C480; // type:function size:0x10 -fn_8019C490 = .text:0x8019C490; // type:function size:0x8 +SetBinary__Q23EGG19IBinaryFPCv = .text:0x8019C480; // type:function size:0x10 +GetBinarySize__Q23EGG28IBinaryCFv = .text:0x8019C490; // type:function size:0x8 fn_8019C4A0 = .text:0x8019C4A0; // type:function size:0x10 -fn_8019C4B0 = .text:0x8019C4B0; // type:function size:0x8 +GetBinarySize__Q23EGG30IBinaryCFv = .text:0x8019C4B0; // type:function size:0x8 fn_8019C4C0 = .text:0x8019C4C0; // type:function size:0x10 finalizeState__26sFStateID_c<11dStageMgr_c>CFR11dStageMgr_c = .text:0x8019C4D0; // type:function size:0x30 executeState__26sFStateID_c<11dStageMgr_c>CFR11dStageMgr_c = .text:0x8019C500; // type:function size:0x30 @@ -10686,15 +10686,15 @@ __dt__26sFStateID_c<11dStageMgr_c>Fv = .text:0x8019CDE0; // type:function size:0 isSameName__26sFStateID_c<11dStageMgr_c>CFPCc = .text:0x8019CE40; // type:function size:0x88 fn_8019CED0 = .text:0x8019CED0; // type:function size:0x8 fn_8019CEE0 = .text:0x8019CEE0; // type:function size:0x8 -fn_8019CEF0 = .text:0x8019CEF0; // type:function size:0x8 -fn_8019CF00 = .text:0x8019CF00; // type:function size:0x8 -fn_8019CF10 = .text:0x8019CF10; // type:function size:0x8 +@24@SetBinaryInner__Q23EGG11DrawPathDOFFRCQ33EGG28IBinary3Bin = .text:0x8019CEF0; // type:function size:0x8 +@24@SetBinaryInner__Q23EGG11DrawPathDOFFRCQ33EGG28IBinary3BinRCQ33EGG28IBinary3Binf = .text:0x8019CF00; // type:function size:0x8 +@24@GetBinaryInner__Q23EGG11DrawPathDOFCFPQ33EGG28IBinary3Bin = .text:0x8019CF10; // type:function size:0x8 fn_8019CF20 = .text:0x8019CF20; // type:function size:0x8 fn_8019CF30 = .text:0x8019CF30; // type:function size:0x8 fn_8019CF40 = .text:0x8019CF40; // type:function size:0x8 -fn_8019CF50 = .text:0x8019CF50; // type:function size:0x8 -fn_8019CF60 = .text:0x8019CF60; // type:function size:0x8 -fn_8019CF70 = .text:0x8019CF70; // type:function size:0x8 +@24@SetBinaryInner__Q23EGG13DrawPathBloomFRCQ33EGG30IBinary3Bin = .text:0x8019CF50; // type:function size:0x8 +@24@SetBinaryInner__Q23EGG13DrawPathBloomFRCQ33EGG30IBinary3BinRCQ33EGG30IBinary3Binf = .text:0x8019CF60; // type:function size:0x8 +@24@GetBinaryInner__Q23EGG13DrawPathBloomCFPQ33EGG30IBinary3Bin = .text:0x8019CF70; // type:function size:0x8 fn_8019CF80 = .text:0x8019CF80; // type:function size:0x8 fn_8019CF90 = .text:0x8019CF90; // type:function size:0x8 fn_8019CFA0 = .text:0x8019CFA0; // type:function size:0x8 @@ -11262,8 +11262,8 @@ getNewStateID__86sStateMgr_c<17dLytCursorStick_c,20sStateMethodUsr_FI_c,12sFStat getStateID__86sStateMgr_c<17dLytCursorStick_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x801BD230; // type:function size:0x10 getOldStateID__86sStateMgr_c<17dLytCursorStick_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x801BD240; // type:function size:0x10 dCsGame_c_classInit__Fv = .text:0x801BD250; // type:function size:0x30 -fn_801BD280 = .text:0x801BD280; // type:function size:0x8C -fn_801BD310 = .text:0x801BD310; // type:function size:0x40 +__ct__17CsGameConfigMaybeFv = .text:0x801BD280; // type:function size:0x8C +__dt__17CsGameConfigMaybeFv = .text:0x801BD310; // type:function size:0x40 __ct__9dCsGame_cFv = .text:0x801BD350; // type:function size:0x4CC fn_801BD820 = .text:0x801BD820; // type:function size:0x40 fn_801BD860 = .text:0x801BD860; // type:function size:0x40 @@ -22396,15 +22396,15 @@ GXInitFogAdjTable = .text:0x803C0CA0; // type:function size:0x160 GXSetFogRangeAdj = .text:0x803C0E00; // type:function size:0x110 GXSetBlendMode = .text:0x803C0F10; // type:function size:0x50 GXSetColorUpdate = .text:0x803C0F60; // type:function size:0x2C -FUN_803c0f90 = .text:0x803C0F90; // type:function size:0x14 +GXGetColorUpdate = .text:0x803C0F90; // type:function size:0x14 GXSetAlphaUpdate = .text:0x803C0FB0; // type:function size:0x2C -FUN_803c0fe0 = .text:0x803C0FE0; // type:function size:0x14 +GXGetAlphaUpdate = .text:0x803C0FE0; // type:function size:0x14 GXSetZMode = .text:0x803C1000; // type:function size:0x34 GXSetZCompLoc = .text:0x803C1040; // type:function size:0x30 GXSetPixelFmt = .text:0x803C1070; // type:function size:0xA8 -FUN_803c1120 = .text:0x803C1120; // type:function size:0x20 +GXGetPixelFmt = .text:0x803C1120; // type:function size:0x20 GXSetDither = .text:0x803C1140; // type:function size:0x2C -FUN_803c1170 = .text:0x803C1170; // type:function size:0x14 +GXGetDither = .text:0x803C1170; // type:function size:0x14 GXSetDstAlpha = .text:0x803C1190; // type:function size:0x30 GXSetFieldMask = .text:0x803C11C0; // type:function size:0x34 GXSetFieldMode = .text:0x803C1200; // type:function size:0x70 @@ -26420,36 +26420,36 @@ load__Q23EGG7PaletteFv = .text:0x8049CB00; // type:function size:0x44 __dt__Q23EGG7TextureFv = .text:0x8049CB50; // type:function size:0x78 storeTIMG__Q23EGG7TextureFPCQ23EGG7ResTIMGUc = .text:0x8049CBD0; // type:function size:0x184 attachPalette__Q23EGG7TextureFPQ23EGG7Palette = .text:0x8049CD60; // type:function size:0x40 -initTexObj__Q23EGG7TextureFvl = .text:0x8049CDA0; // type:function size:0xF0 +initTexObj__Q23EGG7TextureFv = .text:0x8049CDA0; // type:function size:0xF0 initTexObj__Q23EGG7TextureF7_GXTlut = .text:0x8049CE90; // type:function size:0xF8 load__Q23EGG7TextureF11_GXTexMapID = .text:0x8049CF90; // type:function size:0x54 -FUN_8049cff0 = .text:0x8049CFF0; // type:function size:0x12C -FUN_8049d120 = .text:0x8049D120; // type:function size:0x590 -FUN_8049d6b0 = .text:0x8049D6B0; // type:function size:0xB8 -FUN_8049d770 = .text:0x8049D770; // type:function size:0x8 -FUN_8049d780 = .text:0x8049D780; // type:function size:0x40 +__ct__Q23EGG9AnalizeDLFQ34nw4r3g3d6ResShp = .text:0x8049CFF0; // type:function size:0x12C +step__Q23EGG9AnalizeDLFv = .text:0x8049D120; // type:function size:0x590 +init__Q23EGG9AnalizeDLFv = .text:0x8049D6B0; // type:function size:0xB8 +getVtxResult__Q23EGG9AnalizeDLCFv = .text:0x8049D770; // type:function size:0x8 +__dt__Q23EGG9AnalizeDLFv = .text:0x8049D780; // type:function size:0x40 configure__Q23EGG10CapTextureFv = .text:0x8049D7C0; // type:function size:0x7C capture__Q23EGG10CapTextureFUsUsbi = .text:0x8049D840; // type:function size:0x184 -FUN_8049d9d0 = .text:0x8049D9D0; // type:function size:0x58 -calcColorGradient_EGG_CpuTexture_8049da30 = .text:0x8049DA30; // type:function size:0x188 -makeGradient_EGG_CpuTexture_8049dbc0 = .text:0x8049DBC0; // type:function size:0x450 +fn_8049D9D0__Q23EGG10CapTextureFUc = .text:0x8049D9D0; // type:function size:0x58 +calcColorGradient__Q23EGG27@unnamed@eggCpuTexture_cpp@FR8_GXColorRC8_GXColorRC8_GXColorf = .text:0x8049DA30; // type:function size:0x188 +makeGradient__Q23EGG27@unnamed@eggCpuTexture_cpp@FiP8_GXColoriiiRC8_GXColorRC8_GXColor = .text:0x8049DBC0; // type:function size:0x450 __ct__Q23EGG10CpuTextureFv = .text:0x8049E010; // type:function size:0x44 __ct__Q23EGG10CpuTextureFUsUs9_GXTexFmt = .text:0x8049E060; // type:function size:0x40 -__ct__Q23EGG10CpuTextureFP9_GXTexObj = .text:0x8049E0A0; // type:function size:0xB0 +__ct__Q23EGG10CpuTextureFPC9_GXTexObj = .text:0x8049E0A0; // type:function size:0xB0 __dt__Q23EGG10CpuTextureFv = .text:0x8049E150; // type:function size:0x70 configure__Q23EGG10CpuTextureFv = .text:0x8049E1C0; // type:function size:0xC setBuffer__Q23EGG10CpuTextureFPv = .text:0x8049E1D0; // type:function size:0x1C load__Q23EGG10CpuTextureCF11_GXTexMapID = .text:0x8049E1F0; // type:function size:0x3C getTexObj__Q23EGG10CpuTextureCFP9_GXTexObj = .text:0x8049E230; // type:function size:0x80 flush__Q23EGG10CpuTextureCFv = .text:0x8049E2B0; // type:function size:0x4C -buildHeader_EGG_CpuTexture_8049e300 = .text:0x8049E300; // type:function size:0x84 -fillNormalMapSphere__EGG_CpuTexture_8049e390 = .text:0x8049E390; // type:function size:0x1BC -fillGradient_EGG_CpuTexture_8049e550 = .text:0x8049E550; // type:function size:0x3A8 +buildHeader__Q23EGG10CpuTextureCFv = .text:0x8049E300; // type:function size:0x84 +fillNormalMapSphere__Q23EGG10CpuTextureFff = .text:0x8049E390; // type:function size:0x1BC +fillGradient__Q23EGG10CpuTextureFiiUsUsRC8_GXColorRC8_GXColorbb = .text:0x8049E550; // type:function size:0x3A8 alloc__Q23EGG10CpuTextureFPQ23EGG4Heap = .text:0x8049E900; // type:function size:0x84 allocWithHeaderDebug__Q23EGG10CpuTextureFPQ23EGG4Heap = .text:0x8049E990; // type:function size:0xA8 allocate__Q23EGG10CpuTextureFPQ23EGG4Heap = .text:0x8049EA40; // type:function size:0x4 setColor__Q23EGG10CpuTextureFUsUs8_GXColor = .text:0x8049EA50; // type:function size:0x10C -getColor__Q23EGG10CpuTextureFUsUs = .text:0x8049EB60; // type:function size:0x134 +getColor__Q23EGG10CpuTextureCFUsUs = .text:0x8049EB60; // type:function size:0x134 DrawQuadNormal__23@unnamed@eggDrawGX_cpp@FUcUcUcUcUc = .text:0x8049ECA0; // type:function size:0x28 DrawQuadLineStripNormal__23@unnamed@eggDrawGX_cpp@FUcUcUcUcUc = .text:0x8049ECD0; // type:function size:0x7C DrawCircleYPolygonFan__23@unnamed@eggDrawGX_cpp@FRCQ34nw4r4math5MTX34fUs = .text:0x8049ED50; // type:function size:0x318 @@ -26460,8 +26460,8 @@ BeginDrawLine__Q23EGG6DrawGXFQ33EGG6DrawGX12ColorChannelQ33EGG6DrawGX5ZMode = .t BeginDrawCircleZ__Q23EGG6DrawGXFQ33EGG6DrawGX12ColorChannelQ33EGG6DrawGX5ZMode = .text:0x8049F1C0; // type:function size:0x78 BeginDrawQuad__Q23EGG6DrawGXFQ33EGG6DrawGX12ColorChannelQ33EGG6DrawGX5ZModeQ33EGG6DrawGX5Blendbb = .text:0x8049F240; // type:function size:0xDC BeginDrawScreen__Q23EGG6DrawGXFbbb = .text:0x8049F320; // type:function size:0xE0 -DrawLineStrip__Q23EGG6DrawGXFPCQ23EGG8Vector3fUs7GXColorUc = .text:0x8049F400; // type:function size:0x1EC -DrawLine__Q23EGG6DrawGXFPCQ23EGG8Vector3fUs7GXColorUc = .text:0x8049F5F0; // type:function size:0x1EC +DrawLine__Q23EGG6DrawGXFPCQ23EGG8Vector3fUs8_GXColorUc = .text:0x8049F400; // type:function size:0x1EC +DrawLineStrip__Q23EGG6DrawGXFPCQ23EGG8Vector3fUs8_GXColorUc = .text:0x8049F5F0; // type:function size:0x1EC ClearEfb__Q23EGG6DrawGXFRCQ34nw4r4math5MTX34bbb8_GXColorb = .text:0x8049F7E0; // type:function size:0x264 ResetMaterial__Q23EGG6DrawGXFQ33EGG6DrawGX12ColorChannel = .text:0x8049FA50; // type:function size:0x64 SetMat_ColorChannel__Q23EGG6DrawGXFQ33EGG6DrawGX12ColorChannel = .text:0x8049FAC0; // type:function size:0xD8 @@ -26476,50 +26476,50 @@ CreateDisplayList__Q23EGG6DrawGXFPQ23EGG4Heap = .text:0x804A02E0; // type:functi DrawDL__Q23EGG6DrawGXFQ33EGG6DrawGX2DLRCQ34nw4r4math5MTX348_GXColor = .text:0x804A0AE0; // type:function size:0x88 SetZMode__Q23EGG6DrawGXFQ33EGG6DrawGX5ZMode = .text:0x804A0B70; // type:function size:0x20 SetBlendMode__Q23EGG6DrawGXFQ33EGG6DrawGX5Blend = .text:0x804A0B90; // type:function size:0x24 -DrawDLWorld__Q23EGG6DrawGXFQ33EGG6DrawGX2DLRCQ23EGG9Matrix34f7GXColor = .text:0x804A0BC0; // type:function size:0x5C +DrawDLWorld__Q23EGG6DrawGXFQ33EGG6DrawGX2DLRCQ23EGG9Matrix34f8_GXColor = .text:0x804A0BC0; // type:function size:0x5C __sinit_\eggDrawGX_cpp = .text:0x804A0C20; // type:function size:0x4 scope:local __ct__Q23EGG12DrawPathBaseFv = .text:0x804A0C30; // type:function size:0x58 createScnProc__Q23EGG12DrawPathBaseFP12MEMAllocator = .text:0x804A0C90; // type:function size:0x1B0 ExecCallback_CALC_VIEW__Q23EGG12DrawPathBaseFQ44nw4r3g3d6ScnObj6TimingPQ34nw4r3g3d6ScnObjUlPv = .text:0x804A0E40; // type:function size:0x20 scnProcDraw__Q23EGG12DrawPathBaseFUs = .text:0x804A0E60; // type:function size:0x20 -@8@__dt__Q23EGG12DrawPathBaseFv = .text:0x804A0E80; // type:function size:0x8 -@20@__dt__Q23EGG12DrawPathBaseFv = .text:0x804A0E90; // type:function size:0x8 -FUN_804a0ea0 = .text:0x804A0EA0; // type:function size:0x188 -FUN_804a1030 = .text:0x804A1030; // type:function size:0x40 -FUN_804a1070 = .text:0x804A1070; // type:function size:0x40 -FUN_804a10b0 = .text:0x804A10B0; // type:function size:0x40 -FUN_804a10f0 = .text:0x804A10F0; // type:function size:0x60 -FUN_804a1150 = .text:0x804A1150; // type:function size:0x21C -FUN_804a1370 = .text:0x804A1370; // type:function size:0x7A4 -FUN_804a1b20 = .text:0x804A1B20; // type:function size:0x53C -FUN_804a2060 = .text:0x804A2060; // type:function size:0x1D4 -FUN_804a2240 = .text:0x804A2240; // type:function size:0x714 +@8@__dt__Q23EGG12DrawPathBaseFv = .text:0x804A0E80; // type:function size:0x8 scope:weak +@20@__dt__Q23EGG12DrawPathBaseFv = .text:0x804A0E90; // type:function size:0x8 scope:weak +__ct__Q23EGG13DrawPathBloomFv = .text:0x804A0EA0; // type:function size:0x188 +__dt__Q23EGG14PostEffectMaskFv = .text:0x804A1030; // type:function size:0x40 +__dt__Q23EGG20PostEffectBlurGatherFv = .text:0x804A1070; // type:function size:0x40 +__dt__Q23EGG16PostEffectSimpleFv = .text:0x804A10B0; // type:function size:0x40 +__dt__Q23EGG13DrawPathBloomFv = .text:0x804A10F0; // type:function size:0x60 +internalResetForDraw__Q23EGG13DrawPathBloomFv = .text:0x804A1150; // type:function size:0x21C +internalDraw__Q23EGG13DrawPathBloomFUs = .text:0x804A1370; // type:function size:0x7A4 +SetBinaryInner__Q23EGG13DrawPathBloomFRCQ33EGG30IBinary3Bin = .text:0x804A1B20; // type:function size:0x53C +GetBinaryInner__Q23EGG13DrawPathBloomCFPQ33EGG30IBinary3Bin = .text:0x804A2060; // type:function size:0x1D4 +SetBinaryInner__Q23EGG13DrawPathBloomFRCQ33EGG30IBinary3BinRCQ33EGG30IBinary3Binf = .text:0x804A2240; // type:function size:0x714 FUN_804a2960 = .text:0x804A2960; // type:function size:0x28 -fn_804A2990 = .text:0x804A2990; // type:function size:0x8 -fn_804A29A0 = .text:0x804A29A0; // type:function size:0x8 -fn_804A29B0 = .text:0x804A29B0; // type:function size:0x8 -EGG__DrawPathDOF____ct = .text:0x804A29C0; // type:function size:0x164 -EGG__DrawPathDOF____dt = .text:0x804A2B30; // type:function size:0x104 -fn_804A2C40 = .text:0x804A2C40; // type:function size:0x40 -fn_804A2C80 = .text:0x804A2C80; // type:function size:0x9C -FUN_804a2d20 = .text:0x804A2D20; // type:function size:0x324 -FUN_804a3050 = .text:0x804A3050; // type:function size:0xCC -FUN_804a3120 = .text:0x804A3120; // type:function size:0x9A4 -EGG__DrawPathDOF__internalDraw = .text:0x804A3AD0; // type:function size:0x648 +@8@__dt__Q23EGG13DrawPathBloomFv = .text:0x804A2990; // type:function size:0x8 +@20@__dt__Q23EGG13DrawPathBloomFv = .text:0x804A29A0; // type:function size:0x8 +@24@__dt__Q23EGG13DrawPathBloomFv = .text:0x804A29B0; // type:function size:0x8 +__ct__Q23EGG11DrawPathDOFFv = .text:0x804A29C0; // type:function size:0x164 +__dt__Q23EGG11DrawPathDOFFv = .text:0x804A2B30; // type:function size:0x104 +__dt__Q23EGG17PostEffectMaskDOFFv = .text:0x804A2C40; // type:function size:0x40 +execute__Q23EGG11DrawPathDOFFv = .text:0x804A2C80; // type:function size:0x9C +internalResetForDraw__Q23EGG11DrawPathDOFFv = .text:0x804A2D20; // type:function size:0x324 +internalDraw__Q23EGG11DrawPathDOFFUs = .text:0x804A3050; // type:function size:0xCC +internalDrawVariant01__Q23EGG11DrawPathDOFFUs = .text:0x804A3120; // type:function size:0x9A4 +internalDrawVariant2__Q23EGG11DrawPathDOFFUs = .text:0x804A3AD0; // type:function size:0x648 FUN_804a4120 = .text:0x804A4120; // type:function size:0x224 FUN_804a4350 = .text:0x804A4350; // type:function size:0xDC -EGG__DrawPathDOF__SetBinaryInner = .text:0x804A4430; // type:function size:0x238 -EGG__DrawPathDOF__GetBinaryInner = .text:0x804A4670; // type:function size:0xD8 -EGG__DrawPathDOF__SetBinaryInner2 = .text:0x804A4750; // type:function size:0x464 -EGG__DrawPathDOF___8_dt = .text:0x804A4BC0; // type:function size:0x8 -EGG__DrawPathDOF___20_dt = .text:0x804A4BD0; // type:function size:0x8 -EGG__DrawPathDOF___24_dt = .text:0x804A4BE0; // type:function size:0x8 -EGG__DrawPathShadowVolume____ct = .text:0x804A4BF0; // type:function size:0x7C -FUN_804a4c70 = .text:0x804A4C70; // type:function size:0x3C -EGG__DrawPathShadowVolume__internalDraw = .text:0x804A4CB0; // type:function size:0x7B4 -FUN_804a5470 = .text:0x804A5470; // type:function size:0x5C -EGG__DrawPathShadowVolume__8__dt = .text:0x804A54D0; // type:function size:0x8 -EGG__DrawPathShadowVolume__20__dt = .text:0x804A54E0; // type:function size:0x8 +SetBinaryInner__Q23EGG11DrawPathDOFFRCQ33EGG28IBinary3Bin = .text:0x804A4430; // type:function size:0x238 +GetBinaryInner__Q23EGG11DrawPathDOFCFPQ33EGG28IBinary3Bin = .text:0x804A4670; // type:function size:0xD8 +SetBinaryInner__Q23EGG11DrawPathDOFFRCQ33EGG28IBinary3BinRCQ33EGG28IBinary3Binf = .text:0x804A4750; // type:function size:0x464 +@8@__dt__Q23EGG11DrawPathDOFFv = .text:0x804A4BC0; // type:function size:0x8 +@20@__dt__Q23EGG11DrawPathDOFFv = .text:0x804A4BD0; // type:function size:0x8 +@24@__dt__Q23EGG11DrawPathDOFFv = .text:0x804A4BE0; // type:function size:0x8 +__ct__Q23EGG16DrawPathLightMapFv = .text:0x804A4BF0; // type:function size:0x7C +internalResetForDraw__Q23EGG16DrawPathLightMapFv = .text:0x804A4C70; // type:function size:0x3C +internalDraw__Q23EGG16DrawPathLightMapFUs = .text:0x804A4CB0; // type:function size:0x7B4 +freeTextureBuffers__Q23EGG16DrawPathLightMapFv = .text:0x804A5470; // type:function size:0x5C +@8@__dt__Q23EGG16DrawPathLightMapFv = .text:0x804A54D0; // type:function size:0x8 scope:weak +@20@__dt__Q23EGG16DrawPathLightMapFv = .text:0x804A54E0; // type:function size:0x8 scope:weak GetBinaryType__Q23EGG19IBinaryFv = .text:0x804A54F0; // type:function size:0x8 GetVersion__Q23EGG19IBinaryFv = .text:0x804A5500; // type:function size:0x8 __ct__Q23EGG3FogFv = .text:0x804A5510; // type:function size:0x3C @@ -26561,15 +26561,15 @@ GetPerspectiveParam___Q23EGG7FrustumCFPf = .text:0x804A6520; // type:function si GetOrthographicParam___Q23EGG7FrustumCFPf = .text:0x804A65E0; // type:function size:0xE0 GetOrthographicParam___Q23EGG7FrustumCFPfPfPfPf = .text:0x804A66C0; // type:function size:0x164 __sinit_\eggFrustum_cpp = .text:0x804A6830; // type:function size:0x24 scope:local -FUN_804a6860 = .text:0x804A6860; // type:function size:0x104 -FUN_804a6970 = .text:0x804A6970; // type:function size:0x34 -FUN_804a69b0 = .text:0x804A69B0; // type:function size:0x1E8 -FUN_804a6ba0 = .text:0x804A6BA0; // type:function size:0x104 -FUN_804a6cb0 = .text:0x804A6CB0; // type:function size:0x104 -FUN_804a6dc0 = .text:0x804A6DC0; // type:function size:0x144 -SetTexture = .text:0x804A6F10; // type:function size:0x350 -FUN_804a7260 = .text:0x804A7260; // type:function size:0x31C -FUN_804a7580 = .text:0x804A7580; // type:function size:0x30 +create__Q23EGG10G3DUtilityFUlPQ23EGG4Heap = .text:0x804A6860; // type:function size:0x104 +defaultTexMtxFunc__Q23EGG10G3DUtilityFPQ34nw4r4math5MTX34ScSc = .text:0x804A6970; // type:function size:0x34 +setUpLightSet__Q23EGG10G3DUtilityFRQ34nw4r3g3d12LightSettingQ34nw4r3g3d9ResAnmScni = .text:0x804A69B0; // type:function size:0x1E8 +searchStringResNode__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMdlPCcbPQ33EGG10G3DUtility12SearchResulti = .text:0x804A6BA0; // type:function size:0x104 +searchStringResMat__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMdlPCcbPQ33EGG10G3DUtility12SearchResulti = .text:0x804A6CB0; // type:function size:0x104 +searchStringResTexPlttInfo__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMdlPCcbPQ33EGG10G3DUtility12SearchResulti = .text:0x804A6DC0; // type:function size:0x144 +SetTexture__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMatPQ44nw4r3g3d6ScnMdl15CopiedMatAccessPCcPC9_GXTexObjbPQ33EGG10G3DUtility16SetTextureResultii = .text:0x804A6F10; // type:function size:0x350 +ApplyLightMat__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMdlPCc = .text:0x804A7260; // type:function size:0x31C +BumpAlloc__Q23EGG10G3DUtilityFUlUl = .text:0x804A7580; // type:function size:0x30 __dt__Q33EGG9GfxEngine13ConfigurationFv = .text:0x804A75B0; // type:function size:0x40 __ct__Q33EGG9GfxEngine13ConfigurationFv = .text:0x804A75F0; // type:function size:0x154 beginDrawView__Q23EGG15GlobalDrawStateFUsRCQ34nw4r4math5MTX34RCQ23EGG6Screen = .text:0x804A7750; // type:function size:0x3C @@ -26579,13 +26579,13 @@ getTexMtxID__Q23EGG9GXUtilityFi = .text:0x804A7820; // type:function size:0xC setScaleOffsetPerspective__Q23EGG9GXUtilityFPfffff = .text:0x804A7830; // type:function size:0x40 getTexObj__Q23EGG9GXUtilityFP9_GXTexObjRCQ23EGG7ResTIMG = .text:0x804A7870; // type:function size:0x100 getTexObj__Q23EGG9GXUtilityFP9_GXTexObjQ34nw4r3g3d6ResTex14_GXTexWrapMode14_GXTexWrapMode12_GXTexFilter12_GXTexFilter = .text:0x804A7970; // type:function size:0xB8 -FUN_804a7a30 = .text:0x804A7A30; // type:function size:0x190 +getNormalColor__Q23EGG9GXUtilityFR8_GXColorRCQ23EGG8Vector3f = .text:0x804A7A30; // type:function size:0x190 __dt__Q23EGG8IScnProcFv = .text:0x804A7BC0; // type:function size:0xB8 createScnProc__Q23EGG8IScnProcFUsP12MEMAllocator = .text:0x804A7C80; // type:function size:0x110 setPriorityScnProc__Q23EGG8IScnProcFUsUcb = .text:0x804A7D90; // type:function size:0xBC pushBackToScnGroup__Q23EGG8IScnProcFPQ34nw4r3g3d8ScnGroup = .text:0x804A7E50; // type:function size:0x84 drawProcFunc__Q23EGG8IScnProcFPQ34nw4r3g3d7ScnProcb = .text:0x804A7EE0; // type:function size:0x78 -EGG__IScnProc__drawProcFuncNoGlobalState = .text:0x804A7F60; // type:function size:0x1C +drawProcFuncNoGlobalState__Q23EGG8IScnProcFPQ34nw4r3g3d7ScnProcb = .text:0x804A7F60; // type:function size:0x1C __ct__Q23EGG12LightManagerFUlUlUc = .text:0x804A7F80; // type:function size:0x1A8 __ct__Q33EGG12LightManager9LightDataFv = .text:0x804A8130; // type:function size:0x30 __dt__Q23EGG11LightObjectFv = .text:0x804A8160; // type:function size:0x40 @@ -26594,7 +26594,7 @@ __dt__Q23EGG12LightManagerFv = .text:0x804A81E0; // type:function size:0xA0 Reset__Q23EGG12LightManagerFv = .text:0x804A8280; // type:function size:0x12C Calc__Q23EGG12LightManagerFPQ34nw4r3g3d7ScnRoot = .text:0x804A83B0; // type:function size:0xC8 CalcView__Q23EGG12LightManagerFRCQ34nw4r4math5MTX34UcPQ34nw4r3g3d7ScnRoot = .text:0x804A8480; // type:function size:0x118 -EGG__LightManager__LoadLightSet = .text:0x804A85A0; // type:function size:0x6C +LoadLightSet__Q23EGG12LightManagerFiPUlPUlPUlPUlP8_GXColor = .text:0x804A85A0; // type:function size:0x6C DoneDraw__Q23EGG12LightManagerFv = .text:0x804A8610; // type:function size:0x30 LoadScnLightInner__Q23EGG12LightManagerFQ34nw4r3g3d9ResAnmScnfsUl = .text:0x804A8640; // type:function size:0x280 CopyToG3D_Ambient__Q23EGG12LightManagerCFPQ34nw4r3g3d7ScnRoot = .text:0x804A88C0; // type:function size:0x3C @@ -26616,39 +26616,39 @@ __ct__Q23EGG11LightObjectFv = .text:0x804A9830; // type:function size:0xB8 Reset__Q23EGG11LightObjectFv = .text:0x804A98F0; // type:function size:0x110 Calc__Q23EGG11LightObjectFv = .text:0x804A9A00; // type:function size:0x3C CalcView__Q23EGG11LightObjectFRCQ34nw4r4math5MTX34 = .text:0x804A9A40; // type:function size:0x1E8 -FUN_804a9c30 = .text:0x804A9C30; // type:function size:0x104 +fn_804A9C30__Q23EGG11LightObjectCFPCQ23EGG12LightTexturePQ34nw4r4math4VEC3P8_GXColor = .text:0x804A9C30; // type:function size:0x104 InitGX__Q23EGG11LightObjectCFP11_GXLightObj = .text:0x804A9D40; // type:function size:0x200 CopyToG3D_World__Q23EGG11LightObjectCFRQ34nw4r3g3d8LightObj = .text:0x804A9F40; // type:function size:0x150 CopyToG3D_View__Q23EGG11LightObjectCFRQ34nw4r3g3d8LightObjRCQ34nw4r4math5MTX34 = .text:0x804AA090; // type:function size:0x144 CopyFromG3D__Q23EGG11LightObjectFRCQ34nw4r3g3d11ResAnmLightfPQ23EGG11LightObjectb = .text:0x804AA1E0; // type:function size:0xD8 -FUN_804aa2c0 = .text:0x804AA2C0; // type:function size:0x9C -FUN_804aa360 = .text:0x804AA360; // type:function size:0x168 -FUN_804aa4d0 = .text:0x804AA4D0; // type:function size:0xA8 +ApplyAnmResultInner__Q23EGG11LightObjectFRCQ34nw4r3g3d14LightAnmResult = .text:0x804AA2C0; // type:function size:0x9C +ApplyAnmResultA__Q23EGG11LightObjectFRCQ34nw4r3g3d14LightAnmResult = .text:0x804AA360; // type:function size:0x168 +ApplyAnmResultB__Q23EGG11LightObjectFRCQ34nw4r3g3d14LightAnmResult = .text:0x804AA4D0; // type:function size:0xA8 CalcDirDist__Q23EGG11LightObjectFv = .text:0x804AA580; // type:function size:0xD4 -FUN_804aa660 = .text:0x804AA660; // type:function size:0x44 +CalcAt__Q23EGG11LightObjectFv = .text:0x804AA660; // type:function size:0x44 SetPos__Q23EGG11LightObjectFRCQ34nw4r4math4VEC3 = .text:0x804AA6B0; // type:function size:0x1C SetAt__Q23EGG11LightObjectFRCQ34nw4r4math4VEC3 = .text:0x804AA6D0; // type:function size:0x1C -FUN_804aa6f0 = .text:0x804AA6F0; // type:function size:0x8 +SetDist__Q23EGG11LightObjectFf = .text:0x804AA6F0; // type:function size:0x8 SetPosAt__Q23EGG11LightObjectFRCQ34nw4r4math4VEC3RCQ34nw4r4math4VEC3 = .text:0x804AA700; // type:function size:0x34 SetBinaryInner__Q23EGG11LightObjectFRCQ33EGG28IBinary3Bin = .text:0x804AA740; // type:function size:0x418 GetBinaryInner__Q23EGG11LightObjectCFPQ33EGG28IBinary3Bin = .text:0x804AAB60; // type:function size:0xF4 SetBinaryInner__Q23EGG11LightObjectFRCQ33EGG28IBinary3BinRCQ33EGG28IBinary3Binf = .text:0x804AAC60; // type:function size:0x5EC GetBinaryType__Q23EGG29IBinaryFv = .text:0x804AB250; // type:function size:0x8 GetVersion__Q23EGG29IBinaryFv = .text:0x804AB260; // type:function size:0x8 -FUN_804ab270 = .text:0x804AB270; // type:function size:0x9C -FUN_804ab310 = .text:0x804AB310; // type:function size:0x124 -FUN_804ab440 = .text:0x804AB440; // type:function size:0x1B4 -FUN_804ab600 = .text:0x804AB600; // type:function size:0x180 +fn_804AB270__Q23EGG12LightTextureFv = .text:0x804AB270; // type:function size:0x9C +fn_804AB310__Q23EGG12LightTextureFRC8_GXColor = .text:0x804AB310; // type:function size:0x124 +fn_804AB440__Q23EGG12LightTextureFv = .text:0x804AB440; // type:function size:0x1B4 +fn_804AB600__Q23EGG12LightTextureFv = .text:0x804AB600; // type:function size:0x180 initialize__Q23EGG12LightTextureFUsPQ23EGG4Heap = .text:0x804AB780; // type:function size:0x26C __ct__Q23EGG12LightTextureFPCcPCQ23EGG19LightTextureManager = .text:0x804AB9F0; // type:function size:0x284 __dt__Q23EGG12LightTextureFv = .text:0x804ABC80; // type:function size:0x90 configure__Q23EGG12LightTextureFv = .text:0x804ABD10; // type:function size:0x6C -EGG__LightTexture__loadTextureData = .text:0x804ABD80; // type:function size:0x10C -EGG__LightTexture__loadCpuTextureFromBti = .text:0x804ABE90; // type:function size:0xC +loadTextureData__Q23EGG12LightTextureFiPv9_GXTexFmt = .text:0x804ABD80; // type:function size:0x10C +loadTextureFromResTimg__Q23EGG12LightTextureFiPQ23EGG7ResTIMG = .text:0x804ABE90; // type:function size:0xC initDrawSetting__Q23EGG12LightTextureFUsUsUsUs = .text:0x804ABEA0; // type:function size:0x1A4 -FUN_804ac050 = .text:0x804AC050; // type:function size:0x4C -FUN_804ac0a0 = .text:0x804AC0A0; // type:function size:0x34 -FUN_804ac0e0 = .text:0x804AC0E0; // type:function size:0x490 +getTexDimensions__Q23EGG12LightTextureFPUsPUsPUsPUsUs = .text:0x804AC050; // type:function size:0x4C +fn_804AC0A0__Q23EGG12LightTextureFiPiPi = .text:0x804AC0A0; // type:function size:0x34 +fn_804AC0E0__Q23EGG12LightTextureFiRC8_GXColorb = .text:0x804AC0E0; // type:function size:0x490 draw__Q23EGG12LightTextureFi = .text:0x804AC570; // type:function size:0x3E8 beginDebugDraw__Q23EGG12LightTextureFv = .text:0x804AC960; // type:function size:0xD8 debugDraw__Q23EGG12LightTextureFi = .text:0x804ACA40; // type:function size:0x18C @@ -26658,15 +26658,15 @@ GetBinaryInner__Q23EGG12LightTextureCFPQ33EGG29IBinary3Bin GetBinarySize__Q23EGG12LightTextureCFv = .text:0x804AD390; // type:function size:0x14 SetBinaryInner__Q23EGG29IBinaryFRCQ33EGG29IBinary3BinRCQ33EGG29IBinary3Binf = .text:0x804AD3B0; // type:function size:0x4 __sinit_\eggLightTexture_cpp = .text:0x804AD3C0; // type:function size:0x44 scope:local -@52@SetBinaryInner__Q23EGG12LightTextureFRCQ33EGG29IBinary3Bin = .text:0x804AD410; // type:function size:0x8 -@52@GetBinaryInner__Q23EGG12LightTextureCFPQ33EGG29IBinary3Bin = .text:0x804AD420; // type:function size:0x8 -@52@GetBinarySize__Q23EGG12LightTextureCFv = .text:0x804AD430; // type:function size:0x8 -@52@__dt__Q23EGG12LightTextureFv = .text:0x804AD440; // type:function size:0x8 +@44@SetBinaryInner__Q23EGG12LightTextureFRCQ33EGG29IBinary3Bin = .text:0x804AD410; // type:function size:0x8 +@44@GetBinaryInner__Q23EGG12LightTextureCFPQ33EGG29IBinary3Bin = .text:0x804AD420; // type:function size:0x8 +@44@GetBinarySize__Q23EGG12LightTextureCFv = .text:0x804AD430; // type:function size:0x8 +@44@__dt__Q23EGG12LightTextureFv = .text:0x804AD440; // type:function size:0x8 __ct__Q23EGG19LightTextureManagerFPCQ23EGG12LightManager = .text:0x804AD450; // type:function size:0x1AC __dt__Q23EGG19LightTextureManagerFv = .text:0x804AD600; // type:function size:0x90 createTexture__Q23EGG19LightTextureManagerFPCc = .text:0x804AD690; // type:function size:0x110 -EGG__LightTextureManager__createTextureFromBin = .text:0x804AD7A0; // type:function size:0x5C -EGG__LightTextureManager__createTexturesFromBin = .text:0x804AD800; // type:function size:0x6C +createTextureFromBin__Q23EGG19LightTextureManagerFPCv = .text:0x804AD7A0; // type:function size:0x5C +createTexturesFromBin__Q23EGG19LightTextureManagerFPCv = .text:0x804AD800; // type:function size:0x6C deleteTexture__Q23EGG19LightTextureManagerFi = .text:0x804AD870; // type:function size:0x84 replaceModelTextures__Q23EGG19LightTextureManagerCFQ34nw4r3g3d6ResMdl = .text:0x804AD900; // type:function size:0x84 replaceModelTexture__Q23EGG19LightTextureManagerCFiQ34nw4r3g3d6ResMdl = .text:0x804AD990; // type:function size:0x104 @@ -26677,20 +26677,20 @@ frameReset__Q23EGG19LightTextureManagerFv = .text:0x804ADC40; // type:function s drawAndCaptureTexture__Q23EGG19LightTextureManagerFffff = .text:0x804ADC80; // type:function size:0x4C8 SetBinaryInner__Q23EGG19LightTextureManagerFRCQ33EGG36IBinary3Bin = .text:0x804AE150; // type:function size:0x80 GetBinaryInner__Q23EGG19LightTextureManagerCFPQ33EGG36IBinary3Bin = .text:0x804AE1D0; // type:function size:0x90 -getLTEXfromLMAP = .text:0x804AE260; // type:function size:0xDC -FUN_804ae340 = .text:0x804AE340; // type:function size:0xBC +getLtexFromLmap__Q23EGG19LightTextureManagerFPCvUs = .text:0x804AE260; // type:function size:0xDC +fn_804AE340__Q23EGG19LightTextureManagerFQ34nw4r3g3d6ResMat13_GXTexCoordID = .text:0x804AE340; // type:function size:0xBC GetBinarySize__Q23EGG19LightTextureManagerCFv = .text:0x804AE400; // type:function size:0x8 SetBinaryInner__Q23EGG36IBinaryFRCQ33EGG36IBinary3BinRCQ33EGG36IBinary3Binf = .text:0x804AE410; // type:function size:0x4 SetBinary__Q23EGG29IBinaryFPCv = .text:0x804AE420; // type:function size:0x10 GetBinary__Q23EGG29IBinaryCFPv = .text:0x804AE430; // type:function size:0x214 __ct__Q23EGG7ModelExFPQ34nw4r3g3d6ScnObj = .text:0x804AE650; // type:function size:0x1C8 -EGG__ModelEx__getShapeMinMax = .text:0x804AE820; // type:function size:0x228 -EGG__ModelEx__calcWorld = .text:0x804AEA50; // type:function size:0xF0 -EGG__ModelEx__getResMdl = .text:0x804AEB40; // type:function size:0x48 -EGG__ModelEx__getResShp = .text:0x804AEB90; // type:function size:0x90 +getShapeMinMax__Q23EGG7ModelExFUsPQ34nw4r4math4VEC3PQ34nw4r4math4VEC3b = .text:0x804AE820; // type:function size:0x228 +calcWorld__Q23EGG7ModelExCFPQ34nw4r4math5MTX34PCQ34nw4r4math5MTX34 = .text:0x804AEA50; // type:function size:0xF0 +getResMdl__Q23EGG7ModelExCFv = .text:0x804AEB40; // type:function size:0x48 +getResShp__Q23EGG7ModelExCFUs = .text:0x804AEB90; // type:function size:0x90 __ct__Q23EGG14PostEffectBaseFv = .text:0x804AEC20; // type:function size:0x5C draw__Q23EGG14PostEffectBaseFff = .text:0x804AEC80; // type:function size:0x94 -setMaterialInternal__Q23EGG14PostEffectBaseFv = .text:0x804AED20; // type:function size:0x60 +fn_804AED20__Q23EGG14PostEffectBaseFv = .text:0x804AED20; // type:function size:0x60 setVtxState__Q23EGG14PostEffectBaseFv = .text:0x804AED80; // type:function size:0x8 drawScreenInternal__Q23EGG14PostEffectBaseFffff = .text:0x804AED90; // type:function size:0x8C loadTextureInternal__Q23EGG14PostEffectBaseFv = .text:0x804AEE20; // type:function size:0x48 @@ -26698,30 +26698,30 @@ setMatColorChannel__Q23EGG14PostEffectBaseFv = .text:0x804AEE70; // type:functio setMatInd__Q23EGG14PostEffectBaseFv = .text:0x804AEEE0; // type:function size:0x8 setMatPE__Q23EGG14PostEffectBaseFv = .text:0x804AEEF0; // type:function size:0x7C setBlendModeInternal__Q23EGG14PostEffectBaseFv = .text:0x804AEF70; // type:function size:0xC4 -FUN_804af040 = .text:0x804AF040; // type:function size:0x164 -FUN_804af1b0 = .text:0x804AF1B0; // type:function size:0x120 +scaleColor__Q23EGG14PostEffectBaseFR8_GXColorRC8_GXColorbf = .text:0x804AF040; // type:function size:0x164 +lerpColor__Q23EGG14PostEffectBaseFR8_GXColorRC8_GXColorRC8_GXColorf = .text:0x804AF1B0; // type:function size:0x120 getBaseTexMtx__Q23EGG14PostEffectBaseCFPQ34nw4r4math5MTX34 = .text:0x804AF2D0; // type:function size:0xE4 setProjection__Q23EGG14PostEffectBaseFRCQ23EGG6Screen = .text:0x804AF3C0; // type:function size:0xF4 -FUN_804af4c0 = .text:0x804AF4C0; // type:function size:0xE0 -FUN_804af5a0 = .text:0x804AF5A0; // type:function size:0x190 -FUN_804af730 = .text:0x804AF730; // type:function size:0x4D4 -FUN_804afc10 = .text:0x804AFC10; // type:function size:0xC0 -FUN_804afcd0 = .text:0x804AFCD0; // type:function size:0x3C8 -FUN_804b00a0 = .text:0x804B00A0; // type:function size:0x1F8 -FUN_804b02a0 = .text:0x804B02A0; // type:function size:0x80 -FUN_804b0320 = .text:0x804B0320; // type:function size:0x2D4 -FUN_804b0600 = .text:0x804B0600; // type:function size:0x4A4 -FUN_804b0ab0 = .text:0x804B0AB0; // type:function size:0x64 -FUN_804b0b20 = .text:0x804B0B20; // type:function size:0x440 -FUN_804b0f60 = .text:0x804B0F60; // type:function size:0x160 -FUN_804b10c0 = .text:0x804B10C0; // type:function size:0x330 -FUN_804b13f0 = .text:0x804B13F0; // type:function size:0x174 -FUN_804b1570 = .text:0x804B1570; // type:function size:0x64C -FUN_804b1bc0 = .text:0x804B1BC0; // type:function size:0x8 -FUN_804b1bd0 = .text:0x804B1BD0; // type:function size:0x8 -FUN_804b1be0 = .text:0x804B1BE0; // type:function size:0x8 -FUN_804b1bf0 = .text:0x804B1BF0; // type:function size:0x5C -FUN_804b1c50 = .text:0x804B1C50; // type:function size:0x208 +__ct__Q23EGG14PostEffectBlurFv = .text:0x804AF4C0; // type:function size:0xE0 +draw__Q23EGG14PostEffectBlurFff = .text:0x804AF5A0; // type:function size:0x190 +drawInternal__Q23EGG14PostEffectBlurFUcUcff = .text:0x804AF730; // type:function size:0x4D4 +__ct__Q23EGG20PostEffectBlurGatherFv = .text:0x804AFC10; // type:function size:0xC0 +setMaterialInternal__Q23EGG20PostEffectBlurGatherFv = .text:0x804AFCD0; // type:function size:0x3C8 +__ct__Q23EGG14PostEffectUnk2Fv = .text:0x804B00A0; // type:function size:0x1F8 +__dt__Q23EGG14PostEffectUnk2Fv = .text:0x804B02A0; // type:function size:0x80 +draw__Q23EGG14PostEffectUnk2Fff = .text:0x804B0320; // type:function size:0x2D4 +setMaterialInternal__Q23EGG14PostEffectUnk2Fv = .text:0x804B0600; // type:function size:0x4A4 +__ct__Q23EGG14PostEffectMaskFv = .text:0x804B0AB0; // type:function size:0x64 +setMaterialInternal__Q23EGG14PostEffectMaskFv = .text:0x804B0B20; // type:function size:0x440 +__ct__Q23EGG17PostEffectMaskDOFFv = .text:0x804B0F60; // type:function size:0x160 +setUpGradation__Q23EGG17PostEffectMaskDOFFv = .text:0x804B10C0; // type:function size:0x330 +draw__Q23EGG17PostEffectMaskDOFFff = .text:0x804B13F0; // type:function size:0x174 +setMaterialInternal__Q23EGG17PostEffectMaskDOFFv = .text:0x804B1570; // type:function size:0x64C +getNearColor__Q23EGG17PostEffectMaskDOFFv = .text:0x804B1BC0; // type:function size:0x8 +getFarColor__Q23EGG17PostEffectMaskDOFFv = .text:0x804B1BD0; // type:function size:0x8 +getCenterColor__Q23EGG17PostEffectMaskDOFFv = .text:0x804B1BE0; // type:function size:0x8 +__ct__Q23EGG16PostEffectSimpleFv = .text:0x804B1BF0; // type:function size:0x5C +setMaterialInternal__Q23EGG16PostEffectSimpleFv = .text:0x804B1C50; // type:function size:0x208 Initialize__Q23EGG6ScreenFPCUsPCUsPQ23EGG6Screen = .text:0x804B1E60; // type:function size:0x1DC __ct__Q23EGG6ScreenFv = .text:0x804B2040; // type:function size:0xCC __ct__Q23EGG6ScreenFffffPCQ23EGG6ScreenQ33EGG7Frustum10CanvasMode = .text:0x804B2110; // type:function size:0xBC @@ -26731,8 +26731,8 @@ CopyToG3D__Q23EGG6ScreenCFQ34nw4r3g3d6Camera = .text:0x804B2390; // type:functio CopyFromAnother__Q23EGG6ScreenFRCQ23EGG6Screen = .text:0x804B24C0; // type:function size:0xD0 Reset__Q23EGG6ScreenFffffQ33EGG7Frustum10CanvasMode = .text:0x804B2590; // type:function size:0x38 SetParent__Q23EGG6ScreenFPCQ23EGG6Screen = .text:0x804B25D0; // type:function size:0x30 -FUN_804b2600 = .text:0x804B2600; // type:function size:0x24 -OnDirectEfb__Q23EGG6ScreenFv = .text:0x804B2630; // type:function size:0x4D8 +SetUnkFlag8__Q23EGG6ScreenFv = .text:0x804B2600; // type:function size:0x24 +OnDirectEfb__Q23EGG6ScreenCFv = .text:0x804B2630; // type:function size:0x4D8 GetDataEfb__Q23EGG6ScreenCFv = .text:0x804B2B10; // type:function size:0x5C IsChangeEfb__Q23EGG6ScreenCFv = .text:0x804B2B70; // type:function size:0x2C CalcMatrixForDrawQuad__Q23EGG6ScreenCFPQ34nw4r4math5MTX34ffff = .text:0x804B2BA0; // type:function size:0xA8 @@ -26740,34 +26740,34 @@ FillBufferGX__Q23EGG6ScreenCFUl8_GXColorUl = .text:0x804B2C50; // type:function GetGlobalPos__Q23EGG6ScreenCFPfPf = .text:0x804B2D40; // type:function size:0xB0 SetTVMode__Q23EGG6ScreenFQ33EGG6Screen6TVMode = .text:0x804B2DF0; // type:function size:0xB0 SetTVModeDefault__Q23EGG6ScreenFv = .text:0x804B2EA0; // type:function size:0x34 -FUN_804b2ee0 = .text:0x804B2EE0; // type:function size:0x14C +fn_804B2EE0__Q23EGG6ScreenCFPfPfff = .text:0x804B2EE0; // type:function size:0x14C __sinit_\eggScreen_cpp = .text:0x804B3030; // type:function size:0x84 scope:local __ct__Q23EGG16ScreenEffectBaseFv = .text:0x804B30C0; // type:function size:0x18 __sinit_\eggScreenEffectBase_cpp = .text:0x804B30E0; // type:function size:0xC scope:local -FUN_804b30f0 = .text:0x804B30F0; // type:function size:0x104 -FUN_804b3200 = .text:0x804B3200; // type:function size:0xA8 -FUN_804b32b0 = .text:0x804B32B0; // type:function size:0x454 -FUN_804b3710 = .text:0x804B3710; // type:function size:0x184 -FUN_804b38a0 = .text:0x804B38A0; // type:function size:0x78 -FUN_804b3920 = .text:0x804B3920; // type:function size:0x6C -FUN_804b3990 = .text:0x804B3990; // type:function size:0x3B4 -FUN_804b3d50 = .text:0x804B3D50; // type:function size:0x8 -FUN_804b3d60 = .text:0x804B3D60; // type:function size:0x8 -FUN_804b3d70 = .text:0x804B3D70; // type:function size:0x8 -FUN_804b3d80 = .text:0x804B3D80; // type:function size:0x8 -FUN_804b3d90 = .text:0x804B3D90; // type:function size:0x8 +__ct__Q23EGG16ScreenEffectBlurFv = .text:0x804B30F0; // type:function size:0x104 +__dt__Q23EGG16ScreenEffectBlurFv = .text:0x804B3200; // type:function size:0xA8 +fn_804B32B0__Q23EGG16ScreenEffectBlurFv = .text:0x804B32B0; // type:function size:0x454 +fn_804B3710__Q23EGG16ScreenEffectBlurFv = .text:0x804B3710; // type:function size:0x184 +SetBinaryInner__Q23EGG16ScreenEffectBlurFRCQ33EGG33IBinary3Bin = .text:0x804B38A0; // type:function size:0x78 +GetBinaryInner__Q23EGG16ScreenEffectBlurCFPQ33EGG33IBinary3Bin = .text:0x804B3920; // type:function size:0x6C +SetBinaryInner__Q23EGG16ScreenEffectBlurFRCQ33EGG33IBinary3BinRCQ33EGG33IBinary3Binf = .text:0x804B3990; // type:function size:0x3B4 +GetBinarySize__Q23EGG33IBinaryCFv = .text:0x804B3D50; // type:function size:0x8 +@8@SetBinaryInner__Q23EGG16ScreenEffectBlurFRCQ33EGG33IBinary3Bin = .text:0x804B3D60; // type:function size:0x8 +@8@SetBinaryInner__Q23EGG16ScreenEffectBlurFRCQ33EGG33IBinary3BinRCQ33EGG33IBinary3Binf = .text:0x804B3D70; // type:function size:0x8 +@8@GetBinaryInner__Q23EGG16ScreenEffectBlurCFPQ33EGG33IBinary3Bin = .text:0x804B3D80; // type:function size:0x8 +@8@__dt__Q23EGG16ScreenEffectBlurFv = .text:0x804B3D90; // type:function size:0x8 Clean__Q23EGG8StateEfbFv = .text:0x804B3DA0; // type:function size:0x78 captureEfb__Q23EGG8StateEfbFQ33EGG8StateEfb10BufferTypebUl = .text:0x804B3E20; // type:function size:0x3C8 releaseEfb__Q23EGG8StateEfbFQ33EGG8StateEfb10BufferTypeUl = .text:0x804B41F0; // type:function size:0x7C -FUN_804b4270 = .text:0x804B4270; // type:function size:0x98 -FUN_804b4310 = .text:0x804B4310; // type:function size:0x23C -FUN_804b4550 = .text:0x804B4550; // type:function size:0xA0 -FUN_804b45f0 = .text:0x804B45F0; // type:function size:0xC -FUN_804b4600 = .text:0x804B4600; // type:function size:0xC -FUN_804b4610 = .text:0x804B4610; // type:function size:0x28 +fn_804B4270__Q23EGG8StateEfbFQ33EGG8StateEfb10BufferTypeUl = .text:0x804B4270; // type:function size:0x98 +fn_804B4310__Q23EGG8StateEfbFQ33EGG8StateEfb10BufferTypeUl = .text:0x804B4310; // type:function size:0x23C +fn_804B4550__Q23EGG8StateEfbFv = .text:0x804B4550; // type:function size:0xA0 +GetShouldCapture__Q23EGG8StateEfbFv = .text:0x804B45F0; // type:function size:0xC +GetUseTfRgb565__Q23EGG8StateEfbFv = .text:0x804B4600; // type:function size:0xC +texRegionCallback__24@unnamed@eggStateGX_cpp@FPC9_GXTexObj11_GXTexMapID = .text:0x804B4610; // type:function size:0x28 initialize__Q23EGG7StateGXFUsUs8_GXColor11_GXPixelFmt = .text:0x804B4640; // type:function size:0x114 frameInit__Q23EGG7StateGXFv = .text:0x804B4760; // type:function size:0xA8 -FUN_804b4810 = .text:0x804B4810; // type:function size:0x160 +setTMemLayout__Q23EGG7StateGXFi = .text:0x804B4810; // type:function size:0x160 resetGX__Q23EGG7StateGXFv = .text:0x804B4970; // type:function size:0x48 resetVtx__Q23EGG7StateGXFv = .text:0x804B49C0; // type:function size:0x13C resetColorChannel__Q23EGG7StateGXFv = .text:0x804B4B00; // type:function size:0xB8 @@ -26777,15 +26777,15 @@ resetTexGen__Q23EGG7StateGXFv = .text:0x804B4CB0; // type:function size:0xB8 resetTev__Q23EGG7StateGXFv = .text:0x804B4D70; // type:function size:0x17C resetPE__Q23EGG7StateGXFv = .text:0x804B4EF0; // type:function size:0xB0 resetGXCache__Q23EGG7StateGXFv = .text:0x804B4FA0; // type:function size:0x40 -EGG__StateGX__GXSetPixelFmt_ = .text:0x804B4FE0; // type:function size:0xAC +GXSetPixelFmt___Q23EGG7StateGXF11_GXPixelFmt9_GXZFmt16 = .text:0x804B4FE0; // type:function size:0xAC invalidateTexAllGX__Q23EGG7StateGXFv = .text:0x804B5090; // type:function size:0x4 GXSetColorUpdate___Q23EGG7StateGXFb = .text:0x804B50A0; // type:function size:0x4C GXSetAlphaUpdate___Q23EGG7StateGXFb = .text:0x804B50F0; // type:function size:0x4C GXSetDither___Q23EGG7StateGXFb = .text:0x804B5140; // type:function size:0x4C -FUN_804b5190 = .text:0x804B5190; // type:function size:0x8 +GXCopyTex___Q23EGG7StateGXFPvb = .text:0x804B5190; // type:function size:0x8 GXSetDstAlpha___Q23EGG7StateGXFbUc = .text:0x804B51A0; // type:function size:0x4C -FUN_804b51f0 = .text:0x804B51F0; // type:function size:0x108 -FUN_804b5300 = .text:0x804B5300; // type:function size:0x2C +CalculateScreenScissor__Q23EGG7StateGXFPCfPUl = .text:0x804B51F0; // type:function size:0x108 +GXSetProjection___Q23EGG7StateGXFPA4_f17_GXProjectionType = .text:0x804B5300; // type:function size:0x2C GXSetProjectionv___Q23EGG7StateGXFPCf = .text:0x804B5330; // type:function size:0x2C GXSetViewport___Q23EGG7StateGXFffffff = .text:0x804B5360; // type:function size:0x2C GXSetScissor___Q23EGG7StateGXFUlUlUlUl = .text:0x804B5390; // type:function size:0x2C @@ -26797,8 +26797,8 @@ initialize__Q23EGG13TextureBufferFUlPQ23EGG4Heap = .text:0x804B55E0; // type:fun getNotJoin__Q23EGG13TextureBufferFv = .text:0x804B5710; // type:function size:0x28 alloc__Q23EGG13TextureBufferFUl = .text:0x804B5740; // type:function size:0x164 alloc__Q23EGG13TextureBufferFUsUs9_GXTexFmt = .text:0x804B58B0; // type:function size:0xA4 -FUN_804b5960 = .text:0x804B5960; // type:function size:0x8 -FUN_804b5970 = .text:0x804B5970; // type:function size:0x8 +setIncludesHeader__Q23EGG13TextureBufferFb = .text:0x804B5960; // type:function size:0x8 +includesHeader__Q23EGG13TextureBufferFv = .text:0x804B5970; // type:function size:0x8 __dt__Q23EGG13TextureBufferFv = .text:0x804B5980; // type:function size:0x5C __ct__Q23EGG9ArcPlayerFPQ34nw4r3snd18SoundArchivePlayerPQ34nw4r3snd9SoundHeap = .text:0x804B59E0; // type:function size:0x88 __dt__Q23EGG9ArcPlayerFv = .text:0x804B5A70; // type:function size:0x74 @@ -29127,7 +29127,7 @@ TYPE_NAME__Q34nw4r3g3d8ScnGroup = .rodata:0x804F7B10; // type:object size:0x10 TYPE_NAME__Q34nw4r3g3d7ScnRoot = .rodata:0x804F7B20; // type:object size:0x10 TYPE_NAME__Q34nw4r3g3d12ScnMdlSimple = .rodata:0x804F7B30; // type:object size:0x14 TYPE_NAME__Q34nw4r3g3d6ScnMdl = .rodata:0x804F7B48; // type:object size:0xC -TYPE_NAME__Q34nw4r3g3d13ScnMdlMat1Shp = .rodata:0x804F7B58; // type:object size:0x18 +TYPE_NAME__Q34nw4r3g3d14ScnMdl1Mat1Shp = .rodata:0x804F7B58; // type:object size:0x18 TYPE_NAME__Q34nw4r3g3d7ScnProc = .rodata:0x804F7B70; // type:object size:0x10 lbl_804F7B80 = .rodata:0x804F7B80; // type:object size:0x460 lbl_804F7FE0 = .rodata:0x804F7FE0; // type:object size:0x3CC @@ -29159,27 +29159,27 @@ gRMO_Ntsc_640x456Prog_4x3__22@unnamed@eggVideo_cpp@ = .rodata:0x804FB980; // typ gRMO_Ntsc_640x456IntDf_4x3__22@unnamed@eggVideo_cpp@ = .rodata:0x804FB9BC; // type:object size:0x3C scope:local renderModes__3EGG = .rodata:0x804FB9F8; // type:object size:0x28 scope:local @4804 = .rodata:0x804FBA20; // type:object size:0x10 scope:local data:4byte -lbl_804FBA30 = .rodata:0x804FBA30; // type:object size:0x30 -lbl_804FBA60 = .rodata:0x804FBA60; // type:object size:0xD8 -lbl_804FBB38 = .rodata:0x804FBB38; // type:object size:0x30 -lbl_804FBB68 = .rodata:0x804FBB68; // type:object size:0xF0 +copyArg2__3EGG = .rodata:0x804FBA30; // type:object size:0x18 +sVtxTypes__3EGG = .rodata:0x804FBA60; // type:object size:0x10 +s_ZMode__Q23EGG6DrawGX = .rodata:0x804FBB38; // type:object size:0x30 +s_Blend__Q23EGG6DrawGX = .rodata:0x804FBB68; // type:object size:0xF0 lbl_804FBC58 = .rodata:0x804FBC58; // type:object size:0x18 lbl_804FBC70 = .rodata:0x804FBC70; // type:object size:0xC lbl_804FBC7C = .rodata:0x804FBC7C; // type:object size:0xC -lbl_804FBC88 = .rodata:0x804FBC88; // type:object size:0x10 data:float +zeroVec__3EGG = .rodata:0x804FBC88; // type:object size:0xC data:float lbl_804FBC98 = .rodata:0x804FBC98; // type:object size:0xC data:4byte lbl_804FBCA4 = .rodata:0x804FBCA4; // type:object size:0xC data:4byte lbl_804FBCB0 = .rodata:0x804FBCB0; // type:object size:0x10 data:4byte -lbl_804FBCC0 = .rodata:0x804FBCC0; // type:object size:0x48 data:4byte +sCpuTexGradientOp__3EGG = .rodata:0x804FBCC0; // type:object size:0x48 data:4byte lbl_804FBD08 = .rodata:0x804FBD08; // type:object size:0x48 data:float lbl_804FBD50 = .rodata:0x804FBD50; // type:object size:0x10 data:float lbl_804FBD60 = .rodata:0x804FBD60; // type:object size:0x10 data:float lbl_804FBD70 = .rodata:0x804FBD70; // type:object size:0x18 lbl_804FBD88 = .rodata:0x804FBD88; // type:object size:0x18 data:4byte -lbl_804FBDA0 = .rodata:0x804FBDA0; // type:object size:0x30 -lbl_804FBDD0 = .rodata:0x804FBDD0; // type:object size:0x10 -lbl_804FBDE0 = .rodata:0x804FBDE0; // type:object size:0x10 -lbl_804FBDF0 = .rodata:0x804FBDF0; // type:object size:0x18 +identity__24@unnamed@eggStateGX_cpp@ = .rodata:0x804FBDA0; // type:object size:0x30 +@LOCAL@setTMemLayout__Q23EGG7StateGXFi@numbers = .rodata:0x804FBDD0; // type:object size:0x10 +@LOCAL@setTMemLayout__Q23EGG7StateGXFi@offsets@0 = .rodata:0x804FBDE0; // type:object size:0x10 +@LOCAL@resetIndirect__Q23EGG7StateGXFv@ind = .rodata:0x804FBDF0; // type:object size:0x18 lbl_804FBE08 = .rodata:0x804FBE08; // type:object size:0x10 data:4byte lbl_804FBE18 = .rodata:0x804FBE18; // type:object size:0x40 lbl_804FBE58 = .rodata:0x804FBE58; // type:object size:0xC @@ -29879,7 +29879,7 @@ __vt__Q23d3d12UnkWithWater = .data:0x805009C0; // type:object size:0x10 __vt__Q23d3d14AnmMdlWrapper2 = .data:0x805009D0; // type:object size:0x50 __vt__Q23d3d13AnmMdlWrapper = .data:0x80500A20; // type:object size:0x50 lbl_80500A70 = .data:0x80500A70; // type:object size:0x2C -lbl_80500A9C = .data:0x80500A9C; // type:object size:0xC +lbl_80500A9C = .data:0x80500A9C; // type:object size:0xB data:string lbl_80500AA8 = .data:0x80500AA8; // type:object size:0x10 data:string __vt__14dScnCallback_c = .data:0x80500AB8; // type:object size:0x20 lbl_80500AD8 = .data:0x80500AD8; // type:object size:0x18 @@ -37352,41 +37352,41 @@ __vt__Q23EGG14CoreController = .data:0x8056EC50; // type:object size:0x38 @3874 = .data:0x8056ECD0; // type:object size:0xA scope:local data:string @3878 = .data:0x8056ECDC; // type:object size:0xD scope:local data:string @3881 = .data:0x8056ECF0; // type:object size:0x10 scope:local data:string -EGG____OrthoCamera__vtable = .data:0x8056ED00; // type:object size:0x30 -EGG__LookAtCamera__vtable = .data:0x8056ED30; // type:object size:0x30 -lbl_8056ED60 = .data:0x8056ED60; // type:object size:0x10 -EGG__CapTexture__vtable = .data:0x8056ED70; // type:object size:0x10 -EGG__CpuTexture__vtable = .data:0x8056ED80; // type:object size:0x20 +__vt__Q23EGG11OrthoCamera = .data:0x8056ED00; // type:object size:0x30 +__vt__Q23EGG12LookAtCamera = .data:0x8056ED30; // type:object size:0x30 +__vt__Q23EGG9AnalizeDL = .data:0x8056ED60; // type:object size:0xC +__vt__Q23EGG10CapTexture = .data:0x8056ED70; // type:object size:0x10 +__vt__Q23EGG10CpuTexture = .data:0x8056ED80; // type:object size:0x10 DummyTexureData = .data:0x8056EDA0; // type:object size:0x40 jumptable_8056EDE0 = .data:0x8056EDE0; // type:object size:0x38 scope:local jumptable_8056EE18 = .data:0x8056EE18; // type:object size:0x48 scope:local -lbl_8056EE60 = .data:0x8056EE60; // type:object size:0x50 -lbl_8056EEB0 = .data:0x8056EEB0; // type:object size:0x78 -lbl_8056EF28 = .data:0x8056EF28; // type:object size:0x78 -lbl_8056EFA0 = .data:0x8056EFA0; // type:object size:0x50 -EGG__Fog__vtable = .data:0x8056EFF0; // type:object size:0x20 -EGG__FogManager__vtable = .data:0x8056F010; // type:object size:0x20 -EGG__Frustum__vtable = .data:0x8056F030; // type:object size:0x18 -EGG__GfxEnginer__Configuration__vtable = .data:0x8056F048; // type:object size:0x10 -lbl_8056F058 = .data:0x8056F058; // type:object size:0x10 -EGG__LightManager__vtable = .data:0x8056F068; // type:object size:0x30 -EGG__LightObject__vtable = .data:0x8056F098; // type:object size:0x20 -EGG__LightTexture__vtable = .data:0x8056F0B8; // type:object size:0x38 -EGG__LightTextureManager__vtable = .data:0x8056F0F0; // type:object size:0x20 -lbl_8056F110 = .data:0x8056F110; // type:object size:0x10 +__vt__Q23EGG12DrawPathBase = .data:0x8056EE60; // type:object size:0x50 +__vt__Q23EGG13DrawPathBloom = .data:0x8056EEB0; // type:object size:0x78 +__vt__Q23EGG11DrawPathDOF = .data:0x8056EF28; // type:object size:0x78 +__vt__Q23EGG16DrawPathLightMap = .data:0x8056EFA0; // type:object size:0x50 +__vt__Q23EGG3Fog = .data:0x8056EFF0; // type:object size:0x20 +__vt__Q23EGG10FogManager = .data:0x8056F010; // type:object size:0x1C +__vt__Q23EGG7Frustum = .data:0x8056F030; // type:object size:0x14 +__vt__Q33EGG9GfxEngine13Configuration = .data:0x8056F048; // type:object size:0xC +__vt__Q23EGG8IScnProc = .data:0x8056F058; // type:object size:0x10 +__vt__Q23EGG12LightManager = .data:0x8056F068; // type:object size:0x2C +__vt__Q23EGG11LightObject = .data:0x8056F098; // type:object size:0x20 +__vt__Q23EGG12LightTexture = .data:0x8056F0B8; // type:object size:0x38 +__vt__Q23EGG19LightTextureManager = .data:0x8056F0F0; // type:object size:0x1C +lbl_8056F110 = .data:0x8056F110; // type:object size:0x9 data:string jumptable_8056F120 = .data:0x8056F120; // type:object size:0x30 scope:local -lbl_8056F150 = .data:0x8056F150; // type:object size:0x20 -lbl_8056F170 = .data:0x8056F170; // type:object size:0x20 -lbl_8056F190 = .data:0x8056F190; // type:object size:0x20 -lbl_8056F1B0 = .data:0x8056F1B0; // type:object size:0x20 -lbl_8056F1D0 = .data:0x8056F1D0; // type:object size:0x20 -lbl_8056F1F0 = .data:0x8056F1F0; // type:object size:0x20 -lbl_8056F210 = .data:0x8056F210; // type:object size:0x20 +__vt__Q23EGG14PostEffectBase = .data:0x8056F150; // type:object size:0x1C +__vt__Q23EGG14PostEffectBlur = .data:0x8056F170; // type:object size:0x1C +__vt__Q23EGG20PostEffectBlurGather = .data:0x8056F190; // type:object size:0x1C +__vt__Q23EGG14PostEffectUnk2 = .data:0x8056F1B0; // type:object size:0x1C +__vt__Q23EGG14PostEffectMask = .data:0x8056F1D0; // type:object size:0x1C +__vt__Q23EGG17PostEffectMaskDOF = .data:0x8056F1F0; // type:object size:0x1C +__vt__Q23EGG16PostEffectSimple = .data:0x8056F210; // type:object size:0x1C sTVModeInfo__Q23EGG6Screen = .data:0x8056F230; // type:object size:0x24 data:2byte -EGG__Screen__vtable = .data:0x8056F254; // type:object size:0x14 -lbl_8056F268 = .data:0x8056F268; // type:object size:0x10 -lbl_8056F278 = .data:0x8056F278; // type:object size:0x38 -lbl_8056F2B0 = .data:0x8056F2B0; // type:object size:0x10 +__vt__Q23EGG6Screen = .data:0x8056F254; // type:object size:0x14 +__vt__Q23EGG16ScreenEffectBase = .data:0x8056F268; // type:object size:0xC +__vt__Q23EGG16ScreenEffectBlur = .data:0x8056F278; // type:object size:0x38 +__vt__Q23EGG13TextureBuffer = .data:0x8056F2B0; // type:object size:0x10 __vt__Q23EGG9ArcPlayer = .data:0x8056F2C0; // type:object size:0x5C __vt__Q23EGG14SimpleAudioMgr = .data:0x8056F320; // type:object size:0xA4 __vt__Q23EGG9IAudioMgr = .data:0x8056F3C8; // type:object size:0x10 scope:weak @@ -39824,19 +39824,19 @@ sWPADWorkSize__Q23EGG17CoreControllerMgr = .sdata:0x80574EE8; // type:object siz @3877 = .sdata:0x80574F00; // type:object size:0x8 scope:local data:string @3879 = .sdata:0x80574F08; // type:object size:0x8 scope:local data:string @3880 = .sdata:0x80574F10; // type:object size:0x7 scope:local data:string -EGG__DrawGX__sLightMaskDefault = .sdata:0x80574F18; // type:object size:0x8 data:4byte +sLightMaskDefault__Q23EGG6DrawGX = .sdata:0x80574F18; // type:object size:0x4 data:4byte lbl_80574F20 = .sdata:0x80574F20; // type:object size:0x8 lbl_80574F28 = .sdata:0x80574F28; // type:object size:0x4 lbl_80574F2C = .sdata:0x80574F2C; // type:object size:0x4 data:4byte lbl_80574F30 = .sdata:0x80574F30; // type:object size:0x8 -lbl_80574F38 = .sdata:0x80574F38; // type:object size:0x2 data:2byte +sTextureSize__Q23EGG12LightTexture = .sdata:0x80574F38; // type:object size:0x2 data:2byte lbl_80574F3A = .sdata:0x80574F3A; // type:object size:0x1 data:byte lbl_80574F3C = .sdata:0x80574F3C; // type:object size:0xC -lbl_80574F48 = .sdata:0x80574F48; // type:object size:0x8 data:4byte +sByteCodeCalcStr__Q23EGG7ModelEx = .sdata:0x80574F48; // type:object size:0x4 data:4byte lbl_80574F50 = .sdata:0x80574F50; // type:object size:0x8 data:string -lbl_80574F58 = .sdata:0x80574F58; // type:object size:0x8 data:4byte -lbl_80574F60 = .sdata:0x80574F60; // type:object size:0x4 data:4byte -lbl_80574F64 = .sdata:0x80574F64; // type:object size:0x4 data:4byte +sByteCodeMixStr__Q23EGG7ModelEx = .sdata:0x80574F58; // type:object size:0x4 data:4byte +sFlag__Q23EGG8StateEfb = .sdata:0x80574F60; // type:object size:0x4 data:4byte +sWorkBuffer__Q23EGG8StateEfb = .sdata:0x80574F64; // type:object size:0x4 data:4byte sAudioRmtSpeakerWpadVolume__Q23EGG18AudioRmtSpeakerMgr = .sdata:0x80574F68; // type:object size:0x1 data:byte sHBFadeframe__Q33EGG12AudioUtility3HBM = .sdata:0x80574F70; // type:object size:0x4 data:4byte fragmentID = .sdata:0x80574F78; // type:object size:0x4 scope:local data:4byte @@ -41147,53 +41147,53 @@ sAssertCallback2__Q23EGG6Assert = .sbss:0x805767FC; // type:object size:0x4 data sPtrOverride__Q23EGG6Assert = .sbss:0x80576800; // type:object size:0x4 data:4byte sInstantHalt__Q23EGG6Assert = .sbss:0x80576804; // type:object size:0x1 data:byte sAssertOccurred__Q23EGG6Assert = .sbss:0x80576805; // type:object size:0x1 data:byte -lbl_80576808 = .sbss:0x80576808; // type:object size:0x4 data:4byte -EGG__DrawGX__sTexMapDefault = .sbss:0x8057680C; // type:object size:0x4 data:4byte -EGG__Frustum__sGlobalScale = .sbss:0x80576810; // type:object size:0x4 data:float -EGG__Frustum__sGlobalOffset = .sbss:0x80576818; // type:object size:0x4 data:float -lbl_80576820 = .sbss:0x80576820; // type:object size:0x1 data:byte -lbl_80576824 = .sbss:0x80576824; // type:object size:0x4 data:4byte -lbl_80576828 = .sbss:0x80576828; // type:object size:0x4 data:4byte -lbl_8057682C = .sbss:0x8057682C; // type:object size:0x4 data:4byte -lbl_80576830 = .sbss:0x80576830; // type:object size:0x8 data:4byte -EGG__GlobalDrawState__spScreen = .sbss:0x80576838; // type:object size:0x4 data:4byte -EGG__GlobalDrawState__sCameraID = .sbss:0x8057683C; // type:object size:0x2 data:2byte -lbl_80576840 = .sbss:0x80576840; // type:object size:0x8 data:4byte -lbl_80576848 = .sbss:0x80576848; // type:object size:0x2 data:2byte -lbl_8057684A = .sbss:0x8057684A; // type:object size:0x2 data:2byte -lbl_8057684C = .sbss:0x8057684C; // type:object size:0x2 data:2byte -lbl_8057684E = .sbss:0x8057684E; // type:object size:0x2 data:2byte -lbl_80576850 = .sbss:0x80576850; // type:object size:0x2 data:2byte -lbl_80576852 = .sbss:0x80576852; // type:object size:0x2 data:2byte -lbl_80576854 = .sbss:0x80576854; // type:object size:0x2 data:2byte -lbl_80576856 = .sbss:0x80576856; // type:object size:0x2 data:2byte -lbl_80576858 = .sbss:0x80576858; // type:object size:0x4 data:4byte -lbl_8057685C = .sbss:0x8057685C; // type:object size:0x1 data:byte +s_flag__Q23EGG6DrawGX = .sbss:0x80576808; // type:object size:0x4 data:4byte +sTexMapDefault__Q23EGG6DrawGX = .sbss:0x8057680C; // type:object size:0x4 data:4byte +sGlobalScale__Q23EGG7Frustum = .sbss:0x80576810; // type:object size:0x8 data:float +sGlobalOffset__Q23EGG7Frustum = .sbss:0x80576818; // type:object size:0x8 data:float +sId__Q23EGG10G3DUtility = .sbss:0x80576820; // type:object size:0x1 data:byte +sAllocator__Q23EGG10G3DUtility = .sbss:0x80576824; // type:object size:0x4 data:4byte +sBuf__Q23EGG10G3DUtility = .sbss:0x80576828; // type:object size:0x4 data:4byte +sOffset__Q23EGG10G3DUtility = .sbss:0x8057682C; // type:object size:0x4 data:4byte +sSize__Q23EGG10G3DUtility = .sbss:0x80576830; // type:object size:0x8 data:4byte +spScreen__Q23EGG15GlobalDrawState = .sbss:0x80576838; // type:object size:0x4 data:4byte +sCameraId__Q23EGG15GlobalDrawState = .sbss:0x8057683C; // type:object size:0x2 data:2byte +sDrawFlag__Q23EGG15GlobalDrawState = .sbss:0x80576840; // type:object size:0x4 data:4byte +sDrawWidth__Q23EGG12LightTexture = .sbss:0x80576848; // type:object size:0x2 data:2byte +sDrawHeight__Q23EGG12LightTexture = .sbss:0x8057684A; // type:object size:0x2 data:2byte +sDrawPosX__Q23EGG12LightTexture = .sbss:0x8057684C; // type:object size:0x2 data:2byte +sDrawPosY__Q23EGG12LightTexture = .sbss:0x8057684E; // type:object size:0x2 data:2byte +sTexWidth__Q23EGG12LightTexture = .sbss:0x80576850; // type:object size:0x2 data:2byte +sTexHeight__Q23EGG12LightTexture = .sbss:0x80576852; // type:object size:0x2 data:2byte +sDrawNumX__Q23EGG12LightTexture = .sbss:0x80576854; // type:object size:0x2 data:2byte +sDrawNumY__Q23EGG12LightTexture = .sbss:0x80576856; // type:object size:0x2 data:2byte +spNormalEnvironment__Q23EGG12LightTexture = .sbss:0x80576858; // type:object size:0x4 data:4byte +sUseDebug__Q23EGG12LightTexture = .sbss:0x8057685C; // type:object size:0x1 data:byte lbl_80576860 = .sbss:0x80576860; // type:object size:0x1 data:byte -lbl_80576861 = .sbss:0x80576861; // type:object size:0x7 data:byte -lbl_80576868 = .sbss:0x80576868; // type:object size:0x4 data:float +lbl_80576861 = .sbss:0x80576861; // type:object size:0x1 data:byte +lbl_80576868 = .sbss:0x80576868; // type:object size:0x8 data:float sTVMode__Q23EGG6Screen = .sbss:0x80576870; // type:object size:0x4 data:4byte -lbl_80576874 = .sbss:0x80576874; // type:object size:0x4 data:4byte -lbl_80576878 = .sbss:0x80576878; // type:object size:0x4 data:4byte -lbl_8057687C = .sbss:0x8057687C; // type:object size:0x4 data:4byte -lbl_80576880 = .sbss:0x80576880; // type:object size:0x4 data:float -lbl_80576888 = .sbss:0x80576888; // type:object size:0x4 data:float -lbl_80576890 = .sbss:0x80576890; // type:object size:0x8 data:byte -lbl_80576898 = .sbss:0x80576898; // type:object size:0x8 data:4byte -lbl_805768A0 = .sbss:0x805768A0; // type:object size:0x2 data:2byte -lbl_805768A2 = .sbss:0x805768A2; // type:object size:0x2 data:2byte -lbl_805768A4 = .sbss:0x805768A4; // type:object size:0x4 data:4byte -lbl_805768A8 = .sbss:0x805768A8; // type:object size:0x4 data:4byte -lbl_805768AC = .sbss:0x805768AC; // type:object size:0x1 data:byte -lbl_805768B0 = .sbss:0x805768B0; // type:object size:0x2 data:2byte -lbl_805768B2 = .sbss:0x805768B2; // type:object size:0x6 data:2byte -lbl_805768B8 = .sbss:0x805768B8; // type:object size:0x4 data:4byte -lbl_805768BC = .sbss:0x805768BC; // type:object size:0x4 data:4byte -lbl_805768C0 = .sbss:0x805768C0; // type:object size:0x4 data:4byte -lbl_805768C4 = .sbss:0x805768C4; // type:object size:0x4 data:4byte -lbl_805768C8 = .sbss:0x805768C8; // type:object size:0x4 data:4byte -lbl_805768CC = .sbss:0x805768CC; // type:object size:0x4 data:4byte -lbl_805768D0 = .sbss:0x805768D0; // type:object size:0x8 data:byte +spRoot__Q23EGG6Screen = .sbss:0x80576874; // type:object size:0x4 data:4byte +sChangeTVModeFunc__Q23EGG6Screen = .sbss:0x80576878; // type:object size:0x4 data:4byte +spChangeTVModeFuncInfo__Q23EGG6Screen = .sbss:0x8057687C; // type:object size:0x4 data:4byte +sCanvasScale__Q23EGG6Screen = .sbss:0x80576880; // type:object size:0x8 data:float +sCanvasOffset__Q23EGG6Screen = .sbss:0x80576888; // type:object size:0x8 data:float +@GUARD@Initialize__Q23EGG6ScreenFPCUsPCUsPQ23EGG6Screen@defaultRoot = .sbss:0x80576890; // type:object size:0x1 data:byte +sPushCount__Q23EGG8StateEfb = .sbss:0x80576898; // type:object size:0x4 data:4byte +s_widthEfb__Q23EGG7StateGX = .sbss:0x805768A0; // type:object size:0x2 data:2byte +s_heightEfb__Q23EGG7StateGX = .sbss:0x805768A2; // type:object size:0x2 data:2byte +s_pixFormat__Q23EGG7StateGX = .sbss:0x805768A4; // type:object size:0x4 data:4byte +s_zFmt16__Q23EGG7StateGX = .sbss:0x805768A8; // type:object size:0x4 data:4byte +s_clearEfb__Q23EGG7StateGX = .sbss:0x805768AC; // type:object size:0x4 data:byte +s_flag__Q23EGG7StateGX = .sbss:0x805768B0; // type:object size:0x2 data:2byte +s_commandFlag__Q23EGG7StateGX = .sbss:0x805768B2; // type:object size:0x2 data:2byte +spHead__Q23EGG13TextureBuffer = .sbss:0x805768B8; // type:object size:0x4 data:4byte +spTailNotJoin__Q23EGG13TextureBuffer = .sbss:0x805768BC; // type:object size:0x4 data:4byte +spBufferAll__Q23EGG13TextureBuffer = .sbss:0x805768C0; // type:object size:0x4 data:4byte +sBufferAllSize__Q23EGG13TextureBuffer = .sbss:0x805768C4; // type:object size:0x4 data:4byte +sBufferSize__Q23EGG13TextureBuffer = .sbss:0x805768C8; // type:object size:0x4 data:4byte +sBufferRestSizeMin__Q23EGG13TextureBuffer = .sbss:0x805768CC; // type:object size:0x4 data:4byte +sIncludesHeader__Q23EGG13TextureBuffer = .sbss:0x805768D0; // type:object size:0x1 data:byte sAudioRmtSpeakerConnectCanncelSw__Q23EGG18AudioRmtSpeakerMgr = .sbss:0x805768D8; // type:object size:0x1 data:byte mTaskFinishCount__Q23EGG18AudioRmtSpeakerMgr = .sbss:0x805768DC; // type:object size:0x4 data:4byte mTaskRequestCount__Q23EGG18AudioRmtSpeakerMgr = .sbss:0x805768E0; // type:object size:0x4 data:4byte @@ -48011,9 +48011,7 @@ lbl_8057F3FC = .sdata2:0x8057F3FC; // type:object size:0xC lbl_8057F408 = .sdata2:0x8057F408; // type:object size:0x4 data:4byte lbl_8057F40C = .sdata2:0x8057F40C; // type:object size:0x2 data:2byte lbl_8057F40E = .sdata2:0x8057F40E; // type:object size:0x1 data:byte -lbl_8057F410 = .sdata2:0x8057F410; // type:object size:0x4 data:4byte -lbl_8057F414 = .sdata2:0x8057F414; // type:object size:0x2 data:2byte -lbl_8057F416 = .sdata2:0x8057F416; // type:object size:0x1 data:byte +defaultFilter__3EGG = .sdata2:0x8057F410; // type:object size:0x7 data:byte lbl_8057F418 = .sdata2:0x8057F418; // type:object size:0x4 data:float lbl_8057F41C = .sdata2:0x8057F41C; // type:object size:0x4 data:float lbl_8057F420 = .sdata2:0x8057F420; // type:object size:0x8 data:double @@ -48022,7 +48020,7 @@ BLACK__Q23EGG6DrawGX = .sdata2:0x8057F440; // type:object size:0x4 data:4byte WHITE__Q23EGG6DrawGX = .sdata2:0x8057F444; // type:object size:0x4 data:4byte RED__Q23EGG6DrawGX = .sdata2:0x8057F448; // type:object size:0x4 data:4byte GREEN__Q23EGG6DrawGX = .sdata2:0x8057F44C; // type:object size:0x4 data:4byte -BLUE__Q23EGG6DrawGX = .sdata2:0x8057F450; // type:object size:0x8 data:4byte +BLUE__Q23EGG6DrawGX = .sdata2:0x8057F450; // type:object size:0x4 data:4byte lbl_8057F458 = .sdata2:0x8057F458; // type:object size:0x8 data:4byte lbl_8057F460 = .sdata2:0x8057F460; // type:object size:0x4 data:float lbl_8057F464 = .sdata2:0x8057F464; // type:object size:0x4 data:float @@ -48098,7 +48096,7 @@ lbl_8057F62C = .sdata2:0x8057F62C; // type:object size:0x4 data:float lbl_8057F630 = .sdata2:0x8057F630; // type:object size:0x4 data:float lbl_8057F634 = .sdata2:0x8057F634; // type:object size:0x4 data:float lbl_8057F638 = .sdata2:0x8057F638; // type:object size:0x4 data:float -EGG__GXUtility__sTexMtxIDs = .sdata2:0x8057F640; // type:object size:0x8 +s_texMtxIds__Q23EGG9GXUtility = .sdata2:0x8057F640; // type:object size:0x8 lbl_8057F648 = .sdata2:0x8057F648; // type:object size:0x4 data:float lbl_8057F64C = .sdata2:0x8057F64C; // type:object size:0x4 data:float lbl_8057F650 = .sdata2:0x8057F650; // type:object size:0x4 data:float @@ -48168,8 +48166,8 @@ lbl_8057F7BC = .sdata2:0x8057F7BC; // type:object size:0x4 data:float lbl_8057F7C0 = .sdata2:0x8057F7C0; // type:object size:0x4 data:float lbl_8057F7C8 = .sdata2:0x8057F7C8; // type:object size:0x4 data:float lbl_8057F7CC = .sdata2:0x8057F7CC; // type:object size:0x4 data:float -lbl_8057F7D0 = .sdata2:0x8057F7D0; // type:object size:0x4 -lbl_8057F7D4 = .sdata2:0x8057F7D4; // type:object size:0x4 +sColorNear__3EGG = .sdata2:0x8057F7D0; // type:object size:0x4 +sColorFar__3EGG = .sdata2:0x8057F7D4; // type:object size:0x4 lbl_8057F7D8 = .sdata2:0x8057F7D8; // type:object size:0x4 data:float lbl_8057F7DC = .sdata2:0x8057F7DC; // type:object size:0x4 data:float lbl_8057F7E0 = .sdata2:0x8057F7E0; // type:object size:0x4 data:float @@ -48205,7 +48203,7 @@ lbl_8057F874 = .sdata2:0x8057F874; // type:object size:0x4 data:float lbl_8057F878 = .sdata2:0x8057F878; // type:object size:0x4 data:float lbl_8057F880 = .sdata2:0x8057F880; // type:object size:0x8 data:double lbl_8057F888 = .sdata2:0x8057F888; // type:object size:0x4 data:float -lbl_8057F890 = .sdata2:0x8057F890; // type:object size:0x4 data:4byte +white__24@unnamed@eggStateGX_cpp@ = .sdata2:0x8057F890; // type:object size:0x4 data:4byte lbl_8057F894 = .sdata2:0x8057F894; // type:object size:0x4 data:float lbl_8057F898 = .sdata2:0x8057F898; // type:object size:0x4 data:float lbl_8057F89C = .sdata2:0x8057F89C; // type:object size:0x4 data:float @@ -48447,7 +48445,7 @@ lbl_8057FFA0 = .sbss2:0x8057FFA0; // type:object size:0x8 data:4byte lbl_8057FFA8 = .sbss2:0x8057FFA8; // type:object size:0x8 lbl_8057FFB0 = .sbss2:0x8057FFB0; // type:object size:0x8 DefaultBlackColor = .sbss2:0x8057FFB8; // type:object size:0x8 scope:local data:2byte -lbl_8057FFC0 = .sbss2:0x8057FFC0; // type:object size:0x8 data:byte +sBlack__3EGG = .sbss2:0x8057FFC0; // type:object size:0x4 data:byte lbl_8057FFC8 = .sbss2:0x8057FFC8; // type:object size:0x4 lbl_80580000 = .bss:0x80580000; // type:object size:0x14 data:4byte lbl_80580014 = .bss:0x80580014; // type:object size:0xC @@ -49799,24 +49797,24 @@ ex__Q23EGG8Vector3f = .bss:0x80674C3C; // type:object size:0xC data:float ey__Q23EGG8Vector3f = .bss:0x80674C48; // type:object size:0xC data:float ez__Q23EGG8Vector3f = .bss:0x80674C54; // type:object size:0xC data:float buf__Q23EGG6Assert = .bss:0x80674C60; // type:object size:0x104 -lbl_80674D68 = .bss:0x80674D68; // type:object size:0x90 -sCameraMtx = .bss:0x80674DF8; // type:object size:0x30 data:float -lbl_80674E28 = .bss:0x80674E28; // type:object size:0x20 -lbl_80674E48 = .bss:0x80674E48; // type:object size:0x30 -CPU_TEX_ARR = .bss:0x80674E78; // type:object size:0x48 data:4byte -lbl_80674EC0 = .bss:0x80674EC0; // type:object size:0x30 data:float -lbl_80674EF0 = .bss:0x80674EF0; // type:object size:0x10 data:float -lbl_80674F00 = .bss:0x80674F00; // type:object size:0x88 data:4byte -lbl_80674F88 = .bss:0x80674F88; // type:object size:0x88 -lbl_80675010 = .bss:0x80675010; // type:object size:0x30 -lbl_80675040 = .bss:0x80675040; // type:object size:0x18 data:float -lbl_80675058 = .bss:0x80675058; // type:object size:0x18 data:float -lbl_80675070 = .bss:0x80675070; // type:object size:0x30 data:float -lbl_806750A0 = .bss:0x806750A0; // type:object size:0x20 -lbl_806750C0 = .bss:0x806750C0; // type:object size:0xA8 data:4byte -lbl_80675168 = .bss:0x80675168; // type:object size:0x18 -lbl_80675180 = .bss:0x80675180; // type:object size:0x10 -lbl_80675190 = .bss:0x80675190; // type:object size:0x200 data:4byte +s_DL__Q23EGG6DrawGX = .bss:0x80674D68; // type:object size:0x90 +s_cameraMtx__Q23EGG6DrawGX = .bss:0x80674DF8; // type:object size:0x30 data:float +sDummyTexObj__Q23EGG6DrawGX = .bss:0x80674E28; // type:object size:0x20 +sMtx__Q23EGG15GlobalDrawState = .bss:0x80674E48; // type:object size:0x30 +sCpuTexArray__3EGG = .bss:0x80674E78; // type:object size:0x48 data:4byte +sMtx__3EGG = .bss:0x80674EC0; // type:object size:0x30 data:float +lbl_80674EF0 = .bss:0x80674EF0; // type:object size:0xC data:float +@LOCAL@Initialize__Q23EGG6ScreenFPCUsPCUsPQ23EGG6Screen@defaultRoot = .bss:0x80674F00; // type:object size:0x88 data:4byte +sScreen__Q23EGG16ScreenEffectBase = .bss:0x80674F88; // type:object size:0x88 +spBufferSet__Q23EGG8StateEfb = .bss:0x80675010; // type:object size:0x30 +sWorkSpaceV__Q23EGG8StateEfb = .bss:0x80675040; // type:object size:0x18 data:float +sWorkSpaceHideV__Q23EGG8StateEfb = .bss:0x80675058; // type:object size:0x18 data:float +sUnkBuffer__Q23EGG8StateEfb = .bss:0x80675070; // type:object size:0x18 data:float +sDefaultTexObj__Q23EGG7StateGX = .bss:0x806750A0; // type:object size:0x20 +s_tmem_layout__Q23EGG7StateGX = .bss:0x806750C0; // type:object size:0xA8 data:4byte +s_cacheGX__Q23EGG7StateGX = .bss:0x80675168; // type:object size:0x18 +@LOCAL@initialize__Q23EGG7StateGXFUsUs8_GXColor11_GXPixelFmt@sDefaultTexObjData = .bss:0x80675180; // type:object size:0x10 +spBufferTable__Q23EGG13TextureBuffer = .bss:0x80675190; // type:object size:0x200 data:4byte sTasks__Q23EGG18AudioRmtSpeakerMgr = .bss:0x80675390; // type:object size:0xF0 sMoveParamMgr__Q23EGG12AudioUtility = .bss:0x80675480; // type:object size:0xC lbl_80675490 = .bss:0x80675490; // type:object size:0x10 diff --git a/configure.py b/configure.py index d690c126..a4cf29a7 100644 --- a/configure.py +++ b/configure.py @@ -865,41 +865,43 @@ config.libs = [ EGGLib( "gfx", [ - Object(NonMatching, "egg/gfx/eggCamera.cpp"), - Object(NonMatching, "egg/gfx/eggPalette.cpp"), - Object(NonMatching, "egg/gfx/eggTexture.cpp"), - Object(NonMatching, "egg/gfx/eggUnk1.cpp"), # Unknown - Object(NonMatching, "egg/gfx/eggCapTexture.cpp"), + Object(Matching, "egg/gfx/eggCamera.cpp"), + Object(Matching, "egg/gfx/eggPalette.cpp"), + Object(Matching, "egg/gfx/eggTexture.cpp"), + Object(Matching, "egg/gfx/eggAnalizeDL.cpp"), + Object(Matching, "egg/gfx/eggCapTexture.cpp"), Object(NonMatching, "egg/gfx/eggCpuTexture.cpp"), Object(NonMatching, "egg/gfx/eggDrawGX.cpp"), - Object(NonMatching, "egg/gfx/eggDrawPathBase.cpp"), - Object(NonMatching, "egg/gfx/eggDrawPathUnk1.cpp"), + Object(Matching, "egg/gfx/eggDrawPathBase.cpp"), + Object(NonMatching, "egg/gfx/eggDrawPathBloom.cpp"), Object(NonMatching, "egg/gfx/eggDrawPathDOF.cpp"), - Object(NonMatching, "egg/gfx/eggDrawPathUnk2.cpp"), + Object(Matching, "egg/gfx/eggDrawPathLightMap.cpp"), Object(NonMatching, "egg/gfx/eggFog.cpp"), + Object(Matching, "egg/gfx/eggFogManager.cpp"), Object(NonMatching, "egg/gfx/eggFrustum.cpp"), - Object(NonMatching, "egg/gfx/eggG3DUtility.cpp"), # Unknown Guess - Object(NonMatching, "egg/gfx/eggGfxEngine.cpp"), - Object(NonMatching, "egg/gfx/eggGlobalDrawState.cpp"), + Object(NonMatching, "egg/gfx/eggG3DUtility.cpp"), + Object(Matching, "egg/gfx/eggGfxEngine.cpp"), + Object(Matching, "egg/gfx/eggGlobalDrawState.cpp"), Object(NonMatching, "egg/gfx/eggGXUtility.cpp"), - Object(NonMatching, "egg/gfx/eggIScnProc.cpp"), - Object(NonMatching, "egg/gfx/eggLight.cpp"), - Object(NonMatching, "egg/gfx/eggLightTexture.cpp"), - Object(NonMatching, "egg/gfx/eggLightTextureMgr.cpp"), - Object(NonMatching, "egg/gfx/eggModelEx.cpp"), - Object(NonMatching, "egg/gfx/eggPostEffectBase.cpp"), - Object(NonMatching, "egg/gfx/eggPostEffectBlur.cpp"), - Object(NonMatching, "egg/gfx/eggPostEffectUnk1.cpp"), # Unknown + Object(Matching, "egg/gfx/eggIScnProc.cpp"), + Object(NonMatching, "egg/gfx/eggLightManager.cpp"), + Object(NonMatching, "egg/gfx/eggLightObject.cpp"), + Object(Matching, "egg/gfx/eggLightTexture.cpp"), + Object(Matching, "egg/gfx/eggLightTextureMgr.cpp"), + Object(Matching, "egg/gfx/eggModelEx.cpp"), + Object(Matching, "egg/gfx/eggPostEffectBase.cpp"), + Object(Matching, "egg/gfx/eggPostEffectBlur.cpp"), + Object(Matching, "egg/gfx/eggPostEffectBlurGather.cpp"), Object(NonMatching, "egg/gfx/eggPostEffectUnk2.cpp"), # Unknown - Object(NonMatching, "egg/gfx/eggPostEffectMask.cpp"), + Object(Matching, "egg/gfx/eggPostEffectMask.cpp"), Object(NonMatching, "egg/gfx/eggPostEffectMaskDOF.cpp"), - Object(NonMatching, "egg/gfx/eggPostEffectSimple.cpp"), - Object(NonMatching, "egg/gfx/eggScreen.cpp"), - Object(NonMatching, "egg/gfx/eggScreenEffectBase.cpp"), + Object(Matching, "egg/gfx/eggPostEffectSimple.cpp"), + Object(Matching, "egg/gfx/eggScreen.cpp"), + Object(Matching, "egg/gfx/eggScreenEffectBase.cpp"), Object(NonMatching, "egg/gfx/eggScreenEffectBlur.cpp"), # Unknown Guess Object(NonMatching, "egg/gfx/eggStateEfb.cpp"), - Object(NonMatching, "egg/gfx/eggStateGX.cpp"), - Object(NonMatching, "egg/gfx/eggTextureBuffer.cpp"), + Object(Matching, "egg/gfx/eggStateGX.cpp"), + Object(Matching, "egg/gfx/eggTextureBuffer.cpp"), ], ), EGGLib( diff --git a/include/egg/core/eggDisplay.h b/include/egg/core/eggDisplay.h index 08c02c1e..cdf2fe7a 100644 --- a/include/egg/core/eggDisplay.h +++ b/include/egg/core/eggDisplay.h @@ -5,6 +5,7 @@ #include "egg/core/eggSystem.h" // for BaseSystem config #include "egg/core/eggVideo.h" #include "egg/prim/eggBitFlag.h" +#include "nw4r/ut/ut_Color.h" #include "nw4r/ut.h" // IWYU pragma: export #include "rvl/VI.h" // IWYU pragma: export @@ -49,6 +50,14 @@ public: void calcFrequency(); void setBlack(bool b) {} + nw4r::ut::Color getClearColor() const { + return mClearColor; + } + + void setClearColor(nw4r::ut::Color color) { + mClearColor = color; + } + public: static u32 sTickPeriod; }; diff --git a/include/egg/egg_types.h b/include/egg/egg_types.h index c1ff24f8..1b218479 100644 --- a/include/egg/egg_types.h +++ b/include/egg/egg_types.h @@ -25,7 +25,7 @@ class GXUtility; class IDrawGX; class IScnProc; class IScnProcModel; -class LightObj; +class LightObject; class LightManager; class LightTexture; class LightTextureManager; @@ -36,7 +36,10 @@ class PostEffectBase; class PostEffectBlur; class PostEffectBlurGather; class PostEffectHDR; +class PostEffectMask; +class PostEffectMaskDOF; class PostEffectSimple; +class PostEffectUnk2; class ResTIMG; class ScnRenderer; class ScnRootEx; diff --git a/include/egg/gfx/eggAnalizeDL.h b/include/egg/gfx/eggAnalizeDL.h new file mode 100644 index 00000000..f89cfa7b --- /dev/null +++ b/include/egg/gfx/eggAnalizeDL.h @@ -0,0 +1,60 @@ +#ifndef EGG_ANALIZE_DL_H +#define EGG_ANALIZE_DL_H + +#include "nw4r/g3d/res/g3d_resshp.h" +#include "rvl/GX/GXAttr.h" + +namespace EGG { + +class AnalizeDL { +public: + enum Status { + STATUS_NONE, + STATUS_1, + STATUS_2, + STATUS_3, + STATUS_VTX = 4, + STATUS_5, + STATUS_END = 6, + }; + + struct VtxResult { + /* 0x00 */ s32 mMtxIdx; + /* 0x04 */ s32 field_0x04; + /* 0x08 */ Vec field_0x08; + }; + +private: + /* 0x000 */ u8 *mpData; + /* 0x004 */ u32 mBufSize; + /* 0x008 */ u32 mCursor; + /* 0x00C */ u8 field_0x00C; + /* 0x00D */ u8 field_0x00D; + /* 0x00E */ u8 field_0x00E; + /* 0x00F */ u8 field_0x00F; + /* 0x010 */ u16 field_0x010; + /* 0x014 */ GXVtxDescList mVtxDescList[22]; + /* 0x0C4 */ GXVtxAttrFmtList mAttrFmtList[13]; + /* 0x194 */ u8 mArrStride; + /* 0x198 */ const void *mpArr; + /* 0x19C */ Status mStatus; + /* 0x1A0 */ s16 field_0x1A0[10]; + /* 0x1B4 */ s16 field_0x1B4[10]; + /* 0x1C8 */ u8 field_0x1C8; + /* 0x1CA */ u16 field_0x1CA; + /* 0x1CC */ u16 field_0x1CC; + /* 0x1D0 */ VtxResult mVtxResult; + + void init(); + +public: + AnalizeDL(nw4r::g3d::ResShp shp); + virtual ~AnalizeDL() {} + + Status step(); + const VtxResult &getVtxResult() const; +}; + +} // namespace EGG + +#endif diff --git a/include/egg/gfx/eggCamera.h b/include/egg/gfx/eggCamera.h index 58937440..c3104fb7 100644 --- a/include/egg/gfx/eggCamera.h +++ b/include/egg/gfx/eggCamera.h @@ -1,6 +1,77 @@ #ifndef EGG_CAMERA_H #define EGG_CAMERA_H -namespace EGG {} // namespace EGG +#include "egg/math/eggMatrix.h" +#include "egg/math/eggRotation.h" +#include "egg/math/eggVector.h" +#include "nw4r/g3d/g3d_camera.h" + +namespace EGG { + +class BaseCamera { +public: + BaseCamera() {} + virtual Matrix34f &getViewMatrix() = 0; + virtual const Matrix34f &getViewMatrix() const = 0; + virtual void updateMatrix(); + virtual void doUpdateMatrix() = 0; + virtual void loadMatrix() = 0; + virtual void loadOldMatrix() = 0; + virtual EGG::Vector3f getPosition() = 0; + virtual void draw(EGG::BaseCamera *cam); + virtual void doDraw() = 0; + virtual Matrix34f &getViewMatrixOld() = 0; + + void setG3DCamera(nw4r::g3d::Camera &); + // Vector3f getRightVector(); + // Vector3f getLookVector(); + // Vector3f getUpVector(); + +protected: + /* 0x04 */ Matrix34f mViewMtx; + /* 0x34 */ Matrix34f mOtherMtx; +}; + +class LookAtCamera : public BaseCamera { +public: + LookAtCamera() : mPos(0.0f, 10.0f, 0.0f), mAt(0.0f, 0.0f, 0.0f), mUp(0.0f, 1.0f, 0.0f) {} + // Which way around? + virtual Matrix34f &getViewMatrix() override { + return mViewMtx; + } + virtual const Matrix34f &getViewMatrix() const override { + return mViewMtx; + } + + virtual void doUpdateMatrix() override; + virtual void loadMatrix() override; + virtual void loadOldMatrix() override; + virtual EGG::Vector3f getPosition() override { + return mPos; + } + + virtual void doDraw() override; + virtual Matrix34f &getViewMatrixOld() override; + +protected: + /* 0x64 */ Vector3f mPos; + /* 0x70 */ Vector3f mAt; + /* 0x7C */ Vector3f mUp; +}; + +class OrthoCamera : public LookAtCamera { +public: + OrthoCamera(); + + virtual void doUpdateMatrix() override; + +private: + void update_parms(); + + /* 0x88 */ EGG::Rotation field_0x88; + /* 0x8C */ EGG::Rotation field_0x8C; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggCapTexture.h b/include/egg/gfx/eggCapTexture.h index 6fea561c..a3887e5b 100644 --- a/include/egg/gfx/eggCapTexture.h +++ b/include/egg/gfx/eggCapTexture.h @@ -1,6 +1,55 @@ #ifndef EGG_CAP_TEXTURE_H #define EGG_CAP_TEXTURE_H -namespace EGG {} // namespace EGG +#include "egg/gfx/eggCpuTexture.h" +#include "rvl/GX/GXTypes.h" +namespace EGG { + +struct CopyFilter { + u8 values[7]; +}; + +class CapTexture : public CpuTexture { +public: + CapTexture() {} + CapTexture(u16 width, u16 height, GXTexFmt texFmt) : CpuTexture(width, height, texFmt) {} + CapTexture(const GXTexObj *pObj) : CpuTexture(pObj) {} + + virtual void configure() override; // at 0xC + + void capture(u16 x, u16 y, bool upscale, int format); + void fn_8049D9D0(u8 arg); + + void setPixModeSync(bool enable) { + if (enable) { + mCapFlags |= 0x10; + } else { + mCapFlags &= ~0x10; + } + } + + void onCapFlag(u8 flag) { + mCapFlags |= flag; + } + void offCapFlag(u8 flag) { + mCapFlags &= ~flag; + } + + void setClearColor(const GXColor &clr) { + mClearColor = clr; + } + + void setCopyFilter(const CopyFilter &filt) { + mCopyFilterArg = filt; + } + +private: + /* 0x18 */ u8 mCapFlags; + /* 0x19 */ GXColor mClearColor; + /* 0x20 */ u32 field_0x20; + /* 0x24 */ CopyFilter mCopyFilterArg; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggCpuTexture.h b/include/egg/gfx/eggCpuTexture.h index c63c6852..a3e4db22 100644 --- a/include/egg/gfx/eggCpuTexture.h +++ b/include/egg/gfx/eggCpuTexture.h @@ -1,13 +1,133 @@ #ifndef EGG_CPU_TEXTURE_H #define EGG_CPU_TEXTURE_H +#include "common.h" +#include "egg/core/eggHeap.h" +#include "egg/gfx/eggTexture.h" #include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" + namespace EGG { class CpuTexture { - public: - void GetTexObj(GXTexObj *) const; + enum TexFlag { + CONFIGURED = 0x1, + HAS_HEADER = 0x2, + NEEDS_BUFFER_FREE = 0x4, + }; + + virtual ~CpuTexture(); // at 0x8 + virtual void configure(); // at 0xC + + void getTexObj(GXTexObj *) const; // at 0x10 + void load(GXTexMapID) const; // at 0x14 + + CpuTexture(); + CpuTexture(u16 width, u16 height, GXTexFmt texFmt); + CpuTexture(const GXTexObj *pObj); + + void checkTexBuffer() const; + void invalidate() const; + void flush() const; + void alloc(Heap *heap); + void allocWithHeaderDebug(Heap *heap); + void allocate(Heap *heap); + + u32 getTexBufferSize() const; + void buildHeader() const; + ResTIMG *initHeader(); + + void fillNormalMapSphere(f32, f32); + void fillGradient(int op, int, u16, u16, const GXColor &, const GXColor &, bool, bool); + + void setColor(u16 x, u16 y, GXColor color); + GXColor getColor(u16 x, u16 y) const; + + bool checkIsConfigure() const { + return mFlags & CONFIGURED; + } + bool checkHasHeader() const { + return mFlags & HAS_HEADER; + } + + void setFlag(u8 flag) { + mFlags |= flag; + } + void clearFlag(u8 flag) { + mFlags &= ~flag; + } + + u16 getWidth() const { + return mWidth; + } + void setWidth(u16 w) { + mWidth = w; + } + + u16 getHeight() const { + return mHeight; + } + // Needed for PostEffectMaskDOF::setUpGradation + u16 getHeight2() { + return mHeight; + } + void setHeight(u16 h) { + mHeight = h; + } + + GXTexFmt getFormat() const { + return (GXTexFmt)mTexFormat; + } + void setFormat(GXTexFmt fmt) { + mTexFormat = fmt; + } + + void setWrapS(GXTexWrapMode wrap) { + mWrapS = wrap; + } + void setWrapT(GXTexWrapMode wrap) { + mWrapT = wrap; + } + + void setWrap(GXTexWrapMode wrapS, GXTexWrapMode wrapT) { + mWrapS = wrapS; + mWrapT = wrapT; + } + + void setFilt(GXTexFilter min, GXTexFilter mag) { + mMinFilt = min; + mMagFilt = mag; + } + + void setMinFilt(GXTexFilter filt) { + mMinFilt = filt; + } + void setMagFilt(GXTexFilter filt) { + mMagFilt = filt; + } + + ResTIMG *getHeader() const { + return (ResTIMG *)((u8 *)dataPtr - sizeof(ResTIMG)); + } + + void *getBuffer() const { + return dataPtr; + } + void setBuffer(void *pBuffer); + +protected: + u16 mWidth; // at 0x4 + u16 mHeight; // at 0x6 + u8 mFlags; // at 0x8 + u8 mTexFormat; // at 0x9 + u8 mWrapS; // at 0xA + u8 mWrapT; // at 0xB + u8 mMinFilt; // at 0xC + u8 mMagFilt; // at 0xD + u8 UNK_0xE[2]; + void *dataPtr; // at 0x10 + char *mpBuffer; // at 0x14 }; } // namespace EGG diff --git a/include/egg/gfx/eggDrawGX.h b/include/egg/gfx/eggDrawGX.h index 1fc4f6b8..33d5e37a 100644 --- a/include/egg/gfx/eggDrawGX.h +++ b/include/egg/gfx/eggDrawGX.h @@ -5,13 +5,39 @@ #include "egg/core/eggHeap.h" #include "egg/gfx/eggTexture.h" #include "egg/math/eggMatrix.h" -#include "rvl/GX.h" // IWYU pragma: export +#include "nw4r/g3d/res/g3d_restex.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/GX.h" // IWYU pragma: export namespace EGG { class DrawGX { public: + DrawGX() {} + // made up + struct DLData { + u8 *mpList; + u32 mLen; + }; + + // made up, stride 0xC + struct ZModeConfig { + bool mTest; + GXCompare mCompare; + bool mUpdate; + }; + + // made up, stride 0x10 + struct BlendModeConfig { + GXBlendMode mBlendMode; + GXBlendFactor mBlendFactorSrc; + GXBlendFactor mBlendFactorDst; + GXLogicOp mLogicOp; + }; + enum DL { DL_0, DL_1, @@ -35,26 +61,131 @@ public: DL_MAX }; + enum VtxType { + VTX_TYPE_0, + VTX_TYPE_1, + VTX_TYPE_2, + VTX_TYPE_3, + VTX_TYPE_4, + VTX_TYPE_5, + VTX_TYPE_6, + VTX_TYPE_7, + VTX_TYPE_8, + VTX_TYPE_9, + VTX_TYPE_10, + VTX_TYPE_11, + VTX_TYPE_12, + VTX_TYPE_13 + }; + + enum Blend { + BLEND_0, + BLEND_1, + BLEND_2, + BLEND_3, + BLEND_4, + BLEND_5, + BLEND_6, + BLEND_7, + BLEND_8, + BLEND_9, + BLEND_10, + BLEND_11, + BLEND_12, + BLEND_13, + BLEND_14, + + BLEND_MAX + }; + + enum ZMode { + ZMODE_0, + ZMODE_1, + ZMODE_2, + ZMODE_3, + + ZMODE_MAX, + }; + + enum TevSetting { + TEV_0, + TEV_1, + TEV_2, + }; + + enum TexGen { + TEXGEN_0, + TEXGEN_1, + }; + + enum ColorChannel { + COLORCHAN_0, + COLORCHAN_1, + }; + static void Initialize(Heap *); static GXTexMapID GetTexMapDefault(); - static void LoadTexture(const EGG::ResTIMG *, GXTexMapID); - static void BeginDrawScreen(bool, bool, bool); - static void DrawDL(enum DL, const nw4r::math::MTX34 &, GXColor); + static GXLightID GetLightMaskDefault(); + static void BeginDrawLine(ColorChannel, ZMode); + static void BeginDrawCircleZ(ColorChannel, ZMode); + static void BeginDrawQuad(ColorChannel, ZMode, Blend, bool, bool); + static void BeginDrawScreen(bool, bool, bool); + + static void DrawLineStrip(const EGG::Vector3f *, u16, GXColor, u8); + static void DrawLine(const EGG::Vector3f *, u16, GXColor, u8); + static void ClearEfb(const nw4r::math::MTX34 &, bool, bool, bool, GXColor, bool); + static void ResetMaterial(enum ColorChannel); + static void SetMat_ColorChannel(enum ColorChannel); + static void SetMat_TexGen(enum TexGen); + static void SetMat_Ind(); + static void SetMat_Tev(GXTevStageID, enum TevSetting); + static void SetMat_PE(enum ZMode, enum Blend); + + static void LoadTexture(const EGG::ResTIMG *, GXTexMapID); + static void LoadTexture(nw4r::g3d::ResTex, GXTexMapID); + + static void CreateDisplayList(EGG::Heap *); + static void DrawDL(enum DL, const nw4r::math::MTX34 &, GXColor); + static void SetVtxState(enum VtxType); + static void SetZMode(enum ZMode); + static void SetBlendMode(enum Blend); + static void DrawDLWorld(DL dl, const EGG::Matrix34f &mtx, GXColor color); + + static void DrawDL16(const nw4r::math::MTX34 &mtx, GXColor clr) { + DrawDL(DL_16, mtx, clr); + } // TODO MORE - /* static ?? s_DL */ + static void SetTevColor(GXTevRegID regId, GXColor tevClr, GXTevKColorID colorId, GXColor tevkClr) { + GXSetTevColor(regId, tevClr); + GXSetTevKColor(colorId, tevkClr); + } - static Matrix34f s_cameraMtx; + // not sure + static DLData s_DL[DL_MAX]; + static const DL s_DL0; + static const DL s_DL7; + static const DL s_DL8; - /* static ?? s_flag */ + static const ZModeConfig s_ZMode[ZMODE_MAX]; + static const BlendModeConfig s_Blend[BLEND_MAX]; + static GXTexObj sDummyTexObj; + // not sure end - static GXColor BLACK; - static GXColor WHITE; - static GXColor GREEN; - static GXColor RED; - static GXColor BLUE; + static GXTexMapID sTexMapDefault; + static GXLightID sLightMaskDefault; + + static nw4r::math::MTX34 s_cameraMtx; + + static u32 s_flag; + + static const GXColor BLACK; + static const GXColor WHITE; + static const GXColor GREEN; + static const GXColor RED; + static const GXColor BLUE; }; } // namespace EGG diff --git a/include/egg/gfx/eggDrawPathBase.h b/include/egg/gfx/eggDrawPathBase.h index 536864b3..f1e91613 100644 --- a/include/egg/gfx/eggDrawPathBase.h +++ b/include/egg/gfx/eggDrawPathBase.h @@ -1,6 +1,30 @@ #ifndef EGG_DRAW_PATH_BASE_H #define EGG_DRAW_PATH_BASE_H -namespace EGG {} // namespace EGG +#include "egg/egg_types.h" +#include "egg/gfx/eggIScnProc.h" +#include "egg/gfx/eggScreenEffectBase.h" +#include "nw4r/g3d/g3d_scnobj.h" + +namespace EGG { + +class DrawPathBase : public ScreenEffectBase, public IScnProc, public nw4r::g3d::IScnObjCallback { +public: + DrawPathBase(); + + void createScnProc(MEMAllocator *allocator); + +protected: + virtual u16 getNumStep() const = 0; // at 0x3C + virtual void internalResetForDraw() {} // at 0x40 + virtual void internalDraw(u16) = 0; // at 0x44 + + virtual void ExecCallback_CALC_VIEW( + nw4r::g3d::ScnObj::Timing /* timing */, nw4r::g3d::ScnObj * /* pObj */, u32 /* param */, void * /* pInfo */ + ) override; // also at 0x48 + virtual void scnProcDraw(u16) override; // also at 0x4C +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggDrawPathBloom.h b/include/egg/gfx/eggDrawPathBloom.h new file mode 100644 index 00000000..eca7b2b7 --- /dev/null +++ b/include/egg/gfx/eggDrawPathBloom.h @@ -0,0 +1,75 @@ +#ifndef EGG_DRAW_PATH_BLOOM_H +#define EGG_DRAW_PATH_BLOOM_H + +#include "egg/gfx/eggDrawPathBase.h" +#include "egg/gfx/eggPostEffectBlur.h" +#include "egg/gfx/eggPostEffectBlurGather.h" +#include "egg/gfx/eggPostEffectMask.h" +#include "egg/gfx/eggPostEffectSimple.h" +#include "egg/prim/eggBinary.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +class DrawPathBloom : public DrawPathBase, public IBinary { + struct BinData {}; + + // Size 0x20? + struct SubData { + /* 0x00 */ f32 field_0x00; + /* 0x04 */ f32 field_0x04; + /* 0x08 */ u8 field_0x08; + /* 0x09 */ u8 _0x09[0x20 - 0x09]; + }; + + // Not sure about this union thing but need to prevent compiler + // from trying fancy struct copying + struct Data { + union { + struct { + /* 0x00 */ f32 field_0x00; + /* 0x04 */ GXColor field_0x04; + /* 0x08 */ GXColor field_0x08; + /* 0x0C */ u16 field_0x0C; + /* 0x10 */ SubData field_0x10[3]; + /* 0x50 */ u8 field_0x50; + /* 0x51 */ u8 field_0x51; + /* 0x52 */ u8 field_0x52; + /* 0x53 */ u8 _0x53[0x6C - 0x53]; + /* 0x6C */ f32 field_0x6C; + /* 0x70 */ f32 field_0x70; + + }; + }; + }; + +public: + DrawPathBloom(); + virtual ~DrawPathBloom(); + + virtual u16 getNumStep() const override { + return 3; + } + + virtual void internalResetForDraw() override; + virtual void internalDraw(u16) override; + + virtual void SetBinaryInner(const Bin &) override; + virtual void GetBinaryInner(Bin *) const override; + virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; + +private: + /* 0x01C */ u8 field_0x01C; + /* 0x01D */ u8 field_0x01D; + /* 0x020 */ PostEffectMask mMask; + /* 0x1E0 */ PostEffectBlur mBlur1; + /* 0x258 */ PostEffectBlur mBlur2; + /* 0x2D0 */ PostEffectBlurGather mBlurGather; + /* 0x340 */ PostEffectSimple mSimple; + /* 0x37C */ u32 field_0x37C; + /* 0x380 */ Data field_0x380; +}; + +} // namespace EGG + +#endif diff --git a/include/egg/gfx/eggDrawPathDOF.h b/include/egg/gfx/eggDrawPathDOF.h index 054464d1..055e603a 100644 --- a/include/egg/gfx/eggDrawPathDOF.h +++ b/include/egg/gfx/eggDrawPathDOF.h @@ -1,6 +1,69 @@ #ifndef EGG_DRAW_PATH_DOF_H #define EGG_DRAW_PATH_DOF_H -namespace EGG {} // namespace EGG +#include "egg/gfx/eggDrawPathBase.h" +#include "egg/gfx/eggTextureBuffer.h" +#include "egg/prim/eggBinary.h" +#include "egg/egg_types.h" + +namespace EGG { + +class DrawPathDOF : public DrawPathBase, public IBinary { +public: + class BinData { + // TODO + }; + DrawPathDOF(); + virtual ~DrawPathDOF(); + + virtual u16 getNumStep() const override { + return 3; + } + virtual void internalResetForDraw() override; + virtual void internalDraw(u16) override; + + virtual void SetBinaryInner(const Bin &) override; + virtual void GetBinaryInner(Bin *) const override; + virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; + + + void execute(); + +private: + void internalDrawVariant01(u16); + void internalDrawVariant2(u16); + + void afterDraw(u16 x, u16 y, u16 width, u16 height); + + /* 0x1C */ u16 field_0x1C; + /* 0x1E */ u8 field_0x1E; + /* 0x1F */ u8 field_0x1F; + /* 0x20 */ s32 field_0x20; + /* 0x24 */ f32 field_0x24; + /* 0x28 */ f32 field_0x28; + /* 0x2C */ f32 field_0x2C; + /* 0x30 */ f32 field_0x30; + /* 0x34 */ s32 field_0x34; + /* 0x38 */ s32 field_0x38; + + /* 0x3C */ u8 _0x3C[0x5C - 0x3C]; + + /* 0x5C */ f32 field_0x5C; + /* 0x60 */ f32 field_0x60; + /* 0x64 */ f32 field_0x64; + /* 0x68 */ f32 field_0x68; + /* 0x6C */ f32 field_0x6C; + /* 0x70 */ f32 field_0x70; + /* 0x74 */ f32 field_0x74; + /* 0x78 */ f32 field_0x78; + /* 0x7C */ f32 field_0x7C; + /* 0x80 */ u8 field_0x80; + /* 0x84 */ PostEffectBlur *mpBlur; + /* 0x88 */ PostEffectMaskDOF *mpMaskDof; + /* 0x8C */ TextureBuffer *mpTextureBuffer; + /* 0x90 */ PostEffectMask *mpMask; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggDrawPathLightMap.h b/include/egg/gfx/eggDrawPathLightMap.h new file mode 100644 index 00000000..9fed2ac8 --- /dev/null +++ b/include/egg/gfx/eggDrawPathLightMap.h @@ -0,0 +1,36 @@ +#ifndef EGG_DRAW_PATH_LIGHTMAP_H +#define EGG_DRAW_PATH_LIGHTMAP_H + +#include "egg/gfx/eggDrawPathBase.h" +#include "egg/gfx/eggTextureBuffer.h" + +namespace EGG { + +// A guess based of what is seen in ogws. Has been Updated +class DrawPathLightMap : public DrawPathBase { +public: + DrawPathLightMap(); + + virtual u16 getNumStep() const override { + return 3; + } + virtual void internalResetForDraw() override; + virtual void internalDraw(u16) override; + virtual ~DrawPathLightMap(); + void freeTextureBuffers(); + +private: + /* 0x18 */ u8 field_0x18; + /* 0x19 */ u8 mAlpha; + /* 0x1C */ int field_0x1C; + /* 0x20 */ int field_0x20; + /* 0x24 */ u32 field_0x24; + /* 0x28 */ TextureBuffer *mpTextureBuffer_0x28; + /* 0x2C */ TextureBuffer *mpTextureBuffer_0x2C; + /* 0x30 */ TextureBuffer *mpTextureBuffer_0x30; + /* 0x34 */ u32 mOldDrawFlag; +}; + +} // namespace EGG + +#endif diff --git a/include/egg/gfx/eggDrawPathUnk1.h b/include/egg/gfx/eggDrawPathUnk1.h deleted file mode 100644 index 4b2c3cc7..00000000 --- a/include/egg/gfx/eggDrawPathUnk1.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef EGG_DRAW_PATH_UNK1_H -#define EGG_DRAW_PATH_UNK1_H - -namespace EGG {} // namespace EGG - -#endif diff --git a/include/egg/gfx/eggDrawPathUnk2.h b/include/egg/gfx/eggDrawPathUnk2.h deleted file mode 100644 index 3b04c908..00000000 --- a/include/egg/gfx/eggDrawPathUnk2.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef EGG_DRAW_PATH_UNK2_H -#define EGG_DRAW_PATH_UNK2_H - -namespace EGG {} // namespace EGG - -#endif diff --git a/include/egg/gfx/eggFog.h b/include/egg/gfx/eggFog.h index 43f9a8d5..13d1bb94 100644 --- a/include/egg/gfx/eggFog.h +++ b/include/egg/gfx/eggFog.h @@ -1,26 +1,46 @@ #ifndef EGG_FOG_H #define EGG_FOG_H +#include "common.h" #include "egg/prim/eggBinary.h" +#include "nw4r/g3d/g3d_fog.h" #include "nw4r/types_nw4r.h" +#include "rvl/GX/GXTypes.h" namespace EGG { -// TODO: Add members -class FogManager : IBinary { +class Fog : public IBinary { public: - FogManager(u16); - virtual ~FogManager(); - virtual void SetBinaryInner(Bin &) override; + struct BinData { + /* 0x10 */ f32 mStartZ; + /* 0x14 */ f32 mEndZ; + /* 0x18 */ f32 mNearZ; + /* 0x1C */ f32 mFarZ; + /* 0x20 */ GXColor mColor; + /* 0x24 */ u8 field_0x24; + /* 0x25 */ u8 mFlag2; + /* 0x26 */ u16 field_0x26; + /* 0x28 */ UNKWORD field_0x28; + /* 0x2C */ UNKWORD field_0x2C; + }; + Fog(); + virtual ~Fog(); + virtual void SetBinaryInner(const Bin &) override; virtual void GetBinaryInner(Bin *) const override; - virtual size_t GetBinarySize() override; virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; - void Calc(); - void CopyToG3D(nw4r::g3d::ScnRoot *) const; + void CopyToG3D(nw4r::g3d::Fog fof) const; + void Reset(); - /* 0x04 */ u8 mFlag; - /* 0x05 */ u8 TODO[0x10 - 0x05]; +private: + + /* 0x04 */ GXColor mColor; + /* 0x08 */ f32 mStartZ; + /* 0x0C */ f32 mEndZ; + /* 0x10 */ f32 mNearZ; + /* 0x14 */ f32 mFarZ; + /* 0x18 */ GXFogType mFogType; + /* 0x1C */ u8 mFlags; }; } // namespace EGG diff --git a/include/egg/gfx/eggFogManager.h b/include/egg/gfx/eggFogManager.h new file mode 100644 index 00000000..589b5041 --- /dev/null +++ b/include/egg/gfx/eggFogManager.h @@ -0,0 +1,44 @@ +#ifndef EGG_FOG_MANAGER_H +#define EGG_FOG_MANAGER_H + +#include "common.h" +#include "egg/gfx/eggFog.h" +#include "egg/prim/eggBinary.h" +#include "nw4r/types_nw4r.h" + +namespace EGG { + +// TODO: Add members +class FogManager : IBinary { +public: + struct BinData { + /* 0x10 */ u16 mCount; + /* 0x12 */ u8 _0x12[2]; + /* 0x14 */ IBinary::Bin mFogData[1]; + }; + FogManager(u16); + virtual ~FogManager(); + virtual void SetBinaryInner(const Bin &) override; + virtual void GetBinaryInner(Bin *) const override; + virtual size_t GetBinarySize() const override; + virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; + + void ResetFog(); + void Calc(); + void CopyToG3D(nw4r::g3d::ScnRoot *) const; + + void DoneDraw() { + mFlag &= ~4; + } + +private: + /* 0x04 */ u8 mFlag; + /* 0x05 */ u8 TODO[0x08 - 0x05]; + /* 0x08 */ u16 mCount; + /* 0x0A */ u16 mCount2; + /* 0x0C */ Fog *mpFog; +}; + +} // namespace EGG + +#endif diff --git a/include/egg/gfx/eggFrustum.h b/include/egg/gfx/eggFrustum.h index 568b6d73..ded3ea33 100644 --- a/include/egg/gfx/eggFrustum.h +++ b/include/egg/gfx/eggFrustum.h @@ -1,38 +1,66 @@ #ifndef EGG_FRUSTUM_H #define EGG_FRUSTUM_H -#include "common.h" #include "nw4r/g3d/g3d_camera.h" namespace EGG { - -// TODO: Fill out more class Frustum { public: - enum CanvasMode { + enum Flag { + FLAG_DIRTY = (1 << 0), + FLAG_0x02 = (1 << 1), + FLAG_0x04 = (1 << 2), + FLAG_0x08 = (1 << 3), + FLAG_0x20 = (1 << 5), + FLAG_0x40 = (1 << 6), }; + enum ProjectionType { PROJ_ORTHO, PROJ_PERSP }; -private: - /* 0x00 */ ProjectionType mProjType; - /* 0x04 */ CanvasMode mCanvasMode; - /* 0x08 */ nw4r::math::VEC2 mSize; - /* 0x10 */ f32 mFovY; - /* 0x14 */ f32 mTanFovY; - /* 0x18 */ f32 mNearZ; - /* 0x1C */ f32 mFarZ; - /* 0x20 */ nw4r::math::VEC2 mOffset; - /* 0x28 */ nw4r::math::VEC3 mScale; - /* 0x34 */ mutable u16 mFlags; + enum CanvasMode { + CANVASMODE_0, + CANVASMODE_1, + }; + +protected: + ProjectionType mProjType; // at 0x0 + CanvasMode mCanvasMode; // at 0x4 + nw4r::math::VEC2 mSize; // at 0x8 + f32 mFovY; // at 0x10 + f32 mTanFovY; // at 0x14 + f32 mNearZ; // at 0x18 + f32 mFarZ; // at 0x1C + nw4r::math::VEC2 mOffset; // at 0x20 + nw4r::math::VEC3 mScale; // at 0x28 + mutable u16 mFlags; // at 0x34 public: - // vt at 0x38 - virtual ~Frustum() {} - virtual void SetProjectionGX() const; - virtual void CopyToG3D(nw4r::g3d::Camera) const; + Frustum(ProjectionType, const nw4r::math::VEC2 &, f32, f32, CanvasMode); + Frustum(const Frustum &); + + virtual ~Frustum() {} // at 0x8 + virtual void SetProjectionGX() const; // at 0xC + virtual void CopyToG3D(nw4r::g3d::Camera) const; // at 0x10 + void ResetOrthographic(f32, f32, f32, f32, f32, f32); + void CopyFromAnother(const Frustum &); + void SetFovy(f32); + void ConvertToCanvasLU(f32, f32, f32 *, f32 *) const; + + static void SetGlobalScaleOffset(f32, f32, f32, f32); + static void GetGlobalScaleOffset(f32 *, f32 *, f32 *, f32 *); + + f32 GetScreenSizeToViewSize(f32, f32) const; + + void SetDirty(bool dirty) const { + if (dirty) { + mFlags |= FLAG_DIRTY; + } else { + mFlags &= ~FLAG_DIRTY; + } + } ProjectionType GetProjectionType() const { return mProjType; @@ -41,7 +69,65 @@ public: mProjType = type; } - void ResetOrthographic(f32, f32, f32, f32, f32, f32); + CanvasMode GetCanvasMode() const { + return mCanvasMode; + } + void SetCanvasMode(CanvasMode mode) { + if (mode != mCanvasMode) { + SetDirty(true); + mCanvasMode = mode; + } + } + + const nw4r::math::VEC2 &GetSize() const { + return mSize; + } + + u16 GetWidth() const { + return mSize.x; + } + f32 GetSizeX() const { + return mSize.x; + } + void SetSizeX(f32 sizeX) { + SetDirty(true); + mSize.x = sizeX; + } + + u16 GetHeight() const { + return mSize.y; + } + f32 GetSizeY() const { + return mSize.y; + } + void SetSizeY(f32 sizeY) { + SetDirty(true); + mSize.y = sizeY; + } + + void SetSize(const nw4r::math::VEC2 &size) { + SetSizeX(size.x); + SetSizeY(size.y); + } + + void SetNearZ(f32 nearZ) { + mNearZ = nearZ; + } + f32 GetNearZ() const { + return mNearZ; + } + + void SetFarZ(f32 farZ) { + mFarZ = farZ; + } + f32 GetFarZ() const { + return mFarZ; + } + + void SetNearFar(f32 near, f32 far) { + mNearZ = near; + mFarZ = far; + } void SetScale(const nw4r::math::VEC3 &scale) { mScale = scale; @@ -49,8 +135,50 @@ public: void SetOffset(const nw4r::math::VEC2 &offset) { mOffset = offset; } -}; + void SetFlag(u32 flag) { + mFlags |= flag; + } + + f32 TranslateDepthToViewSpace(f32 depth) const { + depth = -depth; + f32 bound = -1e-6f; + f32 val = depth >= bound ? bound : depth; + ProjectionType proj = GetProjectionType(); + f32 near = mNearZ; + f32 far = mFarZ; + f32 diff = far - near; + f32 viewDepth; + if (proj == PROJ_PERSP) { + viewDepth = ((val * -near) / diff - (far * near) / diff) / -val + 1.0f; + } else { + viewDepth = (-val - near) / diff; + } + if (viewDepth < 0.0f) { + return 0.0f; + } else if (viewDepth > 1.0f) { + return 1.0f; + } + return viewDepth; + } + +private: + void SetProjectionPerspectiveGX_() const; + void SetProjectionOrthographicGX_() const; + + void CopyToG3D_Perspective_(nw4r::g3d::Camera) const; + void CopyToG3D_Orthographic_(nw4r::g3d::Camera) const; + + void CalcMtxPerspective_(nw4r::math::MTX44 *) const; + + void GetOrthographicParam_(f32 *) const; + void GetPerspectiveParam_(f32 *) const; + void GetOrthographicParam_(f32 *, f32 *, f32 *, f32 *) const; + +private: + static nw4r::math::VEC2 sGlobalScale; + static nw4r::math::VEC2 sGlobalOffset; +}; } // namespace EGG #endif diff --git a/include/egg/gfx/eggG3DUtility.h b/include/egg/gfx/eggG3DUtility.h index 994b7376..df570020 100644 --- a/include/egg/gfx/eggG3DUtility.h +++ b/include/egg/gfx/eggG3DUtility.h @@ -1,6 +1,63 @@ #ifndef EGG_G3D_UTILITY_H #define EGG_G3D_UTILITY_H -namespace EGG {} // namespace EGG +#include "egg/egg_types.h" +#include "nw4r/g3d/g3d_scnmdl.h" +#include "nw4r/g3d/res/g3d_resmat.h" +#include "nw4r/math/math_types.h" +#include "rvl/MEM/mem_allocator.h" + +namespace EGG { + +class G3DUtility { +public: + static MEMAllocator *getAllocator() { + return sAllocator; + } + + struct SetTextureResult { + /* 0x00 */ u8 _0x00[2]; + /* 0x02 */ s8 texMapId; + /* 0x03 */ s8 texCoordId; + }; + + struct SearchResult { + /* 0x00 */ u16 nodeIdx; + /* 0x04 */ const char *name; + }; + + static u16 SetTexture( + nw4r::g3d::ResMat resMat, nw4r::g3d::ScnMdl::CopiedMatAccess *param_2, const char *name, const GXTexObj *texObj, + bool copy, SetTextureResult *pResult, int maxNumResults, int param_8 + ); + + static int ApplyLightMat(nw4r::g3d::ResMdl mdl, const char *prefix); + + static bool setUpLightSet(nw4r::g3d::LightSetting &, nw4r::g3d::ResAnmScn, int); + + static void *BumpAlloc(u32 size, u32 align); + static void ResetBumpAlloc() { + sOffset = 0; + } + + static void create(u32 size, Heap *pHeap); + + static int searchStringResNode(nw4r::g3d::ResMdl mdl, const char * name, bool exactMatch, SearchResult *pResults, int maxNumResults); + static int searchStringResMat(nw4r::g3d::ResMdl mdl, const char * name, bool exactMatch, SearchResult *pResults, int maxNumResults); + static int searchStringResTexPlttInfo(nw4r::g3d::ResMdl mdl, const char * name, bool exactMatch, SearchResult *pResults, int maxNumResults); + + typedef int (*MdlSearch)(nw4r::g3d::ResMdl mdl, const char * name, bool exactMatch, SearchResult *pResults, int maxNumResults); + +private: + static void defaultTexMtxFunc(nw4r::math::MTX34 *pMtx, s8 camRef, s8 lightRef); + + static MEMAllocator *sAllocator; + static void *sBuf; + static u32 sSize; + static u32 sOffset; + static u8 sId; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggGXUtility.h b/include/egg/gfx/eggGXUtility.h index d36dfff1..f85f56e0 100644 --- a/include/egg/gfx/eggGXUtility.h +++ b/include/egg/gfx/eggGXUtility.h @@ -1,6 +1,27 @@ #ifndef EGG_GX_UTILITY_H #define EGG_GX_UTILITY_H -namespace EGG {} // namespace EGG +#include "egg/gfx/eggTexture.h" +#include "egg/math/eggVector.h" +#include "nw4r/g3d/res/g3d_restex.h" +#include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +class GXUtility { +public: + static int getTexMtxID(int); + static void setScaleOffsetPerspective(f32*, f32, f32, f32, f32); + static void getTexObj(GXTexObj *, const ResTIMG &); + static void getTexObj(GXTexObj *, nw4r::g3d::ResTex, GXTexWrapMode, GXTexWrapMode, GXTexFilter, GXTexFilter); + + static void getNormalColor(GXColor &outColor, const Vector3f &vec); + +private: + static const u8 s_texMtxIds[8]; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggGfxEngine.h b/include/egg/gfx/eggGfxEngine.h index 56e8d67b..cd1a88ef 100644 --- a/include/egg/gfx/eggGfxEngine.h +++ b/include/egg/gfx/eggGfxEngine.h @@ -2,12 +2,12 @@ #define EGG_GFXENGINE_H #include "common.h" -#include "rvl/GX.h" +#include "rvl/GX/GXTypes.h" namespace EGG { -namespace GfxEngine { - +class GfxEngine { +public: struct Configuration { /* 0x00 */ u16 efbWidth; /* 0x02 */ u16 efbHeight; @@ -18,12 +18,12 @@ struct Configuration { /* 0x10 */ u32 bufferSize; /* 0x14 */ u16 field_0x14; /* 0x16 */ u16 field_0x16; - /* 0x18 */ u8 UNK_0x18[4]; + /* 0x18 */ u8 field_0x18; Configuration(); virtual ~Configuration() {} }; -} // namespace GfxEngine +}; } // namespace EGG diff --git a/include/egg/gfx/eggGlobalDrawState.h b/include/egg/gfx/eggGlobalDrawState.h index 36e5203a..19f38fff 100644 --- a/include/egg/gfx/eggGlobalDrawState.h +++ b/include/egg/gfx/eggGlobalDrawState.h @@ -1,6 +1,45 @@ #ifndef EGG_GLOBAL_DRAW_STATE_H #define EGG_GLOBAL_DRAW_STATE_H -namespace EGG {} // namespace EGG +#include "egg/gfx/eggScreen.h" +#include "nw4r/math/math_types.h" + +namespace EGG { + +class GlobalDrawState { +public: + GlobalDrawState() {} + static void setDrawSettingGX(bool, bool); + static void beginDrawView(u16, nw4r::math::MTX34 const &, Screen const &); + + static const Screen &getScreen() { + return *spScreen; + } + static void setScreen(const Screen &screen) { + spScreen = &screen; + } + static u32 getDrawFlag() { + return sDrawFlag; + } + static void setDrawFlag(u32 flag) { + sDrawFlag = flag; + } + static void onDrawFlag(u32 flag) { + sDrawFlag |= flag; + } + static void offDrawFlag(u32 flag) { + sDrawFlag &= ~flag; + } + + static Screen const *spScreen; +private: + static u16 sCameraId; + static u32 sDrawFlag; + + // unknown + static nw4r::math::MTX34 sMtx; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggIScnProc.h b/include/egg/gfx/eggIScnProc.h index c7ef3ce2..9d033f43 100644 --- a/include/egg/gfx/eggIScnProc.h +++ b/include/egg/gfx/eggIScnProc.h @@ -1,6 +1,48 @@ #ifndef EGG_ISCNPROC_H #define EGG_ISCNPROC_H -namespace EGG {} // namespace EGG +#include "common.h" +#include "nw4r/g3d/g3d_scnproc.h" +#include "rvl/MEM/mem_allocator.h" + +namespace EGG { + +class IScnProc { +protected: + // Unofficial name + struct ProcData { + IScnProc *mpThis; // at 0x0 + nw4r::g3d::ScnProc *mpScnProc; // at 0x4 + u16 mIndex; // at 0x8 + u8 mFlags; // at 0xA + }; + + ProcData *mpDataSet; // at 0x0 + u16 mNumScnProc; // at 0x4 + +public: + IScnProc() : mpDataSet(nullptr), mNumScnProc(0) {} + virtual void scnProcDraw(u16) = 0; // at 0x8 + virtual ~IScnProc(); // at 0xC + + void createScnProc(u16 procNum, MEMAllocator *allocator); + void setPriorityScnProc(u16, u8, bool); + void pushBackToScnGroup(nw4r::g3d::ScnGroup *); + void removeFromScnGroup(nw4r::g3d::ScnGroup *); + static void drawProcFunc(nw4r::g3d::ScnProc *, bool); + static void drawProcFuncNoGlobalState(nw4r::g3d::ScnProc *, bool); + + u16 getNumScnProc() { + return mNumScnProc; + } + ProcData *getData(u16 procIndex) { + return &mpDataSet[procIndex]; + } + nw4r::g3d::ScnProc *getProc(u16 procIndex) { + return mpDataSet[procIndex].mpScnProc; + } +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggIScnProcModel.h b/include/egg/gfx/eggIScnProcModel.h new file mode 100644 index 00000000..254d4832 --- /dev/null +++ b/include/egg/gfx/eggIScnProcModel.h @@ -0,0 +1,24 @@ +#ifndef EGG_I_SCN_PROC_MODEL_H +#define EGG_I_SCN_PROC_MODEL_H + +#include "common.h" +#include "nw4r/math/math_types.h" + +namespace EGG { + +class IScnProcModel { +private: + /* 0x00 */ u8 _0x00[0x08]; + +public: + IScnProcModel() {} + virtual ~IScnProcModel() {} // at 0x8 + virtual void draw(bool, u32) = 0; // at 0xC + virtual UNKTYPE VF_0x10(UNKTYPE) = 0; // at 0x10 + virtual UNKTYPE VF_0x14(UNKTYPE) = 0; // at 0x14 + virtual void getMinMaxScnProcModel(nw4r::math::VEC3 *, nw4r::math::VEC3 *) const = 0; // at 0x18 +}; + +} // namespace EGG + +#endif diff --git a/include/egg/gfx/eggLight.h b/include/egg/gfx/eggLight.h deleted file mode 100644 index 16033dc3..00000000 --- a/include/egg/gfx/eggLight.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef EGG_LIGHT_H -#define EGG_LIGHT_H - -#include "egg/core/eggHeap.h" -#include "egg/prim/eggBinary.h" -#include "nw4r/types_nw4r.h" - -namespace EGG { - -// TODO: Fill out more -class LightTexture { -public: - static void initialize(u16 textureSize, Heap *pHeap); -}; - -// TODO: Fill out more -class LightTextureManager : public IBinary { -public: - virtual ~LightTextureManager(); - virtual void SetBinaryInner(Bin &) override; - virtual void GetBinaryInner(Bin *) const override; - virtual size_t GetBinarySize() override; - virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; - void replaceModelTextures(nw4r::g3d::ResMdl) const; - - void drawAndCaptureTexture(f32, f32, f32, f32); -}; - -// TODO: Fill out more -class LightManager : public IBinary { -public: - // vt at 0x00 - LightManager(u32, u32, u8); - virtual ~LightManager(); - virtual void SetBinaryInner(Bin &) override; - virtual void GetBinaryInner(Bin *) const override; - virtual size_t GetBinarySize() override; - virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; - virtual void Reset(); - virtual void Calc(nw4r::g3d::ScnRoot *); - virtual void CalcView(const nw4r::math::MTX34 &, u8, nw4r::g3d::ScnRoot *); - virtual void DoneDraw(); - - LightTextureManager *GetTextureMgr() const { - return mTextureMgr; - } - - u8 TODO_0x04[0x14 - 0x04]; - LightTextureManager *mTextureMgr; - u8 TODO_0x18[0x28 - 0x18]; -}; - -} // namespace EGG - -#endif diff --git a/include/egg/gfx/eggLightManager.h b/include/egg/gfx/eggLightManager.h new file mode 100644 index 00000000..00aef3a4 --- /dev/null +++ b/include/egg/gfx/eggLightManager.h @@ -0,0 +1,125 @@ +#ifndef EGG_LIGHT_MANAGER_H +#define EGG_LIGHT_MANAGER_H + +#include "egg/egg_types.h" +#include "egg/gfx/eggLightObject.h" +#include "egg/prim/eggBinary.h" +#include "nw4r/g3d/g3d_light.h" +#include "nw4r/g3d/res/g3d_resanmamblight.h" +#include "nw4r/g3d/res/g3d_resanmscn.h" +#include "nw4r/types_nw4r.h" +#include "rvl/GX/GXLight.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +// TODO: Fill out more +class LightManager : public IBinary { + struct LightData { + /* 0x00 */ LightObject mLightObject; + }; + + // ??? + union Counts { + struct { + /* 0x00 */ u8 mNumEggLightObjects; + /* 0x01 */ u8 mNumAmbientObjects; + }; + }; + +public: + struct AmbientObject { + /* 0x00 */ nw4r::g3d::AmbLightObj mLightObj; + /* 0x04 */ const char *mLightName; + /* 0x08 */ u8 field_0x08; + }; + + struct BinAmbient { + /* 0x00 */ u8 field_0x00; + /* 0x01 */ u8 field_0x01; + /* 0x02 */ u8 field_0x02; + /* 0x03 */ u8 field_0x03; + /* 0x04 */ u8 field_0x04; + /* 0x05 */ u8 field_0x05; + /* 0x06 */ u8 field_0x06; + /* 0x07 */ u8 field_0x07; + }; + + struct BinData { + /* 0x00 */ u16 mNumLightObjects; + /* 0x02 */ u16 mNumAmbientObjects; + /* 0x04 */ GXColor mColor; + /* 0x08 */ u8 _0x08[0x18 - 0x08]; + /* 0x18 */ LightObject::Bin mObjData[1]; + }; + + // vt at 0x00 + LightManager(u32, u32, u8); + virtual ~LightManager(); + virtual void SetBinaryInner(const Bin &) override; + virtual void GetBinaryInner(Bin *) const override; + virtual size_t GetBinarySize() const override; + virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; + virtual void Reset(); + virtual void Calc(nw4r::g3d::ScnRoot *); + virtual void CalcView(const nw4r::math::MTX34 &, u8, nw4r::g3d::ScnRoot *); + virtual void DoneDraw(); + + void LoadLightSet(int, u32 *, u32 *, u32 *, u32 *, GXColor *); + + void LoadScnLightInner(nw4r::g3d::ResAnmScn, f32, s16, u32); + + void AnmScnRes_GetAmbLightColor(AmbientObject *, nw4r::g3d::ResAnmAmbLight, f32) const; + + void CopyToG3D_Ambient(nw4r::g3d::ScnRoot *) const; + void CopyToG3D_World(nw4r::g3d::ScnRoot *) const; + void CopyToG3D_View(nw4r::g3d::ScnRoot *, const nw4r::math::MTX34 &) const; + + void BecomeInvalidLight(int); + + LightTextureManager *GetTextureMgr() const { + return mpTextureMgr; + } + + static u16 CheckedNumLightObjs(u8 num) { + return num < 8 ? num : 8; + } + + const LightObject *GetLightObject(int i) const { + return &mpLightData[i].mLightObject; + } + + LightObject *GetLightObject(int i) { + return &mpLightData[i].mLightObject; + } + + const AmbientObject *GetAmbientObject(int i) const { + return &mpAmbientObjects[i]; + } + + u8 GetNumLightData() const { + return mCounts.mNumEggLightObjects; + } + + u8 GetField0x1D() const { + return field_0x1D; + } + +private: + /* 0x04 */ Counts mCounts; + /* 0x06 */ Counts mSavedCounts; + /* 0x08 */ LightData *mpLightData; + /* 0x0C */ AmbientObject *mpAmbientObjects; + /* 0x10 */ GXLightObj *mpLightObjs; + /* 0x14 */ LightTextureManager *mpTextureMgr; + /* 0x18 */ GXColor mColor; + /* 0x1C */ u8 mNumGxObjsPerEggObj; + /* 0x1D */ u8 field_0x1D; + /* 0x1E */ u16 mFlags; + /* 0x20 */ nw4r::g3d::ResAnmScn mResAnmScn; + /* 0x24 */ s16 mRefNumber; +}; + +} // namespace EGG + +#endif diff --git a/include/egg/gfx/eggLightObject.h b/include/egg/gfx/eggLightObject.h new file mode 100644 index 00000000..a072e190 --- /dev/null +++ b/include/egg/gfx/eggLightObject.h @@ -0,0 +1,164 @@ +#ifndef EGG_LIGHT_OBJ_H +#define EGG_LIGHT_OBJ_H + +#include "egg/egg_types.h" +#include "egg/prim/eggBinary.h" +#include "nw4r/g3d/res/g3d_resanmlight.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXLight.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtx.h" + +namespace EGG { + +class LightObject : public IBinary { +public: + struct BinData { + /* 0x00 */ u8 mSpotFn; + /* 0x01 */ u8 mDistAttnFn; + /* 0x02 */ u8 field_0x02; + /* 0x03 */ u8 field_0x03; + /* 0x04 */ u16 mIndex; + /* 0x06 */ u16 mFlags; + /* 0x08 */ Vec mPos; + /* 0x14 */ Vec mAt; + /* 0x20 */ f32 field_0x20; + /* 0x24 */ GXColor mWhite; + /* 0x28 */ GXColor mBlack; + /* 0x2C */ f32 field_0x2C; + /* 0x30 */ f32 field_0x30; + /* 0x34 */ f32 field_0x34; + /* 0x38 */ f32 field_0x38; + /* 0x3C */ u16 field_0x3C; + /* 0x3E */ u16 field_0x3E; + }; + + LightObject(); + virtual ~LightObject() {} + + virtual void SetBinaryInner(const Bin &) override; + virtual void GetBinaryInner(Bin *) const override; + virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; + + void CalcDirDist(); + void Reset(); + void Calc(); + void CalcView(nw4r::math::MTX34 const &); + + void fn_804A9C30(const LightTexture *, nw4r::math::VEC3 *, GXColor *) const; + + void InitGX(GXLightObj *obj) const; + void CopyToG3D_World(nw4r::g3d::LightObj &) const; + void CopyToG3D_View(nw4r::g3d::LightObj &, const nw4r::math::MTX34 &) const; + void CopyFromG3D(const nw4r::g3d::ResAnmLight &, f32, EGG::LightObject *, bool); + + void ApplyAnmResultInner(const nw4r::g3d::LightAnmResult &); + void ApplyAnmResultA(const nw4r::g3d::LightAnmResult &); + bool ApplyAnmResultB(const nw4r::g3d::LightAnmResult &); + + void CalcAt(); + void SetPos(const nw4r::math::VEC3 &); + void SetAt(const nw4r::math::VEC3 &); + void SetPosAt(nw4r::math::VEC3 const &, nw4r::math::VEC3 const &); + void SetDist(f32); + + f32 getField0x30() const { + return field_0x30; + } + + int getField0x3C() const { + return field_0x3C; + } + + GXSpotFn getSpotFn() const { + return static_cast(mSpotFn); + } + + GXDistAttnFn getDistAttnFn() const { + return static_cast(mDistAttnFn); + } + + f32 getDistance() const { + return mDist; + } + + void SetIndex(u16 index) { + mIndex = index; + } + + void ClearField0xA0() { + field_0xA0 = 0; + } + + void ClearFlag2() { + mFlags = mFlags & 0xFFFE; + } + + bool CheckFlag1() const { + return (mFlags & 1) != 0; + } + + void SetOtherFlag1() { + field_0xA0 |= 1; + } + + void ClearOtherFlag1() { + field_0xA0 = field_0xA0 & ~1; + } + + bool CheckFlag2() const { + return (mFlags & 2) != 0; + } + + bool CheckFlag0x20() const { + return (mFlags & 0x20) != 0; + } + + u16 GetField0x06() const { + return field_0x06; + } + + u16 GetIndex() const { + return mIndex; + } + + void UpdatePosAt(LightObject &other) { + SetPosAt(other.mPos, other.mAt); + } + + const GXColor &GetBlack() const { + return mBlack; + } + +private: + /* 0x04 */ u16 mIndex; + /* 0x06 */ u16 field_0x06; + /* 0x08 */ nw4r::math::VEC3 mAt; + /* 0x14 */ nw4r::math::VEC3 mPos; + /* 0x20 */ nw4r::math::VEC3 mDir; + /* 0x2C */ GXColor mWhite; + /* 0x30 */ f32 field_0x30; + /* 0x34 */ f32 mDist; + /* 0x38 */ GXColor mBlack; + /* 0x3C */ u8 field_0x3C; + /* 0x3D */ u8 field_0x3D; + /* 0x3E */ u8 mSpotFn; + /* 0x3F */ u8 mDistAttnFn; + /* 0x40 */ f32 mCutoff; + /* 0x44 */ f32 mRefDist; + /* 0x48 */ f32 mRefBrightness; + /* 0x4C */ nw4r::math::VEC3 field_0x4C; + /* 0x58 */ nw4r::math::VEC3 field_0x58; + /* 0x64 */ f32 mShininess; + /* 0x68 */ u16 mFlags; + /* 0x6C */ nw4r::math::VEC3 field_0x6C; + /* 0x78 */ GXColor mLightColor; + /* 0x7C */ nw4r::math::VEC3 mViewPos; + /* 0x88 */ nw4r::math::VEC3 mViewAt; + /* 0x94 */ nw4r::math::VEC3 field_0x94; + /* 0xA0 */ u16 field_0xA0; +}; + +} // namespace EGG + +#endif diff --git a/include/egg/gfx/eggLightTexture.h b/include/egg/gfx/eggLightTexture.h index 263fbaac..ef441058 100644 --- a/include/egg/gfx/eggLightTexture.h +++ b/include/egg/gfx/eggLightTexture.h @@ -1,6 +1,145 @@ #ifndef EGG_LIGHT_TEXTURE_H #define EGG_LIGHT_TEXTURE_H -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/egg_types.h" +#include "egg/gfx/eggCapTexture.h" +#include "egg/gfx/eggTexture.h" +#include "egg/math/eggVector.h" +#include "egg/prim/eggBinary.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +class LightTextureManager; + +class LightTexture : public CapTexture, public IBinary { +public: +#pragma pack(push, 1) + struct SubData { + /* 0x00 */ f32 mIntensity; + /* 0x04 */ u8 mGradientUsed; + /* 0x05 */ u8 field_0x05; + /* 0x06 */ u8 _0x06[2]; + }; + + // Implicit +0x10 from BinHeader + struct BinData { + /* 0x00 */ u16 mNumEntries; + /* 0x02 */ u8 field_0x02; + /* 0x03 */ u8 field_0x03; + /* 0x04 */ char mName[32]; + /* 0x24 */ u8 mType; + /* 0x25 */ u16 field_0x25; + /* 0x27 */ u8 field_0x27; + /* 0x28 */ u32 field_0x28; + /* 0x2C */ f32 field_0x2C; + /* 0x30 */ u8 _0x30[4]; + /* 0x34 */ char mName2[32]; + /* 0x54 */ f32 field_0x54; + u8 _0x00[0x20]; + SubData mSubData[1]; + }; +#pragma pack(pop) + + LightTexture(const char *name, const LightTextureManager *mgr); + virtual ~LightTexture(); + + virtual void configure() override; // at 0xC + + virtual void SetBinaryInner(const Bin &) override; + virtual void GetBinaryInner(Bin *) const override; + virtual size_t GetBinarySize() const override; + + static void initialize(u16 textureSize, Heap *pHeap); + static void loadTextureFromResTimg(int index, EGG::ResTIMG *img); + static void initDrawSetting(u16, u16, u16, u16); + void addLight(const EGG::LightObject &); + + void fn_804AC0E0(int, const GXColor &, bool); + void draw(int); + static void beginDebugDraw(); + void debugDraw(int); + + const char *getName() const { + return mName1; + } + + f32 getFloat(u16 idx) const { + return mpFloatData[idx]; + } + void setFloat(u16 idx, f32 val) { + mpFloatData[idx] = val; + } + + u8 getByte1(u16 idx) const { + return mpByteData1[idx]; + } + void offByte1(u16 idx) { + mpByteData1[idx] &= ~1; + } + void onByte1(u16 idx) { + mpByteData1[idx] |= 1; + } + + u8 getByte2(u16 idx) const { + return mpByteData2[idx]; + } + void setByte2(u16 idx, u8 val) const { + mpByteData2[idx] = val; + } + + static void getTexDimensions(u16 *, u16 *, u16 *, u16 *, u16); + +private: + static void fn_804AB270(); + static void fn_804AB310(const GXColor &color); + static void fn_804AB440(); + static void fn_804AB600(); + + static void fn_804AC0A0(int, int *, int *); + static void loadTextureData(int index, void *data, GXTexFmt fmt); + + // TODO enum + int GetLightType() const { + return mLightType; + } + + /* 0x30 */ const LightTextureManager *mpMgr; + /* 0x34 */ u8 mNumData; + /* 0x35 */ u8 field_0x35; + /* 0x36 */ u8 field_0x36; + /* 0x37 */ u8 mLightType; + /* 0x38 */ Vector3f field_0x38; + /* 0x44 */ f32 *mpFloatData; + /* 0x48 */ u8 *mpByteData1; + /* 0x4C */ u8 *mpByteData2; + /* 0x50 */ f32 field_0x50; + /* 0x54 */ char mName1[0x20]; + /* 0x74 */ char mName2[0x20]; + /* 0x94 */ s16 field_0x94; + /* 0x98 */ f32 field_0x98; + /* 0x9C */ u8 field_0x9C; + /* 0x9D */ u8 field_0x9D; + /* 0x9E */ u8 field_0x9E; + /* 0x9F */ u8 field_0x9F; + + static u16 sTextureSize; + + static u16 sDrawWidth; + static u16 sDrawHeight; + static u16 sDrawPosX; + static u16 sDrawPosY; + static u16 sTexWidth; + static u16 sTexHeight; + static u16 sDrawNumX; + static u16 sDrawNumY; + static CpuTexture *spNormalEnvironment; + + // unsure + static bool sUseDebug; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggLightTextureMgr.h b/include/egg/gfx/eggLightTextureMgr.h index 4acca7ce..c12fc011 100644 --- a/include/egg/gfx/eggLightTextureMgr.h +++ b/include/egg/gfx/eggLightTextureMgr.h @@ -1,6 +1,93 @@ #ifndef EGG_LIGHT_TEXTURE_MGR_H #define EGG_LIGHT_TEXTURE_MGR_H -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggLightManager.h" +#include "egg/gfx/eggLightTexture.h" +#include "egg/prim/eggBinary.h" +#include "nw4r/g3d/res/g3d_resmat.h" +#include "nw4r/g3d/res/g3d_resmdl.h" + +namespace EGG { + +class LightManager; +class LightObject; + +class LightTextureManager : public IBinary { +public: + struct BinData { + u16 mDataCount; + u8 _0x02[14]; + BinHeader mSubData[1]; + }; + LightTextureManager(const LightManager *lightMgr); + virtual ~LightTextureManager(); + virtual void SetBinaryInner(const Bin &) override; + virtual void GetBinaryInner(Bin *) const override; + virtual size_t GetBinarySize() const override; + + u16 createTexture(const char *name); + bool setBinaryToTexture(const void *data); + bool deleteTexture(int idx); + + u16 replaceModelTextures(nw4r::g3d::ResMdl) const; + u16 replaceModelTexture(int, nw4r::g3d::ResMdl) const; + void drawAndCaptureTexture(f32, f32, f32, f32); + void frameReset(); + void correctLightObject(); + + // Inofficial + static const void *getLtexFromLmap(const void *lmap, u16 index); + int createTexturesFromBin(const void *bin); + u16 createTextureFromBin(const void *bin); + + u16 getMaxNumLightTextures() const { + return mMaxNumTextures; + } + + u16 getNumLightTextures() const { + return mTextureCount; + } + + LightTexture *getTextureByName(const char *name) const { + int idx = getTextureIndex(name); + if (idx != -1) { + return mpTextures[idx]; + } else { + return nullptr; + } + } + + const nw4r::g3d::AmbLightObj &GetAmbientObj(int idx) const { + return mpLightMgr->GetAmbientObject(idx)->mLightObj; + } + + const LightObject *GetLightObject(u16 i) const { + return mpObjects[i]; + } + + const LightObject *GetLightObject(u16 i) { + return mpObjects[i]; + } + +private: + static void fn_804AE340(nw4r::g3d::ResMat, GXTexCoordID); + int getTextureIndex(const char *name) const; + + bool getSomeTfRelatedBool() const { + return (mFlags >> 5) & 1; + } + + /* 0x04 */ u8 mFlags; + /* 0x06 */ u16 mTextureCount; + /* 0x08 */ LightTexture **mpTextures; + /* 0x0C */ const LightManager *mpLightMgr; + /* 0x10 */ u32 field_0x10; + /* 0x14 */ u16 mMaxNumTextures; + /* 0x16 */ u8 field_0x16; + /* 0x18 */ const LightObject **mpObjects; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggModelEx.h b/include/egg/gfx/eggModelEx.h index 9fc2283b..9e8aa23f 100644 --- a/include/egg/gfx/eggModelEx.h +++ b/include/egg/gfx/eggModelEx.h @@ -1,6 +1,65 @@ #ifndef EGG_MODEL_EX_H #define EGG_MODEL_EX_H -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/egg_types.h" +#include "nw4r/g3d/g3d_scnobj.h" +#include "nw4r/g3d/res/g3d_resmdl.h" +namespace EGG { + +class ModelEx { +public: + enum EType { + cType_ScnMdlSimple, + cType_ScnMdl, + cType_ScnMdl1Mat1Shp, + cType_ScnProcModel, + cType_ScnRfl, + cType_None + }; + + enum EFlag { + cFlag_HasOriginalBV = (1 << 0) + }; + + enum EDrawShape { + cDrawShape_None = (1 << 0) + }; + +private: + nw4r::g3d::ScnObj *mScnObj; // at 0x0 + EType mType; // at 0x4 + u16 mFlag; // at 0x8 + ModelBoundingInfo *mpBoundingInfo; // at 0xC + + static u32 sDrawFlag; + static const char *sByteCodeCalcStr; + static const char *sByteCodeMixStr; + +public: + ModelEx(nw4r::g3d::ScnObj *); + void getShapeMinMax(u16, nw4r::math::VEC3 *, nw4r::math::VEC3 *, bool); + void calcWorld(nw4r::math::MTX34 *, const nw4r::math::MTX34 *worldMtx) const; + nw4r::g3d::ResMdl getResMdl() const; + nw4r::g3d::ResShp getResShp(u16) const; + + nw4r::g3d::ScnMdl *getScnMdl() const { + return (mType == cType_ScnMdl) ? (nw4r::g3d::ScnMdl *)mScnObj : NULL; + } + + nw4r::g3d::ScnMdlSimple *getScnMdlSimple() const { + return (mType == cType_ScnMdlSimple || mType == cType_ScnMdl) ? (nw4r::g3d::ScnMdlSimple *)mScnObj : NULL; + } + + nw4r::g3d::ScnMdl1Mat1Shp *getScnMdl1Mat1Shp() const { + return (mType == cType_ScnMdl1Mat1Shp) ? (nw4r::g3d::ScnMdl1Mat1Shp *)mScnObj : NULL; + } + + void getMtxType0(nw4r::math::MTX34 *pMtx) const { + nw4r::math::MTX34Copy(pMtx, mScnObj->GetMtxPtr(nw4r::g3d::ScnObj::MTX_LOCAL)); + } +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggPalette.h b/include/egg/gfx/eggPalette.h index a7677d52..ddfff217 100644 --- a/include/egg/gfx/eggPalette.h +++ b/include/egg/gfx/eggPalette.h @@ -1,6 +1,60 @@ #ifndef EGG_PALETTE_H #define EGG_PALETTE_H -namespace EGG {} // namespace EGG +#include "common.h" +#include "rvl/GX/GXTexture.h" + +namespace EGG { + +enum JUTTransparency { + UNK0, + UNK1 +}; +struct ResTLUT { + u8 format; + u8 transparency; + u16 numColors; +}; + +class Palette { +public: + Palette(GXTlut p1, GXTlutFmt p2, JUTTransparency p3, u16 p4, void *p5) { + storeTLUT(p1, p2, p3, p4, p5); + } + + Palette(GXTlut tlutNo, ResTLUT *p_tlutRes) { + storeTLUT(tlutNo, p_tlutRes); + } + + void storeTLUT(GXTlut, ResTLUT *); + void storeTLUT(GXTlut, GXTlutFmt, JUTTransparency, u16, void *); + bool load(); + + u8 getTlutName() const { + return mTlutName; + } + u8 getFormat() const { + return mFormat; + } + u8 getTransparency() const { + return mTransparency; + } + u16 getNumColors() const { + return mNumColors; + } + ResTLUT *getColorTable() const { + return mColorTable; + } + +private: + /* 0x00 */ GXTlutObj mTlutObj; + /* 0x0C */ u8 mTlutName; + /* 0x0D */ u8 mFormat; + /* 0x10 */ ResTLUT *mColorTable; + /* 0x14 */ u16 mNumColors; + /* 0x16 */ u8 mTransparency; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggPostEffectBase.h b/include/egg/gfx/eggPostEffectBase.h index 2c7fa0b9..5b2219cd 100644 --- a/include/egg/gfx/eggPostEffectBase.h +++ b/include/egg/gfx/eggPostEffectBase.h @@ -1,6 +1,76 @@ #ifndef EGG_POST_EFFECT_BASE_H #define EGG_POST_EFFECT_BASE_H -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggCapTexture.h" +#include "egg/gfx/eggScreen.h" +#include "egg/math/eggMath.h" +#include "egg/math/eggRotation.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +class PostEffectBase { +public: + struct CapTextureWrapper { + CapTexture *mpTex; + GXTexMapID mTexMapID; + }; + void setField_0x00(u32 val) { + field_0x00 = val; + } + + static void setProjection(const EGG::Screen &screen); + + f32 getRot() const { + return mRotation; + } + + void setRot(f32 rot) { + mRotation = rot; + } + + void setCapTexture(CapTexture *tex) { + mTex1.mpTex = tex; + } + + void setCapTexMapId(GXTexMapID id) { + mTex1.mTexMapID = id; + } + +public: + u32 field_0x00; // at 0x0 + CapTextureWrapper mTex1; // at 0x4 + CapTextureWrapper mTex2; // at 0xC + f32 mOffsetX; // at 0x14 + f32 mOffsetY; // at 0x18 + f32 mScaleX; // at 0x1C + f32 mScaleY; // at 0x20 + EGG::Rotation mRotation; // at 0x24 + + PostEffectBase(); + virtual ~PostEffectBase() {} // at 0x8 + + void fn_804AED20(); + + void setVtxState(); + void setMatColorChannel(); + void setMatInd(); + void setMatPE(); + void setBlendModeInternal(); + static void scaleColor(GXColor &, const GXColor &, bool, f32); + static void lerpColor(GXColor &, const GXColor &, const GXColor &, f32); + void getBaseTexMtx(nw4r::math::MTX34 *mtx) const; + +public: + virtual void draw(f32 width, f32 height); // at 0xC +protected: + virtual void setMaterialInternal() {} // at 0x10 + virtual void loadTextureInternal(); // at 0x14 + virtual void drawScreenInternal(f32 offsetX, f32 offsetY, f32 width, f32 height); // at 0x18 +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggPostEffectBlur.h b/include/egg/gfx/eggPostEffectBlur.h index 4c116d62..de6d9754 100644 --- a/include/egg/gfx/eggPostEffectBlur.h +++ b/include/egg/gfx/eggPostEffectBlur.h @@ -2,21 +2,67 @@ #define EGG_POST_EFFECT_BLUR_H #include "common.h" +#include "egg/egg_types.h" +#include "egg/gfx/eggPostEffectBase.h" +#include "rvl/GX/GXTypes.h" + namespace EGG { -class PostEffectBlur { +class PostEffectBlur : public PostEffectBase { + struct Stage { + /* 0x00 */ u8 field_0x00; + /* 0x01 */ GXColor field_0x01; + /* 0x08 */ f32 field_0x08; + /* 0x0C */ f32 field_0x0C; + + void init(const GXColor &clr) { + field_0x00 = 16; + field_0x01 = clr; + field_0x08 = 0.0f; + field_0x0C = 1.0f; + } + }; + public: PostEffectBlur(); - ~PostEffectBlur() {} + virtual ~PostEffectBlur() {} + + virtual void draw(f32 width, f32 height) override; // at 0xC void setField0x30(f32 val) { field_0x30 = val; } + void setField0x2C(int i) { + field_0x2C = i; + } + + void setStage0Field0(u8 u1) { + field_0x38[0].field_0x00 = u1; + } + + void setStage0Color(GXColor clr) { + field_0x38[0].field_0x01 = clr; + } + + void setStage0F(f32 f) { + field_0x38[0].field_0x0C = f; + } + + void setStage0ColorThing(u8 i) { + f32 color = (255.0f / field_0x38[0].field_0x00) + 0.5f; + f32 f = (i * 1.75f) / field_0x38[0].field_0x00; + f32 alpha = f <= 255.0f ? f : 255.0f; + field_0x38[0].field_0x01 = (GXColor){color, color, color, alpha}; + } + private: - u8 _0x00[0x30 - 0x00]; - f32 field_0x30; - u8 _0x03[0x78 - 0x34]; + void drawInternal(u8, u8, f32, f32); + + /* 0x2C */ u8 field_0x2C; + /* 0x30 */ f32 field_0x30; + /* 0x34 */ f32 field_0x34; + /* 0x38 */ Stage field_0x38[4]; }; } // namespace EGG diff --git a/include/egg/gfx/eggPostEffectBlurGather.h b/include/egg/gfx/eggPostEffectBlurGather.h new file mode 100644 index 00000000..9a1966d7 --- /dev/null +++ b/include/egg/gfx/eggPostEffectBlurGather.h @@ -0,0 +1,40 @@ +#ifndef EGG_POST_EFFECT_BLUR_GATHER_H +#define EGG_POST_EFFECT_BLUR_GATHER_H + +#include "common.h" +#include "egg/gfx/eggCpuTexture.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggPostEffectBase.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +class PostEffectBlurGather : public PostEffectBase { + // Size 0x18 + struct BlurGatherData { + void reset() { + mpCapTexture = nullptr; + mColor = DrawGX::WHITE; + mColorScale = 1.f; + field_0x10 = 0; + } + /* 0x00 */ EGG::CpuTexture *mpCapTexture; + /* 0x04 */ GXTexMapID mTexMapId; + /* 0x08 */ GXColor mColor; + /* 0x0C */ f32 mColorScale; + /* 0x10 */ u8 field_0x10; + }; + +public: + PostEffectBlurGather(); + virtual void setMaterialInternal() override; + + /* 0x2C */ u8 field_0x2C; + /* 0x2D */ u8 field_0x2D; + /* 0x30 */ f32 field_0x30; + /* 0x34 */ BlurGatherData mBlurGatherData[3]; +}; + +} // namespace EGG + +#endif diff --git a/include/egg/gfx/eggPostEffectMask.h b/include/egg/gfx/eggPostEffectMask.h index 5af4ee11..113ec6cf 100644 --- a/include/egg/gfx/eggPostEffectMask.h +++ b/include/egg/gfx/eggPostEffectMask.h @@ -1,6 +1,38 @@ #ifndef EGG_POST_EFFECT_MASK_H #define EGG_POST_EFFECT_MASK_H -namespace EGG {} // namespace EGG +#include "egg/gfx/eggPostEffectBase.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +class PostEffectMask : public PostEffectBase { +public: + PostEffectMask(); + + virtual void setMaterialInternal() override; + + GXTevScale GetTevScale() const { + return static_cast(field_0x1BC); + } + + void setField_0x2C(int i) { + field_0x2C = i; + } + + void setField_0x34(f32 f) { + field_0x34 = f; + } + +private: + /* 0x2C */ int field_0x2C; + /* 0x30 */ GXColor mColor; + /* 0x34 */ f32 field_0x34; + /* 0x38 */ f32 field_0x38; + /* 0x3C */ u8 _0x3C[0x180]; + /* 0x1BC */ u8 field_0x1BC; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggPostEffectMaskDOF.h b/include/egg/gfx/eggPostEffectMaskDOF.h index cf6398f6..297843ec 100644 --- a/include/egg/gfx/eggPostEffectMaskDOF.h +++ b/include/egg/gfx/eggPostEffectMaskDOF.h @@ -1,6 +1,55 @@ #ifndef EGG_POST_EFFECT_MASK_DOF_H #define EGG_POST_EFFECT_MASK_DOF_H -namespace EGG {} // namespace EGG +#include "egg/gfx/eggCpuTexture.h" +#include "egg/gfx/eggPostEffectBase.h" +#include "egg/math/eggVector.h" +#include "rvl/GX/GXTypes.h" +namespace EGG { + +class PostEffectMaskDOF : public PostEffectBase { +public: + PostEffectMaskDOF(); + + void setUpGradation(); + virtual void draw(f32 width, f32 height) override; + virtual void setMaterialInternal() override; + virtual ~PostEffectMaskDOF() {} + + static const GXColor &getNearColor(); + static const GXColor &getFarColor(); + static const GXColor &getCenterColor(); + + void setParam0x44(f32 f) { + field_0x44 = f; + } + + void setParam0x48(f32 f) { + field_0x48 = f; + } + + void setParam0x4C(f32 f) { + field_0x4C = f; + } + + void setCpuTexArrIdx(int i){ + mCpuTexArrIdx = i; + } + +private: + /* 0x2C */ u8 field_0x2C; + /* 0x30 */ CpuTexture *mpCpuTexArr[3]; + /* 0x3C */ CpuTexture *mpCpuTex; + /* 0x40 */ u8 _40[4]; + /* 0x44 */ f32 field_0x44; + /* 0x48 */ f32 field_0x48; + /* 0x4C */ f32 field_0x4C; + /* 0x50 */ Vector2f field_0x50; + /* 0x58 */ u8 _58[4]; + /* 0x5C */ int mCpuTexArrIdx; + /* 0x60 */ int field_0x60; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggPostEffectSimple.h b/include/egg/gfx/eggPostEffectSimple.h index c0053367..9f26b738 100644 --- a/include/egg/gfx/eggPostEffectSimple.h +++ b/include/egg/gfx/eggPostEffectSimple.h @@ -1,6 +1,26 @@ #ifndef EGG_POST_EFFECT_SIMPLE_H #define EGG_POST_EFFECT_SIMPLE_H -namespace EGG {} // namespace EGG +#include "egg/gfx/eggPostEffectBase.h" +#include "rvl/GX/GXTypes.h" +namespace EGG { + +class PostEffectSimple : public PostEffectBase { +public: + PostEffectSimple(); + virtual void setMaterialInternal() override; + + void setField0x38(s32 v) { + field_0x38 = v; + } + +private: + /* 0x2C */ GXColor field_0x2C; + /* 0x30 */ f32 field_0x30; + /* 0x34 */ GXTevScale field_0x34; + /* 0x38 */ s32 field_0x38; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggPostEffectUnk1.h b/include/egg/gfx/eggPostEffectUnk1.h deleted file mode 100644 index 24b1df6e..00000000 --- a/include/egg/gfx/eggPostEffectUnk1.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef EGG_POST_EFFECT_UNK1_H -#define EGG_POST_EFFECT_UNK1_H - -namespace EGG {} // namespace EGG - -#endif diff --git a/include/egg/gfx/eggPostEffectUnk2.h b/include/egg/gfx/eggPostEffectUnk2.h index 2e324f7a..8cd8ac97 100644 --- a/include/egg/gfx/eggPostEffectUnk2.h +++ b/include/egg/gfx/eggPostEffectUnk2.h @@ -1,6 +1,32 @@ #ifndef EGG_POST_EFFECT_UNK2_H #define EGG_POST_EFFECT_UNK2_H -namespace EGG {} // namespace EGG +#include "egg/egg_types.h" +#include "egg/gfx/eggPostEffectBase.h" +#include "egg/math/eggVector.h" + +namespace EGG { + +class PostEffectUnk2 : public PostEffectBase { +public: + PostEffectUnk2(); + virtual ~PostEffectUnk2(); + virtual void draw(f32 width, f32 height) override; + virtual void setMaterialInternal() override; + +private: + /* 0x2C */ u32 field_0x2C; + /* 0x30 */ u32 field_0x30; + /* 0x34 */ u8 field_0x34; + /* 0x35 */ u8 field_0x35; + /* 0x36 */ s16 field_0x36; + /* 0x38 */ Vector2f field_0x38; + /* 0x40 */ f32 field_0x40; + /* 0x44 */ f32 field_0x44; + /* 0x48 */ f32 field_0x48; + /* 0x4C */ EGG::CpuTexture *mpTexture; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggScreen.h b/include/egg/gfx/eggScreen.h index 12a5fa1a..44fd56da 100644 --- a/include/egg/gfx/eggScreen.h +++ b/include/egg/gfx/eggScreen.h @@ -1,40 +1,26 @@ #ifndef EGG_SCREEN_H #define EGG_SCREEN_H -#include "common.h" +#include "egg/egg_types.h" #include "egg/gfx/eggFrustum.h" +#include "egg/gfx/eggStateGX.h" namespace EGG { -// TODO: Fill out more class Screen : public Frustum { public: - Screen(); - Screen(f32, f32, f32, f32, Screen *, CanvasMode); - - virtual ~Screen() {} - virtual void SetProjectionGX() const override; - virtual void CopyToG3D(nw4r::g3d::Camera) const override; - - static void Initialize(const u16 *, const u16 *, Screen *); - static void SetTVModeDefault(); - - u8 TODO_0x3C[0x88 - 0x3C]; - enum TVMode { - TV_MODE_1, - TV_MODE_2, - TV_MODE_3, - TV_MODE_4, + TV_MODE_4_3, + TV_MODE_16_9, + TV_MODE_UNK_3, TV_MODE_MAX }; - struct TVModeInfo { - TVModeInfo() {} - u16 width; - u16 height; - f32 w_ratio; - f32 h_ratio; + typedef void (*ChangeTVModeFunc)(void *); + + struct UnkStruct { + UNKWORD field_0x00; + UNKWORD field_0x04; }; struct DataEfb { @@ -48,10 +34,26 @@ public: f32 z2; // at 0x14 } vp; - s32 sc_ox; // at 0x18 - s32 sc_oy; // at 0x1C + u32 sc_x; + u32 sc_y; + u32 sc_w; + u32 sc_h; + + s32 sc_ox; // at 0x28 + s32 sc_oy; // at 0x2C }; + struct TVModeInfo { + u16 width; + u16 height; + nw4r::math::VEC2 ratios; + }; + +public: + static void Initialize(const u16 *, const u16 *, Screen *); + static void SetTVMode(TVMode); + static void SetTVModeDefault(); + static u16 GetSizeXMax(TVMode mode) { return sTVModeInfo[mode].width; } @@ -73,11 +75,65 @@ public: return sTVMode; } + TVMode GetComputedTVMode() const { + if ((mFlags & FLAG_0x20) == 0) { + return (mFlags & FLAG_0x08) == 0 ? sTVMode : TV_MODE_UNK_3; + } else { + return TV_MODE_4_3; + } + } + + Screen(); + Screen(f32, f32, f32, f32, const Screen *, CanvasMode); + Screen(const Screen &); + + virtual ~Screen() {} // at 0x8 + virtual void SetProjectionGX() const; // at 0xC + virtual void CopyToG3D(nw4r::g3d::Camera) const; // at 0x10 + + const Screen *GetParent() const { + return mParent; + } + void SetParent(const Screen *parent); + void SetUnkFlag8(); + + void CopyFromAnother(const Screen &other); + void Reset(f32, f32, f32, f32, CanvasMode); + void OnDirectEfb() const; + const DataEfb &GetDataEfb() const; + bool IsChangeEfb() const; + void CalcMatrixForDrawQuad(nw4r::math::MTX34 *, f32, f32, f32, f32) const; + void FillBufferGX(u32, GXColor, u32) const; + void GetGlobalPos(f32 *, f32 *) const; + void fn_804B2EE0(f32 *, f32 *, f32, f32) const; + + f32 ScaleByX(f32 val) const { + return val * StateGX::s_widthEfb / GetSizeXMax(GetComputedTVMode()); + } + + f32 UnscaleByX(f32 val) const { + return val * GetSizeXMax(GetComputedTVMode()) / StateGX::s_widthEfb; + } + + f32 ScaleByY(f32 val) const { + return val * StateGX::s_heightEfb / GetSizeYMax(GetComputedTVMode()); + } + + f32 UnscaleByY(f32 val) const { + return val * GetSizeYMax(GetComputedTVMode()) / StateGX::s_heightEfb; + } + +private: + const Screen *mParent; // at 0x3C + nw4r::math::VEC2 mPosition; // at 0x40 + nw4r::math::VEC2 field_0x48; // at 0x48 + nw4r::math::VEC2 field_0x50; // at 0x50 + mutable DataEfb mDataEfb; // at 0x58 + static TVMode sTVMode; static Screen *spRoot; - typedef void (*ChangeTVModeFunc)(void *); static ChangeTVModeFunc sChangeTVModeFunc; static void *spChangeTVModeFuncInfo; static TVModeInfo sTVModeInfo[Screen::TV_MODE_MAX]; diff --git a/include/egg/gfx/eggScreenEffectBase.h b/include/egg/gfx/eggScreenEffectBase.h index 447b328d..09f44699 100644 --- a/include/egg/gfx/eggScreenEffectBase.h +++ b/include/egg/gfx/eggScreenEffectBase.h @@ -1,6 +1,31 @@ #ifndef EGG_SCREEN_EFFECT_BASE_H #define EGG_SCREEN_EFFECT_BASE_H -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggScreen.h" + +namespace EGG { + +class ScreenEffectBase { +protected: + /* 0x0 */ u8 mFlag; + +public: + ScreenEffectBase(); + virtual ~ScreenEffectBase() {} // at 0x8 + + static Screen &GetScreen() { + return sScreen; + } + + bool isFlag0x2() const { + return mFlag & 2; + } + +protected: + static Screen sScreen; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggScreenEffectBlur.h b/include/egg/gfx/eggScreenEffectBlur.h index 0553161f..86150ff8 100644 --- a/include/egg/gfx/eggScreenEffectBlur.h +++ b/include/egg/gfx/eggScreenEffectBlur.h @@ -2,15 +2,55 @@ #define EGG_SCREEN_EFFECT_BLUR_H #include "common.h" +#include "egg/egg_types.h" +#include "egg/gfx/eggScreenEffectBase.h" +#include "egg/prim/eggBinary.h" +#include "rvl/GX/GXTypes.h" + namespace EGG { -class ScreenEffectBlur { +class ScreenEffectBlur : public ScreenEffectBase, IBinary { public: + struct BinData { + u8 field_0x00; + u8 field_0x01; + u8 field_0x02; + f32 field_0x04; + f32 field_0x08; + f32 field_0x0C; + f32 field_0x10; + f32 field_0x14; + f32 field_0x18; + u8 field_0x1C; + u8 field_0x1D; + u8 field_0x1E; + u8 field_0x1F; + }; + ScreenEffectBlur(); - ~ScreenEffectBlur(); + virtual ~ScreenEffectBlur(); + + virtual void SetBinaryInner(const Bin &) override; + virtual void GetBinaryInner(Bin *) const override; + virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; + + void fn_804B32B0(); + void fn_804B3710(); private: - u8 _0x00[0x38 - 0x00]; + /* 0x0C */ u8 field_0x0C; + /* 0x0D */ u8 field_0x0D; + /* 0x0E */ u8 field_0x0E; + /* 0x10 */ f32 field_0x10; + /* 0x14 */ f32 field_0x14; + /* 0x18 */ f32 field_0x18; + /* 0x1C */ f32 field_0x1C; + /* 0x20 */ f32 field_0x20; + /* 0x24 */ f32 field_0x24; + /* 0x28 */ GXColor field_0x28; + /* 0x2C */ PostEffectUnk2 *mpUnk2; + /* 0x30 */ PostEffectBlur *mpBlur; + /* 0x34 */ TextureBuffer *mpCpuTexture; }; } // namespace EGG diff --git a/include/egg/gfx/eggStateEfb.h b/include/egg/gfx/eggStateEfb.h index 5590f9c7..93386936 100644 --- a/include/egg/gfx/eggStateEfb.h +++ b/include/egg/gfx/eggStateEfb.h @@ -1,6 +1,54 @@ #ifndef EGG_STATE_EFB_H #define EGG_STATE_EFB_H -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/egg_types.h" + +namespace EGG { + +class StateEfb { +public: + enum BufferType { + BUFFER_0, + BUFFER_1, + BUFFER_2, + BUFFER_3, + + BUFFER_MAX, + }; + + struct Buffer { + TextureBuffer *buf; + u32 userData; + u32 field_0x08; + }; +private: + static Buffer spBufferSet[BUFFER_MAX]; + static f32 sWorkSpaceV[6]; + static f32 sWorkSpaceHideV[6]; + static f32 sUnkBuffer[6]; // unk name + static s32 sWorkBuffer; + static s32 sPushCount; + static u32 sFlag; + + static bool GetShouldCapture(); + static bool GetUseTfRgb565(); + + public: + static bool CheckFlag0x2() { + return (sFlag & 2) != 0; + } + + static void Clean(); + static TextureBuffer *captureEfb(BufferType type, bool, u32 userData); + static bool releaseEfb(BufferType type, u32 userData); + + // Unknown names + static void fn_804B4270(BufferType type, u32 userData); + static void fn_804B4310(BufferType type, u32 userData); + static f32 *fn_804B4550(); +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggStateGX.h b/include/egg/gfx/eggStateGX.h index 7351416c..251d864e 100644 --- a/include/egg/gfx/eggStateGX.h +++ b/include/egg/gfx/eggStateGX.h @@ -2,15 +2,71 @@ #define EGG_STATE_GX_H #include "common.h" +#include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" + #include "rvl/GX.h" // IWYU pragma: export namespace EGG { class StateGX { public: + struct ScopedColor { + ScopedColor(bool x) { + old = GXSetColorUpdate_(x); + } + + ~ScopedColor() { + GXSetColorUpdate_(old); + } + + bool old; + }; + + struct ScopedAlpha { + ScopedAlpha(bool x) { + old = GXSetAlphaUpdate_(x); + } + + ~ScopedAlpha() { + GXSetAlphaUpdate_(old); + } + + bool old; + }; + + struct ScopedDither { + ScopedDither(bool x) { + old = GXSetDither_(x); + } + + ~ScopedDither() { + GXSetDither_(old); + } + + bool old; + }; + + struct CacheGX { + /* 0x00 */ u8 _0x00[0xC]; + /* 0x0C */ bool mDstAlphaEnable; + /* 0x0D */ u8 mDstAlpha; + /* 0x0E */ u8 _0x0E[0x18 - 0x0E]; + }; + + struct MemLayout { + /* 0x00 */ int mLayout; + /* 0x04 */ u32 numRegions; + /* 0x08 */ GXTexRegion mRegions[10]; + }; + + static GXColor &getClearEfb() { + return s_clearEfb; + } + static void initialize(u16, u16, GXColor, GXPixelFmt); static void frameInit(); - static void textureInit(); // Guess for 804b4810 + static void setTMemLayout(int layout); static void resetGX(); static void resetVtx(); @@ -23,21 +79,35 @@ public: static void resetGXCache(); - static void GXSetPixelFmt(GXPixelFmt pixelFmt, GXZFmt16 zFmt); - static void invalidateTexAllGX(); - static bool GXSetColorUpdate(bool); - static bool GXSetAlphaUpdate(bool); - static bool GXSetDither(); - static void GXCopyTex(); - static bool GXSetDstAlpha(); - // Unk func here - static void GXSetProjection(Mtx44, int); - static void GXSetProjectionv(const f32 *); - static void GXSetViewport(f32, f32, f32, f32, f32, f32); - static void GZSetScissor(u32, u32, u32, u32); - static void GZSetScissorBoxOffset(s32, s32); + static void GXSetPixelFmt_(GXPixelFmt pixelFmt, GXZFmt16 zFmt); + static bool GXSetColorUpdate_(bool); + static bool GXSetAlphaUpdate_(bool); + static bool GXSetDither_(bool); + static void GXCopyTex_(void *data, bool); + static CacheGX &GXSetDstAlpha_(bool, u8); + static void GXSetProjection_(Mtx44, GXProjectionType); + static void GXSetProjectionv_(const f32 *); + static void GXSetViewport_(f32 ox, f32 oy, f32 sx, f32 sy, f32 near, f32 far); + static void GXSetScissor_(u32, u32, u32, u32); + static void GXSetScissorBoxOffset_(s32, s32); + + // not sure + static void CalculateScreenScissor(const f32 src[4], u32 dst[4]); + + static u16 s_widthEfb; + static u16 s_heightEfb; + static GXPixelFmt s_pixFormat; + static GXZFmt16 s_zFmt16; + static GXColor s_clearEfb; + static u16 s_flag; + static u16 s_commandFlag; + + static CacheGX s_cacheGX; + // Inofficial names + static GXTexObj sDefaultTexObj; + static MemLayout s_tmem_layout; // same name, different type }; } // namespace EGG diff --git a/include/egg/gfx/eggTexture.h b/include/egg/gfx/eggTexture.h index dcf0e926..10420822 100644 --- a/include/egg/gfx/eggTexture.h +++ b/include/egg/gfx/eggTexture.h @@ -1,10 +1,120 @@ #ifndef EGG_TEXTURE_H #define EGG_TEXTURE_H +#include "common.h" +#include "egg/core/eggHeap.h" +#include "egg/gfx/eggPalette.h" +#include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" namespace EGG { -// TODO: Implement Members -struct ResTIMG {}; +// Copy of ResTIMG from JUTTexture +struct ResTIMG { + /* 0x00 */ u8 format; + /* 0x01 */ u8 alphaEnabled; + /* 0x02 */ u16 width; + /* 0x04 */ u16 height; + /* 0x06 */ u8 wrapS; + /* 0x07 */ u8 wrapT; + /* 0x08 */ u8 indexTexture; + /* 0x09 */ u8 colorFormat; + /* 0x0A */ u16 numColors; + /* 0x0C */ u32 paletteOffset; + /* 0x10 */ u8 mipmapEnabled; + /* 0x11 */ u8 doEdgeLOD; + /* 0x12 */ u8 biasClamp; + /* 0x13 */ u8 maxAnisotropy; + /* 0x14 */ u8 minFilter; + /* 0x15 */ u8 magFilter; + /* 0x16 */ s8 minLOD; + /* 0x17 */ s8 maxLOD; + /* 0x18 */ u8 mipmapCount; + /* 0x1A */ s16 LODBias; + /* 0x1C */ u32 imageOffset; +}; + +class Texture { +public: + Texture() { + setCaptureFlag(false); + mEmbPalette = NULL; + mTexInfo = NULL; + } + + Texture(const ResTIMG *p_timg, u8 param_1) { + mEmbPalette = NULL; + storeTIMG(p_timg, param_1); + setCaptureFlag(false); + } + + Texture(int, int, GXTexFmt, Heap *); + ~Texture(); + + void storeTIMG(ResTIMG const *pTIMG, u8 param0); + void storeTIMG(ResTIMG const *pTIMG, Palette *pPalette); + void storeTIMG(ResTIMG const *pTIMG, Palette *pPalette, GXTlut tlut); + void attachPalette(Palette *pPalette); + void init(); + void initTexObj(); + void initTexObj(GXTlut tlut); + void load(GXTexMapID texMapId); + void capture(int, int, GXTexFmt, bool, u8); + void captureTexture(int, int, int, int, bool, GXTexFmt, GXTexFmt); + void captureDolTexture(int, int, int, int, bool, GXTexFmt); + + const ResTIMG *getTexInfo() const { + return mTexInfo; + } + u8 getFormat() const { + return mTexInfo->format; + } + s32 getTransparency() { + return mTexInfo->alphaEnabled; + } + s32 getWidth() const { + return mTexInfo->width; + } + s32 getHeight() const { + return mTexInfo->height; + } + void setCaptureFlag(bool flag) { + mFlags &= 2 | flag; + } + u8 getCaptureFlag() const { + return mFlags & 1; + } + u8 getEmbPaletteDelFlag() const { + return mFlags & 2; + } + void setEmbPaletteDelFlag(bool flag) { + mFlags = (mFlags & 1) | (flag << 1); + } + bool operator==(const Texture &other) { + return mTexInfo == other.mTexInfo && mpPalette == other.mpPalette && mWrapS == other.mWrapS && + mWrapT == other.mWrapT && mMinFilter == other.mMinFilter && mMagFilter == other.mMagFilter && + mMinLOD == other.mMinLOD && mMinLOD == other.mMinLOD && mLODBias == other.mLODBias; + } + bool operator!=(const Texture &other) { + return !operator==(other); + } + +private: + /* 0x00 */ GXTexObj mTexObj; + /* 0x20 */ const ResTIMG *mTexInfo; + /* 0x24 */ void *mTexData; + /* 0x28 */ Palette *mEmbPalette; + /* 0x2C */ Palette *mpPalette; + /* 0x30 */ u8 mWrapS; + /* 0x31 */ u8 mWrapT; + /* 0x32 */ u8 mMinFilter; + /* 0x33 */ u8 mMagFilter; + /* 0x34 */ u16 mMinLOD; + /* 0x36 */ u16 mMaxLOD; + /* 0x38 */ s16 mLODBias; + /* 0x3A */ u8 mTlutName; + /* 0x3B */ u8 mFlags; + /* 0x3C */ void *field_0x3c; +}; } // namespace EGG diff --git a/include/egg/gfx/eggTextureBuffer.h b/include/egg/gfx/eggTextureBuffer.h index bf648ebb..3328a4ad 100644 --- a/include/egg/gfx/eggTextureBuffer.h +++ b/include/egg/gfx/eggTextureBuffer.h @@ -1,6 +1,60 @@ #ifndef EGG_TEXTURE_BUFFER_H #define EGG_TEXTURE_BUFFER_H -namespace EGG {} // namespace EGG +#include "egg/gfx/eggCapTexture.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +class TextureBuffer : public CapTexture { +public: + enum EBufferState { + STATE_FREE, + STATE_ALLOCED + }; + + static void initialize(u32, Heap *); + static TextureBuffer *getNotJoin(); + + static void append(TextureBuffer *buf) { + if (spTailNotJoin != NULL) { + spTailNotJoin->mpNext = buf; + } + + buf->mpPrev = spTailNotJoin; + buf->mpNext = NULL; + + spTailNotJoin = buf; + } + + TextureBuffer(); + virtual ~TextureBuffer() {} // at 0x8 + virtual void configure(); // at 0xC + + void alloc(u32 size); + static TextureBuffer *alloc(u16 w, u16 h, GXTexFmt fmt); + void free(); + +private: + static bool includesHeader(); + static void setIncludesHeader(bool); + + u32 mSize; // at 0x2C + EBufferState mState; // at 0x30 + TextureBuffer *mpNext; // at 0x34 + TextureBuffer *mpPrev; // at 0x38 + + static const int NUM_BUFFERS = 128; + static TextureBuffer *spHead; + static TextureBuffer *spTailNotJoin; + static char *spBufferAll; + static u32 sBufferAllSize; + static u32 sBufferSize; + static u32 sBufferRestSizeMin; + static bool sIncludesHeader; + static TextureBuffer *spBufferTable[NUM_BUFFERS]; +}; + +} // namespace EGG #endif diff --git a/include/egg/math/eggMatrix.h b/include/egg/math/eggMatrix.h index 89060283..a99a0698 100644 --- a/include/egg/math/eggMatrix.h +++ b/include/egg/math/eggMatrix.h @@ -24,6 +24,11 @@ struct Matrix34f { return arr[i]; } + Matrix34f &operator=(const Matrix34f &other) { + copyFrom(other); + return *this; + } + void rotateBaseX(Vector3f &, Matrix34f &); void rotateVectorChange(Vector3f &, Vector3f &, Matrix34f &); void inverseTo(Matrix34f &to) const; diff --git a/include/egg/math/eggRotation.h b/include/egg/math/eggRotation.h new file mode 100644 index 00000000..97910e97 --- /dev/null +++ b/include/egg/math/eggRotation.h @@ -0,0 +1,50 @@ +#ifndef EGG_ROTATION_H +#define EGG_ROTATION_H + +#include "egg/math/eggMath.h" + +namespace EGG { + +template +struct Rotation { + Rotation() {} + Rotation(T val) : mRot(val) {} + Rotation(const Rotation &other) { + mRot = other.mRot; + } + Rotation &operator=(const Rotation &other) { + mRot = val; + return *this; + } + Rotation &operator=(T val) { + mRot = val; + return *this; + } + + operator T() const { + return mRot; + } + + Rotation &operator-=(T val) { + mRot -= val; + return *this; + } + Rotation &operator+=(T val) { + mRot -= val; + return *this; + } + + const T cos() const { + return Math::cos(*this); + } + const T sin() const { + return Math::sin(*this); + } + +protected: + T mRot; +}; + +} // namespace EGG + +#endif diff --git a/include/egg/math/eggVector.h b/include/egg/math/eggVector.h index b0ac18c4..2d030d45 100644 --- a/include/egg/math/eggVector.h +++ b/include/egg/math/eggVector.h @@ -3,25 +3,20 @@ #include "common.h" #include "egg/math/eggMath.h" +#include "nw4r/math/math_triangular.h" + #include "nw4r/math.h" namespace EGG { struct Vector3f : public nw4r::math::VEC3 { - // __ct__Q23EGG8Vector3fFv Vector3f() : nw4r::math::VEC3() {} - - // __ct__Q23EGG8Vector3fFfff Vector3f(f32 fx, f32 fy, f32 fz) : VEC3(fx, fy, fz) {} - // ~Vector3f() {} - - // __cl__Q23EGG8Vector3fFi f32 &operator()(int i) { return ((f32 *)this)[i]; } - // __ml__Q23EGG8Vector3fCFf Vector3f operator*(f32 f) const { return Vector3f(x * f, y * f, z * f); } @@ -30,12 +25,10 @@ struct Vector3f : public nw4r::math::VEC3 { return Vector3f(v.x * f, v.y * f, v.z * f); } - // __pl__Q23EGG8Vector3fCFRCQ23EGG8Vector3f Vector3f operator+(const Vector3f &v) const { return Vector3f(x + v.x, y + v.y, z + v.z); } - // __apl__Q23EGG8Vector3fFRCQ23EGG8Vector3f Vector3f &operator+=(const Vector3f &v) { x += v.x; y += v.y; @@ -43,7 +36,6 @@ struct Vector3f : public nw4r::math::VEC3 { return *this; } - // __mi__Q23EGG8Vector3fCFv Vector3f operator-() const { f32 z = this->z; f32 y = this->y; @@ -51,12 +43,10 @@ struct Vector3f : public nw4r::math::VEC3 { return Vector3f(-x, -y, -z); } - // __mi__Q23EGG8Vector3fCFRCQ23EGG8Vector3f Vector3f operator-(const Vector3f &v) { return Vector3f(x - v.x, y - v.y, z - v.z); } - // __ami__Q23EGG8Vector3fFRCQ23EGG8Vector3f Vector3f &operator-=(const Vector3f &v) { x -= v.x; y -= v.y; @@ -64,24 +54,20 @@ struct Vector3f : public nw4r::math::VEC3 { return *this; } - // __amu__Q23EGG8Vector3fFf Vector3f &operator*=(f32 f) { multScalar(f); return *this; } - // __dv__Q23EGG8Vector3fCFf Vector3f operator/(f32 f) const { return Vector3f(x / f, y / f, z / f); } - // __adv__Q23EGG8Vector3fCFf // assumed Vector3f &operator/=(f32 f) { divScalar(f); return *this; } - // __ne__Q23EGG8Vector3fCFRCQ23EGG8Vector3f bool operator!=(const Vector3f &v) { return x != v.x || y != v.y || z != v.z; } @@ -101,12 +87,10 @@ struct Vector3f : public nw4r::math::VEC3 { return EGG::Math::abs(EGG::Math::atan2(b, a)); } - // dot__Q23EGG8Vector3fCFRCQ23EGG8Vector3f f32 dot(const Vector3f &v) const { return x * v.x + y * v.y + z * v.z; } - // cross__Q23EGG8Vector3fCFRCQ23EGG8Vector3f Vector3f cross(const Vector3f &b) const { f32 _x = (y * b.z) - (z * b.y); f32 _y = (z * b.x) - (x * b.z); @@ -126,6 +110,13 @@ struct Vector3f : public nw4r::math::VEC3 { } f32 normalise(); + + Vector3f normalize() { + Vector3f other(x, y, z); + other.normalise(); + return other; + } + f32 setLength(const Vector3f &src, f32 len); f32 setLength(f32 len); diff --git a/include/egg/prim/eggBinary.h b/include/egg/prim/eggBinary.h index 067bf8c1..9b517545 100644 --- a/include/egg/prim/eggBinary.h +++ b/include/egg/prim/eggBinary.h @@ -3,23 +3,90 @@ #include "common.h" +namespace EGG { + +/** + * @brief Common interface for objects that can be serialized to + * and deserializized from binary. + * + * @tparam T The type of the Egg class. Must have a BinData type + * that describes the binary type. + */ template class IBinary { public: - class Bin {}; - virtual void SetBinaryInner(Bin &) = 0; +#pragma pack(push, 1) + struct BinHeader { + /* 0x00 */ char mType[4]; + /* 0x04 */ size_t mSize; + /* 0x08 */ u8 mVersion; + /* 0x09 */ u16 field_0x09; + /* 0x0B */ u8 field_0x0B; + /* 0x0C */ u32 field_0x0C; + }; + struct Bin { + BinHeader mHeader; + typename T::BinData mData; + }; +#pragma pack(pop) + +protected: + /** Load the object from binary */ + virtual void SetBinaryInner(const Bin &) = 0; + /** Save the object to binary */ virtual void GetBinaryInner(Bin *) const = 0; - virtual size_t GetBinarySize() = 0; - virtual void SetBinaryInner(const Bin &, const Bin &, f32) = 0; + /** Get the size of the serialized data. Override if your binary has a dynamic size */ + virtual size_t GetBinarySize() const { + return sizeof(Bin); + } + /** Load the object from binary, interpolating between values */ + virtual void SetBinaryInner(const Bin &, const Bin &, f32) {} + virtual ~IBinary() {} + + /** Get a 4-bytes long ID string corresponding to this type */ static const char *GetBinaryType(); - int GetVersion(); - - void GetBinary(void *) const; + /** Get the current version of this type */ + static int GetVersion(); +public: + // These functions below are automatically provided, you should not need to + // touch them to implement de-/serialization for your type. They will parse + // the binary header and then invoke the above virtual functions. void SetBinary(const void *); - - void SetBinaryBlend(const void *, const void *, f32); + void GetBinary(void *pData) const; + void SetBinaryBlend(const void *a, const void *b, f32 blend); }; +template +void IBinary::SetBinary(const void *a) { + const Bin *pBinA = reinterpret_cast(a); + SetBinaryInner(*pBinA); +} + +template +void IBinary::GetBinary(void *pData) const { + Bin *pBin = reinterpret_cast(pData); + BinHeader zeroedHeader = {0}; + pBin->mHeader = zeroedHeader; + + pBin->mHeader.mVersion = GetVersion(); + pBin->mHeader.mSize = GetBinarySize(); + for (int i = 0; i < 4; i++) { + pBin->mHeader.mType[i] = GetBinaryType()[i]; + } + typename T::BinData zeroedDatat = {0}; + pBin->mData = zeroedDatat; + GetBinaryInner(pBin); +} + +template +void IBinary::SetBinaryBlend(const void *a, const void *b, f32 blend) { + const Bin *pBinA = reinterpret_cast(a); + const Bin *pBinB = reinterpret_cast(b); + SetBinaryInner(*pBinA, *pBinB, blend); +} + +} // namespace EGG + #endif diff --git a/include/m/m3d/m3d.h b/include/m/m3d/m3d.h index f994db04..db977ea8 100644 --- a/include/m/m3d/m3d.h +++ b/include/m/m3d/m3d.h @@ -1,9 +1,7 @@ #ifndef M3D_H #define M3D_H -#include "egg/core/eggHeap.h" -#include "egg/gfx/eggFog.h" -#include "egg/gfx/eggLight.h" +#include "egg/egg_types.h" #include "m/m_allocator.h" #include "nw4r/g3d/g3d_scnroot.h" diff --git a/include/nw4r/g3d/g3d_calcworld.h b/include/nw4r/g3d/g3d_calcworld.h index 989886eb..d32c5adf 100644 --- a/include/nw4r/g3d/g3d_calcworld.h +++ b/include/nw4r/g3d/g3d_calcworld.h @@ -63,13 +63,13 @@ public: void SetScale(f32 x, f32 y, f32 z); void GetMtx(nw4r::math::MTX34 *out) { - if (out != nullptr) { + if (out != NULL) { PSMTXCopy(*mpM, *out); } } void SetMtx(const nw4r::math::MTX34 *arg) { - if (arg != nullptr) { + if (arg != NULL) { PSMTXCopy(*arg, *mpM); } else { PSMTXIdentity(*mpM); diff --git a/include/nw4r/g3d/g3d_fog.h b/include/nw4r/g3d/g3d_fog.h index 417198d3..7cbe9e00 100644 --- a/include/nw4r/g3d/g3d_fog.h +++ b/include/nw4r/g3d/g3d_fog.h @@ -76,6 +76,13 @@ public: bool IsFogRangeAdjEnable() const { return IsValid() && ref().adjEnable == TRUE; } + + void SetFogRangeAdjEnable(bool enable) { + if (!IsValid()) { + return; + } + ref().adjEnable = enable; + } }; } // namespace g3d diff --git a/include/nw4r/g3d/g3d_obj.h b/include/nw4r/g3d/g3d_obj.h index 07b7ebcf..769f0251 100644 --- a/include/nw4r/g3d/g3d_obj.h +++ b/include/nw4r/g3d/g3d_obj.h @@ -133,7 +133,7 @@ public: if (pObj != NULL && pObj->IsDerivedFrom(TTo::GetTypeObjStatic())) { return static_cast(pObj); } - return nullptr; + return NULL; } private: diff --git a/include/nw4r/g3d/res/g3d_resanmamblight.h b/include/nw4r/g3d/res/g3d_resanmamblight.h index c9e2a48c..cbd5a28e 100644 --- a/include/nw4r/g3d/res/g3d_resanmamblight.h +++ b/include/nw4r/g3d/res/g3d_resanmamblight.h @@ -58,6 +58,16 @@ public: u32 GetRefNumber() const { return ref().refNumber; } + + const char *GetName() const { + const ResAnmAmbLightData &r = ref(); + + if (r.name != 0) { + return NW4R_G3D_OFS_TO_RESNAME(&r, r.name).GetName(); + } + + return NULL; + } }; } // namespace g3d diff --git a/include/nw4r/g3d/res/g3d_resanmscn.h b/include/nw4r/g3d/res/g3d_resanmscn.h index 57540436..c2f270aa 100644 --- a/include/nw4r/g3d/res/g3d_resanmscn.h +++ b/include/nw4r/g3d/res/g3d_resanmscn.h @@ -98,6 +98,22 @@ public: u16 GetResAnmFogMaxRefNumber() const { return ref().info.numResAnmFogData; } + + u16 GetResAnmLightMaxRefNumber() const { + return ref().info.numResAnmLightData; + } + + u16 GetResAnmAmbLightMaxRefNumber() const { + return ref().info.numResAnmAmbLightData; + } + + u16 GetResLightSetMaxRefNumber() const { + return ref().info.numResLightSetData; + } + + u16 GetSpecularLightNumber() const { + return ref().info.numSpecularLight; + } }; } // namespace g3d diff --git a/include/nw4r/g3d/res/g3d_reslightset.h b/include/nw4r/g3d/res/g3d_reslightset.h index 3669d25c..23e0429f 100644 --- a/include/nw4r/g3d/res/g3d_reslightset.h +++ b/include/nw4r/g3d/res/g3d_reslightset.h @@ -49,6 +49,10 @@ public: return ref().ambLightId; } + u32 GetLightID(u32 index) const { + return ref().lightId[index]; + } + u32 GetNumLight() const { return ref().numLight; } diff --git a/include/nw4r/g3d/res/g3d_resmat.h b/include/nw4r/g3d/res/g3d_resmat.h index 0397d13e..0b7ddc59 100644 --- a/include/nw4r/g3d/res/g3d_resmat.h +++ b/include/nw4r/g3d/res/g3d_resmat.h @@ -246,6 +246,13 @@ public: ); } + void Disable(u32 id) { + ref().flag = + ref().flag & + ~((TexSrt::FLAG_ANM_EXISTS | TexSrt::FLAG_SCALE_ONE | TexSrt::FLAG_ROT_ZERO | TexSrt::FLAG_TRANS_ZERO) + << (id * TexSrt::NUM_OF_FLAGS)); + } + bool IsExist(u32 id) const { if (IsValid()) { return ptr()->flag & (1 << id * TexSrt::NUM_OF_FLAGS); @@ -501,7 +508,7 @@ public: return NW4R_G3D_OFS_TO_RESNAME(&r, r.nameTex).GetName(); } - return nullptr; + return NULL; } bool IsCIFmt() const { @@ -513,6 +520,35 @@ private: void BindPltt_(const ResPltt pltt, ResTlutObj tlutObj); }; +/****************************************************************************** + * + * ResTexPlttInfoOffsetData + * + ******************************************************************************/ +struct ResTexPlttInfoOffsetData { + u32 size; // at 0x0 + u8 _0x04[4]; // at 0x4 + struct Unk { + s32 texPlltInfo; + u8 _0x00[4]; + } data[1]; // at 0x8 +}; + +class ResTexPlttInfoOffset : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResTexPlttInfoOffset); + + ResTexPlttInfo GetPllt(int idx) const { + const ResTexPlttInfoOffsetData &r = ref(); + return ofs_to_obj(r.data[idx].texPlltInfo); + } + + u32 GetNumData() const { + const ResTexPlttInfoOffsetData &r = ref(); + return r.size; + } +}; + /****************************************************************************** * * ResMatFur diff --git a/include/nw4r/g3d/res/g3d_resmdl.h b/include/nw4r/g3d/res/g3d_resmdl.h index 3d38c6ce..db0a2b6a 100644 --- a/include/nw4r/g3d/res/g3d_resmdl.h +++ b/include/nw4r/g3d/res/g3d_resmdl.h @@ -196,7 +196,7 @@ public: ResShp GetResShp(u32 idx) const; u32 GetResShpNumEntries() const; - ResTexPlttInfo GetResTexPlttInfoOffsetFromTexName(int idx) const; + ResTexPlttInfoOffset GetResTexPlttInfoOffsetFromTexName(int idx) const; u32 GetResTexPlttInfoOffsetFromTexNameNumEntries() const; ResMdlInfo GetResMdlInfo() { diff --git a/include/nw4r/g3d/res/g3d_resnode.h b/include/nw4r/g3d/res/g3d_resnode.h index 29242792..bc084e72 100644 --- a/include/nw4r/g3d/res/g3d_resnode.h +++ b/include/nw4r/g3d/res/g3d_resnode.h @@ -67,8 +67,8 @@ struct ResNodeData : ResNodeDataTypedef { math::_VEC3 scale; // at 0x20 math::_VEC3 rot; // at 0x2C math::_VEC3 translate; // at 0x38 - math::_VEC3 volume_min; // at 0x44 - math::_VEC3 volume_max; // at 0x50 + math::_VEC3 volume_min; // at 0x44 + math::_VEC3 volume_max; // at 0x50 s32 toParentNode; // at 0x5C s32 toChildNode; // at 0x60 s32 toNextSibling; // at 0x64 @@ -95,6 +95,11 @@ public: return ResName(NULL); } + const char *GetName() const { + const ResNodeData &r = ref(); + return ofs_to_ptr(r.name); + } + u32 GetID() const { if (IsValid()) { return ptr()->id; @@ -145,12 +150,12 @@ public: // not in the dwarf const math::VEC3 &GetBoundsMin() const { - return *(const math::VEC3*)&ref().volume_min; + return *(const math::VEC3 *)&ref().volume_min; } // not in the dwarf const math::VEC3 &GetBoundsMax() const { - return *(const math::VEC3*)&ref().volume_max; + return *(const math::VEC3 *)&ref().volume_max; } ResNode GetParentNode() { diff --git a/include/nw4r/lyt/lyt_texMap.h b/include/nw4r/lyt/lyt_texMap.h index 2b15fafd..f1f82da5 100644 --- a/include/nw4r/lyt/lyt_texMap.h +++ b/include/nw4r/lyt/lyt_texMap.h @@ -1,9 +1,11 @@ #ifndef NW4R_LYT_TEXMAP_H #define NW4R_LYT_TEXMAP_H #include "common.h" -#include "rvl/GX.h" // IWYU pragma: export #include "rvl/TPL/TPL.h" +#include "rvl/GX.h" // IWYU pragma: export + + namespace nw4r { namespace lyt { namespace detail { diff --git a/include/rvl/GX/GXFrameBuf.h b/include/rvl/GX/GXFrameBuf.h index 774e6fb8..5ee0b888 100644 --- a/include/rvl/GX/GXFrameBuf.h +++ b/include/rvl/GX/GXFrameBuf.h @@ -29,6 +29,7 @@ u16 GXGetNumXfbLines(u16 height, f32 scale); void GXSetDispCopyDst(u16 width, u16 height); u32 GXSetDispCopyYScale(f32 scale); void GXCopyDisp(void *data, GXBool bUpdate); +void GXSetCopyClamp(int val); // TODO void GXSetTexCopySrc(u16 left, u16 top, u16 width, u16 height); void GXSetTexCopyDst(u16 left, u16 top, GXTexFmt fmt, u8 mipmap); diff --git a/include/rvl/GX/GXPixel.h b/include/rvl/GX/GXPixel.h index 044aa9a6..165ce4d9 100644 --- a/include/rvl/GX/GXPixel.h +++ b/include/rvl/GX/GXPixel.h @@ -17,11 +17,15 @@ void GXSetFog(GXFogType type, GXColor color, f32 start, f32 end, f32 near, f32 f void GXInitFogAdjTable(GXFogAdjTable *table, u16 width, const Mtx44 proj); void GXSetFogRangeAdj(GXBool enable, u16 center, const GXFogAdjTable *table); void GXSetBlendMode(GXBlendMode mode, GXBlendFactor src, GXBlendFactor dst, GXLogicOp op); +void GXGetColorUpdate(GXBool *enable); void GXSetColorUpdate(GXBool enable); +void GXGetAlphaUpdate(GXBool *enable); void GXSetAlphaUpdate(GXBool enable); void GXSetZMode(GXBool enableTest, GXCompare func, GXBool enableUpdate); void GXSetZCompLoc(GXBool beforeTex); +void GXGetPixelFmt(GXPixelFmt *pixelFmt, GXZFmt16 *zFmt); void GXSetPixelFmt(GXPixelFmt pixelFmt, GXZFmt16 zFmt); +void GXGetDither(GXBool *enable); void GXSetDither(GXBool enable); void GXSetDstAlpha(GXBool enable, u8 alpha); void GXSetFieldMask(GXBool enableEven, GXBool enableOdd); diff --git a/include/rvl/GX/GXTexture.h b/include/rvl/GX/GXTexture.h index 9fbbdace..e6428e51 100644 --- a/include/rvl/GX/GXTexture.h +++ b/include/rvl/GX/GXTexture.h @@ -29,7 +29,7 @@ void GXInitTexObjLOD( u8 biasClampEnable, u8 edgeLODEnable, GXAnisotropy anisotropy ); void GXInitTexObjTlut(GXTexObj *, u32); -void GXInitTexObjCI(GXTexObj *, void *, u16, u16, GXTexFmt, GXTexWrapMode, GXTexWrapMode, u8, u32); +void GXInitTexObjCI(GXTexObj *, void *, u16, u16, GXCITexFmt, GXTexWrapMode, GXTexWrapMode, u8, u32); void GXInitTlutObj(GXTlutObj *, void *, GXTlutFmt, u16); void GXLoadTlut(GXTlutObj *, u32); @@ -44,13 +44,22 @@ void GXGetTexObjLODAll( u8 *biasClampEnable, u8 *edgeLODEnable, GXAnisotropy *anisotropy ); +void GXInitTexObjFilter(GXTexObj *, GXTexFilter minFilter, GXTexFilter magFilter); +void GXInitTexObjWrapMode(GXTexObj *, GXTexWrapMode wrapS, GXTexWrapMode wrapT); + +void GXSetTexCoordScaleManually(GXTexCoordID, GXBool, u16, u16); +void GXSetTexCoordBias(GXTexCoordID, GXBool, GXBool); + u16 GXGetTexObjWidth(const GXTexObj *obj); u16 GXGetTexObjHeight(const GXTexObj *obj); GXTexFmt GXGetTexObjFormat(const GXTexObj *obj); GXBool GXGetTexObjMipMap(const GXTexObj *obj); -GXTexWrapMode GXGetTexObjWrapS(GXTexObj *obj); -u32 GXGetTexObjTlut(GXTexObj *); -GXTexWrapMode GXGetTexObjWrapT(GXTexObj *obj); +GXTexWrapMode GXGetTexObjWrapS(const GXTexObj *obj); +u32 GXGetTexObjTlut(const GXTexObj *); +GXTexWrapMode GXGetTexObjWrapT(const GXTexObj *); +GXTexFilter GXGetTexObjMinFilt(const GXTexObj *); +GXTexFilter GXGetTexObjMagFilt(const GXTexObj *); +void *GXGetTexObjData(const GXTexObj *); u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, GXBool arg3, u8 arg4); void GXInvalidateTexAll(); diff --git a/include/rvl/GX/GXTransform.h b/include/rvl/GX/GXTransform.h index bc571398..8ef9ecb5 100644 --- a/include/rvl/GX/GXTransform.h +++ b/include/rvl/GX/GXTransform.h @@ -33,7 +33,7 @@ void GXGetViewportv(f32 view[6]); void GXSetZScaleOffset(f32 scale, f32 offset); void GXSetScissor(u32 x, u32 y, u32 w, u32 h); void GXGetScissor(u32 *x, u32 *y, u32 *w, u32 *h); -void GXSetScissorBoxOffset(u32 ox, u32 oy); +void GXSetScissorBoxOffset(s32 ox, s32 oy); void GXSetClipMode(GXClipMode mode); void __GXSetProjection(void); diff --git a/include/rvl/OS/OSFastCast.h b/include/rvl/OS/OSFastCast.h index 9f86bac7..8780217f 100644 --- a/include/rvl/OS/OSFastCast.h +++ b/include/rvl/OS/OSFastCast.h @@ -10,7 +10,7 @@ extern "C" { #define OS_GQR_TYPE_S8 6 #define OS_GQR_TYPE_S16 7 -static void OSInitFastCast(void) { +static inline void OSInitFastCast(void) { // clang-format off asm { li r3, 4 diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring index 8b388ec0..8a62a363 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring @@ -19,7 +19,7 @@ using ::strlen; using ::strncat; using ::strncmp; using ::strncpy; -// using ::strstr; +using ::strstr; } // namespace std #endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h index 86c421b3..8e36bf83 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h @@ -17,6 +17,7 @@ char *strrchr(const char *str, int c); char *strchr(const char *str, int c); int strncmp(const char *str1, const char *str2, size_t n); int strcmp(const char *str1, const char *str2); +char *strstr(const char *str1, const char *str2); char *strncat(char *dst, const char *src, size_t n); char *strcat(char *dst, const char *src); char *strncpy(char *dst, const char *src, size_t n); diff --git a/src/REL/d/a/obj/d_a_obj_pool_cock.cpp b/src/REL/d/a/obj/d_a_obj_pool_cock.cpp index f52cd41e..585c021c 100644 --- a/src/REL/d/a/obj/d_a_obj_pool_cock.cpp +++ b/src/REL/d/a/obj/d_a_obj_pool_cock.cpp @@ -52,10 +52,9 @@ int dAcOPoolCock_c::actorExecute() { position += velocity; position += mStts.mCcMove; updateMatrix(); - mMtx_c mdl1Transform; - mMtx_c mdl2Transform; - mdl1Transform = mWorldMtx; - mdl2Transform = mWorldMtx; + + mMtx_c mdl1Transform(mWorldMtx); + mMtx_c mdl2Transform(mWorldMtx); mMtx_c tmp1; mMtx_c tmp2; diff --git a/src/d/lyt/d2d.cpp b/src/d/lyt/d2d.cpp index c69bada8..d33c741e 100644 --- a/src/d/lyt/d2d.cpp +++ b/src/d/lyt/d2d.cpp @@ -164,7 +164,7 @@ nw4r::lyt::AnimTransform *Layout_c::CreateAnimTransform(const void *animResBuf, Multi_c::Multi_c() : Base_c(0x80), mLayout(), mDrawInfo(), mpResAcc(nullptr), mFlags(0) { mDrawInfo.SetLocationAdjustScale(nw4r::math::VEC2( - (f32)EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_1) / (f32)EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_2), + (f32)EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_4_3) / (f32)EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_16_9), 1.0f )); mDrawInfo.SetLocationAdjust(true); @@ -207,8 +207,8 @@ void Multi_c::draw() { f32 far = 500.0f; EGG::Screen s; bool needsAdjust = NeedsScreenAdjustment(); - f32 f1 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_2); - f32 f2 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_1); + f32 f1 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_UNK_3); + f32 f2 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_16_9); f32 left = needsAdjust ? f1 * r.left / f2 : r.left; f32 right = needsAdjust ? f1 * r.right / f2 : r.right; diff --git a/src/egg/gfx/eggAnalizeDL.cpp b/src/egg/gfx/eggAnalizeDL.cpp new file mode 100644 index 00000000..e8febe68 --- /dev/null +++ b/src/egg/gfx/eggAnalizeDL.cpp @@ -0,0 +1,181 @@ +#include "egg/gfx/eggAnalizeDL.h" + +#include "nw4r/g3d/res/g3d_resshp.h" +#include "nw4r/g3d/res/g3d_resvtx.h" + +namespace EGG { + +AnalizeDL::AnalizeDL(nw4r::g3d::ResShp shp) { + mpData = shp.GetPrimDLTag().GetDL(); + mBufSize = shp.GetPrimDLTag().GetBufSize(); + mCursor = 0; + field_0x00C = 0; + shp.GXGetVtxDescv(mVtxDescList); + shp.GXGetVtxAttrFmtv(mAttrFmtList); + field_0x00E = 0; + field_0x00F = 0; + field_0x010 = 0; + + init(); + nw4r::g3d::ResVtxPos pos = shp.GetResVtxPos(); + pos.GetArray(&mpArr, &mArrStride); + mStatus = STATUS_NONE; + field_0x1CC = 0; + + for (int i = 0; i < 10; i++) { + field_0x1A0[i] = -1; + field_0x1B4[i] = -1; + } +} + +AnalizeDL::Status AnalizeDL::step() { + if (mBufSize <= mCursor) { + mStatus = STATUS_END; + } else if (field_0x1CC == 0) { + u8 *pCommand = &mpData[mCursor]; + u8 command = pCommand[0]; + switch (command) { + case 0x20: + field_0x1A0[pCommand[4] / 12] = pCommand[2]; + mStatus = STATUS_1; + mCursor += 5; + break; + case 0x28: + field_0x1B4[pCommand[4] / 9] = pCommand[2]; + mStatus = STATUS_2; + mCursor += 5; + break; + case 0x30: mCursor += 5; break; + case 0x90: + case 0xA8: + case 0xB8: + case 0xB0: + case 0xA0: + case 0x98: + case 0x80: + field_0x1C8 = command; + field_0x1CA = *reinterpret_cast(pCommand + 1); + field_0x1CC = field_0x1CA; + mStatus = STATUS_3; + mCursor += 3; + break; + case 0x0: mCursor += 1; break; + default: mCursor += 1; break; + } + } else { + u8 *pCommand = &mpData[mCursor]; + if ((field_0x010 & 1) != 0) { + mVtxResult.mMtxIdx = field_0x1A0[*(pCommand++) / 3]; + } else { + mVtxResult.mMtxIdx = -1; + } + + for (int i = 0; i < 8; i++) { + if ((field_0x010 & (1 << (i + 1))) != 0) { + pCommand++; + } + } + + if ((field_0x010 & 0x200) != 0) { + if (field_0x00F == 1) { + mVtxResult.field_0x04 = *pCommand; + } else { + mVtxResult.field_0x04 = *reinterpret_cast(pCommand); + } + + int val; + u8 shift = mAttrFmtList[0].shift; + + const u8 *pData = static_cast(mpArr); + pData += mArrStride * mVtxResult.field_0x04; + + switch (mAttrFmtList[0].compType) { + case GX_U8: { + val = 1 << shift; + const u8 *dat = reinterpret_cast(pData); + mVtxResult.field_0x08.x = dat[0] / (f32)val; + mVtxResult.field_0x08.y = dat[1] / (f32)val; + mVtxResult.field_0x08.z = dat[2] / (f32)val; + break; + } + case GX_S8: { + val = 1 << shift; + const s8 *dat = reinterpret_cast(pData); + mVtxResult.field_0x08.x = dat[0] / (f32)val; + mVtxResult.field_0x08.y = dat[1] / (f32)val; + mVtxResult.field_0x08.z = dat[2] / (f32)val; + break; + } + case GX_U16: { + val = 1 << shift; + const u16 *dat = reinterpret_cast(pData); + mVtxResult.field_0x08.x = dat[0] / (f32)val; + mVtxResult.field_0x08.y = dat[1] / (f32)val; + mVtxResult.field_0x08.z = dat[2] / (f32)val; + break; + } + case GX_S16: { + val = 1 << shift; + const s16 *dat = reinterpret_cast(pData); + mVtxResult.field_0x08.x = dat[0] / (f32)val; + mVtxResult.field_0x08.y = dat[1] / (f32)val; + mVtxResult.field_0x08.z = dat[2] / (f32)val; + break; + } + case GX_F32: { + const f32 *dat = reinterpret_cast(pData); + mVtxResult.field_0x08.x = dat[0]; + mVtxResult.field_0x08.y = dat[1]; + mVtxResult.field_0x08.z = dat[2]; + break; + } + default: break; + } + } else { + mVtxResult.field_0x04 = -1; + mVtxResult.field_0x08.z = 0.0f; + mVtxResult.field_0x08.y = 0.0f; + mVtxResult.field_0x08.x = 0.0f; + } + field_0x1CC -= 1; + mStatus = STATUS_VTX; + mCursor += field_0x00E; + } + + return mStatus; +} + +static const s8 sArr1[] = {0, -1, 1, 2}; +static const u8 sArr2[] = {1, 1, 2, 2, 4, 0}; + +void AnalizeDL::init() { + for (int k = 0, i = 0; mVtxDescList[i].attr != GX_VA_NULL; k++, i++) { + // Likely a fakematch + int x = sArr1[mVtxDescList[i++, --i].type]; + if (x == -1) { + if (k >= 0 && k <= 8) { + x = 1; + } else { + int j = -1; + while (k != mAttrFmtList[++j].attr) {} + + x = sArr2[mAttrFmtList[j].compType]; + } + } + + if (k == 9) { + field_0x00F = x; + } + + field_0x00E += x; + if (x != 0) { + field_0x010 |= (1 << k); + } + } +} + +const AnalizeDL::VtxResult &AnalizeDL::getVtxResult() const { + return mVtxResult; +} + +} // namespace EGG diff --git a/src/egg/gfx/eggCamera.cpp b/src/egg/gfx/eggCamera.cpp index ad0889b8..b99ed73c 100644 --- a/src/egg/gfx/eggCamera.cpp +++ b/src/egg/gfx/eggCamera.cpp @@ -1,3 +1,98 @@ #include "egg/gfx/eggCamera.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/math/eggMatrix.h" +#include "egg/math/eggVector.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXTransform.h" + +namespace EGG { + +void BaseCamera::updateMatrix() { + doUpdateMatrix(); +} + +void BaseCamera::draw(EGG::BaseCamera *cam) { + cam->loadMatrix(); + doDraw(); +} + +void BaseCamera::setG3DCamera(nw4r::g3d::Camera &cam) { + cam.SetCameraMtxDirectly(*reinterpret_cast(&getViewMatrix())); +} + +Matrix34f &LookAtCamera::getViewMatrixOld() { + return mOtherMtx; +} + +void LookAtCamera::doUpdateMatrix() { + mOtherMtx = mViewMtx; + + Vector3f right(mPos); + + right -= mAt; + right.normalise(); + + Vector3f forward(mUp.cross(right).normalize()); + + Vector3f up(right.cross(forward)); + up.normalise(); + + f32 tx = -forward.dot(mPos); + f32 ty = -up.dot(mPos); + f32 tz = -right.dot(mPos); + + f32 t[] = { tx, ty, tz}; + + mViewMtx(0, 0) = forward(0); + mViewMtx(0, 1) = forward(1); + mViewMtx(0, 2) = forward(2); + mViewMtx(0, 3) = tx; + + mViewMtx(1, 0) = up(0); + mViewMtx(1, 1) = up(1); + mViewMtx(1, 2) = up(2); + mViewMtx(1, 3) = ty; + + mViewMtx(2, 0) = right(0); + mViewMtx(2, 1) = right(1); + mViewMtx(2, 2) = right(2); + mViewMtx(2, 3) = tz; +} + +void LookAtCamera::doDraw() {} + +void LookAtCamera::loadMatrix() { + Matrix34f mtx; + GXLoadPosMtxImm(mViewMtx.m, 0); + mViewMtx.inverseTransposeTo(mtx); + GXLoadNrmMtxImm(mtx.m, 0); +} + +void LookAtCamera::loadOldMatrix() {} + +OrthoCamera::OrthoCamera() { + field_0x8C = 0.5f; + field_0x88 = 0.0f; + update_parms(); +} + +void OrthoCamera::update_parms() { + f32 z = field_0x8C; + f32 sin = field_0x88.sin(); + f32 cos = field_0x88.cos(); + + mPos(1) = mAt(1); + mPos(0) = mAt(0); + mPos(2) = z; + mUp(2) = 0.f; + mUp(1) = cos; + mUp(0) = sin; +} + +void OrthoCamera::doUpdateMatrix() { + update_parms(); + LookAtCamera::doUpdateMatrix(); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggCapTexture.cpp b/src/egg/gfx/eggCapTexture.cpp index d2779ce3..0847d808 100644 --- a/src/egg/gfx/eggCapTexture.cpp +++ b/src/egg/gfx/eggCapTexture.cpp @@ -1,3 +1,69 @@ #include "egg/gfx/eggCapTexture.h" -namespace EGG {} // namespace EGG +#include "egg/gfx/eggCpuTexture.h" +#include "egg/gfx/eggStateGX.h" +#include "rvl/GX/GXFrameBuf.h" +#include "rvl/GX/GXPixel.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +static const GXColor sBlack = {0, 0, 0, 0}; +static const CopyFilter defaultFilter = { + {0, 0, 1, 0x3F, 0, 0, 0} +}; + +static const u8 copyArg2[12][2] = {}; + +void CapTexture::configure() { + CpuTexture::configure(); + mCapFlags = 0; + mClearColor = sBlack; + field_0x20 = 0xFFFFFF; + mCopyFilterArg = defaultFilter; +} + +void CapTexture::capture(u16 x, u16 y, bool upscale, int format) { + GXTexFmt fmt = format == -1 ? getFormat() : static_cast(format); + u16 width = upscale ? getWidth() * 2 : getWidth(); + u16 height = upscale ? getHeight() * 2 : getHeight(); + + GXSetTexCopySrc(x, y, width, height); + GXSetTexCopyDst(mWidth, mHeight, fmt, upscale); + + GXSetCopyFilter( + 0, copyArg2, (mCapFlags & 8) ? true : false, (mCapFlags & 8) ? mCopyFilterArg.values : defaultFilter.values + ); + + StateGX::ScopedColor colorUpdate((mCapFlags & 1) != 0); + StateGX::ScopedAlpha alphaUpdate((mCapFlags & 2) != 0); + GXSetZMode(true, GX_ALWAYS, (mCapFlags & 4) != 0); + GXSetCopyClear(mClearColor, field_0x20); + GXSetCopyClamp(3); + StateGX::GXCopyTex_(dataPtr, true); + GXSetCopyFilter(0, copyArg2, 0, defaultFilter.values); + + if ((mCapFlags & 0x10) != 0) { + GXPixModeSync(); + } + + if ((mCapFlags & 0x20) != 0) { + StateGX::invalidateTexAllGX(); + } +} + +void CapTexture::fn_8049D9D0(u8 arg) { + onCapFlag(0x8); + + CopyFilter v; + v.values[0] = arg; + v.values[1] = 0; + v.values[2] = 1; + v.values[3] = 64 - (2 * arg) - 1; + v.values[4] = 0; + v.values[5] = arg; + v.values[6] = 0; + setCopyFilter(v); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggCpuTexture.cpp b/src/egg/gfx/eggCpuTexture.cpp index 674d190b..9cf4860c 100644 --- a/src/egg/gfx/eggCpuTexture.cpp +++ b/src/egg/gfx/eggCpuTexture.cpp @@ -1,3 +1,372 @@ #include "egg/gfx/eggCpuTexture.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/core/eggHeap.h" +#include "egg/gfx/eggGXUtility.h" +#include "egg/gfx/eggTexture.h" +#include "egg/math/eggVector.h" +#include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/vec.h" +#include "rvl/OS/OSCache.h" + +namespace EGG { + +namespace { + +void calcColorGradient(GXColor &outColor, const GXColor &c1, const GXColor &c2, f32 amount) { + if (amount <= 0.0f) { + outColor = c1; + } else if (amount >= 1.0f) { + outColor = c2; + } else { + outColor.r = c1.r + amount * (c2.r - c1.r); + outColor.g = c1.g + amount * (c2.g - c1.g); + outColor.b = c1.b + amount * (c2.b - c1.b); + outColor.a = c1.a + amount * (c2.a - c1.a); + } +} + +void makeGradient(int op, GXColor *outColor, int size, int start, int end, const GXColor &c1, const GXColor &c2) { + int start_p1 = start + 1; + // Weird instruction calculation + for (int i = 0; i < start_p1; i++) { + outColor[i] = c1; + } + + int end_1 = end - 1; + for (int i = end_1; i < size; i++) { + outColor[i] = c2; + } + + for (int i = start_p1; i < end_1; i++) { + f32 ratio = (f32)(i - start) / (f32)(end - start); + switch (op) { + case 0: break; + case 1: ratio *= ratio; break; + case 2: + ratio *= ratio; + ratio *= ratio; + break; + case 3: + ratio *= ratio; + ratio *= ratio; + ratio *= ratio; + break; + case 4: + ratio *= ratio; + ratio *= ratio; + ratio *= ratio; + ratio *= ratio; + break; + case 5: ratio = -(ratio - 1.0f) * (ratio - 1.0f) + 1.0f; break; + case 6: + ratio -= 1.0f; + ratio = -ratio * ratio * ratio * ratio + 1.0f; + break; + } + calcColorGradient(outColor[i], c1, c2, ratio); + } +} + +} // namespace + +CpuTexture::CpuTexture() { + mWidth = 0; + mHeight = 0; + mFlags = 0; + mTexFormat = GX_TF_RGBA8; + mWrapS = 0; + mWrapT = 0; + mMinFilt = 1; + mMagFilt = 1; + dataPtr = nullptr; + mpBuffer = nullptr; +} + +CpuTexture::CpuTexture(u16 width, u16 height, GXTexFmt texFmt) { + mWidth = width; + mHeight = height; + mFlags = 0; + mTexFormat = texFmt; + mWrapS = 0; + mWrapT = 0; + mMinFilt = 1; + mMagFilt = 1; + dataPtr = nullptr; + mpBuffer = nullptr; +} + +CpuTexture::CpuTexture(const GXTexObj *pObj) { + mWidth = GXGetTexObjWidth(pObj); + mHeight = GXGetTexObjHeight(pObj); + + mTexFormat = GXGetTexObjFormat(pObj); + mWrapS = GXGetTexObjWrapS(pObj); + mWrapT = GXGetTexObjWrapT(pObj); + mMinFilt = GXGetTexObjMinFilt(pObj); + mMagFilt = GXGetTexObjMagFilt(pObj); + // Convert Physical to Virtual Address + dataPtr = (char *)GXGetTexObjData(pObj) - 0x80000000; + mpBuffer = nullptr; +} + +CpuTexture::~CpuTexture() { + if ((mFlags & NEEDS_BUFFER_FREE) != 0) { + delete[] mpBuffer; + } +} + +void CpuTexture::configure() { + mFlags = CONFIGURED; +} + +void CpuTexture::setBuffer(void *buf) { + if (buf != nullptr) { + dataPtr = buf; + } + mFlags &= ~HAS_HEADER; +} + +void CpuTexture::load(GXTexMapID id) const { + GXTexObj obj; + getTexObj(&obj); + GXLoadTexObj(&obj, id); +} + +void CpuTexture::getTexObj(GXTexObj *pObj) const { + GXInitTexObj(pObj, dataPtr, mWidth, mHeight, getFormat(), (GXTexWrapMode)mWrapS, (GXTexWrapMode)mWrapT, false); + GXInitTexObjLOD(pObj, (GXTexFilter)mMinFilt, (GXTexFilter)mMagFilt, 0.0f, 0.0f, 0.0f, false, false, GX_ANISO_1); +} + +void CpuTexture::flush() const { + size_t size = GXGetTexBufferSize(mWidth, mHeight, getFormat(), false, true); + DCFlushRange(dataPtr, size); +} + +void CpuTexture::buildHeader() const { + ResTIMG *pHdr = getHeader(); + + pHdr->format = mTexFormat; + pHdr->alphaEnabled = 1; + pHdr->width = mWidth; + pHdr->height = mHeight; + pHdr->wrapS = mWrapS; + pHdr->wrapT = mWrapT; + pHdr->indexTexture = 0; + pHdr->colorFormat = 0; + pHdr->numColors = 0; + pHdr->paletteOffset = 0; + pHdr->mipmapEnabled = 0; + pHdr->doEdgeLOD = 0; + pHdr->biasClamp = 0; + pHdr->maxAnisotropy = 0; + pHdr->minFilter = mMinFilt; + pHdr->magFilter = mMagFilt; + pHdr->minLOD = 0; + pHdr->maxLOD = 0; + pHdr->mipmapCount = 1; + pHdr->LODBias = 0; + pHdr->imageOffset = sizeof(ResTIMG); +} + +extern "C" double sqrt(double); + +void CpuTexture::fillNormalMapSphere(f32 f1, f32 f2) { + f32 mid = static_cast(mWidth / 2); + + for (u16 y = 0; y < mHeight; y++) { + for (u16 x = 0; x < mWidth; x++) { + Vector3f vec; + GXColor c; + + f32 fx = f1 * ((x + f2) - mid); + f32 fy = f1 * -((y + f2) - mid); + + f32 mid2 = mid * mid; + f32 fz = mid2 - (fx * fx + fy * fy); + + vec(0) = fx; + vec(1) = fy; + vec(2) = fz < Math::zero() ? Math::zero() : (f32)sqrt(fz); + + PSVECNormalize(vec, vec); + GXUtility::getNormalColor(c, vec); + c.r = c.a; + setColor(x, y, c); + } + } + flush(); +} + +void CpuTexture::fillGradient( + int op, int unk, u16 start, u16 end, const GXColor &c1, const GXColor &c2, bool b1, bool b2 +) { + // NONMATCHING - regswaps + + GXColor gradient[1024]; + GXColor colors[256]; + + bool swapMode = unk == 0x73 || unk == 0x53; + u16 width = swapMode ? mWidth : mHeight; + u16 height = swapMode ? mHeight : mWidth; + u16 mid = width / 2; + + makeGradient(op, gradient, width, start, end, c1, c2); + if (b1) { + // Regswaps here + for (int i2 = mid, i = 0; i < width; i2++, i++) { + colors[i].r = gradient[i < mid ? i2 : i - mid].r; + colors[i].g = gradient[i < mid ? i2 : i - mid].g; + colors[i].b = gradient[i < mid ? i2 : i - mid].b; + colors[i].a = gradient[i < mid ? i2 : i - mid].a; + } + + for (int i = 0; i < width; i++) { + gradient[i] = colors[i]; + } + } + + u16 start2 = b2 ? 0 : start; + u32 end2 = b2 ? width : end; + for (u16 x = start2; x < end2; x++) { + for (u16 y = 0; y < height; y++) { + if (swapMode) { + setColor(x, y, gradient[x]); + } else { + setColor(y, x, gradient[x]); + } + } + } + flush(); +} + +void CpuTexture::alloc(Heap *pHeap) { + Heap *heap = !pHeap ? Heap::getCurrentHeap() : pHeap; + + size_t size = GXGetTexBufferSize(mWidth, mHeight, getFormat(), false, true); + + mpBuffer = new (heap, 0x20) char[size]; + setBuffer(mpBuffer); + + mFlags |= NEEDS_BUFFER_FREE; +} + +void CpuTexture::allocWithHeaderDebug(Heap *pHeap) { + Heap *heap = !pHeap ? Heap::getCurrentHeap() : pHeap; + + size_t size = GXGetTexBufferSize(mWidth, mHeight, getFormat(), false, true); + + // Textures need 32-bit alignment ( ptr is represented with ptr >> 5 ) + mpBuffer = new (heap, 0x20) char[size + sizeof(ResTIMG)]; + + // Texture has Header -> offset to actual image data + void *imageData = mpBuffer + sizeof(ResTIMG); + + setBuffer(imageData); + if (imageData != nullptr) { + mFlags |= HAS_HEADER; + } + mFlags |= NEEDS_BUFFER_FREE; + buildHeader(); +} + +void CpuTexture::allocate(Heap *pHeap) { + alloc(pHeap); +} + +void CpuTexture::setColor(u16 x, u16 y, GXColor color) { + // NONMATCHING + switch (getFormat()) { + case GX_TF_RGBA8: + case GX_TF_Z24X8: { + int pix = (x & 0x3) * 2 + (y & 0x3) * 8; + int block = (x >> 2) + (y >> 2) * (getWidth() / 4); + + int offset = block * 0x40 + pix; + + u8 *dat = static_cast(getBuffer()) + offset; + + dat[0] = color.a; + dat[1] = color.r; + dat[0x20] = color.g; + dat[0x21] = color.b; + break; + } + case GX_TF_I8: + case GX_TF_Z8: { + // Regswaps here + int pix = (x & 0x7); + int pix_y = (y & 0x3) * 8; + + int block = (x >> 3); + int block_y = (y >> 2) * (getWidth() / 8); + + pix = pix + pix_y + (block + block_y) * 0x20; + + u8 *dat = static_cast(getBuffer()) + pix; + dat[0] = color.r; + + break; + } + + case GX_TF_IA8: + case GX_TF_Z16: { + int block = (x >> 2) + (y >> 2) * (getWidth() / 4); + int pix = (x & 0x3) * 2 + (y & 0x3) * 8; + + int offset = block * 0x20 + pix; + + u8 *dat = static_cast(getBuffer()) + offset; + + dat[0] = color.a; + dat[1] = color.r; + break; + } + default: break; + } +} + +GXColor CpuTexture::getColor(u16 x, u16 y) const { + // NONMATCHING + GXColor c; + switch (getFormat()) { + case GX_TF_RGBA8: + case GX_TF_Z24X8: { + int offset = ((x >> 2) + (y >> 2) * (getWidth() / 4)) * 0x40 + (y & 3) * 8 + (x & 3) * 2; + u8 *dat = static_cast(getBuffer()) + offset; + c.r = dat[1]; + c.g = dat[0x20]; + c.b = dat[0x21]; + c.a = dat[0]; + break; + } + case GX_TF_I8: + case GX_TF_Z8: { + int idx = (x & 0x7); + int pixel_idx = (y & 0x3) * 8; + int block_idx = ((getWidth() / 8) * (y >> 2) + (x >> 3)); + idx = idx + pixel_idx + block_idx * 0x20; + u8 *dat = static_cast(getBuffer()) + idx; + c.a = dat[0]; + c.b = dat[0]; + c.g = dat[0]; + c.r = dat[0]; + break; + } + + case GX_TF_IA8: + case GX_TF_Z16: { + int offset = ((x >> 2) + (y >> 2) * (getWidth() / 4)) * 0x20 + (y & 3) * 8 + (x & 3) * 2; + u8 *dat = static_cast(getBuffer()) + offset; + c.a = dat[0]; + c.b = dat[1]; + c.g = c.b; + c.r = c.b; + break; + } + default: break; + } + return c; +} +} // namespace EGG diff --git a/src/egg/gfx/eggDrawGX.cpp b/src/egg/gfx/eggDrawGX.cpp index 8f7b8d2a..31e973e6 100644 --- a/src/egg/gfx/eggDrawGX.cpp +++ b/src/egg/gfx/eggDrawGX.cpp @@ -1,3 +1,728 @@ #include "egg/gfx/eggDrawGX.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggGXUtility.h" +#include "egg/gfx/eggStateGX.h" +#include "math.h" +#include "nw4r/g3d/res/g3d_restex.h" +#include "nw4r/math/math_triangular.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXAttr.h" +#include "rvl/GX/GXBump.h" +#include "rvl/GX/GXDisplayList.h" +#include "rvl/GX/GXDraw.h" +#include "rvl/GX/GXGeometry.h" +#include "rvl/GX/GXLight.h" +#include "rvl/GX/GXPixel.h" +#include "rvl/GX/GXTev.h" +#include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTransform.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/GX/GXVert.h" +#include "rvl/MTX/mtx.h" +#include "rvl/MTX/mtxvec.h" +#include "rvl/MTX/vec.h" +#include "rvl/OS/OSCache.h" + +namespace EGG { + +const GXColor DrawGX::BLACK = {0x00, 0x00, 0x00, 0xFF}; +const GXColor DrawGX::WHITE = {0xFF, 0xFF, 0xFF, 0xFF}; +const GXColor DrawGX::RED = {0xFF, 0x00, 0x00, 0xFF}; +const GXColor DrawGX::GREEN = {0x00, 0xFF, 0x00, 0xFF}; +const GXColor DrawGX::BLUE = {0x00, 0x00, 0xFF, 0xFF}; + +const DrawGX::DL DrawGX::s_DL0 = DrawGX::DL_0; +const DrawGX::DL DrawGX::s_DL7 = DrawGX::DL_7; +const DrawGX::DL DrawGX::s_DL8 = DrawGX::DL_8; + +GXTexMapID DrawGX::sTexMapDefault; +GXLightID DrawGX::sLightMaskDefault = GX_LIGHT0; + +nw4r::math::MTX34 DrawGX::s_cameraMtx; +DrawGX::DLData DrawGX::s_DL[DL_MAX]; +GXTexObj DrawGX::sDummyTexObj; + +u32 DrawGX::s_flag; + +}; // namespace EGG + +namespace { + +static void DrawQuadNormal(u8 x1, u8 x2, u8 x3, u8 x4, u8 y) { + GXPosition2u8(x1, y); + GXPosition2u8(x2, y); + GXPosition2u8(x3, y); + GXPosition2u8(x4, y); +} + +static void DrawQuadLineStripNormal(u8 x1, u8 x2, u8 x3, u8 x4, u8 y) { + GXBegin(GX_LINESTRIP, GX_VTXFMT0, 5); + GXPosition2u8(x1, y); + GXPosition2u8(x2, y); + GXPosition2u8(x3, y); + GXPosition2u8(x4, y); + GXPosition2u8(x1, y); +} + +static void DrawCircleYPolygonFan(const nw4r::math::MTX34 &mtx, f32 f, u16 numSegments) { + f32 stepSize = (2.0f * M_PI / numSegments); + nw4r::math::VEC3 v1(0.0f, 1.0f, 0.0f); + nw4r::math::VEC3 v2(0.0f, f, 0.0f); + + int seg = numSegments + 1; + + PSMTXMultVec(mtx, v1, v1); + PSMTXMultVec(mtx, v2, v2); + + GXBegin(GX_TRIANGLEFAN, GX_VTXFMT0, seg + 1); + + f32 signedStepSize = -stepSize; + + GXPosition3f32(v2.x, v2.y, v2.z); + GXPosition3f32(v1.x, v1.y, v1.z); + + for (int i = 0; i < seg; i++) { + nw4r::math::VEC3 v3( + 0.5f * nw4r::math::SinRad(signedStepSize * i), 0.0f, 0.5f * nw4r::math::CosRad(signedStepSize * i) + ); + PSMTXMultVec(mtx, v3, v3); + GXPosition3f32(v3.x, v3.y, v3.z); + + nw4r::math::VEC3 v4( + 0.5f * nw4r::math::SinRad(signedStepSize * (i - 1)), 0.0f, + 0.5f * nw4r::math::CosRad(signedStepSize * (i - 1)) + ); + nw4r::math::VEC3 v5( + 0.5f * nw4r::math::SinRad(signedStepSize * (i + 1)), 0.0f, + 0.5f * nw4r::math::CosRad(signedStepSize * (i + 1)) + ); + + PSMTXMultVec(mtx, v4, v4); + PSMTXMultVec(mtx, v5, v5); + + nw4r::math::VEC3Sub(&v4, &v4, &v2); + nw4r::math::VEC3Sub(&v5, &v5, &v2); + + nw4r::math::VEC3 v6; + PSVECCrossProduct(v5, v4, v6); + PSVECNormalize(v6, v6); + + GXPosition3f32(v6.x, v6.y, v6.z); + } +} + +} // namespace + +namespace EGG { + +static DrawGX sDrawGX; + +static u8 DummyTextureData[64] = { + // clang-format off +0x00, 0xFF, 0x00, 0xFF, +0x00, 0xFF, 0x00, 0xFF, +0x00, 0xFF, 0x00, 0xFF, +0x00, 0xFF, 0x00, 0xFF, +0x00, 0xFF, 0x00, 0xFF, +0x00, 0xFF, 0x00, 0xFF, +0x00, 0xFF, 0x00, 0xFF, +0x00, 0xFF, 0x00, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, + // clang-format on +}; + +void DrawGX::Initialize(Heap *pHeap_) { + 2.0f; // cool + Heap *pHeap = pHeap_ == nullptr ? Heap::getCurrentHeap() : pHeap_; + + GXInitTexObj(&sDummyTexObj, DummyTextureData, 4, 4, GX_TF_Z24X8, GX_REPEAT, GX_REPEAT, false); + GXInitTexObjLOD(&sDummyTexObj, GX_NEAR, GX_NEAR, 0.0, 0.0, 0.0, 0, 0, GX_ANISO_1); + PSMTXIdentity(s_cameraMtx.m); + CreateDisplayList(pHeap); +} + +GXTexMapID DrawGX::GetTexMapDefault() { + return sTexMapDefault; +} +GXLightID DrawGX::GetLightMaskDefault() { + return sLightMaskDefault; +} + +void DrawGX::BeginDrawLine(ColorChannel chan, ZMode zMode) { + SetMat_ColorChannel(chan); + SetMat_TexGen(TEXGEN_0); + SetMat_Ind(); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetNumTevStages(1); + SetMat_Tev(GX_TEVSTAGE0, TEV_0); + SetMat_PE(zMode, BLEND_0); + SetVtxState(VTX_TYPE_1); +} + +void DrawGX::BeginDrawCircleZ(ColorChannel chan, ZMode zMode) { + SetMat_ColorChannel(chan); + SetMat_TexGen(TEXGEN_0); + SetMat_Ind(); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetNumTevStages(1); + SetMat_Tev(GX_TEVSTAGE0, TEV_0); + SetMat_PE(zMode, BLEND_0); + SetVtxState(VTX_TYPE_4); +} + +void DrawGX::BeginDrawQuad(ColorChannel chan, ZMode zMode, Blend blendMode, bool b1, bool b2) { + SetMat_ColorChannel(chan); + SetMat_TexGen(b1 ? TEXGEN_1 : TEXGEN_0); + SetMat_Ind(); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetNumTevStages(1); + SetMat_Tev(GX_TEVSTAGE0, b1 ? TEV_2 : TEV_0); + if (b2) { + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA); + } + SetMat_PE(zMode, blendMode); + SetVtxState(b1 ? VTX_TYPE_7 : VTX_TYPE_8); +} + +static const DrawGX::VtxType sVtxTypes[2][2] = { + {DrawGX::VTX_TYPE_10, DrawGX::VTX_TYPE_12}, + {DrawGX::VTX_TYPE_11, DrawGX::VTX_TYPE_13}, +}; + +void DrawGX::BeginDrawScreen(bool b1, bool b2, bool b3) { + SetMat_ColorChannel(COLORCHAN_1); + SetMat_TexGen(b2 ? TEXGEN_1 : TEXGEN_0); + SetMat_Ind(); + GXSetNumTevStages(1); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + SetMat_Tev(GX_TEVSTAGE0, b2 ? TEV_2 : TEV_0); + if (b3) { + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA); + } + SetMat_PE(ZMODE_0, BLEND_0); + SetVtxState(sVtxTypes[b1 ? 1 : 0][b2 ? 0 : 1]); +} + +void DrawGX::DrawLine(const EGG::Vector3f *pPoints, u16 numPoints, GXColor color, u8 thickness) { + GXLoadPosMtxImm(s_cameraMtx.m, 0); + GXSetChanMatColor(GX_COLOR0A0, color); + GXSetLineWidth(thickness, 0); + GXBegin(GX_LINES, GX_VTXFMT0, numPoints); + for (int i = 0; i < numPoints; i++) { + GXPosition3f32(pPoints[i].x, pPoints[i].y, pPoints[i].z); + } +} + +void DrawGX::DrawLineStrip(const EGG::Vector3f *pPoints, u16 numPoints, GXColor color, u8 thickness) { + GXLoadPosMtxImm(s_cameraMtx.m, 0); + GXSetChanMatColor(GX_COLOR0A0, color); + GXSetLineWidth(thickness, 0); + GXBegin(GX_LINESTRIP, GX_VTXFMT0, numPoints); + for (int i = 0; i < numPoints; i++) { + GXPosition3f32(pPoints[i].x, pPoints[i].y, pPoints[i].z); + } +} + +void DrawGX::ClearEfb( + const nw4r::math::MTX34 &mat, bool bColorUpdate, bool bAlphaUpdate, bool b3, GXColor clr, bool b4 +) { + StateGX::ScopedColor colorUpdate(bColorUpdate); + StateGX::ScopedAlpha alphaUpdate(bAlphaUpdate); + SetMat_ColorChannel(COLORCHAN_1); + GXSetCullMode(GX_CULL_NONE); + if (b3) { + SetMat_TexGen(TEXGEN_1); + GXLoadTexObj(&sDummyTexObj, sTexMapDefault); + } else { + SetMat_TexGen(TEXGEN_0); + } + + SetMat_Ind(); + GXSetNumTevStages(1); + GXSetTevDirect(GX_TEVSTAGE0); + GXSetTevColor(GX_TEVREG0, clr); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + if (b3) { + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, sTexMapDefault, GX_COLOR_NULL); + } else { + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + } + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_C0); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); + SetBlendMode(BLEND_14); + if (b3) { + GXSetZTexture(2, GX_TF_Z24X8, 0); + SetZMode(ZMODE_3); + GXSetZCompLoc(0); + SetVtxState(b4 ? VTX_TYPE_11 : VTX_TYPE_10); + GXLoadPosMtxImm(mat, 0); + GXCallDisplayList(s_DL[DL_16].mpList, s_DL[DL_16].mLen); + GXSetZTexture(0, GX_TF_Z24X8, 0); + GXSetZCompLoc(1); + } else { + SetZMode(ZMODE_0); + SetVtxState(b4 ? VTX_TYPE_13 : VTX_TYPE_12); + GXLoadPosMtxImm(mat, 0); + GXCallDisplayList(s_DL[DL_17].mpList, s_DL[DL_17].mLen); + } +} + +void DrawGX::ResetMaterial(enum ColorChannel chan) { + SetMat_ColorChannel(chan); + SetMat_TexGen(TEXGEN_0); + SetMat_Ind(); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetNumTevStages(1); + SetMat_Tev(GX_TEVSTAGE0, TEV_0); + SetMat_PE(ZMODE_1, BLEND_0); +} + +void DrawGX::SetMat_ColorChannel(enum ColorChannel chan) { + switch (chan) { + case COLORCHAN_0: + GXSetNumChans(1); + GXSetCullMode(GX_CULL_BACK); + GXSetChanCtrl(GX_COLOR0A0, true, GX_SRC_REG, GX_SRC_REG, GetLightMaskDefault(), GX_DF_CLAMP, GX_AF_SPOT); + GXSetChanCtrl(GX_COLOR1A1, false, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + break; + case COLORCHAN_1: + GXSetNumChans(1); + GXSetCullMode(GX_CULL_BACK); + GXSetChanCtrl(GX_COLOR0A0, false, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_SPOT); + GXSetChanCtrl(GX_COLOR1A1, false, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + break; + } +} + +void DrawGX::SetMat_TexGen(enum TexGen texGen) { + switch (texGen) { + case TEXGEN_0: + GXSetNumTexGens(0); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, 0, 0x7d); + break; + case TEXGEN_1: + GXSetNumTexGens(1); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, 0, 0x7d); + break; + } +} + +void DrawGX::SetMat_Ind() { + GXSetNumIndStages(0); +} + +void DrawGX::SetMat_Tev(GXTevStageID stageId, enum TevSetting setting) { + switch (setting) { + case TEV_0: + GXSetTevDirect(stageId); + GXSetTevOrder(stageId, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevSwapMode(stageId, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevColorIn(stageId, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC); + GXSetTevColorOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(stageId, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA); + GXSetTevAlphaOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + break; + case TEV_2: + GXSetTevDirect(stageId); + GXSetTevOrder(stageId, GX_TEXCOORD0, sTexMapDefault, GX_COLOR0A0); + GXSetTevSwapMode(stageId, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevColorIn(stageId, GX_CC_ZERO, GX_CC_TEXC, GX_CC_RASC, GX_CC_ZERO); + GXSetTevColorOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(stageId, GX_CA_ZERO, GX_CA_TEXA, GX_CA_RASA, GX_CA_ZERO); + GXSetTevAlphaOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + break; + case TEV_1: + GXSetTevDirect(stageId); + GXSetTevOrder(stageId, GX_TEXCOORD0, sTexMapDefault, GX_COLOR0A0); + GXSetTevSwapMode(stageId, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevColorIn(stageId, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + GXSetTevColorOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(stageId, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + GXSetTevAlphaOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + break; + } +} + +void DrawGX::SetMat_PE(enum ZMode zMode, enum Blend blendMode) { + GXSetZCompLoc(true); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); + SetZMode(zMode); + SetBlendMode(blendMode); +} + +void DrawGX::LoadTexture(const EGG::ResTIMG *tex, GXTexMapID texMapId) { + GXTexObj obj; + GXUtility::getTexObj(&obj, *tex); + GXLoadTexObj(&obj, texMapId); +} + +void DrawGX::LoadTexture(nw4r::g3d::ResTex tex, GXTexMapID texMapId) { + GXTexObj obj; + GXUtility::getTexObj(&obj, tex, GX_CLAMP, GX_CLAMP, GX_LINEAR, GX_LINEAR); + GXLoadTexObj(&obj, texMapId); +} + +void DrawGX::SetVtxState(EGG::DrawGX::VtxType type) { + GXClearVtxDesc(); + switch (type) { + case VTX_TYPE_0: + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0xe); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_S16, 0xe); + // clang-format off + static const ALIGN_DECL(32) s16 sVtxDataType0[][3] = { + {0xE000, 0x2000, 0xE000}, + {0xE000, 0x2000, 0x2000}, + {0x2000, 0x2000, 0x2000}, + {0x2000, 0x2000, 0xE000}, + {0xE000, 0xE000, 0xE000}, + {0xE000, 0xE000, 0x2000}, + {0x2000, 0xE000, 0x2000}, + {0x2000, 0xE000, 0xE000}, + }; + static const ALIGN_DECL(32) s16 sNrmDataType0[][3] = { + {0xC000, 0x0000, 0x0000}, + {0x4000, 0x0000, 0x0000}, + {0x0000, 0xC000, 0x0000}, + {0x0000, 0x4000, 0x0000}, + {0x0000, 0x0000, 0xC000}, + {0x0000, 0x0000, 0x4000}, + }; + // clang-format on + GXSetArray(GX_VA_POS, sVtxDataType0, 6); + GXSetArray(GX_VA_NRM, sNrmDataType0, 6); + GXSetVtxDesc(GX_VA_POS, GX_INDEX8); + GXSetVtxDesc(GX_VA_NRM, GX_INDEX8); + break; + case VTX_TYPE_2: + case VTX_TYPE_3: + case VTX_TYPE_4: + case VTX_TYPE_5: + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_NRM, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0); + break; + case VTX_TYPE_6: + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_NRM, GX_DIRECT); + GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + break; + case VTX_TYPE_1: + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + break; + case VTX_TYPE_7: + case VTX_TYPE_8: + // clang-format off + static const ALIGN_DECL(32) s16 sVtxDataType7[][2] = { + {0xE000, 0x2000}, + {0x2000, 0x2000}, + {0x2000, 0xE000}, + {0xE000, 0xE000}, + }; + static const ALIGN_DECL(32) s16 sNrmDataType7[][3] = { + {0x0000, 0x0000, 0x4000} + }; + static const ALIGN_DECL(32) u8 sTexDataType7[][2] = { + {0x00, 0x00}, + {0x01, 0x00}, + {0x01, 0x01}, + {0x00, 0x01}, + }; + // clang-format on + GXSetVtxDesc(GX_VA_POS, GX_INDEX8); + GXSetVtxDesc(GX_VA_NRM, GX_INDEX8); + if (type == VTX_TYPE_7) { + GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8); + } + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_S16, 0xe); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_S16, 0xe); + if (type == VTX_TYPE_7) { + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_U8, 0); + } + GXSetArray(GX_VA_POS, sVtxDataType7, 4); + GXSetArray(GX_VA_NRM, sNrmDataType7, 6); + if (type == VTX_TYPE_7) { + GXSetArray(GX_VA_TEX0, sTexDataType7, 2); + } + break; + case VTX_TYPE_9: + // clang-format off + static const ALIGN_DECL(32) s16 sVtxDataType9[][3] = { + {0xE000, 0x0000, 0xE000}, + {0x2000, 0x0000, 0xE000}, + {0x2000, 0x0000, 0x2000}, + {0xE000, 0x0000, 0x2000}, + }; + static const ALIGN_DECL(32) s16 sNrmDataType9[][3] = { + {0x0000, 0x4000, 0x0000} + }; + // clang-format on + GXSetVtxDesc(GX_VA_POS, GX_INDEX8); + GXSetVtxDesc(GX_VA_NRM, GX_INDEX8); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0xe); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_S16, 0xe); + GXSetArray(GX_VA_POS, sVtxDataType9, 6); + GXSetArray(GX_VA_NRM, sNrmDataType9, 6); + break; + case VTX_TYPE_10: + case VTX_TYPE_11: + case VTX_TYPE_12: + case VTX_TYPE_13: { + // clang-format off + static const ALIGN_DECL(32) u8 sPosDataType10[][2] = { + {0x00, 0x01}, + {0x01, 0x01}, + {0x01, 0x00}, + {0x00, 0x00}, + }; + static const ALIGN_DECL(32) u8 sTexDataType10[][2] = { + {0x00, 0x00}, + {0x01, 0x00}, + {0x01, 0x01}, + {0x00, 0x01}, + }; + // clang-format on + bool bVar1 = type == VTX_TYPE_11 || type == VTX_TYPE_13; + bool bVar2 = type == VTX_TYPE_10 || type == VTX_TYPE_11; + GXSetVtxDesc(GX_VA_POS, GX_INDEX8); + if (bVar2) { + GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8); + } + GXSetArray(GX_VA_POS, bVar1 ? sTexDataType10 : sPosDataType10, 2); + if (bVar2) { + GXSetArray(GX_VA_TEX0, sTexDataType10, 2); + } + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_U8, 0); + if (bVar2) { + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_U8, 0); + } + break; + } + } +} + +const u8 sDetailLevels[] = {0x10, 0x20}; + +void DrawGX::CreateDisplayList(EGG::Heap *pHeap) { + u8 ALIGN_DECL(32) tmpDisplayList[16 * 1024]; + + OSInitFastCast(); + + for (int i = 0; i < DL_MAX; i++) { + DCInvalidateRange(tmpDisplayList, sizeof(tmpDisplayList)); + GXBeginDisplayList(tmpDisplayList, sizeof(tmpDisplayList)); + switch (static_cast
(i)) { + case DL_0: + GXSetChanMatColor(GX_COLOR0A0, RED); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(0.0f, 0.0f, 0.0f); + GXPosition3f32(1.0f, 0.0f, 0.0f); + GXSetChanMatColor(GX_COLOR0A0, GREEN); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(0.0f, 0.0f, 0.0f); + GXPosition3f32(0.0f, 1.0f, 0.0f); + GXSetChanMatColor(GX_COLOR0A0, BLUE); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(0.0f, 0.0f, 0.0f); + GXPosition3f32(0.0f, 0.0f, 1.0f); + break; + case DL_1: + GXBegin(GX_QUADS, GX_VTXFMT0, 6 * 4); + DrawQuadNormal(1, 5, 4, 0, 0); + DrawQuadNormal(3, 7, 6, 2, 1); + DrawQuadNormal(5, 6, 7, 4, 2); + DrawQuadNormal(3, 2, 1, 0, 3); + DrawQuadNormal(0, 4, 7, 3, 4); + DrawQuadNormal(2, 6, 5, 1, 5); + break; + case DL_2: + DrawQuadLineStripNormal(1, 5, 4, 0, 0); + DrawQuadLineStripNormal(3, 7, 6, 2, 1); + DrawQuadLineStripNormal(5, 6, 7, 4, 2); + DrawQuadLineStripNormal(3, 2, 1, 0, 3); + break; + case DL_3: GXDrawSphere(4, 8); break; + case DL_4: GXDrawSphere(8, 16); break; + case DL_5: + case DL_6: { + u16 numSegments = sDetailLevels[i - DL_5] + 1; + f32 radPerSegment = 2.0f * M_PI / (numSegments - 1); + GXBegin(GX_LINESTRIP, GX_VTXFMT0, numSegments); + for (int i = 0; i < numSegments; i++) { + GXPosition3f32( + 0.5f * nw4r::math::CosRad(radPerSegment * i), 0.5f * nw4r::math::SinRad(radPerSegment * i), 0.0f + ); + } + break; + } + case DL_9: + case DL_10: { + u16 numSegments = sDetailLevels[i - DL_9] + 1; + f32 radPerSegment = 2.0f * M_PI / (numSegments - 1); + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, numSegments * 2); + for (int i = 0; i < numSegments; i++) { + f32 x = 0.5f * nw4r::math::SinRad(radPerSegment * i); + f32 z = 0.5f * nw4r::math::CosRad(radPerSegment * i); + GXPosition3f32(x, -0.5f, z); + GXPosition3f32(2.0f * x, 0.0f, 2.0f * z); + GXPosition3f32(x, 0.5f, z); + GXPosition3f32(2.0f * x, 0.0f, 2.0f * z); + } + nw4r::math::MTX34 mtx; + PSMTXTrans(mtx, 0.0f, 0.5f, 0.0f); + DrawCircleYPolygonFan(mtx, 0.0f, sDetailLevels[i - DL_9]); + + PSMTXIdentity(mtx); + PSMTXRotRad(mtx, M_PI, 0x7A); + PSMTXTransApply(mtx, mtx, 0.0f, -0.5f, 0.0f); + DrawCircleYPolygonFan(mtx, 0.0f, sDetailLevels[i - DL_9]); + break; + } + case DL_11: + case DL_12: { + nw4r::math::MTX34 mtx; + PSMTXIdentity(mtx); + DrawCircleYPolygonFan(mtx, 1.0f, sDetailLevels[i - DL_11]); + PSMTXRotRad(mtx, M_PI, 0x7A); + DrawCircleYPolygonFan(mtx, 0.0f, sDetailLevels[i - DL_11]); + break; + } + case DL_7: + case DL_8: { + nw4r::math::MTX34 mtx; + PSMTXIdentity(mtx); + PSMTXRotRad(mtx, M_PI / 2.0f, 0x78); + DrawCircleYPolygonFan(mtx, 0.0f, sDetailLevels[i - DL_7]); + break; + } + + case DL_13: + case DL_14: { + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition2u8(0, 0); + if (i == DL_13) { + GXPosition1x8(0); + } + GXPosition2u8(1, 0); + if (i == DL_13) { + GXPosition1x8(1); + } + GXPosition2u8(2, 0); + if (i == DL_13) { + GXPosition1x8(2); + } + GXPosition2u8(3, 0); + if (i == DL_13) { + GXPosition1x8(3); + } + break; + } + case DL_15: + GXBegin(GX_LINESTRIP, GX_VTXFMT0, 5); + GXPosition3f32(-0.5f, 0.5f, 0.0f); + GXPosition3f32(0.5f, 0.5f, 0.0f); + GXPosition3f32(0.5f, -0.5f, 0.0f); + GXPosition3f32(-0.5f, -0.5f, 0.0f); + GXPosition3f32(-0.5f, 0.5f, 0.0f); + break; + case DL_16: + case DL_17: + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition1x8(0); + if (i == DL_16) { + GXPosition1x8(0); + } + GXPosition1x8(1); + if (i == DL_16) { + GXPosition1x8(1); + } + GXPosition1x8(2); + if (i == DL_16) { + GXPosition1x8(2); + } + GXPosition1x8(3); + if (i == DL_16) { + GXPosition1x8(3); + } + break; + default: break; + } + + u32 size = GXEndDisplayList(); + s_DL[i].mLen = size; + u8 *data = new (pHeap, 0x20) u8[size]; + s_DL[i].mpList = data; + for (int j = 0; j < size; j++) { + data[j] = tmpDisplayList[j]; + } + DCFlushRange(data, size); + } + s_flag |= 1; +} + +void DrawGX::DrawDL(enum DL dl, const nw4r::math::MTX34 &mtx, GXColor clr) { + GXLoadPosMtxImm(mtx, 0); + GXLoadNrmMtxImm(mtx, 0); + GXSetChanMatColor(GX_COLOR0A0, clr); + GXCallDisplayList(s_DL[dl].mpList, s_DL[dl].mLen); +} + +const DrawGX::ZModeConfig DrawGX::s_ZMode[ZMODE_MAX] = { + {false, GX_ALWAYS, false}, + { true, GX_LEQUAL, true}, + { true, GX_LEQUAL, false}, + { true, GX_ALWAYS, true}, +}; + +void DrawGX::SetZMode(enum ZMode mode) { + GXSetZMode(s_ZMode[mode].mTest, s_ZMode[mode].mCompare, s_ZMode[mode].mUpdate); +} + +const DrawGX::BlendModeConfig DrawGX::s_Blend[BLEND_MAX] = { + { GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR}, + { GX_BM_BLEND, GX_BL_INVSRCALPHA, GX_BL_SRCALPHA, GX_LO_CLEAR}, + { GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR}, + { GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_CLEAR}, + { GX_BM_BLEND, GX_BL_SRCCLR, GX_BL_ONE, GX_LO_CLEAR}, + { GX_BM_BLEND, GX_BL_INVSRCCLR, GX_BL_ONE, GX_LO_CLEAR}, + {GX_BM_SUBTRACT, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR}, + { GX_BM_BLEND, GX_BL_ZERO, GX_BL_SRCCLR, GX_LO_CLEAR}, + { GX_BM_BLEND, GX_BL_ZERO, GX_BL_INVSRCCLR, GX_LO_CLEAR}, + { GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR}, + { GX_BM_BLEND, GX_BL_DSTALPHA, GX_BL_INVDSTALPHA, GX_LO_CLEAR}, + { GX_BM_BLEND, GX_BL_INVDSTALPHA, GX_BL_DSTALPHA, GX_LO_CLEAR}, + { GX_BM_BLEND, GX_BL_DSTALPHA, GX_BL_ONE, GX_LO_CLEAR}, + { GX_BM_BLEND, GX_BL_INVDSTALPHA, GX_BL_ONE, GX_LO_CLEAR}, + { GX_BM_NONE, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR}, +}; + +void DrawGX::SetBlendMode(enum Blend mode) { + GXSetBlendMode( + s_Blend[mode].mBlendMode, s_Blend[mode].mBlendFactorSrc, s_Blend[mode].mBlendFactorDst, s_Blend[mode].mLogicOp + ); +} + +void DrawGX::DrawDLWorld(DL dl, const EGG::Matrix34f &mtx, GXColor color) { + nw4r::math::MTX34 resMtx; + + PSMTXConcat(s_cameraMtx.m, mtx.m, resMtx.m); + DrawDL(dl, resMtx, color); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggDrawPathBase.cpp b/src/egg/gfx/eggDrawPathBase.cpp index e59be480..3a98067f 100644 --- a/src/egg/gfx/eggDrawPathBase.cpp +++ b/src/egg/gfx/eggDrawPathBase.cpp @@ -1,3 +1,44 @@ #include "egg/gfx/eggDrawPathBase.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggIScnProc.h" +#include "nw4r/g3d/g3d_scnobj.h" +#include "nw4r/g3d/g3d_scnproc.h" + +namespace EGG { + +DrawPathBase::DrawPathBase() {} + +void DrawPathBase::createScnProc(MEMAllocator *allocator) { + IScnProc::createScnProc(getNumStep(), allocator); + for (u16 i = 0; i < getNumStep(); i++) { + getProc(i)->SetScnObjOption(nw4r::g3d::ScnObj::OPTION_DISABLE_UPDATEFRAME, true); + getProc(i)->SetScnObjOption(nw4r::g3d::ScnObj::OPTION_DISABLE_CALC_WORLD, true); + getProc(i)->SetScnObjOption(nw4r::g3d::ScnObj::OPTION_DISABLE_CALC_MAT, true); + getProc(i)->SetScnObjOption(nw4r::g3d::ScnObj::OPTION_DISABLE_CALC_VTX, true); + getProc(i)->SetScnObjOption(nw4r::g3d::ScnObj::OPTION_DISABLE_CALC_VIEW, true); + } + nw4r::g3d::ScnProc *p = getProc(0); + p->SetScnObjOption(nw4r::g3d::ScnObj::OPTION_DISABLE_CALC_VIEW, false); + p->EnableScnObjCallbackExecOp(nw4r::g3d::ScnObj::EXECOP_CALC_VIEW); + p->EnableScnObjCallbackTiming(nw4r::g3d::ScnObj::CALLBACK_TIMING_A); + p->DisableScnObjCallbackTiming(nw4r::g3d::ScnObj::CALLBACK_TIMING_B); + p->DisableScnObjCallbackTiming(nw4r::g3d::ScnObj::CALLBACK_TIMING_C); + p->SetCallback(this); +} + +void DrawPathBase::ExecCallback_CALC_VIEW( + nw4r::g3d::ScnObj::Timing timing, nw4r::g3d::ScnObj *pObj, u32 param, void *pInfo +) { + if (mFlag & 1) { + internalResetForDraw(); + } +} + +void DrawPathBase::scnProcDraw(u16 idx) { + if (mFlag & 1) { + internalDraw(idx); + } +} + +} // namespace EGG diff --git a/src/egg/gfx/eggDrawPathBloom.cpp b/src/egg/gfx/eggDrawPathBloom.cpp new file mode 100644 index 00000000..844af420 --- /dev/null +++ b/src/egg/gfx/eggDrawPathBloom.cpp @@ -0,0 +1,59 @@ +#include "egg/gfx/eggDrawPathBloom.h" +#include "egg/gfx/eggDrawGX.h" + +namespace EGG { + +DrawPathBloom::DrawPathBloom(): field_0x01C(1), field_0x01D(8), field_0x37C(0) { + Data nullDat = {0}; + field_0x380 = nullDat; + + mSimple.setField0x38(0); + field_0x380.field_0x00 = 0.5f; + field_0x380.field_0x04 = DrawGX::WHITE; + field_0x380.field_0x08 = DrawGX::WHITE; + field_0x380.field_0x0C = 0x21; + + field_0x380.field_0x10[0].field_0x00 = 1.0f; + field_0x380.field_0x10[0].field_0x04 = 0.3f; + field_0x380.field_0x10[0].field_0x08 = 0x15; + + field_0x380.field_0x10[1].field_0x00 = 2.0f; + field_0x380.field_0x10[1].field_0x04 = 0.08f; + field_0x380.field_0x10[1].field_0x08 = 0x15; + + field_0x380.field_0x10[2].field_0x00 = 4.0f; + field_0x380.field_0x10[2].field_0x04 = 0.04f; + field_0x380.field_0x10[2].field_0x08 = 0x15; + + field_0x380.field_0x51 = 2; + field_0x380.field_0x50 = 1; + + field_0x380.field_0x70 = 0.0f; + field_0x380.field_0x6C = 0.0f; + + field_0x380.field_0x52 = 0x15; +} + +DrawPathBloom::~DrawPathBloom() {} + +void DrawPathBloom::internalResetForDraw() { + // TODO +} + +void DrawPathBloom::internalDraw(u16 idx) { + // TODO +} + +void DrawPathBloom::SetBinaryInner(const Bin &bin) { + // TODO +} + +void DrawPathBloom::GetBinaryInner(Bin *pBin) const { + // TODO +} + +void DrawPathBloom::SetBinaryInner(const Bin &, const Bin &, f32) { + // TODO +} + +} // namespace EGG diff --git a/src/egg/gfx/eggDrawPathDOF.cpp b/src/egg/gfx/eggDrawPathDOF.cpp index 8f611cde..b51b64cd 100644 --- a/src/egg/gfx/eggDrawPathDOF.cpp +++ b/src/egg/gfx/eggDrawPathDOF.cpp @@ -1,3 +1,231 @@ #include "egg/gfx/eggDrawPathDOF.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggGlobalDrawState.h" +#include "egg/gfx/eggPostEffectBase.h" +#include "egg/gfx/eggPostEffectBlur.h" +#include "egg/gfx/eggPostEffectMask.h" +#include "egg/gfx/eggPostEffectMaskDOF.h" +#include "egg/gfx/eggPostEffectSimple.h" +#include "egg/gfx/eggScreen.h" +#include "egg/gfx/eggStateEfb.h" +#include "egg/gfx/eggStateGX.h" +#include "egg/gfx/eggTextureBuffer.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +DrawPathDOF::DrawPathDOF() + : field_0x1C(1), + field_0x20(1), + field_0x24(30.0f), + field_0x28(20.0f), + field_0x2C(20.0f), + field_0x30(1.6f), + field_0x34(0), + field_0x38(2), + field_0x5C(0.0f), + field_0x60(0.0f), + field_0x64(0.4f), + field_0x68(0.2f), + field_0x6C(-0.0075f), + field_0x70(-0.0075f), + field_0x74(10.0f), + field_0x78(15.0f), + field_0x7C(1.0f), + field_0x80(21), + mpBlur(nullptr), + mpMask(nullptr), + mpTextureBuffer(nullptr), + mpMaskDof(nullptr) { + mpMaskDof = new PostEffectMaskDOF(); + mpBlur = new PostEffectBlur(); + mpBlur->setField0x2C(1); + mpMask = new PostEffectMask(); + + mpMask->setField_0x00(0); + mpMask->setField_0x34(0.0f); + mpMask->setField_0x2C(0); + field_0x1E = 0xFF; + field_0x1F = 0xFF; +} + +DrawPathDOF::~DrawPathDOF() { + delete mpMaskDof; + mpMaskDof = nullptr; + delete mpBlur; + mpBlur = nullptr; + delete mpMask; + mpMask = nullptr; +} + +void DrawPathDOF::execute() { + field_0x5C += field_0x6C * field_0x7C; + field_0x60 += field_0x70 * field_0x7C; + + if (field_0x5C < -1.0f) { + field_0x5C += 2.0f; + } else if (field_0x5C > 1.0f) { + // @bug typo? + field_0x5C -= -2.0f; + } + + if (field_0x60 < -1.0f) { + field_0x60 += 2.0f; + } else if (field_0x60 > 1.0f) { + field_0x60 -= 2.0f; + } +} + +static int sMaskDofArray[] = {0, 1, 2}; +static u8 sBlurArray[] = {4, 2, 1, 0}; + +void DrawPathDOF::internalResetForDraw() { + // Tons of regswaps... + f32 a = GlobalDrawState::getScreen().TranslateDepthToViewSpace(field_0x24); + f32 b = GlobalDrawState::getScreen().TranslateDepthToViewSpace(field_0x24 - field_0x28 / 2.0f); + f32 c = GlobalDrawState::getScreen().TranslateDepthToViewSpace(field_0x24 + field_0x28 / 2.0f); + + // TODO + if (c < b + 1e-6f) { + c = b + 1e-6f; + + if (b < 1.0f) { + c = 1.0f; + b -= 1e-6f; + } + } + mpMaskDof->setParam0x48(b); + mpMaskDof->setParam0x44(a); + mpMaskDof->setParam0x4C(c); + + if (field_0x38 >= 3) { + field_0x38 = 2; + } + + mpMaskDof->setCpuTexArrIdx(sMaskDofArray[field_0x38]); + mpBlur->setStage0Field0(sBlurArray[field_0x34]); + mpBlur->setStage0F(field_0x34 != 2 ? field_0x30 : 0.0f); + // HELP + mpBlur->setStage0ColorThing(field_0x1E); +} + +void DrawPathDOF::internalDraw(u16 idx) { + if (idx == 0) { + if (StateEfb::CheckFlag0x2() == 0) { + StateEfb::fn_804B4270( + static_cast((field_0x1C >> 2) & 1), reinterpret_cast(this) + ); + } + StateGX::invalidateTexAllGX(); + } + + if (field_0x20 == 2) { + internalDrawVariant2(idx); + } else { + internalDrawVariant01(idx); + } + + switch (idx) { + case 1: + StateEfb::fn_804B4310(StateEfb::BUFFER_0, reinterpret_cast(this)); + StateEfb::releaseEfb(StateEfb::BUFFER_3, reinterpret_cast(this)); + break; + case 2: + if (mpTextureBuffer != nullptr) { + mpTextureBuffer->free(); + mpTextureBuffer = nullptr; + } + } +} + +void DrawPathDOF::internalDrawVariant01(u16 idx) {} + +void DrawPathDOF::internalDrawVariant2(u16 idx) { + const Screen &screen = GlobalDrawState::getScreen(); + const Screen::DataEfb &efb = screen.GetDataEfb(); + switch (idx) { + case 0: { + TextureBuffer *capturedBuf = StateEfb::captureEfb(StateEfb::BUFFER_3, false, reinterpret_cast(this)); + StateGX::GXSetPixelFmt_(GX_PF_RGB8_Z24, GX_ZC_LINEAR); + StateGX::ScopedColor colorGuard(true); + StateGX::ScopedAlpha alphaGuard(false); + StateGX::ScopedDither ditherGuard(false); + PostEffectBase::setProjection(screen); + f32 *floats = StateEfb::fn_804B4550(); + f32 scale = (field_0x1C & 4) != 0 ? 0.25f : 0.5f; + f32 width1 = screen.GetWidth() * scale; + f32 height1 = screen.GetHeight() * scale; + + f32 rot = 0.5f; + + u16 width = efb.vp.x2 * scale; + u16 height = efb.vp.y2 * scale; + + PostEffectSimple effect; + effect.setCapTexMapId(GX_TEXMAP0); + effect.setField0x38(0); + effect.setField_0x00(0); + effect.setRot(rot); + + effect.setCapTexture(capturedBuf); + // TODO tons of problems in these UnscaleByX inlines that probably exist + effect.draw(screen.UnscaleByX(height), screen.UnscaleByY(width)); + TextureBuffer *pTex2 = TextureBuffer::alloc(height, width, GX_TF_RGBA8); + pTex2->fn_8049D9D0(field_0x80); + pTex2->capture(floats[0], floats[1], false, -1); + mpBlur->setCapTexture(pTex2); + mpBlur->setCapTexMapId(GX_TEXMAP0); + mpBlur->setRot(-rot); + mpBlur->draw(width1, height1); + + if (pTex2 != nullptr) { + pTex2->free(); + } + afterDraw(floats[0], floats[1], width, height); + StateGX::GXSetPixelFmt_(StateGX::s_pixFormat, StateGX::s_zFmt16); + break; + } + case 2: { + StateGX::ScopedColor colorGuard(true); + StateGX::ScopedAlpha alphaGuard(false); + StateGX::ScopedDither ditherGuard(true); + + Screen screenCpy(screen); + screenCpy.SetOffset(nw4r::math::VEC2(0.0f, 0.0f)); + screenCpy.SetScale(nw4r::math::VEC3(1.0f, 1.0f, 1.0f)); + screenCpy.SetFlag(Screen::FLAG_0x40); + screenCpy.SetProjectionGX(); + DrawGX::SetMat_ColorChannel(DrawGX::COLORCHAN_1); + DrawGX::SetMat_TexGen(DrawGX::TEXGEN_1); + DrawGX::SetMat_Ind(); + DrawGX::SetMat_Tev(GX_TEVSTAGE0, DrawGX::TEV_2); + GXSetTevAlphaIn(GX_TEVSTAGE0,GX_CA_ZERO,GX_CA_ZERO,GX_CA_ZERO,GX_CA_RASA); + DrawGX::SetMat_PE(DrawGX::ZMODE_2, DrawGX::BLEND_0); + DrawGX::SetVtxState(DrawGX::VTX_TYPE_7); + mpTextureBuffer->load(GX_TEXMAP0); + + for (int i = 0; i < 2; i++) { + // TODO + } + + break; + } + } +} + +void DrawPathDOF::SetBinaryInner(const Bin &bin) { + // TODO +} + +void DrawPathDOF::GetBinaryInner(Bin *pBin) const { + // TODO +} + +void DrawPathDOF::SetBinaryInner(const Bin &, const Bin &, f32) { + // TODO +} + +} // namespace EGG diff --git a/src/egg/gfx/eggDrawPathLightMap.cpp b/src/egg/gfx/eggDrawPathLightMap.cpp new file mode 100644 index 00000000..21a0ad6c --- /dev/null +++ b/src/egg/gfx/eggDrawPathLightMap.cpp @@ -0,0 +1,194 @@ +#include "egg/gfx/eggDrawPathLightMap.h" + +#include "common.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggGlobalDrawState.h" +#include "egg/gfx/eggPostEffectBase.h" +#include "egg/gfx/eggStateGX.h" +#include "rvl/GX/GXPixel.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +DrawPathLightMap::DrawPathLightMap() + : field_0x18(6), + mAlpha(0xFF), + field_0x1C(0), + field_0x20(0), + field_0x24(0), + mpTextureBuffer_0x28(nullptr), + mpTextureBuffer_0x2C(nullptr), + mpTextureBuffer_0x30(nullptr), + mOldDrawFlag(0) {} + +void DrawPathLightMap::internalResetForDraw() { + freeTextureBuffers(); + mpTextureBuffer_0x28 = nullptr; + mpTextureBuffer_0x2C = nullptr; + mpTextureBuffer_0x30 = nullptr; +} + +void DrawPathLightMap::internalDraw(u16 idx) { + const Screen::DataEfb &efb = GlobalDrawState::getScreen().GetDataEfb(); + + switch (idx) { + case 0: { + if (field_0x18 & 1) { + mpTextureBuffer_0x30 = TextureBuffer::alloc(efb.vp.x2, efb.vp.y2, GX_TF_RGBA8); + mpTextureBuffer_0x30->onCapFlag(1); + mpTextureBuffer_0x30->onCapFlag(2); + mpTextureBuffer_0x30->setFilt(GX_NEAR, GX_NEAR); + mpTextureBuffer_0x30->capture(efb.vp.x1, efb.vp.y1, false, -1); + } + mOldDrawFlag = GlobalDrawState::getDrawFlag(); + GlobalDrawState::onDrawFlag(0x1 | 0x2); + } break; + case 1: { + GlobalDrawState::setDrawFlag(mOldDrawFlag); + GXTexFmt fmt = GX_TF_RGBA8; + + if (field_0x20 == 1) { + fmt = GX_TF_RGB5A3; + if (field_0x1C == 1) { + fmt = GX_TF_RGB565; + } + } + + int capW = efb.vp.x1; + int capH = efb.vp.y1; + + mpTextureBuffer_0x28 = TextureBuffer::alloc(efb.vp.x2, efb.vp.y2, fmt); + + mpTextureBuffer_0x28->onCapFlag(1); + mpTextureBuffer_0x28->onCapFlag(2); + if (!(field_0x18 & 2)) { + mpTextureBuffer_0x28->onCapFlag(4); + } + mpTextureBuffer_0x28->setClearColor(StateGX::getClearEfb()); + + mpTextureBuffer_0x28->capture(capW, capH, false, -1); + mpTextureBuffer_0x28->setFilt(GX_NEAR, GX_NEAR); + + if (mpTextureBuffer_0x30) { + nw4r::math::MTX34 forDL; + + StateGX::ScopedColor _color(true); + StateGX::ScopedAlpha _alpha(true); + StateGX::ScopedDither _dither(false); + + PostEffectBase::setProjection(GetScreen()); + + PSMTXScale(forDL, GetScreen().GetWidth(), GetScreen().GetHeight(), 1.0f); + + mpTextureBuffer_0x30->load(GX_TEXMAP0); + DrawGX::BeginDrawScreen(true, true, false); + + DrawGX::SetBlendMode(DrawGX::BLEND_14); + + DrawGX::DrawDL16(forDL, DrawGX::WHITE); + + mpTextureBuffer_0x30->free(); + mpTextureBuffer_0x30 = nullptr; + } + + if (field_0x18 & 2) { + mpTextureBuffer_0x2C = TextureBuffer::alloc(efb.vp.x2, efb.vp.y2, GX_TF_Z24X8); + mpTextureBuffer_0x2C->onCapFlag(4); + + if (isFlag0x2()) { + mpTextureBuffer_0x2C->onCapFlag(0x10); + } else { + mpTextureBuffer_0x2C->offCapFlag(0x10); + } + + mpTextureBuffer_0x2C->capture(capW, capH, false, -1); + mpTextureBuffer_0x2C->setFilt(GX_NEAR, GX_NEAR); + } + StateGX::invalidateTexAllGX(); + } break; + case 2: { + if (mpTextureBuffer_0x28) { + if (mAlpha != 0) { + mpTextureBuffer_0x28->load(GX_TEXMAP0); + + nw4r::math::MTX34 forDL; + PostEffectBase::setProjection(GetScreen()); + PSMTXScale(forDL, GetScreen().GetWidth(), GetScreen().GetHeight(), 1.0f); + + GXColor tevColor = {0xFF, 0xFF, 0xFF, mAlpha}; + + StateGX::ScopedColor _color(true); + StateGX::ScopedAlpha _alpha(false); + StateGX::ScopedDither _dither(true); + + if (mpTextureBuffer_0x2C) { + mpTextureBuffer_0x2C->load(GX_TEXMAP1); + DrawGX::SetMat_ColorChannel(DrawGX::COLORCHAN_1); + DrawGX::SetMat_TexGen(DrawGX::TEXGEN_1); + DrawGX::SetMat_Ind(); + GXSetTevKColor(GX_KCOLOR0, (GXColor){0}); + + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetNumTevStages(2); + GXSetTevDirect(GX_TEVSTAGE0); + GXSetTevDirect(GX_TEVSTAGE1); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0); + + if (field_0x1C == 0) { + GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_RASC, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_TEXA, GX_CA_KONST, GX_CA_RASA, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_COMP_A8_GT, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + } else { + GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + } + + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, GX_TEXMAP1, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_CPREV); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetZTexture(GZ_ZT_REPLACE, GX_TF_Z24X8, 0); + + GXSetZMode(true, field_0x1C == 0 ? GX_LEQUAL : GX_LESS, field_0x18 & 0x4 ? true : false); + GXSetZCompLoc(0); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); + DrawGX::SetBlendMode(DrawGX::BLEND_0); + DrawGX::SetVtxState(DrawGX::VTX_TYPE_11); + } else { + DrawGX::BeginDrawScreen(true, true, false); + GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_TEXA, GX_CA_ZERO, GX_CA_RASA, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_COMP_A8_GT, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + } + + DrawGX::DrawDL16(forDL, tevColor); + GXSetZTexture(GX_ZT_DISABLE, GX_TF_Z24X8, 0); + } + freeTextureBuffers(); + } + } break; + } +} + +void DrawPathLightMap::freeTextureBuffers() { + if (mpTextureBuffer_0x2C) { + mpTextureBuffer_0x2C->free(); + mpTextureBuffer_0x2C = nullptr; + } + if (mpTextureBuffer_0x28) { + mpTextureBuffer_0x28->free(); + mpTextureBuffer_0x28 = nullptr; + } +} + +} // namespace EGG diff --git a/src/egg/gfx/eggDrawPathUnk1.cpp b/src/egg/gfx/eggDrawPathUnk1.cpp deleted file mode 100644 index 2a89d9da..00000000 --- a/src/egg/gfx/eggDrawPathUnk1.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "egg/gfx/eggDrawPathUnk1.h" - -namespace EGG {} // namespace EGG diff --git a/src/egg/gfx/eggDrawPathUnk2.cpp b/src/egg/gfx/eggDrawPathUnk2.cpp deleted file mode 100644 index eb4f9c5d..00000000 --- a/src/egg/gfx/eggDrawPathUnk2.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "egg/gfx/eggDrawPathUnk2.h" - -namespace EGG {} // namespace EGG diff --git a/src/egg/gfx/eggFog.cpp b/src/egg/gfx/eggFog.cpp index 71bf0b8c..cc66c567 100644 --- a/src/egg/gfx/eggFog.cpp +++ b/src/egg/gfx/eggFog.cpp @@ -1,3 +1,70 @@ #include "egg/gfx/eggFog.h" -namespace EGG {} // namespace EGG +#include "egg/egg_types.h" +#include "egg/gfx/eggDrawGX.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +template <> +const char *IBinary::GetBinaryType() { + return "FOGD"; +} + +template <> +int IBinary::GetVersion() { + return 0; +} + +Fog::Fog() { + Reset(); +} + +void Fog::Reset() { + // TODO + mColor = DrawGX::WHITE; + mFarZ = 0.0f; + mNearZ = 0.0f; + mEndZ = 0.0f; + mStartZ = 0.0f; + mFogType = GX_FOG_NONE; + mFlags = 0; +} + +void Fog::CopyToG3D(nw4r::g3d::Fog fog) const { + fog.SetFogType((mFlags & 1) ? mFogType : GX_FOG_NONE); + fog.SetZ(mStartZ, mEndZ); + fog.SetFogColor(mColor); + fog.SetFogRangeAdjEnable(mFlags & 2); +} + +void Fog::SetBinaryInner(const Bin &bin) { + if (bin.mHeader.mVersion != 0) { + return; + } + mStartZ = bin.mData.mStartZ; + mEndZ = bin.mData.mEndZ; + mNearZ = bin.mData.mNearZ; + mFarZ = bin.mData.mFarZ; + mColor = bin.mData.mColor; + mFogType = (GXFogType)bin.mData.field_0x24; + mFlags = bin.mData.mFlag2; +} + +void Fog::GetBinaryInner(Bin *pBin) const { + pBin->mData.mStartZ = mStartZ; + pBin->mData.mEndZ = mEndZ; + pBin->mData.mNearZ = mNearZ; + pBin->mData.mFarZ = mFarZ; + pBin->mData.mColor = mColor; + pBin->mData.field_0x24 = mFogType; + pBin->mData.mFlag2 = mFlags; +} + +void Fog::SetBinaryInner(const Bin &, const Bin &, f32) { + // TODO +} + +Fog::~Fog() {} + +} // namespace EGG diff --git a/src/egg/gfx/eggFogManager.cpp b/src/egg/gfx/eggFogManager.cpp new file mode 100644 index 00000000..8108162e --- /dev/null +++ b/src/egg/gfx/eggFogManager.cpp @@ -0,0 +1,69 @@ +#include "egg/gfx/eggFogManager.h" + +#include "common.h" +#include "nw4r/g3d/g3d_scnroot.h" + + +namespace EGG { + +FogManager::FogManager(const u16 num) : mFlag(0), mCount(num), mCount2(num) { + mpFog = new Fog[num]; +} + +FogManager::~FogManager() { + delete[] mpFog; +} + +void FogManager::ResetFog() { + for (int i = 0; i < mCount; i++) { + mpFog[i].Reset(); + } +} + +void FogManager::Calc() { + if (!(mFlag & 4)) { + mFlag |= 4; + } +} + +void FogManager::CopyToG3D(nw4r::g3d::ScnRoot *root) const { + for (int i = 0; i < mCount; i++) { + mpFog[i].CopyToG3D(root->GetFog(i)); + } +} + +void FogManager::SetBinaryInner(const Bin &bin) { + if (bin.mHeader.mVersion == 0) { + u32 loopMax = bin.mData.mCount >= mCount2 ? mCount2 : bin.mData.mCount; + const IBinary::Bin *pBinData = bin.mData.mFogData; + for (u16 i = 0; i < loopMax; i++) { + mpFog[i].SetBinary(&pBinData[i]); + } + } +} + +void FogManager::SetBinaryInner(const Bin &bin1, const Bin &bin2, f32 blend) { + if (bin1.mHeader.mVersion == 0) { + u32 loopMax = bin1.mData.mCount >= mCount2 ? mCount2 : bin1.mData.mCount; + const IBinary::Bin *pBinData1 = bin1.mData.mFogData; + const IBinary::Bin *pBinData2 = bin2.mData.mFogData; + for (u16 i = 0; i < loopMax; i++) { + mpFog[i].SetBinaryBlend(&pBinData1[i], &pBinData2[i], blend); + } + } +} + +void FogManager::GetBinaryInner(Bin *pOutBin) const { + pOutBin->mData.mCount = mCount2; + u16 max = mCount2; + IBinary::Bin *pOutData = pOutBin->mData.mFogData; + for (u16 i = 0; i < max; i++) { + mpFog[i].GetBinary(&pOutData[i]); + } +} + +size_t FogManager::GetBinarySize() const { + return sizeof(Bin) + (mCount2 - 1) * sizeof(Fog::Bin); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggFrustum.cpp b/src/egg/gfx/eggFrustum.cpp index c060e519..59eafd69 100644 --- a/src/egg/gfx/eggFrustum.cpp +++ b/src/egg/gfx/eggFrustum.cpp @@ -1,3 +1,239 @@ #include "egg/gfx/eggFrustum.h" -namespace EGG {} // namespace EGG +#include "egg/gfx/eggGXUtility.h" +#include "egg/gfx/eggStateGX.h" +#include "nw4r/math/math_arithmetic.h" + +void eggFrustum_float_ordering() { + 1.0f; +} + +namespace EGG { +using namespace nw4r; + +Frustum::Frustum(ProjectionType proj, const math::VEC2 &size, f32 nearZ, f32 farZ, CanvasMode canvas) + : mProjType(proj), + mCanvasMode(canvas), + mSize(size), + mFovY(45.0f), + mTanFovY(2.4142134f), + mNearZ(nearZ), + mFarZ(farZ), + mOffset(0.0f, 0.0f), + mScale(1.0f, 1.0f, 1.0f), + mFlags(FLAG_DIRTY) {} + +Frustum::Frustum(const Frustum &other) { + CopyFromAnother(other); +} + +void Frustum::ResetOrthographic(f32 t, f32 b, f32 l, f32 r, f32 near, f32 far) { + 0.5f; + 2.0f; + + mProjType = PROJ_ORTHO; + mScale.z = 1.0f; + mScale.y = 1.0f; + mScale.x = 1.0f; + mSize.x = r - l; + if (mSize.x < 0.0f) { + mScale.x = -1.0f; + mSize.x *= -1.0f; + } + + mSize.y = t - b; + if (mSize.y >= 0.0f) { + SetCanvasMode(CANVASMODE_0); + mOffset = math::VEC2(0.5f * (r + l), 0.5f * (t + b)); + } else { + SetCanvasMode(CANVASMODE_1); + mOffset = math::VEC2(0.0f, t); + mSize.y *= -1.0f; + } + mNearZ = near; + mFarZ = far; + SetFlag(1); +} + +void Frustum::CopyFromAnother(const Frustum &other) { + mProjType = other.mProjType; + mCanvasMode = other.mCanvasMode; + mSize = other.mSize; + mFovY = other.mFovY; + mTanFovY = other.mTanFovY; + mNearZ = other.mNearZ; + mFarZ = other.mFarZ; + mOffset = other.mOffset; + mScale = other.mScale; + mFlags = other.mFlags; +} + +void Frustum::SetFovy(f32 fov) { + if (mFovY != fov) { + mFovY = fov; + f32 sin, cos; + + math::SinCosDeg(&sin, &cos, (f32)(f64)fov / 2.0f); + mTanFovY = cos / sin; + } +} + +void Frustum::ConvertToCanvasLU(f32 ix, f32 iy, f32 *ox, f32 *oy) const { + if (mCanvasMode == CANVASMODE_1) { + *ox = ix; + *oy = iy; + } else if (mCanvasMode == CANVASMODE_0) { + *ox = ix + (mSize.x * 0.5f); + *oy = -(iy - (mSize.y * 0.5f)); + } +} + +f32 Frustum::GetScreenSizeToViewSize(f32 p1, f32 p2) const { + if (mProjType != PROJ_PERSP) { + return p1; + } + return p1 * math::FAbs(p2) / (mSize.y * 0.5f * mTanFovY); +} + +void Frustum::SetProjectionGX() const { + if (mProjType == PROJ_ORTHO) { + SetProjectionOrthographicGX_(); + } else { + SetProjectionPerspectiveGX_(); + } +} + +void Frustum::CopyToG3D(g3d::Camera cam) const { + if (mProjType == PROJ_ORTHO) { + CopyToG3D_Orthographic_(cam); + } else { + CopyToG3D_Perspective_(cam); + } +} + +void Frustum::SetGlobalScaleOffset(f32 sx, f32 sy, f32 ox, f32 oy) { + sGlobalScale.x = sx; + sGlobalScale.y = sy; + sGlobalOffset.x = ox; + sGlobalOffset.y = oy; +} + +void Frustum::GetGlobalScaleOffset(f32 *sx, f32 *sy, f32 *ox, f32 *oy) { + *sx = sGlobalScale.x; + *sy = sGlobalScale.y; + *ox = sGlobalOffset.x; + *oy = sGlobalOffset.y; +} + +void Frustum::SetProjectionPerspectiveGX_() const { + f32 params[7]; + GetPerspectiveParam_(params); + StateGX::GXSetProjectionv_(params); +} + +void Frustum::SetProjectionOrthographicGX_() const { + f32 v[8]; + GetOrthographicParam_(v); + StateGX::GXSetProjectionv_(v); +} + +void Frustum::CopyToG3D_Perspective_(g3d::Camera cam) const { + math::MTX44 mtx; + f32 ratio = mSize.x / mSize.y; + cam.SetPerspective(mFovY, ratio, mNearZ, mFarZ); + CalcMtxPerspective_(&mtx); + cam.SetProjectionMtxDirectly(&mtx); +} + +void Frustum::CopyToG3D_Orthographic_(g3d::Camera cam) const { + f32 t, b, l, r; + GetOrthographicParam_(&t, &b, &l, &r); + cam.SetOrtho(t, b, l, r, mNearZ, mFarZ); +} + +void Frustum::CalcMtxPerspective_(math::MTX44 *out) const { + f32 params[7]; + GetPerspectiveParam_(params); + + out->m[0][3] = 0.0f; + out->m[0][1] = 0.0f; + out->m[0][0] = params[1]; + out->m[0][2] = params[2]; + + out->m[1][3] = 0.0f; + out->m[1][0] = 0.0f; + out->m[1][1] = params[3]; + out->m[1][2] = params[4]; + + out->m[2][1] = 0.0f; + out->m[2][0] = 0.0f; + out->m[2][2] = params[5]; + out->m[2][3] = params[6]; + + out->m[3][3] = 0.0f; + out->m[3][1] = 0.0f; + out->m[3][0] = 0.0f; + out->m[3][2] = -1.0f; +} + +void Frustum::GetPerspectiveParam_(f32 *p) const { + // NONMATCHING - FPR regswaps + f32 f1 = 1.0f / (mSize.x * 0.5f); + f32 f2 = 1.0f / (mSize.y * 0.5f); + p[0] = 0.0f; + p[1] = (mTanFovY / (mScale.x * (mSize.x / mSize.y))); + p[2] = mOffset.x * f1; + p[3] = mTanFovY / mScale.y; + p[4] = mOffset.y * f2; + + f32 z = -mNearZ / (mFarZ - mNearZ); + p[5] = z; + p[6] = mFarZ * z; + + GXUtility::setScaleOffsetPerspective(p, sGlobalScale.x, sGlobalScale.y, sGlobalOffset.x * f1, sGlobalOffset.y * f2); +} + +void Frustum::GetOrthographicParam_(f32 *p) const { + f32 t, b, l, r; + GetOrthographicParam_(&t, &b, &l, &r); + + f32 invHor = 1.0f / (r - l); + f32 invVert = 1.0f / (t - b); + f32 invZ = 1.0f / (mFarZ - mNearZ); + + p[0] = 1.0f; + p[1] = invHor * 2.0f; + p[2] = invHor * -(r + l); + p[3] = invVert * 2.0f; + + p[4] = invVert * -(t + b); + p[5] = -1.0f * invZ; + p[6] = -mFarZ * invZ; +} + +void Frustum::GetOrthographicParam_(f32 *pT, f32 *pB, f32 *pL, f32 *pR) const { + f32 adjOffsetX = mOffset.x + sGlobalOffset.x; + f32 adjOffsetY = mOffset.y + sGlobalOffset.y; + + if (mCanvasMode == CANVASMODE_0) { + const math::VEC2 adjScale(mScale.x * sGlobalScale.x, mScale.y * sGlobalScale.y); + + *pT = adjScale.y * ((0.5f * mSize.y) + adjOffsetY); + *pB = adjScale.y * ((-0.5f * mSize.y) + adjOffsetY); + *pL = adjScale.x * ((-0.5f * mSize.x) + adjOffsetX); + *pR = adjScale.x * ((0.5f * mSize.x) + adjOffsetX); + } else if (mCanvasMode == CANVASMODE_1) { + f32 adjScaleX = -(sGlobalScale.x - 1.0f) * mSize.x / 2.0f; + f32 adjScaleY = -(sGlobalScale.y - 1.0f) * mSize.y / 2.0f; + + *pT = adjScaleY + -sGlobalScale.y * adjOffsetY; + *pB = adjScaleY + -sGlobalScale.y * (adjOffsetY + mSize.y * -1.0f * mScale.y); + *pL = adjScaleX + sGlobalScale.x * adjOffsetX; + *pR = adjScaleX + sGlobalScale.x * (adjOffsetX + mSize.x * mScale.x); + } +} + +math::VEC2 Frustum::sGlobalScale(1.0f, 1.0f); +math::VEC2 Frustum::sGlobalOffset(0.0f, 0.0f); + +} // namespace EGG diff --git a/src/egg/gfx/eggG3DUtility.cpp b/src/egg/gfx/eggG3DUtility.cpp index b8da6920..a61cefc6 100644 --- a/src/egg/gfx/eggG3DUtility.cpp +++ b/src/egg/gfx/eggG3DUtility.cpp @@ -1,3 +1,379 @@ #include "egg/gfx/eggG3DUtility.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/core/eggHeap.h" +#include "nw4r/g3d/g3d_light.h" +#include "nw4r/g3d/g3d_state.h" +#include "nw4r/g3d/res/g3d_resanmamblight.h" +#include "nw4r/g3d/res/g3d_resanmlight.h" +#include "nw4r/g3d/res/g3d_resanmscn.h" +#include "nw4r/g3d/res/g3d_reslightset.h" +#include "nw4r/g3d/res/g3d_resmat.h" +#include "nw4r/g3d/res/g3d_resnode.h" +#include "nw4r/g3d/res/g3d_restev.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtx.h" + +#include + +namespace EGG { + +void G3DUtility::create(u32 size, Heap *pHeap) { + if (pHeap == nullptr) { + pHeap = Heap::getCurrentHeap(); + } + + if (size != 0) { + sBuf = operator new[](size, pHeap, 0x20); + sSize = size; + } else { + sBuf = nullptr; + sSize = 0; + } + + sOffset = 0; + + nw4r::g3d::G3DState::ScnDependentTexMtxFuncPtr pFunc; + u32 id = 5; + while (true) { + if (nw4r::g3d::G3DState::GetScnDependentTexMtxFunc(id, &pFunc, nullptr) && pFunc == defaultTexMtxFunc) { + break; + } + id++; + if (id >= 256) { + id = 5; + nw4r::g3d::G3DState::ScnDependentTexMtxFuncPtr pFunc2; + while (true) { + if (nw4r::g3d::G3DState::GetScnDependentTexMtxFunc(id, &pFunc2, nullptr) && + pFunc2 == nw4r::g3d::detail::ScnDependentMtxFunc::DefaultMapping) { + sId = id; + nw4r::g3d::G3DState::SetScnDependentTexMtxFunc( + id, defaultTexMtxFunc, nw4r::g3d::G3DState::SCNDEPENDENT_TEXMTX_FUNCTYPE_SRC_POS + ); + break; + } + id++; + if (id >= 256) { + break; + } + } + return; + } + } +} + +void G3DUtility::defaultTexMtxFunc(nw4r::math::MTX34 *pMtx, s8 camRef, s8 lightRef) { + const nw4r::math::MTX34 *mtxPtr = nw4r::g3d::G3DState::GetInvCameraMtxPtr(); + PSMTXCopy(mtxPtr->m, pMtx->m); +} + +bool G3DUtility::setUpLightSet(nw4r::g3d::LightSetting &lightSet, nw4r::g3d::ResAnmScn scn, int refNumber) { + if (!scn.IsValid()) { + return false; + } + + int end = scn.GetResLightSetMaxRefNumber() < lightSet.GetNumLightSet() ? scn.GetResLightSetMaxRefNumber() : + lightSet.GetNumLightSet(); + int start = 0; + if (refNumber >= 0) { + start = refNumber; + end = refNumber + 1; + } + + for (; start < end; start++) { + nw4r::g3d::LightSet set = lightSet.GetLightSet(start); + nw4r::g3d::ResLightSet resSet = scn.GetResLightSetByRefNumber(start); + + if (!set.IsValid()) { + return false; + } + + if (resSet.IsValid()) { + u32 counter = 7; + u32 j = 0; + u32 numLight = resSet.GetNumLight(); + if (numLight != 0) { + for (; j < numLight; j++) { + if (resSet.GetLightID(j) != 0xFFFF) { + nw4r::g3d::ResAnmLight anmLight = scn.GetResAnmLight(resSet.GetLightID(j)); + set.SelectLightObj(j, anmLight.GetRefNumber()); + if (anmLight.HasSpecularLight()) { + set.SelectLightObj(counter--, anmLight.GetSpecularLightIdx()); + } + } else { + set.SelectLightObj(j, -1); + } + } + } + + for (; numLight <= counter; numLight++) { + set.SelectLightObj(numLight, -1); + } + + if (resSet.HasAmbLight()) { + nw4r::g3d::ResAnmAmbLight anmAmbLight = scn.GetResAnmAmbLight(resSet.GetAmbLightID()); + set.SelectAmbLightObj(anmAmbLight.GetRefNumber()); + } else { + set.SelectAmbLightObj(-1); + } + } + } + + return true; +} + +inline bool searchInner( + const char *name, const char *candidate, bool exactMatch, G3DUtility::SearchResult *pResults, int i, int resultIdx, + int maxNumResults +) { + if (name != nullptr) { + bool found; + if (exactMatch) { + found = !std::strcmp(candidate, name); + } else { + found = std::strstr(candidate, name); + } + if (!found) { + goto err; + } + } + + if (resultIdx < maxNumResults) { + pResults[resultIdx].nodeIdx = i; + pResults[resultIdx].name = candidate; + } + return true; + +err: + return false; +} + +int G3DUtility::searchStringResNode( + nw4r::g3d::ResMdl mdl, const char *name, bool exactMatch, SearchResult *pResults, int maxNumResults +) { + u16 resultIdx = 0; + for (int i = 0; i < mdl.GetResNodeNumEntries(); i++) { + nw4r::g3d::ResNode nd = mdl.GetResNode(i); + const char *nodeName = nd.GetName(); + + if (searchInner(name, nodeName, exactMatch, pResults, i, resultIdx, maxNumResults)) { + resultIdx++; + } + } + + return resultIdx; +} + +int G3DUtility::searchStringResMat( + nw4r::g3d::ResMdl mdl, const char *name, bool exactMatch, SearchResult *pResults, int maxNumResults +) { + u16 resultIdx = 0; + for (int i = 0; i < mdl.GetResMatNumEntries(); i++) { + nw4r::g3d::ResMat mat = mdl.GetResMat(i); + const char *nodeName = mat.GetName(); + + if (searchInner(name, nodeName, exactMatch, pResults, i, resultIdx, maxNumResults)) { + resultIdx++; + } + } + + return resultIdx; +} + +int G3DUtility::searchStringResTexPlttInfo( + nw4r::g3d::ResMdl mdl, const char *name, bool exactMatch, SearchResult *pResults, int maxNumResults +) { + u16 resultIdx = 0; + for (u32 i = 0; i < mdl.GetResTexPlttInfoOffsetFromTexNameNumEntries(); i++) { + nw4r::g3d::ResTexPlttInfoOffset info = mdl.GetResTexPlttInfoOffsetFromTexName(i); + for (u16 j = 0; j < info.GetNumData(); j++) { + const char *nodeName = info.GetPllt(j).GetTexName(); + if (searchInner(name, nodeName, exactMatch, pResults, i, resultIdx, maxNumResults)) { + resultIdx++; + } + } + } + + return resultIdx; +} + +u16 G3DUtility::SetTexture( + nw4r::g3d::ResMat resMat, nw4r::g3d::ScnMdl::CopiedMatAccess *matAccess, const char *name, const GXTexObj *texObj, + bool copy, SetTextureResult *pResult, int maxNumResults, int param_8 +) { + if (!resMat.IsValid()) { + return 0; + } + + u16 resultIdx = 0; + for (u16 i = 0; i < resMat.GetNumResTexPlttInfo(); i++) { + nw4r::g3d::ResTexPlttInfo plltInfo = resMat.GetResTexPlttInfo(i); + const char *plltName = plltInfo.GetTexName(); + if (std::strcmp(name, plltName)) { + continue; + } + for (int j = 0; j < 2; j++) { + nw4r::g3d::ResTexObj resTexObj(nullptr); + if (j == 0) { + if ((matAccess == nullptr || param_8 == 1) || + (param_8 == 0 && !matAccess->GetResTexObj(false).IsValid())) { + resTexObj = resMat.GetResTexObj(); + } + } else if (matAccess != nullptr) { + resTexObj = param_8 == 0 ? matAccess->GetResTexObjEx() : matAccess->GetResTexObj(param_8 == 3); + } + + if (resTexObj.IsValid()) { + GXTexObj *obj = resTexObj.GetTexObj(plltInfo.ref().mapID); + if (copy) { + void *pImage; + u16 width; + u16 height; + GXTexFmt format; + GXTexWrapMode wrapS; + GXTexWrapMode wrapT; + u8 mipmap; + GXGetTexObjAll(obj, &pImage, &width, &height, &format, &wrapS, &wrapT, &mipmap); + + GXTexFilter minFilter; + GXTexFilter magFilter; + f32 minLOD; + f32 maxLOD; + f32 LODBias; + u8 biasClampEnable; + u8 edgeLODEnable; + GXAnisotropy anisotropy; + GXGetTexObjLODAll( + obj, &minFilter, &magFilter, &minLOD, &maxLOD, &LODBias, &biasClampEnable, &edgeLODEnable, + &anisotropy + ); + + *obj = *texObj; + GXInitTexObjFilter(obj, minFilter, magFilter); + GXInitTexObjWrapMode(obj, wrapS, wrapT); + } else { + *obj = *texObj; + } + } + } + + if (pResult != nullptr && resultIdx < maxNumResults) { + pResult[resultIdx].texCoordId = -1; + pResult[resultIdx].texMapId = -1; + + nw4r::g3d::ResTev resTev = resMat.GetResTev(); + for (u8 stage = 0; stage < resTev.GetNumTevStages(); stage++) { + GXTexCoordID coord; + GXTexMapID map; + if (resTev.GXGetTevOrder(static_cast(stage), &coord, &map, nullptr) && + map == plltInfo.ref().mapID) { + pResult[resultIdx].texMapId = map; + pResult[resultIdx].texCoordId = coord; + } + } + } + resultIdx++; + } + + return resultIdx; +} + +int G3DUtility::ApplyLightMat(nw4r::g3d::ResMdl mdl, const char *prefix) { + GXTexCoordID matchingLayerCoords[8]; + + int prefixLen = std::strlen(prefix); + int result = 0; + + u32 i = 0; + u32 numMats = mdl.GetResMatNumEntries(); + if (numMats != 0) { + for (; i < numMats; i++) { + int numMatchingLayers = 0; + nw4r::g3d::ResMat mat = mdl.GetResMat(i); + if (mat.GetResGenMode().GXGetNumTexGens() >= mat.GetNumResTexPlttInfo()) { + for (u32 j = 0; j < mat.GetNumResTexPlttInfo(); j++) { + const char *texName = mat.GetResTexPlttInfo(j).GetTexName(); + bool prefixMatch = true; + int rem = prefixLen; + for (int i = 0; i < prefixLen; i++) { + if (prefix[i] != texName[i]) { + prefixMatch = false; + break; + } + } + if (prefixMatch) { + matchingLayerCoords[numMatchingLayers++] = static_cast(j); + } + } + + if (numMatchingLayers > 1) { + nw4r::g3d::ResGenMode genMode = mat.GetResGenMode(); + int numTexGens = genMode.GXGetNumTexGens(); + nw4r::g3d::ResMatTexCoordGen resMatTexCoordGen = mat.GetResMatTexCoordGen(); + nw4r::g3d::ResTexSrt resTexSrt = mat.GetResTexSrt(); + nw4r::g3d::ResTev resTev = mat.GetResTev(); + GXTexGenType texGenType; + GXTexGenSrc param; + GXBool normalize; + u32 postMtx; + resMatTexCoordGen.GXGetTexCoordGen2( + matchingLayerCoords[0], &texGenType, ¶m, &normalize, &postMtx + ); + numMatchingLayers--; + for (; numMatchingLayers > 0; numMatchingLayers--) { + GXTexCoordID idx = matchingLayerCoords[numMatchingLayers]; + if (idx == numTexGens - 1) { + u32 numStages = resTev.GetNumTevStages(); + for (u32 stage = 0; stage < numStages; stage++) { + GXTexCoordID coord; + GXTexMapID map; + GXChannelID channel; + if (resTev.GXGetTevOrder(static_cast(stage), &coord, &map, &channel) && + coord == idx) { + resTev.GXSetTevOrder( + static_cast(stage), + matchingLayerCoords[0], map, channel + ); + } + } + + int stage = 0; + int nInds = genMode.GXGetNumIndStages(); + for (; stage < nInds; stage++) { + GXTexCoordID coord; + GXTexMapID map; + if (resTev.GXGetIndTexOrder(static_cast(stage), &coord, &map) && + coord == idx) { + resTev.GXSetIndTexOrder( + static_cast(stage), + static_cast(matchingLayerCoords[0]), map + ); + } + } + resMatTexCoordGen.Disable(idx); + result++; + resTexSrt.Disable(idx); + numTexGens--; + } + } + resMatTexCoordGen.DCStore(false); + resTev.DCStore(false); + genMode.GXSetNumTexGens(numTexGens); + } + } + } + } + + return result; +} + +void *G3DUtility::BumpAlloc(u32 size, u32 align) { + u32 next = sOffset % align != 0 ? sOffset + (align - sOffset % align) : sOffset; + sOffset = next + size; + // REGSWAP + return reinterpret_cast(sBuf) + next; +} + +} // namespace EGG diff --git a/src/egg/gfx/eggGXUtility.cpp b/src/egg/gfx/eggGXUtility.cpp index 43963b51..09f0390c 100644 --- a/src/egg/gfx/eggGXUtility.cpp +++ b/src/egg/gfx/eggGXUtility.cpp @@ -1,3 +1,86 @@ #include "egg/gfx/eggGXUtility.h" -namespace EGG {} // namespace EGG +#include "egg/gfx/eggTexture.h" +#include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +const u8 GXUtility::s_texMtxIds[8] = {30, 33, 36, 39, 42, 45, 48, 51}; + +int GXUtility::getTexMtxID(int idx) { + return s_texMtxIds[idx]; +} + +void GXUtility::setScaleOffsetPerspective(f32 *pOut, f32 f1, f32 f2, f32 f3, f32 f4) { + pOut[1] *= (1.0f / f1); + pOut[3] *= (1.0f / f2); + pOut[2] += f3; + pOut[4] += f4; +} + +void GXUtility::getTexObj(GXTexObj *obj, const ResTIMG &img) { + u32 offset = img.imageOffset != 0 ? img.imageOffset : sizeof(ResTIMG); + void *pImage = const_cast(reinterpret_cast(reinterpret_cast(&img) + offset)); + // Missing a redundant register move here (obj r30->r3) + GXInitTexObj( + obj, pImage, img.width, img.height, static_cast(img.format), static_cast(img.wrapS), + static_cast(img.wrapT), img.mipmapEnabled != 0 + ); + GXInitTexObjLOD( + obj, static_cast(img.minFilter), static_cast(img.magFilter), img.minLOD / 8.0f, + img.maxLOD / 8.0f, img.LODBias / 100.0f, img.biasClamp, img.doEdgeLOD, + static_cast(img.maxAnisotropy) + ); +} + +void GXUtility::getTexObj( + GXTexObj *obj, nw4r::g3d::ResTex resTex, GXTexWrapMode wrapS, GXTexWrapMode wrapT, GXTexFilter minFilter, + GXTexFilter magFilter +) { + void *pTexData; + u16 width; + u16 height; + GXTexFmt format; + f32 minLod; + f32 maxLod; + GXBool mipMap; + if (resTex.GetTexObjParam(&pTexData, &width, &height, &format, &minLod, &maxLod, &mipMap)) { + GXInitTexObj(obj, pTexData, width, height, format, wrapS, wrapT, mipMap); + GXInitTexObjLOD(obj, minFilter, magFilter, minLod, maxLod, 0.0f, false, false, GX_ANISO_1); + } +} + +void GXUtility::getNormalColor(GXColor &outColor, const Vector3f &vec) { + // Are there inlines that might work here? Probably! + f32 fs[3]; + f32 g = vec.z < 0.0f ? vec.y * 128.0f + 128.0f - 0.5f : vec.z * 127.0f + 128.0f + 0.5f; + f32 b = vec.y < 0.0f ? vec.y * 128.0f + 128.0f - 0.5f : vec.y * 127.0f + 128.0f + 0.5f; + f32 a = vec.x < 0.0f ? vec.x * 128.0f + 128.0f - 0.5f : vec.x * 127.0f + 128.0f + 0.5f; + + fs[0] = a; + fs[1] = b; + fs[2] = g; + + if (fs[0] < 0.0f) { + fs[0] = 0.0f; + } else if (fs[0] > 255.0f) { + fs[0] = 255.0f; + } + if (fs[1] < 0.0f) { + fs[1] = 0.0f; + } else if (fs[1] > 255.0f) { + fs[1] = 255.0f; + } + if (fs[2] < 0.0f) { + fs[2] = 0.0f; + } else if (fs[2] > 255.0f) { + fs[2] = 255.0f; + } + + outColor.a = fs[0]; + outColor.b = fs[1]; + outColor.g = fs[2]; +} + +} // namespace EGG diff --git a/src/egg/gfx/eggGfxEngine.cpp b/src/egg/gfx/eggGfxEngine.cpp index 7a2da6a7..9a1fc150 100644 --- a/src/egg/gfx/eggGfxEngine.cpp +++ b/src/egg/gfx/eggGfxEngine.cpp @@ -1,3 +1,38 @@ #include "egg/gfx/eggGfxEngine.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/core/eggDisplay.h" +#include "egg/core/eggSystem.h" +#include "egg/core/eggVideo.h" +#include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +// Needed for dtor placement +void ProbablySomethingCreatingThisConfiguration() { + GfxEngine::Configuration c; +} + +GfxEngine::Configuration::Configuration() + : efbWidth(640), + efbHeight(528), + clearColor((GXColor){0, 0, 0, 0}), + field_0x08(0), + field_0x0C(32), + field_0x0E(256), + bufferSize(0), + field_0x14(608), + field_0x16(812), + field_0x18(0) { + if (BaseSystem::getVideo() != nullptr) { + efbWidth = BaseSystem::getVideo()->pRenderMode->fbWidth; + efbHeight = BaseSystem::getVideo()->pRenderMode->efbHeight; + } + if (BaseSystem::getDisplay() != nullptr) { + clearColor = BaseSystem::getDisplay()->getClearColor(); + } + bufferSize = GXGetTexBufferSize(efbWidth, efbHeight, GX_TF_RGBA8, false, 0) * 3; +} + +} // namespace EGG diff --git a/src/egg/gfx/eggGlobalDrawState.cpp b/src/egg/gfx/eggGlobalDrawState.cpp index aed5311a..bb1f3df3 100644 --- a/src/egg/gfx/eggGlobalDrawState.cpp +++ b/src/egg/gfx/eggGlobalDrawState.cpp @@ -1,3 +1,37 @@ #include "egg/gfx/eggGlobalDrawState.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggStateEfb.h" +#include "egg/gfx/eggStateGX.h" +#include "rvl/MTX/mtx.h" + +namespace EGG { + +Screen const *GlobalDrawState::spScreen; +u16 GlobalDrawState::sCameraId; +u32 GlobalDrawState::sDrawFlag; + +// unknown +nw4r::math::MTX34 GlobalDrawState::sMtx; + +GlobalDrawState sState; + +void GlobalDrawState::beginDrawView(u16 cameraId, const nw4r::math::MTX34 &mtx, const Screen &screen) { + spScreen = &screen; + sCameraId = cameraId; + PSMTXCopy(mtx, sMtx); + StateEfb::Clean(); +} + +void GlobalDrawState::setDrawSettingGX(bool b1, bool b2) { + StateGX::GXSetColorUpdate_((sDrawFlag & 1) != 0); + StateGX::GXSetAlphaUpdate_((sDrawFlag & 2) != 0); + StateGX::GXSetDither_((sDrawFlag & 4) != 0); + StateGX::GXSetDstAlpha_(false, 0); + if (b2 && spScreen != nullptr) { + spScreen->SetProjectionGX(); + } +} + + +} // namespace EGG diff --git a/src/egg/gfx/eggIScnProc.cpp b/src/egg/gfx/eggIScnProc.cpp index 6b86ce5b..25e3dafa 100644 --- a/src/egg/gfx/eggIScnProc.cpp +++ b/src/egg/gfx/eggIScnProc.cpp @@ -1,3 +1,88 @@ #include "egg/gfx/eggIScnProc.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/egg_types.h" +#include "egg/gfx/eggG3DUtility.h" +#include "egg/gfx/eggGlobalDrawState.h" +#include "egg/gfx/eggStateGX.h" +#include "nw4r/g3d/g3d_scnobj.h" +#include "nw4r/math/math_types.h" +#include "rvl/MTX/mtx.h" + +namespace EGG { + +IScnProc::~IScnProc() { + if (mpDataSet != nullptr) { + for (int i = 0; i < getNumScnProc(); i++) { + mpDataSet[i].mpScnProc->Destroy(); + mpDataSet[i].mpScnProc = nullptr; + } + + delete[] mpDataSet; + mpDataSet = nullptr; + } +} + +void IScnProc::createScnProc(u16 procNum, MEMAllocator *pAllocator) { + mNumScnProc = procNum; + mpDataSet = new ProcData[mNumScnProc]; + nw4r::math::MTX34 mtx; + PSMTXIdentity(mtx); + + for (u16 i = 0; i < getNumScnProc(); i++) { + u32 sp8; + MEMAllocator *allocator = (pAllocator == nullptr) ? G3DUtility::getAllocator() : pAllocator; + + mpDataSet[i].mpScnProc = nw4r::g3d::ScnProc::Construct(allocator, &sp8, IScnProc::drawProcFunc, true, false, 0); + + mpDataSet[i].mpScnProc->SetUserData(&mpDataSet[i]); + mpDataSet[i].mpScnProc->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, mtx); + + mpDataSet[i].mIndex = i; + mpDataSet[i].mpThis = this; + mpDataSet[i].mFlags = 1 | 2; + + setPriorityScnProc(i, i, true); + } +} + +void IScnProc::setPriorityScnProc(u16 procIndex, u8 priority, bool bUseOpa) { + nw4r::g3d::ScnProc *pScnProc = getData(procIndex)->mpScnProc; + if (bUseOpa) { + pScnProc->SetDrawProc(IScnProc::drawProcFunc, true, false); + pScnProc->SetPriorityDrawOpa(priority); + mpDataSet[procIndex].mFlags |= 1; + } else { + pScnProc->SetDrawProc(IScnProc::drawProcFunc, false, true); + pScnProc->SetPriorityDrawXlu(priority); + mpDataSet[procIndex].mFlags &= ~1; + } +} + +void IScnProc::pushBackToScnGroup(nw4r::g3d::ScnGroup *pScnGroup) { + for (u16 i = 0; i < getNumScnProc(); i++) { + bool is_push_back = pScnGroup->Insert(pScnGroup->Size(), getData(i)->mpScnProc); + } +} + +void IScnProc::removeFromScnGroup(nw4r::g3d::ScnGroup *pScnGroup) { + for (u16 i = 0; i < getNumScnProc(); i++) { + bool is_remove = pScnGroup->Remove(getData(i)->mpScnProc); + } +} + +void IScnProc::drawProcFunc(nw4r::g3d::ScnProc *pScnProc, bool b) { + GlobalDrawState::setDrawSettingGX(b, false); + StateGX::s_commandFlag &= ~0xF; + drawProcFuncNoGlobalState(pScnProc, b); + StateGX::resetGXCache(); + + GlobalDrawState::setDrawSettingGX(b, (StateGX::s_commandFlag & 0xF) != 0); +} + +void IScnProc::drawProcFuncNoGlobalState(nw4r::g3d::ScnProc *pScnProc, bool b) { + ProcData *dat = static_cast(pScnProc->GetUserData()); + dat->mpThis->scnProcDraw(dat->mIndex); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggLight.cpp b/src/egg/gfx/eggLight.cpp deleted file mode 100644 index c842a6ec..00000000 --- a/src/egg/gfx/eggLight.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "egg/gfx/eggLight.h" - -namespace EGG {} // namespace EGG diff --git a/src/egg/gfx/eggLightManager.cpp b/src/egg/gfx/eggLightManager.cpp new file mode 100644 index 00000000..003b8703 --- /dev/null +++ b/src/egg/gfx/eggLightManager.cpp @@ -0,0 +1,318 @@ +#include "egg/gfx/eggLightManager.h" + +#include "common.h" +#include "egg/egg_types.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggG3DUtility.h" +#include "egg/gfx/eggLightObject.h" +#include "egg/gfx/eggLightTextureMgr.h" +#include "nw4r/g3d/g3d_light.h" +#include "nw4r/g3d/g3d_scnroot.h" +#include "nw4r/g3d/g3d_state.h" +#include "nw4r/g3d/res/g3d_resanmamblight.h" +#include "nw4r/g3d/res/g3d_resanmscn.h" +#include "nw4r/g3d/res/g3d_reslightset.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXLight.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtx.h" +#include "rvl/OS/OSCache.h" + +namespace EGG { + +LightManager::LightManager(u32 numEggObjects, u32 numAmbientObject, u8 numGxObjsPerEggObj) { + Counts c; + c.mNumEggLightObjects = numEggObjects; + c.mNumAmbientObjects = numAmbientObject; + + mCounts = c; + mSavedCounts = c; + mpLightData = nullptr; + mpAmbientObjects = nullptr; + mpTextureMgr = nullptr; + + mNumGxObjsPerEggObj = numGxObjsPerEggObj; + mFlags = 0x40; + mResAnmScn = nw4r::g3d::ResAnmScn(nullptr); + mRefNumber = -1; + + mpTextureMgr = new LightTextureManager(this); + mpLightObjs = new GXLightObj[mNumGxObjsPerEggObj * CheckedNumLightObjs(mCounts.mNumEggLightObjects)](); + mpLightData = new LightData[mCounts.mNumEggLightObjects](); + mpAmbientObjects = new AmbientObject[mCounts.mNumAmbientObjects](); + + for (int i = 0; i < mCounts.mNumEggLightObjects; i++) { + GetLightObject(i)->SetIndex(i); + GetLightObject(i)->ClearField0xA0(); + BecomeInvalidLight(i); + } + + for (u16 i = 0; i < (u32)mCounts.mNumAmbientObjects; i++) { + mpAmbientObjects[i].field_0x08 = 0; + } + + Reset(); +} + +LightManager::~LightManager() { + delete mpTextureMgr; + delete[] mpLightObjs; + delete[] mpLightData; + delete[] mpAmbientObjects; +} + +static const char *ambientLightPlaceholderName = "--"; + +void LightManager::Reset() { + for (int i = 0; i < mCounts.mNumEggLightObjects; i++) { + LightObject *obj = GetLightObject(i); + obj->Reset(); + if (i > 0) { + obj->ClearFlag2(); + } + } + + for (u16 i = 0; i < (u32)mCounts.mNumAmbientObjects; i++) { + mpAmbientObjects[i].mLightObj = (nw4r::g3d::AmbLightObj){0x64, 0x64, 0x64, 0xFF}; + mpAmbientObjects[i].mLightName = ambientLightPlaceholderName; + } + mColor = DrawGX::BLACK; + field_0x1D = 0; + mFlags = mFlags & 0xFFE0; +} + +void LightManager::Calc(nw4r::g3d::ScnRoot *root) { + if ((mFlags & 4) == 0) { + for (int i = 0; i < mCounts.mNumEggLightObjects; i++) { + LightObject *obj = GetLightObject(i); + if (obj->CheckFlag2()) { + u16 u = obj->GetField0x06(); + if (i != u) { + obj->UpdatePosAt(*GetLightObject(u)); + } + } + obj->Calc(); + } + mFlags |= 4; + mpTextureMgr->frameReset(); + } + + if (root != nullptr) { + CopyToG3D_World(root); + } +} + +void LightManager::CalcView(const nw4r::math::MTX34 &viewMtx, u8 lightObjOffset, nw4r::g3d::ScnRoot *root) { + // NONMATCHING - regswaps + field_0x1D = lightObjOffset; + mFlags |= 8; + + GXLightObj *gxObj = mpLightObjs + lightObjOffset * CheckedNumLightObjs(mCounts.mNumEggLightObjects); + for (int i = 0; i < mCounts.mNumEggLightObjects; i++) { + GetLightObject(i)->CalcView(viewMtx); + if (i < CheckedNumLightObjs(mCounts.mNumEggLightObjects)) { + GetLightObject(i)->InitGX(&gxObj[i]); + } + } + DCFlushRange(gxObj, CheckedNumLightObjs(mCounts.mNumEggLightObjects) * sizeof(GXLightObj)); + if (root != nullptr) { + nw4r::math::MTX34 tmp; + PSMTXInverse(viewMtx, tmp); + CopyToG3D_View(root, tmp); + } +} + +void LightManager::LoadLightSet( + int id, u32 *pDiffColorMask, u32 *pDiffAlphaMask, u32 *pSpecColorMask, u32 *pSpecAlphaMask, GXColor *pColor +) { + nw4r::g3d::AmbLightObj o; + nw4r::g3d::G3DState::LoadLightSet(id, pDiffColorMask, pDiffAlphaMask, pSpecColorMask, pSpecAlphaMask, &o); + if (pColor != nullptr) { + pColor->r = o.r; + pColor->g = o.g; + pColor->b = o.b; + pColor->a = o.a; + } +} + +void LightManager::DoneDraw() { + if (((mFlags & 8) != 0) && ((mFlags & 4) != 0)) { + mFlags = mFlags & 0xffef; + } + mFlags = mFlags & 0xfffb; + mFlags = mFlags & 0xfff7; +} + +void LightManager::LoadScnLightInner(nw4r::g3d::ResAnmScn scn, f32 frame, s16 refNumber, u32 u2) { + // NONMATCHING - small problems around lightSet.GetLightID + if (!scn.IsValid()) { + return; + } + + if ((u2 & 2) != 0) { + mFlags |= 0x10; + mResAnmScn = scn; + mRefNumber = refNumber; + } + + if ((u2 & 1) == 0) { + return; + } + + for (int i = 0; i < mCounts.mNumEggLightObjects; i++) { + BecomeInvalidLight(i); + } + + nw4r::g3d::ResLightSet lightSet = scn.GetResLightSetByRefNumber(refNumber); + s32 lightId = -1; + if (lightSet.IsValid()) { + lightId = lightSet.GetAmbLightID(); + } + u32 loopMax = mCounts.mNumAmbientObjects; + if (scn.GetResAnmAmbLightMaxRefNumber() < loopMax) { + loopMax = scn.GetResAnmAmbLightMaxRefNumber(); + } + for (u32 i = 0; i < loopMax; i++) { + AmbientObject *ambient = &mpAmbientObjects[i]; + ambient->field_0x08 = ambient->field_0x08 & 0xFE; + if (lightId == -1 || i == lightId) { + nw4r::g3d::ResAnmAmbLight light = scn.GetResAnmAmbLightByRefNumber(i); + AnmScnRes_GetAmbLightColor(ambient, light, frame); + ambient->field_0x08 |= 1; + } + } + + u32 numObjs = mCounts.mNumEggLightObjects; + u32 numAmb = scn.GetResAnmLightMaxRefNumber(); + u32 numTotal = numAmb + scn.GetSpecularLightNumber(); + u32 numLight = numAmb <= numObjs ? numAmb : numObjs; + u32 maxIdx = numTotal <= numObjs ? numTotal : numObjs; + + if (lightSet.IsValid()) { + numLight = lightSet.GetNumLight(); + } + + for (u32 i = 0; i < numLight; i++) { + u32 idx = lightSet.IsValid() ? lightSet.GetLightID(i) : i; + GetLightObject(idx)->ClearFlag2(); + } + + for (u32 i = 0; i < numLight; i++) { + u32 idx = lightSet.IsValid() ? lightSet.GetLightID(i) : i; + nw4r::g3d::ResAnmLight light = scn.GetResAnmLightByRefNumber(idx); + if (light.IsValid()) { + LightObject *obj = nullptr; + LightData *dat = &mpLightData[idx]; + if (!GetLightObject(idx)->CheckFlag1()) { + if (light.HasSpecularLight() && light.GetSpecularLightIdx() < maxIdx) { + obj = GetLightObject(light.GetSpecularLightIdx()); + } + dat->mLightObject.CopyFromG3D(light, frame, obj, false); + mpLightData[idx].mLightObject.SetOtherFlag1(); + } + } + } +} + +void LightManager::CopyToG3D_Ambient(nw4r::g3d::ScnRoot *root) const { + // NONMATCHING - word copy + nw4r::g3d::LightSetting &setting = root->GetLightSetting(); + for (int i = 0; i < mCounts.mNumAmbientObjects; i++) { + setting.GetAmbLightObjArray()[i] = mpAmbientObjects[i].mLightObj; + } +} + +void LightManager::CopyToG3D_World(nw4r::g3d::ScnRoot *root) const { + // NONMATCHING - loop registers, variables + nw4r::g3d::LightSetting &setting = root->GetLightSetting(); + if ((mFlags & 0x10) != 0) { + G3DUtility::setUpLightSet(setting, mResAnmScn, mRefNumber); + } + CopyToG3D_Ambient(root); + for (int i = 0; i < mCounts.mNumAmbientObjects; i++) { + GetLightObject(i)->CopyToG3D_World(setting.GetLightObjArray()[i]); + } +} + +void LightManager::CopyToG3D_View(nw4r::g3d::ScnRoot *root, const nw4r::math::MTX34 &viewMtx) const { + nw4r::g3d::LightSetting &setting = root->GetLightSetting(); + // NONMATCHING - loop registers, variables + for (int i = 0; i < mCounts.mNumEggLightObjects; i++) { + GetLightObject(i)->CopyToG3D_View(setting.GetLightObjArray()[i], viewMtx); + } +} + +void LightManager::AnmScnRes_GetAmbLightColor( + EGG::LightManager::AmbientObject *obj, nw4r::g3d::ResAnmAmbLight light, f32 frame +) const { + nw4r::g3d::AmbLightAnmResult res; + if (!light.IsValid()) { + res.flags = 0; + res.color = -1; + } else { + light.GetAnmResult(&res, frame); + obj->mLightName = light.GetName(); + } + + if ((res.flags & nw4r::g3d::AmbLightAnmResult::FLAG_COLOR_ENABLE) == 0) { + res.color |= 0xFFFFFF00; + } + + if ((res.flags & nw4r::g3d::AmbLightAnmResult::FLAG_ALPHA_ENABLE) == 0) { + res.color |= 0x000000FF; + } + + u32 color = res.color; + + obj->mLightObj.r = (color >> 24) & 0xFF; + obj->mLightObj.g = (color >> 16) & 0xFF; + obj->mLightObj.b = (color >> 8) & 0xFF; + obj->mLightObj.a = (color >> 0) & 0xFF; +} + +void LightManager::SetBinaryInner(const Bin &) { + // TODO +} + +void LightManager::GetBinaryInner(Bin *bin) const { + // NONMATCHING - regswaps, loop increments + u16 numObjs = mSavedCounts.mNumEggLightObjects; + u16 numAmbient = mSavedCounts.mNumAmbientObjects; + bin->mData.mNumLightObjects = numObjs; + bin->mData.mNumAmbientObjects = mSavedCounts.mNumAmbientObjects; + + LightObject::Bin *pObj = reinterpret_cast(&bin->mData.mObjData); + for (int i = 0; i < numObjs; i++) { + GetLightObject(i)->GetBinary(&pObj[i]); + } + + BinAmbient *pAmp = reinterpret_cast(&pObj[numObjs]); + for (u16 i = 0; i < numAmbient; i++) { + AmbientObject &o = mpAmbientObjects[i]; + pAmp[i].field_0x00 = o.mLightObj.r; + pAmp[i].field_0x01 = o.mLightObj.g; + pAmp[i].field_0x02 = o.mLightObj.b; + pAmp[i].field_0x03 = o.mLightObj.a; + pAmp[i].field_0x07 = 0; + pAmp[i].field_0x06 = 0; + pAmp[i].field_0x05 = 0; + pAmp[i].field_0x04 = 0; + } + + bin->mData.mColor = mColor; +} + +void LightManager::SetBinaryInner(const Bin &, const Bin &, f32) { + // TODO +} + +void LightManager::BecomeInvalidLight(int idx) { + mpLightData[idx].mLightObject.ClearOtherFlag1(); +} + +size_t LightManager::GetBinarySize() const { + return sizeof(Bin) + sizeof(LightObject::Bin) * (mSavedCounts.mNumEggLightObjects - 1) + + sizeof(BinAmbient) * mSavedCounts.mNumAmbientObjects; +} + +} // namespace EGG diff --git a/src/egg/gfx/eggLightObject.cpp b/src/egg/gfx/eggLightObject.cpp new file mode 100644 index 00000000..baf6a6a8 --- /dev/null +++ b/src/egg/gfx/eggLightObject.cpp @@ -0,0 +1,397 @@ +#include "egg/gfx/eggLightObject.h" + +#include "common.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggLightTexture.h" +#include "nw4r/g3d/g3d_light.h" +#include "nw4r/g3d/res/g3d_resanmlight.h" +#include "nw4r/math/math_arithmetic.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXLight.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtxvec.h" +#include "rvl/MTX/vec.h" + +// TODO: This whole file does weird things with vectors! +// NSMBW symbol names indicate that functions use nw4r::math::VEC3 +// arguments and we have some nw4r PS inlines, but +// a fair number of vector assignments happen in a weird order +// which might indicate EGG::Vector3f? + +namespace EGG { + +template <> +const char *IBinary::GetBinaryType() { + return "LOBJ"; +} + +template <> +int IBinary::GetVersion() { + return 2; +} + +// why +static const f32 zeroVec[3] = {0.0f, 0.0f, 0.0f}; + +LightObject::LightObject() + : mIndex(0), + field_0x06(0), + mAt(zeroVec), + mPos(-10000.0f, 10000.0f, 10000.0f), + mDir(0.0f, -1.0f, 0.0f), + mWhite(DrawGX::WHITE), + field_0x30(1.0f), + mDist(1.0f), + mBlack(DrawGX::BLACK), + field_0x3C(0), + field_0x3D(1), + mSpotFn(GX_SP_OFF), + mDistAttnFn(GX_DA_OFF), + mCutoff(90.0f), + mRefDist(0.5f), + mRefBrightness(0.5f), + mShininess(16.0f), + mFlags(0x661) {} + +void LightObject::Reset() { + SetPosAt(nw4r::math::VEC3(-10000.0f, 10000.0f, 10000.0f), zeroVec); + mFlags = 0x661; + mWhite = DrawGX::WHITE; + mBlack = DrawGX::BLACK; + field_0x30 = 1.0; + field_0x3C = 0; + field_0x3D = 1; + mCutoff = 90.0; + mRefDist = 0.5; + mRefBrightness = 0.5; + mSpotFn = GX_SP_OFF; + mDistAttnFn = GX_DA_OFF; + mShininess = 16.0; + + field_0x4C.x = field_0x58.x = 1.0f; + field_0x4C.z = field_0x58.z = 0.0f; + field_0x4C.y = field_0x58.y = 0.0f; +} + +void LightObject::Calc() { + field_0x6C = mDir; + mLightColor = mWhite; +} + +void LightObject::CalcView(nw4r::math::MTX34 const &viewMtx) { + if ((mFlags & 1) == 0) { + return; + } + + if (getField0x3C() < 0 || getField0x3C() > 1) { + switch (getField0x3C()) { + case 3: { + field_0x94.x = mViewAt.x = 0.0f; + field_0x94.y = mViewAt.y = 0.0f; + field_0x94.z = mViewAt.z = -1.0f; + mViewAt.z *= mDist; + mViewPos.x = mViewPos.y = mViewPos.z = 0.0f; + break; + } + case 4: { + field_0x94.x = mViewPos.x = 0.0f; + field_0x94.y = mViewPos.y = 0.0f; + field_0x94.z = mViewPos.z = 1.0f; + mViewPos.z *= mDist; + mViewAt.x = mViewAt.y = mViewAt.z = 0.0f; + break; + } + case 2: + field_0x94 = mDir; + mViewAt = mAt; + mViewPos = mPos; + break; + } + + } else { + if (getField0x3C() == 1) { + nw4r::math::VEC3 tmp(-viewMtx._20, -viewMtx._21, -viewMtx._22); + if (PSVECMag(tmp) > 0.0f) { + nw4r::math::VEC3 angle; + C_VECHalfAngle(mDir, tmp, angle); + nw4r::math::VEC3Scale(&field_0x6C, &angle, -1.0f); + PSVECNormalize(field_0x6C, field_0x6C); + } else { + field_0x6C.x = field_0x6C.y = 0.0f; + field_0x6C.z = 1.0f; + } + } + PSMTXMultVec(viewMtx, mPos, mViewPos); + PSMTXMultVec(viewMtx, mAt, mViewAt); + nw4r::math::VEC3TransformNormal(&field_0x94, &viewMtx, &field_0x6C); + } +} + +void LightObject::fn_804A9C30(const LightTexture *tex, nw4r::math::VEC3 *pVec, GXColor *color) const { + *pVec = field_0x94; + *color = mLightColor; + f32 f = tex->getFloat(mIndex); + if (f < 1.0f) { + color->r = color->r * f; + color->g = color->g * f; + color->b = color->b * f; + color->a = color->a * f; + } else { + // Yes + *color = *color; + } +} + +void LightObject::InitGX(GXLightObj *obj) const { + if ((mFlags & 1) != 0 && ((mFlags >> 6) & 1) != 0) { + GXInitLightColor(obj, mLightColor); + switch (field_0x3D) { + case 1: { + nw4r::math::VEC3 tmp = field_0x94 * -1e10f; + GXInitLightPos(obj, tmp.x, tmp.y, tmp.z); + GXInitLightDir(obj, zeroVec[0], zeroVec[1], zeroVec[2]); + break; + } + case 0: { + GXInitLightPos(obj, mViewPos.x, mViewPos.y, mViewPos.z); + GXInitLightDir(obj, zeroVec[0], zeroVec[1], zeroVec[2]); + break; + } + case 2: { + GXInitLightPos(obj, mViewPos.x, mViewPos.y, mViewPos.z); + GXInitLightDir(obj, field_0x94.x, field_0x94.y, field_0x94.z); + break; + } + } + + if ((mFlags & 0x80) != 0) { + GXInitLightAttnA(obj, field_0x4C.x, field_0x4C.y, field_0x4C.z); + } else { + GXInitLightSpot(obj, mCutoff > 0.0f ? mCutoff : 0.0001f, getSpotFn()); + } + + if ((mFlags & 0x100) != 0) { + GXInitLightAttnK(obj, field_0x58.x, field_0x58.y, field_0x58.z); + } else { + GXInitLightDistAttn(obj, mRefDist * getDistance(), mRefBrightness, getDistAttnFn()); + } + + if ((mFlags & 0x800) != 0) { + f32 ka = mShininess / 2.0f; + GXInitLightAttn(obj, 0.0f, 0.0f, 1.0f, ka, 0.0f, 1.0f - ka); + } + + } else { + GXInitLightColor(obj, DrawGX::BLACK); + } +} + +void LightObject::CopyToG3D_World(nw4r::g3d::LightObj &g3dObj) const { + if ((mFlags & 1) != 0 && (mFlags & 0x40) != 0) { + g3dObj.Clear(); + if ((mFlags & 0x200) == 0) { + g3dObj.DisableColor(); + } + if ((mFlags & 0x400) == 0) { + g3dObj.DisableAlpha(); + } + + g3dObj.Enable(); + g3dObj.InitLightColor(mLightColor); + + if ((mFlags & 0x80) != 0) { + g3dObj.InitLightAttnA(field_0x4C.x, field_0x4C.y, field_0x4C.z); + } else { + g3dObj.InitLightSpot(mCutoff > 0.0f ? mCutoff : 0.0001f, getSpotFn()); + } + + if ((mFlags & 0x100) != 0) { + g3dObj.InitLightAttnK(field_0x58.x, field_0x58.y, field_0x58.z); + } else { + g3dObj.InitLightDistAttn(mRefDist * getDistance(), mRefBrightness, getDistAttnFn()); + } + + if ((mFlags & 0x800) != 0) { + g3dObj.InitLightShininess(mShininess); + } + } else { + g3dObj.Disable(); + } +} + +void LightObject::CopyToG3D_View(nw4r::g3d::LightObj &g3dObj, const nw4r::math::MTX34 &viewMtx) const { + if (!g3dObj.IsEnable()) { + return; + } + + if (!((mFlags >> 11) & 1)) { + nw4r::math::VEC3 dir; + nw4r::math::VEC3 pos; + switch (field_0x3D) { + case 1: { + nw4r::math::VEC3TransformNormal(&dir, &viewMtx, &field_0x94); + nw4r::math::VEC3Scale(&pos, &dir, -1e10f); + dir.x = dir.y = dir.z = 0.0f; + break; + } + case 0: { + PSMTXMultVec(viewMtx, mViewPos, pos); + dir.x = dir.y = dir.z = 0.0f; + break; + } + case 2: { + PSMTXMultVec(viewMtx, mViewPos, pos); + nw4r::math::VEC3TransformNormal(&dir, &viewMtx, &field_0x94); + break; + } + } + g3dObj.InitLightPos(pos.x, pos.y, pos.z); + g3dObj.InitLightDir(dir.x, dir.y, dir.z); + } else { + g3dObj.InitSpecularDir(mDir.x, mDir.y, mDir.z); + } +} + +void LightObject::CopyFromG3D( + const nw4r::g3d::ResAnmLight &g3dLight, f32 frame, EGG::LightObject *optObj, bool skipDoingSomething +) { + nw4r::g3d::LightAnmResult result; + g3dLight.GetAnmResult(&result, frame); + if (!skipDoingSomething || (result.flags & nw4r::g3d::LightAnmResult::FLAG_LIGHT_ENABLE) != 0) { + if ((result.flags & nw4r::g3d::LightAnmResult::FLAG_LIGHT_ENABLE) != 0) { + ApplyAnmResultA(result); + if (optObj != nullptr && optObj->ApplyAnmResultB(result)) { + optObj->field_0x06 = mIndex; + optObj->mFlags |= 2; + } + } else { + ClearFlag2(); + if (optObj != nullptr) { + optObj->ClearFlag2(); + } + } + } +} + +void LightObject::ApplyAnmResultInner(const nw4r::g3d::LightAnmResult &res) { + // TODO + mFlags = mFlags & 0xF07E; + mCutoff = 90.0f; + mRefDist = 0.5f; + mRefBrightness = 0.5f; + mSpotFn = GX_SP_OFF; + mDistAttnFn = GX_DA_OFF; + mShininess = 16.0f; + + field_0x4C.x = field_0x58.x = 1.0f; + field_0x4C.z = field_0x58.z = 0.0f; + field_0x4C.y = field_0x58.y = 0.0f; + + if ((res.flags & nw4r::g3d::LightAnmResult::FLAG_COLOR_ENABLE) != 0) { + mFlags |= 0x200; + } + if ((res.flags & nw4r::g3d::LightAnmResult::FLAG_ALPHA_ENABLE) != 0) { + mFlags |= 0x400; + } + if ((res.flags & nw4r::g3d::LightAnmResult::FLAG_LIGHT_ENABLE) != 0) { + mFlags |= 1; + } +} + +void LightObject::ApplyAnmResultA(const nw4r::g3d::LightAnmResult &res) { + ApplyAnmResultInner(res); + switch ((int)(res.flags & nw4r::g3d::LightAnmResult::FLAG_LIGHT_TYPE_MASK)) { + case 0: { + field_0x3D = 0; + mWhite = res.color; + SetPosAt(res.pos, res.pos); + mCutoff = 0.0f; + mSpotFn = GX_SP_OFF; + mRefDist = res.refDistance; + mRefBrightness = res.refBrightness; + mDistAttnFn = res.distFunc; + break; + } + case 1: { + field_0x3D = 1; + mWhite = res.color; + SetPosAt(res.pos, res.aim); + mSpotFn = GX_SP_OFF; + mDistAttnFn = GX_AF_SPEC; + break; + } + case 2: { + field_0x3D = 2; + mWhite = res.color; + SetPosAt(res.pos, res.aim); + mSpotFn = res.spotFunc; + mCutoff = res.cutoff; + mDistAttnFn = res.distFunc; + mRefDist = res.refDistance; + mRefBrightness = res.refBrightness; + break; + } + } +} + +bool LightObject::ApplyAnmResultB(const nw4r::g3d::LightAnmResult &res) { + if ((res.flags & nw4r::g3d::LightAnmResult::FLAG_SPECULAR_ENABLE) != 0) { + ApplyAnmResultInner(res); + field_0x3D = 1; + mWhite = res.specColor; + SetPosAt(res.pos, res.aim); + mFlags |= 0x800; + mShininess = res.shininess; + return true; + } else { + ClearFlag2(); + return false; + } +} + +void LightObject::CalcDirDist() { + mDir.x = mAt.x - mPos.x; + mDir.y = mAt.y - mPos.y; + mDir.z = mAt.z - mPos.z; + mDist = nw4r::math::VEC3LenSq(&mDir); + if (mDist > 0.0f) { + nw4r::math::VEC3Scale(&mDir, &mDir, 1.0f / nw4r::math::FSqrt(mDist)); + } else { + mDir.x = mDir.y = mDir.z = 0.0f; + } +} + +void LightObject::CalcAt() { + mAt.x = mPos.x + mDir.x * mDist; + mAt.y = mPos.y + mDir.y * mDist; + mAt.z = mPos.z + mDir.z * mDist; +} + +void LightObject::SetPos(const nw4r::math::VEC3 &pos) { + mPos = pos; + CalcDirDist(); +} + +void LightObject::SetAt(const nw4r::math::VEC3 &at) { + mAt = at; + CalcDirDist(); +} + +void LightObject::SetDist(f32 dist) { + mDist = dist; + CalcAt(); +} + +void LightObject::SetPosAt(nw4r::math::VEC3 const &pos, nw4r::math::VEC3 const &at) { + mPos = pos; + mAt = at; + CalcDirDist(); +} + +void LightObject::SetBinaryInner(const Bin &bin) {} + +void LightObject::GetBinaryInner(Bin *bin) const {} + +void LightObject::SetBinaryInner(const Bin &bin1, const Bin &bin2, f32 blend) {} + +} // namespace EGG diff --git a/src/egg/gfx/eggLightTexture.cpp b/src/egg/gfx/eggLightTexture.cpp index 174c6584..114da7da 100644 --- a/src/egg/gfx/eggLightTexture.cpp +++ b/src/egg/gfx/eggLightTexture.cpp @@ -1,3 +1,748 @@ #include "egg/gfx/eggLightTexture.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/core/eggHeap.h" +#include "egg/gfx/eggCapTexture.h" +#include "egg/gfx/eggCpuTexture.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggLightObject.h" +#include "egg/gfx/eggLightTextureMgr.h" +#include "egg/gfx/eggStateGX.h" +#include "nw4r/g3d/g3d_light.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXBump.h" +#include "rvl/GX/GXGeometry.h" +#include "rvl/GX/GXTev.h" +#include "rvl/GX/GXTransform.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/GX/GXVert.h" +#include "rvl/MTX/mtx.h" +#include "rvl/MTX/mtx44.h" + +#include + +namespace EGG { + +#define NUM_CPU_TEX 18 + +static CpuTexture *sCpuTexArray[NUM_CPU_TEX]; + +u16 LightTexture::sDrawWidth; +u16 LightTexture::sDrawHeight; +u16 LightTexture::sDrawPosX; +u16 LightTexture::sDrawPosY; +u16 LightTexture::sTexWidth; +u16 LightTexture::sTexHeight; +u16 LightTexture::sDrawNumX; +u16 LightTexture::sDrawNumY; + +CpuTexture *LightTexture::spNormalEnvironment; + +bool LightTexture::sUseDebug; + +u16 LightTexture::sTextureSize = 0x20; + +static s8 lbl_80574F3A = 0xFE; + +template <> +const char *IBinary::GetBinaryType() { + return "LTEX"; +} + +template <> +int IBinary::GetVersion() { + return 3; +} + +void LightTexture::fn_804AB270() { + GXSetNumChans(1); + GXSetCullMode(GX_CULL_BACK); + GXSetChanCtrl(GX_COLOR0A0, false, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_SIGN, GX_AF_NONE); + GXSetChanCtrl(GX_COLOR1A1, false, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); + GXSetZMode(false, GX_LEQUAL, false); + EGG::DrawGX::SetBlendMode(DrawGX::BLEND_14); +} + +void LightTexture::fn_804AB310(const GXColor &color) { + GXSetNumTexGens(0); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, 0, 0x7d); + GXSetNumIndStages(0); + GXSetNumTevStages(1); + GXSetTevDirect(GX_TEVSTAGE0); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevKColor(GX_KCOLOR0, color); + GXSetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); + GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_1); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_KONST); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_KONST); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + EGG::DrawGX::SetBlendMode(DrawGX::BLEND_14); +} + +static const GXTevColorArg sTevkColorArg[3] = {GX_CC_C0, GX_CC_C1, GX_CC_C2}; +static const GXTevKColorSel sTevkColorSel[3] = {GX_TEV_KCSEL_K0, GX_TEV_KCSEL_K1, GX_TEV_KCSEL_K2}; +static const GXIndTexMtxID sIndTexMtxId[3] = {GX_ITM_0, GX_ITM_1, GX_ITM_2}; + +void LightTexture::fn_804AB440() { + GXSetNumTexGens(1); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, 0, 0x7d); + GXSetNumIndStages(1); + GXSetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD0, GX_TEXMAP0); + GXSetIndTexCoordScale(GX_INDTEXSTAGE0, GX_ITS_1, GX_ITS_1); + GXSetNumTevStages(3); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + + for (int i = 0; i < 3; i++) { + GXTevStageID id = static_cast(GX_TEVSTAGE0 + i); + GXTevColorArg tevColorArg = id == GX_TEVSTAGE0 ? GX_CC_ZERO : GX_CC_CPREV; + + GXSetTevSwapMode(id, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(id, GX_TEXCOORD_NULL, static_cast(GX_TEXMAP1 + i), GX_COLOR_NULL); + GXSetTevKColorSel(id, sTevkColorSel[i]); + GXSetTevKAlphaSel(id, GX_TEV_KASEL_1); + GXSetTevColorIn(id, GX_CC_KONST, sTevkColorArg[i], GX_CC_TEXC, tevColorArg); + GXSetTevColorOp(id, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_KONST); + GXSetTevAlphaOp(id, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevIndirect( + id, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_STU, sIndTexMtxId[i], GX_ITW_0, GX_ITW_0, false, false, GX_ITBA_OFF + ); + } + EGG::DrawGX::SetBlendMode(DrawGX::BLEND_2); +} + +void LightTexture::fn_804AB600() { + GXSetNumTexGens(2); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, 0, 0x7d); + GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0, 0x1e, 0, 0x7d); + GXSetNumIndStages(0); + GXSetNumTevStages(2); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + for (int i = 0; i < 2; i++) { + GXTevStageID id = static_cast(GX_TEVSTAGE0 + i); + GXTevColorArg tevColorArg = id == GX_TEVSTAGE0 ? GX_CC_ZERO : GX_CC_CPREV; + + GXSetTevOrder( + id, static_cast(GX_TEXCOORD0 + i), static_cast(GX_TEXMAP0 + i), GX_COLOR_NULL + ); + GXSetTevKColorSel(id, sTevkColorSel[i]); + GXSetTevKAlphaSel(id, GX_TEV_KASEL_1); + GXSetTevColorIn(id, GX_CC_KONST, sTevkColorArg[i], GX_CC_TEXC, tevColorArg); + GXSetTevColorOp(id, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_KONST); + GXSetTevAlphaOp(id, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevDirect(id); + } + EGG::DrawGX::SetBlendMode(DrawGX::BLEND_2); +} + +void LightTexture::initialize(u16 textureSize, Heap *pHeap) { + static const int sCpuTexGradientOp[NUM_CPU_TEX] = {0, 0, 0, 1, 2, 3, 4, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0}; + + if (pHeap == nullptr) { + pHeap = Heap::getCurrentHeap(); + } + sTextureSize = textureSize; + for (int i = 0; i < NUM_CPU_TEX; i++) { + sCpuTexArray[i] = new (pHeap) CpuTexture(64, 4, i < 10 ? GX_TF_I8 : GX_TF_RGBA8); + CpuTexture *tex = sCpuTexArray[i]; + tex->configure(); + tex->setWrapS(GX_REPEAT); + tex->setWrapT(GX_REPEAT); + u16 a = 32; + u16 b = 64; + switch (i) { + case 1: a = 0; break; + case 2: a = 16; break; + case 7: + a = 4; + b = 36; + break; + case 8: + a = 10; + b = 42; + break; + case 9: + a = 13; + b = 45; + break; + } + tex->allocate(pHeap); + tex->fillGradient(sCpuTexGradientOp[i], 0x73, a + 1, b - 1, DrawGX::BLACK, DrawGX::WHITE, true, true); + } + if (sTextureSize == 0x100) { + lbl_80574F3A = 1; + } else if (sTextureSize == 0x80) { + lbl_80574F3A = 0; + } else if (sTextureSize == 0x40) { + lbl_80574F3A = -1; + } else if (sTextureSize == 0x20) { + lbl_80574F3A = -2; + } else if (sTextureSize == 0x10) { + lbl_80574F3A = -3; + } else if (sTextureSize == 0x8) { + lbl_80574F3A = -4; + } else if (sTextureSize == 0x4) { + lbl_80574F3A = -5; + } + + spNormalEnvironment = new (pHeap) CpuTexture(sTextureSize, sTextureSize, GX_TF_RGBA8); + spNormalEnvironment->configure(); + spNormalEnvironment->allocate(pHeap); + spNormalEnvironment->fillNormalMapSphere(1.0f, 0.5f); + spNormalEnvironment->setFilt(GX_NEAR, GX_NEAR); + spNormalEnvironment->setWrap(GX_REPEAT, GX_REPEAT); +} + +LightTexture::LightTexture(const char *name, const LightTextureManager *mgr) + : CapTexture(sTextureSize, sTextureSize, GX_TF_RGBA8) { + mpMgr = mgr; + mNumData = mgr->getMaxNumLightTextures(); + field_0x35 = 0; + field_0x36 = 0; + mLightType = 0; + field_0x38.set(0.0f, 0.0f, 0.0f); + mpFloatData = nullptr; + mpByteData1 = nullptr; + mpByteData2 = nullptr; + field_0x50 = 1.0f; + field_0x94 = 0; + field_0x98 = 1.0f; + + size_t len = std::strlen(name); + if (len >= 0x1F) { + len = 0x1E; + } + int i = 0; + for (; i < len; i++) { + mName1[i] = name[i]; + } + mName1[len] = '\0'; + + for (size_t i = 0; i < sizeof(mName2); i++) { + mName2[i] = '\0'; + } + field_0x9C = 0; + mpFloatData = new float[mNumData]; + mpByteData1 = new u8[mNumData]; + mpByteData2 = new u8[mNumData]; + for (int i = 0; i < mNumData; i++) { + mpByteData2[i] = 0; + mpFloatData[i] = 1.0f; + mpByteData1[i] = 0; + } +} + +LightTexture::~LightTexture() { + delete[] mpFloatData; + delete[] mpByteData1; + delete[] mpByteData2; +} + +void LightTexture::configure() { + CapTexture::configure(); + if (sUseDebug) { + allocWithHeaderDebug(nullptr); + } else { + allocate(nullptr); + } + setWrap(GX_CLAMP, GX_CLAMP); + setPixModeSync(false); +} + +void LightTexture::loadTextureData(int index, void *data, GXTexFmt fmt) { + CpuTexture *pTex = sCpuTexArray[index]; + CpuTexture tmpTex(64, 4, fmt); + tmpTex.configure(); + tmpTex.setBuffer(data); + for (u32 y = 0; y < 4; y++) { + for (int x = 0; x < 32; x++) { + pTex->setColor(x, y, tmpTex.getColor(x + 32, y)); + } + for (int x = 0; x < 32; x++) { + pTex->setColor(x + 32, y, tmpTex.getColor(x, y)); + } + } + pTex->flush(); +} + +void LightTexture::loadTextureFromResTimg(int index, EGG::ResTIMG *img) { + loadTextureData(index, img + 1, static_cast(img->format)); +} + +void LightTexture::initDrawSetting(u16 u1, u16 u2, u16 u3, u16 u4) { + static const u8 ALIGN_DECL(32) sVtxBuf[] = {0, 0, 0, 1, 1, 1, 1, 0}; + + nw4r::math::MTX44 mtx; + C_MTXOrtho(mtx, u4, 0.0f, 0.0f, u3, 0.0f, 1.0f); + StateGX::GXSetProjection_(mtx, GX_ORTHOGRAPHIC); + StateGX::GXSetViewport_(u1, u2, u3, u4, 0.0f, 1.0f); + StateGX::GXSetScissor_(u1, u2, u3, u4); + StateGX::GXSetScissorBoxOffset_(0, 0); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_INDEX8); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetArray(GX_VA_POS, sVtxBuf, 2); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGB, GX_RGB565, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_F32, 0); + + sTexWidth = sTextureSize; + sDrawNumX = u3 / sTextureSize; + sTexHeight = sTextureSize; + sDrawNumY = u4 / sTextureSize; + sDrawWidth = u3; + sDrawHeight = u4; + sDrawPosX = u1; + sDrawPosY = u2; + + fn_804AB270(); + GXSetCurrentMtx(0); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); +} + +void LightTexture::getTexDimensions(u16 *x, u16 *y, u16 *w, u16 *h, u16 count) { + *x = sDrawPosX; + *y = sDrawPosY; + + u16 s1 = count / (sDrawNumX + 1); + u16 wp = (count - s1 * sDrawNumX); + *w = wp * sTexWidth; + *h = (s1 + 1) * sTexHeight; +} + +void LightTexture::fn_804AC0A0(int i, int *x, int *y) { + *y = i / sDrawNumX; + *x = sTexWidth * (i % sDrawNumX); + *y *= sTexHeight; +} + +static const nw4r::math::MTX34 sIdentityMtx(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); + +void LightTexture::fn_804AC0E0(int i, const GXColor &color, bool b) { + field_0x9F = 0; + field_0x9C = 1; + int w, h; + fn_804AC0A0(i, &w, &h); + + nw4r::math::MTX34 mtx = sIdentityMtx; + mtx._00 *= sTexWidth; + mtx._11 *= sTexHeight; + mtx._03 = w; + mtx._13 = sDrawHeight - (h + sTexHeight); + + GXLoadPosMtxImm(mtx, 0); + GXLoadTexMtxImm(sIdentityMtx, 0x1E, GX_MTX_2x4); + + GXColor c; + if ((field_0x36 & 1) != 0) { + const nw4r::g3d::AmbLightObj &obj = mpMgr->GetAmbientObj(field_0x35); + c.r = obj.r; + c.g = obj.g; + c.b = obj.b; + c.a = obj.a; + + c.r = c.r * field_0x50; + c.g = c.g * field_0x50; + c.b = c.b * field_0x50; + c.a = 0xFF; + } else { + c = DrawGX::BLACK; + } + + fn_804AB310(c); + + f32 origin = 0.0f; + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + f32 d = 0.99f; + + GXPosition1x8(0); + GXPosition2f32(origin, origin); + + GXPosition1x8(1); + GXPosition2f32(origin, origin - d); + + GXPosition1x8(2); + GXPosition2f32(d + origin, origin - d); + + GXPosition1x8(3); + GXPosition2f32(d + origin, origin); + + switch (mLightType) { + case 0: + case 2: + spNormalEnvironment->load(GX_TEXMAP0); + fn_804AB440(); + field_0x9D = 3; + field_0x9E = 1; + break; + + case 1: + fn_804AB600(); + field_0x9D = 2; + field_0x9E = 0; + break; + } + + for (int i = 0; i < mpMgr->getMaxNumLightTextures(); i++) { + if (mpMgr->GetLightObject(i) == nullptr) { + break; + } + addLight(*mpMgr->GetLightObject(i)); + } + + int remainder = field_0x9F % field_0x9D; + if (remainder > 0) { + for (; remainder < field_0x9D; remainder++) { + DrawGX::SetTevColor( + static_cast(GX_TEVREG0 + remainder), DrawGX::BLACK, + static_cast(GX_KCOLOR0 + remainder), DrawGX::BLACK + ); + } + + f32 origin = GetLightType() != 2 ? 0.0f : 0.5f; + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + f32 d = 0.99f; + GXPosition1x8(0); + GXPosition2f32(origin, origin); + + GXPosition1x8(1); + GXPosition2f32(origin, origin - d); + + GXPosition1x8(2); + GXPosition2f32(d + origin, origin - d); + + GXPosition1x8(3); + GXPosition2f32(d + origin, origin); + } + + field_0x9C = 2; + if (b) { + onCapFlag(1); + onCapFlag(2); + setClearColor(color); + } else { + offCapFlag(1); + offCapFlag(2); + } + capture(sDrawPosX + w, sDrawPosY + h, false, -1); + field_0x9C = 0; +} + +void LightTexture::draw(int i) { + if ((field_0x36 & 2) == 0) { + return; + } + + LightTexture *other = mpMgr->getTextureByName(mName2); + if (other == nullptr) { + return; + } + field_0x9F = 0; + int w, h; + fn_804AC0A0(i, &w, &h); + load(GX_TEXMAP0); + other->load(GX_TEXMAP1); + DrawGX::SetMat_ColorChannel(DrawGX::COLORCHAN_1); + DrawGX::SetMat_TexGen(DrawGX::TEXGEN_1); + DrawGX::SetMat_Ind(); + DrawGX::SetMat_PE(DrawGX::ZMODE_0, DrawGX::BLEND_14); + GXSetNumTevStages(2); + u8 val = field_0x98 * 255.0f; + GXSetTevColor(GX_TEVREG0, (GXColor){val, val, val, val}); + GXSetTevDirect(GX_TEVSTAGE0); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP1, GX_COLOR_NULL); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ONE, GX_CC_TEXC, GX_CC_C0, GX_CC_ZERO); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevDirect(GX_TEVSTAGE1); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_CPREV, GX_CC_TEXC, GX_CC_ZERO); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + + nw4r::math::MTX34 mtx = sIdentityMtx; + mtx._00 *= sTexWidth; + mtx._11 *= sTexHeight; + mtx._03 = w; + mtx._13 = sDrawHeight - (h + sTexHeight); + + GXLoadPosMtxImm(mtx, 0); + GXLoadTexMtxImm(sIdentityMtx, 0x1E, GX_MTX_2x4); + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + + GXPosition1x8(0); + GXPosition2f32(0.0f, 1.0f); + + GXPosition1x8(1); + GXPosition2f32(0.0f, 0.0f); + + GXPosition1x8(2); + GXPosition2f32(1.0f, 0.0f); + + GXPosition1x8(3); + GXPosition2f32(1.0f, 1.0f); + + capture(sDrawPosX + w, sDrawPosY + h, false, -1); +} + +void LightTexture::beginDebugDraw() { + DrawGX::SetMat_ColorChannel(DrawGX::COLORCHAN_1); + DrawGX::SetMat_TexGen(DrawGX::TEXGEN_1); + DrawGX::SetMat_Ind(); + DrawGX::SetMat_PE(DrawGX::ZMODE_0, DrawGX::BLEND_14); + GXSetNumTevStages(1); + GXSetTevDirect(GX_TEVSTAGE0); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); +} + +void LightTexture::debugDraw(int i) { + StateGX::ScopedDither ditherGuard(false); + field_0x9F = 0; + int u1, u2; + fn_804AC0A0(i, &u1, &u2); + load(GX_TEXMAP0); + nw4r::math::MTX34 mtx; + PSMTXScale(mtx, sTexWidth, sTexHeight, 1.0f); + + mtx._03 = u1; + mtx._13 = sDrawHeight - (u2 + sTexHeight); + + GXLoadPosMtxImm(mtx, 0); + GXLoadTexMtxImm(sIdentityMtx, 0x1E, GX_MTX_2x4); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + + GXPosition1x8(0); + GXPosition2f32(0.0f, 1.0f); + + GXPosition1x8(1); + GXPosition2f32(0.0f, 0.0f); + + GXPosition1x8(2); + GXPosition2f32(1.0f, 0.0f); + + GXPosition1x8(3); + GXPosition2f32(1.0f, 1.0f); +} + +void LightTexture::addLight(const EGG::LightObject &obj) { + if (!(obj.CheckFlag1() && obj.CheckFlag0x20() && (mpByteData1[obj.GetIndex()] & 1) != 0 && + (field_0x9F < 2 || mLightType != 1))) { + return; + } + + nw4r::math::VEC3 vec; + GXColor color; + obj.fn_804A9C30(this, &vec, &color); + int remainder = field_0x9F % field_0x9D; + if (field_0x9F == field_0x9D) { + GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR); + } + sCpuTexArray[mpByteData2[obj.GetIndex()]]->load(static_cast(field_0x9E + remainder)); + + GXColor blk = obj.GetBlack(); + f32 mult = obj.getField0x30(); + blk = (GXColor){blk.r * mult, blk.g * mult, blk.b * mult, obj.GetBlack().a}; + + DrawGX::SetTevColor( + static_cast(GX_TEVREG0 + remainder), color, static_cast(GX_KCOLOR0 + remainder), blk + ); + if (GetLightType() == 0 || GetLightType() == 2) { + f32 mtx[2][3]; + mtx[0][0] = -vec.x * 0.485f; + mtx[0][1] = -vec.y * 0.485f; + mtx[0][2] = -vec.z * 0.485f; + mtx[1][0] = 0.0f; + mtx[1][1] = 0.0f; + mtx[1][2] = 0.0f; + + GXSetIndTexMtx(sIndTexMtxId[remainder], mtx, -1); + } + + if (remainder == field_0x9D - 1) { + f32 v = GetLightType() != 2 ? 0.0f : 0.5f; + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + + GXPosition1x8(0); + GXPosition2f32(v, v); + + GXPosition1x8(1); + GXPosition2f32(v, v - 0.99f); + + GXPosition1x8(2); + GXPosition2f32(v + 0.99f, v - 0.99f); + + GXPosition1x8(3); + GXPosition2f32(v + 0.99f, v); + } + + field_0x9F++; +} +void LightTexture::SetBinaryInner(const Bin &bin) { + switch (bin.mHeader.mVersion) { + case 0: { + const struct Data { + /* 0x00 */ u16 mNumEntries; + /* 0x02 */ u8 _pad_02[2]; + /* 0x04 */ char mName[32]; + /* 0x24 */ u8 mType; + /* 0x25 */ u8 _pad_25[3]; + /* 0x28 */ u32 field_0x28; + /* 0x2C */ SubData mSubData[1]; + } &data = *(const Data *)&bin.mData; + mLightType = data.mType; + int numData = (u16)MIN(data.mNumEntries, (u16)mNumData); + + const SubData *pSub = data.mSubData; + for (int i = 0; numData > 0; numData--, i++, pSub++) { + if (data.field_0x28 & (1 << i)) { + onByte1(i); + } else { + offByte1(i); + } + setFloat(i, pSub->mIntensity); + setByte2(i, pSub->mGradientUsed); + } + + field_0x35 = 0; + field_0x50 = 1.f; + field_0x36 &= ~1; + field_0x36 &= ~2; + mName2[0] = '\0'; + field_0x94 = -1; + + } break; + case 1: + case 2: { + const struct Data { + /* 0x00 */ u16 mNumEntries; + /* 0x02 */ u8 field_0x02; + /* 0x03 */ u8 field_0x03; + /* 0x04 */ char mName[32]; + /* 0x24 */ u8 mType; + /* 0x25 */ u8 _pad_25[3]; + /* 0x28 */ u32 field_0x28; + /* 0x2C */ f32 field_0x2C; + /* 0x30 */ u8 _30[8]; + /* 0x38 */ SubData mSubData[1]; + } &data = *(const Data *)&bin.mData; + + mLightType = data.mType; + int numData = (u16)MIN(data.mNumEntries, (u16)mNumData); + + const SubData *pSub = data.mSubData; + for (int i = 0; numData > 0; numData--, i++, pSub++) { + if (bin.mHeader.mVersion == 1) { + if (data.field_0x28 & (1 << i)) { + onByte1(i); + } else { + offByte1(i); + } + } else if (pSub->field_0x05 & 1) { + onByte1(i); + } else { + offByte1(i); + } + setFloat(i, pSub->mIntensity); + setByte2(i, pSub->mGradientUsed); + } + + if (data.field_0x02 & 1) { + field_0x36 |= 1; + } else { + field_0x36 &= ~1; + } + + field_0x35 = data.field_0x03; + field_0x50 = data.field_0x2C; + field_0x36 &= ~2; + mName2[0] = '\0'; + field_0x94 = -1; + field_0x98 = 1.f; + + } break; + case 3: { + const BinData &data = bin.mData; + mLightType = data.mType; + int numData = (u16)MIN(data.mNumEntries, (u16)mNumData); + + const SubData *pSub = data.mSubData; + for (int i = 0; numData > 0; numData--, i++, pSub++) { + if (bin.mHeader.mVersion == 1) { + if (data.field_0x28 & (1 << i)) { + onByte1(i); + } else { + offByte1(i); + } + } else if (pSub->field_0x05 & 1) { + onByte1(i); + } else { + offByte1(i); + } + setFloat(i, pSub->mIntensity); + setByte2(i, pSub->mGradientUsed); + } + + if (data.field_0x02 & 1) { + field_0x36 |= 1; + } else { + field_0x36 &= ~1; + } + field_0x35 = data.field_0x03; + field_0x50 = data.field_0x2C; + + if (data.field_0x02 & 2) { + field_0x36 |= 2; + } else { + field_0x36 &= ~2; + } + std::strcpy(mName2, data.mName2); + field_0x94 = -1; + field_0x98 = data.field_0x54; + } break; + } +} + +void LightTexture::GetBinaryInner(Bin *pOutBin) const { + pOutBin->mData.mType = mLightType; + pOutBin->mData.mNumEntries = mNumData; + std::strncpy(pOutBin->mData.mName, mName1, sizeof(mName1)); + SubData *dat = pOutBin->mData.mSubData; + for (int i = 0; i < mNumData; i++) { + dat[i].field_0x05 = 0; + if (getByte1(i) & 1) { + dat[i].field_0x05 |= 1; + } + dat[i].mIntensity = getFloat(i); + dat[i].mGradientUsed = getByte2(i); + } + pOutBin->mData.field_0x02 = 0; + if (field_0x36 & 1) { + pOutBin->mData.field_0x02 |= 1; + } + if (field_0x36 & 2) { + pOutBin->mData.field_0x02 |= 2; + } + pOutBin->mData.field_0x03 = field_0x35; + pOutBin->mData.field_0x2C = field_0x50; + std::strcpy(pOutBin->mData.mName2, mName2); + pOutBin->mData.field_0x54 = field_0x98; +} + +size_t LightTexture::GetBinarySize() const { + return sizeof(Bin) + (mNumData - 1) * sizeof(SubData); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggLightTextureMgr.cpp b/src/egg/gfx/eggLightTextureMgr.cpp index 6d8d0928..17f28c6d 100644 --- a/src/egg/gfx/eggLightTextureMgr.cpp +++ b/src/egg/gfx/eggLightTextureMgr.cpp @@ -1,3 +1,331 @@ #include "egg/gfx/eggLightTextureMgr.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggG3DUtility.h" +#include "egg/gfx/eggLightObject.h" +#include "egg/gfx/eggLightTexture.h" +#include "egg/gfx/eggStateGX.h" +#include "egg/gfx/eggTextureBuffer.h" +#include "nw4r/g3d/res/g3d_resmat.h" +#include "nw4r/math/math_types.h" +#include "nw4r/ut/ut_Color.h" +#include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtx.h" +#include "rvl/MTX/mtx44.h" + +#include + +namespace EGG { + +LightTextureManager::LightTextureManager(const LightManager *lightMgr) { + mFlags = 0x78; + mTextureCount = 0; + mpTextures = nullptr; + mpLightMgr = lightMgr; + field_0x10 = 0; + mMaxNumTextures = 0x80; + field_0x16 = 1; + mpObjects = nullptr; + mpTextures = new LightTexture *[0x80]; + for (int i = 0; i < 0x80; i++) { + mpTextures[i] = nullptr; + } + + mpObjects = new const LightObject *[mMaxNumTextures]; + for (int i = 0; i < mMaxNumTextures; i++) { + mpObjects[i] = nullptr; + } + + if ((StateGX::s_flag & 0x40) != 0) { + mFlags |= 0x80; + mFlags &= ~0x40; + field_0x16 = 3; + } +} + +LightTextureManager::~LightTextureManager() { + for (int i = 0; i < 0x80; i++) { + deleteTexture(i); + } + delete[] mpTextures; + delete[] mpObjects; +} + +u16 LightTextureManager::createTexture(const char *name) { + // Check if one already exists with the same name + for (int i = 0; i < getNumLightTextures(); i++) { + if (mpTextures[i] != nullptr && !strcmp(name, mpTextures[i]->getName())) { + return i; + } + } + + // Find a hole to fill + int targetPosition = getNumLightTextures(); + for (int i = 0; i < getNumLightTextures(); i++) { + if (mpTextures[i] == nullptr) { + targetPosition = i; + } + } + if (targetPosition == getNumLightTextures()) { + mTextureCount++; + } + LightTexture *tex = new LightTexture(name, this); + mpTextures[targetPosition] = tex; + tex->configure(); + return targetPosition; +} + +u16 LightTextureManager::createTextureFromBin(const void *bin) { + const LightTexture::Bin *data = reinterpret_cast(bin); + u16 idx = createTexture(data->mData.mName); + mpTextures[idx]->SetBinary(data); + return idx; +} + +int LightTextureManager::createTexturesFromBin(const void *bin) { + const LightTextureManager::Bin *data = reinterpret_cast(bin); + // Moderate inefficiency here - this algorithm has quadratic runtime + // since we always search from the beginning + for (int i = 0; i < data->mData.mDataCount; i++) { + const void *subData = getLtexFromLmap(data, (u16)i); + createTextureFromBin(subData); + } + return data->mData.mDataCount; +} + +bool LightTextureManager::deleteTexture(int idx) { + if (0 <= idx && idx < 0x80) { + if (mpTextures[idx] != nullptr) { + delete mpTextures[idx]; + mpTextures[idx] = nullptr; + return true; + } + } + return false; +} + +u16 LightTextureManager::replaceModelTextures(nw4r::g3d::ResMdl mdl) const { + u16 count = 0; + for (u16 i = 0; i < mTextureCount; i++) { + count += replaceModelTexture(i, mdl); + } + return count; +} + +u16 LightTextureManager::replaceModelTexture(int tex, nw4r::g3d::ResMdl mdl) const { + if (mpTextures[tex] == nullptr) { + return 0; + } + + G3DUtility::SetTextureResult buf[256]; + GXTexObj obj; + mpTextures[tex]->getTexObj(&obj); + u16 count = 0; + for (int i = 0; i < mdl.GetResMatNumEntries(); i++) { + nw4r::g3d::ResMat mat = mdl.GetResMat(i); + + u16 res = G3DUtility::SetTexture(mat, nullptr, mpTextures[tex]->getName(), &obj, false, buf, 0xFF, 2); + for (int j = 0; j < res; j++) { + if (buf[j].texCoordId != -1) { + fn_804AE340(mat, static_cast(buf[j].texCoordId)); + } + } + count += res; + } + return count; +} + +int LightTextureManager::getTextureIndex(const char *name) const { + for (int i = 0; i < mTextureCount; i++) { + if (!strcmp(name, mpTextures[i]->getName())) { + return i; + } + } + + return -1; +} + +bool LightTextureManager::setBinaryToTexture(const void *data) { + const LightTexture::Bin *bin = reinterpret_cast(data); + for (int i = 0; i < getNumLightTextures(); i++) { + if (!std::strcmp(bin->mData.mName, mpTextures[i]->getName())) { + mpTextures[i]->SetBinary(bin); + return true; + } + } + return false; +} + +void LightTextureManager::correctLightObject() { + int j = 0; + for (int i = 0; i < mpLightMgr->GetNumLightData(); i++) { + const LightObject *o = mpLightMgr->GetLightObject((u16)i); + if (o->CheckFlag1() && o->CheckFlag0x20()) { + mpObjects[j] = o; + j++; + if (j >= mMaxNumTextures) { + break; + } + } + } + + for (int i = j; i < mMaxNumTextures; i++) { + mpObjects[i] = nullptr; + } +} + +void LightTextureManager::frameReset() { + correctLightObject(); + field_0x10 = 0; +} + +void LightTextureManager::drawAndCaptureTexture(f32 ox, f32 oy, f32 sx, f32 sy) { + bool b1 = getSomeTfRelatedBool(); + u32 mask1 = 1 << (mpLightMgr->GetField0x1D()); + if ((mFlags & 0x10) == 0 || (field_0x10 & mask1) != 0 || mTextureCount == 0) { + return; + } + + StateGX::resetGXCache(); + if ((mFlags & 0x40) != 0) { + ox = 0.0f; + oy = StateGX::s_heightEfb; + sx = StateGX::s_widthEfb; + sy = 528 - StateGX::s_heightEfb; + } + field_0x10 |= mask1; + + StateGX::ScopedColor colorGuard(true); + StateGX::ScopedAlpha alphaGuard(false); + + LightTexture::initDrawSetting(ox + ((u16)ox & 1), oy + ((u16)oy & 1), sx, sy); + + u16 x1, y1, x2, y2; + TextureBuffer *buf = nullptr; + LightTexture::getTexDimensions(&x1, &y1, &x2, &y2, mTextureCount); + x2 += x2 & 3; + y2 += y2 & 3; + + if ((mFlags & 0x40) == 0 && (mFlags & 4) != 0) { + buf = TextureBuffer::alloc(x2, y2, GX_TF_RGBA8); + buf->capture(x1, y1, false, -1); + } + + if (b1) { + StateGX::GXSetPixelFmt_(GX_PF_RGB8_Z24, GX_ZC_LINEAR); + } + + nw4r::ut::Color c(StateGX::s_clearEfb); + if (b1 && StateGX::s_pixFormat == GX_PF_RGBA6_Z24) { + // convert GX_PF_RGBA6_Z24 -> GX_PF_RGB8_Z24 + u8 tmp = c.a >> 2; + c = ((c.r >> 2) << 26) | (c.g & 0x3FFC) << 18 | (c.b & 0xFC) << 12 | (tmp & 0x3F) << 8; + } + + bool b2 = b1 && (mFlags & 8) != 0; + for (int i = 0; i < mTextureCount; i++) { + mpTextures[i]->fn_804AC0E0(i, c, b2); + } + + for (int i = 0; i < mTextureCount; i++) { + mpTextures[i]->draw(i); + } + + if (b1) { + StateGX::GXSetPixelFmt_(StateGX::s_pixFormat, StateGX::s_zFmt16); + } + + if ((mFlags & 0x40) == 0 && buf != nullptr) { + StateGX::ScopedColor colorGuard(true); + StateGX::ScopedAlpha alphaGuard(true); + nw4r::math::MTX44 orthMtx; + C_MTXOrtho(orthMtx, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f); + StateGX::GXSetProjection_(orthMtx, GX_ORTHOGRAPHIC); + StateGX::GXSetViewport_(x1, y1, x2, y2, 0.0f, 1.0f); + StateGX::GXSetScissor_(x1, y1, x2, y2); + StateGX::GXSetScissorBoxOffset_(0, 0); + nw4r::math::MTX34 identity; + PSMTXIdentity(identity); + + DrawGX::BeginDrawScreen(1, 1, 0); + DrawGX::SetBlendMode(DrawGX::BLEND_14); + GXSetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); + buf->load(GX_TEXMAP0); + DrawGX::DrawDL(DrawGX::DL_16, identity, DrawGX::WHITE); + buf->free(); + } + + StateGX::invalidateTexAllGX(); + if ((mFlags & 0x80) != 0) { + LightTexture::beginDebugDraw(); + for (int i = 0; i < mTextureCount; i++) { + mpTextures[i]->debugDraw(i); + } + } +} + +void LightTextureManager::SetBinaryInner(const Bin &bin) { + if (bin.mHeader.mVersion != 0) { + return; + } + const char *buf = reinterpret_cast(bin.mData.mSubData); + for (int i = 0; i < bin.mData.mDataCount; i++) { + const BinHeader *hdr = reinterpret_cast(buf); + setBinaryToTexture(buf); + buf += hdr->mSize; + } +} + +void LightTextureManager::GetBinaryInner(Bin *pOutBin) const { + int count = 0; + char *buf = reinterpret_cast(pOutBin->mData.mSubData); + for (int i = 0; i < getNumLightTextures(); i++) { + mpTextures[i]->GetBinary(buf); + BinHeader *hdr = reinterpret_cast(buf); + // This is where the actually written size is added to the whole object + pOutBin->mHeader.mSize += hdr->mSize; + buf += hdr->mSize; + count++; + } + pOutBin->mData.mDataCount = count; +} + +// Performs a linear search through the data to find the offset for the given index +const void *LightTextureManager::getLtexFromLmap(const void *lmap, u16 index) { + // A bit awkward but it matches + const BinHeader *buf = nullptr; + const Bin *bin = reinterpret_cast(lmap); + if (bin->mHeader.mVersion == 0 && index < bin->mData.mDataCount) { + buf = bin->mData.mSubData; + for (int i = 0; i < index; i++) { + buf = reinterpret_cast(reinterpret_cast(buf) + buf->mSize); + } + } + + return buf; +} + +void LightTextureManager::fn_804AE340(nw4r::g3d::ResMat mat, GXTexCoordID id) { + nw4r::g3d::ResTexSrt dat = mat.GetResTexSrt(); + dat.SetMapMode(id, 1, -1, -1); + nw4r::g3d::ResMatTexCoordGen coordGen = mat.GetResMatTexCoordGen(); + + GXTexGenType type; + GXTexGenSrc src; + GXBool normalize; + u32 postMtx; + coordGen.GXGetTexCoordGen2(id, &type, &src, &normalize, &postMtx); + coordGen.GXSetTexCoordGen2(id, GX_TG_MTX3x4, GX_TG_NRM, true, postMtx); + coordGen.DCStore(false); +} + +size_t LightTextureManager::GetBinarySize() const { + // Contrary to the other dynamically-sized Bins, this only + // returns the fixed size. GetBinaryInner will add the dynamic + // parts when writing. + return sizeof(Bin) - sizeof(BinHeader); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggModelEx.cpp b/src/egg/gfx/eggModelEx.cpp index 4fdaae07..14c10293 100644 --- a/src/egg/gfx/eggModelEx.cpp +++ b/src/egg/gfx/eggModelEx.cpp @@ -1,3 +1,179 @@ #include "egg/gfx/eggModelEx.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggAnalizeDL.h" +#include "egg/gfx/eggG3DUtility.h" +#include "egg/gfx/eggIScnProcModel.h" +#include "nw4r/g3d/g3d_calcworld.h" +#include "nw4r/g3d/g3d_scnmdl.h" +#include "nw4r/g3d/g3d_scnmdl1mat1shp.h" +#include "nw4r/g3d/g3d_scnmdlsmpl.h" +#include "nw4r/g3d/g3d_scnproc.h" +#include "nw4r/g3d/res/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resshp.h" +#include "nw4r/math/math_types.h" +#include "rvl/MTX/mtx.h" +#include "rvl/MTX/mtxvec.h" + +namespace EGG { + +using namespace nw4r; + +const char *ModelEx::sByteCodeCalcStr = "NodeTree"; +const char *ModelEx::sByteCodeMixStr = "NodeMix"; + +ModelEx::ModelEx(g3d::ScnObj *obj) + : mType(cType_None), mScnObj(g3d::G3dObj::DynamicCast(obj)), mFlag(0), mpBoundingInfo(nullptr) { + if (g3d::G3dObj::DynamicCast(mScnObj) != nullptr) { + mType = cType_ScnMdl; + } else if (g3d::G3dObj::DynamicCast(mScnObj) != nullptr) { + mType = cType_ScnMdlSimple; + } else if (g3d::G3dObj::DynamicCast(mScnObj) != nullptr) { + mType = cType_ScnMdl1Mat1Shp; + } +} + +static const f32 sFaceMin[] = {-22.61115f, -55.770135f, -45.93067f}; +static const f32 sFaceMax[] = {81.17467f, 49.677597f, 45.93065f}; + +static const f32 sNoneMin[] = {0.0f, 0.0f, 0.0f}; +static const f32 sNoneMax[] = {0.0f, 0.0f, 0.0f}; + +// Not sure what this was for but it didn't get stripped due to data pooling +static const G3DUtility::MdlSearch sMdlSearch[6] = { + G3DUtility::searchStringResNode, G3DUtility::searchStringResMat, G3DUtility::searchStringResTexPlttInfo, + G3DUtility::searchStringResNode, G3DUtility::searchStringResMat, G3DUtility::searchStringResTexPlttInfo, +}; + +void thisProbablyGotDeadStripped() { + sMdlSearch[0](g3d::ResMdl(nullptr), "", false, nullptr, 0); +} + +extern "C" s32 lbl_8057682C; + +void ModelEx::getShapeMinMax(u16 shapeIndex, math::VEC3 *pMin, math::VEC3 *pMax, bool doCalcWorld) { + switch (mType) { + case cType_ScnMdlSimple: + case cType_ScnMdl: + case cType_ScnMdl1Mat1Shp: { + g3d::ResShp shp = getResShp(shapeIndex); + + G3DUtility::ResetBumpAlloc(); + + g3d::ResMdl mdl = getResMdl(); + math::MTX34 tmpMtx; + g3d::ResMdlInfo info = mdl.GetResMdlInfo(); + math::MTX34 *pMtxArr = + reinterpret_cast(G3DUtility::BumpAlloc(info.GetNumPosNrmMtx() * sizeof(math::MTX34), 1)); + if (doCalcWorld) { + PSMTXIdentity(tmpMtx); + calcWorld(pMtxArr, &tmpMtx); + } + + s32 defaultMatrixIdx = shp.ref().curMtxIdx; + AnalizeDL analyze(shp); + + bool firstIteration = true; + AnalizeDL::Status status; + while ((status = analyze.step()) != AnalizeDL::STATUS_END) { + if (status != AnalizeDL::STATUS_VTX) { + continue; + } + + const AnalizeDL::VtxResult &result = analyze.getVtxResult(); + s32 mtxIdx = result.mMtxIdx; + if (mtxIdx == -1) { + mtxIdx = defaultMatrixIdx; + } + nw4r::math::VEC3 tmpVec; + PSMTXMultVec(pMtxArr[mtxIdx], &analyze.getVtxResult().field_0x08, tmpVec); + if (firstIteration) { + firstIteration = false; + *pMin = *pMax = tmpVec; + } else { + math::VEC3Minimize(pMin, pMin, &tmpVec); + math::VEC3Maximize(pMax, pMax, &tmpVec); + } + } + G3DUtility::ResetBumpAlloc(); + break; + } + case cType_ScnProcModel: + static_cast(static_cast(mScnObj)->GetUserData()) + ->getMinMaxScnProcModel(pMin, pMax); + break; + case cType_ScnRfl: { + const f32 *min = sFaceMin; + const f32 *max = sFaceMax; + pMin->x = min[0]; + pMin->y = min[1]; + pMin->z = min[2]; + pMax->x = max[0]; + pMax->y = max[1]; + pMax->z = max[2]; + break; + } + + case cType_None: + const f32 *min = sNoneMin; + const f32 *max = sNoneMax; + pMin->x = min[0]; + pMin->y = min[1]; + pMin->z = min[2]; + pMax->x = max[0]; + pMax->y = max[1]; + pMax->z = max[2]; + break; + } +} + +void ModelEx::calcWorld(math::MTX34 *pWorldMtxArray, const math::MTX34 *worldMtx) const { + switch (mType) { + case cType_ScnMdlSimple: + case cType_ScnMdl: { + g3d::ScnMdlSimple *pMdl = (g3d::ScnMdlSimple *)mScnObj; + // cast for regalloc + u32 *wldAttrib = (u32 *)pMdl->GetWldMtxAttribArray(); + g3d::ResMdl mdl = pMdl->GetResMdl(); + const math::MTX34 *worldMtx2 = worldMtx == nullptr ? pMdl->GetMtxPtr(g3d::ScnObj::MTX_WORLD) : worldMtx; + + g3d::CalcWorld( + pWorldMtxArray, wldAttrib, mdl.GetResByteCode(sByteCodeCalcStr), worldMtx2, mdl, nullptr, nullptr + ); + + if (mdl.GetResByteCode(sByteCodeMixStr) != nullptr) { + g3d::CalcSkinning(pWorldMtxArray, wldAttrib, mdl, mdl.GetResByteCode(sByteCodeMixStr)); + } + } break; + case cType_ScnMdl1Mat1Shp: + case cType_ScnProcModel: + case cType_ScnRfl: getMtxType0(pWorldMtxArray); break; + case cType_None: + default: break; + } +} + +g3d::ResMdl ModelEx::getResMdl() const { + g3d::ScnMdlSimple *mdl = getScnMdlSimple(); + if (mdl != nullptr) { + return mdl->GetResMdl(); + } + + return g3d::ResMdl(nullptr); +} + +g3d::ResShp ModelEx::getResShp(u16 shapeIndex) const { + g3d::ScnMdlSimple *mdl = getScnMdlSimple(); + if (mdl != nullptr) { + return mdl->GetResMdl().GetResShp(shapeIndex); + } + + g3d::ScnMdl1Mat1Shp *mdl1 = getScnMdl1Mat1Shp(); + if (mdl1 != nullptr) { + return mdl1->GetResShp(); + } + + return g3d::ResShp(nullptr); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggPalette.cpp b/src/egg/gfx/eggPalette.cpp index 425ecb04..bbe3205d 100644 --- a/src/egg/gfx/eggPalette.cpp +++ b/src/egg/gfx/eggPalette.cpp @@ -1,3 +1,23 @@ #include "egg/gfx/eggPalette.h" -namespace EGG {} // namespace EGG +namespace EGG { + +void Palette::storeTLUT(_GXTlut param_0, _GXTlutFmt param_1, JUTTransparency param_2, u16 param_3, void *param_4) { + mTlutName = param_0; + mFormat = param_1; + mTransparency = param_2; + mNumColors = param_3; + mColorTable = (ResTLUT *)param_4; + GXInitTlutObj(&mTlutObj, (void *)mColorTable, (GXTlutFmt)mFormat, mNumColors); +} + +bool Palette::load() { + bool check = mNumColors != 0; + if (check) { + GXLoadTlut(&mTlutObj, mTlutName); + } + + return check; +} + +} // namespace EGG diff --git a/src/egg/gfx/eggPostEffectBase.cpp b/src/egg/gfx/eggPostEffectBase.cpp index d1110185..e7dbd1cb 100644 --- a/src/egg/gfx/eggPostEffectBase.cpp +++ b/src/egg/gfx/eggPostEffectBase.cpp @@ -1,3 +1,164 @@ #include "egg/gfx/eggPostEffectBase.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggCapTexture.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggScreen.h" +#include "egg/math/eggVector.h" +#include "math.h" +#include "nw4r/math/math_triangular.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXBump.h" +#include "rvl/GX/GXDisplayList.h" +#include "rvl/GX/GXLight.h" +#include "rvl/GX/GXTransform.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtx.h" + +namespace EGG { + +PostEffectBase::PostEffectBase() + : field_0x00(0), + mTex1((CapTextureWrapper){nullptr, GX_TEXMAP0}), + mTex2((CapTextureWrapper){nullptr, GX_TEXMAP0}), + mOffsetX(0.0f), + mOffsetY(0.0f), + mScaleX(1.0f), + mScaleY(1.0f), + mRotation(0.0f) {} + +void PostEffectBase::draw(f32 width, f32 height) { + setMaterialInternal(); + setVtxState(); + drawScreenInternal(mOffsetX, mOffsetY, mScaleX * width, mScaleY * height); +} + +void PostEffectBase::fn_804AED20() { + draw(mTex1.mpTex->getWidth(), mTex1.mpTex->getHeight()); +} + +void PostEffectBase::setVtxState() { + DrawGX::SetVtxState(DrawGX::VTX_TYPE_11); +} + +void PostEffectBase::drawScreenInternal(f32 offsetX, f32 offsetY, f32 width, f32 height) { + nw4r::math::MTX34 mtx; + PSMTXScale(mtx, width, height, 1.0f); + mtx._03 = offsetX; + mtx._13 = offsetY; + mtx._23 = 0.0f; + GXLoadPosMtxImm(mtx, 0); + GXCallDisplayList(DrawGX::s_DL[DrawGX::DL_16].mpList, DrawGX::s_DL[DrawGX::DL_16].mLen); +} + +void PostEffectBase::loadTextureInternal() { + mTex1.mpTex->load(mTex1.mTexMapID); + if (mTex2.mpTex != nullptr) { + mTex2.mpTex->load(mTex2.mTexMapID); + } +} + +void PostEffectBase::setMatColorChannel() { + GXSetNumChans(0); + GXSetChanCtrl(GX_COLOR0A0, false, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_SIGN, GX_AF_NONE); + GXSetChanCtrl(GX_COLOR1A1, false, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_SIGN, GX_AF_NONE); + GXSetCullMode(GX_CULL_BACK); +} + +void PostEffectBase::setMatInd() { + GXSetNumIndStages(0); +} + +void PostEffectBase::setMatPE() { + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); + GXSetZMode(false, GX_ALWAYS, false); + static const GXColor black = {0, 0, 0, 0xFF}; + GXSetFog(GX_FOG_NONE, black, 0.0, 1.0, 0.0, 1.0); + setBlendModeInternal(); +} + +void PostEffectBase::setBlendModeInternal() { + switch (field_0x00) { + case 0: DrawGX::SetBlendMode(DrawGX::BLEND_14); break; + case 1: DrawGX::SetBlendMode(DrawGX::BLEND_0); break; + case 2: DrawGX::SetBlendMode(DrawGX::BLEND_2); break; + case 3: DrawGX::SetBlendMode(DrawGX::BLEND_4); break; + case 4: GXSetBlendMode(GX_BM_BLEND, GX_BL_DSTCLR, GX_BL_INVDSTCLR, GX_LO_CLEAR); break; + case 5: DrawGX::SetBlendMode(DrawGX::BLEND_5); break; + case 6: GXSetBlendMode(GX_BM_BLEND, GX_BL_INVSRCCLR, GX_BL_INVSRCCLR, GX_LO_CLEAR); break; + case 7: DrawGX::SetBlendMode(DrawGX::BLEND_3); break; + case 8: GXSetBlendMode(GX_BM_BLEND, GX_BL_INVSRCALPHA, GX_BL_ONE, GX_LO_CLEAR); break; + case 9: GXSetBlendMode(GX_BM_SUBTRACT, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); break; + case 10: DrawGX::SetBlendMode(DrawGX::BLEND_7); break; + case 11: GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ZERO, GX_LO_CLEAR); break; + } +} + +void PostEffectBase::scaleColor(GXColor &out, const GXColor &c, bool bClamp, f32 amount) { + f32 fs[4]; + fs[0] = c.r * amount; + fs[1] = c.g * amount; + fs[2] = c.b * amount; + fs[3] = c.a * amount; + + if (bClamp) { + out.r = fs[0] < 255.0f ? fs[0] : 255.0f; + out.g = fs[1] < 255.0f ? fs[1] : 255.0f; + out.b = fs[2] < 255.0f ? fs[2] : 255.0f; + out.a = fs[3] < 255.0f ? fs[3] : 255.0f; + } else { + out.r = fs[0]; + out.g = fs[1]; + out.b = fs[2]; + out.a = fs[3]; + } +} + +void PostEffectBase::lerpColor(GXColor &out, const GXColor &c1, const GXColor &c2, f32 amount) { + out.r = c1.r + amount * (c2.r - c1.r); + out.g = c1.g + amount * (c2.g - c1.g); + out.b = c1.b + amount * (c2.b - c1.b); + out.a = c1.a + amount * (c2.a - c1.a); +} + +void PostEffectBase::getBaseTexMtx(nw4r::math::MTX34 *mtx) const { + // Feels wrong -> maybe an inline with rotation and pi + f32 rot = Math::pi(); + f32 sin, cos; + nw4r::math::SinCosRad(&sin, &cos, rot * mRotation); + + f32 zero = 0.0f; + f32 scale = 1.0f; + f32 f8 = zero - 0.5f; + + mtx->_00 = scale * cos; + mtx->_01 = scale * sin; + mtx->_02 = ((f8 * cos) - (sin * (f8 + scale))) + 0.5f; + + mtx->_10 = -scale * sin; + mtx->_11 = scale * cos; + mtx->_12 = ((-f8 * sin) - (cos * (f8 + scale))) + 0.5f; + + mtx->_23 = zero; + mtx->_21 = zero; + mtx->_20 = zero; + mtx->_13 = zero; + mtx->_03 = zero; + mtx->_22 = scale; +} + +void PostEffectBase::setProjection(const Screen &screen) { + static Vector3f sScale(1.0f, 1.0f, 1.0f); + static Vector2f sOffset(0.0f, 0.0f); + + Screen screenCpy(screen); + screenCpy.SetFlag(Screen::FLAG_0x40); + screenCpy.SetCanvasMode(Screen::CANVASMODE_1); + screenCpy.SetProjectionType(Screen::PROJ_ORTHO); + screenCpy.SetNearFar(0.0f, 1.0f); + screenCpy.SetScale(sScale); + screenCpy.SetOffset(sOffset); + screenCpy.SetProjectionGX(); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggPostEffectBlur.cpp b/src/egg/gfx/eggPostEffectBlur.cpp index d988b7bb..79d12e8a 100644 --- a/src/egg/gfx/eggPostEffectBlur.cpp +++ b/src/egg/gfx/eggPostEffectBlur.cpp @@ -1,3 +1,126 @@ #include "egg/gfx/eggPostEffectBlur.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggCapTexture.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggGXUtility.h" +#include "egg/math/eggMath.h" +#include "egg/math/eggVector.h" +#include "math.h" +#include "nw4r/math/math_triangular.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXAttr.h" +#include "rvl/GX/GXBump.h" +#include "rvl/GX/GXTev.h" +#include "rvl/GX/GXTransform.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtx.h" + +namespace EGG { + +PostEffectBlur::PostEffectBlur() : field_0x2C(1), field_0x30(1.0f), field_0x34(1.0f) { + const GXColor clr = (GXColor){0xD7, 0xD7, 0xD7, 0xD7}; + field_0x38[0].init(clr); + field_0x38[1].init(clr); + field_0x38[2].init(clr); + field_0x38[3].init(clr); +} + +void PostEffectBlur::draw(f32 width, f32 height) { + // NONMATCHING + loadTextureInternal(); + setMatColorChannel(); + setMatInd(); + setMatPE(); + setVtxState(); + f32 f1 = 1.0f / mTex1.mpTex->getWidth(); + f32 f2 = 1.0f / mTex1.mpTex->getHeight(); + for (u8 i = 0; i < field_0x2C; i++) { + int maxNum = (field_0x38[i].field_0x00 - 1) / 8; + for (u8 b = 0; b <= maxNum; b++) { + drawInternal(i, b, f1, f2); + drawScreenInternal(mOffsetX, mOffsetY, width * mScaleX, height * mScaleY); + DrawGX::SetBlendMode(DrawGX::BLEND_2); + } + } +} + +void PostEffectBlur::drawInternal(u8 kernelIdx, u8 p2, f32 f1, f32 f2) { + // NONMATCHING + nw4r::math::MTX34 mtx; + const Stage &k = field_0x38[kernelIdx]; + + f32 tx = k.field_0x0C * f1; + f32 ty = k.field_0x0C * f2; + f32 rad1 = k.field_0x08 - Math::pi() * mRotation; + f32 abc = 2.f * Math::pi() / k.field_0x00; + + int unk_00_scale = (p2 & 0x1F) * 8; + + u8 numTexGens = k.field_0x00 - unk_00_scale; + if (numTexGens > 8) { + numTexGens = 8; + } + + getBaseTexMtx(&mtx); + GXSetNumTexGens(numTexGens); + for (int id = 0; id < numTexGens; id++) { + int texMtxId = GXUtility::getTexMtxID(id); + GXSetTexCoordGen2(static_cast(id), GX_TG_MTX2x4, GX_TG_TEX0, texMtxId, false, 0x7D); + f32 sin, cos; + nw4r::math::SinCosRad(&sin, &cos, rad1 + abc * unk_00_scale); + nw4r::math::MTX34 m( + // clang-format off + 1.0f, 0.0f, cos * tx, 0.0f, + 0.0f, 1.0f, sin * ty, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f + // clang-format on + ); + PSMTXConcat(m, mtx, m); + GXLoadTexMtxImm(m, texMtxId, GX_MTX_2x4); + unk_00_scale++; + } + + bool isSmallColor = k.field_0x01.r < 0x80 && k.field_0x01.g < 0x80 && k.field_0x01.b < 0x80; + bool isSmallAlpha = k.field_0x01.a < 0x80; + f32 colorScale = (isSmallColor ? 2.0f : 1.0f) * field_0x30; + f32 alphaScale = (isSmallAlpha ? 2.0f : 1.0f) * field_0x30; + + f32 clrs[] = { + k.field_0x01.r * colorScale, + k.field_0x01.g * colorScale, + k.field_0x01.b * colorScale, + k.field_0x01.a * alphaScale, + }; + GXColor clr; + clr.r = clrs[0] < 255.0f ? clrs[0] : 255.0f; + clr.g = clrs[1] < 255.0f ? clrs[1] : 255.0f; + clr.b = clrs[2] < 255.0f ? clrs[2] : 255.0f; + clr.a = clrs[3] < 255.0f ? clrs[3] : 255.0f; + + GXSetTevKColor(GX_KCOLOR0, clr); + GXSetNumTevStages(numTexGens); + for (int id = 0; id < numTexGens; id++) { + GXTevStageID stage = static_cast(id); + GXSetTevDirect(stage); + GXSetTevSwapMode(stage, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXTevColorArg a1 = id > 0 ? GX_CC_CPREV : GX_CC_ZERO; + GXTevAlphaArg a2 = id > 0 ? GX_CA_APREV : GX_CA_ZERO; + + GXSetTevKColorSel(stage, GX_TEV_KCSEL_K0); + GXSetTevKAlphaSel(stage, GX_TEV_KASEL_K0_A); + GXSetTevOrder(stage, static_cast(id), mTex1.mTexMapID, GX_COLOR_NULL); + GXSetTevColorIn(stage, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, a1); + GXSetTevAlphaIn(stage, GX_CA_ZERO, GX_CA_TEXA, GX_CA_KONST, a2); + + bool isLast = stage == numTexGens - 1; + bool colorArg = isLast; + + GXTevScale colorScale = isSmallColor && isLast ? GX_CS_DIVIDE_2 : GX_CS_SCALE_1; + GXTevScale alphaScale = isSmallAlpha && colorArg ? GX_CS_DIVIDE_2 : GX_CS_SCALE_1; + GXSetTevColorOp(stage, GX_TEV_ADD, GX_TB_ZERO, colorScale, colorArg, GX_TEVPREV); + GXSetTevAlphaOp(stage, GX_TEV_ADD, GX_TB_ZERO, alphaScale, isLast, GX_TEVPREV); + } +} + +} // namespace EGG diff --git a/src/egg/gfx/eggPostEffectBlurGather.cpp b/src/egg/gfx/eggPostEffectBlurGather.cpp new file mode 100644 index 00000000..0269966b --- /dev/null +++ b/src/egg/gfx/eggPostEffectBlurGather.cpp @@ -0,0 +1,89 @@ +#include "egg/gfx/eggPostEffectBlurGather.h" + +#include "common.h" +#include "egg/gfx/eggCpuTexture.h" +#include "egg/gfx/eggGXUtility.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXAttr.h" +#include "rvl/GX/GXTev.h" +#include "rvl/GX/GXTransform.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +PostEffectBlurGather::PostEffectBlurGather() { + field_0x2C = 1; + field_0x2D = 1; + field_0x30 = 0.5f; + mBlurGatherData[0].reset(); + mBlurGatherData[1].reset(); + mBlurGatherData[2].reset(); +} + +void PostEffectBlurGather::setMaterialInternal() { + u8 hasExtraStage = (mTex1.mpTex != nullptr && (field_0x2D & 1) == 0) ? 1 : 0; + u8 numStages = field_0x2C + hasExtraStage * 2; + setMatColorChannel(); + nw4r::math::MTX34 mtx; + getBaseTexMtx(&mtx); + u8 numStagesFirst = field_0x2C + hasExtraStage; + GXSetNumTexGens(numStagesFirst); + for (int i = 0; i < numStagesFirst; i++) { + int texMtxIdx = GXUtility::getTexMtxID(i); + GXSetTexCoordGen2(static_cast(i), GX_TG_MTX2x4, GX_TG_TEX0, texMtxIdx, 0, 0x7D); + if (i < field_0x2C) { + mBlurGatherData[i].mpCapTexture->load(mBlurGatherData[i].mTexMapId); + } else { + loadTextureInternal(); + } + GXLoadTexMtxImm(mtx, texMtxIdx, GX_MTX_2x4); + } + + f32 v = field_0x30 * 255.0f; + GXColor c = {v, v, v, v}; + setMatInd(); + GXSetNumTevStages(numStages); + + for (int i = 0; i < numStages; i++) { + BlurGatherData &k = mBlurGatherData[i]; + GXTevStageID stage = static_cast(i); + GXSetTevDirect(stage); + GXSetTevSwapMode(stage, GX_TEV_SWAP0, GX_TEV_SWAP0); + if (i < field_0x2C) { + GXColor scaledColor; + scaleColor(scaledColor, k.mColor, false, k.mColorScale); + + GXSetTevKColorSel(stage, static_cast(GX_TEV_KCSEL_K0 + i)); + GXSetTevKAlphaSel(stage, static_cast(GX_TEV_KASEL_K0_A + i)); + + GXSetTevKColor(static_cast(i), scaledColor); + GXSetTevOrder(stage, static_cast(i), k.mTexMapId, GX_COLOR_NULL); + GXSetTevColorIn(stage, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, stage == 0 ? GX_CC_ZERO : GX_CC_CPREV); + GXSetTevColorOp( + stage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, i == field_0x2C - 1 ? GX_TEVREG0 : GX_TEVPREV + ); + GXSetTevAlphaIn(stage, GX_CA_ZERO, GX_CA_TEXA, GX_CA_KONST, stage == 0 ? GX_CA_ZERO : GX_CA_APREV); + GXSetTevAlphaOp( + stage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, i == field_0x2C - 1 ? GX_TEVREG0 : GX_TEVPREV + ); + } else if (stage == field_0x2C) { + GXSetTevKColorSel(stage, GX_TEV_KCSEL_K2); + GXSetTevKAlphaSel(stage, GX_TEV_KASEL_K2_A); + GXSetTevKColor(GX_KCOLOR2, c); + GXSetTevOrder(stage, static_cast(i), mTex1.mTexMapID, GX_COLOR_NULL); + GXSetTevColorIn(stage, GX_CC_KONST, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + GXSetTevColorOp(stage, GX_TEV_SUB, GX_TB_ZERO, GX_CS_SCALE_4, 1, GX_TEVPREV); + GXSetTevAlphaIn(stage, GX_CA_KONST, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + GXSetTevAlphaOp(stage, GX_TEV_SUB, GX_TB_ZERO, GX_CS_SCALE_4, true, GX_TEVPREV); + } else { + GXSetTevOrder(stage, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevColorIn(stage, GX_CC_C0, GX_CC_ZERO, GX_CC_CPREV, GX_CC_ZERO); + GXSetTevColorOp(stage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(stage, GX_CA_A0, GX_CA_ZERO, GX_CA_APREV, GX_CA_ZERO); + GXSetTevAlphaOp(stage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + } + } + setMatPE(); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggPostEffectMask.cpp b/src/egg/gfx/eggPostEffectMask.cpp index 64833345..a5819a9a 100644 --- a/src/egg/gfx/eggPostEffectMask.cpp +++ b/src/egg/gfx/eggPostEffectMask.cpp @@ -1,3 +1,90 @@ #include "egg/gfx/eggPostEffectMask.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggDrawGX.h" +#include "rvl/GX/GXAttr.h" +#include "rvl/GX/GXTev.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +PostEffectMask::PostEffectMask() + : mColor(DrawGX::WHITE), field_0x2C(0), field_0x34(0.0f), field_0x38(1.0f), field_0x1BC(1) {} + +void PostEffectMask::setMaterialInternal() { + bool hasTex2 = mTex2.mpTex != nullptr; + loadTextureInternal(); + GXColor resColor; + scaleColor(resColor, mColor, false, field_0x34); + setMatColorChannel(); + GXSetNumTexGens(2); + + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX_IDENT, false, GX_DUALMTX_IDENT); + GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX_IDENT, false, GX_DUALMTX_IDENT); + setMatInd(); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetTevDirect(GX_TEVSTAGE0); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevDirect(GX_TEVSTAGE1); + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXTevScale scale = field_0x2C == 0 ? GetTevScale() : GX_CS_SCALE_1; + + GXColor c = resColor; + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, mTex1.mTexMapID, GX_COLOR_NULL); + GXSetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); + GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); + GXSetTevKColor(GX_KCOLOR0, c); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_KONST, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_SUB, GX_TB_ZERO, scale, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_KONST, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_SUB, GX_TB_ZERO, scale, 1, GX_TEVPREV); + + switch (field_0x2C) { + case 0: { + if (hasTex2) { + GXSetNumTevStages(2); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, mTex2.mTexMapID, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_TEXC, GX_CC_CPREV, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_TEXA, GX_CA_APREV, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + field_0x00 = 0; + } else { + GXSetNumTevStages(1); + field_0x00 = 10; + } + break; + } + case 1: { + if (hasTex2) { + GXSetNumTevStages(3); + scale = GetTevScale(); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, mTex1.mTexMapID, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_CPREV, GX_CC_TEXA, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, scale, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD1, mTex2.mTexMapID, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE2, GX_CC_ZERO, GX_CC_TEXC, GX_CC_CPREV, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE2, GX_CA_ZERO, GX_CA_TEXA, GX_CA_APREV, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + field_0x00 = 0; + } else { + GXSetNumTevStages(2); + scale = GetTevScale(); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, mTex1.mTexMapID, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_CPREV, GX_CC_TEXA, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, scale, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + field_0x00 = 10; + } + break; + } + } + + setMatPE(); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggPostEffectMaskDOF.cpp b/src/egg/gfx/eggPostEffectMaskDOF.cpp index 9bd54d28..59104d51 100644 --- a/src/egg/gfx/eggPostEffectMaskDOF.cpp +++ b/src/egg/gfx/eggPostEffectMaskDOF.cpp @@ -1,3 +1,246 @@ #include "egg/gfx/eggPostEffectMaskDOF.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggCpuTexture.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXGeometry.h" +#include "rvl/GX/GXTransform.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtx.h" + +namespace EGG { + +static const GXColor sColorNear = (GXColor){0x00, 0xFF, 0x00, 0xFF}; +static const GXColor sColorFar = (GXColor){0xFF, 0x00, 0x00, 0x00}; +static const GXColor sColorCenter = (GXColor){0x00, 0x00, 0x00, 0x00}; + +PostEffectMaskDOF::PostEffectMaskDOF() + : field_0x2C(8), + field_0x44(0.5), + field_0x48(0.f), + field_0x4C(1.f), + field_0x50(0.f, 0.f), + mCpuTexArrIdx(2), + field_0x60(2) { + for (int i = 0; i < 3; i++) { + mpCpuTexArr[i] = new CpuTexture(64, 2, GX_TF_RGBA8); + mpCpuTexArr[i]->configure(); + mpCpuTexArr[i]->allocate(nullptr); + mpCpuTexArr[i]->setWrapS(GX_CLAMP); + mpCpuTexArr[i]->setWrapT(GX_CLAMP); + } + + mpCpuTex = new CpuTexture(64, 64, GX_TF_RGBA8); + mpCpuTex->configure(); + mpCpuTex->allocate(nullptr); + mpCpuTex->setWrapS(GX_CLAMP); + mpCpuTex->setWrapT(GX_CLAMP); + setUpGradation(); + field_0x00 = 0; +} + +void PostEffectMaskDOF::setUpGradation() { + for (int i = 0; i < 3; i++) { + const u16 width = mpCpuTexArr[i]->getWidth(); + const int mid = width / 2; + for (u16 x = 0; x < mid; x++) { + f32 val = 1.f - (f32)x / (mid - 1); + + switch (i) { + case 1: val *= val; break; + case 2: + val *= val; + val *= val; + break; + } + + GXColor clr1, clr2; + lerpColor(clr1, getCenterColor(), getNearColor(), val); + lerpColor(clr2, getCenterColor(), getFarColor(), val); + + mpCpuTexArr[i]->setColor(x, 0, clr1); + mpCpuTexArr[i]->setColor(x, 1, clr1); + mpCpuTexArr[i]->setColor((width - 1) - x, 0, clr2); + mpCpuTexArr[i]->setColor((width - 1) - x, 1, clr2); + } + mpCpuTexArr[i]->flush(); + } + + const u16 width = mpCpuTex->getWidth() / 2; + for (u16 y = 0; y < mpCpuTex->getHeight(); y++) { + f32 fy = (f32)y / mpCpuTex->getHeight2(); + for (u16 x = 0; x < width; x++) { + // Don't even have to use this one! + (void)(f32)width; + f32 ratio = ((f32)x / width) / (1.f - fy); + + if (ratio > 1.f) { + ratio = 1.f; + } else if (ratio < 0.f) { + ratio = 0.f; + } + ratio *= ratio; + ratio *= ratio; + GXColor clr1, clr2; + lerpColor(clr1, getCenterColor(), getNearColor(), ratio); + lerpColor(clr2, getCenterColor(), getFarColor(), ratio); + mpCpuTex->setColor((width - 1) - x, y, clr1); + mpCpuTex->setColor(width + x, y, clr2); + } + } + mpCpuTex->flush(); +} + +void PostEffectMaskDOF::draw(f32 width, f32 height) { + setMaterialInternal(); + setVtxState(); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX1, GX_TEX_ST, GX_F32, 0); + GXSetVtxDesc(GX_VA_TEX1, GX_DIRECT); + nw4r::math::MTX34 mtx; + PSMTXScale(mtx, width * mScaleX, height * mScaleY, 1.f); + PSMTXTransApply(mtx, mtx, mOffsetX, mOffsetY, 0.f); + GXLoadPosMtxImm(mtx, GX_PNMTX0); + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition2u8(0, 0); + GXPosition2f32(field_0x50.x, field_0x50.y); + GXPosition2u8(1, 1); + GXPosition2f32(field_0x50.x, field_0x50.y); + GXPosition2u8(2, 2); + GXPosition2f32(field_0x50.x, field_0x50.y); + GXPosition2u8(3, 3); + GXPosition2f32(field_0x50.x, field_0x50.y); + GXSetTexCoordScaleManually(GX_TEXCOORD1, 0, 0x40, 0); + GXSetTexCoordBias(GX_TEXCOORD1, 0, 0); +} + +void PostEffectMaskDOF::setMaterialInternal() { + loadTextureInternal(); + setMatColorChannel(); + GXSetNumTexGens(2); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0, false, GX_DUALMTX_IDENT); + GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, GX_TEXMTX_IDENT, false, GX_DUALMTX_IDENT); + nw4r::math::MTX34 baseTexMtx; + getBaseTexMtx(&baseTexMtx); + GXLoadTexMtxImm(baseTexMtx, GX_TEXMTX0, GX_MTX_2x4); + GXSetNumIndStages(1); + GXSetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD0, mTex1.mTexMapID); + GXSetIndTexCoordScale(GX_INDTEXSTAGE0, GX_ITS_1, GX_ITS_1); + + CpuTexture *pCpuTex = mpCpuTexArr[mCpuTexArrIdx]; + switch (field_0x60) { + case 0: { + GXSetNumTevStages(1); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD1, GX_TEXMAP2, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevIndirect( + GX_TEVSTAGE0, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_0, GX_ITW_OFF, GX_ITW_OFF, false, false, + GX_ITBA_OFF + ); + + s8 scaleExp = 0; + f32 fVar2 = scaleExp + 1; + f32 fVar3 = 1.f / (field_0x4C - field_0x48); + + f32 fVar1 = fVar3 / fVar2; + + while (fVar1 > (1023.f / 1024.f)) { + fVar1 /= 2.f; + fVar2 *= 2.f; + + scaleExp++; + } + while (0.f < fVar1 && fVar1 < 0.5f) { + fVar1 *= 2.f; + fVar2 /= 2.f; + + scaleExp--; + } + f32 indTexMtx[2][3] = { + {fVar1 / 256.f, fVar1, 0.f}, + { 0.f, 0.f, 0.f} + }; + GXSetIndTexMtx(GX_ITM_0, indTexMtx, scaleExp - 2); + field_0x50.x = -(field_0x44 * fVar1 * fVar2) + 0.5f; + if (field_0x2C & 8) { + field_0x50.x = (s32)(field_0x50.x * 128.f) / 128.f; + } + field_0x50.y = 0.f; + GXSetTexCoordScaleManually(GX_TEXCOORD1, true, 0x40, 0); + GXSetTexCoordBias(GX_TEXCOORD1, 0, 0); + } break; + case 1: { + pCpuTex = mpCpuTex; + GXSetNumTevStages(2); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetTevDirect(GX_TEVSTAGE0); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD1, GX_TEXMAP2, GX_COLOR_NULL); + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP2, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevIndirect( + GX_TEVSTAGE1, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_0, GX_ITW_0, GX_ITW_0, true, false, + GX_ITBA_OFF + ); + field_0x50.y = field_0x4C; + + f32 val = 1023.f / 1024.f; + f32 indTexMtx[2][3] = { + {val / 256.f, val, 0.f}, + { 0.f, 0.f, 0.f} + }; + + GXSetIndTexMtx(GX_ITM_0, indTexMtx, 8); + + int unk = 1024; + field_0x50.x = -field_0x44 + 0.5f / unk; + + GXSetTexCoordScaleManually(GX_TEXCOORD1, GX_TEXCOORD1, 0, 0x40); + GXSetTexCoordBias(GX_TEXCOORD1, 0, 0); + } break; + case 2: { + GXSetNumTevStages(1); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP2, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevIndirect( + GX_TEVSTAGE0, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_0, GX_ITW_0, GX_ITW_0, false, false, + GX_ITBA_OFF + ); + + f32 indTexMtx[2][3] = { + {0.f, 0.5f, 0.f}, + {0.f, 0.f, 0.f} + }; + GXSetIndTexMtx(GX_ITM_0, indTexMtx, -1); + + field_0x50.y = 0.f; + field_0x50.x = 0.f; + } break; + } + pCpuTex->load(GX_TEXMAP2); + setMatPE(); +} + +const GXColor &PostEffectMaskDOF::getNearColor() { + return sColorNear; +} +const GXColor &PostEffectMaskDOF::getFarColor() { + return sColorFar; +} +const GXColor &PostEffectMaskDOF::getCenterColor() { + return sColorCenter; +} + +} // namespace EGG diff --git a/src/egg/gfx/eggPostEffectSimple.cpp b/src/egg/gfx/eggPostEffectSimple.cpp index 468e8539..c6525a9a 100644 --- a/src/egg/gfx/eggPostEffectSimple.cpp +++ b/src/egg/gfx/eggPostEffectSimple.cpp @@ -1,3 +1,48 @@ #include "egg/gfx/eggPostEffectSimple.h" -namespace EGG {} // namespace EGG +#include "egg/gfx/eggDrawGX.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +PostEffectSimple::PostEffectSimple() + : field_0x2C(DrawGX::WHITE), field_0x30(1.0f), field_0x34(GX_CS_SCALE_1), field_0x38(1) {} + +void PostEffectSimple::setMaterialInternal() { + loadTextureInternal(); + GXColor c = field_0x2C; + if (field_0x30 < 1.0f) { + scaleColor(c, c, true, field_0x30); + } + setMatColorChannel(); + GXSetNumTexGens(1); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x1e, 0, 0x7d); + nw4r::math::MTX34 mtx; + getBaseTexMtx(&mtx); + GXLoadTexMtxImm(mtx, 0x1e, GX_MTX_2x4); + setMatInd(); + GXSetNumTevStages(1); + GXSetTevDirect(GX_TEVSTAGE0); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); + GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); + GXSetTevKColor(GX_KCOLOR0, c); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, mTex1.mTexMapID, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, field_0x34, 1, GX_TEVPREV); + switch (field_0x38) { + case 0: GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_KONST); break; + case 1: GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_TEXA, GX_CA_KONST, GX_CA_ZERO); break; + case 2: + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXA, GX_CC_KONST, GX_CC_ZERO); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_KONST); + break; + } + + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, field_0x34, true, GX_TEVPREV); + setMatPE(); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggPostEffectUnk1.cpp b/src/egg/gfx/eggPostEffectUnk1.cpp deleted file mode 100644 index f85768e6..00000000 --- a/src/egg/gfx/eggPostEffectUnk1.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "egg/gfx/eggPostEffectUnk1.h" - -namespace EGG {} // namespace EGG diff --git a/src/egg/gfx/eggPostEffectUnk2.cpp b/src/egg/gfx/eggPostEffectUnk2.cpp index d44f65cc..ffa43714 100644 --- a/src/egg/gfx/eggPostEffectUnk2.cpp +++ b/src/egg/gfx/eggPostEffectUnk2.cpp @@ -1,3 +1,189 @@ #include "egg/gfx/eggPostEffectUnk2.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggCapTexture.h" +#include "egg/gfx/eggCpuTexture.h" +#include "egg/gfx/eggGXUtility.h" +#include "egg/math/eggVector.h" +#include "nw4r/math/math_triangular.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXBump.h" +#include "rvl/GX/GXGeometry.h" +#include "rvl/GX/GXTransform.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/GX/GXVert.h" +#include "rvl/MTX/mtx.h" + +namespace EGG { + +inline f32 GetColor(f32 x, u16 w) { + return nw4r::ut::Min(x / (w - 1), 1.f) * 0xFF; +} + +PostEffectUnk2::PostEffectUnk2() + : // NONMATCHING + field_0x2C(0), + field_0x30(0), + field_0x34(1), + field_0x35(0xFE), + field_0x36(7), + field_0x38(0.0f, 0.0f), + field_0x40(1.0f), + field_0x44(1.0f), + field_0x48(1.0f) { + mpTexture = new CpuTexture(32, 4, GX_TF_RGBA8); + mpTexture->configure(); + mpTexture->allocate(nullptr); + mpTexture->setWrapS(GX_CLAMP); + mpTexture->setWrapT(GX_CLAMP); + + for (u16 y = 0; y < mpTexture->getHeight(); y++) { + for (u16 x = 0; x < mpTexture->getWidth(); x++) { + u8 val = GetColor(x, mpTexture->getWidth()); + + mpTexture->setColor(x, y, (GXColor){val, val, val, val}); + } + } + + mpTexture->flush(); + field_0x00 = 0; +} + +PostEffectUnk2::~PostEffectUnk2() { + delete mpTexture; +} + +void PostEffectUnk2::draw(f32 width, f32 height) { + // NONMATCHING + setMaterialInternal(); + setVtxState(); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX1, GX_CLR_RGBA, GX_F32, 0); + GXSetVtxDesc(GX_VA_TEX1, GX_DIRECT); + + nw4r::math::MTX34 mtx; + PSMTXScale(mtx, width * mScaleX, height * mScaleY, 1.0f); + PSMTXTransApply(mtx, mtx, mOffsetX, mOffsetY, 0.0f); + GXLoadPosMtxImm(mtx, 0); + + static const f32 floats1[2][2] = { + {-1.0f, 1.0f}, + { 0.0f, 0.0f}, + }; + static const f32 floats2[2][2] = { + { 0.0f, 0.0f}, + {-1.0f, 1.0f}, + }; + + const f32 s1 = field_0x40 / mTex1.mpTex->getWidth(); + const f32 s2 = field_0x40 / mTex1.mpTex->getHeight(); + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + f32 mtx[2][4]; + EGG::Vector3f a(0.f, 0.f, 0.f); + + f32 sin, cos; + nw4r::math::SinCosRad(&sin, &cos, a.z); + + mtx[0][0] = cos; + mtx[0][1] = -sin; + mtx[0][2] = -cos * a.x + sin * a.y + a.x + (s1 * floats1[i][j]); + + mtx[1][0] = sin; + mtx[1][1] = cos; + mtx[1][2] = -sin * a.x - cos * a.y + a.y + (s2 * floats2[i][j]); + + mtx[1][3] = 0.f; + mtx[0][3] = 0.f; + GXLoadTexMtxImm(mtx, GXUtility::getTexMtxID(j), GX_MTX_2x4); + } + if (i == 1 && field_0x2C <= 1) { + GXSetBlendMode(GX_BM_LOGIC, GX_BL_ZERO, GX_BL_ZERO, GX_LO_OR); + } + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition2u8(0, 0); + GXPosition2f32(field_0x38.x, field_0x38.y); + GXPosition2u8(1, 1); + GXPosition2f32(field_0x38.x, field_0x38.y); + GXPosition2u8(2, 2); + GXPosition2f32(field_0x38.x, field_0x38.y); + GXPosition2u8(3, 3); + GXPosition2f32(field_0x38.x, field_0x38.y); + } +} + +void PostEffectUnk2::setMaterialInternal() { + loadTextureInternal(); + setMatColorChannel(); + GXSetNumTexGens(4); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, 0, 0x7d); + GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, 0x3c, 0, 0x7d); + GXSetTexCoordGen2(GX_TEXCOORD2, GX_TG_MTX2x4, GX_TG_TEX0, 0x1e, 0, 0x7d); + GXSetTexCoordGen2(GX_TEXCOORD3, GX_TG_MTX2x4, GX_TG_TEX0, 0x21, 0, 0x7d); + GXSetNumIndStages(3); + GXSetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD0, mTex1.mTexMapID); + GXSetIndTexOrder(GX_INDTEXSTAGE1, GX_TEXCOORD2, mTex1.mTexMapID); + GXSetIndTexOrder(GX_INDTEXSTAGE2, GX_TEXCOORD3, mTex1.mTexMapID); + setMatPE(); + mpTexture->load(GX_TEXMAP1); + + GXSetNumTevStages(4); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetTevDirect(GX_TEVSTAGE0); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR_NULL); + + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP1, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + + GXSetTevIndirect( + GX_TEVSTAGE1, GX_INDTEXSTAGE1, GX_ITF_8, GX_ITB_NONE, GX_ITM_1, GX_ITW_0, GX_ITW_0, true, false, GX_ITBA_OFF + ); + + GXSetTevSwapMode(GX_TEVSTAGE2, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD_NULL, GX_TEXMAP1, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE2, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + GXSetTevColorOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE2, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + GXSetTevAlphaOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevIndirect( + GX_TEVSTAGE2, GX_INDTEXSTAGE2, GX_ITF_8, GX_ITB_NONE, GX_ITM_2, GX_ITW_0, GX_ITW_0, true, false, GX_ITBA_OFF + ); + + GXSetTevSwapMode(GX_TEVSTAGE3, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE3, GX_TEXCOORD_NULL, GX_TEXMAP1, GX_COLOR_NULL); + if ((int)field_0x2C == 2) { + GXSetTevColorIn(GX_TEVSTAGE3, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO); + GXSetTevAlphaIn(GX_TEVSTAGE3, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_GREATER, field_0x35); + } else { + GXSetTevColorIn(GX_TEVSTAGE3, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + GXSetTevAlphaIn(GX_TEVSTAGE3, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + } + GXSetTevColorOp(GX_TEVSTAGE3, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaOp(GX_TEVSTAGE3, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevIndirect( + GX_TEVSTAGE3, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_0, GX_ITW_0, GX_ITW_0, true, false, GX_ITBA_OFF + ); + for (int i = 0; i < 3; i++) { + static const f32 sFloats[2][3] = { + { 1.0f, -1.0f, -1.0f}, + {-1.0f, 1.0f, 1.0f}, + }; + + s16 scale = field_0x36; + f32 f1 = (i != 0 ? 0.5f : 1.0f) * (sFloats[field_0x30][i] * 0.5f); + f32 f2 = (i == 0 ? field_0x44 : 0.0f) * 0.5f; + + f32 v[2][3] = { + {f1 / 256.0f, f1, 0.0f}, + {f2 / 256.0f, f2, 0.0f}, + }; + + GXSetIndTexMtx(static_cast(i + 1), v, scale - 2); + } +} + +} // namespace EGG diff --git a/src/egg/gfx/eggScreen.cpp b/src/egg/gfx/eggScreen.cpp index 66b80c4e..768c4b2c 100644 --- a/src/egg/gfx/eggScreen.cpp +++ b/src/egg/gfx/eggScreen.cpp @@ -1,3 +1,335 @@ #include "egg/gfx/eggScreen.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggStateGX.h" +#include "rvl/SC/scapi.h" + +// ported from OGWS, though this class has evolved a fair bit + +using namespace nw4r; + +namespace EGG { + +Screen::TVMode Screen::sTVMode; +Screen::TVModeInfo Screen::sTVModeInfo[TV_MODE_MAX] = { + { + 608, 456, + nw4r::math::VEC2(1.0526316f, 1.0f), + }, + { + 812, 456, + nw4r::math::VEC2(0.7881773, 1.0f), + }, + { + 640, 456, + nw4r::math::VEC2(1.0f, 1.0f), + } +}; + +Screen *Screen::spRoot = nullptr; + +Screen::ChangeTVModeFunc Screen::sChangeTVModeFunc = nullptr; +void *Screen::spChangeTVModeFuncInfo = nullptr; + +math::VEC2 Screen::sCanvasScale(1.0f, 1.0f); +math::VEC2 Screen::sCanvasOffset(0.0f, 0.0f); + +void Screen::Initialize(const u16 *maxX, const u16 *maxY, Screen *userRoot) { + sTVModeInfo[TV_MODE_4_3].width = maxX[0]; + sTVModeInfo[TV_MODE_4_3].height = maxY[0]; + + sTVModeInfo[TV_MODE_4_3].ratios.x = (f32)StateGX::s_widthEfb / (f32)sTVModeInfo[TV_MODE_4_3].width; + sTVModeInfo[TV_MODE_4_3].ratios.y = (f32)StateGX::s_heightEfb / (f32)sTVModeInfo[TV_MODE_4_3].height; + + sTVModeInfo[TV_MODE_16_9].width = maxX[1]; + sTVModeInfo[TV_MODE_16_9].height = maxY[1]; + + sTVModeInfo[TV_MODE_16_9].ratios.x = (f32)StateGX::s_widthEfb / (f32)sTVModeInfo[TV_MODE_16_9].width; + sTVModeInfo[TV_MODE_16_9].ratios.y = (f32)StateGX::s_heightEfb / (f32)sTVModeInfo[TV_MODE_16_9].height; + + sTVModeInfo[TV_MODE_UNK_3].width = StateGX::s_widthEfb; + sTVModeInfo[TV_MODE_UNK_3].height = StateGX::s_heightEfb; + + sTVModeInfo[TV_MODE_UNK_3].ratios.x = 1.0f; + sTVModeInfo[TV_MODE_UNK_3].ratios.y = 1.0f; + + static Screen defaultRoot; + defaultRoot.SetProjectionType(PROJ_ORTHO); + defaultRoot.SetCanvasMode(CANVASMODE_1); + defaultRoot.SetNearZ(0.0f); + defaultRoot.SetFarZ(1.0f); + defaultRoot.SetSize(math::VEC2(sTVModeInfo[sTVMode].width, sTVModeInfo[sTVMode].height)); + + userRoot = (userRoot == nullptr) ? &defaultRoot : userRoot; + spRoot = userRoot; + userRoot->mParent = nullptr; + SetTVMode(sTVMode); +} + +Screen::Screen() + : Frustum( + PROJ_PERSP, math::VEC2(sTVModeInfo[sTVMode].width, sTVModeInfo[sTVMode].height), 10.0f, 100000.0f, + CANVASMODE_1 + ) { + mParent = nullptr; + mPosition.x = 0.0f; + mPosition.y = 0.0f; + field_0x48.x = 0.0f; + field_0x48.y = 0.0f; + field_0x50.x = 0.0f; + field_0x50.y = 0.0f; + SetParent(nullptr); +} + +Screen::Screen(f32 x, f32 y, f32 w, f32 h, const Screen *userRoot, CanvasMode canvasMode) + : Frustum(PROJ_PERSP, math::VEC2(w, h), 10.0f, 100000.0f, canvasMode) { + mParent = nullptr; + mPosition.x = x; + mPosition.y = y; + field_0x48.x = 0.0f; + field_0x48.y = 0.0f; + field_0x50.x = 0.0f; + field_0x50.y = 0.0f; + SetParent(userRoot); +} + +Screen::Screen(const Screen &other) + : Frustum(other), + mPosition(other.mPosition), + mDataEfb(other.mDataEfb), + field_0x48(other.field_0x48), + field_0x50(other.field_0x50) { + SetParent(other.mParent); +} + +void Screen::SetProjectionGX() const { + if (!(mFlags & 0x40)) { + f32 sx, sy, ox, oy; + GetGlobalScaleOffset(&sx, &sy, &ox, &oy); + + SetGlobalScaleOffset(sCanvasScale.x, sCanvasScale.y, sCanvasOffset.x, sCanvasOffset.y); + Frustum::SetProjectionGX(); + + SetGlobalScaleOffset(sx, sy, ox, oy); + } else { + Frustum::SetProjectionGX(); + } + + const DataEfb &efb = GetDataEfb(); + + StateGX::GXSetViewport_(efb.vp.x1, efb.vp.y1, efb.vp.x2, efb.vp.y2, efb.vp.z1, efb.vp.z2); + StateGX::GXSetScissor_(efb.sc_x, efb.sc_y, efb.sc_w, efb.sc_h); + StateGX::GXSetScissorBoxOffset_(efb.sc_ox, efb.sc_oy); +} + +void Screen::CopyToG3D(g3d::Camera cam) const { + if (!(mFlags & 0x40)) { + f32 sx, sy, ox, oy; + GetGlobalScaleOffset(&sx, &sy, &ox, &oy); + + SetGlobalScaleOffset(sCanvasScale.x, sCanvasScale.y, sCanvasOffset.x, sCanvasOffset.y); + Frustum::CopyToG3D(cam); + + SetGlobalScaleOffset(sx, sy, ox, oy); + } else { + Frustum::CopyToG3D(cam); + } + + const DataEfb &efb = GetDataEfb(); + + f32 x1, x2, y1, y2; + f32 z1, z2; + + y2 = efb.vp.y2; + x2 = efb.vp.x2; + + y1 = efb.vp.y1; + x1 = efb.vp.x1; + + z2 = efb.vp.z2; + z1 = efb.vp.z1; + + cam.SetViewport(x1, y1, x2, y2); + cam.SetViewportZRange(z1, z2); + cam.SetScissor(efb.sc_x, efb.sc_y, efb.sc_w, efb.sc_h); + cam.SetScissorBoxOffset(efb.sc_ox, efb.sc_oy); +} + +void Screen::CopyFromAnother(const Screen &other) { + Frustum::CopyFromAnother(other); + + mPosition = other.mPosition; + field_0x48 = other.field_0x48; + field_0x50 = other.field_0x50; + mDataEfb = other.mDataEfb; + mParent = other.mParent; +} + +void Screen::Reset(f32 x, f32 y, f32 w, f32 h, CanvasMode mode) { + mPosition.x = x; + mPosition.y = y; + mSize.x = w; + SetDirty(true); + mSize.y = h; + SetCanvasMode(mode); +} + +void Screen::SetParent(const Screen *parent) { + const Screen *newParent = parent != nullptr ? parent : spRoot; + + if (mParent != newParent) { + SetDirty(true); + mParent = newParent; + } +} + +void Screen::SetUnkFlag8() { + if ((mFlags & FLAG_0x08) == 0) { + SetDirty(true); + } + mFlags |= FLAG_0x08; +} + +void Screen::OnDirectEfb() const { + f32 &x1 = mDataEfb.vp.x1; + f32 &y1 = mDataEfb.vp.y1; + if (mParent == nullptr) { + x1 = mPosition.x * sCanvasScale.x; + y1 = mPosition.y * sCanvasScale.y; + } else { + mParent->fn_804B2EE0(&x1, &y1, mPosition.x, mPosition.y); + } + + // TODO: Make this work without temporaries? + + mDataEfb.sc_x = x1 + ScaleByX(field_0x48.x); + mDataEfb.sc_y = y1 + ScaleByY(field_0x48.y); + + mDataEfb.sc_oy = 0; + mDataEfb.sc_ox = 0; + if (x1 < 0.0f) { + int x1_i = x1; + int x1_in = -x1_i; + mDataEfb.sc_ox = (x1_in - (x1_in & 1)); + x1 = x1 - x1_i; + } + if (y1 < 0.0f) { + int y1_i = y1; + int y1_in = -y1_i; + mDataEfb.sc_oy = (y1_in - (y1_in & 1)); + y1 = y1 - y1_i; + } + + if ((mFlags & FLAG_0x02) != 0) { + x1 = x1 - (((int)x1) & 1); + y1 = y1 - (((int)y1) & 1); + } + + mDataEfb.vp.x2 = ScaleByX(mSize.x); + mDataEfb.vp.y2 = ScaleByY(mSize.y); + + if ((mFlags & FLAG_0x04) != 0) { + mDataEfb.vp.x2 -= ((int)mDataEfb.vp.x2 & 3); + mDataEfb.vp.y2 -= ((int)mDataEfb.vp.y2 & 3); + } + mDataEfb.vp.x2 = (int)mDataEfb.vp.x2; + mDataEfb.vp.y2 = (int)mDataEfb.vp.y2; + + mDataEfb.sc_w = mDataEfb.vp.x2 - ScaleByX(field_0x48.x + field_0x50.x); + mDataEfb.sc_h = mDataEfb.vp.y2 - ScaleByY(field_0x48.y + field_0x50.y); +} + +const Screen::DataEfb &Screen::GetDataEfb() const { + if (IsChangeEfb()) { + OnDirectEfb(); + mDataEfb.vp.z1 = 0.0f; + mDataEfb.vp.z2 = 1.0f; + SetDirty(false); + } + + return mDataEfb; +} + +bool Screen::IsChangeEfb() const { + if (mFlags & FLAG_DIRTY) { + return true; + } + + if (mParent != nullptr) { + return mParent->IsChangeEfb(); + } + + return false; +} + +void Screen::CalcMatrixForDrawQuad(math::MTX34 *mtx, f32 x, f32 y, f32 sx, f32 sy) const { + PSMTXScale(*mtx, sx, sy, 1.0f); + + mtx->m[0][3] = x; + mtx->m[1][3] = mCanvasMode == CANVASMODE_0 ? y - sy : y; + mtx->m[2][3] = 0.0f; +} + +void Screen::FillBufferGX(u32 flags, GXColor color, u32 r6) const { + if (flags != 0) { + math::MTX34 drawMtx; + Screen clone(mPosition.x, mPosition.y, mSize.x, mSize.y, mParent, CANVASMODE_1); + + if ((mFlags & 0x8) != 0) { + clone.SetUnkFlag8(); + } + + clone.SetNearZ(0.0f); + clone.SetFarZ(1.0f); + clone.SetFlag(0x40); + clone.SetProjectionType(PROJ_ORTHO); + + clone.SetProjectionGX(); + clone.CalcMatrixForDrawQuad(&drawMtx, 0.0f, 0.0f, mSize.x, mSize.y); + DrawGX::ClearEfb( + drawMtx, (flags & 1) ? true : false, (flags & 2) ? true : false, (flags & 4) ? true : false, color, true + ); + } +} + +void Screen::GetGlobalPos(f32 *ox, f32 *oy) const { + f32 px, py; + const Screen *parent = GetParent(); + + if (parent != nullptr) { + parent->GetGlobalPos(&px, &py); + parent->ConvertToCanvasLU(mPosition.x, mPosition.y, ox, oy); + + *ox += px; + *oy += py; + } else { + *ox = mPosition.x; + *oy = mPosition.y; + } +} + +void Screen::SetTVMode(TVMode tvMode) { + sTVMode = tvMode; + if (spRoot != nullptr) { + spRoot->SetSizeX(GetSizeXMax()); + spRoot->SetSizeY(GetSizeYMax()); + } + + if (sChangeTVModeFunc != nullptr) { + sChangeTVModeFunc(spChangeTVModeFuncInfo); + } +} + +void Screen::SetTVModeDefault() { + SetTVMode(SCGetAspectRatio() == SC_ASPECT_STD ? TV_MODE_4_3 : TV_MODE_16_9); +} + +void Screen::fn_804B2EE0(f32 *ox, f32 *oy, f32 a, f32 b) const { + GetGlobalPos(ox, oy); + ConvertToCanvasLU(a, b, &a, &b); + *ox = ScaleByX((*ox + a)); + *oy = ScaleByY((*oy + b)); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggScreenEffectBase.cpp b/src/egg/gfx/eggScreenEffectBase.cpp index 6e8a1f55..890c7106 100644 --- a/src/egg/gfx/eggScreenEffectBase.cpp +++ b/src/egg/gfx/eggScreenEffectBase.cpp @@ -1,3 +1,9 @@ #include "egg/gfx/eggScreenEffectBase.h" -namespace EGG {} // namespace EGG +namespace EGG { + +Screen ScreenEffectBase::sScreen; + +ScreenEffectBase::ScreenEffectBase() : mFlag(1) {} + +} // namespace EGG diff --git a/src/egg/gfx/eggScreenEffectBlur.cpp b/src/egg/gfx/eggScreenEffectBlur.cpp index 65a45952..afe15f76 100644 --- a/src/egg/gfx/eggScreenEffectBlur.cpp +++ b/src/egg/gfx/eggScreenEffectBlur.cpp @@ -1,3 +1,174 @@ #include "egg/gfx/eggScreenEffectBlur.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggCpuTexture.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggPostEffectBase.h" +#include "egg/gfx/eggPostEffectBlur.h" // IWYU pragma: keep +#include "egg/gfx/eggPostEffectUnk2.h" // IWYU pragma: keep +#include "egg/gfx/eggStateGX.h" +#include "egg/gfx/eggTextureBuffer.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXTev.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtx.h" + +#include + +namespace EGG { + +static const GXColor sDefaultColor = {0, 0, 0, 0xFF}; +static const GXColor sDefaultColor2 = {0x80, 0x80, 0x80, 0x80}; + +ScreenEffectBlur::ScreenEffectBlur() + : field_0x0C(3), + field_0x0D(0), + field_0x0E(0), + field_0x10(1.0f), + field_0x14(1.0f), + field_0x18(0.5f), + field_0x1C(1.0f), + field_0x20(0.5f), + field_0x24(0.0f), + field_0x28(sDefaultColor), + mpCpuTexture(0) { + mpUnk2 = new PostEffectUnk2(); + mpBlur = new PostEffectBlur(); + mpBlur->setField_0x00(2); + mpBlur->setStage0Field0(4); + mpBlur->setStage0Color(sDefaultColor2); + mpBlur->setStage0F(field_0x1C); +} + +ScreenEffectBlur::~ScreenEffectBlur() { + delete mpUnk2; + delete mpBlur; +} +static const CopyFilter copyFilter = { + {0x15, 0, 0, 0x16, 0, 0x15, 0} +}; +void ScreenEffectBlur::fn_804B32B0() { + if (mFlag & 1) { + StateGX::invalidateTexAllGX(); + PostEffectBase::setProjection(GetScreen()); + const Screen::DataEfb &efb = GetScreen().GetDataEfb(); + u16 x1 = efb.vp.x1; + u16 y1 = efb.vp.y1; + f32 sizeX = (u16)sScreen.GetSize().x * field_0x10; + f32 sizeY = (u16)sScreen.GetSize().y * field_0x10; + u16 x2 = efb.vp.x2 * field_0x10; + u16 y2 = efb.vp.y2 * field_0x10; + + StateGX::ScopedColor _clr(true); + StateGX::ScopedAlpha _alpha(false); + StateGX::ScopedDither _dither(false); + TextureBuffer *pTex0 = NULL; + if (field_0x0C & 1) { + pTex0 = TextureBuffer::alloc(x2, y2, GX_TF_RGBA8); + pTex0->capture(x1, y1, 0, GX_TF_RGBA8); + } + TextureBuffer *pTex1 = TextureBuffer::alloc(x2, y2, GX_TF_IA8); + pTex1->setMinFilt(GX_NEAR); + pTex1->setMagFilt(GX_NEAR); + pTex1->capture(x1, y1, false, GX_TF_Z16); + + // . . . + if (field_0x0C & 2) { + TextureBuffer *pTex2 = TextureBuffer::alloc(x2, y2, GX_TF_RGBA8); + pTex2->onCapFlag(0x8); + pTex2->setCopyFilter(copyFilter); + pTex2->capture(x1, y1, false, GX_CTF_R8); + u8 val = field_0x18 * 255.f; + GXColor clr = {val, val, val, val}; + mpBlur->setStage0Color(clr); + mpBlur->setStage0F(field_0x1C); + mpBlur->mTex1 = (PostEffectBase::CapTextureWrapper){pTex2, GX_TEXMAP1}; + mpBlur->draw(sizeX * 1.0f, sizeY * 1.0f); + pTex2->free(); + } + // . . . + + mpCpuTexture = TextureBuffer::alloc(x2, y2, GX_TF_I8); + mpCpuTexture->onCapFlag(0x8); + mpCpuTexture->setCopyFilter(copyFilter); + mpCpuTexture->capture(x1, y1, false, GX_CTF_R8); + pTex1->free(); + + if (field_0x0C & 1) { + nw4r::math::MTX34 m; + PSMTXScale(m, sizeY, sizeY, 1.f); + pTex0->load(GX_TEXMAP0); + DrawGX::BeginDrawScreen(true, true, false); + DrawGX::SetBlendMode(DrawGX::BLEND_14); + DrawGX::DrawDL16(m, DrawGX::WHITE); + pTex0->free(); + } + } +} + +void ScreenEffectBlur::fn_804B3710() { + if ((mFlag & 1) != 0) { + StateGX::invalidateTexAllGX(); + PostEffectBase::setProjection(sScreen); + nw4r::math::MTX34 mtx; + // Have to perform a float -> u16 -> float round trip here... + u16 sizeY = sScreen.GetSize().y; + u16 sizeX = sScreen.GetSize().x; + PSMTXScale(mtx, sizeX, sizeY, 0.0f); + mpCpuTexture->load(GX_TEXMAP0); + DrawGX::BeginDrawScreen(true, true, true); + GXSetTevKColor(GX_KCOLOR0, field_0x28); + GXSetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); + GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_KONST); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_KONST, GX_CA_TEXA, GX_CA_ZERO); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_GREATER, field_0x0D); + DrawGX::SetBlendMode((field_0x0C & 4) != 0 ? DrawGX::BLEND_14 : DrawGX::BLEND_0); + DrawGX::DrawDL(DrawGX::DL_16, mtx, DrawGX::WHITE); + } + if (mpCpuTexture != nullptr) { + mpCpuTexture->free(); + mpCpuTexture = nullptr; + } +} + +void ScreenEffectBlur::SetBinaryInner(const Bin &bin) { + if (bin.mHeader.mVersion != 0) { + return; + } + field_0x0C = bin.mData.field_0x00; + field_0x0D = bin.mData.field_0x01; + field_0x0E = bin.mData.field_0x02; + field_0x10 = bin.mData.field_0x04; + field_0x14 = bin.mData.field_0x08; + field_0x18 = bin.mData.field_0x0C; + field_0x1C = bin.mData.field_0x10; + field_0x20 = bin.mData.field_0x14; + field_0x24 = bin.mData.field_0x18; + field_0x28.r = bin.mData.field_0x1C; + field_0x28.g = bin.mData.field_0x1D; + field_0x28.b = bin.mData.field_0x1E; + field_0x28.a = bin.mData.field_0x1F; +} + +void ScreenEffectBlur::GetBinaryInner(Bin *bin) const { + bin->mData.field_0x00 = field_0x0C; + bin->mData.field_0x01 = field_0x0D; + bin->mData.field_0x02 = field_0x0E; + bin->mData.field_0x04 = field_0x10; + bin->mData.field_0x08 = field_0x14; + bin->mData.field_0x0C = field_0x18; + bin->mData.field_0x10 = field_0x1C; + bin->mData.field_0x14 = field_0x20; + bin->mData.field_0x18 = field_0x24; + bin->mData.field_0x1C = field_0x28.r; + bin->mData.field_0x1D = field_0x28.g; + bin->mData.field_0x1E = field_0x28.b; + bin->mData.field_0x1F = field_0x28.a; +} + +void ScreenEffectBlur::SetBinaryInner(const Bin &bin1, const Bin &bin2, f32 blend) { + // TODO +} + +} // namespace EGG diff --git a/src/egg/gfx/eggStateEfb.cpp b/src/egg/gfx/eggStateEfb.cpp index 25f2dbbb..a21cdf0b 100644 --- a/src/egg/gfx/eggStateEfb.cpp +++ b/src/egg/gfx/eggStateEfb.cpp @@ -1,3 +1,229 @@ #include "egg/gfx/eggStateEfb.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggGlobalDrawState.h" +#include "egg/gfx/eggScreen.h" +#include "egg/gfx/eggStateGX.h" +#include "egg/gfx/eggTextureBuffer.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtx.h" + +namespace EGG { + +StateEfb::Buffer StateEfb::spBufferSet[BUFFER_MAX]; +f32 StateEfb::sWorkSpaceV[6]; +f32 StateEfb::sWorkSpaceHideV[6]; +f32 StateEfb::sUnkBuffer[6]; + +u32 StateEfb::sFlag = 4; +s32 StateEfb::sWorkBuffer = -1; + +s32 StateEfb::sPushCount; + +void StateEfb::Clean() { + sFlag &= ~(1 | 2); + sWorkBuffer = -1; + sPushCount = 0; + + for (u32 i = 0; i < ARRAY_LENGTH(spBufferSet); i++) { + spBufferSet[i].field_0x08 = 0; + } + + for (u32 i = 0; i < ARRAY_LENGTH(sWorkSpaceV); i++) { + sWorkSpaceV[i] = 0.0f; + sWorkSpaceHideV[i] = 0.0f; + } +} + +TextureBuffer *StateEfb::captureEfb(BufferType type, bool noTransparencyMaybe, u32 userData) { + // NONMATCHING - GPR regswaps + const Screen::DataEfb &efb = GlobalDrawState::getScreen().GetDataEfb(); + + if (spBufferSet[type].buf == nullptr) { + f32 x1 = efb.vp.x1; + f32 y1 = efb.vp.y1; + + bool doUpscale = false; + bool doCapture = true; + + switch (type) { + case BUFFER_0: + case BUFFER_1: { + f32 arg = type == BUFFER_0 ? 0.25f : 0.5f; + + sWorkSpaceV[2] = efb.vp.x2 * arg; + sWorkSpaceV[3] = efb.vp.y2 * arg; + + sWorkSpaceV[2] = (int)sWorkSpaceV[2] + (int)sWorkSpaceV[2] % 2; + sWorkSpaceV[3] = (int)sWorkSpaceV[3] + (int)sWorkSpaceV[3] % 2; + + if (sWorkSpaceV[2] > sWorkSpaceV[3]) { + sWorkSpaceV[3] = sWorkSpaceV[2]; + } else { + sWorkSpaceV[2] = sWorkSpaceV[3]; + } + + sWorkSpaceV[0] = 640.0f - sWorkSpaceV[2]; + sWorkSpaceHideV[0] = sWorkSpaceV[0]; + sWorkSpaceV[1] = 528.0f - sWorkSpaceV[3]; + sWorkSpaceHideV[1] = sWorkSpaceV[1]; + + sWorkSpaceHideV[2] = sWorkSpaceV[2] - (640 - StateGX::s_widthEfb); + sWorkSpaceHideV[3] = sWorkSpaceV[3] - (528 - StateGX::s_heightEfb); + + if (sWorkSpaceHideV[2] < 0.0f) { + sWorkSpaceHideV[2] = 0.0f; + } + if (sWorkSpaceHideV[3] < 0.0f) { + sWorkSpaceHideV[3] = 0.0f; + } + + x1 = sWorkSpaceV[0]; + y1 = sWorkSpaceV[1]; + + TextureBuffer *buf = TextureBuffer::alloc(sWorkSpaceHideV[2], sWorkSpaceHideV[3], GX_TF_RGBA8); + spBufferSet[type].buf = buf; + if (spBufferSet[type].buf != nullptr) { + spBufferSet[type].buf->setPixModeSync(false); + } + doCapture = GetShouldCapture(); + break; + } + + case BUFFER_2: + spBufferSet[type].buf = TextureBuffer::alloc(efb.vp.x2, efb.vp.y2, GX_TF_RGBA8); + spBufferSet[type].buf->setPixModeSync(false); + break; + case BUFFER_3: + spBufferSet[type].buf = TextureBuffer::alloc( + efb.vp.x2 / 2.0f, efb.vp.y2 / 2.0f, GetUseTfRgb565() ? GX_TF_RGB565 : GX_TF_RGBA8 + ); + doUpscale = true; + break; + default: break; + } + + if (spBufferSet[type].buf != nullptr) { + spBufferSet[type].userData = userData; + if (noTransparencyMaybe) { + spBufferSet[type].buf->onCapFlag(0x2); + spBufferSet[type].buf->setClearColor((GXColor){0, 0, 0, 0}); + } + if (x1 < 0.0f) { + x1 = 0.0f; + } + if (y1 < 0.0f) { + y1 = 0.0f; + } + if (doCapture) { + spBufferSet[type].buf->capture(x1, y1, doUpscale, -1); + } + } + } + + return spBufferSet[type].buf; +} + +bool StateEfb::releaseEfb(BufferType type, u32 userData) { + if (spBufferSet[type].buf != nullptr && spBufferSet[type].userData == userData) { + spBufferSet[type].buf->free(); + spBufferSet[type].buf = nullptr; + spBufferSet[type].userData = 0; + spBufferSet[type].field_0x08 = 0; + return true; + } else { + return false; + } +} + +void StateEfb::fn_804B4270(BufferType type, u32 userData) { + if (type == BUFFER_0) { + if (sWorkBuffer == 1) { + StateEfb::releaseEfb(BUFFER_0, spBufferSet[0].userData); + } + captureEfb(BUFFER_1, false, userData); + sWorkBuffer = 0; + } else if (type == BUFFER_1 && sWorkBuffer != 0) { + captureEfb(BUFFER_0, false, userData); + sWorkBuffer = 1; + } +} + +void StateEfb::fn_804B4310(BufferType type, u32 userData) { + if (sWorkBuffer != -1) { + BufferType i = static_cast(-1); + if (sWorkBuffer == 0) { + i = BUFFER_1; + } else if (sWorkBuffer == 1) { + i = BUFFER_0; + } + + if (spBufferSet[i].userData == userData) { + if (type == BUFFER_0) { + StateGX::ScopedColor colorGuard(true); + StateGX::ScopedAlpha alphaGuard(true); + StateGX::ScopedDither ditherGuard(false); + + const Screen &parentScreen = GlobalDrawState::getScreen(); + Screen s(parentScreen); + + s.SetFlag(Screen::FLAG_0x40); + s.SetCanvasMode(Screen::CANVASMODE_1); + s.SetProjectionType(Screen::PROJ_ORTHO); + s.SetNearFar(0.0f, 1.0f); + s.SetScale(nw4r::math::VEC3(1.0f, 1.0f, 1.0f)); + s.SetOffset(nw4r::math::VEC2(0.0f, 0.0f)); + + s.SetProjectionGX(); + StateGX::GXSetViewport_( + sWorkSpaceHideV[0], sWorkSpaceHideV[1], sWorkSpaceHideV[2], sWorkSpaceHideV[3], 0.0f, 1.0f + ); + StateGX::GXSetScissor_(sWorkSpaceHideV[0], sWorkSpaceHideV[1], sWorkSpaceHideV[2], sWorkSpaceHideV[3]); + StateGX::GXSetScissorBoxOffset_(0, 0); + + nw4r::math::MTX34 mtx; + PSMTXScale(mtx, parentScreen.GetSize().x, parentScreen.GetSize().y, 1.0f); + + DrawGX::BeginDrawScreen(true, GetShouldCapture(), false); + DrawGX::SetBlendMode(DrawGX::BLEND_14); + if (GetShouldCapture()) { + TextureBuffer *buf = spBufferSet[i].buf; + buf->setFilt(GX_NEAR, GX_NEAR); + buf->load(DrawGX::GetTexMapDefault()); + DrawGX::DrawDL(DrawGX::DL_16, mtx, DrawGX::WHITE); + } + } + releaseEfb((i), spBufferSet[i].userData); + sWorkBuffer = -1; + sPushCount += 1; + } + } +} + +f32 *StateEfb::fn_804B4550() { + const Screen::DataEfb &efb = GlobalDrawState::getScreen().GetDataEfb(); + sUnkBuffer[0] = sWorkSpaceV[0]; + sUnkBuffer[1] = sWorkSpaceV[1]; + sUnkBuffer[2] = efb.vp.x2; + sUnkBuffer[3] = efb.vp.y2; + sUnkBuffer[4] = efb.vp.z1; + sUnkBuffer[5] = efb.vp.z2; + StateGX::GXSetViewport_(sUnkBuffer[0], sUnkBuffer[1], sUnkBuffer[2], sUnkBuffer[3], sUnkBuffer[4], sUnkBuffer[5]); + u32 f[4]; + StateGX::CalculateScreenScissor(sUnkBuffer, f); + StateGX::GXSetScissor_(f[0], f[1], f[2], f[3]); + StateGX::GXSetScissorBoxOffset_(0, 0); + return sUnkBuffer; +} + +bool StateEfb::GetShouldCapture() { + return ((sFlag >> 2) & 1) != 0; +} + +bool StateEfb::GetUseTfRgb565() { + return (sFlag & 8) != 0; +} + +} // namespace EGG diff --git a/src/egg/gfx/eggStateGX.cpp b/src/egg/gfx/eggStateGX.cpp index baf181f0..fc56e29e 100644 --- a/src/egg/gfx/eggStateGX.cpp +++ b/src/egg/gfx/eggStateGX.cpp @@ -1,3 +1,323 @@ #include "egg/gfx/eggStateGX.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/core/eggDisplay.h" +#include "egg/core/eggSystem.h" +#include "nw4r/g3d/g3d_init.h" +#include "nw4r/g3d/platform/g3d_tmem.h" +#include "rvl/GX/GXAttr.h" +#include "rvl/GX/GXBump.h" +#include "rvl/GX/GXFrameBuf.h" +#include "rvl/GX/GXGeometry.h" +#include "rvl/GX/GXPixel.h" +#include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTransform.h" +#include "rvl/GX/GXTypes.h" + +#include + +namespace { + +static GXTexRegion *texRegionCallback(const GXTexObj *pObj, GXTexMapID map) { + return &EGG::StateGX::s_tmem_layout.mRegions[map % EGG::StateGX::s_tmem_layout.numRegions]; +} + +static const GXColor white = {0xFF, 0xFF, 0xFF, 0xFF}; + +static const f32 identity[3][4] = { + {1.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, 1.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 1.0f, 0.0f}, +}; + +} // namespace + +namespace EGG { + +GXTexObj ALIGN_DECL(32) StateGX::sDefaultTexObj; +StateGX::MemLayout StateGX::s_tmem_layout; +StateGX::CacheGX StateGX::s_cacheGX; + +u16 StateGX::s_widthEfb; +u16 StateGX::s_heightEfb; +GXPixelFmt StateGX::s_pixFormat; +GXZFmt16 StateGX::s_zFmt16; +GXColor StateGX::s_clearEfb; +u16 StateGX::s_flag; +u16 StateGX::s_commandFlag; + +void StateGX::initialize(u16 width, u16 height, GXColor color, GXPixelFmt pixelFmt) { + s_widthEfb = width; + s_heightEfb = height; + s_clearEfb = color; + s_pixFormat = pixelFmt; + + if (BaseSystem::getDisplay() != nullptr) { + BaseSystem::getDisplay()->setClearColor(color); + } + + static u8 sDefaultTexObjData[16] = {0}; + + GXInitTexObj(&sDefaultTexObj, sDefaultTexObjData, 4, 4, GX_TF_IA8, GX_CLAMP, GX_CLAMP, 0); + GXInitTexObjLOD(&sDefaultTexObj, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1); + invalidateTexAllGX(); + frameInit(); + setTMemLayout(nw4r::g3d::tmem::TMEM_LAYOUT_1); +} + +void StateGX::frameInit() { + GXSetPixelFmt_(s_pixFormat, s_zFmt16); + if (BaseSystem::mConfigData->getDisplay() != nullptr) { + s_clearEfb = BaseSystem::mConfigData->getDisplay()->getClearColor(); + } + GXInvalidateVtxCache(); + GXSetCurrentMtx(0); + GXSetCoPlanar(false); + GXSetClipMode(GX_CLIP_ENABLE); + resetGX(); + nw4r::g3d::G3dReset(); +} + +void StateGX::setTMemLayout(int layout) { + s_tmem_layout.mLayout = layout; + if (nw4r::g3d::tmem::TMEM_LAYOUT_NONE <= layout && layout <= nw4r::g3d::tmem::TMEM_LAYOUT_3) { + nw4r::g3d::tmem::SetTMemLayout(static_cast(layout)); + s_tmem_layout.numRegions = 8; + } else { + static const u32 numbers[4] = {0x8, 0x4, 0x1, 0x7}; + static const u32 offsets[4] = {0x8000, 0x20000, 0x80000, 0}; + + u32 index = layout - 4; + s_tmem_layout.numRegions = numbers[index]; + for (u32 i = 0; i < 8; i++) { + std::memset(&s_tmem_layout.mRegions[i], 0, sizeof(GXTexRegion)); + } + + u32 addr = 0; + for (u32 i = 0; i < numbers[index]; i++) { + int u1 = layout == 7 ? (0 <= i && i < 3 ? 1 : 0) : index; + if ((i & 1) != 0) { + GXInitTexCacheRegion(&s_tmem_layout.mRegions[i], false, addr + 0x80000, u1, addr, u1); + } else { + GXInitTexCacheRegion(&s_tmem_layout.mRegions[i], false, addr, u1, addr + 0x80000, u1); + } + addr += offsets[u1]; + } + GXSetTexRegionCallback(texRegionCallback); + } +} + +void StateGX::resetGX() { + if ((s_flag & 1) == 0) { + resetVtx(); + resetIndirect(); + resetColorChannel(); + resetTexture(); + resetTexGen(); + resetTev(); + resetPE(); + } + resetGXCache(); +} + +void StateGX::resetVtx() { + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_CLR_RGB, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR1, GX_CLR_RGBA, GX_RGBA8, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGBA4, 7); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX1, GX_CLR_RGBA, GX_RGBA4, 7); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX2, GX_CLR_RGBA, GX_RGBA4, 7); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX3, GX_CLR_RGBA, GX_RGBA4, 7); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX4, GX_CLR_RGBA, GX_RGBA4, 7); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX5, GX_CLR_RGBA, GX_RGBA4, 7); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX6, GX_CLR_RGBA, GX_RGBA4, 7); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX7, GX_CLR_RGBA, GX_RGBA4, 7); +} + +void StateGX::resetColorChannel() { + GXSetNumChans(1); + GXSetChanAmbColor(GX_COLOR0A0, white); + GXSetChanAmbColor(GX_COLOR1A1, white); + + GXSetChanMatColor(GX_COLOR0A0, white); + + GXSetChanMatColor(GX_COLOR1A1, white); + GXSetCullMode(GX_CULL_BACK); + GXSetChanCtrl(GX_COLOR0A0, false, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_NONE); + GXSetChanCtrl(GX_COLOR1A1, false, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_NONE); +} + +void StateGX::resetIndirect() { + GXSetNumIndStages(0); + static const f32 ind[2][3] = { + {0.5f, 0.0f, 0.0f}, + {0.0f, 0.5f, 0.0f}, + }; + for (u32 i = 0; i < 3; i++) { + GXSetIndTexMtx(static_cast(i + GX_ITM_0), ind, 1); + } + for (u32 i = 0; i < 4; i++) { + GXSetIndTexCoordScale(static_cast(i + GX_INDTEXSTAGE0), GX_ITS_1, GX_ITS_1); + } +} + +void StateGX::resetTexture() { + for (u32 i = 0; i < s_tmem_layout.numRegions; i++) { + GXLoadTexObj(&sDefaultTexObj, static_cast(i + GX_TEXMAP0)); + } +} + +void StateGX::resetTexGen() { + GXSetNumTexGens(1); + + for (u32 i = 0; i < 10; i++) { + GXLoadTexMtxImm(identity, i * 3 + 0x1E, GX_MTX_3x4); + } + + for (u32 i = 0; i < GX_MAX_TEXCOORD; i++) { + GXTexCoordID id = static_cast(i); + GXSetTexCoordGen2(id, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, 0, 0x7d); + GXSetTexCoordScaleManually(id, false, 0, 0); + GXSetTexCoordBias(id, false, false); + } +} + +void StateGX::resetTev() { + GXSetNumTevStages(1); + for (u32 i = 0; i < GX_MAX_TEVSTAGE; i++) { + GXTevStageID id = static_cast(i); + GXSetTevDirect(id); + GXSetTevOrder(id, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevColorIn(id, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO); + GXSetTevColorOp(id, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevAlphaOp(id, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevSwapMode(id, GX_TEV_SWAP0, GX_TEV_SWAP0); + } + + for (u32 i = 0; i < GX_MAX_KCOLOR; i++) { + GXTevKColorID id = static_cast(i); + GXSetTevKColor(id, white); + } + + for (u32 i = 0; i < GX_MAX_TEVREG; i++) { + GXTevRegID id = static_cast(i); + GXSetTevColor(id, white); + } + + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_RED, GX_CH_RED, GX_CH_ALPHA); + GXSetTevSwapModeTable(GX_TEV_SWAP2, GX_CH_GREEN, GX_CH_GREEN, GX_CH_GREEN, GX_CH_ALPHA); + GXSetTevSwapModeTable(GX_TEV_SWAP3, GX_CH_BLUE, GX_CH_BLUE, GX_CH_BLUE, GX_CH_ALPHA); +} + +void StateGX::resetPE() { + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); + GXSetZTexture(0, GX_TF_Z24X8, 0); + GXSetZMode(true, GX_LEQUAL, true); + GXSetFog(GX_FOG_NONE, white, 0.0f, 1.0f, 0.1f, 1.0f); + GXSetFogRangeAdj(false, 0, nullptr); + GXSetZCompLoc(true); + GXSetDstAlpha(false, 0); +} + +void StateGX::resetGXCache() { + GXSetColorUpdate_(true); + GXSetAlphaUpdate_(true); + GXSetDither_(true); + GXSetDstAlpha_(false, 0); +} + +void StateGX::GXSetPixelFmt_(GXPixelFmt pixelFmt, GXZFmt16 zFmt) { + GXPixelFmt oldPixelFmt; + GXZFmt16 oldZFmt; + + GXGetPixelFmt(&oldPixelFmt, &oldZFmt); + if (pixelFmt != oldPixelFmt || zFmt != oldZFmt) { + GXBool oldColorUpdate; + GXGetColorUpdate(&oldColorUpdate); + bool bOldColorUpdate = oldColorUpdate; + GXBool oldAlphaUpdate; + GXGetAlphaUpdate(&oldAlphaUpdate); + bool bOldAlphaUpdate = oldAlphaUpdate; + + GXSetPixelFmt(pixelFmt, zFmt); + GXSetColorUpdate(bOldColorUpdate); + GXSetAlphaUpdate(bOldAlphaUpdate); + } +} + +void StateGX::invalidateTexAllGX() { + GXInvalidateTexAll(); +} + +bool StateGX::GXSetColorUpdate_(bool enable) { + GXBool oldEnable; + GXGetColorUpdate(&oldEnable); + bool bOldEnable = oldEnable; + GXSetColorUpdate(enable); + return bOldEnable; +} + +bool StateGX::GXSetAlphaUpdate_(bool enable) { + GXBool oldEnable; + GXGetAlphaUpdate(&oldEnable); + bool bOldEnable = oldEnable; + GXSetAlphaUpdate(enable); + return bOldEnable; +} + +bool StateGX::GXSetDither_(bool enable) { + GXBool oldEnable; + GXGetDither(&oldEnable); + bool bOldEnable = oldEnable; + GXSetDither(enable); + return bOldEnable; +} + +void StateGX::GXCopyTex_(void *data, bool bUpdate) { + GXCopyTex(data, bUpdate); +} + +StateGX::CacheGX &StateGX::GXSetDstAlpha_(bool enable, u8 alpha) { + GXSetDstAlpha(enable, alpha); + s_cacheGX.mDstAlphaEnable = enable; + s_cacheGX.mDstAlpha = alpha; + return s_cacheGX; +} + +void StateGX::CalculateScreenScissor(const f32 src[4], u32 dst[4]) { + dst[0] = src[0] >= 0.0f ? src[0] : 0.0f; + dst[1] = src[1] >= 0.0f ? src[1] : 0.0f; + dst[2] = dst[0] + src[2] > 640.0f ? 640 - dst[0] : src[2]; + dst[3] = dst[1] + src[3] > 528.0f ? 528 - dst[1] : src[3]; +} + +void StateGX::GXSetProjection_(Mtx44 proj, GXProjectionType type) { + GXSetProjection(proj, type); + s_commandFlag |= 1; +} + +void StateGX::GXSetProjectionv_(const f32 *proj) { + GXSetProjectionv(proj); + s_commandFlag |= 1; +} + +void StateGX::GXSetViewport_(f32 ox, f32 oy, f32 sx, f32 sy, f32 near, f32 far) { + GXSetViewport(ox, oy, sx, sy, near, far); + s_commandFlag |= 2; +} + +void StateGX::GXSetScissor_(u32 x, u32 y, u32 w, u32 h) { + GXSetScissor(x, y, w, h); + s_commandFlag |= 4; +} + +void StateGX::GXSetScissorBoxOffset_(s32 ox, s32 oy) { + GXSetScissorBoxOffset(ox, oy); + s_commandFlag |= 8; +} + +} // namespace EGG diff --git a/src/egg/gfx/eggTexture.cpp b/src/egg/gfx/eggTexture.cpp index 0e673cef..4d2e9a38 100644 --- a/src/egg/gfx/eggTexture.cpp +++ b/src/egg/gfx/eggTexture.cpp @@ -1,3 +1,119 @@ #include "egg/gfx/eggTexture.h" -namespace EGG {} // namespace EGG +namespace EGG { + +Texture::~Texture() { + if (getCaptureFlag()) { + delete[] field_0x3c; + } + if (getEmbPaletteDelFlag()) { + delete mEmbPalette; + } +} + +void Texture::storeTIMG(ResTIMG const *pTIMG, u8 param0) { + GXTlut tlut; + + if (pTIMG && param0 < GX_BIGTLUT0) { + mTexInfo = pTIMG; + mTexData = (void *)((int)mTexInfo + mTexInfo->imageOffset); + + if (mTexInfo->imageOffset == 0) { + mTexData = (void *)((int)mTexInfo + 0x20); + } + + mpPalette = NULL; + mTlutName = 0; + mWrapS = mTexInfo->wrapS; + mWrapT = mTexInfo->wrapT; + mMinFilter = mTexInfo->minFilter; + mMagFilter = mTexInfo->magFilter; + mMinLOD = mTexInfo->minLOD; + mMaxLOD = mTexInfo->maxLOD; + mLODBias = mTexInfo->LODBias; + + if (mTexInfo->numColors == 0) { + initTexObj(); + } else { + if (mTexInfo->numColors > 0x100) { + tlut = (GXTlut)((param0 % 4) + GX_BIGTLUT0); + } else { + tlut = (GXTlut)param0; + } + + if (mEmbPalette == NULL || !getEmbPaletteDelFlag()) { + mEmbPalette = new Palette( + tlut, (GXTlutFmt)mTexInfo->colorFormat, (JUTTransparency)mTexInfo->alphaEnabled, + mTexInfo->numColors, (void *)(&mTexInfo->format + mTexInfo->paletteOffset) + ); + mFlags = mFlags & 1 | 2; + } else { + mEmbPalette->storeTLUT( + tlut, (GXTlutFmt)mTexInfo->colorFormat, (JUTTransparency)mTexInfo->alphaEnabled, + mTexInfo->numColors, (void *)(&mTexInfo->format + mTexInfo->paletteOffset) + ); + } + attachPalette(mEmbPalette); + } + } +} + +void Texture::attachPalette(Palette *param_0) { + if (mTexInfo->indexTexture) { + if (param_0 == NULL && mEmbPalette != NULL) { + mpPalette = mEmbPalette; + } else { + mpPalette = param_0; + } + GXTlut name = (GXTlut)mpPalette->getTlutName(); + initTexObj(name); + } +} + +void Texture::initTexObj() { + GXBool mipmapEnabled; + if (mTexInfo->mipmapEnabled != 0) { + mipmapEnabled = 1; + } else { + mipmapEnabled = 0; + } + u8 *image = ((u8 *)mTexInfo); + image += (mTexInfo->imageOffset ? mTexInfo->imageOffset : 0x20); + GXInitTexObj( + &mTexObj, image, mTexInfo->width, mTexInfo->height, (GXTexFmt)mTexInfo->format, (GXTexWrapMode)mWrapS, + (GXTexWrapMode)mWrapT, mipmapEnabled + ); + GXInitTexObjLOD( + &mTexObj, (GXTexFilter)mMinFilter, (GXTexFilter)mMagFilter, mMinLOD / 8.0f, mMaxLOD / 8.0f, mLODBias / 100.0f, + mTexInfo->biasClamp, mTexInfo->doEdgeLOD, (GXAnisotropy)mTexInfo->maxAnisotropy + ); +} + +void Texture::initTexObj(GXTlut param_0) { + GXBool mipmapEnabled; + if (mTexInfo->mipmapEnabled != 0) { + mipmapEnabled = 1; + } else { + mipmapEnabled = 0; + } + mTlutName = param_0; + u8 *image = ((u8 *)mTexInfo); + image += (mTexInfo->imageOffset ? mTexInfo->imageOffset : 0x20); + GXInitTexObjCI( + &mTexObj, image, mTexInfo->width, mTexInfo->height, (GXCITexFmt)mTexInfo->format, (GXTexWrapMode)mWrapS, + (GXTexWrapMode)mWrapT, mipmapEnabled, param_0 + ); + GXInitTexObjLOD( + &mTexObj, (GXTexFilter)mMinFilter, (GXTexFilter)mMagFilter, mMinLOD / 8.0f, mMaxLOD / 8.0f, mLODBias / 100.0f, + mTexInfo->biasClamp, mTexInfo->doEdgeLOD, (GXAnisotropy)mTexInfo->maxAnisotropy + ); +} + +void Texture::load(GXTexMapID param_0) { + if (mpPalette) { + mpPalette->load(); + } + GXLoadTexObj(&mTexObj, param_0); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggTextureBuffer.cpp b/src/egg/gfx/eggTextureBuffer.cpp index ed1b41e1..c08f7f45 100644 --- a/src/egg/gfx/eggTextureBuffer.cpp +++ b/src/egg/gfx/eggTextureBuffer.cpp @@ -1,3 +1,198 @@ #include "egg/gfx/eggTextureBuffer.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggCpuTexture.h" +#include "egg/gfx/eggStateGX.h" +#include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +TextureBuffer::TextureBuffer() : mSize(0), mState(STATE_FREE), mpNext(nullptr), mpPrev(nullptr) {} + +void TextureBuffer::configure() { + CapTexture::configure(); + setClearColor(StateGX::getClearEfb()); + setWrap(GX_CLAMP, GX_CLAMP); + setFilt(GX_LINEAR, GX_LINEAR); + setPixModeSync(true); +} + +// Allow buffer to be reclaimed +void TextureBuffer::free() { + mState = STATE_FREE; + sBufferSize += mSize; + + // Check if previous buffer is reclaimable + if (mpPrev != nullptr && mpPrev->mState == STATE_FREE) { + // Merge with previous buffer + mSize += mpPrev->mSize; + setBuffer((u8 *)getBuffer() - mpPrev->mSize); + + // Append reusable buffer + TextureBuffer *beforeAppend = mpPrev->mpPrev; + append(mpPrev); + + // Repair mpPrev link + mpPrev = beforeAppend; + if (beforeAppend != nullptr) { + beforeAppend->mpNext = this; + } else { + spHead = this; + } + } + + // Check if next buffer is reclaimable + if (mpNext != nullptr && mpNext->mState == STATE_FREE) { + // Merge with next buffer + mSize += mpNext->mSize; + + // Append reusable buffer + TextureBuffer *afterAppend = mpNext->mpNext; + append(mpNext); + + // Repair mpNext link + mpNext = afterAppend; + if (afterAppend != nullptr) { + afterAppend->mpPrev = this; + } + } +} + +// Alloc list buffer +void TextureBuffer::initialize(u32 size, Heap *heap_) { + Heap *heap = heap_ == nullptr ? Heap::getCurrentHeap() : heap_; + if (includesHeader()) { + size += 0x20; + } + + sBufferAllSize = size; + spBufferAll = new (heap, 32) char[size]; + + if (includesHeader()) { + spBufferAll += 0x20; + } + + sBufferSize = size; + sBufferRestSizeMin = size; + spTailNotJoin = nullptr; + for (int i = 0; i < NUM_BUFFERS; i++) { + spBufferTable[i] = new TextureBuffer(); + spBufferTable[i]->configure(); + append(spBufferTable[i]); + } + + // Initialize head + spHead = getNotJoin(); + spHead->mState = STATE_FREE; + spHead->mSize = size; + spHead->setBuffer(spBufferAll); +} + +// Remove and return buffer at list end +TextureBuffer *TextureBuffer::getNotJoin() { + TextureBuffer *p_buffer = spTailNotJoin; + + // Move list tail back + spTailNotJoin = spTailNotJoin->mpPrev; + if (spTailNotJoin != nullptr) { + spTailNotJoin->mpNext = nullptr; + } + + // Pop old tail + p_buffer->mpPrev = nullptr; + return p_buffer; +} + +// Attempt to alloc buffer of specified size +void TextureBuffer::alloc(u32 size) { + size = ROUND_UP(size, 0x20); + + sBufferSize -= size; + if (sBufferSize < sBufferRestSizeMin) { + sBufferRestSizeMin = sBufferSize; + } + + // Try to find a free buffer with at least the requested size + for (TextureBuffer *p_list = spHead; p_list != nullptr; p_list = p_list->mpNext) { + if (p_list->mState == STATE_FREE && p_list->mSize >= size) { + // Assign free buffer data to new buffer + mState = STATE_ALLOCED; + mSize = size; + + u8 *buffer = (u8 *)p_list->getBuffer(); + if (includesHeader()) { + setBuffer(buffer); + if (buffer != nullptr) { + setFlag(HAS_HEADER); + } + } else { + setBuffer(buffer); + } + + // Prepend new buffer before old buffer + mpNext = p_list; + TextureBuffer *oldPrev = p_list->mpPrev; + mpPrev = oldPrev; + + // Fix this->prev link + if (oldPrev != nullptr) { + oldPrev->mpNext = this; + } else { + // nullptr prev buffer must be list head + + spHead = this; + } + + // Remove requested size from old buffer + p_list->mSize -= size; + + // Free old buffer if now empty + if (p_list->mSize == 0) { + if (p_list->mpNext != nullptr) { + p_list->mpNext->mpPrev = this; + } + mpNext = p_list->mpNext; + append(p_list); + } + // Adjust old buffer by requested size + else { + p_list->setBuffer(buffer + size); + p_list->mpPrev = this; + } + + return; + } + } +} + +TextureBuffer *TextureBuffer::alloc(u16 width, u16 height, GXTexFmt fmt) { + if (width == 0 || height == 0) { + return nullptr; + } + TextureBuffer *tex = getNotJoin(); + tex->setWidth(width); + tex->setHeight(height); + tex->setFormat(fmt); + tex->configure(); + tex->alloc(GXGetTexBufferSize(tex->getWidth(), tex->getHeight(), tex->getFormat(), false, 1)); + return tex; +} + +void TextureBuffer::setIncludesHeader(bool b) { + sIncludesHeader = b; +} + +bool TextureBuffer::includesHeader() { + return sIncludesHeader; +} + +TextureBuffer *TextureBuffer::spHead; +TextureBuffer *TextureBuffer::spTailNotJoin; +char *TextureBuffer::spBufferAll; +u32 TextureBuffer::sBufferAllSize; +u32 TextureBuffer::sBufferSize; +u32 TextureBuffer::sBufferRestSizeMin; +bool TextureBuffer::sIncludesHeader; + +} // namespace EGG diff --git a/src/m/m2d.cpp b/src/m/m2d.cpp index 9f591a69..3f2ec24d 100644 --- a/src/m/m2d.cpp +++ b/src/m/m2d.cpp @@ -295,9 +295,9 @@ void Simple_c::draw() { f32 near = 0.0f; f32 far = 500.0f; EGG::Screen s; - bool needsAdjust = EGG::Screen::GetTVMode() == EGG::Screen::TV_MODE_2; - f32 f1 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_2); - f32 f2 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_1); + bool needsAdjust = EGG::Screen::GetTVMode() == EGG::Screen::TV_MODE_16_9; + f32 f1 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_16_9); + f32 f2 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_4_3); f32 left = needsAdjust ? f1 * r.left / f2 : r.left; f32 right = needsAdjust ? f1 * r.right / f2 : r.right; diff --git a/src/m/m3d/m3d.cpp b/src/m/m3d/m3d.cpp index 688be98d..f701c3c3 100644 --- a/src/m/m3d/m3d.cpp +++ b/src/m/m3d/m3d.cpp @@ -1,7 +1,11 @@ #include "m/m3d/m3d.h" #include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggFogManager.h" #include "egg/gfx/eggGfxEngine.h" +#include "egg/gfx/eggLightManager.h" +#include "egg/gfx/eggLightTexture.h" +#include "egg/gfx/eggLightTextureMgr.h" #include "egg/gfx/eggScreen.h" #include "egg/gfx/eggStateGX.h" #include "m/m_heap.h" @@ -11,6 +15,7 @@ #include "nw4r/g3d/g3d_state.h" #include "nw4r/g3d/res/g3d_resmat.h" #include "nw4r/g3d/res/g3d_resmdl.h" + #include "rvl/GX.h" // IWYU pragma: export namespace m3d { @@ -180,7 +185,7 @@ void drawDone(int idx) { internal::l_lightMgr_pp[idx]->DoneDraw(); } if (internal::l_fogMgr_pp && internal::l_fogMgr_pp[idx]) { - internal::l_fogMgr_pp[idx]->mFlag &= 0xFB; + internal::l_fogMgr_pp[idx]->DoneDraw(); } } diff --git a/src/nw4r/g3d/g3d_anmtexpat.cpp b/src/nw4r/g3d/g3d_anmtexpat.cpp index 1dd1287b..587d77b8 100644 --- a/src/nw4r/g3d/g3d_anmtexpat.cpp +++ b/src/nw4r/g3d/g3d_anmtexpat.cpp @@ -499,10 +499,7 @@ void ApplyTexPatAnmResult(ResTexObj texObj, ResTlutObj tlutObj, const TexPatAnmR if (tex.IsCIFmt()) { tex.GetTexObjCIParam(&pTexData, &width, &height, &cifmt, &minLod, &maxLod, &mipmap); - GXInitTexObjCI( - pGXObj, pTexData, width, height, static_cast(cifmt), wrapS, wrapT, mipmap, - static_cast(i) - ); + GXInitTexObjCI(pGXObj, pTexData, width, height, cifmt, wrapS, wrapT, mipmap, static_cast(i)); } else { tex.GetTexObjParam(&pTexData, &width, &height, &fmt, &minLod, &maxLod, &mipmap); diff --git a/src/nw4r/g3d/res/g3d_resmat.cpp b/src/nw4r/g3d/res/g3d_resmat.cpp index be7a96da..6aee3a52 100644 --- a/src/nw4r/g3d/res/g3d_resmat.cpp +++ b/src/nw4r/g3d/res/g3d_resmat.cpp @@ -1566,9 +1566,7 @@ void ResTexPlttInfo::BindTex_(const ResTex tex, ResTexObj texObj) { GXCITexFmt fmtCi; tex.GetTexObjCIParam(&pTexData, &width, &height, &fmtCi, &minLod, &maxLod, &mipmap); - GXInitTexObjCI( - pGXObj, pTexData, width, height, static_cast(fmtCi), r.wrap_s, r.wrap_t, mipmap, r.tlutID - ); + GXInitTexObjCI(pGXObj, pTexData, width, height, fmtCi, r.wrap_s, r.wrap_t, mipmap, r.tlutID); } else { GXTexFmt fmt; tex.GetTexObjParam(&pTexData, &width, &height, &fmt, &minLod, &maxLod, &mipmap); diff --git a/src/nw4r/g3d/res/g3d_resmdl.cpp b/src/nw4r/g3d/res/g3d_resmdl.cpp index 1e49d94e..145b525b 100644 --- a/src/nw4r/g3d/res/g3d_resmdl.cpp +++ b/src/nw4r/g3d/res/g3d_resmdl.cpp @@ -1,4 +1,5 @@ #include "nw4r/g3d.h" // IWYU pragma: export +#include "nw4r/g3d/res/g3d_resmat.h" namespace nw4r { namespace g3d { @@ -192,8 +193,8 @@ u32 ResMdl::GetResShpNumEntries() const { * ResTexPlttInfo * ******************************************************************************/ -ResTexPlttInfo ResMdl::GetResTexPlttInfoOffsetFromTexName(int idx) const { - return ResTexPlttInfo(ofs_to_obj(ref().toResTexNameToTexPlttInfoDic)[idx]); + ResTexPlttInfoOffset ResMdl::GetResTexPlttInfoOffsetFromTexName(int idx) const { + return ResTexPlttInfoOffset(ofs_to_obj(ref().toResTexNameToTexPlttInfoDic)[idx]); } u32 ResMdl::GetResTexPlttInfoOffsetFromTexNameNumEntries() const { diff --git a/src/nw4r/lyt/lyt_texMap.cpp b/src/nw4r/lyt/lyt_texMap.cpp index 47288be1..a1bf8c3f 100644 --- a/src/nw4r/lyt/lyt_texMap.cpp +++ b/src/nw4r/lyt/lyt_texMap.cpp @@ -19,8 +19,8 @@ void TexMap::Get(GXTexObj *pTexObj) const { if (detail::IsCITexelFormat(GetTexelFormat())) { u32 tlutName = GXGetTexObjTlut(pTexObj); GXInitTexObjCI( - pTexObj, GetImage(), GetWidth(), GetHeight(), GetTexelFormat(), GetWrapModeS(), GetWrapModeT(), IsMipMap(), - tlutName + pTexObj, GetImage(), GetWidth(), GetHeight(), (GXCITexFmt)GetTexelFormat(), GetWrapModeS(), GetWrapModeT(), + IsMipMap(), tlutName ); } else { GXInitTexObj( diff --git a/src/toBeSorted/arc_callback_handler.cpp b/src/toBeSorted/arc_callback_handler.cpp index 680d8589..aca65dd4 100644 --- a/src/toBeSorted/arc_callback_handler.cpp +++ b/src/toBeSorted/arc_callback_handler.cpp @@ -1,7 +1,9 @@ #include "d/col/bg/d_bg_s.h" #include "d/col/bg/d_bg_w_kcol.h" #include "d/d_rawarchive.h" -#include "egg/gfx/eggLight.h" +#include "egg/gfx/eggG3DUtility.h" +#include "egg/gfx/eggLightTextureMgr.h" +#include "egg/gfx/eggLightManager.h" #include "m/m3d/m3d.h" #include "nw4r/g3d.h" // IWYU pragma: export #include "toBeSorted/arc_managers/current_stage_arc_manager.h" @@ -15,8 +17,6 @@ ArcCallbackHandler ArcCallbackHandler::sInstance; #define NAME_OARC 'oarc' #define NAME_RARC 'rarc' -extern "C" void FUN_804a7260(nw4r::g3d::ResMdl, const char *prefix); - void BindSystemModelsAndLighting(nw4r::g3d::ResFile file) { nw4r::g3d::ResFile sysFile(OarcManager::GetInstance()->getMdlFromArc2("System")); if (sysFile.IsValid()) { @@ -29,7 +29,7 @@ void BindSystemModelsAndLighting(nw4r::g3d::ResFile file) { for (int i = 0; i < file.GetResMdlNumEntries(); i++) { nw4r::g3d::ResMdl mdl = file.GetResMdl(i); lightTexMgr->replaceModelTextures(mdl); - FUN_804a7260(mdl, "Lm"); + EGG::G3DUtility::ApplyLightMat(mdl, "Lm"); for (int j = 0; j < mdl.GetResMatNumEntries(); j++) { nw4r::g3d::ResMat mat = mdl.GetResMat(j); if (mat.IsOpaque()) { diff --git a/src/toBeSorted/d_d3d.cpp b/src/toBeSorted/d_d3d.cpp index 9ed56f95..0b885de7 100644 --- a/src/toBeSorted/d_d3d.cpp +++ b/src/toBeSorted/d_d3d.cpp @@ -327,7 +327,7 @@ void setRoomTevColors(nw4r::g3d::ResMdl mdl, int b1, bool bUnk) { void UnkWithWater::calc(EGG::CpuTexture *tex) { GXTexObj obj; if (tex != nullptr) { - tex->GetTexObj(&obj); + tex->getTexObj(&obj); } for (NodeList::Iterator it = mList.GetBeginIter(); it != mList.GetEndIter(); ++it) {