From c2a4909bd2a9a23d73a65f6840e8c886658cef74 Mon Sep 17 00:00:00 2001 From: Elijah Thomas Date: Sun, 24 Dec 2023 11:35:03 -0500 Subject: [PATCH] updated nw4r stuff from ogw (not final) --- include/MSL_C/MSL_Common/Src/fdlibm.h | 121 ++-- include/MSL_C/MSL_Common/Src/limits.h | 31 + include/MSL_C/MSL_Common/Src/wmem.h | 14 + include/MSL_C/MSL_Common/Src/wprintf.h | 14 + include/MSL_C/MSL_Common/Src/wstring.h | 18 + include/MSL_C/limits.h | 30 + include/MSL_C/math.h | 66 +- include/MSL_C/wchar.h | 19 + include/common.h | 2 + include/decomp.h | 47 ++ include/egg/core/eggColorFader.h | 3 +- include/egg/core/eggDisplay.h | 2 +- include/egg/core/eggDisposer.h | 2 +- include/egg/core/eggDvdFile.h | 3 +- include/egg/core/eggHeap.h | 3 +- include/egg/core/eggThread.h | 3 +- include/egg/math/eggVector.h | 3 +- include/nw4r/ef/ef_animcurve.h | 13 + include/nw4r/ef/ef_creationqueue.h | 46 ++ include/nw4r/ef/ef_cube.h | 16 + include/nw4r/ef/ef_cylinder.h | 16 + include/nw4r/ef/ef_disc.h | 16 + include/nw4r/ef/ef_drawbillboardstrategy.h | 22 + include/nw4r/ef/ef_drawdirectionalstrategy.h | 22 + include/nw4r/ef/ef_drawfreestrategy.h | 21 + include/nw4r/ef/ef_drawinfo.h | 16 + include/nw4r/ef/ef_drawlinestrategy.h | 21 + include/nw4r/ef/ef_draworder.h | 20 + include/nw4r/ef/ef_draworderbase.h | 18 + include/nw4r/ef/ef_drawpointstrategy.h | 22 + include/nw4r/ef/ef_drawsmoothstripestrategy.h | 22 + include/nw4r/ef/ef_drawstrategy.h | 17 + include/nw4r/ef/ef_drawstrategybuilder.h | 27 + include/nw4r/ef/ef_drawstrategyimpl.h | 44 ++ include/nw4r/ef/ef_drawstripestrategy.h | 22 + include/nw4r/ef/ef_effect.h | 59 ++ include/nw4r/ef/ef_effectsystem.h | 57 ++ include/nw4r/ef/ef_emform.h | 27 + include/nw4r/ef/ef_emitter.h | 259 ++++++++ include/nw4r/ef/ef_emitterform.h | 19 + include/nw4r/ef/ef_handle.h | 29 + include/nw4r/ef/ef_line.h | 16 + include/nw4r/ef/ef_list.h | 67 +++ include/nw4r/ef/ef_memorymanager.h | 16 + include/nw4r/ef/ef_memorymanagerbase.h | 43 ++ include/nw4r/ef/ef_particle.h | 24 + include/nw4r/ef/ef_particlemanager.h | 91 +++ include/nw4r/ef/ef_point.h | 16 + include/nw4r/ef/ef_rand.h | 38 ++ include/nw4r/ef/ef_ref.h | 48 ++ include/nw4r/ef/ef_resource.h | 18 + include/nw4r/ef/ef_sphere.h | 16 + include/nw4r/ef/ef_torus.h | 16 + include/nw4r/ef/ef_util.h | 22 + include/nw4r/g3d/g3d_3dsmax.h | 20 + include/nw4r/g3d/g3d_anmcamera.h | 28 + include/nw4r/g3d/g3d_anmchr.h | 40 ++ include/nw4r/g3d/g3d_anmclr.h | 23 + include/nw4r/g3d/g3d_anmfog.h | 18 + include/nw4r/g3d/g3d_anmobj.h | 129 ++++ include/nw4r/g3d/g3d_anmscn.h | 60 ++ include/nw4r/g3d/g3d_anmtexpat.h | 24 + include/nw4r/g3d/g3d_anmtexsrt.h | 47 ++ include/nw4r/g3d/g3d_anmvis.h | 188 ++++++ include/nw4r/g3d/g3d_basic.h | 48 ++ include/nw4r/g3d/g3d_calcview.h | 14 + include/nw4r/g3d/g3d_calcworld.h | 19 + include/nw4r/g3d/g3d_camera.h | 107 ++++ include/nw4r/g3d/g3d_cpu.h | 17 + include/nw4r/g3d/g3d_dcc.h | 15 + include/nw4r/g3d/g3d_draw.h | 19 + include/nw4r/g3d/g3d_draw1mat1shp.h | 20 + include/nw4r/g3d/g3d_fog.h | 75 +++ include/nw4r/g3d/g3d_gpu.h | 49 ++ include/nw4r/g3d/g3d_init.h | 19 + include/nw4r/g3d/g3d_light.h | 151 +++++ include/nw4r/g3d/g3d_maya.h | 20 + include/nw4r/g3d/g3d_obj.h | 130 ++++ include/nw4r/g3d/g3d_resanm.h | 88 +++ include/nw4r/g3d/g3d_resanmcamera.h | 30 + include/nw4r/g3d/g3d_resanmchr.h | 35 ++ include/nw4r/g3d/g3d_resanmclr.h | 68 +++ include/nw4r/g3d/g3d_resanmfog.h | 30 + include/nw4r/g3d/g3d_resanmscn.h | 45 ++ include/nw4r/g3d/g3d_resanmshp.h | 35 ++ include/nw4r/g3d/g3d_resanmtexpat.h | 90 +++ include/nw4r/g3d/g3d_resanmtexsrt.h | 63 ++ include/nw4r/g3d/g3d_resanmvis.h | 82 +++ include/nw4r/g3d/g3d_rescommon.h | 141 +++++ include/nw4r/g3d/g3d_resdict.h | 57 ++ include/nw4r/g3d/g3d_resfile.h | 103 +++- include/nw4r/g3d/g3d_resmat.h | 90 +++ include/nw4r/g3d/g3d_resmdl.h | 100 +++ include/nw4r/g3d/g3d_resnode.h | 68 +++ include/nw4r/g3d/g3d_resshp.h | 122 ++++ include/nw4r/g3d/g3d_restev.h | 61 ++ include/nw4r/g3d/g3d_restex.h | 73 +++ include/nw4r/g3d/g3d_resvtx.h | 158 +++++ include/nw4r/g3d/g3d_scnmdl.h | 42 ++ include/nw4r/g3d/g3d_scnmdl1mat1shp.h | 32 + include/nw4r/g3d/g3d_scnmdlsmpl.h | 73 +++ include/nw4r/g3d/g3d_scnobj.h | 340 +++++++++++ include/nw4r/g3d/g3d_scnproc.h | 78 +++ include/nw4r/g3d/g3d_scnrfl.h | 56 ++ include/nw4r/g3d/g3d_scnroot.h | 41 ++ include/nw4r/g3d/g3d_state.h | 20 + include/nw4r/g3d/g3d_tmem.h | 22 + include/nw4r/g3d/g3d_workmem.h | 26 + include/nw4r/g3d/g3d_xsi.h | 20 + include/nw4r/lyt/lyt_animation.h | 82 +++ include/nw4r/lyt/lyt_arcResourceAccessor.h | 84 +++ include/nw4r/lyt/lyt_bounding.h | 36 ++ include/nw4r/lyt/lyt_common.h | 60 ++ include/nw4r/lyt/lyt_drawInfo.h | 25 + include/nw4r/lyt/lyt_group.h | 55 ++ include/nw4r/lyt/lyt_layout.h | 57 ++ include/nw4r/lyt/lyt_material.h | 26 + include/nw4r/lyt/lyt_pane.h | 157 +++++ include/nw4r/lyt/lyt_resourceAccessor.h | 21 + include/nw4r/lyt/lyt_texMap.h | 168 ++++++ include/nw4r/math.h | 9 + include/nw4r/math/arithmetic.h | 111 ---- include/nw4r/math/math_arithmetic.h | 142 +++++ include/nw4r/math/math_geometry.h | 93 +++ include/nw4r/math/math_triangular.h | 105 ++++ include/nw4r/math/math_types.h | 567 ++++++++++++++++++ include/nw4r/math/vec.h | 148 ----- include/nw4r/snd.h | 21 + include/nw4r/snd/snd_AxManager.h | 98 +++ include/nw4r/snd/snd_AxVoice.h | 262 ++++++++ include/nw4r/snd/snd_AxVoiceManager.h | 43 ++ include/nw4r/snd/snd_AxfxImpl.h | 42 ++ include/nw4r/snd/snd_Bank.h | 26 + include/nw4r/snd/snd_BankFile.h | 102 ++++ include/nw4r/snd/snd_BasicPlayer.h | 147 +++++ include/nw4r/snd/snd_BasicSound.h | 206 +++++++ include/nw4r/snd/snd_Channel.h | 161 +++++ include/nw4r/snd/snd_ChannelManager.h | 21 + include/nw4r/snd/snd_Common.h | 63 ++ include/nw4r/snd/snd_DisposeCallback.h | 24 + include/nw4r/snd/snd_DisposeCallbackManager.h | 29 + include/nw4r/snd/snd_DvdSoundArchive.h | 41 ++ include/nw4r/snd/snd_EnvGenerator.h | 48 ++ include/nw4r/snd/snd_ExternalSoundPlayer.h | 68 +++ include/nw4r/snd/snd_FrameHeap.h | 90 +++ include/nw4r/snd/snd_FxBase.h | 33 + include/nw4r/snd/snd_FxChorus.h | 47 ++ include/nw4r/snd/snd_FxDelay.h | 47 ++ include/nw4r/snd/snd_FxReverbHi.h | 50 ++ include/nw4r/snd/snd_InstancePool.h | 71 +++ include/nw4r/snd/snd_Lfo.h | 43 ++ include/nw4r/snd/snd_MemorySoundArchive.h | 33 + include/nw4r/snd/snd_MmlParser.h | 46 ++ include/nw4r/snd/snd_MmlSeqTrack.h | 40 ++ include/nw4r/snd/snd_MmlSeqTrackAllocator.h | 31 + include/nw4r/snd/snd_MoveValue.h | 58 ++ include/nw4r/snd/snd_NandSoundArchive.h | 40 ++ include/nw4r/snd/snd_NoteOn.h | 34 ++ include/nw4r/snd/snd_PlayerHeap.h | 21 + include/nw4r/snd/snd_RemoteSpeaker.h | 75 +++ include/nw4r/snd/snd_RemoteSpeakerManager.h | 34 ++ include/nw4r/snd/snd_SeqFile.h | 37 ++ include/nw4r/snd/snd_SeqPlayer.h | 138 +++++ include/nw4r/snd/snd_SeqSound.h | 104 ++++ include/nw4r/snd/snd_SeqSoundHandle.h | 22 + include/nw4r/snd/snd_SeqTrack.h | 129 ++++ include/nw4r/snd/snd_Sound3DActor.h | 40 ++ include/nw4r/snd/snd_Sound3DListener.h | 23 + include/nw4r/snd/snd_Sound3DManager.h | 53 ++ include/nw4r/snd/snd_SoundActor.h | 56 ++ include/nw4r/snd/snd_SoundArchive.h | 163 +++++ include/nw4r/snd/snd_SoundArchiveFile.h | 278 +++++++++ include/nw4r/snd/snd_SoundArchiveLoader.h | 52 ++ include/nw4r/snd/snd_SoundArchivePlayer.h | 53 ++ include/nw4r/snd/snd_SoundHandle.h | 39 ++ include/nw4r/snd/snd_SoundHeap.h | 33 + include/nw4r/snd/snd_SoundInstanceManager.h | 61 ++ include/nw4r/snd/snd_SoundMemoryAllocatable.h | 17 + include/nw4r/snd/snd_SoundPlayer.h | 36 ++ include/nw4r/snd/snd_SoundStartable.h | 48 ++ include/nw4r/snd/snd_SoundSystem.h | 49 +- include/nw4r/snd/snd_SoundThread.h | 82 +++ include/nw4r/snd/snd_StrmChannel.h | 31 + include/nw4r/snd/snd_StrmPlayer.h | 63 ++ include/nw4r/snd/snd_StrmSound.h | 39 ++ include/nw4r/snd/snd_StrmSoundHandle.h | 24 + include/nw4r/snd/snd_Task.h | 28 + include/nw4r/snd/snd_TaskManager.h | 48 ++ include/nw4r/snd/snd_TaskThread.h | 26 + include/nw4r/snd/snd_Util.h | 78 +++ include/nw4r/snd/snd_Voice.h | 67 +++ include/nw4r/snd/snd_VoiceManager.h | 25 + include/nw4r/snd/snd_WaveFile.h | 39 ++ include/nw4r/snd/snd_WaveSound.h | 42 ++ include/nw4r/snd/snd_WaveSoundHandle.h | 24 + include/nw4r/snd/snd_WsdPlayer.h | 53 ++ include/nw4r/snd/snd_adpcm.h | 16 + include/nw4r/types_nw4r.h | 233 +++++++ include/nw4r/ut.h | 28 + include/nw4r/ut/Color.h | 24 - include/nw4r/ut/List.h | 41 -- include/nw4r/ut/ut_CharStrmReader.h | 43 ++ include/nw4r/ut/ut_CharWriter.h | 191 ++++++ include/nw4r/ut/ut_Color.h | 60 ++ include/nw4r/ut/ut_DvdFileStream.h | 111 ++++ include/nw4r/ut/ut_DvdLockedFileStream.h | 42 ++ include/nw4r/ut/ut_FileStream.h | 49 ++ include/nw4r/ut/ut_Font.h | 70 +++ include/nw4r/ut/ut_IOStream.h | 45 ++ include/nw4r/ut/ut_LinkList.h | 400 ++++++++++++ include/nw4r/ut/ut_LockedCache.h | 38 ++ include/nw4r/ut/ut_NandFileStream.h | 102 ++++ include/nw4r/ut/ut_NonCopyable.h | 20 + include/nw4r/ut/ut_Rect.h | 48 ++ include/nw4r/ut/ut_ResFont.h | 22 + include/nw4r/ut/ut_ResFontBase.h | 113 ++++ include/nw4r/ut/ut_RomFont.h | 51 ++ include/nw4r/ut/ut_RuntimeTypeInfo.h | 65 ++ include/nw4r/ut/ut_TagProcessorBase.h | 45 ++ include/nw4r/ut/ut_TextWriterBase.h | 123 ++++ include/nw4r/ut/ut_algorithm.h | 94 +++ include/nw4r/ut/ut_binaryFileFormat.h | 28 + include/nw4r/ut/ut_list.h | 56 ++ include/nw4r/ut/ut_lock.h | 48 ++ include/rvl/AX.h | 26 + include/rvl/AX/AX.h | 14 + include/rvl/AX/AXAlloc.h | 32 + include/rvl/AX/AXAux.h | 48 ++ include/rvl/AX/AXCL.h | 36 ++ include/rvl/AX/AXComp.h | 13 + include/rvl/AX/AXOut.h | 26 + include/rvl/AX/AXPB.h | 279 +++++++++ include/rvl/AX/AXProf.h | 24 + include/rvl/AX/AXSPB.h | 82 +++ include/rvl/AX/AXVPB.h | 80 +++ include/rvl/AX/DSPCode.h | 17 + include/rvl/AXFX.h | 22 + include/rvl/AXFX/AXFXChorus.h | 26 + include/rvl/AXFX/AXFXChorusExp.h | 59 ++ include/rvl/AXFX/AXFXCommon.h | 30 + include/rvl/AXFX/AXFXDelay.h | 29 + include/rvl/AXFX/AXFXHooks.h | 20 + include/rvl/AXFX/AXFXLfoTable.h | 13 + include/rvl/AXFX/AXFXReverbHi.h | 29 + include/rvl/AXFX/AXFXReverbHiDpl2.h | 29 + include/rvl/AXFX/AXFXReverbHiExp.h | 69 +++ include/rvl/AXFX/AXFXReverbHiExpDpl2.h | 65 ++ include/rvl/AXFX/AXFXSrcCoef.h | 13 + include/rvl/KPAD/KPAD.h | 14 + include/rvl/OS/OSCache.h | 1 + include/rvl/WPAD.h | 12 + include/rvl/WPAD/WPAD.h | 30 + src/m/m_mtx.cpp | 2 +- src/toBeSorted/misc_flag_managers.cpp | 40 +- 254 files changed, 14384 insertions(+), 475 deletions(-) create mode 100644 include/MSL_C/MSL_Common/Src/limits.h create mode 100644 include/MSL_C/MSL_Common/Src/wmem.h create mode 100644 include/MSL_C/MSL_Common/Src/wprintf.h create mode 100644 include/MSL_C/MSL_Common/Src/wstring.h create mode 100644 include/MSL_C/limits.h create mode 100644 include/MSL_C/wchar.h create mode 100644 include/decomp.h create mode 100644 include/nw4r/ef/ef_animcurve.h create mode 100644 include/nw4r/ef/ef_creationqueue.h create mode 100644 include/nw4r/ef/ef_cube.h create mode 100644 include/nw4r/ef/ef_cylinder.h create mode 100644 include/nw4r/ef/ef_disc.h create mode 100644 include/nw4r/ef/ef_drawbillboardstrategy.h create mode 100644 include/nw4r/ef/ef_drawdirectionalstrategy.h create mode 100644 include/nw4r/ef/ef_drawfreestrategy.h create mode 100644 include/nw4r/ef/ef_drawinfo.h create mode 100644 include/nw4r/ef/ef_drawlinestrategy.h create mode 100644 include/nw4r/ef/ef_draworder.h create mode 100644 include/nw4r/ef/ef_draworderbase.h create mode 100644 include/nw4r/ef/ef_drawpointstrategy.h create mode 100644 include/nw4r/ef/ef_drawsmoothstripestrategy.h create mode 100644 include/nw4r/ef/ef_drawstrategy.h create mode 100644 include/nw4r/ef/ef_drawstrategybuilder.h create mode 100644 include/nw4r/ef/ef_drawstrategyimpl.h create mode 100644 include/nw4r/ef/ef_drawstripestrategy.h create mode 100644 include/nw4r/ef/ef_effect.h create mode 100644 include/nw4r/ef/ef_effectsystem.h create mode 100644 include/nw4r/ef/ef_emform.h create mode 100644 include/nw4r/ef/ef_emitter.h create mode 100644 include/nw4r/ef/ef_emitterform.h create mode 100644 include/nw4r/ef/ef_handle.h create mode 100644 include/nw4r/ef/ef_line.h create mode 100644 include/nw4r/ef/ef_list.h create mode 100644 include/nw4r/ef/ef_memorymanager.h create mode 100644 include/nw4r/ef/ef_memorymanagerbase.h create mode 100644 include/nw4r/ef/ef_particle.h create mode 100644 include/nw4r/ef/ef_particlemanager.h create mode 100644 include/nw4r/ef/ef_point.h create mode 100644 include/nw4r/ef/ef_rand.h create mode 100644 include/nw4r/ef/ef_ref.h create mode 100644 include/nw4r/ef/ef_resource.h create mode 100644 include/nw4r/ef/ef_sphere.h create mode 100644 include/nw4r/ef/ef_torus.h create mode 100644 include/nw4r/ef/ef_util.h create mode 100644 include/nw4r/g3d/g3d_3dsmax.h create mode 100644 include/nw4r/g3d/g3d_anmcamera.h create mode 100644 include/nw4r/g3d/g3d_anmchr.h create mode 100644 include/nw4r/g3d/g3d_anmclr.h create mode 100644 include/nw4r/g3d/g3d_anmfog.h create mode 100644 include/nw4r/g3d/g3d_anmobj.h create mode 100644 include/nw4r/g3d/g3d_anmscn.h create mode 100644 include/nw4r/g3d/g3d_anmtexpat.h create mode 100644 include/nw4r/g3d/g3d_anmtexsrt.h create mode 100644 include/nw4r/g3d/g3d_anmvis.h create mode 100644 include/nw4r/g3d/g3d_basic.h create mode 100644 include/nw4r/g3d/g3d_calcview.h create mode 100644 include/nw4r/g3d/g3d_calcworld.h create mode 100644 include/nw4r/g3d/g3d_camera.h create mode 100644 include/nw4r/g3d/g3d_cpu.h create mode 100644 include/nw4r/g3d/g3d_dcc.h create mode 100644 include/nw4r/g3d/g3d_draw.h create mode 100644 include/nw4r/g3d/g3d_draw1mat1shp.h create mode 100644 include/nw4r/g3d/g3d_fog.h create mode 100644 include/nw4r/g3d/g3d_gpu.h create mode 100644 include/nw4r/g3d/g3d_init.h create mode 100644 include/nw4r/g3d/g3d_light.h create mode 100644 include/nw4r/g3d/g3d_maya.h create mode 100644 include/nw4r/g3d/g3d_obj.h create mode 100644 include/nw4r/g3d/g3d_resanm.h create mode 100644 include/nw4r/g3d/g3d_resanmcamera.h create mode 100644 include/nw4r/g3d/g3d_resanmchr.h create mode 100644 include/nw4r/g3d/g3d_resanmclr.h create mode 100644 include/nw4r/g3d/g3d_resanmfog.h create mode 100644 include/nw4r/g3d/g3d_resanmscn.h create mode 100644 include/nw4r/g3d/g3d_resanmshp.h create mode 100644 include/nw4r/g3d/g3d_resanmtexpat.h create mode 100644 include/nw4r/g3d/g3d_resanmtexsrt.h create mode 100644 include/nw4r/g3d/g3d_resanmvis.h create mode 100644 include/nw4r/g3d/g3d_resdict.h create mode 100644 include/nw4r/g3d/g3d_resmat.h create mode 100644 include/nw4r/g3d/g3d_resmdl.h create mode 100644 include/nw4r/g3d/g3d_resnode.h create mode 100644 include/nw4r/g3d/g3d_resshp.h create mode 100644 include/nw4r/g3d/g3d_restev.h create mode 100644 include/nw4r/g3d/g3d_restex.h create mode 100644 include/nw4r/g3d/g3d_resvtx.h create mode 100644 include/nw4r/g3d/g3d_scnmdl.h create mode 100644 include/nw4r/g3d/g3d_scnmdl1mat1shp.h create mode 100644 include/nw4r/g3d/g3d_scnmdlsmpl.h create mode 100644 include/nw4r/g3d/g3d_scnobj.h create mode 100644 include/nw4r/g3d/g3d_scnproc.h create mode 100644 include/nw4r/g3d/g3d_scnrfl.h create mode 100644 include/nw4r/g3d/g3d_scnroot.h create mode 100644 include/nw4r/g3d/g3d_state.h create mode 100644 include/nw4r/g3d/g3d_tmem.h create mode 100644 include/nw4r/g3d/g3d_workmem.h create mode 100644 include/nw4r/g3d/g3d_xsi.h create mode 100644 include/nw4r/lyt/lyt_animation.h create mode 100644 include/nw4r/lyt/lyt_arcResourceAccessor.h create mode 100644 include/nw4r/lyt/lyt_bounding.h create mode 100644 include/nw4r/lyt/lyt_common.h create mode 100644 include/nw4r/lyt/lyt_drawInfo.h create mode 100644 include/nw4r/lyt/lyt_group.h create mode 100644 include/nw4r/lyt/lyt_layout.h create mode 100644 include/nw4r/lyt/lyt_material.h create mode 100644 include/nw4r/lyt/lyt_pane.h create mode 100644 include/nw4r/lyt/lyt_resourceAccessor.h create mode 100644 include/nw4r/lyt/lyt_texMap.h create mode 100644 include/nw4r/math.h delete mode 100644 include/nw4r/math/arithmetic.h create mode 100644 include/nw4r/math/math_arithmetic.h create mode 100644 include/nw4r/math/math_geometry.h create mode 100644 include/nw4r/math/math_triangular.h create mode 100644 include/nw4r/math/math_types.h delete mode 100644 include/nw4r/math/vec.h create mode 100644 include/nw4r/snd.h create mode 100644 include/nw4r/snd/snd_AxManager.h create mode 100644 include/nw4r/snd/snd_AxVoice.h create mode 100644 include/nw4r/snd/snd_AxVoiceManager.h create mode 100644 include/nw4r/snd/snd_AxfxImpl.h create mode 100644 include/nw4r/snd/snd_Bank.h create mode 100644 include/nw4r/snd/snd_BankFile.h create mode 100644 include/nw4r/snd/snd_BasicPlayer.h create mode 100644 include/nw4r/snd/snd_BasicSound.h create mode 100644 include/nw4r/snd/snd_Channel.h create mode 100644 include/nw4r/snd/snd_ChannelManager.h create mode 100644 include/nw4r/snd/snd_Common.h create mode 100644 include/nw4r/snd/snd_DisposeCallback.h create mode 100644 include/nw4r/snd/snd_DisposeCallbackManager.h create mode 100644 include/nw4r/snd/snd_DvdSoundArchive.h create mode 100644 include/nw4r/snd/snd_EnvGenerator.h create mode 100644 include/nw4r/snd/snd_ExternalSoundPlayer.h create mode 100644 include/nw4r/snd/snd_FrameHeap.h create mode 100644 include/nw4r/snd/snd_FxBase.h create mode 100644 include/nw4r/snd/snd_FxChorus.h create mode 100644 include/nw4r/snd/snd_FxDelay.h create mode 100644 include/nw4r/snd/snd_FxReverbHi.h create mode 100644 include/nw4r/snd/snd_InstancePool.h create mode 100644 include/nw4r/snd/snd_Lfo.h create mode 100644 include/nw4r/snd/snd_MemorySoundArchive.h create mode 100644 include/nw4r/snd/snd_MmlParser.h create mode 100644 include/nw4r/snd/snd_MmlSeqTrack.h create mode 100644 include/nw4r/snd/snd_MmlSeqTrackAllocator.h create mode 100644 include/nw4r/snd/snd_MoveValue.h create mode 100644 include/nw4r/snd/snd_NandSoundArchive.h create mode 100644 include/nw4r/snd/snd_NoteOn.h create mode 100644 include/nw4r/snd/snd_PlayerHeap.h create mode 100644 include/nw4r/snd/snd_RemoteSpeaker.h create mode 100644 include/nw4r/snd/snd_RemoteSpeakerManager.h create mode 100644 include/nw4r/snd/snd_SeqFile.h create mode 100644 include/nw4r/snd/snd_SeqPlayer.h create mode 100644 include/nw4r/snd/snd_SeqSound.h create mode 100644 include/nw4r/snd/snd_SeqSoundHandle.h create mode 100644 include/nw4r/snd/snd_SeqTrack.h create mode 100644 include/nw4r/snd/snd_Sound3DActor.h create mode 100644 include/nw4r/snd/snd_Sound3DListener.h create mode 100644 include/nw4r/snd/snd_Sound3DManager.h create mode 100644 include/nw4r/snd/snd_SoundActor.h create mode 100644 include/nw4r/snd/snd_SoundArchive.h create mode 100644 include/nw4r/snd/snd_SoundArchiveFile.h create mode 100644 include/nw4r/snd/snd_SoundArchiveLoader.h create mode 100644 include/nw4r/snd/snd_SoundArchivePlayer.h create mode 100644 include/nw4r/snd/snd_SoundHandle.h create mode 100644 include/nw4r/snd/snd_SoundHeap.h create mode 100644 include/nw4r/snd/snd_SoundInstanceManager.h create mode 100644 include/nw4r/snd/snd_SoundMemoryAllocatable.h create mode 100644 include/nw4r/snd/snd_SoundPlayer.h create mode 100644 include/nw4r/snd/snd_SoundStartable.h create mode 100644 include/nw4r/snd/snd_SoundThread.h create mode 100644 include/nw4r/snd/snd_StrmChannel.h create mode 100644 include/nw4r/snd/snd_StrmPlayer.h create mode 100644 include/nw4r/snd/snd_StrmSound.h create mode 100644 include/nw4r/snd/snd_StrmSoundHandle.h create mode 100644 include/nw4r/snd/snd_Task.h create mode 100644 include/nw4r/snd/snd_TaskManager.h create mode 100644 include/nw4r/snd/snd_TaskThread.h create mode 100644 include/nw4r/snd/snd_Util.h create mode 100644 include/nw4r/snd/snd_Voice.h create mode 100644 include/nw4r/snd/snd_VoiceManager.h create mode 100644 include/nw4r/snd/snd_WaveFile.h create mode 100644 include/nw4r/snd/snd_WaveSound.h create mode 100644 include/nw4r/snd/snd_WaveSoundHandle.h create mode 100644 include/nw4r/snd/snd_WsdPlayer.h create mode 100644 include/nw4r/snd/snd_adpcm.h create mode 100644 include/nw4r/types_nw4r.h create mode 100644 include/nw4r/ut.h delete mode 100644 include/nw4r/ut/Color.h delete mode 100644 include/nw4r/ut/List.h create mode 100644 include/nw4r/ut/ut_CharStrmReader.h create mode 100644 include/nw4r/ut/ut_CharWriter.h create mode 100644 include/nw4r/ut/ut_Color.h create mode 100644 include/nw4r/ut/ut_DvdFileStream.h create mode 100644 include/nw4r/ut/ut_DvdLockedFileStream.h create mode 100644 include/nw4r/ut/ut_FileStream.h create mode 100644 include/nw4r/ut/ut_Font.h create mode 100644 include/nw4r/ut/ut_IOStream.h create mode 100644 include/nw4r/ut/ut_LinkList.h create mode 100644 include/nw4r/ut/ut_LockedCache.h create mode 100644 include/nw4r/ut/ut_NandFileStream.h create mode 100644 include/nw4r/ut/ut_NonCopyable.h create mode 100644 include/nw4r/ut/ut_Rect.h create mode 100644 include/nw4r/ut/ut_ResFont.h create mode 100644 include/nw4r/ut/ut_ResFontBase.h create mode 100644 include/nw4r/ut/ut_RomFont.h create mode 100644 include/nw4r/ut/ut_RuntimeTypeInfo.h create mode 100644 include/nw4r/ut/ut_TagProcessorBase.h create mode 100644 include/nw4r/ut/ut_TextWriterBase.h create mode 100644 include/nw4r/ut/ut_algorithm.h create mode 100644 include/nw4r/ut/ut_binaryFileFormat.h create mode 100644 include/nw4r/ut/ut_list.h create mode 100644 include/nw4r/ut/ut_lock.h create mode 100644 include/rvl/AX.h create mode 100644 include/rvl/AX/AX.h create mode 100644 include/rvl/AX/AXAlloc.h create mode 100644 include/rvl/AX/AXAux.h create mode 100644 include/rvl/AX/AXCL.h create mode 100644 include/rvl/AX/AXComp.h create mode 100644 include/rvl/AX/AXOut.h create mode 100644 include/rvl/AX/AXPB.h create mode 100644 include/rvl/AX/AXProf.h create mode 100644 include/rvl/AX/AXSPB.h create mode 100644 include/rvl/AX/AXVPB.h create mode 100644 include/rvl/AX/DSPCode.h create mode 100644 include/rvl/AXFX.h create mode 100644 include/rvl/AXFX/AXFXChorus.h create mode 100644 include/rvl/AXFX/AXFXChorusExp.h create mode 100644 include/rvl/AXFX/AXFXCommon.h create mode 100644 include/rvl/AXFX/AXFXDelay.h create mode 100644 include/rvl/AXFX/AXFXHooks.h create mode 100644 include/rvl/AXFX/AXFXLfoTable.h create mode 100644 include/rvl/AXFX/AXFXReverbHi.h create mode 100644 include/rvl/AXFX/AXFXReverbHiDpl2.h create mode 100644 include/rvl/AXFX/AXFXReverbHiExp.h create mode 100644 include/rvl/AXFX/AXFXReverbHiExpDpl2.h create mode 100644 include/rvl/AXFX/AXFXSrcCoef.h create mode 100644 include/rvl/KPAD/KPAD.h create mode 100644 include/rvl/WPAD.h create mode 100644 include/rvl/WPAD/WPAD.h diff --git a/include/MSL_C/MSL_Common/Src/fdlibm.h b/include/MSL_C/MSL_Common/Src/fdlibm.h index 8124fbb5..b0f144ba 100644 --- a/include/MSL_C/MSL_Common/Src/fdlibm.h +++ b/include/MSL_C/MSL_Common/Src/fdlibm.h @@ -5,7 +5,7 @@ * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. * * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice + * software is freely granted, provided that this notice * is preserved. * ==================================================== */ @@ -13,28 +13,27 @@ /* Sometimes it's necessary to define __LITTLE_ENDIAN explicitly but these catch some common cases. */ -#if defined(i386) || defined(i486) || \ - defined(intel) || defined(x86) || defined(i86pc) || \ - defined(__alpha) || defined(__osf__) +#if defined(i386) || defined(i486) || defined(intel) || defined(x86) || defined(i86pc) || defined(__alpha) || \ + defined(__osf__) #define __LITTLE_ENDIAN #endif #ifdef __LITTLE_ENDIAN -#define __HI(x) *(1+(int*)&x) -#define __LO(x) *(int*)&x -#define __HIp(x) *(1+(int*)x) -#define __LOp(x) *(int*)x +#define __HI(x) *(1 + (int *)&x) +#define __LO(x) *(int *)&x +#define __HIp(x) *(1 + (int *)x) +#define __LOp(x) *(int *)x #else -#define __HI(x) *(int*)&x -#define __LO(x) *(1+(int*)&x) -#define __HIp(x) *(int*)x -#define __LOp(x) *(1+(int*)x) +#define __HI(x) *(int *)&x +#define __LO(x) *(1 + (int *)&x) +#define __HIp(x) *(int *)x +#define __LOp(x) *(1 + (int *)x) #endif #ifdef __STDC__ -#define __P(p) p +#define __P(p) p #else -#define __P(p) () +#define __P(p) () #endif /* @@ -43,50 +42,50 @@ extern int signgam; -#define MAXFLOAT ((float)3.40282346638528860e+38) +#define MAXFLOAT ((float)3.40282346638528860e+38) -enum fdversion {fdlibm_ieee = -1, fdlibm_svid, fdlibm_xopen, fdlibm_posix}; +enum fdversion { fdlibm_ieee = -1, fdlibm_svid, fdlibm_xopen, fdlibm_posix }; #define _LIB_VERSION_TYPE enum fdversion -#define _LIB_VERSION _fdlib_version +#define _LIB_VERSION _fdlib_version -/* if global variable _LIB_VERSION is not desirable, one may - * change the following to be a constant by: +/* if global variable _LIB_VERSION is not desirable, one may + * change the following to be a constant by: * #define _LIB_VERSION_TYPE const enum version * In that case, after one initializes the value _LIB_VERSION (see * s_lib_version.c) during compile time, it cannot be modified * in the middle of a program - */ -extern _LIB_VERSION_TYPE _LIB_VERSION; + */ +extern _LIB_VERSION_TYPE _LIB_VERSION; -#define _IEEE_ fdlibm_ieee -#define _SVID_ fdlibm_svid +#define _IEEE_ fdlibm_ieee +#define _SVID_ fdlibm_svid #define _XOPEN_ fdlibm_xopen #define _POSIX_ fdlibm_posix struct exception { - int type; - char *name; - double arg1; - double arg2; - double retval; + int type; + char *name; + double arg1; + double arg2; + double retval; }; -#define HUGE MAXFLOAT +#define HUGE MAXFLOAT -/* +/* * set X_TLOSS = pi*2**52, which is possibly defined in * (one may replace the following line by "#include ") */ -#define X_TLOSS 1.41484755040568800000e+16 +#define X_TLOSS 1.41484755040568800000e+16 -#define DOMAIN 1 -#define SING 2 -#define OVERFLOW 3 -#define UNDERFLOW 4 -#define TLOSS 5 -#define PLOSS 6 +#define DOMAIN 1 +#define SING 2 +#define OVERFLOW 3 +#define UNDERFLOW 4 +#define TLOSS 5 +#define PLOSS 6 /* * ANSI/POSIX @@ -173,44 +172,44 @@ extern double log1p __P((double)); #ifdef _REENTRANT extern double gamma_r __P((double, int *)); extern double lgamma_r __P((double, int *)); -#endif /* _REENTRANT */ +#endif /* _REENTRANT */ /* ieee style elementary functions */ -extern double __ieee754_sqrt __P((double)); -extern double __ieee754_acos __P((double)); -extern double __ieee754_acosh __P((double)); -extern double __ieee754_log __P((double)); -extern double __ieee754_atanh __P((double)); -extern double __ieee754_asin __P((double)); -extern double __ieee754_atan2 __P((double,double)); +extern double __ieee754_sqrt __P((double)); +extern double __ieee754_acos __P((double)); +extern double __ieee754_acosh __P((double)); +extern double __ieee754_log __P((double)); +extern double __ieee754_atanh __P((double)); +extern double __ieee754_asin __P((double)); +extern double __ieee754_atan2 __P((double, double)); extern double __ieee754_exp __P((double)); extern double __ieee754_cosh __P((double)); -extern double __ieee754_fmod __P((double,double)); -extern double __ieee754_pow __P((double,double)); -extern double __ieee754_lgamma_r __P((double,int *)); -extern double __ieee754_gamma_r __P((double,int *)); +extern double __ieee754_fmod __P((double, double)); +extern double __ieee754_pow __P((double, double)); +extern double __ieee754_lgamma_r __P((double, int *)); +extern double __ieee754_gamma_r __P((double, int *)); extern double __ieee754_lgamma __P((double)); extern double __ieee754_gamma __P((double)); extern double __ieee754_log10 __P((double)); extern double __ieee754_sinh __P((double)); -extern double __ieee754_hypot __P((double,double)); +extern double __ieee754_hypot __P((double, double)); extern double __ieee754_j0 __P((double)); extern double __ieee754_j1 __P((double)); extern double __ieee754_y0 __P((double)); extern double __ieee754_y1 __P((double)); -extern double __ieee754_jn __P((int,double)); -extern double __ieee754_yn __P((int,double)); -extern double __ieee754_remainder __P((double,double)); -extern int __ieee754_rem_pio2 __P((double,double*)); +extern double __ieee754_jn __P((int, double)); +extern double __ieee754_yn __P((int, double)); +extern double __ieee754_remainder __P((double, double)); +extern int __ieee754_rem_pio2 __P((double, double *)); #ifdef _SCALB_INT -extern double __ieee754_scalb __P((double,int)); +extern double __ieee754_scalb __P((double, int)); #else -extern double __ieee754_scalb __P((double,double)); +extern double __ieee754_scalb __P((double, double)); #endif /* fdlibm kernel function */ -extern double __kernel_standard __P((double,double,int)); -extern double __kernel_sin __P((double,double,int)); -extern double __kernel_cos __P((double,double)); -extern double __kernel_tan __P((double,double,int)); -extern int __kernel_rem_pio2 __P((double*,double*,int,int,int,const int*)); \ No newline at end of file +extern double __kernel_standard __P((double, double, int)); +extern double __kernel_sin __P((double, double, int)); +extern double __kernel_cos __P((double, double)); +extern double __kernel_tan __P((double, double, int)); +extern int __kernel_rem_pio2 __P((double *, double *, int, int, int, const int *)); diff --git a/include/MSL_C/MSL_Common/Src/limits.h b/include/MSL_C/MSL_Common/Src/limits.h new file mode 100644 index 00000000..dfc3623c --- /dev/null +++ b/include/MSL_C/MSL_Common/Src/limits.h @@ -0,0 +1,31 @@ +#ifndef MSL_LIMITS_H +#define MSL_LIMITS_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +#define CHAR_BIT 8 + +#define SCHAR_MIN -127 +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +#define CHAR_MIN 0 +#define CHAR_MAX SCHAR_MAX + +#define SHRT_MIN -32767 +#define SHRT_MAX 32767 +#define USHRT_MAX 65535 + +#define INT_MIN -2147483647 +#define INT_MAX 2147483647 + +#define LONG_MIN INT_MIN +#define LONG_MAX INT_MAX +#define ULONG_MAX 4294967295 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/MSL_C/MSL_Common/Src/wmem.h b/include/MSL_C/MSL_Common/Src/wmem.h new file mode 100644 index 00000000..33c89e57 --- /dev/null +++ b/include/MSL_C/MSL_Common/Src/wmem.h @@ -0,0 +1,14 @@ +#ifndef MSL_WMEM_H +#define MSL_WMEM_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +void *wmemcpy(void *, const void *, size_t); +void *wmemchr(const void *, int, size_t); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/MSL_C/MSL_Common/Src/wprintf.h b/include/MSL_C/MSL_Common/Src/wprintf.h new file mode 100644 index 00000000..94445588 --- /dev/null +++ b/include/MSL_C/MSL_Common/Src/wprintf.h @@ -0,0 +1,14 @@ +#ifndef MSL_WPRINTF_H +#define MSL_WPRINTF_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +int vswprintf(wchar_t *, size_t, const wchar_t *, va_list); +int swprintf(wchar_t *, size_t, const wchar_t *, ...); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/MSL_C/MSL_Common/Src/wstring.h b/include/MSL_C/MSL_Common/Src/wstring.h new file mode 100644 index 00000000..761f17a9 --- /dev/null +++ b/include/MSL_C/MSL_Common/Src/wstring.h @@ -0,0 +1,18 @@ +#ifndef MSL_WSTRING_H +#define MSL_WSTRING_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +size_t wcslen(const wchar_t *); +wchar_t *wcscpy(wchar_t *, const wchar_t *); +wchar_t *wcsncpy(wchar_t *, const wchar_t *, size_t); +wchar_t *wcscat(wchar_t *, const wchar_t *); +int wcscmp(const wchar_t *, const wchar_t *); +wchar_t *wcschr(const wchar_t *, wchar_t); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/MSL_C/limits.h b/include/MSL_C/limits.h new file mode 100644 index 00000000..7aabf2ec --- /dev/null +++ b/include/MSL_C/limits.h @@ -0,0 +1,30 @@ +#ifndef MSL_LIMITS_H +#define MSL_LIMITS_H +#ifdef __cplusplus +extern "C" { +#endif + +#define CHAR_BIT 8 + +#define SCHAR_MIN -127 +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +#define CHAR_MIN 0 +#define CHAR_MAX SCHAR_MAX + +#define SHRT_MIN -32767 +#define SHRT_MAX 32767 +#define USHRT_MAX 65535 + +#define INT_MIN -2147483647 +#define INT_MAX 2147483647 + +#define LONG_MIN INT_MIN +#define LONG_MAX INT_MAX +#define ULONG_MAX 4294967295 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/MSL_C/math.h b/include/MSL_C/math.h index afabafac..ca14879f 100644 --- a/include/MSL_C/math.h +++ b/include/MSL_C/math.h @@ -3,8 +3,8 @@ #include "MSL_C/MSL_Common/Src/float.h" -#define NAN (*(float*)__float_nan) -#define HUGE_VALF (*(float*)__float_huge) +#define NAN (*(float *)__float_nan) +#define HUGE_VALF (*(float *)__float_huge) #define M_PI 3.14159265358979323846f @@ -25,6 +25,21 @@ double copysign(double, double); double cos(double); float cosf(float); double exp(double); +double ceil(double); +float ceilf(float); +double frexp(double, int *); +double ldexp(double, int); +double modf(double, double *); +double pow(double, double); +double sin(double); +float sinf(float); +double tan(double); +float tanf(float); +double floor(double); +float floorf(float); +double fmod(double, double); +float fmodf(float, float); +float fmodff(float, float *); extern float __fabsf(float); inline double fabs(double f) { @@ -37,21 +52,19 @@ inline float fabsf(float f) { return fabsf2(f); } -double floor(double); -double fmod(double, double); inline float fmodf(float f1, float f2) { return fmod(f1, f2); } -double frexp(double, int*); -double ldexp(double, int); -double modf(double, double*); -double pow(double, double); -double sin(double); -float sinf(float); -double tan(double); -float tanf(float); +inline float modff(float x, float *iptr) { + float frac; + double intg; + frac = modf((double)x, &intg); + *iptr = intg; + + return frac; +} inline double sqrt_step(double tmpd, float mag) { return tmpd * 0.5 * (3.0 - mag * (tmpd * tmpd)); } @@ -61,10 +74,10 @@ extern inline float sqrtf(float x) { const double _three = 3.0; volatile float y; if (x > 0.0f) { - double guess = __frsqrte((double)x); // returns an approximation to - guess = _half * guess * (_three - guess * guess * x); // now have 12 sig bits - guess = _half * guess * (_three - guess * guess * x); // now have 24 sig bits - guess = _half * guess * (_three - guess * guess * x); // now have 32 sig bits + double guess = __frsqrte((double)x); // returns an approximation to + guess = _half * guess * (_three - guess * guess * x); // now have 12 sig bits + guess = _half * guess * (_three - guess * guess * x); // now have 24 sig bits + guess = _half * guess * (_three - guess * guess * x); // now have 32 sig bits y = (float)(x * guess); return y; } @@ -72,19 +85,18 @@ extern inline float sqrtf(float x) { } extern inline double sqrt(double x) { - if(x > 0.0) - { - double guess = __frsqrte(x); /* returns an approximation to */ - guess = .5*guess*(3.0 - guess*guess*x); /* now have 8 sig bits */ - guess = .5*guess*(3.0 - guess*guess*x); /* now have 16 sig bits */ - guess = .5*guess*(3.0 - guess*guess*x); /* now have 32 sig bits */ - guess = .5*guess*(3.0 - guess*guess*x); /* now have > 53 sig bits */ - return x*guess ; - } - else if ( x == 0 ) + if (x > 0.0) { + double guess = __frsqrte(x); /* returns an approximation to */ + guess = .5 * guess * (3.0 - guess * guess * x); /* now have 8 sig bits */ + guess = .5 * guess * (3.0 - guess * guess * x); /* now have 16 sig bits */ + guess = .5 * guess * (3.0 - guess * guess * x); /* now have 32 sig bits */ + guess = .5 * guess * (3.0 - guess * guess * x); /* now have > 53 sig bits */ + return x * guess; + } else if (x == 0) { return 0; - else if ( x ) + } else if (x) { return NAN; + } return HUGE_VALF; } diff --git a/include/MSL_C/wchar.h b/include/MSL_C/wchar.h new file mode 100644 index 00000000..36cb4a92 --- /dev/null +++ b/include/MSL_C/wchar.h @@ -0,0 +1,19 @@ +#ifndef MSL_WCHAR_H +#define MSL_WCHAR_H +#include + +#include +#include +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +#define WCHAR_MIN SHRT_MIN +#define WCHAR_MAX USHRT_MAX + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/common.h b/include/common.h index 102058f7..dbfd7e05 100644 --- a/include/common.h +++ b/include/common.h @@ -42,6 +42,8 @@ #define CW_FORCE_STRINGS(module, ...) #endif +#include + // For VSCode #ifdef __INTELLISENSE__ #define asm diff --git a/include/decomp.h b/include/decomp.h new file mode 100644 index 00000000..577ffdbd --- /dev/null +++ b/include/decomp.h @@ -0,0 +1,47 @@ +/** + * Codewarrior tricks for matching decomp + * (Macros generate prototypes to satisfy -requireprotos) + */ + +#ifndef DECOMP_H +#define DECOMP_H + +#define __CONCAT(x, y) x##y +#define CONCAT(x, y) __CONCAT(x, y) + +// Compile without matching hacks. +#ifdef NON_MATCHING +#define DECOMP_FORCEACTIVE(module, ...) +#define DECOMP_FORCELITERAL(module, x) +#define DECOMP_FORCEDTOR(module, cls) +#define DECOMP_INLINE +#define DECOMP_DONT_INLINE +// Compile with matching hacks. +// (This version of CW does not support pragmas inside macros.) +#else +// Force reference specific data +#define DECOMP_FORCEACTIVE(module, ...) \ + void fake_function(...); \ + void CONCAT(FORCEACTIVE##module, __LINE__)(void); \ + void CONCAT(FORCEACTIVE##module, __LINE__)(void) { \ + fake_function(__VA_ARGS__); \ + } + +// Force literal ordering, such as floats in sdata2 +#define DECOMP_FORCELITERAL(module, ...) \ + void CONCAT(FORCELITERAL##module, __LINE__)(void); \ + void CONCAT(FORCELITERAL##module, __LINE__)(void) { \ + (__VA_ARGS__); \ + } + +// Force reference destructor +#define DECOMP_FORCEDTOR(module, cls) \ + void CONCAT(FORCEDTOR##module##cls, __LINE__)(void) { \ + cls dummy; \ + dummy.~cls(); \ + } +#define DECOMP_INLINE inline +#define DECOMP_DONT_INLINE __attribute__((never_inline)) +#endif + +#endif diff --git a/include/egg/core/eggColorFader.h b/include/egg/core/eggColorFader.h index 9f23f692..4432fd17 100644 --- a/include/egg/core/eggColorFader.h +++ b/include/egg/core/eggColorFader.h @@ -2,10 +2,9 @@ #include "egg/core/eggFader.h" #include "egg/prim/eggBitFlag.h" -#include "nw4r/ut/Color.h" +#include "nw4r/ut.h" #include - namespace EGG { class ColorFader : public Fader { diff --git a/include/egg/core/eggDisplay.h b/include/egg/core/eggDisplay.h index fa771035..ce216883 100644 --- a/include/egg/core/eggDisplay.h +++ b/include/egg/core/eggDisplay.h @@ -3,7 +3,7 @@ #include "egg/core/eggSystem.h" // for BaseSystem config #include "egg/core/eggVideo.h" #include "egg/prim/eggBitFlag.h" -#include "nw4r/ut/Color.h" +#include "nw4r/ut.h" #include "rvl/VI.h" #include diff --git a/include/egg/core/eggDisposer.h b/include/egg/core/eggDisposer.h index adf6ebd3..3600816a 100644 --- a/include/egg/core/eggDisposer.h +++ b/include/egg/core/eggDisposer.h @@ -2,7 +2,7 @@ // This file was adapted from https://github.com/riidefi/mkw/blob/master/source/egg/core/eggDisposer.hpp -#include "nw4r/ut/List.h" +#include "nw4r/ut.h" #include namespace EGG { diff --git a/include/egg/core/eggDvdFile.h b/include/egg/core/eggDvdFile.h index 07c8afab..598b9647 100644 --- a/include/egg/core/eggDvdFile.h +++ b/include/egg/core/eggDvdFile.h @@ -1,12 +1,11 @@ #pragma once #include "egg/core/eggFile.h" -#include "nw4r/ut/List.h" +#include "nw4r/ut.h" #include "rvl/DVD.h" #include "rvl/OS.h" #include - namespace EGG { class DvdFile : public File { diff --git a/include/egg/core/eggHeap.h b/include/egg/core/eggHeap.h index 4ee76380..d8efd657 100644 --- a/include/egg/core/eggHeap.h +++ b/include/egg/core/eggHeap.h @@ -6,12 +6,11 @@ #include "egg/core/eggDisposer.h" #include "egg/core/eggThread.h" #include "egg/prim/eggBitFlag.h" -#include "nw4r/ut/List.h" +#include "nw4r/ut.h" #include "rvl/MEM.h" #include "rvl/OS.h" #include - namespace EGG { // class ExpHeap; diff --git a/include/egg/core/eggThread.h b/include/egg/core/eggThread.h index 117b0677..e2dfcf97 100644 --- a/include/egg/core/eggThread.h +++ b/include/egg/core/eggThread.h @@ -1,11 +1,10 @@ #pragma once #include "egg/core/eggHeap.h" -#include "nw4r/ut/List.h" +#include "nw4r/ut.h" #include "rvl/OS.h" #include - namespace EGG { class Thread { diff --git a/include/egg/math/eggVector.h b/include/egg/math/eggVector.h index 000e5be0..cbd1196b 100644 --- a/include/egg/math/eggVector.h +++ b/include/egg/math/eggVector.h @@ -2,8 +2,9 @@ #include "MSL_C/float.h" #include "egg/math/eggMath.h" -#include "nw4r/math/vec.h" #include +#include + namespace EGG { diff --git a/include/nw4r/ef/ef_animcurve.h b/include/nw4r/ef/ef_animcurve.h new file mode 100644 index 00000000..3471172c --- /dev/null +++ b/include/nw4r/ef/ef_animcurve.h @@ -0,0 +1,13 @@ +#ifndef NW4R_EF_ANIMCURVE_H +#define NW4R_EF_ANIMCURVE_H +#include "types_nw4r.h" + +namespace nw4r +{ + namespace ef + { + UNKTYPE AnimCurveExecuteF32(u8 *, float *, u32, u16, u32); + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_creationqueue.h b/include/nw4r/ef/ef_creationqueue.h new file mode 100644 index 00000000..9cccffc7 --- /dev/null +++ b/include/nw4r/ef/ef_creationqueue.h @@ -0,0 +1,46 @@ +#ifndef NW4R_EF_CREATIONQUEUE +#define NW4R_EF_CREATIONQUEUE +#include "ef_emitter.h" +#include "types_nw4r.h" + +namespace nw4r +{ + namespace ef + { + enum CreationType + { + CreationType_Particle, + CreationType_Emitter + }; + + //sizeof(UNK_CREATIONQUEUE) = 0x14 + struct Creation + { + u8 mType; // at 0x0 + u16 SHORT_0x2; + EmitterInheritSetting mInheritSetting; // at 0x4 + Particle * mParticle; // at 0x8 + EmitterResource * mResource; // at 0xc + }; + + struct CreationQueue + { + CreationQueue(); + void AddParticleCreation(const EmitterInheritSetting *, Particle *, EmitterResource *, u16); + void AddEmitterCreation(const EmitterInheritSetting *, Particle *, EmitterResource *, u16); + + int mSize; + + Creation mCreations[0x400]; + + inline bool IsEmpty() + { + return mSize == 0; + } + + void Execute(); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_cube.h b/include/nw4r/ef/ef_cube.h new file mode 100644 index 00000000..8e091e71 --- /dev/null +++ b/include/nw4r/ef/ef_cube.h @@ -0,0 +1,16 @@ +#ifndef NW4R_EF_CUBE_H +#define NW4R_EF_CUBE_H +#include "ef_emitterform.h" + +namespace nw4r +{ + namespace ef + { + struct EmitterFormCube : EmitterForm + { + virtual UNKTYPE Emission(Emitter *, ParticleManager *, int, u32, float *, u16, float, const math::MTX34 *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_cylinder.h b/include/nw4r/ef/ef_cylinder.h new file mode 100644 index 00000000..ac27d4e7 --- /dev/null +++ b/include/nw4r/ef/ef_cylinder.h @@ -0,0 +1,16 @@ +#ifndef NW4R_EF_CYLINDER_H +#define NW4R_EF_CYLINDER_H +#include "ef_emitterform.h" + +namespace nw4r +{ + namespace ef + { + struct EmitterFormCylinder : EmitterForm + { + virtual UNKTYPE Emission(Emitter *, ParticleManager *, int, u32, float *, u16, float, const math::MTX34 *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_disc.h b/include/nw4r/ef/ef_disc.h new file mode 100644 index 00000000..98d37cb6 --- /dev/null +++ b/include/nw4r/ef/ef_disc.h @@ -0,0 +1,16 @@ +#ifndef NW4R_EF_DISC_H +#define NW4R_EF_DISC_H +#include "ef_emitterform.h" + +namespace nw4r +{ + namespace ef + { + struct EmitterFormDisc : EmitterForm + { + virtual UNKTYPE Emission(Emitter *, ParticleManager *, int, u32, float *, u16, float, const math::MTX34 *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_drawbillboardstrategy.h b/include/nw4r/ef/ef_drawbillboardstrategy.h new file mode 100644 index 00000000..2bdf88cf --- /dev/null +++ b/include/nw4r/ef/ef_drawbillboardstrategy.h @@ -0,0 +1,22 @@ +#ifndef NW4R_EF_DRAW_BILLBOARD_STRATEGY_H +#define NW4R_EF_DRAW_BILLBOARD_STRATEGY_H +#include "types_nw4r.h" +#include "ef_drawstrategyimpl.h" + +namespace nw4r +{ + namespace ef + { + class DrawBillboardStrategy : public DrawStrategyImpl + { + public: + DrawBillboardStrategy(); + virtual ~DrawBillboardStrategy() {} // at 0x8 + virtual UNKTYPE GetCalcAheadFunc(ParticleManager *); // at 0x18 + + void Draw(const DrawInfo &, ParticleManager *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_drawdirectionalstrategy.h b/include/nw4r/ef/ef_drawdirectionalstrategy.h new file mode 100644 index 00000000..47abae96 --- /dev/null +++ b/include/nw4r/ef/ef_drawdirectionalstrategy.h @@ -0,0 +1,22 @@ +#ifndef NW4R_EF_DRAW_DIRECTIONAL_STRATEGY_H +#define NW4R_EF_DRAW_DIRECTIONAL_STRATEGY_H +#include "types_nw4r.h" +#include "ef_drawstrategyimpl.h" + +namespace nw4r +{ + namespace ef + { + class DrawDirectionalStrategy : public DrawStrategyImpl + { + public: + DrawDirectionalStrategy(); + virtual ~DrawDirectionalStrategy() {} // at 0x8 + virtual UNKTYPE GetCalcAheadFunc(ParticleManager *); // at 0x18 + + void Draw(const DrawInfo &, ParticleManager *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_drawfreestrategy.h b/include/nw4r/ef/ef_drawfreestrategy.h new file mode 100644 index 00000000..42b156b0 --- /dev/null +++ b/include/nw4r/ef/ef_drawfreestrategy.h @@ -0,0 +1,21 @@ +#ifndef NW4R_EF_DRAW_FREE_STRATEGY_H +#define NW4R_EF_DRAW_FREE_STRATEGY_H +#include "types_nw4r.h" +#include "ef_drawstrategyimpl.h" + +namespace nw4r +{ + namespace ef + { + class DrawFreeStrategy : public DrawStrategyImpl + { + public: + DrawFreeStrategy(); + virtual ~DrawFreeStrategy() {} // at 0x8 + + UNKTYPE Draw(const DrawInfo &, ParticleManager *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_drawinfo.h b/include/nw4r/ef/ef_drawinfo.h new file mode 100644 index 00000000..a156d1ab --- /dev/null +++ b/include/nw4r/ef/ef_drawinfo.h @@ -0,0 +1,16 @@ +#ifndef NW4R_EF_DRAWINFO +#define NW4R_EF_DRAWINFO +#include "types_nw4r.h" + +namespace nw4r +{ + namespace ef + { + struct DrawInfo + { + + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_drawlinestrategy.h b/include/nw4r/ef/ef_drawlinestrategy.h new file mode 100644 index 00000000..cdc87596 --- /dev/null +++ b/include/nw4r/ef/ef_drawlinestrategy.h @@ -0,0 +1,21 @@ +#ifndef NW4R_EF_DRAW_LINE_STRATEGY_H +#define NW4R_EF_DRAW_LINE_STRATEGY_H +#include "types_nw4r.h" +#include "ef_drawstrategyimpl.h" + +namespace nw4r +{ + namespace ef + { + class DrawLineStrategy : public DrawStrategyImpl + { + public: + DrawLineStrategy(); + virtual ~DrawLineStrategy() {} // at 0x8 + + UNKTYPE Draw(const DrawInfo &, ParticleManager *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_draworder.h b/include/nw4r/ef/ef_draworder.h new file mode 100644 index 00000000..53a568bd --- /dev/null +++ b/include/nw4r/ef/ef_draworder.h @@ -0,0 +1,20 @@ +#ifndef NW4R_EF_DRAWORDER +#define NW4R_EF_DRAWORDER +#include "types_nw4r.h" +#include "ef_particlemanager.h" +#include "ef_draworderbase.h" + +namespace nw4r +{ + namespace ef + { + struct DrawOrder : DrawOrderBase + { + void Draw(Effect *, const DrawInfo &); + void Add(Effect *, ParticleManager *); + void Remove(Effect *, ParticleManager *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_draworderbase.h b/include/nw4r/ef/ef_draworderbase.h new file mode 100644 index 00000000..ba42be89 --- /dev/null +++ b/include/nw4r/ef/ef_draworderbase.h @@ -0,0 +1,18 @@ +#ifndef NW4R_EF_DRAWORDERBASE +#define NW4R_EF_DRAWORDERBASE +#include "ef_particlemanager.h" +#include "ut_list.h" +#include + + +namespace nw4r { +namespace ef { +struct DrawOrderBase { + virtual void Add(Effect *, ParticleManager *) = 0; + virtual void Remove(Effect *, ParticleManager *) = 0; + virtual void Draw(Effect *, const DrawInfo &) = 0; +}; +} // namespace ef +} // namespace nw4r + +#endif diff --git a/include/nw4r/ef/ef_drawpointstrategy.h b/include/nw4r/ef/ef_drawpointstrategy.h new file mode 100644 index 00000000..ef4ca9d1 --- /dev/null +++ b/include/nw4r/ef/ef_drawpointstrategy.h @@ -0,0 +1,22 @@ +#ifndef NW4R_EF_DRAW_POINT_STRATEGY_H +#define NW4R_EF_DRAW_POINT_STRATEGY_H +#include "types_nw4r.h" +#include "ef_drawstrategyimpl.h" + +namespace nw4r +{ + namespace ef + { + class DrawPointStrategy : public DrawStrategyImpl + { + public: + DrawPointStrategy(); + virtual ~DrawPointStrategy() {} // at 0x8 + + void Draw(const DrawInfo&, ParticleManager *); + void InitGraphics(const DrawInfo&, ParticleManager *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_drawsmoothstripestrategy.h b/include/nw4r/ef/ef_drawsmoothstripestrategy.h new file mode 100644 index 00000000..3a172b5f --- /dev/null +++ b/include/nw4r/ef/ef_drawsmoothstripestrategy.h @@ -0,0 +1,22 @@ +#ifndef NW4R_EF_DRAW_SMOOTH_STRIPE_STRATEGY_H +#define NW4R_EF_DRAW_SMOOTH_STRIPE_STRATEGY_H +#include "types_nw4r.h" +#include "ef_drawstrategyimpl.h" + +namespace nw4r +{ + namespace ef + { + class DrawSmoothStripeStrategy : public DrawStrategyImpl + { + public: + DrawSmoothStripeStrategy(); + virtual ~DrawSmoothStripeStrategy() {} // at 0x8 + virtual UNKTYPE GetCalcAheadFunc(ParticleManager *); // at 0x18 + + UNKTYPE Draw(const DrawInfo &, ParticleManager *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_drawstrategy.h b/include/nw4r/ef/ef_drawstrategy.h new file mode 100644 index 00000000..e3ed01d7 --- /dev/null +++ b/include/nw4r/ef/ef_drawstrategy.h @@ -0,0 +1,17 @@ +#ifndef NW4R_EF_DRAWSTRATEGY_H +#define NW4R_EF_DRAWSTRATEGY_H +#include "types_nw4r.h" + +namespace nw4r +{ + namespace ef + { + struct DrawStrategy + { + inline virtual ~DrawStrategy() {} + virtual UNKTYPE Draw(const DrawInfo &, ParticleManager *) = 0; + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_drawstrategybuilder.h b/include/nw4r/ef/ef_drawstrategybuilder.h new file mode 100644 index 00000000..d39e638d --- /dev/null +++ b/include/nw4r/ef/ef_drawstrategybuilder.h @@ -0,0 +1,27 @@ +#ifndef NW4R_EF_DRAWSTRATEGYBUILDER_H +#define NW4R_EF_DRAWSTRATEGYBUILDER_H +#include "types_nw4r.h" + +namespace nw4r +{ + namespace ef + { + enum DrawStrategyType + { + DrawStratType_Point, + DrawStratType_Line, + DrawStratType_Free, + DrawStratType_Billboard, + DrawStratType_Directional, + DrawStratType_Stripe, + DrawStratType_SmoothStripe + }; + + struct DrawStrategyBuilder + { + virtual DrawStrategy * Create(u32); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_drawstrategyimpl.h b/include/nw4r/ef/ef_drawstrategyimpl.h new file mode 100644 index 00000000..c236a044 --- /dev/null +++ b/include/nw4r/ef/ef_drawstrategyimpl.h @@ -0,0 +1,44 @@ +#ifndef NW4R_EF_DRAW_STRATEGY_IMPL_H +#define NW4R_EF_DRAW_STRATEGY_IMPL_H +#include "types_nw4r.h" +#include "ef_drawstrategy.h" +#include "math_types.h" + +namespace nw4r +{ + namespace ef + { + class DrawStrategyImpl : public DrawStrategy + { + public: + struct PrevTexture + { + UNKWORD WORD_0x0; + f32 FLOAT_0x4; + f32 FLOAT_0x8; + f32 FLOAT_0xC; + f32 FLOAT_0x10; + UNKWORD WORD_0x14; + UNKWORD WORD_0x18; + math::VEC2 VEC2_0x1C; + f32 FLOAT_0x24; + math::VEC2 VEC2_0x28; + }; + + public: + DrawStrategyImpl(); + virtual UNKTYPE GetGetFirstDrawParticleFunc(int); + virtual UNKTYPE GetGetNextDrawParticleFunc(int); + + void InitTexture(const EmitterDrawSetting &); + void InitTev(const EmitterDrawSetting &, const DrawInfo &); + void InitColor(ParticleManager *, const EmitterDrawSetting &, const DrawInfo &); + + private: + PrevTexture mPrevTextures[3]; // at 0x4 + char UNK_0x94[0xBC - 0x94]; + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_drawstripestrategy.h b/include/nw4r/ef/ef_drawstripestrategy.h new file mode 100644 index 00000000..ccdbc04f --- /dev/null +++ b/include/nw4r/ef/ef_drawstripestrategy.h @@ -0,0 +1,22 @@ +#ifndef NW4R_EF_DRAW_STRIPE_STRATEGY_H +#define NW4R_EF_DRAW_STRIPE_STRATEGY_H +#include "types_nw4r.h" +#include "ef_drawstrategyimpl.h" + +namespace nw4r +{ + namespace ef + { + class DrawStripeStrategy : public DrawStrategyImpl + { + public: + DrawStripeStrategy(); + virtual ~DrawStripeStrategy() {} // at 0x8 + virtual UNKTYPE GetCalcAheadFunc(ParticleManager *); // at 0x18 + + UNKTYPE Draw(const DrawInfo &, ParticleManager *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_effect.h b/include/nw4r/ef/ef_effect.h new file mode 100644 index 00000000..24050fc8 --- /dev/null +++ b/include/nw4r/ef/ef_effect.h @@ -0,0 +1,59 @@ +#ifndef NW4R_EF_EFFECT +#define NW4R_EF_EFFECT +#include "types_nw4r.h" +#include "math_types.h" +#include "ef_ref.h" +#include "ut_list.h" +#include "ef_list.h" +#include "ef_util.h" + +namespace nw4r +{ + namespace ef + { + struct Effect : ReferencedObject + { + EffectSystem * mSystem; // at 0x20 + ActivityList mEmitters; // at 0x24 + u32 INDEX_0x40; + + void (* mEmissionPrologue)(Emitter *, ParticleManager *, int *, u32 *, float *, u16 *, float *, math::MTX34 *); // at 0x44 + + UNKWORD WORD_0x48; + UNKWORD WORD_0x4C; + u32 mFlags; // at 0x50 + math::MTX34 mRootMtx; // at 0x54 + math::VEC3 VEC_0x84; + ut::List UTLIST_0x90; + DrawOrder * mDrawOrder; // at 0x9c + + Effect(); + ~Effect(); + + virtual bool Initialize(EffectSystem *, EmitterResource *, u16); + virtual Emitter * CreateEmitter(ResEmitter, u8, u16); + virtual void Calc(bool); + virtual void Draw(const DrawInfo &); + + bool SendClosing(); + UNKTYPE DestroyFunc(); + bool Closing(Emitter *); + Emitter * CreateEmitter(EmitterResource *, u8, u16); + bool RetireEmitter(Emitter *); + u16 RetireEmitterAll(); + u16 RetireParticleAll(); + u16 GetNumEmitter() const; + Emitter * GetEmitter(u16); + u16 ForeachParticleManager(Action, u32, bool); + u16 ForeachEmitterFrom(Action, u32, bool, Emitter *); + UNKTYPE SetRootMtx(const math::MTX34 &); + + inline bool GetFlagDisableDraw() + { + return mFlags & 2; + } + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_effectsystem.h b/include/nw4r/ef/ef_effectsystem.h new file mode 100644 index 00000000..93ccccf7 --- /dev/null +++ b/include/nw4r/ef/ef_effectsystem.h @@ -0,0 +1,57 @@ +#ifndef NW4R_EF_EFFECTSYSTEM +#define NW4R_EF_EFFECTSYSTEM +#include "types_nw4r.h" +#include "ef_creationqueue.h" +#include "ef_ref.h" +#include "ef_rand.h" +#include "ef_list.h" + +namespace nw4r +{ + namespace ef + { + struct EffectSystem + { + static bool mDisplayVersion; + + static EffectSystem instance; + + MemoryManager * mMemoryManager; // at 0x0 + DrawOrder * mDrawOrder; // at 0x4 + DrawStrategyBuilder * mDrawStrategyBuilder; // at 0x8 + EmitFormBuilder * mEmitFormBuilder; // at 0xc + CreationQueue mCreationQueue; // at 0x10 + u32 mNumGroup; + ActivityList * ARR_0x5018; + Random mRandom; // at 0x501C + math::VEC3 VEC_0x5020; + math::MTX34 MTX_0x502C; + float FLOAT_0x505C; + float FLOAT_0x5060; + char BYTE_0x5064; + + inline MemoryManager * GetMemoryManager() const + { + return mMemoryManager; + } + + EffectSystem(); + ~EffectSystem(); + + static EffectSystem * GetInstance(); + + bool Initialize(u32); + bool Closing(Effect *); + Effect * CreateEffect(const char *, u32, u16); + bool RetireEffect(Effect *); + u16 RetireEffectAll(u32); + u16 RetireEmitterAll(u32); + u16 RetireParticleAll(u32); + + void Calc(u32, bool); + void Draw(const DrawInfo &, u32); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_emform.h b/include/nw4r/ef/ef_emform.h new file mode 100644 index 00000000..97f8adf2 --- /dev/null +++ b/include/nw4r/ef/ef_emform.h @@ -0,0 +1,27 @@ +#ifndef NW4R_EF_EMFORM_H +#define NW4R_EF_EMFORM_H +#include "types_nw4r.h" + +namespace nw4r +{ + namespace ef + { + enum EmitFormType + { + EmitForm_Disc, + EmitForm_Line, + EmitForm_Cube = 5, + EmitForm_Cylinder = 7, + EmitForm_Sphere, + EmitForm_Point, + EmitForm_Torus + }; + + struct EmitFormBuilder + { + virtual EmitterForm * Create(EmitFormType); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_emitter.h b/include/nw4r/ef/ef_emitter.h new file mode 100644 index 00000000..b19ae39a --- /dev/null +++ b/include/nw4r/ef/ef_emitter.h @@ -0,0 +1,259 @@ +#ifndef NW4R_EF_EMITTER +#define NW4R_EF_EMITTER +#include +#include "types_nw4r.h" +#include "ef_ref.h" +#include "ut_list.h" +#include "ef_list.h" +#include "ef_rand.h" +#include "ef_util.h" +#include "ef_animcurve.h" + +namespace nw4r +{ + namespace ef + { + struct ResEmitter + { + EmitterResource * mPtr; + + inline EmitterResource * ptr() { return mPtr; } + }; + + struct EmitterInheritSetting + { + s16 SHORT_0x0; + u8 BYTE_0x2; + u8 BYTE_0x3; + u8 BYTE_0x4; + u8 BYTE_0x5; + u8 BYTE_0x6; + u8 BYTE_0x7; + }; + + struct EmitterDesc + { + UNKWORD FLAGS_0x0; // at 0x0/0x8 + UNKWORD EMFORMTYPE_0x4; // at 0x4/0xc + u16 SHORT_0x8; // at 0x8/0x10 + u16 SHORT_0xA; // at 0xa/0x12 + s8 SBYTE_0xC; // at 0xc/0x14 + s8 SBYTE_0xD; // at 0xd/0x15 + s8 SBYTE_0xE; // at 0xe/0x16 + s8 SBYTE_0xF; // at 0xf/0x17 + float FLOAT_0x10; // at 0x10/0x18 + u16 SHORT_0x14; // at 0x14/0x1c + u16 SHORT_0x16; // at 0x16/0x1e + u16 SHORT_0x18; // at 0x18/0x20 + s8 BYTE_0x1A; // at 0x1a/0x22 + s8 BYTE_0x1B; // at 0x1b/0x23 + float FLOAT_0x1C; + float FLOAT_0x20; + float FLOAT_0x24; + float FLOAT_0x28; + float FLOAT_0x2C; + float FLOAT_0x30; + u16 SHORT_0x34; + u8 BYTE_0x36; + u8 BYTE_0x37; + float FLOAT_0x38; + float FLOAT_0x3C; + float FLOAT_0x40; + float FLOAT_0x44; + float FLOAT_0x48; + float FLOAT_0x4C; + float FLOAT_0x50; + float FLOAT_0x54; + float FLOAT_0x58; + float FLOAT_0x5C; + + float FLOAT_0x60; + float FLOAT_0x64; + float FLOAT_0x68; + float FLOAT_0x6C; + float FLOAT_0x70; + float FLOAT_0x74; + + float FLOAT_0x78; + float FLOAT_0x7C; + float FLOAT_0x80; + + u8 BYTE_0x84; // at 0x84/0x8c + u8 BYTE_0x85; // at 0x85/0x8d + u8 BYTE_0x86; // at 0x86/0x8e + UNKWORD WORD_0x88; + }; + + struct EmitTrack + { + u8 BYTE_0x0; + u8 BYTE_0x1; + u16 SHORT_0x2; + + u8 BYTE_0x4; + }; + + struct EmitterResource + { + char UNK_0x0[0x4]; + u32 OFFSET_0x4; + + EmitterDesc STRUCT_0x8; + + inline UNKTYPE * SkipEmitterDesc() + { + return (char *)&STRUCT_0x8 + OFFSET_0x4; + } + + inline UNKTYPE * SkipParticleParameterDesc() + { + char * particleDesc = (char *)SkipEmitterDesc(); + + return particleDesc + *(int *)particleDesc; + } + + inline u16 NumEmitInitTrack() + { + u16 * ptr = (u16 *)SkipParticleParameterDesc(); + + return ptr[(4**(ptr += 2))+3]; + } + + inline u16 NumEmitTrack() + { + u16 * ptr = (u16 *)SkipParticleParameterDesc(); + + return ptr[(4**(ptr += 2))+2]; + } + + inline EmitTrack * GetEmitTrack(u16 i) + { + u16 * ptr = (u16 *)SkipParticleParameterDesc(); + + return reinterpret_cast(ptr)[(2**(ptr += 1))+1+i]; + } + }; + + struct Emitter : ReferencedObject + { + virtual bool Initialize(Effect *, EmitterResource *, u8); // at 0x10 + virtual Emitter * CreateEmitter(EmitterResource *, EmitterInheritSetting *, Particle *, u16); // at 0x14 + virtual void CalcEmitter(); // at 0x18 + virtual void CalcParticle(); // at 0x1c + virtual void CalcEmission(); // at 0x20 + virtual void CalcBillboard(); // at 0x24 + + u32 mFlags; + UNKWORD WORD_0x24; + + //char UNK_0x28[0x8C]; + float FLOAT_0x28; + float FLOAT_0x2C; + short SHORT_0x30; + short SHORT_0x32; + float FLOAT_0x34; + float FLOAT_0x38; + short SHORT_0x3C; + float FLOAT_0x40; + float FLOAT_0x44; + float FLOAT_0x48; + float FLOAT_0x4C; + float FLOAT_0x50; + float FLOAT_0x54; + float FLOAT_0x58; + float FLOAT_0x5C; + float FLOAT_0x60; + + u8 BYTE_0x64; + s8 BYTE_0x65; + u8 BYTE_0x66; + s8 BYTE_0x67; + + float FLOAT_0x68; + float FLOAT_0x6C; + float FLOAT_0x70; + float FLOAT_0x74; + float FLOAT_0x78; + float FLOAT_0x7C; + float FLOAT_0x80; + float FLOAT_0x84; + float FLOAT_0x88; + float FLOAT_0x8C; + /* + float FLOAT_0x90; + float FLOAT_0x94; + float FLOAT_0x98; + */ + math::VEC3 VEC_0x90; + /* + float FLOAT_0x9C; + float FLOAT_0xA0; + float FLOAT_0xA4; + */ + math::VEC3 VEC_0x9C; + /* + float FLOAT_0xA8; + float FLOAT_0xAC; + float FLOAT_0xB0; + */ + math::VEC3 VEC_0xA8; + + UNKWORD WORD_0xB4; + EmitterResource * mResource; // at 0xb8 + Effect * mEffect; // at 0xbc + ActivityList mManagers; // at 0xc0 + char UNK_0xDA[0x2]; + u8 BYTE_0xDC; + u16 SHORT_0xDE; + u16 SHORT_0xE0; + UNKWORD WORD_0xE4; + u16 SHORT_0xE8; + u16 SHORT_0xEA; + Random mRandom; // at 0xec + EmitterForm * mForm; // at 0xf0 + Emitter * mParent; // at 0xf4 + Particle * REF_0xF8; // at 0xf8 + + EmitterInheritSetting mInheritSettings; // at 0xfc + + bool mMtxDirtyFlag; // at 0x104 + + math::MTX34 mGlobalMtx; // at 0x108 + + Emitter(); + ~Emitter(); + + u16 RetireParticleAll(); + bool SendClosing(); + void DestroyFunc(); + bool Closing(ParticleManager *); + bool RetireParticleManager(ParticleManager *); + u16 RetireParticleManagerAll(); + bool InitializeDatas(EmitterResource *, Effect *); + + ParticleManager * FindParticleManager(EmitterResource *, bool, bool, s8, u8); + UNKTYPE CreateEmitterTmp(EmitterResource *, EmitterInheritSetting *, Particle *, u16); + + float GetLODratio(math::VEC3 &, math::VEC3 &, float, float, float, float); + + u16 ForeachParticleManager(Action, u32, bool, bool); + + UNKTYPE Emission(ParticleManager *, const math::MTX34 *); + + math::MTX34 * CalcGlobalMtx(math::MTX34 *); + UNKTYPE SetMtxDirty(); + + static math::MTX34 * RestructMatrix(math::MTX34 *, math::MTX34 *, bool, bool, s8); + + u16 GetNumParticleManager() const; + ParticleManager * GetParticleManager(u16); + + inline bool GetFlagDisableCalc() const + { + return mFlags & 0x200; + } + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_emitterform.h b/include/nw4r/ef/ef_emitterform.h new file mode 100644 index 00000000..28de21fb --- /dev/null +++ b/include/nw4r/ef/ef_emitterform.h @@ -0,0 +1,19 @@ +#ifndef NW4R_EF_EMITTERFORM_H +#define NW4R_EF_EMITTERFORM_H +#include "types_nw4r.h" + +namespace nw4r +{ + namespace ef + { + struct EmitterForm + { + virtual UNKTYPE Emission(Emitter *, ParticleManager *, int, u32, float *, u16, float, const math::MTX34 *) = 0; + + UNKTYPE CalcVelocity(math::VEC3 *, Emitter *, const math::VEC3 &, const math::VEC3 &, const math::VEC3 &, const math::VEC3 &) const; + u16 CalcLife(u16, float, Emitter *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_handle.h b/include/nw4r/ef/ef_handle.h new file mode 100644 index 00000000..4e0c4f6e --- /dev/null +++ b/include/nw4r/ef/ef_handle.h @@ -0,0 +1,29 @@ +#ifndef NW4R_EF_HANDLE_H +#define NW4R_EF_HANDLE_H +#include "types_nw4r.h" + +namespace nw4r +{ + namespace ef + { + struct LinkedObject + { + char UNK_0x0[8]; + LinkedObject * PTR_0x8; + }; + + struct HandleBase + { + LinkedObject * PTR_0x0; + LinkedObject * mPtr; + + HandleBase(); + HandleBase & operator=(const HandleBase &); + HandleBase & operator=(LinkedObject *); + bool IsValid() const; + LinkedObject * GetPtr() const; + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_line.h b/include/nw4r/ef/ef_line.h new file mode 100644 index 00000000..ed8067d9 --- /dev/null +++ b/include/nw4r/ef/ef_line.h @@ -0,0 +1,16 @@ +#ifndef NW4R_EF_LINE_H +#define NW4R_EF_LINE_H +#include "ef_emitterform.h" + +namespace nw4r +{ + namespace ef + { + struct EmitterFormLine : EmitterForm + { + virtual UNKTYPE Emission(Emitter *, ParticleManager *, int, u32, float *, u16, float, const math::MTX34 *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_list.h b/include/nw4r/ef/ef_list.h new file mode 100644 index 00000000..d4ea3468 --- /dev/null +++ b/include/nw4r/ef/ef_list.h @@ -0,0 +1,67 @@ +#ifndef NW4R_EF_LIST +#define NW4R_EF_LIST +#include "types_nw4r.h" +#include "ut_list.h" + +namespace nw4r +{ + namespace ef + { + //sizeof(ActivityList) = 0x1C + struct ActivityList + { + ut::List mActive; + ut::List mClosing; + u16 mNumActive; + + inline void SetOffset(u16 offset) + { + ut::List_Init(&mActive, offset); + ut::List_Init(&mClosing, offset); + mNumActive = 0; + } + + inline ActivityList(u16 offset) + { + SetOffset(offset); + } + + inline ActivityList() + { + SetOffset(0); + } + + inline void Initialize() + { + mActive.first = NULL; + mActive.size = 0; + mActive.last = NULL; + + mClosing.first = NULL; + mClosing.size = 0; + mClosing.last = NULL; + + mNumActive = 0; + } + + inline void ToActive(void * pNode) + { + ut::List_Append(&mActive, pNode); + mNumActive++; + } + + inline void ToClosing(void * pNode) + { + ut::List_Remove(&mActive, pNode); + ut::List_Append(&mClosing, pNode); + } + + inline void ToWait(void * pNode) + { + mNumActive--; + } + }; + } +} + +#endif diff --git a/include/nw4r/ef/ef_memorymanager.h b/include/nw4r/ef/ef_memorymanager.h new file mode 100644 index 00000000..198778d3 --- /dev/null +++ b/include/nw4r/ef/ef_memorymanager.h @@ -0,0 +1,16 @@ +#ifndef NW4R_EF_MEMORYMANAGER +#define NW4R_EF_MEMORYMANAGER +#include "ef_memorymanagerbase.h" + +namespace nw4r +{ + namespace ef + { + struct MemoryManager : MemoryManagerBase + { + + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_memorymanagerbase.h b/include/nw4r/ef/ef_memorymanagerbase.h new file mode 100644 index 00000000..bf722d83 --- /dev/null +++ b/include/nw4r/ef/ef_memorymanagerbase.h @@ -0,0 +1,43 @@ +#ifndef NW4R_EF_MEMORYMANAGERBASE +#define NW4R_EF_MEMORYMANAGERBASE +#include "types_nw4r.h" + +namespace nw4r +{ + namespace ef + { + struct MemoryManagerBase + { + virtual ~MemoryManagerBase(); // at 0x8 + virtual UNKTYPE GarbageCollection() = 0; // at 0xc + + virtual Effect * AllocEffect() = 0; // at 0x10 + virtual UNKTYPE FreeEffect(void *) = 0; // at 0x14 + virtual UNKWORD GetNumAllocEffect() const = 0; // at 0x18 + virtual UNKWORD GetNumActiveEffect() const = 0; // at 0x1c + virtual UNKWORD GetNumFreeEffect() const = 0; // at 0x20 + + virtual Emitter * AllocEmitter() = 0; // at 0x24 + virtual UNKTYPE FreeEmitter(void *) = 0; // at 0x28 + virtual UNKWORD GetNumAllocEmitter() const = 0; // at 0x2c + virtual UNKWORD GetNumActiveEmitter() const = 0; // at 0x30 + virtual UNKWORD GetNumFreeEmitter() const = 0; // at 0x34 + + virtual ParticleManager * AllocParticleManager() = 0; // at 0x38 + virtual UNKTYPE FreeParticleManager(void *) = 0; // at 0x3c + virtual UNKWORD GetNumAllocParticleManager() const = 0; // at 0x40 + virtual UNKWORD GetNumActiveParticleManager() const = 0; // at 0x44 + virtual UNKWORD GetNumFreeParticleManager() const = 0; // at 0x48 + + virtual Particle * AllocParticle() = 0; // at 0x4c + virtual UNKTYPE FreeParticle(void *) = 0; // at 0x50 + virtual UNKWORD GetNumAllocParticle() const = 0; // at 0x54 + virtual UNKWORD GetNumActiveParticle() const = 0; // at 0x58 + virtual UNKWORD GetNumFreeParticle() const = 0; // at 0x5c + + virtual void * AllocHeap(u32) = 0; // at 0x60 + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_particle.h b/include/nw4r/ef/ef_particle.h new file mode 100644 index 00000000..faae8309 --- /dev/null +++ b/include/nw4r/ef/ef_particle.h @@ -0,0 +1,24 @@ +#ifndef NW4R_EF_PARTICLE_H +#define NW4R_EF_PARTICLE_H +#include "types_nw4r.h" +#include "ef_ref.h" + +namespace nw4r +{ + namespace ef + { + struct Particle : ReferencedObject + { + char UNK_0x20[0x8C]; + + math::VEC3 VEC_0xAC; + math::VEC3 VEC_0xB8; + + char UNK_0xC4[0x4]; + + ParticleManager * mManager; // at 0xc8 + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_particlemanager.h b/include/nw4r/ef/ef_particlemanager.h new file mode 100644 index 00000000..f850f3e9 --- /dev/null +++ b/include/nw4r/ef/ef_particlemanager.h @@ -0,0 +1,91 @@ +#ifndef NW4R_EF_PARTICLEMANAGER +#define NW4R_EF_PARTICLEMANAGER +#include "types_nw4r.h" +#include "math_types.h" +#include "ef_list.h" +#include "ef_ref.h" +#include "ut_Color.h" + +namespace nw4r +{ + namespace ef + { + struct ParticleManager : ReferencedObject + { + struct ParticleModifier + { + math::VEC2 mScale; // at 0x0 + math::VEC3 mRotate; // at 0x8 + + struct SimpleLight + { + u8 mType; // at 0x0 + ut::Color mAmbColor; // at 0x1 + } mLight; + }; + + UNKTYPE BeginDraw(); + UNKTYPE EndDraw(); + UNKTYPE BeginCalc(bool); + UNKTYPE EndCalc(); + + bool SendClosing(); + UNKTYPE DestroyFunc(); + virtual bool Initialize(Emitter *, EmitterResource *); + virtual UNKTYPE CreateParticle(u16, math::VEC3, math::VEC3, const math::MTX34 *, float, const EmitterInheritSetting *, Particle *, u16); + virtual UNKTYPE Calc(); + virtual UNKTYPE Draw(const DrawInfo &); + + Emitter * mEmitter; // at 0x20 + EmitterResource * mResource; // at 0x24 + UNKWORD FLAGS_0x28; + char UNK_0x2C[0xC]; + ActivityList EFLIST_0x38; + char UNK_0x54[0x4]; + + ParticleModifier mMod; // at 0x58 + + char UNK_0x74[0x14]; + + s8 BYTE_0x88; + u8 BYTE_0x89; + bool BOOL_0x8A; + + UNKWORD FLAGS_0xB4; + + u16 RetireParticleAll(); + + UNKTYPE CalcGlobalMtx(math::MTX34 *); + + static void ModifierTravFunc_SetSimpleLightType(void *p, u32 payload) + { + ParticleManager *mgr = (ParticleManager *)p; + u8 type = (u8)payload; + mgr->mMod.mLight.mType = type; + } + + static void ModifierTravFunc_SetSimpleLightAmbient(void *p, u32 payload) + { + ParticleManager *mgr = (ParticleManager *)p; + ut::Color *color = (ut::Color *)payload; + mgr->mMod.mLight.mAmbColor = *color; + } + + static void ModifierTravFunc_SetScale(void *p, u32 payload) + { + ParticleManager *mgr = (ParticleManager *)p; + math::VEC2 *scale = (math::VEC2 *)payload; + mgr->mMod.mScale = *scale; + } + + static void ModifierTravFunc_SetRotate(void *p, u32 payload) + { + ParticleManager *mgr = (ParticleManager *)p; + math::VEC3 *rot = (math::VEC3 *)payload; + mgr->mMod.mRotate = *rot; + } + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_point.h b/include/nw4r/ef/ef_point.h new file mode 100644 index 00000000..3fdebae6 --- /dev/null +++ b/include/nw4r/ef/ef_point.h @@ -0,0 +1,16 @@ +#ifndef NW4R_EF_POINT_H +#define NW4R_EF_POINT_H +#include "ef_emitterform.h" + +namespace nw4r +{ + namespace ef + { + struct EmitterFormPoint : EmitterForm + { + virtual UNKTYPE Emission(Emitter *, ParticleManager *, int, u32, float *, u16, float, const math::MTX34 *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_rand.h b/include/nw4r/ef/ef_rand.h new file mode 100644 index 00000000..a007d096 --- /dev/null +++ b/include/nw4r/ef/ef_rand.h @@ -0,0 +1,38 @@ +#ifndef NW4R_EF_RAND_H +#define NW4R_EF_RAND_H +#include "types_nw4r.h" + +namespace nw4r +{ + namespace ef + { + struct Random + { + u32 mSeed; // at 0x0 + + inline u32 MixRandomSeed() + { + return mSeed = mSeed * 0x343fd + 0x269ec3; + } + + inline void Srand(u32 seed) + { + mSeed = seed; + } + + inline u32 Rand() + { + //WARNING: THIS INLINE FUNCTION MAY NOT BE ACCURATE + return MixRandomSeed() >> 0x10; + } + + inline float RandFloat() + { + //WARNING: THIS INLINE FUNCTION MAY NOT BE ACCURATE + return (float)Rand() / 0xFFFF; + } + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_ref.h b/include/nw4r/ef/ef_ref.h new file mode 100644 index 00000000..2ee05712 --- /dev/null +++ b/include/nw4r/ef/ef_ref.h @@ -0,0 +1,48 @@ +#ifndef NW4R_EF_REF +#define NW4R_EF_REF +#include "types_nw4r.h" +#include "math_types.h" + +namespace nw4r +{ + namespace ef + { + struct ReferencedObject + { + char UNK_0x0[0xC]; + UNKWORD WORD_0xC; + u32 mRefCount; // at 0x10 + char UNK_0x14[0x8]; + + virtual bool SendClosing(); + virtual UNKTYPE DestroyFunc(); + + inline void Initialize() + { + mRefCount = 0; + WORD_0xC = 1; + } + + inline void Ref() + { + mRefCount++; + } + + inline void UnRef() + { + if (--mRefCount == 0 && WORD_0xC == 2) SendClosing(); + } + + inline void Destroy() + { + DestroyFunc(); + WORD_0xC = 2; + if (mRefCount == 0) SendClosing(); + } + }; + + typedef ReferencedObject UNKREF; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_resource.h b/include/nw4r/ef/ef_resource.h new file mode 100644 index 00000000..f3cdd672 --- /dev/null +++ b/include/nw4r/ef/ef_resource.h @@ -0,0 +1,18 @@ +#ifndef NW4R_EF_RESOURCE +#define NW4R_EF_RESOURCE +#include "types_nw4r.h" + +namespace nw4r +{ + namespace ef + { + struct Resource + { + EmitterResource * _FindEmitter(const char *, EffectProject *) const; + + static Resource * GetInstance(); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_sphere.h b/include/nw4r/ef/ef_sphere.h new file mode 100644 index 00000000..88aa9ca2 --- /dev/null +++ b/include/nw4r/ef/ef_sphere.h @@ -0,0 +1,16 @@ +#ifndef NW4R_EF_SPHERE_H +#define NW4R_EF_SPHERE_H +#include "ef_emitterform.h" + +namespace nw4r +{ + namespace ef + { + struct EmitterFormSphere : EmitterForm + { + virtual UNKTYPE Emission(Emitter *, ParticleManager *, int, u32, float *, u16, float, const math::MTX34 *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_torus.h b/include/nw4r/ef/ef_torus.h new file mode 100644 index 00000000..e9521c19 --- /dev/null +++ b/include/nw4r/ef/ef_torus.h @@ -0,0 +1,16 @@ +#ifndef NW4R_EF_TORUS_H +#define NW4R_EF_TORUS_H +#include "ef_emitterform.h" + +namespace nw4r +{ + namespace ef + { + struct EmitterFormTorus : EmitterForm + { + virtual UNKTYPE Emission(Emitter *, ParticleManager *, int, u32, float *, u16, float, const math::MTX34 *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/ef/ef_util.h b/include/nw4r/ef/ef_util.h new file mode 100644 index 00000000..5f7dd6b0 --- /dev/null +++ b/include/nw4r/ef/ef_util.h @@ -0,0 +1,22 @@ +#ifndef NW4R_EF_UTIL +#define NW4R_EF_UTIL +#include "types_nw4r.h" +#include "ut_list.h" + +namespace nw4r +{ + namespace ef + { + typedef void (* Action)(void *, u32); + + u16 UtlistToArray(const ut::List *, void **, int); + + UNKTYPE GetDirMtxY(math::MTX34 *, const math::VEC3 &); + UNKTYPE MtxGetRotation(const math::MTX34 &, math::VEC3 *); + UNKTYPE MtxGetTranslate(const math::MTX34 &, math::VEC3 *); + UNKTYPE MtxGetRotationMtx(const math::MTX34 &, math::MTX34 *); + UNKTYPE MtxGetScale(const math::MTX34 &, math::VEC3 *); + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_3dsmax.h b/include/nw4r/g3d/g3d_3dsmax.h new file mode 100644 index 00000000..01be899b --- /dev/null +++ b/include/nw4r/g3d/g3d_3dsmax.h @@ -0,0 +1,20 @@ +#ifndef NW4R_G3D_3DSMAX_H +#define NW4R_G3D_3DSMAX_H +#include "types_nw4r.h" +#include "g3d_anmtexsrt.h" + +namespace nw4r +{ + namespace g3d + { + namespace detail + { + namespace dcc + { + bool CalcTexMtx_3dsmax(math::MTX34 *, bool, const TexSrt &, TexSrt::Flag); + } + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_anmcamera.h b/include/nw4r/g3d/g3d_anmcamera.h new file mode 100644 index 00000000..1ea8fd1c --- /dev/null +++ b/include/nw4r/g3d/g3d_anmcamera.h @@ -0,0 +1,28 @@ +#ifndef NW4R_G3D_ANMCAMERA_H +#define NW4R_G3D_ANMCAMERA_H +#include "math_types.h" +#include "types_nw4r.h" +#include + + +namespace nw4r { +namespace g3d { +struct CameraAnmResult { + UNKWORD WORD_0x0; + GXProjectionType projType; + f32 FLOAT_0x8; + f32 FLOAT_0xC; + f32 FLOAT_0x10; + f32 FLOAT_0x14; + f32 FLOAT_0x18; + f32 FLOAT_0x1C; + f32 FLOAT_0x20; + f32 FLOAT_0x24; + f32 FLOAT_0x28; + f32 FLOAT_0x2C; + f32 FLOAT_0x30; +}; +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/g3d_anmchr.h b/include/nw4r/g3d/g3d_anmchr.h new file mode 100644 index 00000000..34c6ab51 --- /dev/null +++ b/include/nw4r/g3d/g3d_anmchr.h @@ -0,0 +1,40 @@ +#ifndef NW4R_G3D_ANMCHR_H +#define NW4R_G3D_ANMCHR_H +#include "types_nw4r.h" +#include "math_types.h" + +namespace nw4r +{ + namespace g3d + { + struct ChrAnmResult + { + u32 mFlags; // at 0x0 + math::VEC3 VEC3_0x4; + math::VEC3 VEC3_0x10; + math::MTX34 mMtx; // at 0x1C + }; + + struct AnmObjChr + { + + }; + + struct AnmObjChrNode + { + + }; + + struct AnmObjChrBlend + { + + }; + + struct AnmObjChrRes + { + + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_anmclr.h b/include/nw4r/g3d/g3d_anmclr.h new file mode 100644 index 00000000..dab07f60 --- /dev/null +++ b/include/nw4r/g3d/g3d_anmclr.h @@ -0,0 +1,23 @@ +#ifndef NW4R_G3D_ANMCLR_H +#define NW4R_G3D_ANMCLR_H +#include "types_nw4r.h" + +namespace nw4r +{ + namespace g3d + { + struct ClrAnmResult + { + enum + { + ANM_COUNT = 11 + }; + + u32 mFlags; // at 0x0 + u32 COLORS_0x4[ANM_COUNT]; + UNKWORD WORDS_0x30[ANM_COUNT]; + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_anmfog.h b/include/nw4r/g3d/g3d_anmfog.h new file mode 100644 index 00000000..10f6e72f --- /dev/null +++ b/include/nw4r/g3d/g3d_anmfog.h @@ -0,0 +1,18 @@ +#ifndef NW4R_G3D_ANMFOG_H +#define NW4R_G3D_ANMFOG_H +#include "types_nw4r.h" +#include "ut_Color.h" +#include + +namespace nw4r { +namespace g3d { +struct FogAnmResult { + GXFogType mFogType; // at 0x18 + f32 mStartZ; // at 0x14 + f32 mEndZ; // at 0x10 + ut::Color mColor; // at 0xC +}; +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/g3d_anmobj.h b/include/nw4r/g3d/g3d_anmobj.h new file mode 100644 index 00000000..da233a0e --- /dev/null +++ b/include/nw4r/g3d/g3d_anmobj.h @@ -0,0 +1,129 @@ +#ifndef NW4R_G3D_ANMOBJ_H +#define NW4R_G3D_ANMOBJ_H +#include "types_nw4r.h" +#include "g3d_rescommon.h" +#include "g3d_resmdl.h" +#include "g3d_obj.h" + +namespace nw4r +{ + namespace g3d + { + enum AnmPolicy + { + ANM_POLICY_ONETIME, + ANM_POLICY_LOOP, + ANM_POLICY_MAX + }; + + typedef f32 (* PlayPolicyFunc)(f32, f32, f32); + f32 PlayPolicy_Onetime(f32, f32, f32); + f32 PlayPolicy_Loop(f32, f32, f32); + + inline PlayPolicyFunc GetAnmPlayPolicy(AnmPolicy policy) + { + static PlayPolicyFunc policyTable[ANM_POLICY_MAX] = { + PlayPolicy_Onetime, + PlayPolicy_Loop + }; + return policyTable[policy]; + } + + struct FrameCtrl + { + FrameCtrl(f32 f1, f32 f2, PlayPolicyFunc policy) + : mFrame(0.0f), mRate(1.0f), FLOAT_0x8(f1), mEndFrame(f2), mPolicy(policy) {} + + f32 GetFrm() const + { + return mFrame; + } + + f32 GetRate() const + { + return mRate; + } + + void SetFrm(f32 frm) + { + f32 newFrm = mPolicy(FLOAT_0x8, mEndFrame, frm); + mFrame = newFrm; + } + + void SetRate(f32 rate) + { + mRate = rate; + } + + void SetPolicy(PlayPolicyFunc func) + { + mPolicy = func; + } + + void UpdateFrm() + { + SetFrm(mFrame + mRate * smBaseUpdateRate); + } + + f32 mFrame; // at 0x0 + f32 mRate; // at 0x4 + f32 FLOAT_0x8; + f32 mEndFrame; + PlayPolicyFunc mPolicy; // at 0x10 + + static f32 smBaseUpdateRate; + }; + + class AnmObj : public G3dObj + { + public: + enum AnmFlag + { + ANMFLAG_2 = 0x2, + ANMFLAG_ISBOUND = 0x4 + }; + + public: + AnmObj(MEMAllocator *pAllocator, G3dObj *pParent) + : G3dObj(pAllocator, pParent), mFlags(0) {} + + virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 + { + return (other == GetTypeObjStatic()) ? true + : G3dObj::IsDerivedFrom(other); + } + virtual void G3dProc(u32, u32, void *) = 0; // at 0xC + virtual ~AnmObj() {} // at 0x10 + virtual const TypeObj GetTypeObj() const // at 0x14 + { + return TypeObj(TYPE_NAME); + } + virtual const char * GetTypeName() const // at 0x18 + { + return GetTypeObj().GetTypeName(); + } + virtual void SetFrame(f32) = 0; // at 0x1C + virtual f32 GetFrame() const = 0; // at 0x20 + virtual void UpdateFrame() = 0; // at 0x24 + virtual void SetUpdateRate(f32) = 0; // at 0x28 + virtual f32 GetUpdateRate() const = 0; // at 0x2C + virtual bool Bind(ResMdl) = 0; // at 0x30 + virtual void Release(); // at 0x34 + + static const TypeObj GetTypeObjStatic() + { + return TypeObj(TYPE_NAME); + } + + void SetAnmFlag(AnmFlag, bool); + bool TestAnmFlag(AnmFlag) const; + + private: + u32 mFlags; // at 0x4 + + NW4R_G3D_TYPE_OBJ_DECL(AnmObj); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_anmscn.h b/include/nw4r/g3d/g3d_anmscn.h new file mode 100644 index 00000000..42643e0d --- /dev/null +++ b/include/nw4r/g3d/g3d_anmscn.h @@ -0,0 +1,60 @@ +#ifndef NW4R_G3D_ANMSCN_H +#define NW4R_G3D_ANMSCN_H +#include "types_nw4r.h" +#include "g3d_obj.h" +#include "g3d_light.h" +#include "g3d_fog.h" +#include "g3d_camera.h" + +namespace nw4r +{ + namespace g3d + { + class AnmScnRes // : public AnmScn + { + }; + + class AnmScn : G3dObj + { + public: + AnmScn(MEMAllocator *); + virtual bool IsDerivedFrom(TypeObj other) const; // at 0x8 + virtual ~AnmScn(); // at 0x10 + virtual const TypeObj GetTypeObj() const; // at 0x14 + virtual const char * GetTypeName() const; // at 0x18 + virtual void SetFrame(f32) = 0; // at 0x1C + virtual f32 GetFrame() const = 0; // at 0x20 + virtual void SetUpdateRate(f32) = 0; // at 0x24 + virtual f32 GetUpdateRate() const = 0; // at 0x28 + virtual void UpdateFrame() = 0; // at 0x2C + virtual void Attach(int, AnmScnRes); // at 0x30 + virtual void Detach(); // at 0x34 + virtual int GetNumLightSet() const = 0; // at 0x38 + virtual int GetNumAmbLight() const = 0; // at 0x3C + virtual int GetNumDiffuseLight() const = 0; // at 0x40 + virtual int GetNumSpecularLight() const = 0; // at 0x44 + virtual int GetNumFog() const = 0; // at 0x48 + virtual int GetNumCamera() const = 0; // at 0x4C + virtual int GetLightSetMaxRefNumber() const = 0; // at 0x50 + virtual int GetAmbLightMaxRefNumber() const = 0; // at 0x54 + virtual int GetDiffuseLightMaxRefNumber() const = 0; // at 0x58 + virtual int GetFogMaxRefNumber() const = 0; // at 0x5C + virtual int GetCameraMaxRefNumber() const = 0; // at 0x60 + virtual void GetLightSet(LightSet, u32) = 0; // at 0x64 + virtual ut::Color GetAmbLightColor(u32) = 0; // at 0x68 + virtual void GetLight(LightObj *, LightObj *, u32) = 0; // at 0x6C + virtual void GetFog(Fog, u32) = 0; // at 0x70 + virtual void GetCamera(Camera, u32) = 0; // at 0x74 + virtual int GetSpecularLightID(u32) const = 0; // at 0x78 + virtual bool HasSpecularLight(u32) const = 0; // at 0x7C + virtual void GetAmbLightResult(AmbLightAnmResult *, u32) = 0; // at 0x80 + virtual void GetLightResult(LightAnmResult *, u32) = 0; // at 0x84 + virtual void GetFogResult(FogAnmResult *, u32) = 0; // at 0x88 + virtual void GetFogResult(CameraAnmResult *, u32) = 0; // at 0x8C + + void GetLightSetting(LightSetting *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_anmtexpat.h b/include/nw4r/g3d/g3d_anmtexpat.h new file mode 100644 index 00000000..434a10f7 --- /dev/null +++ b/include/nw4r/g3d/g3d_anmtexpat.h @@ -0,0 +1,24 @@ +#ifndef NW4R_G3D_ANMTEXPAT_H +#define NW4R_G3D_ANMTEXPAT_H +#include "g3d_restex.h" + +namespace nw4r +{ + namespace g3d + { + struct TexPatAnmResult + { + enum + { + ANM_COUNT = 8 + }; + + u8 mTexFlags; // at 0x0 + u8 mPlttFlags; // at 0x1 + ResTex mTexs[ANM_COUNT]; // at 0x4 + ResPltt mPltts[ANM_COUNT]; // at 0x24 + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_anmtexsrt.h b/include/nw4r/g3d/g3d_anmtexsrt.h new file mode 100644 index 00000000..55c286aa --- /dev/null +++ b/include/nw4r/g3d/g3d_anmtexsrt.h @@ -0,0 +1,47 @@ +#ifndef NW4R_G3D_ANMTEXSRT_H +#define NW4R_G3D_ANMTEXSRT_H +#include "g3d_restex.h" + +namespace nw4r +{ + namespace g3d + { + struct TexSrtTypedef + { + enum TexMatrixMode + { + TEX_MTX_MAYA, + TEX_MTX_XSI, + TEX_MTX_3DSMAX + }; + }; + + struct TexSrt + { + enum Flag + { + FLAG_ANM_EXISTS, + }; + + float mScaleX; // at 0x0 + float mScaleY; // at 0x4 + float mRotation; // at 0x8 + float mTranslationX; // at 0xc + float mTranslationY; // at 0x10 + }; + + struct TexSrtAnmResult + { + enum + { + ANM_COUNT = 8 + }; + + UNKWORD FLAGS_0x0; + UNKWORD FLAGS_0x4; + TexSrt mSrts[ANM_COUNT * 2]; // at 0x8 + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_anmvis.h b/include/nw4r/g3d/g3d_anmvis.h new file mode 100644 index 00000000..d7549f8a --- /dev/null +++ b/include/nw4r/g3d/g3d_anmvis.h @@ -0,0 +1,188 @@ +#ifndef NW4R_G3D_ANMVIS_H +#define NW4R_G3D_ANMVIS_H +#include "types_nw4r.h" +#include "g3d_anmobj.h" +#include "g3d_resanmvis.h" + +namespace nw4r +{ + namespace g3d + { + void ApplyVisAnmResult(ResMdl, AnmObjVis *); + void ApplyVisAnmResult(u8 *, ResMdl, AnmObjVis *); + + class AnmObjVis : public AnmObj + { + public: + AnmObjVis(MEMAllocator *, u16 *, int); + virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 + { + return (other == GetTypeObjStatic()) ? true + : AnmObj::IsDerivedFrom(other); + } + virtual void G3dProc(u32, u32, void *); // at 0xC + virtual ~AnmObjVis() {} // at 0x10 + virtual const TypeObj GetTypeObj() const // at 0x14 + { + return TypeObj(TYPE_NAME); + } + virtual const char * GetTypeName() const // at 0x18 + { + return GetTypeObj().GetTypeName(); + } + virtual void SetFrame(f32) = 0; // at 0x1C + virtual f32 GetFrame() const = 0; // at 0x20 + virtual void UpdateFrame() = 0; // at 0x24 + virtual void SetUpdateRate(f32) = 0; // at 0x28 + virtual f32 GetUpdateRate() const = 0; // at 0x2C + virtual bool Bind(ResMdl) = 0; // at 0x30 + virtual void Release(); // at 0x34 + virtual bool GetResult(u32) = 0; // at 0x38 + virtual AnmObjVisRes * Attach(int, AnmObjVisRes *); // at 0x3C + virtual AnmObjVisRes * Detach(int); // at 0x40 + + static const TypeObj GetTypeObjStatic() + { + return TypeObj(TYPE_NAME); + } + + bool TestDefined(u32 idx) const; + bool TestExistence(u32 idx) const; + void DetachAll(); + + protected: + static const int MAX_RESOURCES = 4; + + int mNumBinds; // at 0x10 + u16 *mBinds; // at 0x14 + + NW4R_G3D_TYPE_OBJ_DECL(AnmObjVis); + }; + + class AnmObjVisNode : public AnmObjVis + { + public: + AnmObjVisNode(MEMAllocator *allocator, u16 *bindBuffer, int numBinds) + : AnmObjVis(allocator, bindBuffer, numBinds) + { + mResources[0] = NULL; + mResources[1] = NULL; + mResources[2] = NULL; + mResources[3] = NULL; + } + + virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 + { + return (other == GetTypeObjStatic()) ? true + : AnmObjVis::IsDerivedFrom(other); + } + virtual void G3dProc(u32, u32, void *); // at 0xC + virtual ~AnmObjVisNode(); // at 0x10 + virtual const TypeObj GetTypeObj() const // at 0x14 + { + return TypeObj(TYPE_NAME); + } + virtual const char * GetTypeName() const // at 0x18 + { + return GetTypeObj().GetTypeName(); + } + virtual void SetFrame(f32); // at 0x1C + virtual f32 GetFrame() const; // at 0x20 + virtual void UpdateFrame(); // at 0x24 + virtual void SetUpdateRate(f32); // at 0x28 + virtual f32 GetUpdateRate() const; // at 0x2C + virtual bool Bind(ResMdl); // at 0x30 + virtual void Release(); // at 0x34 + virtual bool GetResult(u32) = 0; // at 0x38 + virtual AnmObjVisRes * Attach(int, AnmObjVisRes *); // at 0x3C + virtual AnmObjVisRes * Detach(int); // at 0x40 + + static const TypeObj GetTypeObjStatic() + { + return TypeObj(TYPE_NAME); + } + + protected: + AnmObjVisRes *mResources[MAX_RESOURCES]; // at 0x18 + + NW4R_G3D_TYPE_OBJ_DECL(AnmObjVisNode); + }; + + class AnmObjVisOR : public AnmObjVisNode + { + public: + AnmObjVisOR(MEMAllocator *allocator, u16 *bindBuffer, int numBinds) + : AnmObjVisNode(allocator, bindBuffer, numBinds) + { + } + + virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 + { + return (other == GetTypeObjStatic()) ? true + : AnmObjVisNode::IsDerivedFrom(other); + } + virtual ~AnmObjVisOR() {} // at 0x10 + virtual const TypeObj GetTypeObj() const // at 0x14 + { + return TypeObj(TYPE_NAME); + } + virtual const char * GetTypeName() const // at 0x18 + { + return GetTypeObj().GetTypeName(); + } + virtual bool GetResult(u32); // at 0x38 + + static const TypeObj GetTypeObjStatic() + { + return TypeObj(TYPE_NAME); + } + + static AnmObjVisOR * Construct(MEMAllocator *, u32 *, ResMdl); + + private: + NW4R_G3D_TYPE_OBJ_DECL(AnmObjVisOR); + }; + + class AnmObjVisRes : public AnmObjVis, public FrameCtrl + { + public: + AnmObjVisRes(MEMAllocator *, ResAnmVis, u16 *, int); + + virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 + { + return (other == GetTypeObjStatic()) ? true + : AnmObjVis::IsDerivedFrom(other); + } + virtual ~AnmObjVisRes() {} // at 0x10 + virtual const TypeObj GetTypeObj() const // at 0x14 + { + return TypeObj(TYPE_NAME); + } + virtual const char * GetTypeName() const // at 0x18 + { + return GetTypeObj().GetTypeName(); + } + virtual void SetFrame(f32); // at 0x1C + virtual f32 GetFrame() const; // at 0x20 + virtual void UpdateFrame(); // at 0x24 + virtual void SetUpdateRate(f32); // at 0x28 + virtual f32 GetUpdateRate() const; // at 0x2C + virtual bool Bind(ResMdl); // at 0x30 + virtual bool GetResult(u32); // at 0x38 + + static const TypeObj GetTypeObjStatic() + { + return TypeObj(TYPE_NAME); + } + + static AnmObjVisRes * Construct(MEMAllocator *, u32 *, ResAnmVis, ResMdl); + + private: + ResAnmVis mResAnmVis; // at 0x2C + + NW4R_G3D_TYPE_OBJ_DECL(AnmObjVisRes); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_basic.h b/include/nw4r/g3d/g3d_basic.h new file mode 100644 index 00000000..e80b3ed3 --- /dev/null +++ b/include/nw4r/g3d/g3d_basic.h @@ -0,0 +1,48 @@ +#ifndef NW4R_G3D_BASIC_H +#define NW4R_G3D_BASIC_H +#include "math_types.h" +#include "g3d_anmchr.h" + +namespace nw4r +{ + namespace g3d + { + namespace detail + { + namespace WorldMtxAttr + { + inline bool IsScaleOne(u32 flags) + { + return (flags & 0x40000000); + } + + inline u32 AnmScaleOne(u32 flags) + { + return (flags | 0x40000000); + } + + inline u32 AnmNotScaleOne(u32 flags) + { + return (flags & 0x3fffffff); + } + + inline u32 AnmScaleUniform(u32 flags) + { + return (flags | 0x10000000); + } + + inline u32 AnmNotScaleUniform(u32 flags) + { + return (flags & 0x0fffffff); + } + } + + namespace dcc + { + u32 CalcWorldMtx_Basic(math::MTX34 *, math::VEC3 *, const math::MTX34 *, const math::VEC3 *, u32, const ChrAnmResult *); + } + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_calcview.h b/include/nw4r/g3d/g3d_calcview.h new file mode 100644 index 00000000..9a705da4 --- /dev/null +++ b/include/nw4r/g3d/g3d_calcview.h @@ -0,0 +1,14 @@ +#ifndef NW4R_G3D_CALC_VIEW_H +#define NW4R_G3D_CALC_VIEW_H +#include "types_nw4r.h" + +namespace nw4r +{ + namespace g3d + { + void CalcView(math::MTX34 *, math::MTX33 *, const math::MTX34 *, const u32 *, + u32, const math::MTX34 *, ResMdl, math::MTX34 *); + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_calcworld.h b/include/nw4r/g3d/g3d_calcworld.h new file mode 100644 index 00000000..70d052cb --- /dev/null +++ b/include/nw4r/g3d/g3d_calcworld.h @@ -0,0 +1,19 @@ +#ifndef NW4R_G3D_CALC_WORLD_H +#define NW4R_G3D_CALC_WORLD_H +#include "types_nw4r.h" + +namespace nw4r +{ + namespace g3d + { + void CalcWorld(math::MTX34 *, u32 *, const u8 *, const math::MTX34 *, + ResMdl, AnmObjChr *, FuncObjCalcWorld *, u32); + + void CalcWorld(math::MTX34 *, u32 *, const u8 *, const math::MTX34 *, + ResMdl, AnmObjChr *, FuncObjCalcWorld *); + + void CalcSkinning(math::MTX34 *, u32 *, ResMdl, const u8 *); + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_camera.h b/include/nw4r/g3d/g3d_camera.h new file mode 100644 index 00000000..5c270db1 --- /dev/null +++ b/include/nw4r/g3d/g3d_camera.h @@ -0,0 +1,107 @@ +#ifndef NW4R_G3D_CAMERA_H +#define NW4R_G3D_CAMERA_H +#include "g3d_rescommon.h" +#include "math_types.h" +#include "types_nw4r.h" +#include + + +namespace nw4r { +namespace g3d { +struct CameraData { + math::MTX34 mCamMtx; // at 0x0 + math::MTX44 mProjMtx; // at 0x30 + u32 mFlags; + math::VEC3 mPos; // at 0x74 + math::VEC3 VEC3_0x80; + math::VEC3 VEC3_0x8C; + math::VEC3 VEC3_0x98; + f32 FLOAT_0xA4; + u32 INT_0xA8; + f32 FLOAT_0xAC; + f32 FLOAT_0xB0; + f32 FLOAT_0xB4; + f32 FLOAT_0xB8; + f32 FLOAT_0xBC; + f32 FLOAT_0xC0; + f32 FLOAT_0xC4; + f32 FLOAT_0xC8; + f32 FLOAT_0xCC; + f32 FLOAT_0xD0; + f32 FLOAT_0xD4; + f32 FLOAT_0xD8; + f32 FLOAT_0xDC; + f32 FLOAT_0xE0; + f32 FLOAT_0xE4; + f32 FLOAT_0xE8; + f32 FLOAT_0xEC; + f32 FLOAT_0xF0; + u32 INT_0xF4; + u32 INT_0xF8; + u32 INT_0xFC; + u32 INT_0x100; + u32 INT_0x104; + u32 INT_0x108; +}; + +struct Camera { + struct PostureInfo { + u32 INT_0x0; + math::VEC3 VEC3_0x04; + math::VEC3 VEC3_0x10; + math::VEC3 VEC3_0x1C; + f32 FLOAT_0x28; + // . . . + }; + + ResCommon mCamData; + + inline Camera(void *vptr) : mCamData(vptr) {} + inline void UpdateProjectionMtx() const { + CameraData &rCamData = mCamData.ref(); + + if (rCamData.mFlags & 0x40) { + C_MTXOrtho(rCamData.mProjMtx, rCamData.FLOAT_0xBC, rCamData.FLOAT_0xC0, rCamData.FLOAT_0xC4, + rCamData.FLOAT_0xC8, rCamData.FLOAT_0xB4, rCamData.FLOAT_0xB8); + } else { + if (rCamData.mFlags & 0x10) { + C_MTXFrustum(rCamData.mProjMtx, rCamData.FLOAT_0xBC, rCamData.FLOAT_0xC0, rCamData.FLOAT_0xC4, + rCamData.FLOAT_0xC8, rCamData.FLOAT_0xB4, rCamData.FLOAT_0xB8); + } else { + C_MTXPerspective(rCamData.mProjMtx, rCamData.FLOAT_0xAC, rCamData.FLOAT_0xB0, rCamData.FLOAT_0xB4, + rCamData.FLOAT_0xB8); + } + } + + rCamData.mFlags |= 0x80; + } + + Camera(CameraData *); + void Init(); + void Init(u16, u16, u16, u16, u16, u16); + void SetPosition(f32, f32, f32); + void SetPosition(const math::VEC3 &); + void SetPosture(const PostureInfo &); + void SetCameraMtxDirectly(const math::MTX34 &); + void SetPerspective(f32, f32, f32, f32); + void SetOrtho(f32, f32, f32, f32, f32, f32); + void SetProjectionMtxDirectly(const math::MTX44 *); + void SetScissor(u32, u32, u32, u32); + void SetScissorBoxOffset(s32, s32); + void SetViewport(f32, f32, f32, f32); + void SetViewportZRange(f32, f32); + void GetViewport(f32 *, f32 *, f32 *, f32 *, f32 *, f32 *) const; + void GetCameraMtx(math::MTX34 *) const; + void GetProjectionMtx(math::MTX44 *) const; + void GetProjectionTexMtx(math::MTX34 *) const; + void GetEnvironmentTexMtx(math::MTX34 *) const; + void GXSetViewport() const; + void GXSetProjection() const; + void GXSetScissor() const; + void GXSetScissorBoxOffset() const; + void UpdateCameraMtx() const; +}; +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/g3d_cpu.h b/include/nw4r/g3d/g3d_cpu.h new file mode 100644 index 00000000..8b159c85 --- /dev/null +++ b/include/nw4r/g3d/g3d_cpu.h @@ -0,0 +1,17 @@ +#ifndef NW4R_G3D_CPU_H +#define NW4R_G3D_CPU_H +#include "types_nw4r.h" + +namespace nw4r +{ + namespace g3d + { + namespace detail + { + void Copy32ByteBlocks(void *, const void *, u32); + void ZeroMemory32ByteBlocks(void *, u32); + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_dcc.h b/include/nw4r/g3d/g3d_dcc.h new file mode 100644 index 00000000..570cdc81 --- /dev/null +++ b/include/nw4r/g3d/g3d_dcc.h @@ -0,0 +1,15 @@ +#ifndef NW4R_G3D_DCC_H +#define NW4R_G3D_DCC_H +#include "types_nw4r.h" +#include "g3d_anmtexsrt.h" + +namespace nw4r +{ + namespace g3d + { + void CalcTexMtx(math::MTX34 *, bool, const TexSrt &, TexSrt::Flag, + TexSrtTypedef::TexMatrixMode); + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_draw.h b/include/nw4r/g3d/g3d_draw.h new file mode 100644 index 00000000..d163bd8d --- /dev/null +++ b/include/nw4r/g3d/g3d_draw.h @@ -0,0 +1,19 @@ +#ifndef NW4R_G3D_DRAW_H +#define NW4R_G3D_DRAW_H +#include "types_nw4r.h" +#include "g3d_resmdl.h" + +namespace nw4r +{ + namespace g3d + { + struct DrawResMdlReplacement + { + }; + + void DrawResMdlDirectly(ResMdl, const math::MTX34 *, const math::MTX33 *, + const math::MTX34 *, const u8 *, const u8 *, DrawResMdlReplacement *, u32); + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_draw1mat1shp.h b/include/nw4r/g3d/g3d_draw1mat1shp.h new file mode 100644 index 00000000..cad3e4a9 --- /dev/null +++ b/include/nw4r/g3d/g3d_draw1mat1shp.h @@ -0,0 +1,20 @@ +#ifndef NW4R_G3D_DRAW1_MAT1_SHP_H +#define NW4R_G3D_DRAW1_MAT1_SHP_H +#include "types_nw4r.h" +#include "g3d_resmat.h" +#include "g3d_resshp.h" + +namespace nw4r +{ + namespace g3d + { + struct Draw1Mat1ShpSwap + { + }; + + void Draw1Mat1ShpDirectly(ResMat, ResShp, const math::MTX34 *, + const math::MTX34 *, u32, Draw1Mat1ShpSwap *, G3DState::IndMtxOp *); + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_fog.h b/include/nw4r/g3d/g3d_fog.h new file mode 100644 index 00000000..240ffc9c --- /dev/null +++ b/include/nw4r/g3d/g3d_fog.h @@ -0,0 +1,75 @@ +#ifndef NW4R_G3D_FOG_H +#define NW4R_G3D_FOG_H +#include "g3d_rescommon.h" +#include "math_types.h" +#include "types_nw4r.h" +#include "ut_Color.h" +#include + + +namespace nw4r { +namespace g3d { +struct FogData { + GXFogType mFogType; // at 0x0 + f32 mStartZ; // at 0x4 + f32 mEndZ; // at 0x8 + f32 mNear; // at 0xC + f32 mFar; // at 0x10 + GXColor mColor; // at 0x14 + u8 mFogRangeAdjEnable; // at 0x18 + u8 BYTE_0x19; + u16 mAdjTableWidth; // at 0x1A + GXFogAdjTable mAdjTable; // at 0x1C +}; + +struct Fog { + ResCommon mFogData; + + inline Fog(void *vptr) : mFogData(vptr) {} + + Fog(FogData *); + void Init(); + void *CopyTo(void *) const; + void SetFogRangeAdjParam(u16, u16, const math::MTX44 &); + void SetGP() const; + + bool IsValid() const { + return mFogData.IsValid(); + } + + bool IsFogRangeAdjEnable() const { + return (IsValid() && mFogData.ref().mFogRangeAdjEnable != 1) ? true : false; + } + + void SetFogColor(GXColor c) { + if (IsValid()) { + mFogData.ref().mColor = c; + } + } + + void SetFogType(GXFogType fog) { + if (IsValid()) { + mFogData.ref().mFogType = fog; + } + } + + void SetNearFar(f32 near, f32 far) { + if (IsValid()) { + FogData &ref = mFogData.ref(); + ref.mNear = near; + ref.mFar = far; + } + } + + void SetZ(f32 start, f32 end) { + if (IsValid()) { + FogData &ref = mFogData.ref(); + ref.mStartZ = start; + ref.mEndZ = end; + } + } +}; +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/g3d_gpu.h b/include/nw4r/g3d/g3d_gpu.h new file mode 100644 index 00000000..760609fe --- /dev/null +++ b/include/nw4r/g3d/g3d_gpu.h @@ -0,0 +1,49 @@ +#ifndef NW4R_G3D_GPU_H +#define NW4R_G3D_GPU_H +#include "g3d_rescommon.h" +#include "math_types.h" +#include "types_nw4r.h" +#include + + +namespace nw4r { +namespace g3d { +namespace fifo { +const u8 cm2hw[] = {0x00, 0x02, 0x01, 0x03}; + +inline void LoadXFCmd(u16 us, u32 ul) { + GXCmd1u8(FIFO_ACCESS_XF); + GXCmd1u16(0); + GXCmd1u16(us); + GXCmd1u32(ul); +} + +inline void LoadBPCmd(u32 ul) { + GXCmd1u8(FIFO_ACCESS_BP); + GXCmd1u32(ul); +} + +inline void LoadXFCmdHdr(u16 us, u8 uc) { + GXCmd1u8(FIFO_ACCESS_XF); + GXCmd1u16((u16)(uc - 1)); + GXCmd1u16(us); +} + +inline void LoadCPCmd(u8 uc, u32 ul) { + GXCmd1u8(FIFO_ACCESS_CP); + GXCmd1u8(uc); + GXCmd1u32(ul); +} + +void GDSetGenMode2(u8, u8, u8, u8, GXCullMode); +void GDSetCullMode(GXCullMode); +void GDSetTexCoordScale2(GXTexCoordID, u16, u8, u8, u16, u8, u8); +void GDSetIndTexMtx(u32, const math::MTX34 &); +void GDResetCurrentMtx(); +void GDSetCurrentMtx(const u32 *); +void GDLoadTexMtxImm3x3(const math::MTX33 &, u32); +} // namespace fifo +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/g3d_init.h b/include/nw4r/g3d/g3d_init.h new file mode 100644 index 00000000..d8d39907 --- /dev/null +++ b/include/nw4r/g3d/g3d_init.h @@ -0,0 +1,19 @@ +#ifndef NW4R_G3D_INIT_H +#define NW4R_G3D_INIT_H +#include "types_nw4r.h" +#include + +namespace nw4r { +namespace g3d { +inline void InitFastCast() { + OSInitFastCast(); + OSSetGQR6(7, 5); + OSSetGQR7(7, 8); +} + +void G3dInit(bool); +void G3dReset(); +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/g3d_light.h b/include/nw4r/g3d/g3d_light.h new file mode 100644 index 00000000..b1235377 --- /dev/null +++ b/include/nw4r/g3d/g3d_light.h @@ -0,0 +1,151 @@ +#ifndef NW4R_G3D_LIGHT_H +#define NW4R_G3D_LIGHT_H +#include "g3d_rescommon.h" +#include "types_nw4r.h" +#include + + +namespace nw4r { +namespace g3d { +struct LightSetData { + static const int NUM_LIGHTS = 8; + + s8 mLights[NUM_LIGHTS]; // at 0x0 + s8 mAmbient; // at 0x8 + char UNK_0x8[3]; // at 0x9 +}; + +struct AmbLightObj { + u8 r, g, b, a; +}; + +struct AmbLightAnmResult {}; + +class LightObj { +private: + enum LightObjFlag { + SPOT_LIGHT = 0x1, + SPECULAR_LIGHT = 0x2, + ENABLED = 0x4, + SPECULAR_DIR = 0x8, + COLOR_ENABLE = 0x10, + ALPHA_ENABLE = 0x20 + }; + +public: + LightObj() : mFlags() {} + + operator GXLightObj *() { + return &mLightObj; + } + operator const GXLightObj *() const { + return &mLightObj; + } + + LightObj &operator=(const LightObj &rhs); + + bool IsSpotLight() const { + return mFlags & SPOT_LIGHT; + } + bool IsSpecularLight() const { + return mFlags & SPECULAR_LIGHT; + } + bool IsEnable() const { + return mFlags & ENABLED; + } + bool IsSpecularDir() const { + return mFlags & SPECULAR_DIR; + } + bool IsColorEnable() const { + return mFlags & COLOR_ENABLE; + } + bool IsAlphaEnable() const { + return mFlags & ALPHA_ENABLE; + } + bool IsDiffuseLight() const { + return !IsSpotLight() && !IsSpecularLight(); + } + + void Enable() { + mFlags |= ENABLED; + } + void Disable() { + mFlags &= ~ENABLED; + } + + void Clear(); + void InitLightColor(GXColor); + void InitLightPos(f32, f32, f32); + void InitLightDir(f32, f32, f32); + void InitSpecularDir(f32, f32, f32); + void InitLightSpot(f32, GXSpotFn); + void InitLightAttnA(f32, f32, f32); + void InitLightDistAttn(f32, f32, GXDistAttnFn); + void InitLightAttnK(f32, f32, f32); + void InitLightShininess(f32); + void GetLightPos(math::VEC3 *) const; + void GetLightDir(math::VEC3 *) const; + void ApplyViewMtx(const math::MTX34 &rMtx); + +private: + u32 mFlags; // at 0x0 + GXLightObj mLightObj; // at 0x4 +}; + +struct LightAnmResult {}; + +struct LightSet { + LightSet(LightSetting *setting, LightSetData *data) : mSetting(setting), mLightSetData(data) {} + + bool IsValid() const { + return mSetting != NULL && mLightSetData != NULL; + } + + bool SelectLightObj(u32, int); + bool SelectAmbLightObj(int); + + LightSetting *mSetting; // at 0x0 + LightSetData *mLightSetData; // at 0x4 +}; + +class LightSetting { +public: + LightSetting(LightObj *, AmbLightObj *, u32, LightSetData *, u32); + bool Import(const LightSetting &); + void ApplyViewMtx(const math::MTX34 &, u32); + + u16 GetNumLightObj() const { + return mNumLightObj; + } + u16 GetNumLightSet() const { + return mNumLightSet; + } + LightObj *GetLightObjArray() const { + return mLightObjArray; + } + AmbLightObj *GetAmbLightObjArray() const { + return mAmbLightObjArray; + } + LightSetData *GetLightSetDataArray() const { + return mLightSetDataArray; + } + + LightSet GetLightSet(int i) { + if (i < mNumLightSet && i > 0) { + return LightSet(this, &mLightSetDataArray[i]); + } + + return LightSet(this, NULL); + } + +private: + u16 mNumLightObj; // at 0x0 + u16 mNumLightSet; // at 0x2 + LightObj *mLightObjArray; // at 0x4 + AmbLightObj *mAmbLightObjArray; // at 0x8 + LightSetData *mLightSetDataArray; // at 0xC +}; +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/g3d_maya.h b/include/nw4r/g3d/g3d_maya.h new file mode 100644 index 00000000..b28becdb --- /dev/null +++ b/include/nw4r/g3d/g3d_maya.h @@ -0,0 +1,20 @@ +#ifndef NW4R_G3D_MAYA_H +#define NW4R_G3D_MAYA_H +#include "types_nw4r.h" +#include "g3d_anmtexsrt.h" + +namespace nw4r +{ + namespace g3d + { + namespace detail + { + namespace dcc + { + bool CalcTexMtx_Maya(math::MTX34 *, bool, const TexSrt &, TexSrt::Flag); + } + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_obj.h b/include/nw4r/g3d/g3d_obj.h new file mode 100644 index 00000000..e755ea47 --- /dev/null +++ b/include/nw4r/g3d/g3d_obj.h @@ -0,0 +1,130 @@ +#ifndef NW4R_G3D_G3DOBJ_H +#define NW4R_G3D_G3DOBJ_H +#include "types_nw4r.h" +#include + +#define NW4R_G3D_TYPE_OBJ_DECL(VAL) static const nw4r::g3d::G3dObj::ResNameDataT TYPE_NAME +#define NW4R_G3D_TYPE_OBJ_DEF(VAL) \ + const nw4r::g3d::G3dObj::ResNameDataT VAL::TYPE_NAME = {sizeof(#VAL), #VAL} + +namespace nw4r { +namespace g3d { +namespace detail { +inline void *AllocFromAllocator(MEMAllocator *pAllocator, u32 size) { + return MEMAllocFromAllocator(pAllocator, size); +} + +inline void FreeToAllocator(MEMAllocator *pAllocator, void *pBlock) { + return MEMFreeToAllocator(pAllocator, pBlock); +} +} // namespace detail + +class G3dObj { +public: + enum G3dProcTask { + G3DPROC_CALC_WORLD = 0x1, + G3DPROC_CALC_MAT = 0x2, + G3DPROC_CALC_VTX = 0x3, + G3DPROC_CALC_VIEW = 0x4, + G3DPROC_GATHER_SCNOBJ = 0x5, + G3DPROC_DRAW_OPA = 0x6, + G3DPROC_DRAW_XLU = 0x7, + G3DPROC_UPDATEFRAME = 0x8, + + G3DPROC_CHILD_DETACHED = 0x10001, + G3DPROC_ATTACH_PARENT = 0x10002, + G3DPROC_DETACH_PARENT = 0x10003, + G3DPROC_0x10004 = 0x10004 + }; + + template + struct ResNameDataT { + u32 mLength; + // Bug? +1 seemingly for null terminator, + // but size N already includes it + char mName[N + 1 + 3 & ~3]; + }; + + struct TypeObj { + struct TypeObjData { + u32 mLength; // at 0x0 + char mName[]; // at 0x4 + }; + + template + TypeObj(const ResNameDataT &pRes) : mData((const TypeObjData *)&pRes) {} + + u32 GetTypeID() const { + return (u32)mData; + } + + const char *GetTypeName() const { + return mData->mName; + } + + bool operator==(const TypeObj &rhs) const { + return GetTypeID() == rhs.GetTypeID(); + } + + const TypeObjData *mData; // at 0x0 + }; + +public: + virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 + { + return other == GetTypeObjStatic(); + } + virtual void G3dProc(u32, u32, void *) = 0; // at 0xC + virtual ~G3dObj(); // at 0x10 + virtual const TypeObj GetTypeObj() const // at 0x14 + { + return TypeObj(TYPE_NAME); + } + virtual const char *GetTypeName() const // at 0x18 + { + return GetTypeObj().GetTypeName(); + } + + static const G3dObj::TypeObj GetTypeObjStatic() { + return TypeObj(TYPE_NAME); + } + + void Destroy(); + + G3dObj(MEMAllocator *pAllocator, G3dObj *pParent) : mAllocator(pAllocator), mParent(pParent) {} + + G3dObj *GetParent() const { + return mParent; + } + void SetParent(G3dObj *parent) { + mParent = parent; + } + + static void *Alloc(MEMAllocator *pAllocator, u32 size) { + return detail::AllocFromAllocator(pAllocator, size); + } + + static void Dealloc(MEMAllocator *pAllocator, void *pBlock) { + detail::FreeToAllocator(pAllocator, pBlock); + } + + static inline void *operator new(size_t size, void *pBlock) { + return pBlock; + } + static inline void operator delete(void *pBlock) {} + + template + static T *DynamicCast(G3dObj *obj) { + return (obj != NULL && obj->IsDerivedFrom(T::GetTypeObjStatic())) ? static_cast(obj) : NULL; + } + +private: + G3dObj *mParent; // at 0x4 + MEMAllocator *mAllocator; // at 0x8 + + NW4R_G3D_TYPE_OBJ_DECL(G3dObj); +}; +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/g3d_resanm.h b/include/nw4r/g3d/g3d_resanm.h new file mode 100644 index 00000000..8e1205a6 --- /dev/null +++ b/include/nw4r/g3d/g3d_resanm.h @@ -0,0 +1,88 @@ +#ifndef NW4R_G3D_RESANM_H +#define NW4R_G3D_RESANM_H +#include "types_nw4r.h" + +namespace nw4r +{ + namespace g3d + { + struct ResKeyFrameAnmFramesData + { + float mTime; // at 0x0 + float mValue; // at 0x4 + float mDerivative; // at 0x8 + }; + + struct ResKeyFrameAnmData + { + u16 mCount; // at 0x0 + float FLOAT_0x4; + ResKeyFrameAnmFramesData mFrames[]; // at 0x8 + }; + + struct ResColorAnmFramesData + { + u32 mColor; // at 0x0 + }; + + union ResColorAnmData + { + u32 mColor; + s32 mOffset; + }; + + struct ResBoolAnmFramesData + { + u32 mFlags; // at 0x0 + }; + + union ResAnmData + { + float mValue; + s32 mOffset; + }; + + namespace detail + { + float GetResKeyFrameAnmResult(const ResKeyFrameAnmData *, float); + + u32 GetResColorAnmResult(const ResColorAnmFramesData *, float); + + inline u32 GetResColorAnmResult(const ResColorAnmData * pData, float time, bool b) + { + if (b) return pData->mColor; + + return GetResColorAnmResult((const ResColorAnmFramesData *)((u8 *)pData + pData->mOffset), time); + } + + inline bool GetResBoolAnmFramesResult(const ResBoolAnmFramesData * pData, int i) + { + u32 index = i; + + u32 mask = 0x80000000 >> (index % 32); + u32 flags = pData[index / 32].mFlags; + + return flags & mask; + } + + template + inline float ClipFrame(T & info, float time) + { + if (time <= 0.0f) return 0.0f; + + if (info.mNumFrames <= time) return info.mNumFrames; + + return time; + } + + inline float GetResAnmResult(const ResAnmData * pData, float time, bool b) + { + if (b) return pData->mValue; + + return GetResKeyFrameAnmResult((const ResKeyFrameAnmData *)((u8 *)pData + pData->mOffset), time); + } + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_resanmcamera.h b/include/nw4r/g3d/g3d_resanmcamera.h new file mode 100644 index 00000000..d3b00b17 --- /dev/null +++ b/include/nw4r/g3d/g3d_resanmcamera.h @@ -0,0 +1,30 @@ +#ifndef NW4R_G3D_RESANMCAMERA_H +#define NW4R_G3D_RESANMCAMERA_H +#include "types_nw4r.h" +#include "g3d_rescommon.h" +#include "g3d_anmcamera.h" + +namespace nw4r +{ + namespace g3d + { + struct ResAnmCameraData + { + char UNK_0x0[0xC]; + u32 mID; // at 0xC + }; + + struct ResAnmCamera + { + ResCommon mAnmCamera; + + inline ResAnmCamera(void * vptr) : mAnmCamera(vptr) {} + + bool IsValid() const { return mAnmCamera.IsValid(); } + + void GetAnmResult(CameraAnmResult *, f32) const; + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_resanmchr.h b/include/nw4r/g3d/g3d_resanmchr.h new file mode 100644 index 00000000..f37edd22 --- /dev/null +++ b/include/nw4r/g3d/g3d_resanmchr.h @@ -0,0 +1,35 @@ +#ifndef NW4R_G3D_RESANMCHR_H +#define NW4R_G3D_RESANMCHR_H +#include "types_nw4r.h" +#include "g3d_rescommon.h" + +namespace nw4r +{ + namespace g3d + { + struct ResAnmChrData + { + char UNK_0x0[0x8]; + u32 mRevision; // at 0x8 + }; + + struct ResAnmChr + { + enum + { + REVISION = 4 + }; + + ResCommon mAnmChr; + + inline ResAnmChr(void * vptr) : mAnmChr(vptr) {} + + inline bool CheckRevision() const + { + return mAnmChr.ref().mRevision == REVISION; + } + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_resanmclr.h b/include/nw4r/g3d/g3d_resanmclr.h new file mode 100644 index 00000000..a92ad053 --- /dev/null +++ b/include/nw4r/g3d/g3d_resanmclr.h @@ -0,0 +1,68 @@ +#ifndef NW4R_G3D_RESANMCLR_H +#define NW4R_G3D_RESANMCLR_H +#include "g3d_resdict.h" +#include "g3d_resanm.h" + +namespace nw4r +{ + namespace g3d + { + struct ResAnmClrInfoData + { + char UNK_0x0[0x8]; + u16 mNumFrames; + }; + + struct ResAnmClrMatData + { + char UNK_0x0[0x4]; + u32 mFlags; // at 0x4 + + struct AnmData + { + UNKWORD WORD_0x0; + ResColorAnmData mColor; // at 0x4 + } mAnms[]; // at 0x8 + }; + + struct ResAnmClrData + { + char UNK_0x0[0x8]; + u32 mRevision; // at 0x8 + char UNK_0xC[0x4]; + s32 mMatDictOffset; // at 0x10 + ResAnmClrInfoData mInfo; // at 0x14 + }; + + struct ResAnmClr + { + enum + { + REVISION = 3 + }; + + ResCommon mAnmClr; + + inline ResAnmClr(void * vptr) : mAnmClr(vptr) {} + + inline ResAnmClrData & ref() const + { + return mAnmClr.ref(); + } + + inline bool CheckRevision() const + { + return ref().mRevision == REVISION; + } + + inline const ResAnmClrMatData * GetMatAnm(u32 i) const + { + return static_cast(mAnmClr.ofs_to_obj(ref().mMatDictOffset)[i]); + } + + void GetAnmResult(ClrAnmResult *, u32, float) const; + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_resanmfog.h b/include/nw4r/g3d/g3d_resanmfog.h new file mode 100644 index 00000000..2aab7454 --- /dev/null +++ b/include/nw4r/g3d/g3d_resanmfog.h @@ -0,0 +1,30 @@ +#ifndef NW4R_G3D_RESANMFOG_H +#define NW4R_G3D_RESANMFOG_H +#include "types_nw4r.h" +#include "g3d_rescommon.h" +#include "g3d_anmfog.h" + +namespace nw4r +{ + namespace g3d + { + struct ResAnmFogData + { + char UNK_0x0[0xC]; + u32 mID; // at 0xC + }; + + struct ResAnmFog + { + ResCommon mAnmFog; + + inline ResAnmFog(void * vptr) : mAnmFog(vptr) {} + + void GetAnmResult(FogAnmResult *, f32) const; + + bool IsValid() const { return mAnmFog.IsValid(); } + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_resanmscn.h b/include/nw4r/g3d/g3d_resanmscn.h new file mode 100644 index 00000000..86c5ffd8 --- /dev/null +++ b/include/nw4r/g3d/g3d_resanmscn.h @@ -0,0 +1,45 @@ +#ifndef NW4R_G3D_RESANMSCN_H +#define NW4R_G3D_RESANMSCN_H +#include "types_nw4r.h" +#include "g3d_rescommon.h" +#include "g3d_resanmfog.h" +#include "g3d_resanmcamera.h" + +namespace nw4r +{ + namespace g3d + { + struct ResAnmScnData + { + char UNK_0x0[0x8]; + u32 mRevision; // at 0x8 + char UNK_0xC[0x3E - 0xC]; + u16 mFogMaxRefNum; // at 0x3E + }; + + struct ResAnmScn + { + enum + { + REVISION = 4 + }; + + ResCommon mAnmScn; + + ResAnmFog GetResAnmFogByRefNumber(u32) const; + ResAnmCamera GetResAnmCameraByRefNumber(u32) const; + + inline ResAnmScn(void * vptr) : mAnmScn(vptr) {} + + inline bool IsValid() const { return mAnmScn.IsValid(); } + inline bool CheckRevision() const + { + return mAnmScn.ref().mRevision == REVISION; + } + + u16 GetResAnmFogMaxRefNumber() const { return mAnmScn.ref().mFogMaxRefNum; } + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_resanmshp.h b/include/nw4r/g3d/g3d_resanmshp.h new file mode 100644 index 00000000..96bce327 --- /dev/null +++ b/include/nw4r/g3d/g3d_resanmshp.h @@ -0,0 +1,35 @@ +#ifndef NW4R_G3D_RESANMSHP_H +#define NW4R_G3D_RESANMSHP_H +#include "types_nw4r.h" +#include "g3d_rescommon.h" + +namespace nw4r +{ + namespace g3d + { + struct ResAnmShpData + { + char UNK_0x0[0x8]; + u32 mRevision; // at 0x8 + }; + + struct ResAnmShp + { + enum + { + REVISION = 3 + }; + + ResCommon mAnmShp; + + inline ResAnmShp(void * vptr) : mAnmShp(vptr) {} + + inline bool CheckRevision() const + { + return mAnmShp.ref().mRevision == REVISION; + } + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_resanmtexpat.h b/include/nw4r/g3d/g3d_resanmtexpat.h new file mode 100644 index 00000000..e06dfe9c --- /dev/null +++ b/include/nw4r/g3d/g3d_resanmtexpat.h @@ -0,0 +1,90 @@ +#ifndef NW4R_G3D_RESANMTEXPAT_H +#define NW4R_G3D_RESANMTEXPAT_H +#include "g3d_resdict.h" +#include "g3d_resanm.h" + +namespace nw4r +{ + namespace g3d + { + struct ResAnmTexPatAnmFramesData + { + float mTime; // at 0x0 + u16 mTexIndex; // at 0x4 + u16 mPlttIndex; // at 0x6 + }; + + struct ResAnmTexPatAnmData + { + u16 mCount; // at 0x0 + float FLOAT_0x4; + ResAnmTexPatAnmFramesData mFrames[]; // at 0x8 + }; + + struct ResAnmTexPatMatData + { + char UNK_0x0[0x4]; + u32 mFlags; // at 0x4 + + union AnmData + { + struct + { + u16 mTexIndex; // at 0x0 + u16 mPlttIndex; // at 0x2 + }; + + s32 mOffset; + } mAnms[]; // at 0x8 + }; + + struct ResAnmTexPatData + { + char UNK_0x0[0x8]; + u32 mRevision; // at 0x8 + char UNK_0xC[0x4]; + s32 mMatDictOffset; // at 0x10 + s32 mTexNameArrayOffset; // at 0x14 + s32 mPlttNameArrayOffset; // at 0x18 + s32 mTexArrayOffset; // at 0x1c + s32 mPlttArrayOffset; // at 0x20 + char UNK_0x24[0xC]; + u16 mTexCount; // at 0x30 + u16 mPlttCount; // at 0x32 + }; + + struct ResAnmTexPat + { + enum + { + REVISION = 3 + }; + + ResCommon mAnmTexPat; + + inline ResAnmTexPat(void * vptr) : mAnmTexPat(vptr) {} + + inline ResAnmTexPatData & ref() const + { + return mAnmTexPat.ref(); + } + + inline bool CheckRevision() const + { + return ref().mRevision == REVISION; + } + + inline const ResAnmTexPatMatData * GetMatAnm(u32 i) const + { + return static_cast(mAnmTexPat.ofs_to_obj(ref().mMatDictOffset)[i]); + } + + void GetAnmResult(TexPatAnmResult *, u32, float) const; + + bool Bind(ResFile); + void Release(); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_resanmtexsrt.h b/include/nw4r/g3d/g3d_resanmtexsrt.h new file mode 100644 index 00000000..563a0e00 --- /dev/null +++ b/include/nw4r/g3d/g3d_resanmtexsrt.h @@ -0,0 +1,63 @@ +#ifndef NW4R_G3D_RESANMTEXSRT_H +#define NW4R_G3D_RESANMTEXSRT_H +#include "g3d_resanm.h" +#include "g3d_resdict.h" + +namespace nw4r +{ + namespace g3d + { + struct ResAnmTexSrtTexData + { + u32 mFlags; // at 0x0 + ResAnmData mAnms[]; // at 0x4 + }; + + struct ResAnmTexSrtMatData + { + char UNK_0x0[0x4]; + UNKWORD FLAGS_0x4; + UNKWORD FLAGS_0x8; + s32 mTexOffsets[]; // at 0xc + }; + + struct ResAnmTexSrtData + { + char UNK_0x0[0x8]; + u32 mRevision; // at 0x8 + char UNK_0xC[0x4]; + s32 mMatDictOffset; // at 0x10 + }; + + struct ResAnmTexSrt + { + enum + { + REVISION = 4 + }; + + ResCommon mAnmTexSrt; + + inline ResAnmTexSrt(void * vptr) : mAnmTexSrt(vptr) {} + + inline ResAnmTexSrtData & ref() const + { + return mAnmTexSrt.ref(); + } + + inline bool CheckRevision() const + { + return mAnmTexSrt.ref().mRevision == REVISION; + } + + inline const ResAnmTexSrtMatData * GetMatAnm(u32 i) const + { + return static_cast(mAnmTexSrt.ofs_to_obj(ref().mMatDictOffset)[i]); + } + + void GetAnmResult(TexSrtAnmResult *, u32, float) const; + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_resanmvis.h b/include/nw4r/g3d/g3d_resanmvis.h new file mode 100644 index 00000000..82c28ea1 --- /dev/null +++ b/include/nw4r/g3d/g3d_resanmvis.h @@ -0,0 +1,82 @@ +#ifndef NW4R_G3D_RESANMVIS_H +#define NW4R_G3D_RESANMVIS_H +#include "g3d_resdict.h" +#include "g3d_resanm.h" +#include "g3d_anmobj.h" + +namespace nw4r +{ + namespace g3d + { + struct ResAnmVisInfoData + { + char UNK_0x0[0x8]; + u16 mNumFrames; // at 0x1C + u16 mNumNodes; + AnmPolicy mAnmPolicy; // at 0x20 + }; + + struct ResAnmVisNodeData + { + UNKWORD WORD_0x0; + u32 mFlags; // at 0x4 + ResBoolAnmFramesData mBoolFrames[]; // at 0x8 + }; + + struct ResAnmVisData + { + char UNK_0x0[0x8]; + u32 mRevision; // at 0x8 + char UNK_0xC[0x4]; + s32 mNodeDictOffset; // at 0x10 + ResAnmVisInfoData mInfo; // at 0x14 + }; + + struct ResAnmVis + { + enum + { + REVISION = 3 + }; + + ResCommon mAnmVis; + + inline ResAnmVis(void * vptr) : mAnmVis(vptr) {} + bool IsValid() const { return mAnmVis.IsValid(); } + + inline ResAnmVisData & ref() const + { + return mAnmVis.ref(); + } + + inline bool CheckRevision() const + { + return ref().mRevision == REVISION; + } + + inline const ResAnmVisNodeData * GetNodeAnm(u32 i) const + { + return static_cast(mAnmVis.ofs_to_obj(ref().mNodeDictOffset)[i]); + } + + AnmPolicy GetAnmPolicy() const + { + return ref().mInfo.mAnmPolicy; + } + + int GetNumFrame() const + { + return ref().mInfo.mNumFrames; + } + + int GetNumNode() const + { + return ref().mInfo.mNumNodes; + } + + bool GetAnmResult(u32, float) const; + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_rescommon.h b/include/nw4r/g3d/g3d_rescommon.h index e69de29b..6bbd814f 100644 --- a/include/nw4r/g3d/g3d_rescommon.h +++ b/include/nw4r/g3d/g3d_rescommon.h @@ -0,0 +1,141 @@ +#ifndef NW4R_G3D_RESCOMMON_H +#define NW4R_G3D_RESCOMMON_H +#include "types_nw4r.h" + +#define NW4R_G3D_CREATE_RES_NAME_DATA(VAR,VAL) ResNameData ResNameData_##VAR = { sizeof(VAL) - 1, VAL } + +#define FIFO_ACCESS_BP 0x61 +#define FIFO_ACCESS_CP 0x8 +#define FIFO_ACCESS_XF 0x10 + +namespace nw4r +{ + namespace g3d + { + template + class ResCommon + { + T * mPtr; + + public: + inline ResCommon(void * vptr) : mPtr(static_cast(vptr)) {} + inline ResCommon(const void * vptr) : mPtr(static_cast(vptr)) {} + + inline T & ref() const { return *mPtr; } + inline T * ptr() const { return mPtr; } + inline bool IsValid() const { return mPtr != NULL; } + + template + inline const TPtr * ofs_to_ptr_raw(s32 ofs) const + { + return (const TPtr *)((u8 *)mPtr + ofs); + } + + template + inline TPtr * ofs_to_ptr(s32 ofs) + { + if (ofs) return (TPtr *)((u8 *)mPtr + ofs); + + return NULL; + } + + template + inline const TPtr * ofs_to_ptr(s32 ofs) const + { + if (ofs) return (const TPtr *)((u8 *)mPtr + ofs); + + return NULL; + } + + template + inline TObj ofs_to_obj(s32 ofs) const + { + if (ofs) return (u8 *)mPtr + ofs; + + return NULL; + } + }; + + struct ResNameData + { + u32 mLength; + char mName[0x1C]; + }; + + struct ResName + { + ResCommon mRes; + + inline ResName(const void *vptr) : mRes(vptr) {} + + inline u32 GetLength() const + { + return mRes.ref().mLength; + } + + inline const char * GetName() const + { + return mRes.ref().mName; + } + + bool operator==(ResName) const; + }; + + namespace detail + { + typedef u8 CPCmd[6]; + typedef u8 BPCmd[5]; + + inline void ResWrite_u8(u8 *res, u8 arg) + { + *res = arg; + } + + inline void ResWrite_u16(u8 *res, u16 arg) + { + ResWrite_u8(res + 0, arg >> 8); + ResWrite_u8(res + 1, arg >> 0); + } + + inline void ResWrite_u32(u8 *res, u32 arg) + { + ResWrite_u8(res + 0, arg >> 24); + ResWrite_u8(res + 1, arg >> 16); + ResWrite_u8(res + 2, arg >> 8); + ResWrite_u8(res + 3, arg >> 0); + } + + inline u8 ResRead_u8(const u8 *res) + { + return *res; + } + + inline u32 ResRead_u32(const u8 *res) + { + int ret = ResRead_u8(res) << 24; + ret |= ResRead_u8(res + 1) << 16; + ret |= ResRead_u8(res + 2) << 8; + ret |= ResRead_u8(res + 3); + return ret; + } + + inline void ResReadBPCmd(const u8 *res, u32 *out) + { + *out = ResRead_u32(res + 1); + } + + inline void ResReadCPCmd(const u8 *res, u32 *out) + { + *out = ResRead_u32(res + 2); + } + + void ResWriteBPCmd(u8 *, u32); + void ResWriteBPCmd(u8 *, u32, u32); + void ResWriteCPCmd(u8 *, u8, u32); + void ResWriteXFCmd(u8 *, u16, u32); + void ResWriteSSMask(u8 *, u32); + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_resdict.h b/include/nw4r/g3d/g3d_resdict.h new file mode 100644 index 00000000..c3fde06a --- /dev/null +++ b/include/nw4r/g3d/g3d_resdict.h @@ -0,0 +1,57 @@ +#ifndef NW4R_G3D_RESDICT_H +#define NW4R_G3D_RESDICT_H +#include "types_nw4r.h" +#include "g3d_rescommon.h" +#include + +namespace nw4r +{ + namespace g3d + { + struct ResDicEntry + { + u16 INT_0x0; // at 0x0 + u16 INT_0x2; // at 0x2 + u16 unk_index; // at 0x4 + u16 unk_index2; // at 0x6 + u32 INT_0x8; // at 0x8 + u32 INT_0xC; // at 0xC + }; + + struct ResDicData + { + u32 mSize; // at 0x0 + u32 mNumData; // at 0x4 + ResDicEntry mEntries[]; // 0x8 + }; + + struct ResDic + { + ResCommon mDict; + + ResDicEntry * Get(ResName) const; + ResDicEntry * Get(const char *, u32) const; + void * operator[](const char *) const; + void * operator[](ResName) const; + s32 GetIndex(ResName) const; + + inline ResDic(void * vptr) : mDict(vptr) {} + + inline void * operator[](int i) const + { + if (mDict.IsValid()) return (void *)mDict.ofs_to_ptr(mDict.ref().mEntries[i + 1].INT_0xC); + + return NULL; + } + + inline u32 GetNumData() const + { + if (mDict.IsValid()) return mDict.ref().mNumData; + + return 0; + } + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_resfile.h b/include/nw4r/g3d/g3d_resfile.h index edcd9e5a..fceaf42c 100644 --- a/include/nw4r/g3d/g3d_resfile.h +++ b/include/nw4r/g3d/g3d_resfile.h @@ -1,15 +1,92 @@ -#pragma once +#ifndef NW4R_G3D_RESFILE_H +#define NW4R_G3D_RESFILE_H +#include "ut_binaryFileFormat.h" +#include "g3d_rescommon.h" +#include "g3d_resdict.h" +#include "types_nw4r.h" -#include +namespace nw4r +{ + namespace g3d + { + + struct ResFileData + { + ut::BinaryFileHeader mHeader; // at 0x0 + + ut::BinaryBlockHeader mRootHeader; // at 0x10 + ResDicData mRootData; // at 0x18 + }; + + struct ResFile + { + ResCommon mFile; // at 0x0 + + inline ResFileData & ref() const + { + return mFile.ref(); + } + + ResMdl GetResMdl(const char *) const; + ResMdl GetResMdl(int) const; + ResMdl GetResMdl(u32) const; //inlined + + ResPltt GetResPltt(const char *) const; + ResPltt GetResPltt(ResName) const; + ResPltt GetResPltt(int) const; + ResPltt GetResPltt(u32) const; //inlined + + ResTex GetResTex(const char *) const; + ResTex GetResTex(ResName) const; + ResTex GetResTex(int) const; + ResTex GetResTex(u32) const; //inlined + + ResAnmChr GetResAnmChr(const char *) const; + ResAnmChr GetResAnmChr(int) const; + ResAnmChr GetResAnmChr(u32) const; //inlined + + ResAnmVis GetResAnmVis(const char *) const; + ResAnmVis GetResAnmVis(int) const; + ResAnmVis GetResAnmVis(u32) const; //inlined + + ResAnmClr GetResAnmClr(const char *) const; + ResAnmClr GetResAnmClr(int) const; + ResAnmClr GetResAnmClr(u32) const; //inlined + + ResAnmTexPat GetResAnmTexPat(const char *) const; + ResAnmTexPat GetResAnmTexPat(int) const; + ResAnmTexPat GetResAnmTexPat(u32) const; //inlined + + ResAnmTexSrt GetResAnmTexSrt(const char *) const; + ResAnmTexSrt GetResAnmTexSrt(int) const; + ResAnmTexSrt GetResAnmTexSrt(u32) const; //inlined + + ResAnmShp GetResAnmShp(const char *) const; + ResAnmShp GetResAnmShp(int) const; + ResAnmShp GetResAnmShp(u32) const; //inlined + + ResAnmScn GetResAnmScn(const char *) const; + ResAnmScn GetResAnmScn(int) const; + ResAnmScn GetResAnmScn(u32) const; //inlined + + u32 GetResMdlNumEntries() const; //inlined + u32 GetResPlttNumEntries() const; //inlined + u32 GetResTexNumEntries() const; //inlined + u32 GetResAnmChrNumEntries() const; //inlined + u32 GetResAnmVisNumEntries() const; //inlined + u32 GetResAnmClrNumEntries() const; //inlined + u32 GetResAnmTexPatNumEntries() const; //inlined + u32 GetResAnmTexSrtNumEntries() const; //inlined + u32 GetResAnmShpNumEntries() const; //inlined + u32 GetResAnmScnNumEntries() const; + + bool Bind(ResFile); + void Release(); + void Init(); + void Terminate(); + bool CheckRevision() const; + }; + } +} -namespace nw4r { -namespace g3d { - -struct ResFileData {}; - -struct ResFile { - /* data */ -}; - -}; // namespace g3d -}; // namespace nw4r +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_resmat.h b/include/nw4r/g3d/g3d_resmat.h new file mode 100644 index 00000000..f9638af4 --- /dev/null +++ b/include/nw4r/g3d/g3d_resmat.h @@ -0,0 +1,90 @@ +#ifndef NW4R_G3D_RESMAT_H +#define NW4R_G3D_RESMAT_H +#include "g3d_rescommon.h" +#include "math_types.h" +#include "types_nw4r.h" +#include + + +namespace nw4r { +namespace g3d { +struct ResMatTexCoordGenData {}; + +struct ResMatTexCoordGen { + ResCommon mTexGen; // at 0x0 + + inline ResMatTexCoordGen(void *vptr) : mTexGen(vptr) {} + bool IsValid() const { + return mTexGen.IsValid(); + } + + bool GXGetTexCoordGen2(GXTexCoordID, GXTexGenType *, GXTexGenSrc *, u8 *, u32 *); + void GXSetTexCoordGen2(GXTexCoordID, GXTexGenType, GXTexGenSrc, u8, u32); + void DCStore(bool); +}; + +struct ResTexSrtData {}; + +struct ResTexSrt { + ResCommon mTexSrt; // at 0x0 + + inline ResTexSrt(void *vptr) : mTexSrt(vptr) {} + bool IsValid() const { + return mTexSrt.IsValid(); + } + + void SetMapMode(u32, u32, int, int); +}; + +struct ResTexPlttInfoData { + u32 mNumOffsets; // at 0x0 + + struct InfoOffset { + u32 mResOffset; // at 0x0 + u32 mTexOffset; // at 0x4 + } mOffsets[]; // at 0x4 +}; + +struct ResTexPlttInfo { + ResCommon mInfo; + + inline ResTexPlttInfo(void *vptr) : mInfo(vptr) {} +}; + +struct ResMatDLData { + char UNK_0x0[0xE0]; + ResMatTexCoordGenData texCoordGenData; // at 0xE0 +}; + +struct ResMatData { + char UNK_0x0[0x38]; + u32 resMatDLOfs; // at 0x38 + char UNK_0x3C[0x1A4 - 0x3C]; + ResTexSrtData texSrtData; // at 0x1A4 +}; + +struct ResMat { + ResCommon mMat; + + inline ResMat(void *vptr) : mMat(vptr) {} + bool IsValid() const { + return mMat.IsValid(); + } + + ResTexSrt GetResTexSrt() { + return ResTexSrt(&mMat.ref().texSrtData); + } + + ResMatTexCoordGen GetResMatTexCoordGen() { + ResMatDLData *dlData = mMat.ofs_to_ptr(mMat.ref().resMatDLOfs); + return ResMatTexCoordGen(&dlData->texCoordGenData); + } + + bool Bind(ResFile); + UNKTYPE Release(); + UNKTYPE Init(); +}; +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/g3d_resmdl.h b/include/nw4r/g3d/g3d_resmdl.h new file mode 100644 index 00000000..84975c47 --- /dev/null +++ b/include/nw4r/g3d/g3d_resmdl.h @@ -0,0 +1,100 @@ +#ifndef NW4R_G3D_RESMDL_H +#define NW4R_G3D_RESMDL_H +#include "types_nw4r.h" +#include "g3d_rescommon.h" +#include "g3d_resnode.h" +#include "g3d_resdict.h" + +namespace nw4r +{ + namespace g3d + { + struct ResMdlData + { + char mMagic[4]; // "MDL0" + u32 INT_0x4; + u32 mRevision; // at 0x8 + s32 INT_0xC; + u32 mByteCodeDictOfs; // at 0x10 + u32 mNodeDictOfs; // at 0x14 + u32 mVtxPosDictOfs; // at 0x18 + u32 mVtxNrmDictOfs; // at 0x1C + u32 mVtxClrDictOfs; // at 0x20 + u32 mVtxTexCoordDictOfs; // at 0x24 + u32 mMatDictOfs; // at 0x28 + u32 mTevDictOfs; // at 0x2C + u32 mShpDictOfs; // at 0x30 + u32 mPlttTexInfoOfs; // at 0x34 + }; + + struct ResMdl + { + enum + { + REVISION = 9 + }; + + ResCommon mMdl; + + inline ResMdl(void * vptr) : mMdl(vptr) {} + bool IsValid() const { return mMdl.IsValid(); } + + u8 * GetResByteCode(const char *) const; + + ResNode GetResNode(const char *) const; + ResNode GetResNode(ResName) const; + ResNode GetResNode(int) const; + ResNode GetResNode(u32) const; + u32 GetResNodeNumEntries() const; + + ResVtxPos GetResVtxPos(ResName) const; + ResVtxPos GetResVtxPos(int) const; + ResVtxPos GetResVtxPos(u32) const; + u32 GetResVtxPosNumEntries() const; + + ResVtxNrm GetResVtxNrm(ResName) const; + ResVtxNrm GetResVtxNrm(int) const; + ResVtxNrm GetResVtxNrm(u32) const; + u32 GetResVtxNrmNumEntries() const; + + ResVtxClr GetResVtxClr(ResName) const; + ResVtxClr GetResVtxClr(int) const; + ResVtxClr GetResVtxClr(u32) const; + u32 GetResVtxClrNumEntries() const; + + ResVtxTexCoord GetResVtxTexCoord(int) const; + + ResMat GetResMat(const char *) const; + ResMat GetResMat(ResName) const; + ResMat GetResMat(int) const; + ResMat GetResMat(u32) const; + u32 GetResMatNumEntries() const; + + ResShp GetResShp(const char *) const; + ResShp GetResShp(int) const; + ResShp GetResShp(u32) const; + u32 GetResShpNumEntries() const; + + ResTexPlttInfo GetResTexPlttInfoOffsetFromTexName(int) const; + u32 GetResTexPlttInfoOffsetFromTexNameNumEntries() const; + + bool Bind(ResFile); + void Release(); + void Init(); + void Terminate(); + + inline bool CheckRevision() const + { + return mMdl.ref().mRevision == REVISION; + } + + inline u32 GetResVtxTexCoordNumEntries() const + { + ResMdlData& ref = mMdl.ref(); + return mMdl.ofs_to_obj(ref.mVtxTexCoordDictOfs).GetNumData(); + } + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_resnode.h b/include/nw4r/g3d/g3d_resnode.h new file mode 100644 index 00000000..54e1a0c5 --- /dev/null +++ b/include/nw4r/g3d/g3d_resnode.h @@ -0,0 +1,68 @@ +#ifndef NW4R_G3D_RESNODE_H +#define NW4R_G3D_RESNODE_H +#include "types_nw4r.h" +#include "g3d_rescommon.h" +#include "g3d_anmchr.h" +#include "math_types.h" + +namespace nw4r +{ + namespace g3d + { + struct ResNodeData + { + u32 INT_0x0; + s32 INT_0x4; + u16 SHORT_0x8; + u16 SHORT_0xA; + UNKWORD WORD_0xC; + UNKWORD WORD_0x10; + u32 mFlags; // at 0x14 + UNKWORD WORD_0x18; + UNKWORD WORD_0x1C; + math::VEC3 VEC3_0x20; + math::VEC3 VEC3_0x2C; + f32 FLOAT_0x38; + f32 FLOAT_0x3C; + f32 FLOAT_0x40; + // . . . + }; + + struct ResNode + { + enum ResNodeFlags + { + NODE_IS_VISIBLE = 0x100 + }; + + ResCommon mNode; + + inline ResNode(void * vptr) : mNode(vptr) {} + + bool IsValid() const { return mNode.IsValid(); } + + UNKWORD GetID() const + { + if (IsValid()) + return mNode.ptr()->WORD_0xC; + return 0; + } + + void SetVisibility(bool visible) + { + if (IsValid()) + { + if (visible) + mNode.ptr()->mFlags |= NODE_IS_VISIBLE; + else + mNode.ptr()->mFlags &= ~NODE_IS_VISIBLE; + } + } + + void PatchChrAnmResult(ChrAnmResult *) const; + void CalcChrAnmResult(ChrAnmResult *) const; + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_resshp.h b/include/nw4r/g3d/g3d_resshp.h new file mode 100644 index 00000000..bf61cebb --- /dev/null +++ b/include/nw4r/g3d/g3d_resshp.h @@ -0,0 +1,122 @@ +#ifndef NW4R_G3D_RESSHP_H +#define NW4R_G3D_RESSHP_H +#include +#include "types_nw4r.h" +#include "g3d_rescommon.h" +#include "g3d_resmdl.h" +#include "g3d_resvtx.h" + +namespace nw4r +{ + namespace g3d + { + struct ResTagDLData + { + u32 mBufSize; // at 0x0 + u32 mCmdSize; // at 0x4 + u32 mOffset; // at 0x8 + }; + + struct ResPrePrimDL + { + char UNK_0x0[0xA]; + detail::CPCmd CP_CMD_0xA; + detail::CPCmd CP_CMD_0x10; + char UNK_0x16[0xA]; + detail::CPCmd CP_CMD_0x20; + detail::CPCmd CP_CMD_0x26; + detail::CPCmd CP_CMD_0x2C; + detail::CPCmd CP_CMD_PAIRS_0x32[GX_POS_MTX_ARRAY - GX_VA_POS][2]; + char UNK_0xC2[0x1E]; + }; + + struct ResShpData + { + char UNK_0x0[0x4]; + u32 mParentOffset; // at 0x4 + char UNK_0x8[0x10]; + ResTagDLData mPrePrimDLTag; // at 0x18 + ResTagDLData mPrimDLTag; // at 0x24 + char UNK_0x30[0x18]; + + s16 mVtxPosIndex; // at 0x48 + s16 mVtxNrmIndex; // at 0x4a + s16 mVtxClrIndices[GX_VA_TEX0 - GX_VA_CLR0]; // at 0x4c + s16 mVtxTexCoordIndices[GX_POS_MTX_ARRAY - GX_VA_TEX0]; // at 0x50 + }; + + struct ResTagDL + { + ResCommon mData; + + inline ResTagDL(void * vptr) : mData(vptr) {} + + inline u8 * GetDL() const + { + return const_cast(mData.ofs_to_ptr(mData.ref().mOffset)); + } + + inline u32 GetBufSize() const + { + return mData.ref().mBufSize; + } + + inline u32 GetCmdSize() const + { + return mData.ref().mCmdSize; + } + }; + + struct ResShpPrePrim + { + ResCommon mDL; + + inline ResShpPrePrim(void * vptr) : mDL(vptr) {} + + inline ResPrePrimDL & ref() const + { + return mDL.ref(); + } + }; + + struct ResShp + { + ResCommon mShp; + + inline ResShp(void * vptr) : mShp(vptr) {} + bool IsValid() const { return mShp.IsValid(); } + + inline ResShpData & ref() const + { + return mShp.ref(); + } + + inline ResShpPrePrim GetResShpPrePrim() const + { + return ResTagDL(&ref().mPrePrimDLTag).GetDL(); + } + + bool GXGetVtxDescv(GXVtxDescList*) const; + bool GXGetVtxAttrFmtv(GXVtxAttrFmtList*) const; + + ResMdl GetParent() const; //inlined + + ResVtxPos GetResVtxPos() const; + ResVtxNrm GetResVtxNrm() const; + ResVtxClr GetResVtxClr(u32) const; + ResVtxTexCoord GetResVtxTexCoord(u32) const; //inlined + + void GXSetArray(GXAttr, const void *, u8); //inlined + + void Init(); + + void DisableSetArray(GXAttr); //inlined + void Terminate(); + + void CallPrePrimitiveDisplayList(bool, bool) const; + void CallPrimitiveDisplayList(bool) const; + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_restev.h b/include/nw4r/g3d/g3d_restev.h new file mode 100644 index 00000000..14c158ad --- /dev/null +++ b/include/nw4r/g3d/g3d_restev.h @@ -0,0 +1,61 @@ +#ifndef NW4R_G3D_RESTEV_H +#define NW4R_G3D_RESTEV_H +#include +#include +#include "g3d_cpu.h" +#include "g3d_rescommon.h" + +namespace nw4r +{ + namespace g3d + { + struct ResTevData + { + u32 SIZE_0x0; + u32 INT_0x4; + char UNK_0x8[0x4]; + u8 BYTE_0xC; + char UNK_0xD[0x13]; + + detail::BPCmd mSwapSelCmds[GX_MAX_TEVSWAP][4]; + + char UNK_0x70[0x10]; + + struct + { + detail::BPCmd BP_CMD_0x0; + detail::BPCmd BP_CMD_0x5; + detail::BPCmd BP_CMD_0xA; + detail::BPCmd BP_CMD_PAIR_0xF[2]; + char UNK_0x19[0x17]; + } mStageCmds[];//[GX_TEV_STAGE_COUNT]; + }; + + struct ResTev + { + ResCommon mTev; + + inline ResTev(void * vptr) : mTev(vptr) {} + + inline ResTevData & ref() const + { + return mTev.ref(); + } + + bool GXGetTevSwapModeTable(GXTevSwapSel, GXTevColorChan *, GXTevColorChan *, GXTevColorChan *, GXTevColorChan *) const; + void GXSetTevSwapModeTable(GXTevSwapSel, GXTevColorChan, GXTevColorChan, GXTevColorChan, GXTevColorChan); + + bool GXGetTevOrder(GXTevStageID, GXTexCoordID *, GXTexMapID *, GXChannelID *) const; + + void GXSetTevColorIn(GXTevStageID, GXTevColorArg, GXTevColorArg, GXTevColorArg, GXTevColorArg); + + void CallDisplayList(bool) const; + + void * CopyTo(void *); + + UNKTYPE DCStore(bool); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_restex.h b/include/nw4r/g3d/g3d_restex.h new file mode 100644 index 00000000..15283910 --- /dev/null +++ b/include/nw4r/g3d/g3d_restex.h @@ -0,0 +1,73 @@ +#ifndef NW4R_G3D_RESTEX_H +#define NW4R_G3D_RESTEX_H +#include "g3d_rescommon.h" +#include "types_nw4r.h" +#include + + +namespace nw4r { +namespace g3d { +struct ResTexData { + char mMagic[4]; // "TEX0"; at 0x0 + u32 mLength; // at 0x4 + u32 mRevision; // at 0x8 + s16 SHORT_0xC; + u16 SHORT_0xE; + u32 INT_0x10; + UNKWORD WORD_0x14; + u32 mFlags; // at 0x18 + u16 SHORT_0x1C; + u16 SHORT_0x1E; + union // at 0x20 + { + GXTexFmt mFormat; + GXCITexFmt mCiFormat; + }; + u32 WORD_0x24; + f32 FLOAT_0x28; + f32 FLOAT_0x2C; +}; + +struct ResPlttData { + char mMagic[4]; // "PLT0"; at 0x0 + u32 mLength; // at 0x4 + u32 mRevision; // at 0x8 +}; + +struct ResTex { + enum { REVISION = 1 }; + + ResCommon mTex; // at 0x0 + + inline ResTex(void *vptr) : mTex(vptr) {} + + inline bool CheckRevision() const { + return mTex.ref().mRevision == REVISION; + } + + bool GetTexObjParam(void **, u16 *, u16 *, GXTexFmt *, f32 *, f32 *, u8 *) const; + bool GetTexObjCIParam(void **, u16 *, u16 *, GXCITexFmt *, f32 *, f32 *, u8 *) const; + void Init(); + + bool IsValid() const { + return mTex.IsValid(); + } +}; + +struct ResPltt { + enum { REVISION = 1 }; + + ResCommon mPltt; // at 0x0 + + inline ResPltt(void *vptr) : mPltt(vptr) {} + + inline bool CheckRevision() const { + return mPltt.ref().mRevision == REVISION; + } + + void DCStore(bool); +}; +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/g3d_resvtx.h b/include/nw4r/g3d/g3d_resvtx.h new file mode 100644 index 00000000..717aa0e4 --- /dev/null +++ b/include/nw4r/g3d/g3d_resvtx.h @@ -0,0 +1,158 @@ +#ifndef NW4R_G3D_RESVTX_H +#define NW4R_G3D_RESVTX_H +#include +#include "g3d_rescommon.h" + +namespace nw4r +{ + namespace g3d + { + struct ResVtxPosData + { + u32 SIZE_0x0; + char UNK_0x4[0x4]; + u32 mDataOffset; // at 0x8 + char UNK_0xC[0x11]; + u8 BYTE_0x1D; + }; + + struct ResVtxNrmData + { + u32 SIZE_0x0; + char UNK_0x4[0x4]; + u32 mDataOffset; // at 0x8 + char UNK_0xC[0x11]; + u8 BYTE_0x1D; + }; + + struct ResVtxClrData + { + u32 SIZE_0x0; + char UNK_0x4[0x4]; + u32 mDataOffset; // at 0x8 + char UNK_0xC[0x10]; + u8 BYTE_0x1C; + }; + + struct ResVtxTexCoordData + { + u32 SIZE_0x0; + char UNK_0x4[0x4]; + u32 mDataOffset; // at 0x8 + char UNK_0xC[0x11]; + u8 BYTE_0x1D; + }; + + struct ResVtxPos + { + ResCommon mPos; + + inline ResVtxPos(void * vptr) : mPos(vptr) {} + + inline ResVtxPosData & ref() const + { + return mPos.ref(); + } + + inline const void * GetData() const + { + return mPos.ofs_to_ptr(ref().mDataOffset); + } + + inline UNKTYPE Init() + { + DCStore(false); + } + + void SetArray(); + void GetArray(const void **, u8 *) const; + UNKTYPE CopyTo(void *) const; + + UNKTYPE DCStore(bool); + }; + + struct ResVtxNrm + { + ResCommon mNrm; + + inline ResVtxNrm(void * vptr) : mNrm(vptr) {} + + inline ResVtxNrmData & ref() const + { + return mNrm.ref(); + } + + inline const void * GetData() const + { + return mNrm.ofs_to_ptr(ref().mDataOffset); + } + + inline UNKTYPE Init() + { + DCStore(false); + } + + void SetArray(); + void GetArray(const void **, u8 *) const; + UNKTYPE CopyTo(void *) const; + + UNKTYPE DCStore(bool); + }; + + struct ResVtxClr + { + ResCommon mClr; + + inline ResVtxClr(void * vptr) : mClr(vptr) {} + + inline ResVtxClrData & ref() const + { + return mClr.ref(); + } + + inline const void * GetData() const + { + return mClr.ofs_to_ptr(ref().mDataOffset); + } + + inline UNKTYPE Init() + { + DCStore(false); + } + + void SetArray(GXAttr); + void GetArray(const void **, u8 *) const; + UNKTYPE CopyTo(void *) const; + + UNKTYPE DCStore(bool); + }; + + struct ResVtxTexCoord + { + ResCommon mTexCoord; + + inline ResVtxTexCoord(void * vptr) : mTexCoord(vptr) {} + + inline ResVtxTexCoordData & ref() const + { + return mTexCoord.ref(); + } + + inline const void * GetData() const + { + return mTexCoord.ofs_to_ptr(ref().mDataOffset); + } + + inline UNKTYPE Init() + { + DCStore(false); + } + + void GetArray(const void **, u8 *) const; + + UNKTYPE DCStore(bool); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_scnmdl.h b/include/nw4r/g3d/g3d_scnmdl.h new file mode 100644 index 00000000..f1875981 --- /dev/null +++ b/include/nw4r/g3d/g3d_scnmdl.h @@ -0,0 +1,42 @@ +#ifndef NW4R_G3D_SCN_MDL_H +#define NW4R_G3D_SCN_MDL_H +#include "types_nw4r.h" +#include "g3d_scnmdlsmpl.h" +#include "g3d_resmat.h" +#include "g3d_draw.h" + +namespace nw4r +{ + namespace g3d + { + class ScnMdl : public ScnMdlSimple + { + public: + class CopiedMatAccess + { + public: + CopiedMatAccess(ScnMdl *, u32); + ResTexSrt GetResTexSrtEx(); + + private: + char UNK_0x0[0x2C]; + }; + + public: + static const G3dObj::TypeObj GetTypeObjStatic() + { + return TypeObj(TYPE_NAME); + } + + DrawResMdlReplacement * GetDrawResMdlReplacement() { return &mDrawMdlReplace; } + + private: + char UNK_0x118[0x144 - 0x118]; + DrawResMdlReplacement mDrawMdlReplace; // at 0x144 + + NW4R_G3D_TYPE_OBJ_DECL(ScnMdl); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_scnmdl1mat1shp.h b/include/nw4r/g3d/g3d_scnmdl1mat1shp.h new file mode 100644 index 00000000..1b55ece6 --- /dev/null +++ b/include/nw4r/g3d/g3d_scnmdl1mat1shp.h @@ -0,0 +1,32 @@ +#ifndef NW4R_G3D_SCN_MDL1_MAT1_SHP_H +#define NW4R_G3D_SCN_MDL1_MAT1_SHP_H +#include "types_nw4r.h" +#include "g3d_scnobj.h" +#include "g3d_resmat.h" +#include "g3d_resshp.h" + +namespace nw4r +{ + namespace g3d + { + class ScnMdl1Mat1Shp : public ScnLeaf + { + public: + static const G3dObj::TypeObj GetTypeObjStatic() + { + return TypeObj(TYPE_NAME); + } + + ResMat GetResMat() { return mResMat; } + ResShp GetResShp() { return mResShp; } + + private: + ResMat mResMat; // at 0xE8 + ResShp mResShp; // at 0xEC + + NW4R_G3D_TYPE_OBJ_DECL(ScnMdl1Mat1Shp); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_scnmdlsmpl.h b/include/nw4r/g3d/g3d_scnmdlsmpl.h new file mode 100644 index 00000000..56ae32c0 --- /dev/null +++ b/include/nw4r/g3d/g3d_scnmdlsmpl.h @@ -0,0 +1,73 @@ +#ifndef NW4R_G3D_SCN_MDL_SIMPLE_H +#define NW4R_G3D_SCN_MDL_SIMPLE_H +#include "types_nw4r.h" +#include "g3d_scnobj.h" +#include "g3d_resmdl.h" + +namespace nw4r +{ + namespace g3d + { + class ScnMdlSimple : public ScnLeaf + { + public: + enum ByteCodeType + { + BYTE_CODE_CALC, + BYTE_CODE_MIX, + BYTE_CODE_DRAW_OPA, + BYTE_CODE_DRAW_XLU, + }; + + public: + ScnMdlSimple(MEMAllocator *, ResMdl, math::MTX34 *, u32 *, + math::MTX34 *, math::MTX33 *, math::MTX34 *, int, int); + + virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 + { + return (other == GetTypeObjStatic()) ? true + : ScnLeaf::IsDerivedFrom(other); + } + virtual void G3dProc(u32, u32, void *); // at 0xC + virtual ~ScnMdlSimple(); // at 0x10 + virtual const TypeObj GetTypeObj() const // at 0x14 + { + return TypeObj(TYPE_NAME); + } + virtual const char * GetTypeName() const // at 0x18 + { + return GetTypeObj().GetTypeName(); + } + + const u8 * GetByteCode(ByteCodeType) const; + + const ResMdl GetResMdl() const { return mResMdl; } + ResMdl GetResMdl() { return mResMdl; } + + math::MTX34 * GetWldMtxArray() { return mWldMatrixArray; } + u32 * GetWldMtxAttribArray() { return mWldMtxAttribArray; } + + u16 GetNumViewMtx() const { return mNumViewMtx; } + + private: + ResMdl mResMdl; // at 0xE8 + math::MTX34 *mWldMatrixArray; // at 0xEC + u32 *mWldMtxAttribArray; // at 0xF0 + math::MTX34 *PTR_0xF4; + math::MTX33 *PTR_0xF8; + math::MTX34 *PTR_0xFC; + u8 BYTE_0x100; + u8 BYTE_0x101; + u16 mNumViewMtx; // at 0x102 + UNKWORD WORD_0x104; + void *mByteCodeCalc; // at 0x108 + void *mByteCodeMix; // at 0x10C + void *mByteCodeDrawOpa; // at 0x110 + void *mByteCodeDrawXlu; // at 0x114 + + NW4R_G3D_TYPE_OBJ_DECL(ScnMdlSimple); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_scnobj.h b/include/nw4r/g3d/g3d_scnobj.h new file mode 100644 index 00000000..babda1f0 --- /dev/null +++ b/include/nw4r/g3d/g3d_scnobj.h @@ -0,0 +1,340 @@ +#ifndef NW4R_G3D_SCNOBJ_H +#define NW4R_G3D_SCNOBJ_H +#include "types_nw4r.h" +#include "math_types.h" +#include "math_geometry.h" +#include "g3d_obj.h" + +namespace nw4r +{ + namespace g3d + { + namespace + { + static inline u32 align4(u32 x) { return x + 3 & ~3; } + } + + struct IScnObjGather + { + virtual ~IScnObjGather(); + virtual UNKWORD Add(ScnObj *, bool, bool) = 0; + }; + + class ScnObj : public G3dObj + { + public: + enum ForEachResult + { + FOREACH_RESULT_0, + FOREACH_RESULT_1 + }; + + enum ScnObjFlag + { + FLAG_1 = 0x1, + FLAG_2 = 0x2, + FLAG_4 = 0x4, + FLAG_8 = 0x8, + FLAG_10 = 0x10, + FLAG_20 = 0x20, + FLAG_40 = 0x40, + FLAG_80 = 0x80, + FLAG_10000000 = 0x10000000, + FLAG_20000000 = 0x20000000, + FLAG_40000000 = 0x40000000, + FLAG_80000000 = 0x80000000, + + FLAG_60 = FLAG_40 | FLAG_20 + }; + + enum ScnObjMtxType + { + MTX_TYPE_0, + MTX_TYPE_WORLD, + MTX_TYPE_VIEW, + MTX_TYPE_MAX + }; + + enum Timing + { + TIMING_1 = 0x1, + TIMING_2 = 0x2, + TIMING_4 = 0x4 + }; + + enum ExecOp + { + EXEC_OP_1 = 0x1, + EXEC_OP_2 = 0x2, + EXEC_OP_4 = 0x4 + }; + + enum ScnObjBoundingVolumeType + { + BOUNDING_0, + BOUNDING_1, + BOUNDING_MAX + }; + + enum ScnObjOption + { + OPTION_VISIBLE = (1 << 0) + }; + + typedef ForEachResult (* ForEachAction)(ScnObj *, void *); + + public: + ScnObj(MEMAllocator *); + + virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 + { + return (other == GetTypeObjStatic()) ? true + : G3dObj::IsDerivedFrom(other); + } + virtual void G3dProc(u32, u32, void *) = 0; // at 0xC + virtual ~ScnObj(); // at 0x10 + virtual const TypeObj GetTypeObj() const // at 0x14 + { + return TypeObj(TYPE_NAME); + } + virtual const char * GetTypeName() const // at 0x18 + { + return GetTypeObj().GetTypeName(); + } + virtual ForEachResult ForEach(ForEachAction, void *, bool) = 0; // at 0x1C + virtual bool SetScnObjOption(u32, u32); // at 0x20 + virtual bool GetScnObjOption(u32, u32 *) const; // at 0x24 + virtual f32 GetValueForSortOpa() const; // at 0x28 + virtual f32 GetValueForSortXlu() const; // at 0x2C + virtual void CalcWorldMtx(const math::MTX34 *, u32 *); // at 0x30 + + static const G3dObj::TypeObj GetTypeObjStatic() + { + return TypeObj(TYPE_NAME); + } + + void CalcViewMtx(const math::MTX34 *); + bool SetMtx(ScnObjMtxType, const math::MTX34 *); + bool GetMtx(ScnObjMtxType, math::MTX34 *) const; + void SetPriorityDrawOpa(int); + void SetPriorityDrawXlu(int); + void EnableScnObjCallbackTiming(Timing); + void EnableScnObjCallbackExecOp(ExecOp); + bool SetBoundingVolume(ScnObjBoundingVolumeType, const math::AABB *); + bool GetBoundingVolume(ScnObjBoundingVolumeType, math::AABB *) const; + + const math::MTX34 * GetMtxPtr(ScnObjMtxType type) const + { + return &mMatrices[type]; + } + + void SetScnObjFlag(ScnObjFlag f, u32 set) + { + if (set) + { + mFlags |= f; + } + else + { + mFlags &= ~f; + } + } + bool TestScnObjFlag(ScnObjFlag f) const + { + return mFlags & f; + } + + inline void CheckCallback_CALC_VIEW(Timing timing, u32 r5, void *r6); + inline void CheckCallback_CALC_MAT(Timing timing, u32 r5, void *r6); + inline void CheckCallback_CALC_WORLD(Timing timing, u32 r5, void *r6); + + bool IsG3dProcDisabled(u32 task) const + { + if ((task < 9) && (1 << (task - 1) & mFlags)) return true; + return false; + } + + protected: + math::MTX34 mMatrices[MTX_TYPE_MAX]; // at 0xC + math::AABB mBounds[BOUNDING_MAX]; // at 0x9C + + u32 mFlags; // at 0xCC + u8 mPriorityDrawOpa; // at 0xD0 + u8 mPriorityDrawXlu; // at 0xD1 + u8 BYTE_0xD2; + u8 BYTE_0xD3; + IScnObjCallback *mCallback; // at 0xD4 + u8 mTiming; // at 0xD8 + u8 BYTE_0xD9; + u16 mExecOp; // at 0xDA + + NW4R_G3D_TYPE_OBJ_DECL(ScnObj); + }; + + struct IScnObjCallback + { + virtual ~IScnObjCallback() {} // at 0x8 + virtual void ExecCallback_CALC_WORLD(ScnObj::Timing, ScnObj *, u32, void *) {} // at 0xC + virtual void ExecCallback_CALC_MAT(ScnObj::Timing, ScnObj *, u32, void *) {} // at 0x10 + virtual void ExecCallback_CALC_VIEW(ScnObj::Timing, ScnObj *, u32, void *) {} // at 0x14 + }; + + // Is there a better way of resolving this dependency? + void ScnObj::CheckCallback_CALC_VIEW(Timing timing, u32 r5, void *r6) + { + if (mCallback != NULL) + { + if ((mExecOp & EXEC_OP_4) && (mTiming & timing)) + { + mCallback->ExecCallback_CALC_VIEW(timing, this, r5, r6); + } + } + } + + void ScnObj::CheckCallback_CALC_MAT(Timing timing, u32 r5, void *r6) + { + if (mCallback != NULL) + { + if ((mExecOp & EXEC_OP_2) && (mTiming & timing)) + { + mCallback->ExecCallback_CALC_MAT(timing, this, r5, r6); + } + } + } + + void ScnObj::CheckCallback_CALC_WORLD(Timing timing, u32 r5, void *r6) + { + if (mCallback != NULL) + { + if ((mExecOp & EXEC_OP_1) && (mTiming & timing)) + { + mCallback->ExecCallback_CALC_WORLD(timing, this, r5, r6); + } + } + } + + class ScnLeaf : public ScnObj + { + public: + // Unofficial name, however GetScaleProperty needs to return an enum to match + enum ScaleProperty + { + SCALE_PROPERTY_0, + SCALE_PROPERTY_1, + SCALE_PROPERTY_2, + }; + + public: + ScnLeaf(MEMAllocator *allocator) : ScnObj(allocator), mScale(1.0f, 1.0f, 1.0f) {} + + virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 + { + return (other == GetTypeObjStatic()) ? true + : ScnObj::IsDerivedFrom(other); + } + virtual void G3dProc(u32, u32, void *) = 0; // at 0xC + virtual ~ScnLeaf() {} // at 0x10 + virtual const TypeObj GetTypeObj() const // at 0x14 + { + return TypeObj(TYPE_NAME); + } + virtual const char * GetTypeName() const // at 0x18 + { + return GetTypeObj().GetTypeName(); + } + virtual ForEachResult ForEach(ForEachAction, void *, bool); // at 0x1C + virtual bool SetScnObjOption(u32, u32); // at 0x20 + virtual bool GetScnObjOption(u32, u32 *) const; // at 0x24 + virtual void CalcWorldMtx(const math::MTX34 *, u32 *); // at 0x30 + + static const G3dObj::TypeObj GetTypeObjStatic() + { + return TypeObj(TYPE_NAME); + } + + ScaleProperty GetScaleProperty() const; + void DefG3dProcScnLeaf(u32, u32, void *); + + private: + math::VEC3 mScale; + + NW4R_G3D_TYPE_OBJ_DECL(ScnLeaf); + }; + + class ScnGroup : public ScnObj + { + public: + ScnGroup(MEMAllocator *, ScnObj **, u32); + + virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 + { + return (other == GetTypeObjStatic()) ? true + : ScnObj::IsDerivedFrom(other); + } + virtual void G3dProc(u32, u32, void *); // at 0xC + virtual ~ScnGroup(); // at 0x10 + virtual const TypeObj GetTypeObj() const // at 0x14 + { + return TypeObj(TYPE_NAME); + } + virtual const char * GetTypeName() const // at 0x18 + { + return GetTypeObj().GetTypeName(); + } + virtual ForEachResult ForEach(ForEachAction, void *, bool); // at 0x1C + virtual bool Insert(u32, ScnObj *); // at 0x34 + virtual ScnObj * Remove(u32); // at 0x38 + virtual bool Remove(ScnObj *); // at 0x3C + + static const G3dObj::TypeObj GetTypeObjStatic() + { + return TypeObj(TYPE_NAME); + } + + bool Empty() const + { + return mSize == 0; + } + + u32 Size() const + { + return mSize; + } + + ScnObj * PopBack() + { + if (!Empty()) + { + return Remove(Size() - 1); + } + + return NULL; + } + + void Clear() + { + while (!Empty()) + { + PopBack(); + } + } + + void ScnGroup_G3DPROC_GATHER_SCNOBJ(u32, IScnObjGather *); + void ScnGroup_G3DPROC_CALC_WORLD(u32, const math::MTX34 *); + void ScnGroup_G3DPROC_CALC_MAT(u32, void *); + void ScnGroup_G3DPROC_CALC_VIEW(u32, const math::MTX34 *); + void DefG3dProcScnGroup(u32, u32, void *); + + bool PushBack(ScnObj *); + + ScnObj **mObjects; // at 0xDC + u32 mCapacity; // at 0xE0 + u32 mSize; // at 0xE4 + + private: + NW4R_G3D_TYPE_OBJ_DECL(ScnGroup); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_scnproc.h b/include/nw4r/g3d/g3d_scnproc.h new file mode 100644 index 00000000..0f01d175 --- /dev/null +++ b/include/nw4r/g3d/g3d_scnproc.h @@ -0,0 +1,78 @@ +#ifndef NW4R_G3D_SCNPROC_H +#define NW4R_G3D_SCNPROC_H +#include "types_nw4r.h" +#include "g3d_scnobj.h" + +namespace nw4r +{ + namespace g3d + { + class ScnProc : public ScnLeaf + { + public: + typedef void (* DrawProc)(ScnProc *, bool opa); + + ScnProc(MEMAllocator *allocator, DrawProc proc, void *userdata, bool set1, bool set2) + : ScnLeaf(allocator), mFlags(0), mDrawProc(proc), mUserData(userdata) + { + if (set1) mFlags |= 0x1; + if (set2) mFlags |= 0x2; + } + + static ScnProc * Construct(MEMAllocator *, u32 *, DrawProc, bool, bool, u32); + + virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 + { + return other == GetTypeObjStatic() ? true + : ScnLeaf::IsDerivedFrom(other); + }; + virtual void G3dProc(u32, u32, void *); // at 0xC + virtual ~ScnProc() {} // at 0x10 + virtual const TypeObj GetTypeObj() const // at 0x14 + { + return TypeObj(TYPE_NAME); + } + virtual const char * GetTypeName() const // at 0x18 + { + return GetTypeObj().GetTypeName(); + } + + static const G3dObj::TypeObj GetTypeObjStatic() { return TypeObj(TYPE_NAME); } + + void * GetUserData() { return mUserData; } + void SetUserData(void *data) { mUserData = data; } + + void SetDrawProc(DrawProc proc, bool r5, bool r6) + { + mDrawProc = proc; + + if (r5) + { + mFlags |= 0x1; + } + else + { + mFlags &= ~0x1; + } + + if (r6) + { + mFlags |= 0x2; + } + else + { + mFlags &= ~0x2; + } + } + + private: + u32 mFlags; // at 0xE8 + DrawProc mDrawProc; // at 0xEC + void *mUserData; // at 0xF0 + + NW4R_G3D_TYPE_OBJ_DECL(ScnProc); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_scnrfl.h b/include/nw4r/g3d/g3d_scnrfl.h new file mode 100644 index 00000000..2ccba439 --- /dev/null +++ b/include/nw4r/g3d/g3d_scnrfl.h @@ -0,0 +1,56 @@ +#ifndef NW4R_G3D_SCNRFL_H +#define NW4R_G3D_SCNRFL_H +#include "types_nw4r.h" +#include "g3d_scnleaf.h" +#include +#include + +namespace nw4r +{ + namespace g3d + { + class ScnRfl : public ScnLeaf + { + public: + struct RflData + { + bool SetupCharModel(RFLDataSource, u16, RFLMiddleDB *); + }; + + public: + static ScnRfl * Construct(MEMAllocator *, u32 *, RFLResolution, u32, u32); + ScnRfl(MEMAllocator *, ScnRfl *, RflData *, void *, u32); + + virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 + { + return (other == GetTypeObjStatic()); + } + virtual void G3dProc(u32, u32, void *); // at 0xC + virtual ~ScnRfl(); // at 0x10 + virtual const TypeObj GetTypeObj() const // at 0x14 + { + return TypeObj(TYPE_NAME); + } + virtual const char * GetTypeName() const // at 0x18 + { + return GetTypeObj().GetTypeName(); + } + + bool GetExpression(RFLExpression *); + bool SetExpression(RFLExpression); + + void SetFogIdx(int); + void SetLightSetIdx(int); + + static const nw4r::g3d::G3dObj::TypeObj GetTypeObjStatic() + { + return TypeObj(TYPE_NAME); + } + + private: + NW4R_G3D_TYPE_OBJ_DECL(ScnRfl); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_scnroot.h b/include/nw4r/g3d/g3d_scnroot.h new file mode 100644 index 00000000..8c3fb797 --- /dev/null +++ b/include/nw4r/g3d/g3d_scnroot.h @@ -0,0 +1,41 @@ +#ifndef NW4R_G3D_SCNROOT_H +#define NW4R_G3D_SCNROOT_H +#include "types_nw4r.h" +#include "g3d_scnobj.h" +#include "g3d_camera.h" +#include "g3d_fog.h" + +namespace nw4r +{ + namespace g3d + { + class ScnRoot : public ScnGroup + { + public: + Camera GetCamera(int); + Camera GetCurrentCamera(); + void SetCurrentCamera(int); + Fog GetFog(int); + + void UpdateFrame(); + void CalcWorld(); + void CalcMaterial(); + void CalcVtx(); + void CalcView(); + void GatherDrawScnObj(); + void ZSort(); + void DrawOpa(); + void DrawXlu(); + + u8 GetCurrentCameraID() const { return mCameraId; } + + private: + UNKWORD WORD_0xE8; + UNKWORD WORD_0xEC; + UNKWORD WORD_0xF0; + u8 mCameraId; + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_state.h b/include/nw4r/g3d/g3d_state.h new file mode 100644 index 00000000..5b7b87e8 --- /dev/null +++ b/include/nw4r/g3d/g3d_state.h @@ -0,0 +1,20 @@ +#ifndef NW4R_G3D_STATE_H +#define NW4R_G3D_STATE_H +#include "types_nw4r.h" +#include + +namespace nw4r { +namespace g3d { +namespace G3DState { +struct IndMtxOp {}; + +void SetViewPosNrmMtxArray(const math::MTX34 *, const math::MTX33 *, const math::MTX34 *); + +void SetRenderModeObj(const GXRenderModeObj &); +GXRenderModeObj &GetRenderModeObj(); +void Invalidate(u32); +} // namespace G3DState +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/g3d_tmem.h b/include/nw4r/g3d/g3d_tmem.h new file mode 100644 index 00000000..749156de --- /dev/null +++ b/include/nw4r/g3d/g3d_tmem.h @@ -0,0 +1,22 @@ +#ifndef NW4R_G3D_TMEM_H +#define NW4R_G3D_TMEM_H +#include "types_nw4r.h" + +namespace nw4r +{ + namespace g3d + { + namespace tmem + { + enum TMemLayout + { + TMEM_LAYOUT_0, + TMEM_LAYOUT_1 + }; + + void SetTMemLayout(TMemLayout); + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_workmem.h b/include/nw4r/g3d/g3d_workmem.h new file mode 100644 index 00000000..3f0ca444 --- /dev/null +++ b/include/nw4r/g3d/g3d_workmem.h @@ -0,0 +1,26 @@ +#ifndef NW4R_G3D_WORKMEM_H +#define NW4R_G3D_WORKMEM_H +#include "types_nw4r.h" + +#define G3D_WORKMEM_SIZE 0x18000 + +namespace nw4r +{ + namespace g3d + { + namespace detail + { + namespace workmem + { + void * GetScaleTemporary(); + void * GetMtxIDTemporary(); + void * GetMdlZTemporary(); + void * GetSkinningMtxTemporary(); + void * GetBillboardMtxTemporary(); + void * GetShpAnmResultBufTemporary(); + } + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/g3d/g3d_xsi.h b/include/nw4r/g3d/g3d_xsi.h new file mode 100644 index 00000000..939e6a19 --- /dev/null +++ b/include/nw4r/g3d/g3d_xsi.h @@ -0,0 +1,20 @@ +#ifndef NW4R_G3D_XSI_H +#define NW4R_G3D_XSI_H +#include "types_nw4r.h" +#include "g3d_anmtexsrt.h" + +namespace nw4r +{ + namespace g3d + { + namespace detail + { + namespace dcc + { + bool CalcTexMtx_Xsi(math::MTX34 *, bool, const TexSrt &, TexSrt::Flag); + } + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/lyt/lyt_animation.h b/include/nw4r/lyt/lyt_animation.h new file mode 100644 index 00000000..a9303e03 --- /dev/null +++ b/include/nw4r/lyt/lyt_animation.h @@ -0,0 +1,82 @@ +#ifndef NW4R_LYT_ANIMATION_H +#define NW4R_LYT_ANIMATION_H +#include "types_nw4r.h" +#include "ut_LinkList.h" +#include "lyt_resourceAccessor.h" +#include "lyt_common.h" + +namespace nw4r +{ + namespace lyt + { + namespace res + { + struct AnimationBlock + { + + }; + } + + struct AnimationBlock + { + res::DataBlockHeader header; // at 0x0 + u16 frameSize; // at 0x8 + bool loop; // at 0xA + // . . . + }; + + struct AnimTransform + { + inline AnimTransform() : mNode(), mResource(NULL), mFrame(0.0f) {} + + u16 GetFrameSize() const; + bool IsLoopData() const; + + ut::LinkListNode mNode; // at 0x0 + AnimationBlock *mResource; // at 0xC + f32 mFrame; // at 0x10 + }; + + struct AnimTransformBasic : AnimTransform + { + AnimTransformBasic(); + virtual ~AnimTransformBasic(); + virtual UNKTYPE SetResource(const res::AnimationBlock *, ResourceAccessor *); + virtual UNKTYPE Bind(Pane *, bool); + virtual UNKTYPE Bind(Material *); + virtual UNKTYPE Animate(u32, Pane *); + virtual UNKTYPE Animate(u32, Material *); + + u32 INT_0x14; + u32 INT_0x18; + u16 INT_0x1C; + }; + + struct AnimationLink + { + inline AnimationLink() : mNode() + { + Reset(); + } + + inline void Reset() + { + Set(NULL, 0, false); + } + + inline void Set(AnimTransform *pTransform, u16 us, bool b) + { + mTransform = pTransform; + SHORT_0xC = us; + BOOL_0xE = b; + } + + ut::LinkListNode mNode; // at 0x0 + AnimTransform *mTransform; // at 0x8 + u16 SHORT_0xC; + bool BOOL_0xE; + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/lyt/lyt_arcResourceAccessor.h b/include/nw4r/lyt/lyt_arcResourceAccessor.h new file mode 100644 index 00000000..7c5e86ae --- /dev/null +++ b/include/nw4r/lyt/lyt_arcResourceAccessor.h @@ -0,0 +1,84 @@ +#ifndef NW4R_LYT_ARC_RESOURCE_ACCESSOR_H +#define NW4R_LYT_ARC_RESOURCE_ACCESSOR_H +#include "lyt_resourceAccessor.h" +#include "types_nw4r.h" +#include "ut_Font.h" +#include "ut_LinkList.h" +#include +#include + + +#define FONTNAMEBUF_MAX 127 + +namespace nw4r { +namespace lyt { +class FontRefLink { +public: + FontRefLink(); + ~FontRefLink() {} + + void Set(const char *, ut::Font *); + + ut::Font *GetFont() const { + return mFont; + } + + const char *GetFontName() const { + return mFontName; + } + +private: + ut::LinkListNode mNode; // at 0x0 + char mFontName[FONTNAMEBUF_MAX]; // at 0x8 + ut::Font *mFont; // at 0x88 +}; + +class ArcResourceAccessor : public ResourceAccessor { +public: + ArcResourceAccessor(); + virtual ~ArcResourceAccessor() {} // at 0x8 + virtual UNKTYPE *GetResource(u32, const char *, u32 *); // at 0xC + virtual ut::Font *GetFont(const char *); // at 0x10 + + bool Attach(void *, const char *); + void *Detach() { + void *old = mArchive; + mArchive = NULL; + + return old; + } + + bool IsAttached() const { + return (mArchive != NULL); + } + + void RegistFont(FontRefLink *pLink) { + mRefList.PushBack(pLink); + } + void UnregistFont(FontRefLink *pLink) { + mRefList.Erase(pLink); + } + +private: + ARCHandle mHandle; // at 0x4 + void *mArchive; // at 0x8 + ut::LinkList mRefList; // at 0x24 + char mRootDir[FONTNAMEBUF_MAX]; // at 0x30 +}; + +namespace detail { +static ut::Font *FindFont(ut::LinkList *pList, const char *name) { + ut::LinkList::Iterator it = pList->GetBeginIter(); + for (; it != pList->GetEndIter(); it++) { + if (strcmp(name, it->GetFontName()) == 0) { + return it->GetFont(); + } + } + + return NULL; +} +} // namespace detail +} // namespace lyt +} // namespace nw4r + +#endif diff --git a/include/nw4r/lyt/lyt_bounding.h b/include/nw4r/lyt/lyt_bounding.h new file mode 100644 index 00000000..7dcc2013 --- /dev/null +++ b/include/nw4r/lyt/lyt_bounding.h @@ -0,0 +1,36 @@ +#ifndef NW4R_LYT_BOUNDING_H +#define NW4R_LYT_BOUNDING_H +#include "types_nw4r.h" +#include "lyt_pane.h" +#include "lyt_drawInfo.h" + +namespace nw4r +{ + namespace lyt + { + namespace res + { + struct Bounding : Pane + { + + }; + } + + struct ResBlockSet + { + + }; + + struct Bounding : Pane + { + Bounding(const res::Bounding *, const ResBlockSet&); + virtual ~Bounding(); + virtual const ut::detail::RuntimeTypeInfo * GetRuntimeTypeInfo() const; + virtual void DrawSelf(const DrawInfo&); + + static ut::detail::RuntimeTypeInfo typeInfo; + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/lyt/lyt_common.h b/include/nw4r/lyt/lyt_common.h new file mode 100644 index 00000000..af80950b --- /dev/null +++ b/include/nw4r/lyt/lyt_common.h @@ -0,0 +1,60 @@ +#ifndef NW4R_LYT_COMMON_H +#define NW4R_LYT_COMMON_H +#include "types_nw4r.h" +#include "math_types.h" +#include "ut_binaryFileFormat.h" + +#define NW4R_RES_NAME_SIZE 16 +#define NW4R_MAT_NAME_SIZE 20 + +#define TEXCOORD_VTX_COUNT 4 + +namespace nw4r +{ + namespace lyt + { + namespace res + { + struct BinaryFileHeader : ut::BinaryFileHeader + { + + }; + + struct DataBlockHeader { + u32 kind; // at 0x0 + u32 size; // at 0x4 + }; + } + + namespace detail + { + typedef math::VEC2 TexCoordData[TEXCOORD_VTX_COUNT]; + + struct TexCoordAry + { + TexCoordAry(); + void Free(); + void Reserve(u8); + void SetSize(u8); + void Copy(const void *, u8); + + u8 mCap; // at 0x0 + u8 mSize; // at 0x1 + TexCoordData *mTexCoords; // at 0x4 + }; + + bool EqualsResName(const char *, const char *); + bool EqualsMaterialName(const char *, const char *); + bool TestFileHeader(const res::BinaryFileHeader&); + bool TestFileHeader(const res::BinaryFileHeader&, u32); + bool IsModulateVertexColor(ut::Color *, u8); + void MultipleAlpha(ut::Color *, const ut::Color *, u8); // Inlined + ut::Color MultipleAlpha(ut::Color, u8); + void SetVertexFormat(bool, u8); + void DrawQuad(const math::VEC2&, const Size&, u8, const TexCoordData *, const ut::Color *); + void DrawQuad(const math::VEC2&, const Size&, u8, const TexCoordData *, const ut::Color *, u8); + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/lyt/lyt_drawInfo.h b/include/nw4r/lyt/lyt_drawInfo.h new file mode 100644 index 00000000..8aab5fcc --- /dev/null +++ b/include/nw4r/lyt/lyt_drawInfo.h @@ -0,0 +1,25 @@ +#ifndef NW4R_LYT_DRAWINFO_H +#define NW4R_LYT_DRAWINFO_H +#include "types_nw4r.h" +#include "math_types.h" +#include "ut_Rect.h" + +namespace nw4r +{ + namespace lyt + { + struct DrawInfo + { + virtual ~DrawInfo(); + DrawInfo(); + + math::MTX34 mViewMtx; // at 0x0 + ut::Rect mViewRect; // at 0x34 + math::VEC2 mScale; // at 0x44 + f32 mGlobalAlpha; // at 0x48 + u8 mFlags; // at 0x50 + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/lyt/lyt_group.h b/include/nw4r/lyt/lyt_group.h new file mode 100644 index 00000000..efe17ac0 --- /dev/null +++ b/include/nw4r/lyt/lyt_group.h @@ -0,0 +1,55 @@ +#ifndef NW4R_LYT_GROUP_H +#define NW4R_LYT_GROUP_H +#include "types_nw4r.h" +#include "lyt_pane.h" +#include "lyt_common.h" +#include "ut_LinkList.h" + +namespace nw4r +{ + namespace lyt + { + namespace res + { + struct Group + { + char UNK_0x0[0x8]; + char mName[NW4R_RES_NAME_SIZE]; // at 0x8 + u16 SHORT_0x18; + }; + } + + namespace detail + { + struct PaneLink + { + ut::LinkListNode mNode; // at 0x0 + Pane *PANE_0x8; + }; + } + + struct Group + { + Group(const res::Group *, Pane *); + virtual ~Group(); + void AppendPane(Pane *); + void Init(); + + ut::LinkListNode mNode; // at 0x4 + ut::LinkList mPaneList; // at 0xC + char mName[NW4R_RES_NAME_SIZE]; // at 0x18 + bool mIsUserAllocated; // at 0x29 + }; + + struct GroupContainer + { + ~GroupContainer(); + void AppendGroup(Group *); + Group * FindGroupByName(const char *); + + ut::LinkList mGroups; // at 0x4 + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/lyt/lyt_layout.h b/include/nw4r/lyt/lyt_layout.h new file mode 100644 index 00000000..6f052a0b --- /dev/null +++ b/include/nw4r/lyt/lyt_layout.h @@ -0,0 +1,57 @@ +#ifndef NW4R_LYT_LAYOUT_H +#define NW4R_LYT_LAYOUT_H +#include "types_nw4r.h" +#include +#include + +namespace nw4r { +namespace lyt { +struct Layout { + // TO-DO: Class members + + static void FreeMemory(void *p) { + MEMFreeToAllocator(mspAllocator, p); + } + + static void *AllocMemory(size_t n) { + return MEMAllocFromAllocator(mspAllocator, n); + } + + template + static void DeleteArray(T *p, size_t n) { + for (size_t i = 0; i < n; i++) { + p[i].~T(); + } + + FreeMemory(p); + } + + template + static T *NewArray(size_t n) { + T *array = (T *)AllocMemory(n * sizeof(T)); + + for (size_t i = 0; i < n; i++) { + new (&array[i]) T(); + } + + return array; + } + + template + static void DeleteObj(T *t) { + t->~T(); + FreeMemory(t); + } + + template + static T *NewObj() { + T *obj = (T *)AllocMemory(sizeof(T)); + return new (obj) T(); + } + + static MEMAllocator *mspAllocator; +}; +} // namespace lyt +} // namespace nw4r + +#endif diff --git a/include/nw4r/lyt/lyt_material.h b/include/nw4r/lyt/lyt_material.h new file mode 100644 index 00000000..4b2e76ac --- /dev/null +++ b/include/nw4r/lyt/lyt_material.h @@ -0,0 +1,26 @@ +#ifndef NW4R_LYT_MATERIAL_H +#define NW4R_LYT_MATERIAL_H +#include "lyt_animation.h" +#include "ut_LinkList.h" +#include + + +namespace nw4r { +namespace lyt { +// TO-DO +struct Material { + ut::LinkList mAnimLinks; // at 0x4 + // . . . + GXColorS10 COLOR_0x10; + GXColorS10 COLOR_0x18; + GXColorS10 COLOR_0x20; + // . . . + UNKWORD WORD_0x40; + // . . . + u8 BYTE_0x59; + // . . . +}; +} // namespace lyt +} // namespace nw4r + +#endif diff --git a/include/nw4r/lyt/lyt_pane.h b/include/nw4r/lyt/lyt_pane.h new file mode 100644 index 00000000..28acbb6d --- /dev/null +++ b/include/nw4r/lyt/lyt_pane.h @@ -0,0 +1,157 @@ +#ifndef NW4R_LYT_PANE_H +#define NW4R_LYT_PANE_H +#include "types_nw4r.h" +#include "math_types.h" +#include "ut_LinkList.h" +#include "ut_RuntimeTypeInfo.h" +#include "ut_Color.h" +#include "ut_algorithm.h" +#include "lyt_animation.h" +#include + +#define PANE_NAME_SIZE 17 +#define PANE_USERDATA_SIZE 9 +#define ANIMTARGET_PANE_MAX 10 + +namespace nw4r +{ + namespace lyt + { + void LytInit(); + + struct Size + { + inline Size() : x(), y() {} + + inline Size& operator=(const Size& rhs) + { + x = rhs.x; + y = rhs.y; + return *this; + } + + f32 x, y; + }; + + namespace detail + { + struct PaneBase + { + inline PaneBase() : mNode() {} + + virtual ~PaneBase(); + ut::LinkListNode mNode; // at 0x4 + }; + } + + namespace res + { + struct Pane + { + u32 mMagic; // "pan1", at 0x0 + u32 mLength; // at 0x4 + u8 BYTE_0x8; + u8 BYTE_0x9; + u8 BYTE_0xA; + u8 BYTE_0xB; // NO REFERENCES + char mName[PANE_NAME_SIZE]; // at 0xC + char mUserData[PANE_USERDATA_SIZE]; // at 0x1C + math::VEC3 VEC3_0x24; + math::VEC3 VEC3_0x30; + math::VEC2 VEC2_0x3C; + Size mSize; // at 0x44 + }; + } + + struct Pane : detail::PaneBase + { + // For use with TestBit + enum PaneBits + { + VISIBLE, + INFLUENCED_ALPHA, + LOCATION_ADJUST + }; + + inline void Init() + { + mParent = NULL; + mMaterial = NULL; + BYTE_0xD6 = 0; + INT_0xB4 = 0; + } + + inline void SetName(const char *pName) + { + strncpy(mName, pName, PANE_NAME_SIZE); + mName[PANE_NAME_SIZE - 1] = '\0'; + } + + inline void SetUserData(const char *pData) + { + strncpy(mUserData, pData, PANE_USERDATA_SIZE); + mUserData[PANE_USERDATA_SIZE - 1] = '\0'; + } + + inline void InsertChild(ut::LinkList::Iterator iter, lyt::Pane *pChild) + { + mChildren.Insert(iter, pChild); + pChild->mParent = this; + } + + Pane(const res::Pane *); + virtual ~Pane(); // at 0x8 + virtual const ut::detail::RuntimeTypeInfo * GetRuntimeTypeInfo() const; // at 0xC + virtual UNKTYPE CalculateMtx(const DrawInfo&); // at 0x10 + virtual UNKTYPE Draw(const DrawInfo&); // at 0x14 + virtual void DrawSelf(const DrawInfo&); // at 0x18 + virtual UNKTYPE Animate(u32); // at 0x1C + virtual UNKTYPE AnimateSelf(u32); // at 0x20 + virtual ut::Color GetVtxColor(u32) const; // at 0x24 + virtual void SetVtxColor(u32, ut::Color); // at 0x28 + virtual UNKTYPE GetColorElement(u32) const; // at 0x2C + virtual UNKTYPE SetColorElement(u32, u8); // at 0x30 + virtual u8 GetVtxColorElement(u32) const; // at 0x34 + virtual void SetVtxColorElement(u32, u8); // at 0x38 + virtual Pane * FindPaneByName(const char *, bool); // at 0x3C + virtual UNKTYPE FindMaterialByName(const char *, bool); // at 0x40 + virtual UNKTYPE BindAnimation(AnimTransform *, bool); // at 0x44 + virtual UNKTYPE UnbindAnimation(AnimTransform *, bool); // at 0x48 + virtual UNKTYPE UnbindAllAnimation(bool); // at 0x4C + virtual UNKTYPE UnbindAnimationSelf(AnimTransform *); // at 0x50 + virtual UNKTYPE FindAnimationLink(AnimTransform *); // at 0x54 + virtual UNKTYPE SetAnimationEnable(AnimTransform *, bool, bool); // at 0x58 + virtual UNKTYPE GetMaterial() const; // at 0x5C + virtual UNKTYPE LoadMtx(const DrawInfo&); // at 0x60 + void AppendChild(Pane *); + void RemoveChild(Pane *); + UNKTYPE GetPaneRect(const DrawInfo&) const; + UNKTYPE AddAnimationLink(AnimationLink *); + UNKTYPE GetVtxPos() const; + + ut::LinkListNode mNode; // at 0x4 + Pane *mParent; // at 0x8 + ut::LinkList mChildren; // at 0x14 + ut::LinkList mAnims; // at 0x20; + Material *mMaterial; // at 0x2C + math::VEC3 mTranslate; // at 0x30 + math::VEC3 VEC3_0x3C; + math::VEC2 mScale; // at 0x48 + Size mSize; // at 0x50 + math::MTX34 MTX34_0x58; + math::MTX34 mGlobalMtx; // at 0x84 + int INT_0xB4; + u8 mAlpha; // at 0xB8 + u8 BYTE_0xB9; + u8 BYTE_0xBA; + u8 mFlags; // at 0xBB + char mName[PANE_NAME_SIZE]; // at 0xBC + char mUserData[PANE_USERDATA_SIZE]; // at 0xCD + u8 BYTE_0xD6; + + static ut::detail::RuntimeTypeInfo typeInfo; + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/lyt/lyt_resourceAccessor.h b/include/nw4r/lyt/lyt_resourceAccessor.h new file mode 100644 index 00000000..d8a10c8a --- /dev/null +++ b/include/nw4r/lyt/lyt_resourceAccessor.h @@ -0,0 +1,21 @@ +#ifndef NW4R_LYT_RESOURCE_ACCESSOR_H +#define NW4R_LYT_RESOURCE_ACCESSOR_H +#include "types_nw4r.h" +#include "ut_Font.h" + +namespace nw4r +{ + namespace lyt + { + class ResourceAccessor + { + public: + ResourceAccessor(); + virtual ~ResourceAccessor(); // at 0x8 + virtual UNKTYPE * GetResource(u32, const char *, u32 *) = 0; // at 0xC + virtual ut::Font * GetFont(const char *); // at 0x10 + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/lyt/lyt_texMap.h b/include/nw4r/lyt/lyt_texMap.h new file mode 100644 index 00000000..e685602b --- /dev/null +++ b/include/nw4r/lyt/lyt_texMap.h @@ -0,0 +1,168 @@ +#ifndef NW4R_LYT_TEXMAP_H +#define NW4R_LYT_TEXMAP_H +#include "types_nw4r.h" +#include +#include + +namespace nw4r { +namespace lyt { +namespace detail { +bool IsCITexelFormat(GXTexFmt fmt) { + return (fmt == GX_TF_C4 || fmt == GX_TF_C8 || fmt == GX_TF_C14X2); +} +} // namespace detail + +class TexMap { +public: + void Get(GXTexObj *) const; + void Get(GXTlutObj *) const; + + void Set(const TexMap &t) { + *this = t; + } + void Set(TPLPalette *, u32); + void Set(const TPLDescriptor *); + + void SetNoWrap(const TexMap &); + void SetNoWrap(const TPLDescriptor *); + + void *GetImage() const { + return mImage; + } + void SetImage(void *img) { + mImage = img; + } + + void *GetPalette() const { + return mPalette; + } + void SetPalette(void *pal) { + mPalette = pal; + } + + u16 GetWidth() const { + return mWidth; + } + u16 GetHeight() const { + return mHeight; + } + void SetSize(u16 w, u16 h) { + mWidth = w; + mHeight = h; + } + + f32 GetMinLOD() const { + return mMinLOD; + } + f32 GetMaxLOD() const { + return mMaxLOD; + } + void SetLOD(f32 min, f32 max) { + mMinLOD = min; + mMaxLOD = max; + } + + f32 GetLODBias() const { + return mLODBias / 256.0f; + } + void SetLODBias(f32 val) { + mLODBias = u16(val * 256.0f); + } + + u16 GetPaletteEntryNum() const { + return mPaletteEntryNum; + } + void SetPaletteEntryNum(u16 num) { + mPaletteEntryNum = num; + } + + GXTexFmt GetTexelFormat() const { + return (GXTexFmt)mTexelFormat; + } + void SetTexelFormat(GXTexFmt fmt) { + mTexelFormat = fmt; + } + + bool IsMipMap() const { + return mIsMipMap; + } + void SetMipMap(bool b) { + mIsMipMap = b; + } + + GXTexWrapMode GetWrapModeS() const { + return (GXTexWrapMode)mWrapModeS; + } + GXTexWrapMode GetWrapModeT() const { + return (GXTexWrapMode)mWrapModeT; + } + void SetWrapMode(GXTexWrapMode wrapS, GXTexWrapMode wrapT) { + mWrapModeS = wrapS; + mWrapModeT = wrapT; + } + + GXTexFilter GetMinFilter() const { + return (GXTexFilter)mMinFilter; + } + GXTexFilter GetMagFilter() const { + return (GXTexFilter)mMagFilter; + } + void SetFilter(GXTexFilter minFlt, GXTexFilter magFlt) { + mMinFilter = minFlt; + mMagFilter = magFlt; + } + + bool IsBiasClampEnable() const { + return mIsBiasClampEnable; + } + void SetBiasClampEnable(bool b) { + mIsBiasClampEnable = b; + } + + bool IsEdgeLODEnable() const { + return mIsEdgeLODEnable; + } + void SetEdgeLODEnable(bool b) { + mIsEdgeLODEnable = b; + } + + GXAnisotropy GetAnisotropy() const { + return (GXAnisotropy)mAnisotropy; + } + void SetAnisotropy(GXAnisotropy a) { + mAnisotropy = a; + } + + GXTlutFmt GetPaletteFormat() const { + return (GXTlutFmt)mPaletteFormat; + } + void SetPaletteFormat(GXTlutFmt fmt) { + mPaletteFormat = fmt; + } + +private: + void *mImage; // at 0x0 + void *mPalette; // at 0x4 + u16 mWidth; // at 0x8 + u16 mHeight; // at 0xA + f32 mMinLOD; // at 0xC + f32 mMaxLOD; // at 0x10 + u16 mLODBias; // at 0x14 + u16 mPaletteEntryNum; // at 0x16 + + // at 0x18 + u32 mTexelFormat : 4; // GXTexFmt + u32 mIsMipMap : 1; // bool + u32 mWrapModeS : 2; // GXTexWrapMode + u32 mWrapModeT : 2; // GXTexWrapMode + u32 mMinFilter : 3; // GXTexFilter + u32 mMagFilter : 3; // GXTexFilter + u32 mIsBiasClampEnable : 1; // bool + u32 mIsEdgeLODEnable : 1; // bool + u32 mAnisotropy : 2; // GXAnisotropy + u32 mPaletteFormat : 2; // GXTlutFmt +}; +} // namespace lyt +} // namespace nw4r + +#endif diff --git a/include/nw4r/math.h b/include/nw4r/math.h new file mode 100644 index 00000000..ea99d35f --- /dev/null +++ b/include/nw4r/math.h @@ -0,0 +1,9 @@ +#ifndef NW4R_PUBLIC_MATH_H +#define NW4R_PUBLIC_MATH_H + +#include +#include +#include +#include + +#endif diff --git a/include/nw4r/math/arithmetic.h b/include/nw4r/math/arithmetic.h deleted file mode 100644 index caa97bba..00000000 --- a/include/nw4r/math/arithmetic.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef NW4R_MATH_ARITHMETIC_H -#define NW4R_MATH_ARITHMETIC_H - -#include -#include -#include - -namespace nw4r -{ - namespace math - { - namespace detail - { - f32 FExp(f32); - f32 FLog(f32); - } - - f32 FrSqrt(register f32); - - inline u32 F32AsU32(f32 x) - { - return *(u32 *)&x; - } - - inline f32 U32AsF32(u32 x) - { - return *(f32 *)&x; - } - - inline s32 FGetExpPart(f32 x) - { - u32 ul = F32AsU32(x); - return ((ul >> 23) & 0xFF) - 127; - } - - inline f32 FGetMantPart(f32 x) - { - u32 ul = F32AsU32(x); - return U32AsF32((ul & 0x807FFFFF) | 0x3F800000); - } - - inline float FFloor(float arg) - { - return floor(arg); - } - - inline float FModf(float arg, float * pIntegralPart) - { - double integralPart; - float fractionalPart = modf(arg, &integralPart); - - *pIntegralPart = integralPart; - - return fractionalPart; - } - - inline float FInv(register float arg) - { - register float tmp; - register float ret; - - asm - { - fres ret, arg - ps_add tmp, ret, ret - ps_mul ret, ret, ret - ps_nmsub ret, arg, ret, tmp - } - - return ret; - } - - inline f32 U16ToF32(u16 arg) - { - f32 ret; - - OSu16tof32(&arg, &ret); - - return ret; - } - - inline u16 F32ToU16(f32 arg) - { - u16 ret; - - OSf32tou16(&arg, &ret); - - return ret; - } - - inline f32 S16ToF32(s16 arg) - { - f32 ret; - - OSs16tof32(&arg, &ret); - - return ret; - } - - inline s16 F32ToS16(f32 arg) - { - s16 ret; - - OSf32tos16(&arg, &ret); - - return ret; - } - } -} - -#endif diff --git a/include/nw4r/math/math_arithmetic.h b/include/nw4r/math/math_arithmetic.h new file mode 100644 index 00000000..cce709d2 --- /dev/null +++ b/include/nw4r/math/math_arithmetic.h @@ -0,0 +1,142 @@ +#ifndef NW4R_MATH_ARITHMETIC_H +#define NW4R_MATH_ARITHMETIC_H +#include +#include +#include + +#define NW4R_MATH_QNAN (-(0.0f / 0.0f)) +#define NW4R_MATH_FLT_MAX 3.402823466e+38f + +namespace nw4r { +namespace math { +namespace detail { + +f32 FExp(f32 x); +f32 FLog(f32 x); + +} // namespace detail + +f32 FrSqrt(f32 x); + +inline f32 FAbs(register f32 x) { + // clang-format off + asm { + fabs x, x + } + // clang-format on + + return x; +} + +inline f32 FCeil(f32 x) { + return ceilf(x); +} + +inline f32 FExp(f32 x) { + return detail::FExp(x); +} + +inline f32 FFloor(f32 x) { + return floorf(x); +} + +inline f32 FInv(register f32 x) { + register f32 work0, work1, work2, work3; + + // clang-format off + asm { + fmr work1, x // x + fres work0, work1 // 1/x + + // Refine estimate + ps_add work2, work0, work0 // 2/x + ps_mul work3, work0, work0 // 1/x^2 + ps_nmsub work0, work1, work3, work2 // -(x * 1/x^2 - 2/x) + } + // clang-format on + + return work0; +} + +inline f32 FMod(f32 x, f32 y) { + return fmodf(x, y); +} + +inline f32 FModf(f32 x, f32 *y) { + return fmodff(x, y); +} + +inline f32 FSqrt(f32 x) { + if (x < 0.0f) { + return 0.0f; + } + + return x * FrSqrt(x); +} + +inline f32 FLog(f32 x) { + if (x >= 0.0f) { + return detail::FLog(x); + } + + return NW4R_MATH_QNAN; +} + +inline f32 FSelect(register f32 value, register f32 ge_zero, register f32 lt_zero) { + register f32 ret; + + // clang-format off + asm { + fsel ret, value, ge_zero, lt_zero + } + // clang-format on + + return ret; +} + +inline f32 U16ToF32(u16 arg) { + f32 ret; + OSu16tof32(&arg, &ret); + return ret; +} + +inline u16 F32ToU16(f32 arg) { + u16 ret; + OSf32tou16(&arg, &ret); + return ret; +} + +inline f32 S16ToF32(s16 arg) { + f32 ret; + OSs16tof32(&arg, &ret); + return ret; +} + +inline s16 F32ToS16(f32 arg) { + s16 ret; + OSf32tos16(&arg, &ret); + return ret; +} + +inline u32 F32AsU32(f32 arg) { + return *reinterpret_cast(&arg); +} + +inline f32 U32AsF32(u32 arg) { + return *reinterpret_cast(&arg); +} + +inline s32 FGetExpPart(f32 x) { + s32 s = F32AsU32(x); + return ((s >> 23) & 0xFF) - 0x7F; +} + +inline f32 FGetMantPart(f32 x) { + u32 u = F32AsU32(x); + return U32AsF32((u & 0x807FFFFF) | 0x3F800000); +} + +} // namespace math +} // namespace nw4r + +#endif diff --git a/include/nw4r/math/math_geometry.h b/include/nw4r/math/math_geometry.h new file mode 100644 index 00000000..d693711e --- /dev/null +++ b/include/nw4r/math/math_geometry.h @@ -0,0 +1,93 @@ +#ifndef NW4R_MATH_GEOMETRY_H +#define NW4R_MATH_GEOMETRY_H +#include +#include + +namespace nw4r { +namespace math { + +enum IntersectionResult { + INTERSECTION_NONE, + INTERSECTION_1, + INTERSECTION_2, + + INTERSECTION_LINE3_ON_PLANE = INTERSECTION_2, + INTERSECTION_RAY3_ON_PLANE = INTERSECTION_2, + INTERSECTION_SEGMENT3_ON_PLANE = INTERSECTION_2, + + INTERSECTION_OUTSIDE = 0, + INTERSECTION_INSIDE, + INTERSECTION_INTERSECT +}; + +struct PLANE { + PLANE() {} + + f32 Test(const VEC3& point) const { return d + VEC3Dot(&n, &point); } + void Set(const VEC3* p0, const VEC3* p1, const VEC3* p2); + + VEC3 n; // at 0x0 + f32 d; // at 0xC +}; + +struct AABB { + AABB() {} + + void Set(const VEC3* points, unsigned int num); + void Set(const AABB* box, const MTX34* mtx); + + VEC3 min; // at 0x0 + VEC3 max; // at 0xC +}; + +class FRUSTUM { +private: + enum Point { + POINT_NEAR_TL, + POINT_NEAR_TR, + POINT_NEAR_BR, + POINT_NEAR_BL, + + POINT_FAR_TL, + POINT_FAR_TR, + POINT_FAR_BR, + POINT_FAR_BL, + + POINT_MAX + }; + + enum Plane { + PLANE_L, + PLANE_R, + PLANE_N, + PLANE_F, + PLANE_T, + PLANE_B, + + PLANE_MAX + }; + +public: + void Set(f32 fovy, f32 aspect, f32 n, f32 f, const MTX34& cam); + void Set(f32 t, f32 b, f32 l, f32 r, f32 n, f32 f, const MTX34& cam); + + IntersectionResult IntersectAABB_Ex(const AABB* box) const; + +private: + MTX34 mCamMtx; // at 0x0 + PLANE mPlaneL; // at 0x30 + PLANE mPlaneR; // at 0x40 + PLANE mPlaneT; // at 0x50 + PLANE mPlaneB; // at 0x60 + f32 mNearZ; // at 0x70 + f32 mFarZ; // at 0x74 + AABB mBox; // at 0x78 + PLANE mPlanes[PLANE_MAX]; // at 0x90 +}; + +bool IntersectionAABB(const AABB* a, const AABB* b); + +} // namespace math +} // namespace nw4r + +#endif diff --git a/include/nw4r/math/math_triangular.h b/include/nw4r/math/math_triangular.h new file mode 100644 index 00000000..4d27959d --- /dev/null +++ b/include/nw4r/math/math_triangular.h @@ -0,0 +1,105 @@ +#ifndef NW4R_MATH_TRIANGULAR_H +#define NW4R_MATH_TRIANGULAR_H +#include +#include + +#define NW4R_MATH_PI M_PI +#define NW4R_MATH_LN_2 0.69314718056f + +// [0, 65535] -> [0.0, 256.0f] +#define NW4R_MATH_IDX_TO_FIDX(x) ((x) * (1.0f / 256.0f)) + +// Convert degrees <-> lookup-table index +#define NW4R_MATH_DEG_TO_FIDX(x) ((x) * (256.0f / 360.0f)) +#define NW4R_MATH_FIDX_TO_DEG(x) ((x) * (360.0f / 256.0f)) + +// Convert radians <-> lookup-table index +#define NW4R_MATH_RAD_TO_FIDX(x) ((x) * (128.0f / NW4R_MATH_PI)) +#define NW4R_MATH_FIDX_TO_RAD(x) ((x) * (NW4R_MATH_PI / 128.0f)) + +namespace nw4r { +namespace math { + +/** + * sin + */ +f32 SinFIdx(f32 fidx); + +inline f32 SinIdx(u16 idx) { + return SinFIdx(NW4R_MATH_IDX_TO_FIDX(U16ToF32(idx))); +} + +inline f32 SinDeg(f32 deg) { + return SinFIdx(NW4R_MATH_DEG_TO_FIDX(deg)); +} +inline f32 SinRad(f32 rad) { + return SinFIdx(NW4R_MATH_RAD_TO_FIDX(rad)); +} + +/** + * cos + */ +f32 CosFIdx(f32 fidx); + +inline f32 CosDeg(f32 deg) { + return CosFIdx(NW4R_MATH_DEG_TO_FIDX(deg)); +} +inline f32 CosRad(f32 rad) { + return CosFIdx(NW4R_MATH_RAD_TO_FIDX(rad)); +} + +/** + * tan + */ +inline f32 TanFIdx(f32 fidx) { + return tanf(NW4R_MATH_FIDX_TO_RAD(fidx)); +} +inline f32 TanDeg(f32 deg) { + return TanFIdx(NW4R_MATH_DEG_TO_FIDX(deg)); +} +inline f32 TanRad(f32 rad) { + return TanFIdx(NW4R_MATH_RAD_TO_FIDX(rad)); +} + +/** + * sin/cos + */ +void SinCosFIdx(f32 *pSin, f32 *pCos, f32 fidx); + +inline void SinCosDeg(f32 *pSin, f32 *pCos, f32 deg) { + return SinCosFIdx(pSin, pCos, NW4R_MATH_DEG_TO_FIDX(deg)); +} + +inline void SinCosRad(f32 *pSin, f32 *pCos, f32 rad) { + return SinCosFIdx(pSin, pCos, NW4R_MATH_RAD_TO_FIDX(rad)); +} + +/** + * atan + */ +f32 AtanFIdx(f32 x); + +inline f32 AtanDeg(f32 x) { + return NW4R_MATH_FIDX_TO_DEG(AtanFIdx(x)); +} +inline f32 AtanRad(f32 x) { + return NW4R_MATH_FIDX_TO_RAD(AtanFIdx(x)); +} + +/** + * atan2 + */ +f32 Atan2FIdx(f32 y, f32 x); + +inline f32 Atan2Deg(f32 y, f32 x) { + return NW4R_MATH_FIDX_TO_DEG(Atan2FIdx(y, x)); +} + +inline f32 Atan2Rad(f32 y, f32 x) { + return NW4R_MATH_FIDX_TO_RAD(Atan2FIdx(y, x)); +} + +} // namespace math +} // namespace nw4r + +#endif diff --git a/include/nw4r/math/math_types.h b/include/nw4r/math/math_types.h new file mode 100644 index 00000000..f08094d4 --- /dev/null +++ b/include/nw4r/math/math_types.h @@ -0,0 +1,567 @@ +#ifndef NW4R_MATH_TYPES_H +#define NW4R_MATH_TYPES_H +#include +#include +#include +#include + +namespace nw4r { +namespace math { + +/****************************************************************************** + * + * VEC2 structure + * + ******************************************************************************/ +// Optimization: Forces copy by lwz/stw +struct _VEC2 { + f32 x, y; +}; + +struct VEC2 : _VEC2 { + VEC2() {} + VEC2(f32 fx, f32 fy) { + x = fx; + y = fy; + } + + operator f32 *() { + return reinterpret_cast(this); + } + operator const f32 *() const { + return reinterpret_cast(this); + } + + VEC2 operator+(const VEC2 &rhs) const { + return VEC2(x + rhs.x, y + rhs.y); + } + VEC2 operator-(const VEC2 &rhs) const { + return VEC2(x - rhs.x, y - rhs.y); + } + + VEC2 &operator+=(const VEC2 &rhs) { + x += rhs.x; + y += rhs.y; + return *this; + } + VEC2 &operator-=(const VEC2 &rhs) { + x -= rhs.x; + y -= rhs.y; + return *this; + } + + bool operator==(const VEC2 &rhs) const { + return x == rhs.x && y == rhs.y; + } + bool operator!=(const VEC2 &rhs) const { + return x != rhs.x || y != rhs.y; + } +}; + +/****************************************************************************** + * + * VEC3 structure + * + ******************************************************************************/ +// Forward declarations +VEC3 *VEC3Add(VEC3 *out, const VEC3 *a, const VEC3 *b); +VEC3 *VEC3Sub(VEC3 *out, const VEC3 *a, const VEC3 *b); +VEC3 *VEC3Scale(VEC3 *out, const VEC3 *in, f32 scale); + +// Optimization: Forces copy by lwz/stw +struct _VEC3 { + f32 x, y, z; +}; + +struct VEC3 : _VEC3 { + VEC3() {} + VEC3(f32 fx, f32 fy, f32 fz) { + x = fx; + y = fy; + z = fz; + } + VEC3(const Vec &vec) { + x = vec.x; + y = vec.y; + z = vec.z; + } + VEC3(const f32 *p) { + x = p[0]; + y = p[1]; + z = p[2]; + } + + operator Vec *() { + return reinterpret_cast(this); + } + operator const Vec *() const { + return reinterpret_cast(this); + } + + f32 LenSq() const { + return x * x + y * y + z * z; + } + + VEC3 operator-() const { + return VEC3(-x, -y, -z); + } + + VEC3 operator+(const VEC3 &rhs) const { + VEC3 out; + VEC3Add(&out, this, &rhs); + return out; + } + VEC3 operator-(const VEC3 &rhs) const { + VEC3 out; + VEC3Sub(&out, this, &rhs); + return out; + } + VEC3 operator*(f32 x) const { + VEC3 out; + VEC3Scale(&out, this, x); + return out; + } + VEC3 operator/(f32 x) const { + f32 r = 1 / x; + return *this * r; + } + + VEC3 &operator+=(const VEC3 &rhs) { + VEC3Add(this, this, &rhs); + return *this; + } + VEC3 &operator-=(const VEC3 &rhs) { + VEC3Sub(this, this, &rhs); + return *this; + } + VEC3 &operator*=(f32 x) { + VEC3Scale(this, this, x); + return *this; + } + VEC3 &operator/=(f32 x) { + return *this *= (1 / x); + } + + bool operator==(const VEC3 &rhs) const { + return x == rhs.x && y == rhs.y && z == rhs.z; + } + bool operator!=(const VEC3 &rhs) const { + return x != rhs.x || y != rhs.y || z != rhs.z; + } +}; + +/****************************************************************************** + * + * MTX33 structure + * + ******************************************************************************/ +// Optimization: Forces copy by lwz/stw +struct _MTX33 { + union { + struct { + f32 _00, _01, _02; + f32 _10, _11, _12; + f32 _20, _21, _22; + }; + + f32 m[3][3]; + f32 a[3 * 3]; + }; +}; + +struct MTX33 : _MTX33 { + MTX33() {} +}; + +/****************************************************************************** + * + * MTX34 structure + * + ******************************************************************************/ +// Optimization: Forces copy by lwz/stw +struct _MTX34 { + union { + struct { + f32 _00, _01, _02, _03; + f32 _10, _11, _12, _13; + f32 _20, _21, _22, _23; + }; + + f32 m[3][4]; + f32 a[3 * 4]; + Mtx mtx; + }; +}; + +struct MTX34 : _MTX34 { + typedef f32 (*MtxRef)[4]; + typedef const f32 (*MtxRefConst)[4]; + + MTX34() {} + + // clang-format off + MTX34(f32 f00, f32 f01, f32 f02, f32 f03, + f32 f10, f32 f11, f32 f12, f32 f13, + f32 f20, f32 f21, f32 f22, f32 f23) { + _00 = f00; _01 = f01; _02 = f02; _03 = f03; + _10 = f10; _11 = f11; _12 = f12; _13 = f13; + _20 = f20; _21 = f21; _22 = f22; _23 = f23; + } + // clang-format on + + operator MtxRef() { + return mtx; + } + operator MtxRefConst() const { + return mtx; + } +}; + +/****************************************************************************** + * + * MTX44 structure + * + ******************************************************************************/ +// Optimization: Forces copy by lwz/stw +struct _MTX44 { + union { + struct { + f32 _00, _01, _02, _03; + f32 _10, _11, _12, _13; + f32 _20, _21, _22, _23; + f32 _30, _31, _32, _33; + }; + + f32 m[4][4]; + f32 a[4 * 4]; + Mtx44 mtx; + }; +}; + +struct MTX44 : _MTX44 { + typedef f32 (*Mtx44Ref)[4]; + typedef const f32 (*Mtx44RefConst)[4]; + + MTX44() {} + + operator Mtx44Ref() { + return mtx; + } + operator Mtx44RefConst() const { + return mtx; + } +}; + +/****************************************************************************** + * + * QUAT structure + * + ******************************************************************************/ +// Optimization: Forces copy by lwz/stw +struct _QUAT { + f32 x, y, z, w; +}; + +struct QUAT : _QUAT { + QUAT() {} + QUAT(f32 fx, f32 fy, f32 fz, f32 fw) { + x = fx; + y = fy; + z = fz; + w = fw; + } + + // These are not real AFAIK. Do they really manually cast the QUAT? + operator Quaternion *() { + return reinterpret_cast(this); + } + operator const Quaternion *() const { + return reinterpret_cast(this); + } +}; + +/****************************************************************************** + * + * VEC2 functions + * + ******************************************************************************/ +inline f32 VEC2Len(const VEC2 *vec) { + return FSqrt(vec->x * vec->x + vec->y * vec->y); +} + +/****************************************************************************** + * + * VEC3 functions + * + ******************************************************************************/ +VEC3 *VEC3Maximize(VEC3 *out, const VEC3 *a, const VEC3 *b); +VEC3 *VEC3Minimize(VEC3 *out, const VEC3 *a, const VEC3 *b); +VEC3 *VEC3TransformNormal(VEC3 *out, const MTX34 *mtx, const VEC3 *vec); + +inline VEC3 *VEC3Add(register VEC3 *out, register const VEC3 *a, register const VEC3 *b) { + register f32 work0, work1, work2; + + // clang-format off + asm { + // Add XY + psq_l work0, VEC3.x(a), 0, 0 + psq_l work1, VEC3.x(b), 0, 0 + ps_add work2, work0, work1 + psq_st work2, VEC3.x(out), 0, 0 + + // Add Z + psq_l work0, VEC3.z(a), 1, 0 + psq_l work1, VEC3.z(b), 1, 0 + ps_add work2, work0, work1 + psq_st work2, VEC3.z(out), 1, 0 + } + // clang-format on + + return out; +} + +inline f32 VEC3Dot(register const VEC3 *a, register const VEC3 *b) { + register f32 dot; + register f32 work0, work1, work2, work3; + + // clang-format off + asm { + // YZ product + psq_l work0, VEC3.y(a), 0, 0 + psq_l work1, VEC3.y(b), 0, 0 + ps_mul work0, work0, work1 + + // X product + YZ product + psq_l work3, VEC3.x(a), 1, 0 + psq_l work2, VEC3.x(b), 1, 0 + ps_madd work1, work3, work2, work0 + + // Dot product + ps_sum0 dot, work1, work0, work0 + } + // clang-format on + + return dot; +} + +inline f32 VEC3LenSq(register const VEC3 *vec) { + register f32 work0, work1, work2; + + // clang-format off + asm { + // Square XY + psq_l work0, VEC3.x(vec), 0, 0 + ps_mul work0, work0, work0 + + // Square Z + lfs work1, VEC3.z(vec) + ps_madd work2, work1, work1, work0 + + // Sum products + ps_sum0 work2, work2, work0, work0 + } + // clang-format on + + return work2; +} + +inline VEC3 *VEC3Lerp(register VEC3 *out, register const VEC3 *vec1, register const VEC3 *vec2, register f32 t) { + register f32 work0, work1, work2; + + // clang-format off + asm { + // X/Y delta + psq_l work0, VEC3.x(vec1), 0, 0 + psq_l work1, VEC3.x(vec2), 0, 0 + ps_sub work2, work1, work0 + // Scale with time and add to v0 + ps_madds0 work2, work2, t, work0 + psq_st work2, VEC3.x(out), 0, 0 + + // Z delta + psq_l work0, VEC3.z(vec1), 1, 0 + psq_l work1, VEC3.z(vec2), 1, 0 + ps_sub work2, work1, work0 + // Scale with time and add to v0 + ps_madds0 work2, work2, t, work0 + psq_st work2, VEC3.z(out), 1, 0 + } + // clang-format on + + return out; +} + +inline VEC3 *VEC3Scale(register VEC3 *out, register const VEC3 *in, register f32 scale) { + register f32 work0, work1; + + // clang-format off + asm { + // Scale XY + psq_l work0, VEC3.x(in), 0, 0 + ps_muls0 work1, work0, scale + psq_st work1, VEC3.x(out), 0, 0 + + // Scale Z + psq_l work0, VEC3.z(in), 1, 0 + ps_muls0 work1, work0, scale + psq_st work1, VEC3.z(out), 1, 0 + } + // clang-format on + + return out; +} + +inline VEC3 *VEC3Sub(register VEC3 *out, register const VEC3 *a, register const VEC3 *b) { + register f32 work0, work1, work2; + + // clang-format off + asm { + // Sub XY + psq_l work0, VEC3.x(a), 0, 0 + psq_l work1, VEC3.x(b), 0, 0 + ps_sub work2, work0, work1 + psq_st work2, VEC3.x(out), 0, 0 + + // Sub Z + psq_l work0, VEC3.z(a), 1, 0 + psq_l work1, VEC3.z(b), 1, 0 + ps_sub work2, work0, work1 + psq_st work2, VEC3.z(out), 1, 0 + } + // clang-format on + + return out; +} + +inline VEC3 *VEC3Cross(VEC3 *out, const VEC3 *a, const VEC3 *b) { + PSVECCrossProduct(*a, *b, *out); + return out; +} + +inline f32 VEC3DistSq(const VEC3 *a, const VEC3 *b) { + return PSVECSquareDistance(*a, *b); +} + +inline f32 VEC3Len(const VEC3 *vec) { + return PSVECMag(*vec); +} + +inline VEC3 *VEC3Normalize(VEC3 *out, const VEC3 *in) { + PSVECNormalize(*in, *out); + return out; +} + +inline VEC3 *VEC3Transform(VEC3 *out, const MTX34 *mtx, const VEC3 *vec) { + PSMTXMultVec(*mtx, *vec, *out); + return out; +} + +inline VEC3 *VEC3TransformCoord(VEC3 *out, const MTX34 *mtx, const VEC3 *vec) { + PSMTXMultVec(*mtx, *vec, *out); + return out; +} + +/****************************************************************************** + * + * MTX33 functions + * + ******************************************************************************/ +MTX33 *MTX33Identity(MTX33 *mtx); + +/****************************************************************************** + * + * MTX34 functions + * + ******************************************************************************/ +MTX33 *MTX34ToMTX33(MTX33 *out, const MTX34 *in); +bool MTX34InvTranspose(MTX33 *out, const MTX34 *in); +MTX34 *MTX34Zero(MTX34 *mtx); +MTX34 *MTX34Scale(MTX34 *out, const MTX34 *in, const VEC3 *scale); +MTX34 *MTX34Trans(MTX34 *out, const MTX34 *in, const VEC3 *trans); +MTX34 *MTX34RotAxisFIdx(MTX34 *mtx, const VEC3 *axis, f32 fidx); +MTX34 *MTX34RotXYZFIdx(MTX34 *mtx, f32 fx, f32 fy, f32 fz); + +inline MTX34 *MTX34Copy(MTX34 *out, const MTX34 *in) { + PSMTXCopy(*in, *out); + return out; +} + +inline MTX34 *MTX34Identity(MTX34 *mtx) { + PSMTXIdentity(*mtx); + return mtx; +} + +inline MTX34 *MTX34Inv(MTX34 *out, const MTX34 *in) { + PSMTXInverse(*in, *out); + return out; +} + +inline MTX34 *MTX34LookAt(MTX34 *mtx, const VEC3 *pos, const VEC3 *up, const VEC3 *target) { + C_MTXLookAt(*mtx, *pos, *up, *target); + return mtx; +} + +inline MTX34 *MTX34Mult(MTX34 *out, const MTX34 *a, const MTX34 *b) { + PSMTXConcat(*a, *b, *out); + return out; +} + +inline MTX34 *MTX34MultArray(MTX34 *out, const MTX34 *p1, const MTX34 *src, u32 len) { + PSMTXConcatArray(*p1, *src, *out, len); + return out; +} + +inline MTX34 *MTX34RotAxisRad(MTX34 *out, const VEC3 *axis, f32 frad) { + return MTX34RotAxisFIdx(out, axis, NW4R_MATH_RAD_TO_FIDX(frad)); +} + +inline MTX34 *MTX34RotXYZDeg(MTX34 *mtx, f32 dx, f32 dy, f32 dz) { + return MTX34RotXYZFIdx(mtx, NW4R_MATH_DEG_TO_FIDX(dx), NW4R_MATH_DEG_TO_FIDX(dy), NW4R_MATH_DEG_TO_FIDX(dz)); +} + +inline MTX34 *MTX34RotXYZRad(MTX34 *mtx, f32 rx, f32 ry, f32 rz) { + return MTX34RotXYZFIdx(mtx, NW4R_MATH_RAD_TO_FIDX(rx), NW4R_MATH_RAD_TO_FIDX(ry), NW4R_MATH_RAD_TO_FIDX(rz)); +} + +inline MTX34 *MTX34Scale(MTX34 *out, const VEC3 *scale, const MTX34 *in) { + PSMTXScaleApply(*in, *out, scale->x, scale->y, scale->z); + return out; +} + +inline QUAT *MTX34ToQUAT(QUAT *quat, const MTX34 *mtx) { + C_QUATMtx(*quat, *mtx); + return quat; +} + +inline MTX34 *MTX34Trans(MTX34 *out, const VEC3 *trans, const MTX34 *in) { + PSMTXTransApply(*in, *out, trans->x, trans->y, trans->z); + return out; +} + +/****************************************************************************** + * + * MTX44 functions + * + ******************************************************************************/ +MTX44 *MTX44Identity(MTX44 *mtx); +MTX44 *MTX44Copy(MTX44 *dst, const MTX44 *src); + +/****************************************************************************** + * + * QUAT functions + * + ******************************************************************************/ +inline MTX34 *QUATToMTX34(MTX34 *mtx, const QUAT *quat) { + PSMTXQuat(*mtx, *quat); + return mtx; +} + +inline QUAT *C_QUATSlerp(QUAT *out, const QUAT *q1, const QUAT *q2, f32 t) { + ::C_QUATSlerp(*q1, *q2, *out, t); + return out; +} + +} // namespace math +} // namespace nw4r + +#endif diff --git a/include/nw4r/math/vec.h b/include/nw4r/math/vec.h deleted file mode 100644 index 1c868b29..00000000 --- a/include/nw4r/math/vec.h +++ /dev/null @@ -1,148 +0,0 @@ -#pragma once - -#include "nw4r/nw4r_types.h" - -// struct Vec { -// f32 x,y,z; -// }; - -namespace nw4r -{ - namespace math - { - // forward decl - struct _VEC2; struct VEC2; - struct _VEC3; struct VEC3; - struct _QUAT; struct QUAT; - struct _MTX33; struct MTX33; - struct _MTX34; struct MTX34; - struct _MTX44; struct MTX44; - void VEC3Add(VEC3* pOut, const VEC3* p1, const VEC3* p2); - void VEC3Sub(VEC3* pOut, const VEC3* p1, const VEC3* p2); - void VEC3Scale(VEC3* pOut, const VEC3* p, f32 scale); - f32 VEC3Len(const VEC3* p); - f32 VEC3LenSq(const VEC3* p); - f32 VEC3DistSq(const VEC3* p1, const VEC3* p2); - void VEC3Normalize(VEC3* pOut, const VEC3* p); - f32 VEC3Dot(const VEC3* p1, const VEC3* p2); - void VEC3Cross(VEC3* pOut, const VEC3* p1, const VEC3* p2); - void VEC3Lerp(VEC3* pOut, const VEC3* p1, const VEC3* p2, f32 t); - void VEC3Transform(VEC3* pOut, const MTX34* pM, const VEC3* pV); - void VEC3TransformCoord(VEC3* pOut, const MTX34* pM, const VEC3* pV); - - struct _VEC2 {f32 x, y;}; - struct VEC2 : _VEC2 { - VEC2() {} - VEC2(f32 fx, f32 fy) { x = fx; y = fy;} - }; - - struct _VEC3 { f32 x,y,z; }; - struct VEC3 : public _VEC3 { - VEC3() {} - VEC3(f32 fx, f32 fy, f32 fz) { x = fx; y = fy; z = fz;} - // VEC3(const Vec& v) { x = v.x; y = v.y; z = v.z;} - VEC3(const f32* p) { x = p[0]; x = p[1]; z = p[2];} - VEC3(const _VEC3& v) { x = v.x; y = v.y; z = v.z; } - - // operator Vec*() { return (Vec*)this; } - // operator const Vec*() const { return (const Vec*)this; } - - f32 LenSq() const { - return x*x + y*y + z*z; - } - - VEC3 operator+(const VEC3& rhs) const { - VEC3 tmp; - VEC3Add(&tmp, this, &rhs); - return tmp; - } - VEC3& operator+=(const VEC3& rhs) { - VEC3Add(this, this, &rhs); - return *this; - } - VEC3 operator-() const { - return VEC3(-x, -y, -z); - } - VEC3 operator-(const VEC3& rhs) const { - VEC3 tmp; - VEC3Sub(&tmp, this, &rhs); - return tmp; - } - VEC3& operator-=(const VEC3& rhs) { - VEC3Sub(this, this, &rhs); - return *this; - } - VEC3 operator*(f32 f) const { - VEC3 tmp; - VEC3Scale(&tmp, this, f); - return tmp; - } - VEC3& operator*=(f32 f) { - VEC3Scale(this, this, f); - return *this; - } - VEC3 operator/(f32 f) const { - f32 r = 1.0f / f; // DWARF has it - return operator*(r); - } - VEC3& operator/=(f32 f) { - return operator*=(1.0f / f); - } - bool operator!=(const VEC3& rhs) { - return x != rhs.x || y != rhs.y || z != rhs.z; - } - }; - inline void VEC3Add(register VEC3* pOut, register const VEC3* p1, register const VEC3* p2) { - asm { - psq_l f2, 0x0(p1), 0, 0 - psq_l f2, 0x0(p2), 0, 0 - ps_add f0, f2, f1 - psq_l f2, 0x8(p1), 1, 0 - psq_l f2, 0x8(p2), 1, 0 - psq_st f0, 0x0(pOut), 0, 0 - ps_add f0, f2, f1 - psq_st f0, 0x8(pOut), 1, 0 - } - } - inline void VEC3Sub(register VEC3* pOut, register const VEC3* p1, register const VEC3* p2) { - asm - { - psq_l f2, 0x0(p1), 0, 0 - psq_l f2, 0x0(p2), 0, 0 - ps_sub f0, f2, f1 - psq_l f2, 0x8(p1), 1, 0 - psq_l f2, 0x8(p2), 1, 0 - psq_st f0, 0x0(pOut), 0, 0 - ps_sub f0, f2, f1 - psq_st f0, 0x8(pOut), 1, 0 - } - } - inline void VEC3Scale(register VEC3* pOut, register const VEC3* p, register f32 scale) { - asm - { - psq_l f2, 0x0(p), 0, 0 - ps_muls0 f1, f2, scale - psq_l f2, 0x8(p), 0, 1 - psq_st f1, 0x0(pOut), 0, 0 - ps_muls0 f1, f2, scale - psq_st f1, 0x8(pOut), 1, 0 - } - } - inline float VEC3Dot(register const VEC3 * p1, register const VEC3 * p2) - { - register f32 a, b, d, c, e; - asm - { - psq_l a, 0x4(p1), 0, 0 - psq_l b, 0x4(p2), 0, 0 - ps_mul a, a, b - psq_l c, 0(p1), 1, 0 - psq_l d, 0(p2), 1, 0 - ps_madd b, c, d, a - ps_sum0 e, b, a, a - } - return e; - } - } // namespace math - -} // namespace nw4r \ No newline at end of file diff --git a/include/nw4r/snd.h b/include/nw4r/snd.h new file mode 100644 index 00000000..9faa65ed --- /dev/null +++ b/include/nw4r/snd.h @@ -0,0 +1,21 @@ +#ifndef NW4R_PUBLIC_SND_H +#define NW4R_PUBLIC_SND_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/include/nw4r/snd/snd_AxManager.h b/include/nw4r/snd/snd_AxManager.h new file mode 100644 index 00000000..a51ae25e --- /dev/null +++ b/include/nw4r/snd/snd_AxManager.h @@ -0,0 +1,98 @@ +#ifndef NW4R_SND_AX_MANAGER_H +#define NW4R_SND_AX_MANAGER_H +#include +#include +#include +#include +#include +#include +#include + +namespace nw4r { +namespace snd { +namespace detail { + +class AxManager { +public: + struct CallbackListNode { + NW4R_UT_LIST_NODE_DECL(); // at 0x0 + AXOutCallback callback; // at 0x8 + }; + + NW4R_UT_LIST_TYPEDEF_DECL(CallbackListNode); + +public: + static AxManager &GetInstance(); + + AxManager(); + ~AxManager() {} + + bool CheckInit() { + return mInitialized; + } + bool IsDiskError() const { + return mDiskError; + } + s32 GetResetReadyTimer() const { + return mResetReadyTimer; + } + FxBaseList &GetEffectList(AuxBus bus) { + return mFxList[bus]; + } + + void Init(); + void Shutdown(); + f32 GetOutputVolume() const; + void Update(); + void *GetZeroBufferAddress(); + + void RegisterCallback(CallbackListNode *node, AXOutCallback callback); + void UnregisterCallback(CallbackListNode *node); + + void SetOutputMode(OutputMode mode); + OutputMode GetOutputMode(); + + f32 GetMasterVolume() const { + return mMasterVolume.GetValue(); + } + void SetMasterVolume(f32 volume, int frame); + + bool AppendEffect(AuxBus bus, FxBase *fx); + void ClearEffect(AuxBus bus, int frame); + void ShutdownEffect(AuxBus bus); + + void PrepareReset(); + +private: + static void AxCallbackFunc(); + static void AuxCallbackFunc(void *chans, void *context); + static void AiDmaCallbackFunc(); + +private: + static u8 sZeroBuffer[0x100]; + + OutputMode mOutputMode; // at 0x0 + void *mZeroBuffer; // at 0x4 + CallbackListNodeList mCallbackList; // at 0x8 + AXOutCallback mOldAxCallback; // at 0x14 + bool mInitialized; // at 0x18 + bool mUpdateVoicePrio; // at 0x19 + bool mDiskError; // at 0x1A + MoveValue mMasterVolume; // at 0x1C + MoveValue mMainOutVolume; // at 0x2C + MoveValue mVolumeForReset; // at 0x3C + AIDMACallback mOldAiCallback; // at 0x4C + s32 mResetReadyTimer; // at 0x50 + MoveValue mAuxFadeVolume[AUX_BUS_NUM]; // at 0x54 + MoveValue mAuxUserVolume[AUX_BUS_NUM]; // at 0x84 + FxBaseList mFxList[AUX_BUS_NUM]; // at 0xB4 + AXAuxCallback mAuxCallback[AUX_BUS_NUM]; // at 0xD8 + void *mAuxCallbackContext[AUX_BUS_NUM]; // at 0xE4 + u8 mAuxCallbackWait[AUX_BUS_NUM]; // at 0xF0 +}; + +} // namespace detail +} // namespace snd +} // namespace nw4r + +#endif diff --git a/include/nw4r/snd/snd_AxVoice.h b/include/nw4r/snd/snd_AxVoice.h new file mode 100644 index 00000000..f9796e23 --- /dev/null +++ b/include/nw4r/snd/snd_AxVoice.h @@ -0,0 +1,262 @@ +#ifndef NW4R_SND_AX_VOICE_H +#define NW4R_SND_AX_VOICE_H +#include +#include +#include + +namespace nw4r { +namespace snd { +namespace detail { + +inline int CalcAxvpbDelta(u16 init, u16 target) { + return (target - init) / AX_SAMPLES_PER_FRAME; +} + +class AxVoiceParamBlock { +public: + AxVoiceParamBlock(); + + operator AXVPB *() { + return mVpb; + } + + bool IsAvailable() const { + return mVpb != NULL; + } + + bool IsRun() const { + return IsAvailable() && mVpb->pb.state == AX_VOICE_RUN; + } + + bool IsLpfEnable() const { + return IsAvailable() && mVpb->pb.lpf.on == AX_PB_LPF_ON; + } + + bool IsBiquadEnable() const { + return IsAvailable() && mVpb->pb.biquad.on == AX_PB_BIQUAD_ON; + } + + u32 GetCurrentAddress() const { + if (!IsAvailable()) { + return 0; + } + + return (mVpb->pb.addr.currentAddressHi << 16) + mVpb->pb.addr.currentAddressLo; + } + + u32 GetLoopAddress() const { + if (!IsAvailable()) { + return 0; + } + + return (mVpb->pb.addr.loopAddressHi << 16) + mVpb->pb.addr.loopAddressLo; + } + + u32 GetEndAddress() const { + if (!IsAvailable()) { + return 0; + } + + return (mVpb->pb.addr.endAddressHi << 16) + mVpb->pb.addr.endAddressLo; + } + + void SetVoiceAddr(const AXPBADDR &addr) { + if (IsAvailable()) { + // AXSetVoiceAddr doesn't actually modify the object + AXSetVoiceAddr(mVpb, const_cast(&addr)); + } + } + + void SetVoicePriority(u32 prio) { + if (IsAvailable()) { + AXSetVoicePriority(mVpb, prio); + } + } + + void SetVoiceStateRun() { + if (IsAvailable()) { + AXSetVoiceState(mVpb, AX_VOICE_RUN); + } + } + + void SetVoiceStateStop() { + if (IsRun()) { + AXSetVoiceState(mVpb, AX_VOICE_STOP); + } + } + + void Sync(); + bool IsRmtIirEnable() const; + + void Set(AXVPB *vpb); + void Clear(); + + void SetVoiceType(u16 type); + void SetVoiceVe(u16 volume, u16 initVolume); + void SetVoiceMix(const AXPBMIX &mix, bool syncNow); + void SetVoiceLoop(u16 loop); + void SetVoiceLoopAddr(u32 addr); + void SetVoiceEndAddr(u32 addr); + void SetVoiceAdpcm(const AXPBADPCM &adpcm); + void SetVoiceSrcType(u32 type); + void SetVoiceSrc(const AXPBSRC &src); + void SetVoiceSrcRatio(f32 ratio); + void SetVoiceAdpcmLoop(const AXPBADPCMLOOP &loop); + void SetVoiceLpf(const AXPBLPF &lpf); + void SetVoiceLpfCoefs(u16 a0, u16 b0); + void SetVoiceRmtOn(u16 on); + void SetVoiceRmtMix(const AXPBRMTMIX &mix); + void SetVoiceRmtIIR(const AXPBRMTIIR &iir); + void SetVoiceRmtIIRCoefs(u16 type, ...); + void UpdateDelta(); + +private: + AXVPB *mVpb; // at 0x0 + u32 mSync; // at 0x4 + volatile AXPBVE mVePrev; // at 0x8 + bool mFirstVeUpdate; // at 0xC + u16 mVolume; // at 0xE +}; + +class AxVoice { + friend class AxVoiceManager; + +public: + enum AxVoiceCallbackStatus { CALLBACK_STATUS_CANCEL, CALLBACK_STATUS_DROP_DSP }; + + typedef void (*Callback)(AxVoice *voice, AxVoiceCallbackStatus status, void *arg); + + enum Format { + FORMAT_ADPCM = 0, + FORMAT_PCM16 = 10, + FORMAT_PCM8 = 25, + }; + + enum VoiceType { + VOICE_TYPE_NORMAL, + VOICE_TYPE_STREAM, + }; + + enum SrcType { + SRC_NONE, + SRC_LINEAR, + SRC_4TAP_8K, + SRC_4TAP_12K, + SRC_4TAP_16K, + SRC_4TAP_AUTO, + }; + + struct MixParam { + u16 vL; // at 0x0 + u16 vR; // at 0x2 + u16 vS; // at 0x4 + u16 vAuxAL; // at 0x6 + u16 vAuxAR; // at 0x8 + u16 vAuxAS; // at 0xA + u16 vAuxBL; // at 0xC + u16 vAuxBR; // at 0xE + u16 vAuxBS; // at 0x10 + u16 vAuxCL; // at 0x12 + u16 vAuxCR; // at 0x14 + u16 vAuxCS; // at 0x16 + }; + + struct RemoteMixParam { + u16 vMain0; // at 0x0 + u16 vAux0; // at 0x2 + u16 vMain1; // at 0x4 + u16 vAux1; // at 0x6 + u16 vMain2; // at 0x8 + u16 vAux2; // at 0xA + u16 vMain3; // at 0xC + u16 vAux3; // at 0xE + }; + +public: + static u32 GetDspAddressBySample(const void *base, u32 samples, Format fmt); + static u32 GetSampleByDspAddress(const void *base, u32 addr, Format fmt); + static u32 GetSampleByByte(u32 addr, Format fmt); + static void CalcOffsetAdpcmParam(u16 *outPredScale, u16 *outYn1, u16 *outYn2, u32 offset, const void *data, + const AdpcmParam ¶m); + + AxVoice(); + ~AxVoice(); + + bool IsRun() const { + return mVpb.IsRun(); + } + void Run() { + mVpb.SetVoiceStateRun(); + } + void Stop() { + mVpb.SetVoiceStateStop(); + } + void Sync() { + mVpb.Sync(); + } + + Format GetFormat() const { + return mFormat; + } + + void SetBaseAddress(const void *base) { + mWaveData = base; + } + + f32 GetDspRatio(f32 ratio) const { + return (ratio * mSampleRate) / AX_SAMPLE_RATE; + } + + void Setup(const void *wave, Format fmt, int rate); + + bool IsPlayFinished() const; + void SetLoopStart(const void *base, u32 samples); + void SetLoopEnd(const void *base, u32 samples); + void SetLoopFlag(bool loop); + void StopAtPoint(const void *base, u32 samples); + + bool IsDataAddressCoverd(const void *begin, const void *end) const; + u32 GetCurrentPlayingSample() const; + u32 GetCurrentPlayingDspAddress() const; + u32 GetLoopEndDspAddress() const; + + void SetPriority(u32 prio); + void SetVoiceType(VoiceType type); + void EnableRemote(bool enable); + void ResetDelta(); + void SetAddr(bool loop, const void *wave, u32 offset, u32 loopStart, u32 loopEnd); + void SetSrcType(SrcType type, f32 pitch); + void SetAdpcm(const AdpcmParam *param); + void SetAdpcmLoop(const AdpcmLoopParam *param); + bool SetMix(const MixParam ¶m); + void SetRmtMix(const RemoteMixParam ¶m); + void SetSrc(f32 ratio, bool initial); + void SetVe(f32 volume, f32 initVolume); + void SetLpf(u16 freq); + void SetRemoteFilter(u8 filter); + +private: + static void VoiceCallback(void *arg); + +private: + AxVoiceParamBlock mVpb; // at 0x0 + const void *mWaveData; // at 0x10 + Format mFormat; // at 0x14 + int mSampleRate; // at 0x18 + bool mFirstMixUpdate; // at 0x1C + bool mReserveForFree; // at 0x1D + MixParam mMixPrev; // at 0x1E + Callback mCallback; // at 0x38 + void *mCallbackArg; // at 0x3C + +public: + NW4R_UT_LIST_NODE_DECL(); // at 0x40 +}; + +NW4R_UT_LIST_TYPEDEF_DECL(AxVoice); + +} // namespace detail +} // namespace snd +} // namespace nw4r + +#endif diff --git a/include/nw4r/snd/snd_AxVoiceManager.h b/include/nw4r/snd/snd_AxVoiceManager.h new file mode 100644 index 00000000..d492bfb2 --- /dev/null +++ b/include/nw4r/snd/snd_AxVoiceManager.h @@ -0,0 +1,43 @@ +#ifndef NW4R_SND_AX_VOICE_MANAGER_H +#define NW4R_SND_AX_VOICE_MANAGER_H +#include +#include + +namespace nw4r { +namespace snd { +namespace detail { + +class AxVoiceManager { +public: + static AxVoiceManager& GetInstance(); + + AxVoiceManager(); + ~AxVoiceManager() {} + + u32 GetRequiredMemSize(); + void Setup(void* work, u32 size); + void Shutdown(); + + AxVoice* AcquireAxVoice(u32 prio, AxVoice::Callback callback, void* arg); + void FreeAxVoice(AxVoice* voice); + void ReserveForFreeAxVoice(AxVoice* voice); + void FreeAllReservedAxVoice(); + +private: + AxVoice* Alloc(); + void Free(AxVoice* voice); + void ReserveForFree(AxVoice* voice); + +private: + AxVoiceList mActiveList; // at 0x0 + AxVoiceList mFreeList; // at 0xC + AxVoiceList mFreeReservedList; // at 0x18 + bool mInitialized; // at 0x24 + int mVoiceCount; // at 0x28 +}; + +} // namespace detail +} // namespace snd +} // namespace nw4r + +#endif diff --git a/include/nw4r/snd/snd_AxfxImpl.h b/include/nw4r/snd/snd_AxfxImpl.h new file mode 100644 index 00000000..751d6210 --- /dev/null +++ b/include/nw4r/snd/snd_AxfxImpl.h @@ -0,0 +1,42 @@ +#ifndef NW4R_SND_AXFX_IMPL_H +#define NW4R_SND_AXFX_IMPL_H +#include +#include +#include + +namespace nw4r { +namespace snd { +namespace detail { + +struct AxfxImpl { + static void *Alloc(u32 size); + static void Free(void *block); + + AxfxImpl() : mIsActive(false), mHeap(NULL), mAllocCount(0) {} + + u32 GetHeapTotalSize() { + if (mHeap == NULL) { + return 0; + } + + return MEMGetHeapTotalSize(mHeap); + } + + bool CreateHeap(void *buffer, u32 size); + void DestroyHeap(); + void HookAlloc(AXFXAllocHook *allocHook, AXFXFreeHook *freeHook); + void RestoreAlloc(AXFXAllocHook allocHook, AXFXFreeHook freeHook); + + bool mIsActive; // at 0x0 + MEMiHeapHead *mHeap; // at 0x4 + u32 mAllocCount; // at 0x8 + + static AxfxImpl *mCurrentFx; + static u32 mAllocatedSize; +}; + +} // namespace detail +} // namespace snd +} // namespace nw4r + +#endif diff --git a/include/nw4r/snd/snd_Bank.h b/include/nw4r/snd/snd_Bank.h new file mode 100644 index 00000000..8b6e7d4d --- /dev/null +++ b/include/nw4r/snd/snd_Bank.h @@ -0,0 +1,26 @@ +#ifndef NW4R_SND_BANK_H +#define NW4R_SND_BANK_H +#include "snd_BankFile.h" +#include "snd_Channel.h" +#include "snd_NoteOn.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct Bank + { + Bank(const void *); + ~Bank(); + Channel * NoteOn(const NoteOnInfo &) const; + + BankFileReader mFileReader; // at 0x0 + const UNKTYPE * PTR_0xC; + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_BankFile.h b/include/nw4r/snd/snd_BankFile.h new file mode 100644 index 00000000..9286704f --- /dev/null +++ b/include/nw4r/snd/snd_BankFile.h @@ -0,0 +1,102 @@ +#ifndef NW4R_SND_BANK_FILE_H +#define NW4R_SND_BANK_FILE_H +#include "types_nw4r.h" +#include "ut_binaryFileFormat.h" +#include "ut_algorithm.h" +#include "snd_Util.h" +#include "snd_WaveFile.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct InstInfo + { + int WORD_0x0; + u8 mAttack; // at 0x4 + u8 mDecay; // at 0x5 + u8 mSustain; // at 0x6 + u8 mRelease; // at 0x7 + + u8 BYTE_0x8; + u8 BYTE_0x9; + u8 BYTE_0xA; + float FLOAT_0xC; + }; + + struct BankFile + { + struct InstParam + { + int WORD_0x0; + u8 mAttack; // at 0x4 + u8 mDecay; // at 0x5 + u8 mSustain; // at 0x6 + u8 mRelease; // at 0x7 + + char UNK_0x8[0x4]; + + char BYTE_0xC; + u8 BYTE_0xD; + char BYTE_0xE; + float FLOAT_0x10; + }; + + struct RangeTable + { + u8 BYTE_0x0; + u8 BYTES_0x1[]; + }; + + struct IndexTable + { + u8 BYTE_0x0; + u8 BYTE_0x1; + }; + + ut::BinaryFileHeader mHeader; // at 0x0 + u32 OFFSET_0x10; + char UNK_0x14[0x4]; + u32 OFFSET_0x18; + + typedef Util::DataRef Region; + }; + + struct BankFileReader + { + struct UNKBLOCK_DATA + { + ut::BinaryBlockHeader mHeader; // at 0x0 + int INT_0x8; + BankFile::Region ARR_0xC[]; + }; + + struct UNKBLOCK_WAVE + { + ut::BinaryBlockHeader mHeader; // at 0x0 + u32 INT_0x8; + WaveFile::Region ARR_0xC[]; + }; + + bool IsValidFileHeader(const void *); + BankFileReader(const void *); + bool ReadInstInfo(InstInfo *, int, int, int) const; + const BankFile::Region * GetReferenceToSubRegion(const BankFile::Region *, int) const; + bool ReadWaveParam(WaveData *, int, const void *) const; + + const BankFile * mFile; // at 0x0 + const UNKBLOCK_DATA * PTR_0x4; + const UNKBLOCK_WAVE * PTR_0x8; + }; + + inline u8 ReadByte(const void * ptr) + { + return *static_cast(ptr); + } + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_BasicPlayer.h b/include/nw4r/snd/snd_BasicPlayer.h new file mode 100644 index 00000000..968a50d9 --- /dev/null +++ b/include/nw4r/snd/snd_BasicPlayer.h @@ -0,0 +1,147 @@ +#ifndef NW4R_SND_BASIC_PLAYER_H +#define NW4R_SND_BASIC_PLAYER_H +#include +#include +#include + +namespace nw4r { +namespace snd { +namespace detail { + +class BasicPlayer { +public: + BasicPlayer(); + virtual ~BasicPlayer() {} // at 0x8 + + virtual bool Start() = 0; // at 0xC + virtual void Stop() = 0; // at 0x10 + virtual void Pause(bool flag) = 0; // at 0x14 + virtual bool IsActive() const = 0; // at 0x18 + virtual bool IsStarted() const = 0; // at 0x1C + virtual bool IsPause() const = 0; // at 0x20 + + void InitParam(); + + u32 GetId() const { + return mId; + } + void SetId(u32 id) { + mId = id; + } + + f32 GetVolume() const { + return mVolume; + } + void SetVolume(f32 volume) { + mVolume = volume; + } + + f32 GetPitch() const { + return mPitch; + } + void SetPitch(f32 pitch) { + mPitch = pitch; + } + + f32 GetPan() const { + return mPan; + } + void SetPan(f32 pan) { + mPan = pan; + } + + f32 GetSurroundPan() const { + return mSurroundPan; + } + void SetSurroundPan(f32 pan) { + mSurroundPan = pan; + } + + f32 GetLpfFreq() const { + return mLpfFreq; + } + void SetLpfFreq(f32 freq) { + mLpfFreq = freq; + } + + int GetOutputLine() const { + return mOutputLine; + } + void SetOutputLine(int flags) { + mOutputLine = flags; + } + + f32 GetMainOutVolume() const { + return mMainOutVolume; + } + void SetMainOutVolume(f32 volume) { + mMainOutVolume = volume; + } + + f32 GetMainSend() const { + return mMainSend; + } + void SetMainSend(f32 send) { + mMainSend = send; + } + + void SetFxSend(AuxBus bus, f32 send); + f32 GetFxSend(AuxBus bus) const; + + void SetRemoteOutVolume(int remote, f32 vol); + f32 GetRemoteOutVolume(int remote) const; + + f32 GetRemoteSend(int remote) const; + + f32 GetRemoteFxSend(int remote) const; + + int GetRemoteFilter() const { + return mRemoteFilter; + } + void SetRemoteFilter(int filter) { + mRemoteFilter = ut::Clamp(filter, FILTER_MIN, FILTER_MAX); + } + + PanMode GetPanMode() const { + return mPanMode; + } + void SetPanMode(PanMode mode) { + mPanMode = mode; + } + + PanCurve GetPanCurve() const { + return mPanCurve; + } + void SetPanCurve(PanCurve curve) { + mPanCurve = curve; + } + +public: + static const int FILTER_MIN = 0; + static const int FILTER_MAX = 127; + +private: + u32 mId; // at 0x4 + f32 mVolume; // at 0x8 + f32 mPitch; // at 0xC + f32 mPan; // at 0x10 + f32 mSurroundPan; // at 0x14 + f32 mLpfFreq; // at 0x18 + char UNK_0x1C[0x4]; + int mOutputLine; // at 0x20 + f32 mMainOutVolume; // at 0x24 + f32 mMainSend; // at 0x28 + f32 mFxSend[AUX_BUS_NUM]; // at 0x2C + f32 mRemoteOutVolume[WPAD_MAX_CONTROLLERS]; // at 0x38 + f32 mRemoteSend[WPAD_MAX_CONTROLLERS]; // at 0x48 + f32 mRemoteFxSend[WPAD_MAX_CONTROLLERS]; // at 0x58 + u8 mRemoteFilter; // at 0x68 + PanMode mPanMode; // at 0x6C + PanCurve mPanCurve; // at 0x70 +}; + +} // namespace detail +} // namespace snd +} // namespace nw4r + +#endif diff --git a/include/nw4r/snd/snd_BasicSound.h b/include/nw4r/snd/snd_BasicSound.h new file mode 100644 index 00000000..59cae0be --- /dev/null +++ b/include/nw4r/snd/snd_BasicSound.h @@ -0,0 +1,206 @@ +#ifndef NW4R_SND_BASIC_SOUND_H +#define NW4R_SND_BASIC_SOUND_H +#include +#include +#include +#include +#include + +namespace nw4r { +namespace snd { +namespace detail { + +class BasicSound { + friend class SoundHandle; + +public: + NW4R_UT_RTTI_DECL(BasicSound); + + struct AmbientParamUpdateCallback { + virtual void detail_Update(SoundParam *param, u32 id, BasicSound *sound, const void *arg, u32 flags) = 0; + }; + + struct AmbientArgUpdateCallback { + virtual void detail_Update(void *arg, const BasicSound *sound) = 0; + }; + + struct AmbientArgAllocaterCallback { + virtual void *detail_AllocAmbientArg(u32 size) = 0; + virtual void detail_FreeAmbientArg(void *arg, const BasicSound *sound) = 0; + }; + + struct AmbientArgInfo { + AmbientParamUpdateCallback *mParamUpdateCallback; // at 0x0 + AmbientArgUpdateCallback *mArgUpdateCallback; // at 0x4 + AmbientArgAllocaterCallback *mArgAllocaterCallback; // at 0x8 + void *arg; // at 0xC + u32 argSize; // at 0x10 + }; + +public: + BasicSound(); + virtual ~BasicSound() {} // at 0xC + + virtual void Update(); // at 0x10 + virtual void StartPrepared(); // at 0x14 + virtual void Stop(int frames); // at 0x18 + virtual void Pause(bool flag, int frames); // at 0x1C + virtual void SetAutoStopCounter(int count); // at 0x20 + virtual void FadeIn(int frames); // at 0x24 + virtual void Shutdown(); // at 0x28 + virtual bool IsPrepared() const = 0; // at 0x2C + virtual bool IsPause() const; // at 0x30 + + virtual void SetInitialVolume(f32 vol); // at 0x34 + virtual void SetVolume(f32 vol, int frames); // at 0x38 + virtual void SetPitch(f32 pitch); // at 0x3C + virtual void SetPan(f32 pan); // at 0x40 + virtual void SetSurroundPan(f32 pan); // at 0x44 + virtual void SetLpfFreq(f32 freq); // at 0x48 + virtual void SetPlayerPriority(int prio); // at 0x4C + virtual void SetRemoteFilter(int filter); // at 0x50 + virtual void SetPanMode(PanMode mode); // at 0x54 + virtual void SetPanCurve(PanCurve curve); // at 0x58 + virtual bool IsAttachedTempSpecialHandle() = 0; // at 0x5C + virtual void DetachTempSpecialHandle() = 0; // at 0x60 + virtual void InitParam(); // at 0x64 + virtual BasicPlayer *GetBasicPlayer() = 0; // at 0x68 + virtual const BasicPlayer *GetBasicPlayer() const = 0; // at 0x6C + + PlayerHeap *GetPlayerHeap() { + return mPlayerHeap; + } + void SetPlayerHeap(PlayerHeap *heap) { + mPlayerHeap = heap; + } + + bool IsAttachedGeneralHandle(); + void DetachGeneralHandle(); + + bool IsAttachedTempGeneralHandle(); + void DetachTempGeneralHandle(); + + SoundPlayer *GetSoundPlayer() { + return mSoundPlayer; + } + void SetSoundPlayer(SoundPlayer *player) { + mSoundPlayer = player; + } + + ExternalSoundPlayer *GetExternalSoundPlayer() { + return mExtSoundPlayer; + } + void SetExternalSoundPlayer(ExternalSoundPlayer *player) { + mExtSoundPlayer = player; + } + + AmbientParamUpdateCallback *GetAmbientParamUpdateCallback() { + return mParamUpdateCallback; + } + + AmbientArgUpdateCallback *GetAmbientArgUpdateCallback() { + return mArgUpdateCallback; + } + void ClearAmbientArgUpdateCallback() { + mArgUpdateCallback = NULL; + } + + AmbientArgAllocaterCallback *GetAmbientArgAllocaterCallback() { + return mArgAllocCallback; + } + + void *GetAmbientArg() { + return mCallbackArg; + } + + SoundParam &GetAmbientParam() { + return mAmbientParam; + } + + void SetAmbientParamCallback(AmbientParamUpdateCallback *paramUpdate, AmbientArgUpdateCallback *argUpdate, + AmbientArgAllocaterCallback *argAlloc, void *arg); + + u32 GetId() const { + return mId; + } + void SetId(u32 id); + + f32 GetMoveVolume() { + return mExtVolume.GetValue(); + } + + f32 GetInitialVolume() const; + f32 GetPan() const; + f32 GetSurroundPan() const; + f32 GetPitch() const; + + void SetOutputLine(int flag); + bool IsEnabledOutputLine() const; + int GetOutputLine() const; + + f32 GetMainOutVolume() const; + void SetMainOutVolume(f32 vol); + + f32 GetRemoteOutVolume(int remote) const; + void SetRemoteOutVolume(int remote, f32 vol); + + void SetFxSend(AuxBus bus, f32 send); + + int CalcCurrentPlayerPriority() const { + return ut::Clamp(mPriority + mAmbientParam.priority, PRIORITY_MIN, PRIORITY_MAX); + } + +public: + static const int PRIORITY_MIN = 0; + static const int PRIORITY_MAX = 127; + +private: + PlayerHeap *mPlayerHeap; // at 0x4 + SoundHandle *mGeneralHandle; // at 0x8 + SoundHandle *mTempGeneralHandle; // at 0xC + SoundPlayer *mSoundPlayer; // at 0x10 + ExternalSoundPlayer *mExtSoundPlayer; // at 0x14 + AmbientParamUpdateCallback *mParamUpdateCallback; // at 0x18 + AmbientArgUpdateCallback *mArgUpdateCallback; // at 0x1C + AmbientArgAllocaterCallback *mArgAllocCallback; // at 0x20 + void *mCallbackArg; // at 0x24 + SoundParam mAmbientParam; // at 0x28 + MoveValue mFadeVolume; // at 0x44 + MoveValue mPauseFadeVolume; // at 0x54 + bool mIsStarting; // at 0x64 + bool mIsStarted; // at 0x65 + bool mIsAutoStop; // at 0x66 + bool mIsPause; // at 0x67 + bool mIsPauseFade; // at 0x68 + bool mIsFadeOut; // at 0x69 + int mAutoStopCounter; // at 0x6C + u32 mUpdateCounter; // at 0x70 + u8 mPriority; // at 0x74 + u32 mId; // at 0x78 + MoveValue mExtVolume; // at 0x7C + f32 mInitVolume; // at 0x8C + f32 mExtPan; // at 0x90 + f32 mExtSurroundPan; // at 0x94 + f32 mExtPitch; // at 0x98 + bool mEnableOutputLine; // at 0x9C + int mOutputLine; // at 0xA0 + f32 mMainOutVolume; // at 0xA4 + f32 mRemoteOutVolumes[WPAD_MAX_CONTROLLERS]; // at 0xA8 + +public: + NW4R_UT_LIST_NODE_DECL_EX(Prio); // at 0xB8 + NW4R_UT_LIST_NODE_DECL_EX(PlayerPlay); // at 0xC0 + NW4R_UT_LIST_NODE_DECL_EX(PlayerPrio); // at 0xC8 + NW4R_UT_LIST_NODE_DECL_EX(ExtPlay); // at 0xD0 +}; + +NW4R_UT_LIST_TYPEDEF_DECL_EX(BasicSound, Prio); +NW4R_UT_LIST_TYPEDEF_DECL_EX(BasicSound, PlayerPlay); +NW4R_UT_LIST_TYPEDEF_DECL_EX(BasicSound, PlayerPrio); +NW4R_UT_LIST_TYPEDEF_DECL_EX(BasicSound, ExtPlay); + +} // namespace detail +} // namespace snd +} // namespace nw4r + +#endif diff --git a/include/nw4r/snd/snd_Channel.h b/include/nw4r/snd/snd_Channel.h new file mode 100644 index 00000000..47fc74b2 --- /dev/null +++ b/include/nw4r/snd/snd_Channel.h @@ -0,0 +1,161 @@ +#ifndef NW4R_SND_CHANNEL_H +#define NW4R_SND_CHANNEL_H +#include "types_nw4r.h" +#include "ut_LinkList.h" +#include "snd_Voice.h" +#include "snd_Lfo.h" +#include "snd_InstancePool.h" +#include "snd_WaveFile.h" +#include "snd_EnvGenerator.h" +#include "snd_MoveValue.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct Channel + { + enum ChannelCallbackStatus + { + CALLBACK_STATUS_0, + CALLBACK_STATUS_1, + CALLBACK_STATUS_2, + CALLBACK_STATUS_3 + }; + + typedef void (* ChannelCallback)(Channel *, ChannelCallbackStatus, u32); + + static void VoiceCallbackFunc(Voice *, Voice::VoiceCallbackStatus, void *); + + static Channel * AllocChannel(int, int, int, ChannelCallback, u32); + static void FreeChannel(Channel *); + Channel(); + + UNKTYPE InitParam(ChannelCallback, u32); + void Update(bool); + UNKTYPE Start(const WaveData &, int, u32); + UNKTYPE Release(); + UNKTYPE Stop(); + + float GetSweepValue() const; + void UpdateSweep(int); + void SetSweepParam(float, int, bool); + + EnvGenerator mEnvGenerator; // at 0x0 + Lfo mLfo; // at 0x18 + u8 BYTE_0x30; + bool mPauseFlag; // at 0x31 + bool mActiveFlag; // at 0x32 + bool BOOL_0x33; + bool mAutoUpdateSweepFlag; // at 0x34 + bool mReleasePriorityFixFlag; // at 0x35 + + float FLOAT_0x38; + float FLOAT_0x3C; + float FLOAT_0x40; + float FLOAT_0x44; + float FLOAT_0x48; + + int mRemoteFilter; // at 0x4c + int mOutputLine; // at 0x50 + + float FLOAT_0x54; + float FLOAT_0x58; + + float ARR_0x5C[3]; + + float mRemoteOutVolumes[4]; // at 0x68 + float ARR_0x78[4]; + float ARR_0x88[4]; + + float FLOAT_0x98; + float FLOAT_0x9C; + + int INT_0xA0; + int INT_0xA4; + + float FLOAT_0xA8; + float FLOAT_0xAC; + float FLOAT_0xB0; + float FLOAT_0xB4; + MoveValue MV_0xB8; + UNKWORD INT_0xC0; + UNKWORD INT_0xC4; + int mLength; // at 0xc8 + + PanMode mPanMode; // at 0xcc + PanCurve mPanCurve; // at 0xd0 + + ChannelCallback mCallback; // at 0xd4 + u32 INT_0xD8; + Voice * mVoice; // at 0xdc + Channel * mNext; // at 0xe0 + ut::LinkListNode mNode; // at 0xe4 + + inline bool IsActive() const + { + return mActiveFlag; + } + + inline void SetRelease(int release) + { + if (release >= 0) mEnvGenerator.SetRelease(release); + + Release(); + } + + inline bool IsAutoUpdateSweep() const + { + return mAutoUpdateSweepFlag; + } + + inline bool IsPause() const + { + return mPauseFlag; + } + + inline void Pause(bool flag) + { + mPauseFlag = flag; + + mVoice->Pause(flag); + } + + inline void SetLfoParam(const LfoParam & lfoParam) + { + mLfo.SetParam(lfoParam); + } + + inline void SetSilence(bool silentFlag, int time) + { + MV_0xB8.SetTarget(silentFlag ? 0 : 0xFF, time); + } + }; + + struct ChannelManager + { + ChannelManager(); + + u32 GetRequiredMemSize(); + void Setup(void *, u32); + void Shutdown(); + UNKTYPE UpdateAllChannel(); + static void Free(Channel *); //inlined + Channel * Alloc(); // inlined + static ChannelManager * GetInstance(); + + InstancePool mPool; // at 0x0 + ut::LinkList mList; // at 0x4 + + bool BOOL_0x10; + u32 INT_0x14; + UNKTYPE * PTR_0x18; + u32 INT_0x1C; + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_ChannelManager.h b/include/nw4r/snd/snd_ChannelManager.h new file mode 100644 index 00000000..2b9fca7e --- /dev/null +++ b/include/nw4r/snd/snd_ChannelManager.h @@ -0,0 +1,21 @@ +#ifndef NW4R_SND_CHANNEL_MANAGER_H +#define NW4R_SND_CHANNEL_MANAGER_H +#include "types_nw4r.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct ChannelManager + { + static ChannelManager * GetInstance(); + + void UpdateAllChannel(); + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_Common.h b/include/nw4r/snd/snd_Common.h new file mode 100644 index 00000000..9bf11875 --- /dev/null +++ b/include/nw4r/snd/snd_Common.h @@ -0,0 +1,63 @@ +#ifndef NW4R_SND_COMMON_H +#define NW4R_SND_COMMON_H +#include + +namespace nw4r { +namespace snd { + +enum AuxBus { AUX_A, AUX_B, AUX_C, AUX_BUS_NUM }; + +enum OutputMode { + OUTPUT_MODE_STEREO, + OUTPUT_MODE_SURROUND, + OUTPUT_MODE_DPL2, + OUTPUT_MODE_MONO +}; + +struct SoundParam { + f32 volume; // at 0x0 + f32 pitch; // at 0x4 + f32 pan; // at 0x8 + f32 surroundPan; // at 0xC + f32 fxSend; // at 0x10 + f32 lpf; // at 0x14 + int priority; // at 0x18 +}; + +namespace detail { + +enum PanMode { + PAN_MODE_DUAL, + PAN_MODE_BALANCE, +}; +enum PanCurve { + PAN_CURVE_SQRT, + PAN_CURVE_SQRT_0DB, + PAN_CURVE_SQRT_0DB_CLAMP, + PAN_CURVE_SINCOS, + PAN_CURVE_SINCOS_0DB, + PAN_CURVE_SINCOS_0DB_CLAMP, + PAN_CURVE_LINEAR, + PAN_CURVE_LINEAR_0DB, + PAN_CURVE_LINEAR_0DB_CLAMP, +}; + +struct AdpcmParam { + u16 coef[16]; // at 0x0 + u16 gain; // at 0x20 + u16 pred_scale; // at 0x22 + u16 yn1; // at 0x24 + u16 yn2; // at 0x26 +}; + +struct AdpcmLoopParam { + u16 loop_pred_scale; // at 0x0 + u16 loop_yn1; // at 0x2 + u16 loop_yn2; // at 0x4 +}; + +} // namespace detail +} // namespace snd +} // namespace nw4r + +#endif diff --git a/include/nw4r/snd/snd_DisposeCallback.h b/include/nw4r/snd/snd_DisposeCallback.h new file mode 100644 index 00000000..b76bfeed --- /dev/null +++ b/include/nw4r/snd/snd_DisposeCallback.h @@ -0,0 +1,24 @@ +#ifndef NW4R_SND_DISPOSE_CALLBACK_H +#define NW4R_SND_DISPOSE_CALLBACK_H +#include "types_nw4r.h" +#include "ut_LinkList.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct DisposeCallback + { + ut::LinkListNode mNode; // at 0x0 + + inline virtual ~DisposeCallback() {} // at 0x8 + virtual void InvalidateData(const void *, const void *) = 0; // at 0xc + virtual void InvalidateWaveData(const void *, const void *) = 0; // at 0x10 + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_DisposeCallbackManager.h b/include/nw4r/snd/snd_DisposeCallbackManager.h new file mode 100644 index 00000000..16c0a67e --- /dev/null +++ b/include/nw4r/snd/snd_DisposeCallbackManager.h @@ -0,0 +1,29 @@ +#ifndef NW4R_SND_DISPOSE_CALLBACK_MANAGER_H +#define NW4R_SND_DISPOSE_CALLBACK_MANAGER_H +#include "types_nw4r.h" +#include "snd_DisposeCallback.h" +#include "ut_LinkList.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct DisposeCallbackManager + { + static DisposeCallbackManager * GetInstance(); + + ut::LinkList mList; // at 0x0 + + UNKTYPE RegisterDisposeCallback(DisposeCallback *); + UNKTYPE UnregisterDisposeCallback(DisposeCallback *); + + UNKTYPE Dispose(void *, u32, void *); + UNKTYPE DisposeWave(void *, u32, void *); + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_DvdSoundArchive.h b/include/nw4r/snd/snd_DvdSoundArchive.h new file mode 100644 index 00000000..257b026b --- /dev/null +++ b/include/nw4r/snd/snd_DvdSoundArchive.h @@ -0,0 +1,41 @@ +#ifndef NW4R_SND_DVD_SOUND_ARCHIVE_H +#define NW4R_SND_DVD_SOUND_ARCHIVE_H +#include +#include "ut_DvdLockedFileStream.h" +#include "snd_SoundArchive.h" +#include "snd_SoundArchiveFile.h" + +namespace nw4r +{ + namespace snd + { + struct DvdSoundArchive : SoundArchive + { + struct DvdFileStream; + + detail::SoundArchiveFileReader mFileReader; // at 0x108 + DVDFileInfo mFileInfo; // at 0x14c + bool mOpenFlag; // at 0x188 + + DvdSoundArchive(); + + virtual ~DvdSoundArchive(); // at 0x8 + virtual const void * detail_GetFileAddress(u32) const; // at 0xC + virtual const void * detail_GetWaveDataFileAddress(u32) const; // at 0x10 + virtual int detail_GetRequiredStreamBufferSize() const; // at 0x14 + virtual ut::FileStream * OpenStream(void *, int, u32, u32) const; // at 0x18 + virtual ut::FileStream * OpenExtStream(void *, int, const char *, u32, u32) const; // at 0x1c + + bool Open(s32); //inlined + bool Open(const char *); + + void Close(); + + bool LoadFileHeader(); //inlined + bool LoadHeader(void *, u32); + bool LoadLabelStringData(void *, u32); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_EnvGenerator.h b/include/nw4r/snd/snd_EnvGenerator.h new file mode 100644 index 00000000..a102ef96 --- /dev/null +++ b/include/nw4r/snd/snd_EnvGenerator.h @@ -0,0 +1,48 @@ +#ifndef NW4R_SND_ENV_GENERATOR_H +#define NW4R_SND_ENV_GENERATOR_H +#include + +namespace nw4r { +namespace snd { +namespace detail { + +class EnvGenerator { +public: + enum Status { STATUS_ATTACK, STATUS_DECAY, STATUS_SUSTAIN, STATUS_RELEASE }; + +public: + EnvGenerator(); + + void Init(f32 db); + void Reset(f32 db); + f32 GetValue() const; + void Update(int msec); + + Status GetStatus() const { return mStatus; } + void SetStatus(Status status) { mStatus = status; } + + void SetAttack(int attack); + void SetDecay(int decay); + void SetSustain(int sustain); + void SetRelease(int release); + + f32 CalcRelease(int release); + int CalcDecibelSquare(int scale); + +private: + static const volatile f32 VOLUME_INIT; + static const s16 DecibelSquareTable[128]; + + Status mStatus; // at 0x0 + f32 mValue; // at 0x4 + f32 mDecay; // at 0x8 + f32 mRelease; // at 0xC + f32 mAttack; // at 0x10 + u8 mSustain; // at 0x14 +}; + +} // namespace detail +} // namespace snd +} // namespace nw4r + +#endif diff --git a/include/nw4r/snd/snd_ExternalSoundPlayer.h b/include/nw4r/snd/snd_ExternalSoundPlayer.h new file mode 100644 index 00000000..b3a288ca --- /dev/null +++ b/include/nw4r/snd/snd_ExternalSoundPlayer.h @@ -0,0 +1,68 @@ +#ifndef NW4R_SND_EXTERNAL_SOUND_PLAYER_H +#define NW4R_SND_EXTERNAL_SOUND_PLAYER_H +#include +#include + +namespace nw4r { +namespace snd { +namespace detail { + +class ExternalSoundPlayer { +public: + ExternalSoundPlayer(); + ~ExternalSoundPlayer(); + + int GetPlayableSoundCount() const { return mPlayableSoundCount; } + void SetPlayableSoundCount(int count); + + int GetPlayingSoundCount() const { return mSoundList.GetSize(); } + + f32 detail_GetVolume() const { return mVolume; } + BasicSound* GetLowestPrioritySound(); + + void InsertSoundList(BasicSound* sound); + void RemoveSoundList(BasicSound* sound); + + template + TForEachFunc ForEachSound(TForEachFunc func, bool reverse) { + if (reverse) { + BasicSoundExtPlayList::RevIterator it = + mSoundList.GetBeginReverseIter(); + + while (it != mSoundList.GetEndReverseIter()) { + BasicSoundExtPlayList::RevIterator curr = it; + + SoundHandle handle; + handle.detail_AttachSoundAsTempHandle(&*curr); + func(handle); + + if (handle.IsAttachedSound()) { + ++it; + } + } + } else { + BasicSoundExtPlayList::Iterator it = mSoundList.GetBeginIter(); + + while (it != mSoundList.GetEndIter()) { + BasicSoundExtPlayList::Iterator curr = it++; + + SoundHandle handle; + handle.detail_AttachSoundAsTempHandle(&*curr); + func(handle); + } + } + + return func; + } + +private: + BasicSoundExtPlayList mSoundList; // at 0x0 + u16 mPlayableSoundCount; // at 0xC + f32 mVolume; // at 0x10 +}; + +} // namespace detail +} // namespace snd +} // namespace nw4r + +#endif diff --git a/include/nw4r/snd/snd_FrameHeap.h b/include/nw4r/snd/snd_FrameHeap.h new file mode 100644 index 00000000..dec66053 --- /dev/null +++ b/include/nw4r/snd/snd_FrameHeap.h @@ -0,0 +1,90 @@ +#ifndef NW4R_SND_FRAME_HEAP_H +#define NW4R_SND_FRAME_HEAP_H +#include "types_nw4r.h" +#include "ut_LinkList.h" +#include "ut_algorithm.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct FrameHeap + { + typedef void (* AllocCallback)(void *, u32, void *); + + struct Block + { + ut::LinkListNode mNode; // at 0x0 + u32 mSize; // at 0x8 + AllocCallback mCallback; // at 0xc + void * PTR_0x10; + + inline Block(u32 size, AllocCallback callback, void * ptr) + : + mSize(size), + mCallback(callback), + PTR_0x10(ptr) + {} + + inline void * GetBufferAddr() + { + return reinterpret_cast(this) + ut::RoundUp(sizeof(Block), 0x20); + } + + inline ~Block() + { + if (mCallback) mCallback(PTR_0x10, mSize, GetBufferAddr()); + } + }; + + struct Section + { + ut::LinkListNode mNode; // at 0x0 + ut::LinkList mList; // at 0x8 + + inline void AppendBlock(Block * pBlock) + { + mList.PushBack(pBlock); + } + + inline ~Section() + { + ut::LinkList::Iterator iter = mList.GetEndIter(); + + while (iter != mList.GetBeginIter()) + { + (--iter)->~Block(); + } + } + }; + + bool NewSection(); //inlined + UNKTYPE ClearSection(); //inlined + + FrameHeap(); + ~FrameHeap(); + + bool Create(void *, u32); + UNKTYPE Destroy(); + void Clear(); + void * Alloc(u32, AllocCallback, void *); + int SaveState(); + void LoadState(int); + int GetCurrentLevel() const; + u32 GetFreeSize() const; + + UNKTYPE * PTR_0x0; + ut::LinkList mList; // at 0x4 + + inline bool IsValid() const + { + return mList.GetSize(); + } + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_FxBase.h b/include/nw4r/snd/snd_FxBase.h new file mode 100644 index 00000000..d8a0725b --- /dev/null +++ b/include/nw4r/snd/snd_FxBase.h @@ -0,0 +1,33 @@ +#ifndef NW4R_SND_FX_BASE_H +#define NW4R_SND_FX_BASE_H +#include "types_nw4r.h" +#include "snd_Common.h" +#include "ut_LinkList.h" + +namespace nw4r +{ + namespace snd + { + enum SampleFormat + { + SAMPLE_FORMAT_PCM_S32, + SAMPLE_FORMAT_PCM_S16, + SAMPLE_FORMAT_PCM_S8, + SAMPLE_FORMAT_DSP_ADPCM + }; + + struct FxBase + { + inline virtual ~FxBase() {} // at 0x8 + inline virtual bool StartUp() {} // at 0xc + inline virtual UNKTYPE Shutdown() {} // at 0x10 + inline virtual UNKTYPE UpdateBuffer(int, void **, u32, SampleFormat, float, OutputMode) {} // at 0x14 + + NW4R_UT_LIST_NODE_DECL(); // at 0x4 + }; + + NW4R_UT_LIST_TYPEDEF_DECL(FxBase); + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_FxChorus.h b/include/nw4r/snd/snd_FxChorus.h new file mode 100644 index 00000000..77af4857 --- /dev/null +++ b/include/nw4r/snd/snd_FxChorus.h @@ -0,0 +1,47 @@ +#ifndef NW4R_SND_FX_CHORUS_H +#define NW4R_SND_FX_CHORUS_H +#include +#include "types_nw4r.h" +#include "snd_FxBase.h" +#include "snd_AxfxImpl.h" + +namespace nw4r +{ + namespace snd + { + struct FxChorus : FxBase + { + //sizeof(ChorusParam) = 0xc + struct ChorusParam + { + float FLOAT_0x0; + float FLOAT_0x4; + float FLOAT_0x8; + }; + + FxChorus(); + + inline ~FxChorus() + { + Shutdown(); + ReleaseWorkBuffer(); + } + + u32 GetRequiredMemSize(); + virtual UNKTYPE AssignWorkBuffer(void *, u32); // at 0x18 + virtual UNKTYPE ReleaseWorkBuffer(); // at 0x1c + + bool StartUp(); // at 0xc + UNKTYPE Shutdown(); // at 0x10 + bool SetParam(const ChorusParam &); + UNKTYPE UpdateBuffer(int, void **, u32, SampleFormat, float, OutputMode); // at 0x14 + + detail::AxfxImpl mAxfxImpl; + + ChorusParam mParam; // at 0x18 + AXFX_CHORUS mAXFXChorus; // 0x24 + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_FxDelay.h b/include/nw4r/snd/snd_FxDelay.h new file mode 100644 index 00000000..a054c39b --- /dev/null +++ b/include/nw4r/snd/snd_FxDelay.h @@ -0,0 +1,47 @@ +#ifndef NW4R_SND_FX_DELAY_H +#define NW4R_SND_FX_DELAY_H +#include +#include "snd_FxBase.h" +#include "snd_AxfxImpl.h" +#include "types_nw4r.h" + +namespace nw4r +{ + namespace snd + { + struct FxDelay : FxBase + { + //sizeof(FxDelayParam) = 0xc + struct DelayParam + { + float FLOAT_0x0; + float FLOAT_0x4; + float FLOAT_0x8; + }; + + FxDelay(); + + inline ~FxDelay() + { + Shutdown(); + ReleaseWorkBuffer(); + } + + u32 GetRequiredMemSize(); + virtual UNKTYPE AssignWorkBuffer(void *, u32); // at 0x18 + virtual UNKTYPE ReleaseWorkBuffer(); // at 0x1c + + bool StartUp(); // at 0xc + UNKTYPE Shutdown(); // at 0x10 + bool SetParam(const DelayParam &); + UNKTYPE UpdateBuffer(int, void **, u32, SampleFormat, float, OutputMode); // at 0x14 + + detail::AxfxImpl mAxfxImpl; // at 0xc + DelayParam mParam; // at 0x18 + + AXFX_DELAY mAXFXDelay; // at 0x24 + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_FxReverbHi.h b/include/nw4r/snd/snd_FxReverbHi.h new file mode 100644 index 00000000..2b472d05 --- /dev/null +++ b/include/nw4r/snd/snd_FxReverbHi.h @@ -0,0 +1,50 @@ +#ifndef NW4R_SND_FX_REVERB_HI_H +#define NW4R_SND_FX_REVERB_HI_H +#include +#include "snd_FxBase.h" +#include "snd_AxfxImpl.h" +#include "types_nw4r.h" + +namespace nw4r +{ + namespace snd + { + struct FxReverbHi : FxBase + { + //sizeof(ReverbHiParam) = 0x18 + struct ReverbHiParam + { + float FLOAT_0x0; + float FLOAT_0x4; + float FLOAT_0x8; + float FLOAT_0xC; + float FLOAT_0x10; + float FLOAT_0x14; + }; + + FxReverbHi(); + + inline ~FxReverbHi() + { + Shutdown(); + ReleaseWorkBuffer(); + } + + u32 GetRequiredMemSize(); + virtual UNKTYPE AssignWorkBuffer(void *, u32); // at 0x18 + virtual UNKTYPE ReleaseWorkBuffer(); // at 0x1c + + bool StartUp(); // at 0xc + UNKTYPE Shutdown(); // at 0x10 + bool SetParam(const ReverbHiParam &); + UNKTYPE UpdateBuffer(int, void **, u32, SampleFormat, float, OutputMode); // at 0x14 + + detail::AxfxImpl mAxfxImpl; // at 0xc + ReverbHiParam mParam; // at 0x18 + + AXFX_REVERBHI mAXFXReverbHi; // at 0x30 + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_InstancePool.h b/include/nw4r/snd/snd_InstancePool.h new file mode 100644 index 00000000..ad630a98 --- /dev/null +++ b/include/nw4r/snd/snd_InstancePool.h @@ -0,0 +1,71 @@ +#ifndef NW4R_SND_INSTANCE_POOL_H +#define NW4R_SND_INSTANCE_POOL_H +#include "types_nw4r.h" +#include + + +namespace nw4r { +namespace snd { +namespace detail { +struct PoolImpl { + struct Member { + Member *mNext; // at 0x0 + }; + + u32 CreateImpl(void *, u32, u32); + void DestroyImpl(void *, u32); + u32 CountImpl() const; + void *AllocImpl(); + void FreeImpl(void *); + + Member mHead; // at 0x0 + + inline PoolImpl() { + mHead.mNext = NULL; + } +}; + +template +struct InstancePool : PoolImpl { + inline u32 Create(void *ptr, u32 num) { + return CreateImpl(ptr, num, sizeof(T)); + } + + inline T *Alloc() { + void *ptr = AllocImpl(); + + if (!ptr) { + return NULL; + } + + return new (ptr) T; + } + + inline void Free(T *ptr) { + if (ptr) { + ptr->~T(); + FreeImpl(ptr); + } + } + + inline void Destroy(void *ptr, u32 num) { + DestroyImpl(ptr, num); + } + + inline u32 Count() const { + return CountImpl(); + } +}; + +template +struct MemoryPool : PoolImpl { + inline void Free(T *ptr) { + ptr->~T(); + FreeImpl(ptr); + } +}; +} // namespace detail +} // namespace snd +} // namespace nw4r + +#endif diff --git a/include/nw4r/snd/snd_Lfo.h b/include/nw4r/snd/snd_Lfo.h new file mode 100644 index 00000000..88efbec8 --- /dev/null +++ b/include/nw4r/snd/snd_Lfo.h @@ -0,0 +1,43 @@ +#ifndef NW4R_SND_LFO_H +#define NW4R_SND_LFO_H +#include + +namespace nw4r { +namespace snd { +namespace detail { + +struct LfoParam { + LfoParam() { Init(); } + void Init(); + + f32 depth; // at 0x0 + f32 speed; // at 0x4 + u32 delay; // at 0x8 + u8 range; // at 0xC +}; + +class Lfo { +public: + static s8 GetSinIdx(int i); + + Lfo() : mDelayCounter(0), mCounter(0.0f) {} + + LfoParam& GetParam() { return mParam; } + void SetParam(const LfoParam& param) { mParam = param; } + + void Reset(); + void Update(int msec); + + f32 GetValue() const; + +private: + LfoParam mParam; // at 0x0 + u32 mDelayCounter; // at 0x10 + f32 mCounter; // at 0x14 +}; + +} // namespace detail +} // namespace snd +} // namespace nw4r + +#endif diff --git a/include/nw4r/snd/snd_MemorySoundArchive.h b/include/nw4r/snd/snd_MemorySoundArchive.h new file mode 100644 index 00000000..d850fe86 --- /dev/null +++ b/include/nw4r/snd/snd_MemorySoundArchive.h @@ -0,0 +1,33 @@ +#ifndef NW4R_SND_MEMORY_SOUND_ARCHIVE_H +#define NW4R_SND_MEMORY_SOUND_ARCHIVE_H +#include "ut_FileStream.h" +#include "snd_SoundArchive.h" +#include "snd_SoundArchiveFile.h" + +namespace nw4r +{ + namespace snd + { + struct MemorySoundArchive : SoundArchive + { + struct MemoryFileStream; + + const void * mMemory; // at 0x108 + detail::SoundArchiveFileReader mFileReader; // at 0x10c + + MemorySoundArchive(); + virtual ~MemorySoundArchive(); // at 0x8 + + bool Setup(const void *); + void Shutdown(); + + virtual const void * detail_GetFileAddress(u32) const; + virtual const void * detail_GetWaveDataFileAddress(u32) const; + virtual int detail_GetRequiredStreamBufferSize() const; + virtual ut::FileStream * OpenStream(void *, int, u32, u32) const; // at 0x18 + virtual ut::FileStream * OpenExtStream(void *, int, const char *, u32, u32) const; // at 0x1c + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_MmlParser.h b/include/nw4r/snd/snd_MmlParser.h new file mode 100644 index 00000000..54398397 --- /dev/null +++ b/include/nw4r/snd/snd_MmlParser.h @@ -0,0 +1,46 @@ +#ifndef NW4R_SND_MML_PARSER_H +#define NW4R_SND_MML_PARSER_H +#include "types_nw4r.h" +#include "snd_MmlSeqTrack.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct MmlParser + { + u16 Read16(const u8 **) const; //inlined + u32 Read24(const u8 **) const; //inlined + u32 ReadVar(const u8 **) const; //inlined + + volatile s16 * GetVariablePtr(SeqPlayer *, SeqTrack *, int) const; + + UNKWORD Parse(MmlSeqTrack *, bool) const; + virtual void CommandProc(MmlSeqTrack *, u32, s32, s32) const; // at 0x8 + virtual Channel * NoteOnCommandProc(MmlSeqTrack *, int, int, s32, bool) const; // at 0xc + + enum SeqArgType + { + SEQ_ARG_TYPE_IMMEDIATE_BYTE, + SEQ_ARG_TYPE_IMMEDIATE_16, + SEQ_ARG_TYPE_IMMEDIATE_VAR, + SEQ_ARG_TYPE_RANDOM, + SEQ_ARG_TYPE_VARIABLE + }; + + s32 ReadArg(const u8 **, SeqPlayer *, SeqTrack *, SeqArgType) const; + + inline u8 ReadByte(const u8 ** pPointer) const + { + return *(*pPointer)++; + } + + static bool mPrintVarEnabledFlag; + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_MmlSeqTrack.h b/include/nw4r/snd/snd_MmlSeqTrack.h new file mode 100644 index 00000000..a35646c7 --- /dev/null +++ b/include/nw4r/snd/snd_MmlSeqTrack.h @@ -0,0 +1,40 @@ +#ifndef NW4R_SND_MML_SEQ_TRACK_H +#define NW4R_SND_MML_SEQ_TRACK_H +#include "snd_SeqTrack.h" +#include "types_nw4r.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct MmlSeqTrack : SeqTrack + { + enum + { + STACK_FRAME_COUNT = 3 + }; + + struct MmlParserParam + { + bool mPredicate; // at 0x0 + bool BOOL_0x1; + bool BOOL_0x2; + u8 mLoopCounters[STACK_FRAME_COUNT]; // at 0x3 + u8 mStackIndex; // at 0x6 + const u8 * mReturnAddresses[STACK_FRAME_COUNT]; // at 0x8 + }; + + MmlParser * mParser; // at 0xc0 + MmlParserParam mMmlParserParam; // at 0xc4 + + MmlSeqTrack(); + + UNKWORD Parse(bool); // at 0xc + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_MmlSeqTrackAllocator.h b/include/nw4r/snd/snd_MmlSeqTrackAllocator.h new file mode 100644 index 00000000..b8d5750b --- /dev/null +++ b/include/nw4r/snd/snd_MmlSeqTrackAllocator.h @@ -0,0 +1,31 @@ +#ifndef NW4R_SND_MML_SEQ_TRACK_ALLOCATOR_H +#define NW4R_SND_MML_SEQ_TRACK_ALLOCATOR_H +#include "snd_MmlSeqTrack.h" +#include "snd_MmlParser.h" +#include "snd_InstancePool.h" +#include "types_nw4r.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct MmlSeqTrackAllocator : SeqTrackAllocator + { + MmlParser * mParser; + InstancePool mPool; // at 0x8 + + SeqTrack * AllocTrack(SeqPlayer *); // at 0xc + void FreeTrack(SeqTrack *); // at 0x10 + + u32 Create(void *, u32); + void Destroy(void *, u32); + + int GetAllocatableTrackCount() const; // at 0x14 + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_MoveValue.h b/include/nw4r/snd/snd_MoveValue.h new file mode 100644 index 00000000..c9b0f96b --- /dev/null +++ b/include/nw4r/snd/snd_MoveValue.h @@ -0,0 +1,58 @@ +#ifndef NW4R_SND_MOVE_VALUE_H +#define NW4R_SND_MOVE_VALUE_H +#include + +namespace nw4r { +namespace snd { +namespace detail { + +template class MoveValue { +public: + MoveValue() + : mOrigin(TValue()), + mTarget(TValue()), + mFrame(TTime()), + mCounter(TTime()) {} + + void InitValue(TValue t1) { + mOrigin = t1; + mTarget = t1; + mFrame = 0; + mCounter = 0; + } + + bool IsFinished() const { return mCounter >= mFrame; } + + TValue GetValue() const { + if (IsFinished()) { + return mTarget; + } + + return mOrigin + mCounter * (mTarget - mOrigin) / mFrame; + } + + void Update() { + if (mCounter < mFrame) { + mCounter++; + } + } + + void SetTarget(TValue target, TTime frame) { + mOrigin = GetValue(); + mTarget = target; + mFrame = frame; + mCounter = 0; + } + +private: + TValue mOrigin; // at 0x0 + TValue mTarget; // at 0x4 + TTime mFrame; // at 0x8 + TTime mCounter; // at 0xC +}; + +} // namespace detail +} // namespace snd +} // namespace nw4r + +#endif diff --git a/include/nw4r/snd/snd_NandSoundArchive.h b/include/nw4r/snd/snd_NandSoundArchive.h new file mode 100644 index 00000000..d1e9dba6 --- /dev/null +++ b/include/nw4r/snd/snd_NandSoundArchive.h @@ -0,0 +1,40 @@ +#ifndef NW4R_SND_NAND_SOUND_ARCHIVE_H +#define NW4R_SND_NAND_SOUND_ARCHIVE_H +#include +#include "ut_NandFileStream.h" +#include "snd_SoundArchive.h" +#include "snd_SoundArchiveFile.h" + +namespace nw4r +{ + namespace snd + { + struct NandSoundArchive : SoundArchive + { + struct NandFileStream; + + detail::SoundArchiveFileReader mFileReader; // at 0x108 + NANDFileInfo mFileInfo; // at 0x14c + bool mOpenFlag; // at 0x1d8 + + NandSoundArchive(); + + virtual ~NandSoundArchive(); // at 0x8 + virtual const void * detail_GetFileAddress(u32) const; // at 0xC + virtual const void * detail_GetWaveDataFileAddress(u32) const; // at 0x10 + virtual int detail_GetRequiredStreamBufferSize() const; // at 0x14 + virtual ut::FileStream * OpenStream(void *, int, u32, u32) const; // at 0x18 + virtual ut::FileStream * OpenExtStream(void *, int, const char *, u32, u32) const; // at 0x1c + + bool Open(const char *); + + void Close(); + + bool LoadFileHeader(); + bool LoadHeader(void *, u32); + bool LoadLabelStringData(void *, u32); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_NoteOn.h b/include/nw4r/snd/snd_NoteOn.h new file mode 100644 index 00000000..474ed151 --- /dev/null +++ b/include/nw4r/snd/snd_NoteOn.h @@ -0,0 +1,34 @@ +#ifndef NW4R_SND_NOTE_ON_H +#define NW4R_SND_NOTE_ON_H +#include "types_nw4r.h" +#include "snd_Channel.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct NoteOnInfo + { + int INT_0x0; + int INT_0x4; + int INT_0x8; + int INT_0xC; + int INT_0x10; + int INT_0x14; + int INT_0x18; + Channel::ChannelCallback mChannelCallback; // at 0x1c + u32 INT_0x20; + }; + + struct NoteOnCallback + { + virtual ~NoteOnCallback(); // at 0x8 + virtual bool NoteOn(SeqPlayer *, int, const NoteOnInfo &) = 0; // at 0xc + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_PlayerHeap.h b/include/nw4r/snd/snd_PlayerHeap.h new file mode 100644 index 00000000..f29b1dd5 --- /dev/null +++ b/include/nw4r/snd/snd_PlayerHeap.h @@ -0,0 +1,21 @@ +#ifndef NW4R_SND_PLAYER_HEAP_H +#define NW4R_SND_PLAYER_HEAP_H +#include "types_nw4r.h" +#include "snd_SoundHeap.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct PlayerHeap : SoundHeap + { + ~PlayerHeap(); + UNKTYPE * Alloc(u32); + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_RemoteSpeaker.h b/include/nw4r/snd/snd_RemoteSpeaker.h new file mode 100644 index 00000000..2252a5e8 --- /dev/null +++ b/include/nw4r/snd/snd_RemoteSpeaker.h @@ -0,0 +1,75 @@ +#ifndef NW4R_SND_REMOTE_SPEAKER_H +#define NW4R_SND_REMOTE_SPEAKER_H +#include +#include +#include "types_nw4r.h" + +namespace nw4r +{ + namespace snd + { + struct RemoteSpeaker + { + typedef void (*RemoteSpeakerCallback)(s32, s32); + + enum SpeakerCommand + { + SpeakerCommand_None, + SpeakerCommand_On, + SpeakerCommand_Play, + SpeakerCommand_Off, + }; + + bool mPoweredFlag; // at 0x0 + bool BOOL_0x1; + bool mEnabledOutputFlag; // at 0x2 + bool BOOL_0x3; + bool BOOL_0x4; + bool BOOL_0x5; + bool BOOL_0x6; + bool BOOL_0x7; + volatile bool BOOL_0x8; + + UNKWORD WORD_0xC; + SpeakerCommand CMD_0x10; + SpeakerCommand CMD_0x14; + char UNK_0x18[0x20]; + s32 mChannelIndex; // at 0x38 + RemoteSpeakerCallback mCallback; // at 0x3c + OSAlarm ALARM_0x40; + OSAlarm ALARM_0x70; + s64 mTime; // at 0xa0 + + RemoteSpeaker(); + void ClearParam(); //inlined + void InitParam(); //inlined + + bool Setup(RemoteSpeakerCallback); + void Shutdown(RemoteSpeakerCallback); + + bool EnableOutput(bool); + bool IsEnabledOutput() const; + + void Update(); + void ExecCommand(SpeakerCommand); + + bool IsAllSampleZero(const s16 *); //inlined + void UpdateStreamData(const s16 *); + + void NotifyCallback(s32, s32); //inlined + static void SpeakerOnCallback(s32, s32); + static void SpeakerPlayCallback(s32, s32); + static void SpeakerOffCallback(s32, s32); + + static void ContinueAlarmHandler(OSAlarm *, OSContext *); + static void IntervalAlarmHandler(OSAlarm *, OSContext *); + + inline void SetChannelIndex(int channelIndex) + { + mChannelIndex = channelIndex; + } + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_RemoteSpeakerManager.h b/include/nw4r/snd/snd_RemoteSpeakerManager.h new file mode 100644 index 00000000..b440efad --- /dev/null +++ b/include/nw4r/snd/snd_RemoteSpeakerManager.h @@ -0,0 +1,34 @@ +#ifndef NW4R_SND_REMOTE_SPEAKER_MANAGER_H +#define NW4R_SND_REMOTE_SPEAKER_MANAGER_H +#include +#include "snd_RemoteSpeaker.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct RemoteSpeakerManager + { + bool mPoweredFlag; // at 0x0 + char UNK_0x4[4]; + OSAlarm mAlarm; // at 0x8 + RemoteSpeaker mRemoteSpeakers[4]; + + RemoteSpeakerManager(); //inlined + + static RemoteSpeakerManager * GetInstance(); + + RemoteSpeaker * GetRemoteSpeaker(int); + + void Setup(); + void Shutdown(); + + static void RemoteSpeakerAlarmProc(OSAlarm *, OSContext *); + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_SeqFile.h b/include/nw4r/snd/snd_SeqFile.h new file mode 100644 index 00000000..0d72e344 --- /dev/null +++ b/include/nw4r/snd/snd_SeqFile.h @@ -0,0 +1,37 @@ +#ifndef NW4R_SND_SEQ_FILE_H +#define NW4R_SND_SEQ_FILE_H +#include "types_nw4r.h" +#include "ut_binaryFileFormat.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct SeqFile + { + ut::BinaryFileHeader mHeader; // at 0x0 + u32 OFFSET_0x10; // at 0x10 + }; + + struct SeqFileReader + { + struct UNKBLOCK + { + ut::BinaryBlockHeader mHeader; // at 0x0 + u32 OFFSET_0x8; + }; + + const SeqFile * mFile; // at 0x0 + const UNKBLOCK * PTR_0x4; + + bool IsValidFileHeader(const void *); + SeqFileReader(const void *); + const void * GetBaseAddress() const; + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_SeqPlayer.h b/include/nw4r/snd/snd_SeqPlayer.h new file mode 100644 index 00000000..12236216 --- /dev/null +++ b/include/nw4r/snd/snd_SeqPlayer.h @@ -0,0 +1,138 @@ +#ifndef NW4R_SND_SEQ_PLAYER_H +#define NW4R_SND_SEQ_PLAYER_H +#include "types_nw4r.h" +#include "ut_lock.h" +#include "snd_BasicPlayer.h" +#include "snd_InstancePool.h" +#include "snd_DisposeCallback.h" +#include "snd_SoundThread.h" +#include "snd_NoteOn.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + // Used an anonymous enum instead of a macro + // because I wanted the magic number to have + // namespace scope + enum + { + SEQ_TRACKS_PER_PLAYER = 0x10, + SEQ_VARIABLE_COUNT = 0x10 + }; + + //sizeof(SeqPlayer) = 0x11C + struct SeqPlayer : BasicPlayer, DisposeCallback, SoundThread::PlayerCallback + { + enum OffsetType + { + OFFSET_TYPE_0, + OFFSET_TYPE_1 + }; + + + bool Start(); // at 0xc + void Stop(); // at 0x10 + void Pause(bool); // at 0x14 + bool IsActive() const; // at 0x18 + bool IsStarted() const; // at 0x1c + bool IsPause() const; // at 0x20 + + void InvalidateData(const void *, const void *); + inline void InvalidateWaveData(const void *, const void *) {} + inline virtual void ChannelCallback(Channel *) {} + + bool mActiveFlag; // at 0x8c + bool mStartedFlag; // at 0x8d + bool mPauseFlag; // at 0x8e + + bool mReleasePriorityFixFlag; // at 0x8f + float FLOAT_0x90; + float mTempoRatio; // at 0x94 + float FLOAT_0x98; + int OFFSET_0x9C; + float OFFSET_0xA0; + int INT_0xA4; + char BYTE_0xA8; + u8 mChannelPriority; // at 0xa9 + u8 BYTE_0xAA; + u16 SHORT_0xAC; + + NoteOnCallback * mNoteOnCallback; // at 0xb0 + SeqTrackAllocator * mTrackAllocator; // at 0xb4 + SeqTrack * mPlayerTracks[SEQ_TRACKS_PER_PLAYER]; // at 0xb8 + volatile s16 mLocalVariables[SEQ_VARIABLE_COUNT]; // at 0xf8 + + int INT_0x118; + + SeqPlayer(); + ~SeqPlayer(); + + UNKTYPE InitParam(int, NoteOnCallback *); + void CloseTrack(int); + void FinishPlayer(); //inlined + + bool Setup(SeqTrackAllocator *, u32, int, NoteOnCallback *); + void SetSeqData(const void *, s32); + void Skip(OffsetType, int); + + void SetTempoRatio(float); + void SetChannelPriority(int); + void SetReleasePriorityFix(bool); + void SetLocalVariable(int, short); + static void InitGlobalVariable(); //inline + static void SetGlobalVariable(int, short); + + template + inline void SetTrackParam(u32 flags, void (SeqTrack::* pSetter)(T), T param) + { + ut::AutoInterruptLock lock; + + for (int i = 0; i < SEQ_TRACKS_PER_PLAYER && flags; flags >>= 1, i++) + { + if (flags & 1) + { + SeqTrack * pPlayerTrack = GetPlayerTrack(i); + + if (pPlayerTrack) (pPlayerTrack->*pSetter)(param); + } + } + } + + void SetTrackVolume(u32, float); + void SetTrackPitch(u32, float); + + void SetPlayerTrack(int, SeqTrack *); //inlined + SeqTrack * GetPlayerTrack(int); + bool ParseNextTick(bool); + volatile s16 * GetVariablePtr(int); + void UpdateChannelParam(); //inlined + void Update(); + void UpdateTick(); + void UpdateTick(int); + bool NoteOn(int, const NoteOnInfo &); + inline void OnUpdateFrameSoundThread() + { + Update(); + } + + inline void OnShutdownSoundThread() + { + Stop(); + } + + inline float GetBaseTempo() const + { + return mTempoRatio * (BYTE_0xAA * SHORT_0xAC) / 60000.0f; + } + + static volatile s16 mGlobalVariable[SEQ_VARIABLE_COUNT]; + static bool mGobalVariableInitialized; // typo + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_SeqSound.h b/include/nw4r/snd/snd_SeqSound.h new file mode 100644 index 00000000..26a825a3 --- /dev/null +++ b/include/nw4r/snd/snd_SeqSound.h @@ -0,0 +1,104 @@ +#ifndef NW4R_SND_SEQ_SOUND_H +#define NW4R_SND_SEQ_SOUND_H +#include +#include "types_nw4r.h" +#include "snd_BasicSound.h" +#include "snd_SeqPlayer.h" +#include "snd_SoundInstanceManager.h" +#include "snd_Task.h" +#include "snd_NoteOn.h" +#include "ut_FileStream.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct SeqSound : BasicSound + { + typedef void (*SeqLoadCallback)(bool, const void *, void *); + + //sizeof(SeqLoadTask) = 0x24 + struct SeqLoadTask : Task + { + ut::FileStream * mFileStream; // at 0x10 + void * mData; // at 0x14 + int mSize; // at 0x18 + SeqLoadCallback mCallback; // at 0x1c + SeqSound * mSound; // at 0x20 + + inline SeqLoadTask() : mFileStream(NULL), mData(NULL), mCallback(NULL), mSound(NULL) {} + + void Execute(); + void Cancel(); + void OnCancel(); + }; + + static ut::detail::RuntimeTypeInfo typeInfo; + + SeqPlayer mPlayer; // at 0xd8 + SeqSoundHandle * mTempSpecialHandle; // at 0x1f4 + SoundInstanceManager * mManager; // at 0x1f8 + s32 INT_0x1FC; + SeqPlayer::OffsetType mOffsetType; // at 0x200 + int mOffset; // at 0x204 + bool mLoadingFlag; // at 0x208 + volatile bool mPreparedFlag; // at 0x209 + ut::FileStream * mFileStream; // at 0x20c + char UNK_0x210[0x200]; + SeqLoadTask mLoadTask; // at 0x410 + OSMutex MUTEX_0x434; // at 0x434 + + SeqSound(SoundInstanceManager *); + UNKTYPE InitParam(); + UNKTYPE Setup(SeqTrackAllocator *, u32, int, NoteOnCallback *); + + UNKTYPE Skip(SeqPlayer::OffsetType, int); //inlined + bool LoadData(SeqLoadCallback, void *); //inlined + void Prepare(const void *, s32, SeqPlayer::OffsetType, int); + void Prepare(ut::FileStream *, s32, SeqPlayer::OffsetType, int); + static void NotifyLoadAsyncEndSeqData(bool, const void *, void *); + + void Shutdown(); + + UNKTYPE SetTempoRatio(float); + UNKTYPE SetChannelPriority(int); + UNKTYPE SetReleasePriorityFix(bool); + + UNKTYPE SetPlayerPriority(int); + + UNKTYPE SetTrackVolume(u32, float); + UNKTYPE SetTrackPitch(u32, float); + + bool WriteVariable(int, short); + static bool WriteGlobalVariable(int, short); + + bool IsAttachedTempSpecialHandle(); + UNKTYPE DetachTempSpecialHandle(); + + inline const BasicPlayer * GetBasicPlayer() const + { + return &mPlayer; + } + + inline BasicPlayer * GetBasicPlayer() + { + return &mPlayer; + } + + inline bool IsPrepared() const + { + return mPreparedFlag; + } + + inline const ut::detail::RuntimeTypeInfo * GetRuntimeTypeInfo() const + { + return &typeInfo; + } + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_SeqSoundHandle.h b/include/nw4r/snd/snd_SeqSoundHandle.h new file mode 100644 index 00000000..4f4c1b05 --- /dev/null +++ b/include/nw4r/snd/snd_SeqSoundHandle.h @@ -0,0 +1,22 @@ +#ifndef NW4R_SND_SEQ_SOUND_HANDLE_H +#define NW4R_SND_SEQ_SOUND_HANDLE_H +#include "types_nw4r.h" +#include "snd_SoundHandle.h" + +namespace nw4r +{ + namespace snd + { + using namespace detail; + + struct SeqSoundHandle + { + detail::SeqSound * mSound; // at 0x0 + + SeqSoundHandle(SoundHandle *); + void DetachSound(); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_SeqTrack.h b/include/nw4r/snd/snd_SeqTrack.h new file mode 100644 index 00000000..3040d00f --- /dev/null +++ b/include/nw4r/snd/snd_SeqTrack.h @@ -0,0 +1,129 @@ +#ifndef NW4R_SND_SEQ_TRACK_H +#define NW4R_SND_SEQ_TRACK_H +#include "types_nw4r.h" +#include "snd_Lfo.h" +#include "snd_Channel.h" + +namespace nw4r +{ + namespace snd + { + enum SeqMute + { + SEQ_MUTE_0, + SEQ_MUTE_1, + SEQ_MUTE_2, + SEQ_MUTE_3 + }; + + namespace detail + { + struct SeqTrack + { + virtual ~SeqTrack(); + virtual UNKWORD Parse(bool) = 0; + + u8 mPlayerTrackNo; // at 0x4 + bool mOpenFlag; // at 0x5 + + float mVolume; // at 0x8 + float mPitch; // at 0xc + float FLOAT_0x10; + float FLOAT_0x14; + float FLOAT_0x18; + float FLOAT_0x1C; + float FLOAT_0x20; + float FLOATS_0x24[3]; + float FLOATS_0x30[4]; + float FLOATS_0x40[4]; + + const u8 * PTR_0x50; + const u8 * PTR_0x54; + + int TIMER_0x58; + + bool BOOL_0x5C; + char BYTE_0x5D; + bool BOOL_0x5E; + bool BOOL_0x5F; + bool BOOL_0x60; + + int INT_0x64; + UNKWORD WORD_0x68; + + LfoParam mLfoParam; // at 0x6c + + u8 BYTE_0x7C; + float FLOAT_0x80; + u8 BYTE_0x84; + u8 BYTE_0x85; + s8 BYTE_0x86; + u8 BYTE_0x87; + s8 BYTE_0x88; + s8 BYTE_0x89; + s8 BYTE_0x8A; + char BYTE_0x8B; + u8 BYTE_0x8C; + char BYTE_0x8D; + u8 BYTE_0x8E; + + u8 mAttack; // at 0x8f + u8 mDecay; // at 0x90 + u8 mSustain; // at 0x91 + u8 mRelease; // at 0x92 + + u8 BYTE_0x93; + u8 BYTES_0x94[3]; + char BYTE_0x97; + + s16 mVariables[0x10]; // at 0x98 + + SeqPlayer * mPlayer; // at 0xb8 + Channel * mChannel; // at 0xbc + + void SetPlayerTrackNo(int); + + SeqTrack(); + + UNKTYPE InitParam(); + + void SetSeqData(const void *, s32); + + void Open(); + void Close(); + + void UpdateChannelRelease(Channel *); //inlined + void UpdateChannelLength(); + UNKWORD ParseNextTick(bool); + void ReleaseAllChannel(int); + UNKTYPE PauseAllChannel(bool); + void UpdateChannelParam(); + UNKTYPE FreeAllChannel(); + + static void ChannelCallbackFunc(Channel *, Channel::ChannelCallbackStatus, u32); + + void StopAllChannel(); //inlined + void SetMute(SeqMute); + void SetVolume(float); + void SetPitch(float); + s16 * GetVariablePtr(int); + void AddChannel(Channel *); //inlined + Channel * NoteOn(int, int, s32, bool); + + inline bool IsOpened() const + { + return mOpenFlag; + } + }; + + struct SeqTrackAllocator + { + inline virtual ~SeqTrackAllocator() {} + virtual SeqTrack * AllocTrack(SeqPlayer *) = 0; + virtual void FreeTrack(SeqTrack *) = 0; + virtual int GetAllocatableTrackCount() const = 0; + }; + } + } +} +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_Sound3DActor.h b/include/nw4r/snd/snd_Sound3DActor.h new file mode 100644 index 00000000..977eab1b --- /dev/null +++ b/include/nw4r/snd/snd_Sound3DActor.h @@ -0,0 +1,40 @@ +#ifndef NW4R_SND_SOUND_3D_ACTOR_H +#define NW4R_SND_SOUND_3D_ACTOR_H +#include "snd_BasicSound.h" +#include "snd_SoundActor.h" +#include "math_types.h" + +namespace nw4r +{ + namespace snd + { + struct Sound3DActor : + detail::SoundActor, + detail::BasicSound::AmbientArgUpdateCallback + { + Sound3DManager & mManager; // at 0xac + SoundArchivePlayer & mArchivePlayer; // at 0xb0 + UNKWORD WORD_0xB4; + math::VEC3 mPosition; // at 0xb8 + + Sound3DActor(SoundArchivePlayer &, Sound3DManager &); + + ~Sound3DActor(); + + UNKWORD detail_SetupSound(SoundHandle *, + u32, + detail::BasicSound::AmbientArgInfo *, + detail::ExternalSoundPlayer *, + bool, + const SoundStartable::StartInfo *); + + void SetPosition(const math::VEC3 &); + + void detail_Update(void *, const detail::BasicSound *); + + static void ClearUpdateCallback(SoundHandle& handle); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_Sound3DListener.h b/include/nw4r/snd/snd_Sound3DListener.h new file mode 100644 index 00000000..2a61b8cd --- /dev/null +++ b/include/nw4r/snd/snd_Sound3DListener.h @@ -0,0 +1,23 @@ +#ifndef NW4R_SND_SOUND_3D_LISTENER_H +#define NW4R_SND_SOUND_3D_LISTENER_H +#include "types_nw4r.h" +#include "math_types.h" + +namespace nw4r +{ + namespace snd + { + struct Sound3DListener + { + math::MTX34 mMatrix; // at 0x0 + + float mInteriorSize; // at 0x30 + float mMaxVolumeDistance; // at 0x34 + float mUnitDistance; // at 0x38 + + Sound3DListener(); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_Sound3DManager.h b/include/nw4r/snd/snd_Sound3DManager.h new file mode 100644 index 00000000..432c30df --- /dev/null +++ b/include/nw4r/snd/snd_Sound3DManager.h @@ -0,0 +1,53 @@ +#ifndef NW4R_SND_SOUND_3D_MANAGER_H +#define NW4R_SND_SOUND_3D_MANAGER_H +#include "snd_BasicSound.h" +#include "snd_SoundArchive.h" +#include "snd_SoundActor.h" +#include "snd_InstancePool.h" +#include "math_types.h" + +namespace nw4r +{ + namespace snd + { + struct Sound3DManager : + detail::BasicSound::AmbientParamUpdateCallback, + detail::BasicSound::AmbientArgAllocaterCallback + { + struct Sound3DActorParam + { + u32 WORD_0x0; + + SoundArchive::Sound3DParam mSound3DParam; // at 0x4 + + math::VEC3 mPosition; // at 0xc + + Sound3DActorParam(); + }; + + detail::InstancePool mPool; // at 0x8 + Sound3DListener * mListener; // at 0xc + int INT_0x10; + float FLOAT_0x14; + float FLOAT_0x18; + float FLOAT_0x1C; + float FLOAT_0x20; + float FLOAT_0x24; + + Sound3DManager(); + + u32 GetRequiredMemSize(const SoundArchive *); + + bool Setup(const SoundArchive *, void *, u32); + + void detail_Update(SoundParam *, u32, detail::BasicSound *, const void *, u32); + + virtual void Update(SoundParam *, u32, SoundHandle *, const void *, u32); + + void * detail_AllocAmbientArg(u32); + void detail_FreeAmbientArg(void *, const detail::BasicSound *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_SoundActor.h b/include/nw4r/snd/snd_SoundActor.h new file mode 100644 index 00000000..bca4d68c --- /dev/null +++ b/include/nw4r/snd/snd_SoundActor.h @@ -0,0 +1,56 @@ +#ifndef NW4R_SND_SOUND_ACTOR_H +#define NW4R_SND_SOUND_ACTOR_H +#include "snd_SoundStartable.h" +#include "snd_ExternalSoundPlayer.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + enum + { + SOUND_PLAYERS_PER_ACTOR = 8 + }; + + struct SoundActor : SoundStartable + { + SoundStartable & mStartable; // at 0x4 + ExternalSoundPlayer mPlayers[SOUND_PLAYERS_PER_ACTOR]; // at 0x8 + + inline SoundActor(SoundStartable & startable) : mStartable(startable) + { + mPlayers[0].SetPlayableSoundCount(0x7FFFFFFF); + } + + inline UNKWORD detail_ConvertLabelStringToSoundId(const char * labelString) + { + return mStartable.detail_ConvertLabelStringToSoundId(labelString); + } + + template + TForEachFunc ForEachSound(TForEachFunc func, bool reverse) { + int i; + ExternalSoundPlayer* player = mPlayers; + + for (i = 0; i < SOUND_PLAYERS_PER_ACTOR; i++) { + player->ForEachSound(func, reverse); + player++; + } + + return func; + } + + virtual UNKWORD detail_SetupSound(SoundHandle *, + u32, + detail::BasicSound::AmbientArgInfo *, + detail::ExternalSoundPlayer *, + bool, + const StartInfo *); + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_SoundArchive.h b/include/nw4r/snd/snd_SoundArchive.h new file mode 100644 index 00000000..3a3bd351 --- /dev/null +++ b/include/nw4r/snd/snd_SoundArchive.h @@ -0,0 +1,163 @@ +#ifndef NW4R_SND_SOUND_ARCHIVE_H +#define NW4R_SND_SOUND_ARCHIVE_H +#include "ut_FileStream.h" +#include "types_nw4r.h" + +namespace nw4r +{ + namespace snd + { + struct SoundArchive + { + struct Sound3DParam + { + UNKWORD WORD_0x0; + u8 BYTE_0x4; + u8 BYTE_0x5; + }; + + struct SoundArchivePlayerInfo + { + u32 SIZE_0x0; + UNKWORD WORD_0x4; + u32 SIZE_0x8; + UNKWORD WORD_0xC; + UNKWORD WORD_0x10; + u32 SIZE_0x14; + UNKWORD WORD_0x18; + }; + + struct SoundInfo + { + UNKWORD WORD_0x0; + UNKWORD WORD_0x4; + UNKWORD WORD_0x8; + UNKWORD WORD_0xC; + UNKWORD WORD_0x10; + UNKWORD WORD_0x14; + UNKWORD WORD_0x18; + }; + + struct SeqSoundInfo + { + UNKWORD WORD_0x0; + UNKWORD WORD_0x4; + UNKWORD WORD_0x8; + UNKWORD WORD_0xC; + bool BOOL_0x10; + }; + + struct StrmSoundInfo + { + + }; + + struct WaveSoundInfo + { + UNKWORD WORD_0x0; + UNKWORD WORD_0x4; + bool BOOL_0x8; + }; + + struct BankInfo + { + UNKWORD WORD_0x0; + }; + + struct PlayerInfo + { + UNKWORD WORD_0x0; + UNKWORD WORD_0x4; + }; + + struct GroupInfo + { + u32 mCount; // at 0x0 + const char * mExternalFileName; // at 0x4 + u32 INT_0x8; + u32 INT_0xC; + u32 INT_0x10; + u32 INT_0x14; + }; + + struct GroupItemInfo + { + UNKWORD WORD_0x0; + u32 INT_0x4; + u32 INT_0x8; + u32 INT_0xC; + UNKWORD WORD_0x10; + }; + + struct FileInfo + { + UNKWORD WORD_0x0; + UNKWORD WORD_0x4; + const char * mExternalFileName; // at 0x8 + u32 SIZE_0xC; + }; + + struct FilePos + { + u32 mGroupIndex; // at 0x0 + u32 mGroupItemIndex; // at 0x4 + }; + + virtual ~SoundArchive(); // at 0x8 + virtual const void * detail_GetFileAddress(u32) const = 0; // at 0xc + virtual const void * detail_GetWaveDataFileAddress(u32) const = 0; // at 0x10 + virtual int detail_GetRequiredStreamBufferSize() const = 0; // at 0x14 + virtual ut::FileStream * OpenStream(void *, int, u32, u32) const = 0; // at 0x18 + virtual ut::FileStream * OpenExtStream(void *, int, const char *, u32, u32) const = 0; // at 0x1c + + detail::SoundArchiveFileReader * mFileReader; // at 0x4 + char mExternalFileRoot[0x100]; // at 0x8 + + SoundArchive(); + + bool IsAvailable() const; + + void Setup(detail::SoundArchiveFileReader *); + void Shutdown(); + + u32 GetPlayerCount() const; + u32 GetGroupCount() const; + + const char * GetSoundLabelString(u32) const; + + u32 ConvertLabelStringToSoundId(const char *) const; + u32 ConvertLabelStringToPlayerId(const char *) const; + u32 ConvertLabelStringToGroupId(const char *) const; + + UNKWORD GetSoundUserParam(u32) const; + UNKWORD GetSoundType(u32) const; + + bool ReadSoundInfo(u32, SoundInfo *) const; + + bool detail_ReadSeqSoundInfo(u32, SeqSoundInfo *) const; + bool detail_ReadStrmSoundInfo(u32, StrmSoundInfo *) const; + bool detail_ReadWaveSoundInfo(u32, WaveSoundInfo *) const; + + bool ReadPlayerInfo(u32, PlayerInfo *) const; + + bool ReadSoundArchivePlayerInfo(SoundArchivePlayerInfo *) const; + + bool detail_ReadSound3DParam(u32, Sound3DParam *) const; + + bool detail_ReadBankInfo(u32, BankInfo *) const; + bool detail_ReadGroupInfo(u32, GroupInfo *) const; + bool detail_ReadGroupItemInfo(u32, u32, GroupItemInfo *) const; + bool detail_ReadFileInfo(u32, FileInfo *) const; + bool detail_ReadFilePos(u32, u32, FilePos *) const; + + ut::FileStream * OpenExtStreamImpl(void *, int, const char *, u32, u32) const; //inlined + ut::FileStream * detail_OpenFileStream(u32, void *, int) const; + ut::FileStream * detail_OpenGroupStream(u32, void *, int) const; + ut::FileStream * detail_OpenGroupWaveDataStream(u32, void *, int) const; + + UNKTYPE SetExternalFileRoot(const char *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_SoundArchiveFile.h b/include/nw4r/snd/snd_SoundArchiveFile.h new file mode 100644 index 00000000..eff6e904 --- /dev/null +++ b/include/nw4r/snd/snd_SoundArchiveFile.h @@ -0,0 +1,278 @@ +#ifndef NW4R_SND_SOUND_ARCHIVE_FILE_H +#define NW4R_SND_SOUND_ARCHIVE_FILE_H +#include "types_nw4r.h" +#include "ut_binaryFileFormat.h" +#include "snd_Util.h" +#include "snd_SoundArchive.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + namespace SoundArchiveFile + { + struct Header + { + ut::BinaryFileHeader mHeader; // at 0x0 + u32 mLabelStringChunkOffset; // at 0x10 + u32 mLabelStringChunkSize; // at 0x14 + u32 mInfoChunkOffset; // at 0x18 + u32 mInfoChunkSize; // at 0x1c + UNKWORD UNK_0x20[0x8 / sizeof(UNKWORD)]; // at 0x20 + }; + + struct Sound3DParam + { + UNKWORD WORD_0x0; + u8 BYTE_0x4; + u8 BYTE_0x5; + }; + + struct SeqSoundInfo + { + UNKWORD WORD_0x0; + UNKWORD WORD_0x4; + UNKWORD WORD_0x8; + u8 BYTE_0xC; + u8 BYTE_0xD; + }; + + struct StrmSoundInfo + { + + }; + + struct WaveSoundInfo + { + UNKWORD WORD_0x0; + char UNK_0x4[0x4]; + u8 BYTE_0x8; + u8 BYTE_0x9; + }; + + typedef Util::DataRef SoundInfoOffset; + + struct SoundCommonInfo + { + u32 mSoundStringId; // at 0x0 + UNKWORD WORD_0x4; + UNKWORD WORD_0x8; + Util::DataRef mSound3DParam; // at 0xc + u8 BYTE_0x14; + u8 BYTE_0x15; + u8 mType; // at 0x16 + u8 BYTE_0x17; + SoundInfoOffset mSoundInfoOffset; // at 0x18 + UNKWORD mSoundUserParam; // at 0x20 + char UNK_0x24[0x4]; + u8 BYTE_0x28; + u8 BYTE_0x29; + }; + + typedef Util::Table > SoundCommonTable; + + struct BankInfo + { + char UNK_0x0[0x4]; + UNKWORD WORD_0x4; + }; + + typedef Util::Table > BankTable; + + struct PlayerInfo + { + char UNK_0x0[0x4]; + u8 BYTE_0x4; + UNKWORD WORD_0x8; + }; + + typedef Util::Table > PlayerTable; + + struct GroupItemInfo + { + UNKWORD WORD_0x0; + u32 INT_0x4; + u32 INT_0x8; + u32 INT_0xC; + UNKWORD WORD_0x10; + }; + + typedef Util::Table > GroupItemTable; + + struct GroupInfo + { + char UNK_0x0[0x8]; + Util::DataRef mExternalFileName; // at 0x8 + u32 INT_0x10; + u32 INT_0x14; + u32 INT_0x18; + u32 INT_0x1C; + Util::DataRef mGroupItemTable; // at 0x20 + }; + + typedef Util::Table > GroupTable; + + struct SoundArchivePlayerInfo + { + u16 SIZE_0x0; + u16 SHORT_0x2; + u16 SIZE_0x4; + u16 SHORT_0x6; + u16 SHORT_0x8; + u16 SIZE_0xA; + u16 SHORT_0xC; + }; + + typedef Util::Table > FilePosTable; + + struct FileInfo + { + UNKWORD WORD_0x0; + UNKWORD WORD_0x4; + char UNK_0x8[0x4]; + Util::DataRef mExternalFileName; // at 0xc + Util::DataRef TABLE_0x14; + }; + + typedef Util::Table > FileTable; + + struct StringNode + { + enum + { + FLAG_LEAF = 0x0001 + }; + + u16 mFlags; // at 0x0 + u16 SHORT_0x2; + u32 mLeftIndex; // at 0x4 + u32 mRightIndex; // at 0x8 + u32 mStringId; // at 0xc + u32 mId; // at 0x10 + }; + + struct StringTree + { + u32 mRootIndex; // at 0x0 + u32 INT_0x4; + StringNode mNodes[]; // at 0x8 + }; + + struct StringChunk + { + u32 mTableOffset; // at 0x0 + u32 mSoundTreeOffset; // at 0x4 + u32 mPlayerTreeOffset; // at 0x8 + u32 mGroupTreeOffset; // at 0xc + u32 OFFSET_0x10; + }; + + struct InfoChunk + { + Util::DataRef mSoundCommonTable; // at 0x0 + Util::DataRef mBankTable; // at 0x8 + Util::DataRef mPlayerTable; // at 0x10 + Util::DataRef mFileTable; // at 0x18 + Util::DataRef mGroupTable; // at 0x20 + Util::DataRef mSoundArchivePlayerInfo; // at 0x28 + }; + }; + + struct SoundArchiveFileReader + { + struct StringBlock + { + ut::BinaryBlockHeader mHeader; // at 0x0 + SoundArchiveFile::StringChunk mChunk; // at 0x8 + }; + + struct InfoBlock + { + ut::BinaryBlockHeader mHeader; // at 0x0 + SoundArchiveFile::InfoChunk mChunk; // at 0x8 + }; + + SoundArchiveFile::Header mHeader; // at 0x0 + + const SoundArchiveFile::InfoChunk * mInfoChunk; // at 0x28 + const SoundArchiveFile::StringChunk * mStringChunk; // at 0x2c + const Util::Table * mStringTable; // at 0x30 + const SoundArchiveFile::StringTree * mSoundStringTree; // at 0x34 + const SoundArchiveFile::StringTree * mPlayerStringTree; // at 0x38 + const SoundArchiveFile::StringTree * mGroupStringTree; // at 0x3c + const UNKTYPE * PTR_0x40; + + SoundArchiveFileReader(); + + bool IsValidFileHeader(const void *); //inlined + void Init(const void *); + + const void * GetPtrConst(const void *, u32) const; //inlined + + void SetStringChunk(const void *, u32); + void SetInfoChunk(const void *, u32); + + UNKWORD GetSoundType(u32) const; + + const SoundArchiveFile::SoundCommonInfo * impl_GetSoundInfo(u32) const; //inlined + bool ReadSoundInfo(u32, SoundArchive::SoundInfo *) const; + bool ReadSound3DParam(u32, SoundArchive::Sound3DParam *) const; + bool ReadSeqSoundInfo(u32, SoundArchive::SeqSoundInfo *) const; + bool ReadStrmSoundInfo(u32, SoundArchive::StrmSoundInfo *) const; + bool ReadWaveSoundInfo(u32, SoundArchive::WaveSoundInfo *) const; + const SoundArchiveFile::BankInfo * impl_GetBankInfo(u32) const; //inlined + bool ReadBankInfo(u32, SoundArchive::BankInfo *) const; + const SoundArchiveFile::PlayerInfo * impl_GetPlayerInfo(u32) const; //inlined + bool ReadPlayerInfo(u32, SoundArchive::PlayerInfo *) const; + const SoundArchiveFile::GroupInfo * impl_GetGroupInfo(u32) const; //inlined + bool ReadGroupInfo(u32, SoundArchive::GroupInfo *) const; + bool ReadGroupItemInfo(u32, u32, SoundArchive::GroupItemInfo *) const; + bool ReadSoundArchivePlayerInfo(SoundArchive::SoundArchivePlayerInfo *) const; + + u32 GetPlayerCount() const; + u32 GetGroupCount() const; + + u32 GetSoundStringId(u32) const; //inlined + const char * GetString(u32) const; //inlined + const char * GetSoundLabelString(u32) const; + UNKWORD GetSoundUserParam(u32) const; + + bool ReadFileInfo(u32, SoundArchive::FileInfo *) const; + bool ReadFilePos(u32, u32, SoundArchive::FilePos *) const; + + u32 ConvertLabelStringToId(const SoundArchiveFile::StringTree *, const char *) const; + + SoundArchiveFile::SoundInfoOffset impl_GetSoundInfoOffset(u32) const; + + inline u16 GetVersion() const + { + return mHeader.mHeader.version; + } + + inline u32 GetLabelStringChunkOffset() const + { + return mHeader.mLabelStringChunkOffset; + } + + inline u32 GetLabelStringChunkSize() const + { + return mHeader.mLabelStringChunkSize; + } + + inline u32 GetInfoChunkOffset() const + { + return mHeader.mInfoChunkOffset; + } + + inline u32 GetInfoChunkSize() const + { + return mHeader.mInfoChunkSize; + } + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_SoundArchiveLoader.h b/include/nw4r/snd/snd_SoundArchiveLoader.h new file mode 100644 index 00000000..87f57846 --- /dev/null +++ b/include/nw4r/snd/snd_SoundArchiveLoader.h @@ -0,0 +1,52 @@ +#ifndef NW4R_SND_SOUND_ARCHIVE_LOADER_H +#define NW4R_SND_SOUND_ARCHIVE_LOADER_H +#include "snd_SoundMemoryAllocatable.h" +#include "ut_FileStream.h" +#include "types_nw4r.h" +#include + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct FileStreamHandle + { + ut::FileStream * mFileStream; + + inline FileStreamHandle(ut::FileStream * pFileStream) : mFileStream(pFileStream) {} + + inline ~FileStreamHandle() + { + if (mFileStream) mFileStream->Close(); + } + + inline operator bool() const + { + return mFileStream; + } + + inline ut::FileStream * operator->() + { + return mFileStream; + } + }; + + struct SoundArchiveLoader + { + OSMutex mMutex; // at 0x0 + const SoundArchive & mArchive; // at 0x18 + u8 mBuffer[0x200]; // at 0x1c + ut::FileStream * mFileStream; // at 0x21c + + SoundArchiveLoader(const SoundArchive &); + ~SoundArchiveLoader(); + + void * LoadGroup(u32, SoundMemoryAllocatable *, void **, u32); + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_SoundArchivePlayer.h b/include/nw4r/snd/snd_SoundArchivePlayer.h new file mode 100644 index 00000000..0070b4d4 --- /dev/null +++ b/include/nw4r/snd/snd_SoundArchivePlayer.h @@ -0,0 +1,53 @@ +#ifndef NW4R_SND_SOUND_ARCHIVE_PLAYER_H +#define NW4R_SND_SOUND_ARCHIVE_PLAYER_H +#include "snd_SoundStartable.h" +#include "snd_SoundHandle.h" +#include "snd_DisposeCallback.h" +#include "snd_SoundMemoryAllocatable.h" +#include "types_nw4r.h" + +namespace nw4r +{ + namespace snd + { + struct SoundArchivePlayer : detail::DisposeCallback, SoundStartable + { + SoundArchivePlayer(); + ~SoundArchivePlayer(); + + bool IsAvailable() const; + bool Setup(const SoundArchive *, void *, u32, void *, u32); + + void Shutdown(); + u32 GetRequiredMemSize(const SoundArchive *); + u32 GetRequiredStrmBufferSize(const SoundArchive *); + + void Update(); + + SoundArchive * GetSoundArchive() const; + SoundPlayer * GetSoundPlayer(u32); + + UNKWORD detail_SetupSound(SoundHandle *, + u32, + detail::BasicSound::AmbientArgInfo *, + detail::ExternalSoundPlayer *, + bool, + const StartInfo *); + + UNKWORD LoadGroup(u32, SoundMemoryAllocatable *, u32); + UNKWORD LoadGroup(const char *, SoundMemoryAllocatable *, u32); + + virtual void InvalidateData(const void *, const void *); + virtual void InvalidateWaveData(const void *, const void *); + virtual UNKWORD detail_ConvertLabelStringToSoundId(const char *); + + char UNK_0x4[0x8]; + SoundHandle mHandle; // at 0xC + char UNK_0x1C[0x14]; + u32 WORD_0x30; + char UNK_0x34[0xAC]; + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_SoundHandle.h b/include/nw4r/snd/snd_SoundHandle.h new file mode 100644 index 00000000..b1071033 --- /dev/null +++ b/include/nw4r/snd/snd_SoundHandle.h @@ -0,0 +1,39 @@ +#ifndef NW4R_SND_SOUND_HANDLE_H +#define NW4R_SND_SOUND_HANDLE_H +#include "types_nw4r.h" +#include "snd_BasicSound.h" + +namespace nw4r +{ + namespace snd + { + struct SoundHandle + { + detail::BasicSound * mSound; // at 0x0 + + void detail_AttachSound(detail::BasicSound *); + void detail_AttachSoundAsTempHandle(detail::BasicSound *); + void DetachSound(); + + inline SoundHandle() : mSound(NULL) {} + + inline ~SoundHandle() + { + DetachSound(); + } + + inline detail::BasicSound * detail_GetAttachedSound() { return mSound; } + + inline bool IsAttachedSound() const { return mSound != NULL; } + + inline void StartPrepared() + { + if (IsAttachedSound()) mSound->StartPrepared(); + } + + inline u32 GetId() const { return IsAttachedSound() ? mSound->GetId() : -1; } + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_SoundHeap.h b/include/nw4r/snd/snd_SoundHeap.h new file mode 100644 index 00000000..62987130 --- /dev/null +++ b/include/nw4r/snd/snd_SoundHeap.h @@ -0,0 +1,33 @@ +#ifndef NW4R_SND_SOUND_HEAP_H +#define NW4R_SND_SOUND_HEAP_H +#include "types_nw4r.h" +#include "snd_FrameHeap.h" +#include "snd_SoundMemoryAllocatable.h" +#include + +namespace nw4r +{ + namespace snd + { + struct SoundHeap : SoundMemoryAllocatable + { + SoundHeap(); + virtual ~SoundHeap(); // VMT 0x8 + bool Create(void *, u32); + void Destroy(); + virtual void * Alloc(u32); // VMT 0xC + void* Alloc(u32, detail::FrameHeap::AllocCallback, void *); + void Clear(); + int SaveState(); + void LoadState(int); + static void DisposeCallbackFunc(void *, u32, void *); + + bool IsValid() { return mFrameHeap.PTR_0x0 != NULL; } + + OSMutex mMutex; // 0x00 + detail::FrameHeap mFrameHeap; // 0x1C + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_SoundInstanceManager.h b/include/nw4r/snd/snd_SoundInstanceManager.h new file mode 100644 index 00000000..3bb4a445 --- /dev/null +++ b/include/nw4r/snd/snd_SoundInstanceManager.h @@ -0,0 +1,61 @@ +#ifndef NW4R_SND_SOUND_INSTANCE_MANAGER_H +#define NW4R_SND_SOUND_INSTANCE_MANAGER_H +#include +#include "types_nw4r.h" +#include "ut_lock.h" +#include "ut_LinkList.h" +#include "snd_InstancePool.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + template + struct SoundInstanceManager + { + MemoryPool mPool; // at 0x0 + ut::LinkList mPriorityList; // at 0x4 + OSMutex mMutex; // at 0x10 + + inline void Free(T * pInstance) + { + ut::detail::AutoLock lock(mMutex); + + if (mPriorityList.IsEmpty()) return; + + mPriorityList.Erase(pInstance); + mPool.Free(pInstance); + } + + inline void InsertPriorityList(T * pInstance, int priority) + { + ut::LinkList::Iterator iter = mPriorityList.GetBeginIter(); + int curPriority; + + while (iter != mPriorityList.GetEndIter()) + { + curPriority = iter->CalcCurrentPlayerPriority(); + + if (priority < curPriority) break; + + iter++; + } + + mPriorityList.Insert(iter, pInstance); + } + + inline void UpdatePriority(T * pInstance, int priority) + { + ut::detail::AutoLock lock(mMutex); + + mPriorityList.Erase(pInstance); + InsertPriorityList(pInstance, priority); + } + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_SoundMemoryAllocatable.h b/include/nw4r/snd/snd_SoundMemoryAllocatable.h new file mode 100644 index 00000000..218df211 --- /dev/null +++ b/include/nw4r/snd/snd_SoundMemoryAllocatable.h @@ -0,0 +1,17 @@ +#ifndef NW4R_SOUND_MEMORY_ALLOCATABLE_H +#define NW4R_SOUND_MEMORY_ALLOCATABLE_H +#include "types_nw4r.h" + +namespace nw4r +{ + namespace snd + { + struct SoundMemoryAllocatable + { + virtual ~SoundMemoryAllocatable() {} // at 0x8 + virtual void * Alloc(u32) = 0; // at 0xc + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_SoundPlayer.h b/include/nw4r/snd/snd_SoundPlayer.h new file mode 100644 index 00000000..24ceee98 --- /dev/null +++ b/include/nw4r/snd/snd_SoundPlayer.h @@ -0,0 +1,36 @@ +#ifndef NW4R_SND_SOUND_PLAYER_H +#define NW4R_SND_SOUND_PLAYER_H +#include "types_nw4r.h" + +namespace nw4r +{ + namespace snd + { + class SoundPlayer + { + public: + + f32 GetVolume() const { return mVolume; } + f32 detail_GetMainOutVolume() const { return mMainOutVolume; } + + void StopAllSound(int); + + bool detail_IsEnabledOutputLine() const; + int detail_GetOutputLine() const; + f32 detail_GetRemoteOutVolume(int) const; + UNKTYPE detail_FreePlayerHeap(detail::BasicSound *); + UNKTYPE detail_InsertPriorityList(detail::BasicSound *); + UNKTYPE detail_RemoveSoundList(detail::BasicSound *); + UNKTYPE detail_RemovePriorityList(detail::BasicSound *); + + private: + char UNK_0x0[0x28]; + f32 mVolume; // at 0x28 + bool mEnableOutputLine; // at 0x2C + int mOutputLine; // at 0x30 + f32 mMainOutVolume; // at 0x34 + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_SoundStartable.h b/include/nw4r/snd/snd_SoundStartable.h new file mode 100644 index 00000000..2868fd83 --- /dev/null +++ b/include/nw4r/snd/snd_SoundStartable.h @@ -0,0 +1,48 @@ +#ifndef NW4R_SND_SOUND_STARTABLE_H +#define NW4R_SND_SOUND_STARTABLE_H +#include "snd_BasicSound.h" +#include "types_nw4r.h" + +namespace nw4r +{ + namespace snd + { + struct SoundStartable + { + struct StartInfo + { + + }; + + inline SoundStartable() {} + inline virtual ~SoundStartable() {} // at 0x8 + virtual UNKWORD detail_SetupSound(SoundHandle *, + u32, + detail::BasicSound::AmbientArgInfo *, + detail::ExternalSoundPlayer *, + bool, + const StartInfo *) = 0; // at 0xc + virtual UNKWORD detail_ConvertLabelStringToSoundId(const char *) = 0; // at 0x10 + + UNKWORD detail_StartSound(SoundHandle *, + u32, + detail::BasicSound::AmbientArgInfo *, + detail::ExternalSoundPlayer *, + const StartInfo *); + + UNKWORD detail_HoldSound(SoundHandle *, + u32, + detail::BasicSound::AmbientArgInfo *, + detail::ExternalSoundPlayer *, + const StartInfo *); + + UNKWORD detail_PrepareSound(SoundHandle *, + u32, + detail::BasicSound::AmbientArgInfo *, + detail::ExternalSoundPlayer *, + const StartInfo *); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_SoundSystem.h b/include/nw4r/snd/snd_SoundSystem.h index 0dd206f2..c60affc9 100644 --- a/include/nw4r/snd/snd_SoundSystem.h +++ b/include/nw4r/snd/snd_SoundSystem.h @@ -1,23 +1,36 @@ -#pragma once - -#include "nw4r/nw4r_types.h" +#ifndef NW4R_SND_SOUND_SYSTEM_H +#define NW4R_SND_SOUND_SYSTEM_H +#include "types_nw4r.h" +#include "snd_AxManager.h" namespace nw4r { -namespace snd -{ - -class SoundSystem { -public: - struct SoundSystemParam { - int soundThreadPriority; - int soundThreadStackSize; - int dvdThreadPriority; - int dvdThreadStackSize; - }; -}; + namespace snd + { + struct SoundSystem + { + struct SoundSystemParam + { -} // namespace snd - -} // namespace nw4r + }; + static inline f32 GetMasterVolume() + { + return detail::AxManager::GetInstance().GetMasterVolume(); + } + + static inline void PrepareReset() + { + detail::AxManager::GetInstance().PrepareReset(); + } + + void InitSoundSystem(s32, s32); + void InitSoundSystem(const SoundSystemParam&, void *, u32); + static void ShutdownSoundSystem(); + static void WaitForResetReady(); + UNKWORD GetRequiredMemSize(const SoundSystemParam &); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_SoundThread.h b/include/nw4r/snd/snd_SoundThread.h new file mode 100644 index 00000000..ca27746d --- /dev/null +++ b/include/nw4r/snd/snd_SoundThread.h @@ -0,0 +1,82 @@ +#ifndef NW4R_SND_SOUND_THREAD_H +#define NW4R_SND_SOUND_THREAD_H +#include "snd_AxManager.h" +#include "types_nw4r.h" +#include "ut_LinkList.h" +#include +#include +#include + + +namespace nw4r { +namespace snd { +namespace detail { +class SoundThread { +public: + struct SoundThreadCallback { + ut::LinkListNode mNode; // at 0x0 + + inline virtual ~SoundThreadCallback() {} // at 0x8 + inline virtual void VF_0xC() {} // at 0xC + inline virtual void VF_0x10() {} // at 0x10 + }; + + struct PlayerCallback { + ut::LinkListNode mNode; // at 0x0 + + inline virtual ~PlayerCallback() {} // at 0x8 + inline virtual void OnUpdateFrameSoundThread() {} // at 0xc + inline virtual void OnUpdateVoiceSoundThread() {} // at 0x10 + inline virtual void OnShutdownSoundThread() {} // at 0x14 + }; + + struct AutoLock { + inline AutoLock() { + GetInstance()->Lock(); + } + inline ~AutoLock() { + GetInstance()->Unlock(); + } + }; + +public: + static SoundThread *GetInstance(); + + SoundThread(); + ~SoundThread() {} + + void Lock() { + OSLockMutex(&mMutex); + } + void Unlock() { + OSUnlockMutex(&mMutex); + } + + bool Create(s32, void *, u32); + void Shutdown(); + static void AxCallbackFunc(); + void AxCallbackProc(); + static void *SoundThreadFunc(void *); + void RegisterPlayerCallback(PlayerCallback *); + void UnregisterPlayerCallback(PlayerCallback *); + void SoundThreadProc(); + +private: + OSThread mThread; // at 0x0 + OSThreadQueue mThreadQueue; // at 0x318 + OSMessageQueue mMesgQueue; // at 0x320 + OSMessage mMesgBuffer; // at 0x340 + char UNK_0x344[0x350 - 0x344]; + void *mStackEnd; // at 0x350 + OSMutex mMutex; // at 0x354 + AxManager::CallbackListNode mAxNode; // at 0x36C + ut::LinkList mThreadCbList; // at 0x378 + ut::LinkList mPlayerCbList; // at 0x384 + s32 mLastUpdateTime; // at 0x390 + bool mIsCreated; // at 0x394 +}; +} // namespace detail +} // namespace snd +} // namespace nw4r + +#endif diff --git a/include/nw4r/snd/snd_StrmChannel.h b/include/nw4r/snd/snd_StrmChannel.h new file mode 100644 index 00000000..20abdcc7 --- /dev/null +++ b/include/nw4r/snd/snd_StrmChannel.h @@ -0,0 +1,31 @@ +#ifndef NW4R_SND_STRMCHANNEL_H +#define NW4R_SND_STRMCHANNEL_H +#include "types_nw4r.h" + +#define BLOCK_MAX 0x20 + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct StrmBufferPool + { + void Setup(void *, u32, int); + void Shutdown(); + void * Alloc(); + void Free(void *); + + void *mBuffer; // at 0x0 + u32 mStrmBufferSize; // at 0x4 + u32 mBlockSize; // at 0x8 + s32 mBlockCount; // at 0xC (< BLOCK_MAX) + s32 mAllocCount; // at 0x10 + u8 mAllocFlags[4]; // at 0x14 (1 bit per block) + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_StrmPlayer.h b/include/nw4r/snd/snd_StrmPlayer.h new file mode 100644 index 00000000..1cd14dba --- /dev/null +++ b/include/nw4r/snd/snd_StrmPlayer.h @@ -0,0 +1,63 @@ +#ifndef NW4R_SND_STRMPLAYER_H +#define NW4R_SND_STRMPLAYER_H +#include "types_nw4r.h" +#include "snd_BasicPlayer.h" +#include "snd_SoundThread.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct StrmPlayer : BasicPlayer, SoundThread::PlayerCallback + { + enum StartOffsetType + { + + }; + + virtual ~StrmPlayer(); // at 0x8 + virtual bool Start(); // at 0xc + virtual void Stop(); // at 0x10 + virtual void Pause(bool); // at 0x14 + virtual bool IsActive() const; // at 0x18 + virtual bool IsStarted() const; // at 0x1c + virtual bool IsPause() const; // at 0x20 + + virtual void OnUpdateFrameSoundThread(); // at 0xc + virtual void OnUpdateVoiceSoundThread(); // at 0x10 + virtual void OnShutdownSoundThread(); // at 0x14 + + struct StrmDataLoadTask + { + virtual ~StrmDataLoadTask(); + virtual UNKTYPE Execute(); + virtual UNKTYPE Cancel(); + virtual UNKTYPE OnCancel(); + }; + + struct StrmHeaderLoadTask + { + virtual ~StrmHeaderLoadTask(); + virtual UNKTYPE Execute(); + virtual UNKTYPE Cancel(); + virtual UNKTYPE OnCancel(); + }; + + bool IsPrepared() const { return mIsPrepared; } + + StrmPlayer(); + bool Setup(StrmBufferPool *); + bool Prepare(ut::FileStream *, int, StartOffsetType, int); + void Shutdown(); + + char UNK_D8[0x113 - 0xD8]; + bool mIsPrepared; // at 0x113 + char UNK_120[0x78C]; + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_StrmSound.h b/include/nw4r/snd/snd_StrmSound.h new file mode 100644 index 00000000..d77ca533 --- /dev/null +++ b/include/nw4r/snd/snd_StrmSound.h @@ -0,0 +1,39 @@ +#ifndef NW4R_SND_STRMSOUND_H +#define NW4R_SND_STRMSOUND_H +#include "types_nw4r.h" +#include "snd_BasicSound.h" +#include "snd_StrmPlayer.h" +#include "ut_RuntimeTypeInfo.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct StrmSound : BasicSound + { + StrmPlayer mPlayer; // at 0xD8 + StrmSoundHandle *mTempSpecialHandle; // at 0x920 + SoundInstanceManager *mManager; // at 0x924 + + StrmSound(SoundInstanceManager *); + bool Prepare(StrmBufferPool *, StrmPlayer::StartOffsetType, s32, int, ut::FileStream *); + + static ut::detail::RuntimeTypeInfo typeInfo; + + virtual const ut::detail::RuntimeTypeInfo * GetRuntimeTypeInfo() const; // at 0x8 + virtual ~StrmSound(); // at 0xc + virtual UNKTYPE Shutdown(); // at 0x28 + virtual bool IsPrepared() const; // at 0x2c + virtual void SetPlayerPriority(int); // at 0x4c + virtual bool IsAttachedTempSpecialHandle(); // at 0x5c + virtual UNKTYPE DetachTempSpecialHandle(); // at 0x60 + virtual BasicPlayer * GetBasicPlayer(); // at 0x68 + virtual const BasicPlayer * GetBasicPlayer() const; // at 0x6c + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_StrmSoundHandle.h b/include/nw4r/snd/snd_StrmSoundHandle.h new file mode 100644 index 00000000..c64e61ee --- /dev/null +++ b/include/nw4r/snd/snd_StrmSoundHandle.h @@ -0,0 +1,24 @@ +#ifndef NW4R_SND_STRMSOUNDHANDLE_H +#define NW4R_SND_STRMSOUNDHANDLE_H +#include "types_nw4r.h" + +namespace nw4r +{ + namespace snd + { + struct StrmSoundHandle + { + detail::StrmSound *mStrmSound; // at 0x0 + + inline StrmSoundHandle() : mStrmSound(NULL) {} + inline bool IsAttachedSound() + { + return mStrmSound != NULL; + } + + void DetachSound(); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_Task.h b/include/nw4r/snd/snd_Task.h new file mode 100644 index 00000000..688a2c99 --- /dev/null +++ b/include/nw4r/snd/snd_Task.h @@ -0,0 +1,28 @@ +#ifndef NW4R_SND_TASK_H +#define NW4R_SND_TASK_H +#include "types_nw4r.h" +#include "ut_LinkList.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct Task + { + virtual ~Task(); // at 0x8 + virtual void Execute() = 0; // at 0xc + virtual void Cancel() = 0; // at 0x10 + virtual void OnCancel() = 0; // at 0x14 + + ut::LinkListNode mNode; // at 0x4 + char BYTE_0xC; + + inline Task() : BYTE_0xC() {} + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_TaskManager.h b/include/nw4r/snd/snd_TaskManager.h new file mode 100644 index 00000000..978fe886 --- /dev/null +++ b/include/nw4r/snd/snd_TaskManager.h @@ -0,0 +1,48 @@ +#ifndef NW4R_SND_TASK_MANAGER_H +#define NW4R_SND_TASK_MANAGER_H +#include "snd_Task.h" +#include "types_nw4r.h" +#include "ut_LinkList.h" +#include "ut_lock.h" +#include + + +namespace nw4r { +namespace snd { +namespace detail { +struct TaskManager { + enum TaskPriority { + PRIORITY_0 = 0, + PRIORITY_1 = 1, + PRIORITY_2 = 2 + // PRIORITY_MAX = 3 + }; + + inline TaskManager() : mTaskStacks(), WORD_0x24(0), BYTE_0x28(0) { + OSInitThreadQueue(&mQueue_0x2C); + OSInitThreadQueue(&mQueue_0x34); + } + + static TaskManager *GetInstance(); + + ~TaskManager(); + void AppendTask(Task *, TaskPriority); + Task *PopTask(); + UNKTYPE GetNextTask(); + UNKTYPE ExecuteTask(); + UNKTYPE CancelTask(Task *); + UNKTYPE CancelAllTask(); + UNKTYPE WaitTask(); + UNKTYPE CancelWaitTask(); + + ut::LinkList mTaskStacks[3]; + u32 WORD_0x24; + u8 BYTE_0x28; + OSThreadQueue mQueue_0x2C; + OSThreadQueue mQueue_0x34; +}; +} // namespace detail +} // namespace snd +} // namespace nw4r + +#endif diff --git a/include/nw4r/snd/snd_TaskThread.h b/include/nw4r/snd/snd_TaskThread.h new file mode 100644 index 00000000..6cb6e4df --- /dev/null +++ b/include/nw4r/snd/snd_TaskThread.h @@ -0,0 +1,26 @@ +#ifndef NW4R_SND_TASKTHREAD_H +#define NW4R_SND_TASKTHREAD_H +#include "types_nw4r.h" +#include + +namespace nw4r { +namespace snd { +namespace detail { +struct TaskThread { + static void *ThreadFunc(void *); + + TaskThread(); + ~TaskThread(); + bool Create(s32, void *, u32); + void Destroy(); + + OSThread mThread; // at 0x0 + void *mStackEnd; // at 0x318 + bool mIsExiting; // at 0x31C + bool mIsAlive; // at 0x31D +}; +} // namespace detail +} // namespace snd +} // namespace nw4r + +#endif diff --git a/include/nw4r/snd/snd_Util.h b/include/nw4r/snd/snd_Util.h new file mode 100644 index 00000000..dd48ddf5 --- /dev/null +++ b/include/nw4r/snd/snd_Util.h @@ -0,0 +1,78 @@ +#ifndef NW4R_SND_UTIL_H +#define NW4R_SND_UTIL_H +#include "types_nw4r.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + namespace Util + { + enum RefType + { + REFTYPE_ADDRESS, + REFTYPE_OFFSET, + }; + + template + struct DataRef + { + u8 mType; // at 0x0 + u8 BYTE_0x1; + u32 INT_0x4; + }; + + template + struct Table + { + u32 mCount; // at 0x0 + T mEntries[]; // at 0x4 + }; + + struct PanInfo + { + u32 mPanTableID; // 0x0, (PanTableTable) + bool BOOL_0x4; + bool BOOL_0x5; + }; + + template + inline const T0 * GetDataRefAddress0(const DataRef & dataRef, const void * ptr) + { + return (const T0 *)GetDataRefAddressImpl((RefType)dataRef.mType, dataRef.INT_0x4, ptr); + } + + template + inline const T1 * GetDataRefAddress1(const DataRef & dataRef, const void * ptr) + { + return (const T1 *)GetDataRefAddressImpl((RefType)dataRef.mType, dataRef.INT_0x4, ptr); + } + + template + inline const T2 * GetDataRefAddress2(const DataRef & dataRef, const void * ptr) + { + return (const T2 *)GetDataRefAddressImpl((RefType)dataRef.mType, dataRef.INT_0x4, ptr); + } + + template + inline const T3 * GetDataRefAddress3(const DataRef & dataRef, const void * ptr) + { + return (const T3 *)GetDataRefAddressImpl((RefType)dataRef.mType, dataRef.INT_0x4, ptr); + } + + f32 CalcPitchRatio(int); + f32 CalcVolumeRatio(f32); + f32 CalcPanRatio(f32, const PanInfo&); + f32 CalcSurroundPanRatio(f32, const PanInfo&); + int CalcLpfFreq(f32); + void GetRemoteFilterCoefs(int, u16 *, u16 *, u16 *, u16 *, u16 *); + u16 CalcRandom(); + const void * GetDataRefAddressImpl(RefType, u32, const void *); + } + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_Voice.h b/include/nw4r/snd/snd_Voice.h new file mode 100644 index 00000000..f96b19d1 --- /dev/null +++ b/include/nw4r/snd/snd_Voice.h @@ -0,0 +1,67 @@ +#ifndef NW4R_SND_VOICE_H +#define NW4R_SND_VOICE_H +#include "types_nw4r.h" +#include "snd_AxManager.h" +#include "snd_WaveFile.h" +#include "snd_Common.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct Voice + { + enum VoiceCallbackStatus + { + STATUS_0, + STATUS_1, + STATUS_2, + STATUS_3 + }; + + enum VoiceSyncFlag { + SYNC_AX_SRC_INITIAL = (1 << 0), + SYNC_AX_VOICE = (1 << 1), + SYNC_AX_SRC = (1 << 2), + SYNC_AX_VE = (1 << 3), + SYNC_AX_MIX = (1 << 4), + SYNC_AX_LPF = (1 << 5), + SYNC_AX_REMOTE = (1 << 7), + SYNC_AX_BIQUAD = (1 << 8), + }; + + typedef void (* VoiceCallback)(Voice *, VoiceCallbackStatus, void *); + + UNKTYPE Start(); + UNKTYPE Setup(const WaveData &, u32); + UNKTYPE SetPriority(int); + UNKTYPE Stop(); + UNKTYPE Free(); + UNKTYPE SetPanMode(PanMode); + UNKTYPE SetPanCurve(PanCurve); + UNKTYPE SetVolume(float); + UNKTYPE SetVeVolume(float, float); + UNKTYPE SetPitch(float); + UNKTYPE SetPan(float); + UNKTYPE SetSurroundPan(float); + UNKTYPE SetLpfFreq(float); + UNKTYPE SetRemoteFilter(int); + UNKTYPE SetOutputLine(int); + UNKTYPE SetMainOutVolume(float); + UNKTYPE SetMainSend(float); + + UNKTYPE SetFxSend(AuxBus, float); + + UNKTYPE SetRemoteOutVolume(int, float); + UNKTYPE SetRemoteSend(int, float); + UNKTYPE SetRemoteFxSend(int, float); + + UNKTYPE Pause(bool); + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_VoiceManager.h b/include/nw4r/snd/snd_VoiceManager.h new file mode 100644 index 00000000..1706d975 --- /dev/null +++ b/include/nw4r/snd/snd_VoiceManager.h @@ -0,0 +1,25 @@ +#ifndef NW4R_SND_VOICE_MANAGER_H +#define NW4R_SND_VOICE_MANAGER_H +#include "types_nw4r.h" +#include "snd_Voice.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct VoiceManager + { + static VoiceManager& GetInstance(); + + Voice * AllocVoice(int, int, int, Voice::VoiceCallback, void *); + void UpdateAllVoices(); + void NotifyVoiceUpdate(); + UNKTYPE UpdateAllVoicesSync(u32); + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_WaveFile.h b/include/nw4r/snd/snd_WaveFile.h new file mode 100644 index 00000000..0bd32763 --- /dev/null +++ b/include/nw4r/snd/snd_WaveFile.h @@ -0,0 +1,39 @@ +#ifndef NW4R_SND_WAVE_FILE_H +#define NW4R_SND_WAVE_FILE_H +#include "types_nw4r.h" +#include "ut_binaryFileFormat.h" +#include "snd_Util.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct WaveData + { + char UNK_0x0[0x2]; + u8 BYTE_0x2; + char UNK_0x4[0x90]; + }; + + struct WaveFile + { + struct WaveInfo + { + + }; + + typedef Util::DataRef Region; + }; + + struct WaveFileReader + { + WaveFileReader(const WaveFile::WaveInfo *); + bool ReadWaveParam(WaveData *, const void *) const; + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_WaveSound.h b/include/nw4r/snd/snd_WaveSound.h new file mode 100644 index 00000000..d240e3cb --- /dev/null +++ b/include/nw4r/snd/snd_WaveSound.h @@ -0,0 +1,42 @@ +#ifndef NW4R_SND_WAVESOUND_H +#define NW4R_SND_WAVESOUND_H +#include "types_nw4r.h" +#include "snd_BasicSound.h" +#include "snd_WsdPlayer.h" +#include "ut_RuntimeTypeInfo.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct WaveSound : BasicSound + { + WsdPlayer mPlayer; // at 0xD8 + WaveSoundHandle *mTempSpecialHandle; // at 0x1B0 + SoundInstanceManager *mManager; // at 0x1B4 + bool mIsPrepared; // at 0x1B8 + + WaveSound(SoundInstanceManager *); + bool Prepare(const void *, long, WsdPlayer::StartOffsetType, s32, int, const WsdPlayer::WsdCallback *, u32); + void SetChannelPriority(int); + void SetReleasePriorityFix(bool); + + static ut::detail::RuntimeTypeInfo typeInfo; + + virtual const ut::detail::RuntimeTypeInfo * GetRuntimeTypeInfo() const; // at 0x8 + virtual ~WaveSound(); // at 0xc + virtual UNKTYPE Shutdown(); // at 0x28 + virtual bool IsPrepared() const; // at 0x2c + virtual void SetPlayerPriority(int); // at 0x4c + virtual bool IsAttachedTempSpecialHandle(); // at 0x5c + virtual UNKTYPE DetachTempSpecialHandle(); // at 0x60 + virtual BasicPlayer * GetBasicPlayer(); // at 0x68 + virtual const BasicPlayer * GetBasicPlayer() const; // at 0x6c + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_WaveSoundHandle.h b/include/nw4r/snd/snd_WaveSoundHandle.h new file mode 100644 index 00000000..e9a150db --- /dev/null +++ b/include/nw4r/snd/snd_WaveSoundHandle.h @@ -0,0 +1,24 @@ +#ifndef NW4R_SND_WAVESOUNDHANDLE_H +#define NW4R_SND_WAVESOUNDHANDLE_H +#include "types_nw4r.h" + +namespace nw4r +{ + namespace snd + { + struct WaveSoundHandle + { + detail::WaveSound *mWaveSound; // at 0x0 + + inline WaveSoundHandle() : mWaveSound(NULL) {} + inline bool IsAttachedSound() + { + return mWaveSound != NULL; + } + + void DetachSound(); + }; + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_WsdPlayer.h b/include/nw4r/snd/snd_WsdPlayer.h new file mode 100644 index 00000000..80a2a0b5 --- /dev/null +++ b/include/nw4r/snd/snd_WsdPlayer.h @@ -0,0 +1,53 @@ +#ifndef NW4R_SND_WSDPLAYER_H +#define NW4R_SND_WSDPLAYER_H +#include "types_nw4r.h" +#include "snd_BasicPlayer.h" +#include "snd_DisposeCallback.h" +#include "snd_SoundThread.h" +#include "snd_Lfo.h" + +namespace nw4r +{ + namespace snd + { + namespace detail + { + struct WsdPlayer : BasicPlayer, DisposeCallback, SoundThread::PlayerCallback + { + enum StartOffsetType + { + + }; + + virtual ~WsdPlayer() {} // at 0x8 + virtual bool Start(); // at 0xc + virtual void Stop(); // at 0x10 + virtual void Pause(bool); // at 0x14 + virtual bool IsActive() const; // at 0x18 + virtual bool IsStarted() const; // at 0x1c + virtual bool IsPause() const; // at 0x20 + + virtual void OnUpdateFrameSoundThread(); // at 0xc + virtual void OnUpdateVoiceSoundThread(); // at 0x10 + virtual void OnShutdownSoundThread(); // at 0x14 + + virtual void InvalidateData(const void *, const void *); // at 0xc + virtual void InvalidateWaveData(const void *, const void *); // at 0x10 + + struct WsdCallback + { + virtual ~WsdCallback(); + }; + + WsdPlayer(); + bool Prepare(const void *, int, WsdPlayer::StartOffsetType, int, int, const WsdPlayer::WsdCallback *, u32); + void SetChannelPriority(int); + void SetReleasePriorityFix(bool); + + char UNK_0xE4[0x4C]; + }; + } + } +} + +#endif \ No newline at end of file diff --git a/include/nw4r/snd/snd_adpcm.h b/include/nw4r/snd/snd_adpcm.h new file mode 100644 index 00000000..368a3510 --- /dev/null +++ b/include/nw4r/snd/snd_adpcm.h @@ -0,0 +1,16 @@ +#ifndef NW4R_SND_ADPCM_H +#define NW4R_SND_ADPCM_H +#include +#include + +namespace nw4r { +namespace snd { +namespace detail { + +s16 DecodeDspAdpcm(AXPBADPCM *adpcm, u8 bits); + +} // namespace detail +} // namespace snd +} // namespace nw4r + +#endif diff --git a/include/nw4r/types_nw4r.h b/include/nw4r/types_nw4r.h new file mode 100644 index 00000000..47e53320 --- /dev/null +++ b/include/nw4r/types_nw4r.h @@ -0,0 +1,233 @@ +#ifndef NW4R_TYPES_H +#define NW4R_TYPES_H +#include + +#define NW4R_BYTEORDER_BIG 0xFEFF +#define NW4R_BYTEORDER_LITTLE 0xFFFE + +#define NW4R_VERSION(major, minor) ((major & 0xFF) << 8 | minor & 0xFF) + +namespace nw4r { +namespace ut { +namespace detail { + +struct RuntimeTypeInfo; +struct ResFontBase; + +} // namespace detail + +template +struct AutoLock; +struct AutoInterruptLock; +struct BinaryBlockHeader; +struct BinaryFileHeader; +struct CharStrmReader; +struct CharWidths; +struct CharWriter; +struct Color; +struct DvdFileStream; +struct DvdLockedFileStream; +struct FileStream; +struct Font; +struct Glyph; +struct IOStream; +template +struct LinkList; +struct List; +struct NandFileStream; +template +struct PrintContext; +struct Rect; +struct ResFont; +struct RomFont; +template +struct TagProcessorBase; +template +struct TextWriterBase; + +} // namespace ut + +namespace ef { +struct DrawOrder; +struct DrawInfo; +struct DrawStrategy; +struct DrawStrategyImpl; +struct DrawStrategyBuilder; +struct Effect; +struct EffectSystem; +struct EffectProject; +struct Emitter; +struct EmitterDrawSetting; +struct EmitFormBuilder; +struct ResEmitter; +struct EmitterResource; +struct EmitterForm; +struct EmitterInheritSetting; +struct Particle; +struct ParticleManager; +struct MemoryManager; +struct MemoryManagerBase; +} // namespace ef + +namespace math { + +struct VEC2; +struct VEC3; +struct MTX33; +struct MTX34; +struct MTX44; +struct QUAT; +struct PLANE; +struct AABB; +struct FRUSTUM; + +} // namespace math + +namespace snd { + +struct AxVoice; +struct FxBase; +struct SoundPlayer; +struct SoundHandle; +struct SeqSoundHandle; +struct SoundArchive; +struct SoundArchivePlayer; +struct Sound3DActor; +struct Sound3DListener; +struct Sound3DManager; +struct SoundHandle; +struct StrmSoundHandle; +struct WaveSoundHandle; + +namespace detail { + +struct AxfxImpl; +struct AxManager; +struct AxVoiceManager; +struct ExternalSoundPlayer; + +struct BasicSound; +struct BasicPlayer; +struct ChannelManager; +struct SeqSound; +struct SeqPlayer; +struct MmlParser; +struct MmlSeqTrack; +struct SeqTrack; +struct SeqTrackAllocator; +template +struct SoundInstanceManager; +struct StrmBufferPool; +struct StrmSound; +struct NoteOnCallback; +struct PlayerHeap; +struct SoundArchiveFileReader; +struct SoundThread; +struct WaveSound; +struct StrmPlayer; +struct WsdPlayer; +} // namespace detail +} // namespace snd + +namespace g3d { +struct AnmObjVis; +struct AnmObjVisNode; +struct AnmObjVisOR; +struct AnmObjVisRes; +struct AnmObj; +struct AnmObjChr; +struct FuncObjCalcWorld; +struct AnmScn; +struct AnmScnRes; +struct CameraAnmResult; +struct Draw1Mat1ShpSwap; +struct DrawResMdlReplacement; +struct FogAnmResult; +struct ResFile; +struct ResMdl; +struct ResPltt; +struct ResTex; +struct ResTexSrt; +struct ResMat; +struct ResTexPlttInfo; +struct ResShp; +struct ResFog; +struct ResAnmChr; +struct ResAnmVis; +struct ResAnmClr; +struct ResAnmTexPat; +struct ResAnmTexSrt; +struct ResAnmShp; +struct ResAnmScn; +struct ResAnmFog; +struct ResAnmCamera; +struct ResVtxPos; +struct ResVtxNrm; +struct ResVtxClr; +struct ResVtxTexCoord; +struct ClrAnmResult; +struct TexPatAnmResult; +struct TexSrtAnmResult; +struct ScnMdl1Mat1Shp; +struct TexSrt; +struct TexSrtTypedef; +struct LightObj; +struct LightAnmResult; +struct LightSet; +struct LightSetting; +struct LightSetData; +struct AmbLightObj; +struct AmbLightAnmResult; +struct Fog; +struct ScnRoot; +struct ScnProc; +struct ScnLeaf; +struct ScnObj; +struct ScnRfl; +struct ScnGroup; +struct ScnMdlSimple; +struct ScnMdl; +struct IScnObjGather; +struct IScnObjCallback; + +namespace G3DState { +struct IndMtxOp; +} +} // namespace g3d + +namespace lyt { +struct Size; + +namespace detail { +struct PaneBase; +struct TexCoordAry; +} // namespace detail + +namespace res { +struct Group; +struct Pane; +struct Bounding; +struct AnimationBlock; +struct BinaryFileHeader; +} // namespace res + +struct Group; +struct GroupContainer; +struct Pane; +struct DrawInfo; +struct AnimResource; +struct AnimTransform; +struct AnimTransformBasic; +struct AnimationLink; +struct ResourceAccessor; +struct ArcResourceAccessor; +struct FontRefLink; +struct Material; +struct Layout; +struct Bounding; +struct ResBlockSet; +struct TexMap; +} // namespace lyt +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut.h b/include/nw4r/ut.h new file mode 100644 index 00000000..0b8309fc --- /dev/null +++ b/include/nw4r/ut.h @@ -0,0 +1,28 @@ +#ifndef NW4R_PUBLIC_UT_H +#define NW4R_PUBLIC_UT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/include/nw4r/ut/Color.h b/include/nw4r/ut/Color.h deleted file mode 100644 index 57312e54..00000000 --- a/include/nw4r/ut/Color.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "rvl/GX.h" -#include - - -namespace nw4r { -namespace ut { - -struct Color : public _GXColor { - Color() {} - /* 80007bc0 */ ~Color(); - Color(u32 color) { - *(u32 *)this = color; - } - - Color &operator=(u32 color) { - *(u32 *)this = color; - return *this; - } -}; - -} // namespace ut -} // namespace nw4r diff --git a/include/nw4r/ut/List.h b/include/nw4r/ut/List.h deleted file mode 100644 index 194f67a8..00000000 --- a/include/nw4r/ut/List.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -// This file was ported from https://github.com/riidefi/mkw/blob/master/source/nw4r/ut/utList.hpp - -#include - -// TODO: Doc file boundaries - -namespace nw4r { -namespace ut { - -//! Bidirectional list node -struct Node { - void *pred; - void *succ; -}; - -// Unlike modern "std::list"-like structures, list nodes are directly inherited -// by children, which saves a level of indirection. -struct List { - void *head; - void *tail; - u16 count; - u16 intrusion_offset; -}; - -void List_Init(List *pList, u16 intrusion_offset); -void List_Append(List *pList, void *pObj); -void List_Insert(List *pList, void *pTgt, void *pObj); -void List_Remove(List *pList, void *pObj); -void *List_GetNext(const List *, const void *); -void *List_GetPrev(const List *, const void *); -void *List_GetNth(const List *pList, unsigned short); -inline void *List_GetFirst(const List *pList) { - return List_GetNext(pList, nullptr); -} -// Seems to be not included as a symbol. Only inlined. -// void List_Prepend(List* pList, void* pObj); - -} // namespace ut -} // namespace nw4r diff --git a/include/nw4r/ut/ut_CharStrmReader.h b/include/nw4r/ut/ut_CharStrmReader.h new file mode 100644 index 00000000..e5305c47 --- /dev/null +++ b/include/nw4r/ut/ut_CharStrmReader.h @@ -0,0 +1,43 @@ +#ifndef NW4R_UT_CHAR_STRM_READER_H +#define NW4R_UT_CHAR_STRM_READER_H +#include + +namespace nw4r { +namespace ut { + +class CharStrmReader { +public: + typedef u16 (CharStrmReader::*ReadFunc)(); + + CharStrmReader(ReadFunc func) : mCharStrm(NULL), mReadFunc(func) {} + ~CharStrmReader() {} + + u16 ReadNextCharUTF8(); + u16 ReadNextCharUTF16(); + u16 ReadNextCharCP1252(); + u16 ReadNextCharSJIS(); + + const void* GetCurrentPos() const { return mCharStrm; } + + template T GetChar(int offset) const { + return static_cast(mCharStrm)[offset]; + } + + template void StepStrm(int offset) { + static_cast(mCharStrm) += offset; + } + + u16 Next() { return (this->*mReadFunc)(); } + + void Set(const char* strm) { mCharStrm = strm; } + void Set(const wchar_t* strm) { mCharStrm = strm; } + +private: + const void* mCharStrm; // at 0x0 + ReadFunc mReadFunc; // at 0x4 +}; + +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut/ut_CharWriter.h b/include/nw4r/ut/ut_CharWriter.h new file mode 100644 index 00000000..e5801516 --- /dev/null +++ b/include/nw4r/ut/ut_CharWriter.h @@ -0,0 +1,191 @@ +#ifndef NW4R_UT_CHAR_WRITER_H +#define NW4R_UT_CHAR_WRITER_H +#include +#include +#include +#include + +namespace nw4r { +namespace ut { + +class CharWriter { +public: + enum GradationMode { GRADMODE_NONE, GRADMODE_H, GRADMODE_V }; + + struct ColorMapping { + Color min; // at 0x0 + Color max; // at 0x4 + }; + + struct VertexColor { + Color tl; // at 0x0 + Color tr; // at 0x4 + Color bl; // at 0x8 + Color br; // at 0xC + }; + + struct TextColor { + Color start; // at 0x0 + Color end; // at 0x4 + GradationMode gradMode; // at 0x8 + }; + + struct TextureFilter { + GXTexFilter atSmall; // at 0x0 + GXTexFilter atLarge; // at 0x4 + + bool operator!=(const TextureFilter &other) const { + return atSmall != other.atSmall || atLarge != other.atLarge; + } + }; + + struct LoadingTexture { + GXTexMapID slot; // at 0x0 + void *texture; // at 0x4 + TextureFilter filter; // at 0x8 + + bool operator!=(const LoadingTexture &other) const { + return slot != other.slot || texture != other.texture || filter != other.filter; + } + + void Reset() { + slot = GX_TEXMAP_NULL; + texture = NULL; + } + }; + +public: + static void SetupVertexFormat(); + static void SetupGXDefault(); + static void SetupGXWithColorMapping(Color min, Color max); + static void SetupGXForI(); + static void SetupGXForRGBA(); + + CharWriter(); + ~CharWriter(); + + void SetColorMapping(Color min, Color max) { + mColorMapping.min = min; + mColorMapping.max = max; + } + + void ResetColorMapping() { + SetColorMapping(Color(0x00000000), Color(0xFFFFFFFF)); + } + + void SetTextColor(Color start) { + mTextColor.start = start; + UpdateVertexColor(); + } + + void SetTextColor(Color start, Color end) { + mTextColor.start = start; + mTextColor.end = end; + UpdateVertexColor(); + } + + void SetGradationMode(GradationMode mode) { + mTextColor.gradMode = mode; + UpdateVertexColor(); + } + + f32 GetScaleH() const { + return mScale.x; + } + f32 GetScaleV() const { + return mScale.y; + } + + void SetScale(f32 x, f32 y) { + mScale.x = x; + mScale.y = y; + } + + f32 GetCursorX() const { + return mCursorPos.x; + } + void SetCursorX(f32 x) { + mCursorPos.x = x; + } + + f32 GetCursorY() const { + return mCursorPos.y; + } + void SetCursorY(f32 y) { + mCursorPos.y = y; + } + + void SetCursor(f32 x, f32 y) { + mCursorPos.x = x; + mCursorPos.y = y; + } + void SetCursor(f32 x, f32 y, f32 z) { + mCursorPos.x = x; + mCursorPos.y = y; + mCursorPos.z = z; + } + + void MoveCursorX(f32 dx) { + mCursorPos.x += dx; + } + void MoveCursorY(f32 dy) { + mCursorPos.y += dy; + } + + void EnableFixedWidth(bool enable) { + mIsWidthFixed = enable; + } + bool IsWidthFixed() const { + return mIsWidthFixed; + } + + void SetFixedWidth(f32 width) { + mFixedWidth = width; + } + f32 GetFixedWidth() const { + return mFixedWidth; + } + + void SetFont(const Font &font) { + mFont = &font; + } + const Font *GetFont() const { + return mFont; + } + + void ResetTextureCache() { + mLoadingTexture.Reset(); + } + + void SetupGX(); + void SetFontSize(f32 width, f32 height); + f32 GetFontWidth() const; + f32 GetFontHeight() const; + f32 GetFontAscent() const; + f32 GetFontDescent() const; + void EnableLinearFilter(bool atSmall, bool atLarge); + f32 Print(u16 ch); + void PrintGlyph(f32 x, f32 y, f32 z, const Glyph &glyph); + void LoadTexture(const Glyph &glyph, GXTexMapID slot); + void UpdateVertexColor(); + +private: + ColorMapping mColorMapping; // at 0x0 + VertexColor mVertexColor; // at 0x8 + TextColor mTextColor; // at 0x18 + math::VEC2 mScale; // at 0x24 + math::VEC3 mCursorPos; // at 0x2C + TextureFilter mFilter; // at 0x38 + u8 padding[2]; // at 0x40 + u8 mAlpha; // at 0x42 + bool mIsWidthFixed; // at 0x43 + f32 mFixedWidth; // at 0x44 + const Font *mFont; // at 0x48 + + static LoadingTexture mLoadingTexture; +}; + +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut/ut_Color.h b/include/nw4r/ut/ut_Color.h new file mode 100644 index 00000000..b9112d10 --- /dev/null +++ b/include/nw4r/ut/ut_Color.h @@ -0,0 +1,60 @@ +#ifndef NW4R_UT_COLOR_H +#define NW4R_UT_COLOR_H +#include +#include + +namespace nw4r { +namespace ut { + +class Color : public GXColor { +public: + Color() { + *this = 0xFFFFFFFF; + } + Color(u32 color) { + *this = color; + } + Color(int red, int green, int blue, int alpha) { + Set(red, green, blue, alpha); + } + ~Color() {} + + void Set(int red, int green, int blue, int alpha) { + r = red; + g = green; + b = blue; + a = alpha; + } + + Color &operator=(u32 color) { + ToU32ref() = color; + return *this; + } + + Color operator|(u32 color) { + return Color(ToU32() | color); + } + Color operator&(u32 color) { + return Color(ToU32() & color); + } + + u32 &ToU32ref() { + return *reinterpret_cast(this); + } + const u32 &ToU32ref() const { + return *reinterpret_cast(this); + } + + u32 ToU32() const { + return ToU32ref(); + } + + operator u32() const { + return ToU32ref(); + } +}; + +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut/ut_DvdFileStream.h b/include/nw4r/ut/ut_DvdFileStream.h new file mode 100644 index 00000000..5b000b6e --- /dev/null +++ b/include/nw4r/ut/ut_DvdFileStream.h @@ -0,0 +1,111 @@ +#ifndef NW4R_UT_DVD_FILE_STREAM_H +#define NW4R_UT_DVD_FILE_STREAM_H +#include +#include +#include + +namespace nw4r { +namespace ut { + +class DvdFileStream : public FileStream { +public: + NW4R_UT_RTTI_DECL(DvdFileStream); + + /** + * DVD callbacks need a reference to the NW4R stream. This structure is + * used to up-cast the DVDFileInfo given to the async callback. + * + * This structure's DVDFileInfo is always used in calls to async DVD + * functions, so the up-cast is always safe. + */ + struct AsyncContext { + DVDFileInfo info; // at 0x0 + DvdFileStream *stream; // at 0x3C + }; + +public: + DvdFileStream(s32 entrynum); + DvdFileStream(const DVDFileInfo *info, bool close); + virtual ~DvdFileStream(); // at 0xC + + virtual bool IsBusy() const { + return mIsBusy; + } // at 0x24 + + virtual u32 Tell() const { + return mFilePosition.Tell(); + } // at 0x58 + virtual u32 GetSize() const { + return mFilePosition.GetFileSize(); + } // at 0x40 + + virtual bool CanAsync() const { + return true; + } // at 0x28 + virtual bool CanSeek() const { + return true; + } // at 0x50 + virtual bool CanRead() const { + return true; + } // at 0x2C + virtual bool CanWrite() const { + return false; + } // at 0x30 + virtual bool CanCancel() const { + return true; + } // at 0x54 + + virtual u32 GetOffsetAlign() const { + return 4; + } // at 0x34 + virtual u32 GetSizeAlign() const { + return 32; + } // at 0x38 + virtual u32 GetBufferAlign() const { + return 32; + } // at 0x3C + + virtual void Close(); // at 0x10 + + virtual s32 Read(void *dst, u32 size); // at 0x14 + virtual bool ReadAsync(void *dst, u32 size, AsyncCallback callback, + void *arg); // at 0x18 + + virtual s32 Peek(void *dst, u32 size); // at 0x5C + virtual bool PeekAsync(void *dst, u32 size, AsyncCallback callback, + void *arg); // at 0x60 + + virtual void Seek(s32 offset, u32 origin); // at 0x44 + + virtual void Cancel(); // at 0x48 + virtual bool CancelAsync(AsyncCallback callback, void *arg); // at 0x4C + + void SetPriority(s32 priority) { + mPriority = priority; + } + + bool Open(s32 entrynum); + bool Open(const DVDFileInfo *info, bool close); + +private: + static void DvdAsyncCallback_(s32 result, DVDFileInfo *info); + static void DvdCBAsyncCallback_(s32 result, DVDCommandBlock *block); + + void Initialize_(); + u32 AdjustReadLength_(u32 len); + +private: + FilePosition mFilePosition; // at 0x14 + AsyncCallback mCancelCallback; // at 0x1C + void *mCancelCallbackArg; // at 0x20 + volatile bool mIsCancelling; // at 0x24 + AsyncContext mAsyncContext; // at 0x28 + s32 mPriority; // at 0x68 + volatile bool mIsBusy; // at 0x6C + bool mCloseOnDestroy; // at 0x6D + bool mAllowClose; // at 0x6E +}; + +} // namespace ut +} // namespace nw4r +#endif diff --git a/include/nw4r/ut/ut_DvdLockedFileStream.h b/include/nw4r/ut/ut_DvdLockedFileStream.h new file mode 100644 index 00000000..8bbf85af --- /dev/null +++ b/include/nw4r/ut/ut_DvdLockedFileStream.h @@ -0,0 +1,42 @@ +#ifndef NW4R_UT_DVD_LOCKED_FILE_STREAM_H +#define NW4R_UT_DVD_LOCKED_FILE_STREAM_H +#include +#include +#include + +namespace nw4r { +namespace ut { + +class DvdLockedFileStream : public DvdFileStream { +public: + NW4R_UT_RTTI_DECL(DvdLockedFileStream); + + DvdLockedFileStream(s32 entrynum); + DvdLockedFileStream(const DVDFileInfo *info, bool close); + virtual ~DvdLockedFileStream(); // at 0xC + + virtual s32 Read(void *dst, u32 size); // at 0x14 + virtual bool ReadAsync(void *dst, u32 size, AsyncCallback callback, void *arg) { + return false; + } // at 0x18 + + virtual s32 Peek(void *dst, u32 size); // at 0x5C + virtual bool PeekAsync(void *dst, u32 size, AsyncCallback callback, void *arg) { + return false; + } // at 0x60 + + virtual bool CanAsync() const { + return false; + } // at 0x28 + +private: + static void InitMutex_(); + +private: + static bool sInitialized; + static OSMutex sMutex; +}; + +} // namespace ut +} // namespace nw4r +#endif diff --git a/include/nw4r/ut/ut_FileStream.h b/include/nw4r/ut/ut_FileStream.h new file mode 100644 index 00000000..99e4b336 --- /dev/null +++ b/include/nw4r/ut/ut_FileStream.h @@ -0,0 +1,49 @@ +#ifndef NW4R_UT_FILE_STREAM_H +#define NW4R_UT_FILE_STREAM_H +#include +#include + +namespace nw4r { +namespace ut { + +class FileStream : public IOStream { +public: + NW4R_UT_RTTI_DECL(FileStream); + + enum SeekOrigin { SEEK_BEG, SEEK_CUR, SEEK_END }; + + class FilePosition { + public: + FilePosition() : mFileSize(0), mFileOffset(0) {} + + u32 GetFileSize() const { return mFileSize; } + void SetFileSize(u32 fileSize) { mFileSize = fileSize; } + + u32 Tell() const { return mFileOffset; } + + u32 Skip(s32 offset); + u32 Append(s32 offset); + void Seek(s32 offset, u32 origin); + + private: + u32 mFileSize; // at 0x0 + u32 mFileOffset; // at 0x4 + }; + +public: + FileStream() {} + virtual ~FileStream() {} // at 0xC + + virtual u32 GetSize() const = 0; // at 0x40 + virtual void Seek(s32 offset, u32 origin); // at 0x44 + virtual void Cancel(); // at 0x48 + virtual bool CancelAsync(AsyncCallback callback, void* arg); // at 0x4C + virtual bool CanSeek() const = 0; // at 0x50 + virtual bool CanCancel() const = 0; // at 0x54 + virtual u32 Tell() const = 0; // at 0x58 +}; + +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut/ut_Font.h b/include/nw4r/ut/ut_Font.h new file mode 100644 index 00000000..0aefe054 --- /dev/null +++ b/include/nw4r/ut/ut_Font.h @@ -0,0 +1,70 @@ +#ifndef NW4R_UT_FONT_H +#define NW4R_UT_FONT_H +#include +#include +#include + +namespace nw4r { +namespace ut { + +struct CharWidths { + s8 leftSpacing; // at 0x0 + u8 glyphWidth; // at 0x1 + s8 charWidth; // at 0x2 +}; + +struct Glyph { + void *texture; // at 0x0 + CharWidths widths; // at 0x4 + u8 height; // at 0x7 + GXTexFmt format; // at 0x8 + u16 texWidth; // at 0xC + u16 texHeight; // at 0xE + u16 cellX; // at 0x10 + u16 cellY; // at 0x12 +}; + +enum FontEncoding { FONT_ENCODE_UTF8, FONT_ENCODE_UTF16, FONT_ENCODE_SJIS, FONT_ENCODE_CP1252 }; + +class Font { +public: + enum Type { TYPE_NULL, TYPE_ROM, TYPE_RESOURCE, TYPE_PAIR }; + +public: + Font() : mReadFunc(&CharStrmReader::ReadNextCharCP1252) {} + virtual ~Font() {} // at 0x8 + + virtual int GetWidth() const = 0; // at 0xC + virtual int GetHeight() const = 0; // at 0x10 + virtual int GetAscent() const = 0; // at 0x14 + virtual int GetDescent() const = 0; // at 0x18 + virtual int GetBaselinePos() const = 0; // at 0x1C + virtual int GetCellHeight() const = 0; // at 0x20 + virtual int GetCellWidth() const = 0; // at 0x24 + virtual int GetMaxCharWidth() const = 0; // at 0x28 + virtual Type GetType() const = 0; // at 0x2C + virtual GXTexFmt GetTextureFormat() const = 0; // at 0x30 + virtual int GetLineFeed() const = 0; // at 0x34 + virtual CharWidths GetDefaultCharWidths() const = 0; // at 0x38 + virtual void SetDefaultCharWidths(const CharWidths &widths) = 0; // at 0x3C + virtual bool SetAlternateChar(u16 c) = 0; // at 0x40 + virtual void SetLineFeed(int lf) = 0; // at 0x44 + virtual int GetCharWidth(u16 c) const = 0; // at 0x48 + virtual CharWidths GetCharWidths(u16 c) const = 0; // at 0x4C + virtual void GetGlyph(Glyph *out, u16 c) const = 0; // at 0x50 + virtual FontEncoding GetEncoding() const = 0; // at 0x54 + + void InitReaderFunc(FontEncoding encode); + + CharStrmReader GetCharStrmReader() const { + return CharStrmReader(mReadFunc); + } + +private: + CharStrmReader::ReadFunc mReadFunc; // at 0x4 +}; + +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut/ut_IOStream.h b/include/nw4r/ut/ut_IOStream.h new file mode 100644 index 00000000..13467904 --- /dev/null +++ b/include/nw4r/ut/ut_IOStream.h @@ -0,0 +1,45 @@ +#ifndef NW4R_UT_IO_STREAM_H +#define NW4R_UT_IO_STREAM_H +#include +#include + +namespace nw4r { +namespace ut { + +class IOStream { +public: + NW4R_UT_RTTI_DECL(IOStream); + + typedef void (*AsyncCallback)(s32 result, IOStream* stream, void* arg); + + IOStream() : mIsOpen(false), mCallback(NULL), mCallbackArg(NULL) {} + virtual ~IOStream() {} // at 0xC + + virtual void Close() = 0; // at 0x10 + virtual s32 Read(void* dst, u32 size) = 0; // at 0x14 + virtual bool ReadAsync(void* dst, u32 size, AsyncCallback callback, + void* arg); // at 0x18 + virtual void Write(const void* src, u32 size); // at 0x1C + virtual bool WriteAsync(const void* src, u32 size, AsyncCallback callback, + void* arg); // at 0x20 + virtual bool IsBusy() const; // at 0x24 + virtual bool CanAsync() const = 0; // at 0x28 + virtual bool CanRead() const = 0; // at 0x2C + virtual bool CanWrite() const = 0; // at 0x30 + virtual u32 GetOffsetAlign() const { return 1; } // at 0x34 + virtual u32 GetSizeAlign() const { return 1; } // at 0x38 + virtual u32 GetBufferAlign() const { return 1; } // at 0x3C + + bool IsAvailable() const { return mIsOpen; } + +protected: + bool mIsOpen; // at 0x4 + s32 mResult; // at 0x8 + AsyncCallback mCallback; // at 0xC + void* mCallbackArg; // at 0x10 +}; + +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut/ut_LinkList.h b/include/nw4r/ut/ut_LinkList.h new file mode 100644 index 00000000..580c6187 --- /dev/null +++ b/include/nw4r/ut/ut_LinkList.h @@ -0,0 +1,400 @@ +#ifndef NW4R_UT_LINK_LIST_H +#define NW4R_UT_LINK_LIST_H +#include +#include + +/** + * Declare typedef for linked-list specialization. + */ +#define NW4R_UT_LIST_TYPEDEF_DECL(T) typedef nw4r::ut::LinkList T##List; + +/** + * Declare typedef for linked-list specialization. + * + * Use the specified link node (name suffix) for classes with multiple nodes. + */ +#define NW4R_UT_LIST_TYPEDEF_DECL_EX(T, SUFFIX) \ + typedef nw4r::ut::LinkList T##SUFFIX##List; + +/** + * Declare a member LinkListNode for use with the typedef. + */ +#define NW4R_UT_LIST_NODE_DECL() nw4r::ut::LinkListNode node + +/** + * Declare a member LinkListNode for use with the typedef. + * + * Use the specified link node (name suffix) for classes with multiple nodes. + */ +#define NW4R_UT_LIST_NODE_DECL_EX(SUFFIX) nw4r::ut::LinkListNode node##SUFFIX + +/** + * Explicitly instantiate a linked list specialization. + * (RESERVED FOR MATCHING DECOMP HACKS) + */ +#ifndef NON_MATCHING +#define NW4R_UT_LIST_TYPEDEF_INST(T) template struct nw4r::ut::LinkList +#else +#define NW4R_UT_LIST_TYPEDEF_INST(T) +#endif + +namespace nw4r { +namespace ut { + +// Forward declaration +namespace detail { +class LinkListImpl; +} + +class LinkListNode : private NonCopyable { + friend class detail::LinkListImpl; + +public: + LinkListNode() : mNext(NULL), mPrev(NULL) {} + + LinkListNode *GetNext() const { + return mNext; + } + LinkListNode *GetPrev() const { + return mPrev; + } + +private: + LinkListNode *mNext; // at 0x0 + LinkListNode *mPrev; // at 0x4 +}; + +namespace detail { + +class LinkListImpl : private NonCopyable { +public: + // Forward declaration + class ConstIterator; + + class Iterator { + friend class LinkListImpl; + friend class ConstIterator; + + public: + Iterator() : mNode(NULL) {} + Iterator(LinkListNode *node) : mNode(node) {} + + Iterator &operator++() { + mNode = mNode->GetNext(); + return *this; + } + + Iterator &operator--() { + mNode = mNode->GetPrev(); + return *this; + } + + LinkListNode *operator->() const { + return mNode; + } + + friend bool operator==(LinkListImpl::Iterator lhs, LinkListImpl::Iterator rhs) { + return lhs.mNode == rhs.mNode; + } + + private: + LinkListNode *mNode; // at 0x0 + }; + + class ConstIterator { + friend class LinkListImpl; + + public: + ConstIterator(Iterator it) : mNode(it.mNode) {} + + ConstIterator &operator++() { + mNode = mNode->GetNext(); + return *this; + } + + ConstIterator &operator--() { + mNode = mNode->GetPrev(); + return *this; + } + + const LinkListNode *operator->() const { + return mNode; + } + + friend bool operator==(LinkListImpl::ConstIterator lhs, LinkListImpl::ConstIterator rhs) { + return lhs.mNode == rhs.mNode; + } + + private: + LinkListNode *mNode; // at 0x0 + }; + +protected: + static Iterator GetIteratorFromPointer(LinkListNode *node) { + return Iterator(node); + } + + LinkListImpl() { + Initialize_(); + } + ~LinkListImpl(); + + Iterator GetBeginIter() { + return Iterator(mNode.GetNext()); + } + Iterator GetEndIter() { + return Iterator(&mNode); + } + + Iterator Insert(Iterator it, LinkListNode *node); + + Iterator Erase(Iterator it); + Iterator Erase(LinkListNode *node); + Iterator Erase(Iterator begin, Iterator end); + +public: + u32 GetSize() const { + return mSize; + } + bool IsEmpty() const { + return mSize == 0; + } + + void PopFront() { + Erase(GetBeginIter()); + } + void PopBack() { + Erase(GetEndIter()); + } + + void Clear(); + +private: + void Initialize_() { + mSize = 0; + mNode.mNext = &mNode; + mNode.mPrev = &mNode; + } + +private: + u32 mSize; // at 0x0 + LinkListNode mNode; // at 0x4 +}; + +template +class ReverseIterator { +public: + ReverseIterator(TIter it) : mCurrent(it) {} + + TIter GetBase() const { + return mCurrent; + } + + ReverseIterator &operator++() { + --mCurrent; + return *this; + } + + const typename TIter::TElem *operator->() const { + return &this->operator*(); + } + + typename TIter::TElem &operator*() const { + TIter it = mCurrent; + --it; + return *it; + } + + friend bool operator==(const ReverseIterator &lhs, const ReverseIterator &rhs) { + return lhs.mCurrent == rhs.mCurrent; + } + + friend bool operator!=(const ReverseIterator &lhs, const ReverseIterator &rhs) { + return !(lhs.mCurrent == rhs.mCurrent); + } + +private: + TIter mCurrent; // at 0x0 +}; + +} // namespace detail + +template +class LinkList : public detail::LinkListImpl { +public: + class Iterator { + friend class LinkList; + + public: + // Element type must be visible to ReverseIterator + typedef T TElem; + + public: + Iterator() : mIterator(NULL) {} + Iterator(LinkListImpl::Iterator it) : mIterator(it) {} + + Iterator &operator++() { + ++mIterator; + return *this; + } + + Iterator &operator--() { + --mIterator; + return *this; + } + + Iterator operator++(int) { + Iterator ret = *this; + ++*this; + return ret; + } + + T *operator->() const { + return GetPointerFromNode(mIterator.operator->()); + } + + T &operator*() const { + return *this->operator->(); + } + + friend bool operator==(Iterator lhs, Iterator rhs) { + return lhs.mIterator == rhs.mIterator; + } + + friend bool operator!=(Iterator lhs, Iterator rhs) { + return !(lhs == rhs); + } + + private: + LinkListImpl::Iterator mIterator; // at 0x0 + }; + + class ConstIterator { + friend class LinkList; + + public: + // Element type must be visible to ReverseIterator + typedef T TElem; + + public: + ConstIterator(LinkListImpl::Iterator it) : mIterator(it) {} + + ConstIterator &operator++() { + ++mIterator; + return *this; + } + + ConstIterator &operator--() { + --mIterator; + return *this; + } + + ConstIterator operator++(int) { + ConstIterator ret = *this; + ++*this; + return ret; + } + + const T *operator->() const { + return GetPointerFromNode(mIterator.operator->()); + } + + const T &operator*() const { + return *this->operator->(); + } + + friend bool operator==(ConstIterator lhs, ConstIterator rhs) { + return lhs.mIterator == rhs.mIterator; + } + + friend bool operator!=(ConstIterator lhs, ConstIterator rhs) { + return !(lhs == rhs); + } + + private: + LinkListImpl::ConstIterator mIterator; // at 0x0 + }; + +public: + // Shorthand names for reverse iterator types + typedef detail::ReverseIterator RevIterator; + typedef detail::ReverseIterator RevConstIterator; + +public: + LinkList() {} + ~LinkList() {} + + Iterator GetBeginIter() { + return Iterator(LinkListImpl::GetBeginIter()); + } + ConstIterator GetBeginIter() const { + return ConstIterator(GetBeginIter()); + } + detail::ReverseIterator GetBeginReverseIter() { + return detail::ReverseIterator(GetBeginIter()); + } + + Iterator GetEndIter() { + return Iterator(LinkListImpl::GetEndIter()); + } + ConstIterator GetEndIter() const { + return ConstIterator(GetEndIter()); + } + detail::ReverseIterator GetEndReverseIter() { + return detail::ReverseIterator(GetEndIter()); + } + + Iterator Insert(Iterator it, T *p) { + return Iterator(LinkListImpl::Insert(it.mIterator, GetNodeFromPointer(p))); + } + + Iterator Erase(T *p) { + return Iterator(LinkListImpl::Erase(GetNodeFromPointer(p))); + } + Iterator Erase(Iterator it) { + return Iterator(LinkListImpl::Erase(it.mIterator)); + } + + void PushBack(T *p) { + Insert(GetEndIter(), p); + } + + T &GetFront() { + return *GetBeginIter(); + } + const T &GetFront() const { + return *GetBeginIter(); + } + + T &GetBack() { + return *--GetEndIter(); + } + const T &GetBack() const { + return *--GetEndIter(); + } + + static Iterator GetIteratorFromPointer(T *p) { + return GetIteratorFromPointer(GetNodeFromPointer(p)); + } + + static Iterator GetIteratorFromPointer(LinkListNode *node) { + return Iterator(LinkListImpl::GetIteratorFromPointer(node)); + } + + static LinkListNode *GetNodeFromPointer(T *p) { + return reinterpret_cast(reinterpret_cast(p) + Ofs); + } + + static T *GetPointerFromNode(LinkListNode *node) { + return reinterpret_cast(reinterpret_cast(node) - Ofs); + } + + static const T *GetPointerFromNode(const LinkListNode *node) { + return reinterpret_cast(reinterpret_cast(node) - Ofs); + } +}; + +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut/ut_LockedCache.h b/include/nw4r/ut/ut_LockedCache.h new file mode 100644 index 00000000..290b1036 --- /dev/null +++ b/include/nw4r/ut/ut_LockedCache.h @@ -0,0 +1,38 @@ +#ifndef NW4R_UT_LOCKED_CACHE_H +#define NW4R_UT_LOCKED_CACHE_H +#include +#include + +namespace nw4r { +namespace ut { +namespace LC { + +void Enable(); +void Disable(); + +bool Lock(); +void Unlock(); + +void LoadBlocks(void *dst, void *src, u32 size); +void StoreBlocks(void *dst, void *src, u32 size); +void StoreData(void *dst, void *src, u32 size); + +inline void *GetBase() { + return reinterpret_cast(OS_CACHE_BASE); +} + +inline void QueueWait(u32 len) { + LCQueueWait(len); +} + +inline void QueueWaitEx(u32 len) { + while (LCQueueLength() != len) { + OSYieldThread(); + } +} + +} // namespace LC +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut/ut_NandFileStream.h b/include/nw4r/ut/ut_NandFileStream.h new file mode 100644 index 00000000..1e1ef805 --- /dev/null +++ b/include/nw4r/ut/ut_NandFileStream.h @@ -0,0 +1,102 @@ +#ifndef NW4R_UT_NAND_FILE_STREAM_H +#define NW4R_UT_NAND_FILE_STREAM_H +#include +#include +#include + +namespace nw4r { +namespace ut { + +class NandFileStream : public FileStream { +public: + NW4R_UT_RTTI_DECL(NandFileStream); + + /** + * NAND callbacks need a reference to the NW4R stream. This structure is + * used to up-cast the NANDCommandBlock given to the async callback. + * + * This structure's NANDCommandBlock is always used in calls to async NAND + * functions, so the up-cast is always safe. + */ + struct AsyncContext { + NANDCommandBlock block; // at 0x0 + NANDFileInfo info; // at 0xB8 + NandFileStream *stream; // at 0x144 + }; + +public: + NandFileStream(const char *path, u32 access); + NandFileStream(const NANDFileInfo *info, u32 access, bool close); + virtual ~NandFileStream(); // at 0xC + + virtual bool IsBusy() const { + return mIsBusy; + } // at 0x24 + + virtual u32 Tell() const { + return mFilePosition.Tell(); + } // at 0x58 + virtual u32 GetSize() const { + return mFilePosition.GetFileSize(); + } // at 0x40 + + virtual bool CanAsync() const { + return true; + } // at 0x28 + virtual bool CanSeek() const { + return true; + } // at 0x50 + virtual bool CanRead() const { + return mCanRead; + } // at 0x2C + virtual bool CanWrite() const { + return mCanWrite; + } // at 0x30 + virtual bool CanCancel() const { + return false; + } // at 0x54 + + virtual u32 GetOffsetAlign() const { + return 1; + } // at 0x34 + virtual u32 GetSizeAlign() const { + return 32; + } // at 0x38 + virtual u32 GetBufferAlign() const { + return 32; + } // at 0x3C + + virtual void Close(); // at 0x10 + + virtual s32 Read(void *dst, u32 size); // at 0x14 + virtual bool ReadAsync(void *dst, u32 size, AsyncCallback callback, + void *arg); // at 0x18 + + virtual void Write(const void *src, u32 size); // at 0x1C + virtual bool WriteAsync(const void *src, u32 size, AsyncCallback callback, + void *arg); // at 0x20 + + virtual void Seek(s32 offset, u32 origin); // at 0x44 + + bool Open(const char *path, u32 access); + bool Open(const NANDFileInfo *info, u32 access, bool close) DECOMP_DONT_INLINE; + +private: + static void NandAsyncCallback_(s32 result, NANDCommandBlock *block); + + void Initialize_(); + +private: + FilePosition mFilePosition; // at 0x14 + AsyncContext mAsyncContext; // at 0x1C + bool mCanRead; // at 0x164 + bool mCanWrite; // at 0x165 + volatile bool mIsBusy; // at 0x166 + bool mCloseOnDestroy; // at 0x167 + bool mAllowClose; // at 0x168 +}; + +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut/ut_NonCopyable.h b/include/nw4r/ut/ut_NonCopyable.h new file mode 100644 index 00000000..7e37309b --- /dev/null +++ b/include/nw4r/ut/ut_NonCopyable.h @@ -0,0 +1,20 @@ +#ifndef NW4R_UT_NON_COPYABLE_H +#define NW4R_UT_NON_COPYABLE_H +#include + +namespace nw4r { +namespace ut { +namespace { + +class NonCopyable { +protected: + NonCopyable() {} + NonCopyable(const NonCopyable&) {} + ~NonCopyable() {} +}; + +} // namespace +} // namespace ut +} // namespace nw4r + +#endif \ No newline at end of file diff --git a/include/nw4r/ut/ut_Rect.h b/include/nw4r/ut/ut_Rect.h new file mode 100644 index 00000000..3a4ec1e2 --- /dev/null +++ b/include/nw4r/ut/ut_Rect.h @@ -0,0 +1,48 @@ +#ifndef NW4R_UT_RECT_H +#define NW4R_UT_RECT_H +#include +#include + +namespace nw4r { +namespace ut { + +struct Rect { + f32 left; // at 0x0 + f32 top; // at 0x4 + f32 right; // at 0x8 + f32 bottom; // at 0xC + + Rect() : left(0.0f), top(0.0f), right(0.0f), bottom(0.0f) {} + Rect(f32 l, f32 t, f32 r, f32 b) : left(l), top(t), right(r), bottom(b) {} + ~Rect() {} + + void SetWidth(f32 width) { right = left + width; } + f32 GetWidth() const { return right - left; } + + void SetHeight(f32 height) { bottom = top + height; } + f32 GetHeight() const { return bottom - top; } + + void Normalize() { + f32 l = left; + f32 t = top; + f32 r = right; + f32 b = bottom; + + left = math::FSelect(r - l, l, r); // min(r, l) + right = math::FSelect(r - l, r, l); // max(r, l) + top = math::FSelect(b - t, t, b); // min(b, t) + bottom = math::FSelect(b - t, b, t); // max(b, t) + } + + void MoveTo(f32 x, f32 y) { + right = GetWidth() + x; + left = x; + bottom = GetHeight() + y; + top = y; + } +}; + +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut/ut_ResFont.h b/include/nw4r/ut/ut_ResFont.h new file mode 100644 index 00000000..61e4e778 --- /dev/null +++ b/include/nw4r/ut/ut_ResFont.h @@ -0,0 +1,22 @@ +#ifndef NW4R_UT_RES_FONT_H +#define NW4R_UT_RES_FONT_H +#include +#include + +namespace nw4r { +namespace ut { + +class ResFont : public detail::ResFontBase { +public: + static FontInformation* Rebuild(BinaryFileHeader* header); + + ResFont(); + ~ResFont(); + + bool SetResource(void* buffer); +}; + +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut/ut_ResFontBase.h b/include/nw4r/ut/ut_ResFontBase.h new file mode 100644 index 00000000..35870190 --- /dev/null +++ b/include/nw4r/ut/ut_ResFontBase.h @@ -0,0 +1,113 @@ +#ifndef NW4R_UT_RES_FONT_BASE_H +#define NW4R_UT_RES_FONT_BASE_H +#include +#include + +namespace nw4r { +namespace ut { + +enum FontMapMethod { + FONT_MAPMETHOD_LINEAR, + FONT_MAPMETHOD_ARRAY, + FONT_MAPMETHOD_SCAN +}; + +struct FontTextureGlyph { + u8 cellWidth; // at 0x0 + u8 cellHeight; // at 0x1 + s8 baselinePos; // at 0x2 + u8 maxCharWidth; // at 0x3 + u32 sheetSize; // at 0x4 + u16 sheetNum; // at 0x8 + u16 sheetFormat; // at 0xA + u16 sheetRow; // at 0xC + u16 sheetLine; // at 0xE + u16 sheetWidth; // at 0x10 + u16 sheetHeight; // at 0x12 + u8* sheetImage; // at 0x14 +}; + +struct FontWidth { + u16 firstChar; // at 0x0 + u16 lastChar; // at 0x2 + FontWidth* next; // at 0x4 + CharWidths widthTable[]; // at 0x8 +}; + +struct FontCodeMap { + u16 firstChar; // at 0x0 + u16 lastChar; // at 0x2 + u16 mappingMethod; // at 0x4 + u16 reserved; // at 0x6 + FontCodeMap* next; // at 0x8 + u16 mapInfo[]; // at 0xc +}; + +struct FontInformation { + u8 type; // at 0x0 + s8 lineFeed; // at 0x1 + u16 alterCharIndex; // at 0x2 + CharWidths defaultWidth; // at 0x4 + u8 encoding; // at 0x7 + FontTextureGlyph* fontGlyph; // at 0x8 + FontWidth* fontWidth; // at 0xC + FontCodeMap* fontMap; // at 0x10 + u8 height; // at 0x14 + u8 width; // at 0x15 + u8 ascent; // at 0x16 +}; + +namespace detail { + +class ResFontBase : public Font { +public: + ResFontBase(); + virtual ~ResFontBase(); // at 0x8 + + virtual int GetWidth() const; // at 0xC + virtual int GetHeight() const; // at 0x10 + virtual int GetAscent() const; // at 0x14 + virtual int GetDescent() const; // at 0x18 + virtual int GetBaselinePos() const; // at 0x1C + virtual int GetCellHeight() const; // at 0x20 + virtual int GetCellWidth() const; // at 0x24 + virtual int GetMaxCharWidth() const; // at 0x28 + virtual Type GetType() const; // at 0x2C + virtual GXTexFmt GetTextureFormat() const; // at 0x30 + virtual int GetLineFeed() const; // at 0x34 + virtual CharWidths GetDefaultCharWidths() const; // at 0x38 + virtual void SetDefaultCharWidths(const CharWidths& widths); // at 0x3C + virtual bool SetAlternateChar(u16 c); // at 0x40 + virtual void SetLineFeed(int lf); // at 0x44 + virtual int GetCharWidth(u16 c) const; // at 0x48 + virtual CharWidths GetCharWidths(u16 c) const; // at 0x4C + virtual void GetGlyph(Glyph* out, u16 c) const; // at 0x50 + virtual FontEncoding GetEncoding() const; // at 0x54 + + bool IsManaging(const void* buffer) const { return mResource == buffer; } + + void SetResourceBuffer(void* buffer, FontInformation* info); + + u16 GetGlyphIndex(u16 c) const; + + u16 FindGlyphIndex(u16 c) const; + u16 FindGlyphIndex(const FontCodeMap* map, u16 c) const; + + const CharWidths& GetCharWidthsFromIndex(u16 index) const; + const CharWidths& GetCharWidthsFromIndex(const FontWidth* width, + u16 index) const; + + void GetGlyphFromIndex(Glyph* out, u16 index) const; + +private: + void* mResource; // at 0x10 + FontInformation* mFontInfo; // at 0x14 + u16 mLastCharCode; // at 0x18 + u16 mLastGlyphIndex; // at 0x18 +}; + +} // namespace detail +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut/ut_RomFont.h b/include/nw4r/ut/ut_RomFont.h new file mode 100644 index 00000000..30fc5425 --- /dev/null +++ b/include/nw4r/ut/ut_RomFont.h @@ -0,0 +1,51 @@ +#ifndef NW4R_UT_ROM_FONT_H +#define NW4R_UT_ROM_FONT_H +#include +#include +#include + +namespace nw4r { +namespace ut { + +class RomFont : public Font { +public: + RomFont(); + virtual ~RomFont(); // at 0x8 + + virtual int GetWidth() const; // at 0xC + virtual int GetHeight() const; // at 0x10 + virtual int GetAscent() const; // at 0x14 + virtual int GetDescent() const; // at 0x18 + virtual int GetBaselinePos() const; // at 0x1C + virtual int GetCellHeight() const; // at 0x20 + virtual int GetCellWidth() const; // at 0x24 + virtual int GetMaxCharWidth() const; // at 0x28 + virtual Type GetType() const; // at 0x2C + virtual GXTexFmt GetTextureFormat() const; // at 0x30 + virtual int GetLineFeed() const; // at 0x34 + virtual CharWidths GetDefaultCharWidths() const; // at 0x38 + virtual void SetDefaultCharWidths(const CharWidths &widths); // at 0x3C + virtual bool SetAlternateChar(u16 c); // at 0x40 + virtual void SetLineFeed(int lf); // at 0x44 + virtual int GetCharWidth(u16 c) const; // at 0x48 + virtual CharWidths GetCharWidths(u16 c) const; // at 0x4C + virtual void GetGlyph(Glyph *out, u16 c) const; // at 0x50 + virtual FontEncoding GetEncoding() const; // at 0x54 + + bool Load(void *buffer); + u32 GetRequireBufferSize(); + void MakeCharPtr(char *buffer, u16 c) const; + u16 HandleUndefinedChar(u16 c) const; + +private: + OSFontHeader *mFontHeader; // at 0x10 + CharWidths mDefaultWidths; // at 0x14 + u16 mAlternateChar; // at 0x18 + + static u16 mFontEncode; +}; + +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut/ut_RuntimeTypeInfo.h b/include/nw4r/ut/ut_RuntimeTypeInfo.h new file mode 100644 index 00000000..43c7f3d0 --- /dev/null +++ b/include/nw4r/ut/ut_RuntimeTypeInfo.h @@ -0,0 +1,65 @@ +#ifndef NW4R_UT_RUNTIME_TYPE_INFO_H +#define NW4R_UT_RUNTIME_TYPE_INFO_H +#include + +// Declare type RTTI and accessor function +#define NW4R_UT_RTTI_DECL(T) \ + static nw4r::ut::detail::RuntimeTypeInfo typeInfo; \ + virtual const nw4r::ut::detail::RuntimeTypeInfo* GetRuntimeTypeInfo() \ + const { \ + return &typeInfo; \ + } + +// Define type RTTI (base type) +#define NW4R_UT_RTTI_DEF_BASE(T) \ + nw4r::ut::detail::RuntimeTypeInfo T::typeInfo(NULL) + +// Define type RTTI (derived type) +#define NW4R_UT_RTTI_DEF_DERIVED(T, BASE) \ + nw4r::ut::detail::RuntimeTypeInfo T::typeInfo(&BASE::typeInfo) + +namespace nw4r { +namespace ut { +namespace detail { + +struct RuntimeTypeInfo { + RuntimeTypeInfo(const RuntimeTypeInfo* base) : mBase(base) {} + + bool IsDerivedFrom(const RuntimeTypeInfo* base) const { + for (const RuntimeTypeInfo* it = this; it != NULL; it = it->mBase) { + if (it == base) { + return true; + } + } + + return false; + } + + const RuntimeTypeInfo* mBase; // at 0x0 +}; + +template +inline const RuntimeTypeInfo* GetTypeInfoFromPtr_(T* ptr) { + return &ptr->typeInfo; +} + +} // namespace detail + +template +inline TDerived DynamicCast(TBase* ptr) { + // Derived type info + const detail::RuntimeTypeInfo* derivedTypeInfo = + detail::GetTypeInfoFromPtr_(static_cast(NULL)); + + // Downcast if possible + if (ptr->GetRuntimeTypeInfo()->IsDerivedFrom(derivedTypeInfo)) { + return static_cast(ptr); + } + + return NULL; +} + +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut/ut_TagProcessorBase.h b/include/nw4r/ut/ut_TagProcessorBase.h new file mode 100644 index 00000000..f58ff6d7 --- /dev/null +++ b/include/nw4r/ut/ut_TagProcessorBase.h @@ -0,0 +1,45 @@ +#ifndef NW4R_UT_TAG_PROCESSOR_BASE_H +#define NW4R_UT_TAG_PROCESSOR_BASE_H +#include +#include + +namespace nw4r { +namespace ut { + +enum PrintFlags { + PRINTFLAGS_CHARSPACE = (1 << 0), +}; + +template struct PrintContext { + TextWriterBase* writer; // at 0x0 + const T* str; // at 0x4 + f32 x; // at 0x8 + f32 y; // at 0xC + u32 flags; // at 0x10 +}; + +enum Operation { + OPERATION_DEFAULT, + OPERATION_NO_CHAR_SPACE, + OPERATION_CHAR_SPACE, + OPERATION_NEXT_LINE, + OPERATION_END_DRAW +}; + +template class TagProcessorBase { +public: + TagProcessorBase(); + virtual ~TagProcessorBase(); // at 0x8 + + virtual Operation Process(u16 ch, PrintContext* ctx); // at 0xC + virtual Operation CalcRect(Rect* rect, u16 ch, + PrintContext* ctx); // at 0x10 + + void ProcessTab(PrintContext* ctx); + void ProcessLinefeed(PrintContext* ctx); +}; + +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut/ut_TextWriterBase.h b/include/nw4r/ut/ut_TextWriterBase.h new file mode 100644 index 00000000..0dd9e271 --- /dev/null +++ b/include/nw4r/ut/ut_TextWriterBase.h @@ -0,0 +1,123 @@ +#ifndef NW4R_UT_TEXT_WRITER_BASE_H +#define NW4R_UT_TEXT_WRITER_BASE_H +#include +#include +#include +#include +#include +#include + +namespace nw4r { +namespace ut { + +template +class TextWriterBase : public CharWriter { +public: + static T *GetBuffer() { + return mFormatBuffer; + } + static T *SetBuffer(T *buffer, u32 size) { + T *old = mFormatBuffer; + mFormatBuffer = buffer; + mFormatBufferSize = size; + return old; + } + + static u32 GetBufferSize() { + return mFormatBufferSize; + } + + TextWriterBase(); + ~TextWriterBase(); + + f32 GetWidthLimit() const { + return mWidthLimit; + } + void SetWidthLimit(f32 limit) { + mWidthLimit = limit; + } + void ResetWidthLimit() { + mWidthLimit = NW4R_MATH_FLT_MAX; + } + + f32 GetCharSpace() const { + return mCharSpace; + } + void SetCharSpace(f32 space) { + mCharSpace = space; + } + + f32 GetLineSpace() const { + return mLineSpace; + } + void SetLineSpace(f32 space) { + mLineSpace = space; + } + + int GetTabWidth() const { + return mTabWidth; + } + void SetTabWidth(int width) { + mTabWidth = width; + } + + void SetDrawFlag(u32 flag) { + mDrawFlag = flag; + } + bool IsDrawFlagSet(u32 mask, u32 flag) const { + return (mDrawFlag & mask) == flag; + } + + TagProcessorBase *GetTagProcessor() const { + return mTagProcessor; + } + void SetTagProcessor(TagProcessorBase *processor) { + mTagProcessor = processor; + } + void ResetTagProcessor() { + mTagProcessor = &mDefaultTagProcessor; + } + + f32 GetLineHeight() const; + + f32 CalcLineWidth(const T *str, int len); + f32 CalcStringWidth(const T *str, int len) const; + void CalcStringRect(Rect *rect, const T *str, int len) const; + + int VSNPrintf(T *buffer, u32 count, const T *fmt, va_list args); + f32 VPrintf(const T *str, va_list args); + f32 Print(const T *str, int len); + + bool CalcLineRectImpl(Rect *rect, const T **str, int len); + void CalcStringRectImpl(Rect *rect, const T *str, int len); + + f32 PrintImpl(const T *str, int len); + f32 AdjustCursor(f32 *x1, f32 *y1, const T *str, int len); + +private: + f32 mWidthLimit; // at 0x4C + f32 mCharSpace; // at 0x50 + f32 mLineSpace; // at 0x54 + int mTabWidth; // at 0x58 + u32 mDrawFlag; // at 0x5C + TagProcessorBase *mTagProcessor; // at 0x60 + + static T *mFormatBuffer; + static u32 mFormatBufferSize; + static TagProcessorBase mDefaultTagProcessor; +}; + +template <> +inline int TextWriterBase::VSNPrintf(char *buffer, u32 count, const char *fmt, va_list args) { + return vsnprintf(buffer, count, fmt, args); +} + +template <> +inline int TextWriterBase::VSNPrintf(wchar_t *buffer, u32 count, const wchar_t *fmt, va_list args) { + return vswprintf(buffer, count, fmt, args); +} + +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut/ut_algorithm.h b/include/nw4r/ut/ut_algorithm.h new file mode 100644 index 00000000..38aa38ab --- /dev/null +++ b/include/nw4r/ut/ut_algorithm.h @@ -0,0 +1,94 @@ +#ifndef NW4R_UT_ALGORITHM_H +#define NW4R_UT_ALGORITHM_H +#include + +namespace nw4r { +namespace ut { +namespace { + +/** + * Value operations + */ +template inline T Max(T t1, T t2) { return (t1 < t2) ? t2 : t1; } + +template inline T Min(T t1, T t2) { return (t1 > t2) ? t2 : t1; } + +template inline T Clamp(T value, T min, T max) { + return value > max ? max : (value < min ? min : value); +} + +template inline T Abs(T x) { + // Static cast needed to break abs optimization during instruction selection + return x < 0 ? static_cast(-x) : static_cast(x); +} + +template <> f32 inline Abs(register f32 x) { + register f32 ax; + + // clang-format off + asm { + fabs ax, x + } + // clang-format on + + return ax; +} + +/** + * Bit operations + */ +template inline T BitExtract(T bits, int pos, int len) { + T mask = (1 << len) - 1; + return (bits >> pos) & mask; +} + +template inline bool TestBit(T t, int bitIndexLSB) { + return BitExtract(t, sizeof(T), bitIndexLSB); +} + +/** + * Pointer operations + */ +inline u32 GetIntPtr(const void* ptr) { return reinterpret_cast(ptr); } + +template +inline const void* AddOffsetToPtr(const void* ptr, T offset) { + return reinterpret_cast(GetIntPtr(ptr) + offset); +} + +inline s32 GetOffsetFromPtr(const void* start, const void* end) { + return static_cast(GetIntPtr(end) - GetIntPtr(start)); +} + +inline int ComparePtr(const void* p1, const void* p2) { + return static_cast(GetIntPtr(p1) - GetIntPtr(p2)); +} + +/** + * Rounding + */ +template inline T RoundUp(T t, unsigned int alignment) { + return (alignment + t - 1) & ~(alignment - 1); +} + +template inline void* RoundUp(T* t, unsigned int alignment) { + u32 value = reinterpret_cast(t); + u32 rounded = (alignment + value - 1) & ~(alignment - 1); + return reinterpret_cast(rounded); +} + +template inline T RoundDown(T t, unsigned int alignment) { + return t & ~(alignment - 1); +} + +template inline void* RoundDown(T* t, unsigned int alignment) { + u32 value = reinterpret_cast(t); + u32 rounded = value & ~(alignment - 1); + return reinterpret_cast(rounded); +} + +} // namespace +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut/ut_binaryFileFormat.h b/include/nw4r/ut/ut_binaryFileFormat.h new file mode 100644 index 00000000..eeb5faca --- /dev/null +++ b/include/nw4r/ut/ut_binaryFileFormat.h @@ -0,0 +1,28 @@ +#ifndef NW4R_UT_BINARY_FILE_FORMAT_H +#define NW4R_UT_BINARY_FILE_FORMAT_H +#include + +namespace nw4r { +namespace ut { + +struct BinaryBlockHeader { + u32 magic; // at 0x0 + u32 length; // at 0x4 +}; + +struct BinaryFileHeader { + u32 magic; // at 0x0 + u16 byteOrder; // at 0x4 + u16 version; // at 0x6 + u32 fileSize; // at 0x8 + u16 headerSize; // at 0xC + u16 numBlocks; // at 0xE +}; + +bool IsValidBinaryFile(const BinaryFileHeader* header, u32 magic, u16 version, + u16 numBlocks); + +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut/ut_list.h b/include/nw4r/ut/ut_list.h new file mode 100644 index 00000000..f6b13a0a --- /dev/null +++ b/include/nw4r/ut/ut_list.h @@ -0,0 +1,56 @@ +#ifndef NW4R_UT_LIST_H +#define NW4R_UT_LIST_H +#include + +namespace nw4r { +namespace ut { + +struct List { + void* first; // at 0x0 + void* last; // at 0x4 + u16 size; // at 0x8 + u16 offset; // at 0xA +}; + +struct Node { + void* prev; // at 0x0 + void* next; // at 0x4 +}; + +void List_Init(List* list, u16 offset); +void List_Append(List* list, void* object); +void List_Prepend(List* list, void* object); +void List_Insert(List* list, void* next, void* object); +void List_Remove(List* list, void* object); +void* List_GetNext(const List* list, const void* object); +void* List_GetPrev(const List* list, const void* object); +void* List_GetNth(const List* list, u16 n); + +inline void* List_GetFirst(const List* list) { + return List_GetNext(list, NULL); +} + +inline const void* List_GetFirstConst(const List* list) { + return List_GetFirst(list); +} + +inline void* List_GetLast(const List* list) { return List_GetPrev(list, NULL); } + +inline const void* List_GetLastConst(const List* list) { + return List_GetLast(list); +} + +inline const void* List_GetNextConst(const List* list, const void* object) { + return List_GetNext(list, object); +} + +inline const void* List_GetNthConst(const List* list, u16 n) { + return List_GetNth(list, n); +} + +inline u16 List_GetSize(const List* list) { return list->size; } + +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/nw4r/ut/ut_lock.h b/include/nw4r/ut/ut_lock.h new file mode 100644 index 00000000..905514f4 --- /dev/null +++ b/include/nw4r/ut/ut_lock.h @@ -0,0 +1,48 @@ +#ifndef NW4R_UT_LOCK_H +#define NW4R_UT_LOCK_H +#include +#include +#include + +namespace nw4r { +namespace ut { +namespace detail { + +inline void Lock(OSMutex &mutex) { + OSLockMutex(&mutex); +} +inline void Unlock(OSMutex &mutex) { + OSUnlockMutex(&mutex); +} + +template +class AutoLock : private NonCopyable { +public: + AutoLock(T &obj) : mMutex(obj) { + Lock(mMutex); + } + ~AutoLock() { + Unlock(mMutex); + } + +private: + T &mMutex; // at 0x0 +}; + +} // namespace detail + +class AutoInterruptLock : private NonCopyable { +public: + AutoInterruptLock() : mEnabled(OSDisableInterrupts()) {} + ~AutoInterruptLock() { + OSRestoreInterrupts(mEnabled); + } + +private: + BOOL mEnabled; // at 0x0 +}; + +} // namespace ut +} // namespace nw4r + +#endif diff --git a/include/rvl/AX.h b/include/rvl/AX.h new file mode 100644 index 00000000..ba62c550 --- /dev/null +++ b/include/rvl/AX.h @@ -0,0 +1,26 @@ +/** + * References: Dolphin Emulator, Retro Modding Wiki, vgmstream + */ + +#ifndef RVL_SDK_PUBLIC_AX_H +#define RVL_SDK_PUBLIC_AX_H +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AX/AX.h b/include/rvl/AX/AX.h new file mode 100644 index 00000000..0f4458e6 --- /dev/null +++ b/include/rvl/AX/AX.h @@ -0,0 +1,14 @@ +#ifndef RVL_SDK_AX_H +#define RVL_SDK_AX_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +void AXInit(void); +void AXInitEx(u32 mode); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AX/AXAlloc.h b/include/rvl/AX/AXAlloc.h new file mode 100644 index 00000000..7622de28 --- /dev/null +++ b/include/rvl/AX/AXAlloc.h @@ -0,0 +1,32 @@ +#ifndef RVL_SDK_AX_ALLOC_H +#define RVL_SDK_AX_ALLOC_H +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define AX_PRIORITY_FREE 0 +#define AX_PRIORITY_MIN 1 +#define AX_PRIORITY_MAX 31 + +AXVPB *__AXGetStackHead(u32 prio); +void __AXServiceCallbackStack(void); +void __AXInitVoiceStacks(void); +void __AXAllocInit(void); +void __AXPushFreeStack(AXVPB *vpb); +AXVPB *__AXPopFreeStack(void); +void __AXPushCallbackStack(AXVPB *vpb); +AXVPB *__AXPopCallbackStack(void); +void __AXRemoveFromStack(AXVPB *vpb); +void __AXPushStackHead(AXVPB *vpb, u32 prio); +AXVPB *__AXPopStackFromBottom(u32 prio); +void AXFreeVoice(AXVPB *vpb); +AXVPB *AXAcquireVoice(u32 prio, AXVoiceCallback callback, u32 userContext); +void AXSetVoicePriority(AXVPB *vpb, u32 prio); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AX/AXAux.h b/include/rvl/AX/AXAux.h new file mode 100644 index 00000000..8c718ab4 --- /dev/null +++ b/include/rvl/AX/AXAux.h @@ -0,0 +1,48 @@ +#ifndef RVL_SDK_AX_AUX_H +#define RVL_SDK_AX_AUX_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Stereo: Left, Right, Surround + * DPL2: Left, Right, Left Surround, Right Surround + */ +#define AX_STEREO_CHAN_MAX 3 +#define AX_DPL2_CHAN_MAX 4 + +#define AX_SAMPLES_PER_FRAME 96 +#define AX_SAMPLE_DEPTH_BYTES sizeof(u32) +#define AX_SAMPLES_PER_FRAME_RMT 18 +#define AX_FRAME_SIZE (AX_SAMPLES_PER_FRAME * AX_SAMPLE_DEPTH_BYTES) + +typedef void (*AXAuxCallback)(void *chans, void *context); + +void __AXAuxInit(void); +void __AXGetAuxAInput(void **out); +void __AXGetAuxAOutput(void **out); +void __AXGetAuxAInputDpl2(void **out); +void __AXGetAuxAOutputDpl2R(void **out); +void __AXGetAuxAOutputDpl2Ls(void **out); +void __AXGetAuxAOutputDpl2Rs(void **out); +void __AXGetAuxBInput(void **out); +void __AXGetAuxBOutput(void **out); +void __AXGetAuxBInputDpl2(void **out); +void __AXGetAuxBOutputDpl2R(void **out); +void __AXGetAuxBOutputDpl2Ls(void **out); +void __AXGetAuxBOutputDpl2Rs(void **out); +void __AXGetAuxCInput(void **out); +void __AXGetAuxCOutput(void **out); +void __AXProcessAux(void); +void AXRegisterAuxACallback(AXAuxCallback callback, void *context); +void AXRegisterAuxBCallback(AXAuxCallback callback, void *context); +void AXRegisterAuxCCallback(AXAuxCallback callback, void *context); +void AXGetAuxACallback(AXAuxCallback *callback, void **context); +void AXGetAuxBCallback(AXAuxCallback *callback, void **context); +void AXGetAuxCCallback(AXAuxCallback *callback, void **context); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AX/AXCL.h b/include/rvl/AX/AXCL.h new file mode 100644 index 00000000..d69e0f2c --- /dev/null +++ b/include/rvl/AX/AXCL.h @@ -0,0 +1,36 @@ +#ifndef RVL_SDK_AX_CL_H +#define RVL_SDK_AX_CL_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +#define AX_MAX_VOLUME 32768 +// Command list can hold up to 64 commands +#define AX_CL_MAX_CMD 64 +// Each command takes up two bytes +#define AX_CL_SIZE (AX_CL_MAX_CMD * sizeof(u16)) + +typedef enum { AX_OUTPUT_STEREO, AX_OUTPUT_SURROUND, AX_OUTPUT_DPL2 } AXOutputMode; + +extern u32 __AXClMode; + +u32 __AXGetCommandListCycles(void); +void *__AXGetCommandListAddress(void); +void __AXWriteToCommandList(u16 cmd); +void __AXNextFrame(void *surround, void *lr, void *rmt); +void __AXClInit(void); +void AXSetMode(u32 mode); +u32 AXGetMode(void); +u16 AXGetAuxAReturnVolume(void); +u16 AXGetAuxBReturnVolume(void); +u16 AXGetAuxCReturnVolume(void); +void AXSetMasterVolume(u16 volume); +void AXSetAuxAReturnVolume(u16 volume); +void AXSetAuxBReturnVolume(u16 volume); +void AXSetAuxCReturnVolume(u16 volume); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AX/AXComp.h b/include/rvl/AX/AXComp.h new file mode 100644 index 00000000..3fffde81 --- /dev/null +++ b/include/rvl/AX/AXComp.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_AX_COMP_H +#define RVL_SDK_AX_COMP_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +extern u16 __AXCompressorTable[]; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AX/AXOut.h b/include/rvl/AX/AXOut.h new file mode 100644 index 00000000..7dbb6e81 --- /dev/null +++ b/include/rvl/AX/AXOut.h @@ -0,0 +1,26 @@ +#ifndef RVL_SDK_AX_OUT_H +#define RVL_SDK_AX_OUT_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +#define AX_STREAM_SIZE_RMT 40 +#define AX_RMT_MAX 4 + +typedef void (*AXOutCallback)(void); +typedef void (*AXExceedCallback)(u32 cycles); + +u32 __AXOutNewFrame(void); +void __AXOutAiCallback(void); +void __AXOutInitDSP(void); +void __AXOutInit(u32 mode); +AXOutCallback AXRegisterCallback(AXOutCallback callback); +s32 AXRmtGetSamplesLeft(void); +s32 AXRmtGetSamples(s32 chan, s16 *out, s32 num); +s32 AXRmtAdvancePtr(s32 num); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AX/AXPB.h b/include/rvl/AX/AXPB.h new file mode 100644 index 00000000..e3c133f0 --- /dev/null +++ b/include/rvl/AX/AXPB.h @@ -0,0 +1,279 @@ +#ifndef RVL_SDK_AX_PB_H +#define RVL_SDK_AX_PB_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + * One frame contains eight bytes: + * - One for the header + * - Seven for the audio samples + */ +#define AX_ADPCM_FRAME_SIZE 8 +#define AX_ADPCM_SAMPLE_BYTES_PER_FRAME (AX_ADPCM_FRAME_SIZE - 1) + +// Two audio samples per byte (each nibble) +#define AX_ADPCM_SAMPLES_PER_BYTE 2 + +// Amount of audio samples in a frame +#define AX_ADPCM_SAMPLES_PER_FRAME (AX_ADPCM_SAMPLE_BYTES_PER_FRAME * AX_ADPCM_SAMPLES_PER_BYTE) + +// Amount of nibbles in a frame +#define AX_ADPCM_NIBBLES_PER_FRAME (AX_ADPCM_FRAME_SIZE * 2) + +typedef enum { AX_VOICE_NORMAL, AX_VOICE_STREAM } AXVOICETYPE; + +typedef enum { AX_VOICE_STOP, AX_VOICE_RUN } AXVOICESTATE; + +typedef enum { + AX_SAMPLE_FORMAT_DSP_ADPCM = 0, + AX_SAMPLE_FORMAT_PCM_S16 = 10, + AX_SAMPLE_FORMAT_PCM_S8 = 25, +} AXSAMPLETYPE; + +// For rmtIIR union I think? From NW4R asserts, but fits well in __AXSyncPBs +typedef enum { + AX_PB_LPF_ON = 1, + AX_PB_BIQUAD_ON, +}; + +typedef enum { + AX_SRC_TYPE_NONE, + AX_SRC_TYPE_LINEAR, + AX_SRC_TYPE_4TAP_8K, + AX_SRC_TYPE_4TAP_12K, + AX_SRC_TYPE_4TAP_16K, + AX_SRC_TYPE_4TAP_AUTO +} AXPBSRCTYPE; + +typedef enum { + AX_MIXER_CTRL_L = (1 << 0), + AX_MIXER_CTRL_R = (1 << 1), + AX_MIXER_CTRL_DELTA = (1 << 2), + AX_MIXER_CTRL_S = (1 << 3), + AX_MIXER_CTRL_DELTA_S = (1 << 4), + + AX_MIXER_CTRL_AL = (1 << 16), + AX_MIXER_CTRL_AR = (1 << 17), + AX_MIXER_CTRL_DELTA_A = (1 << 18), + AX_MIXER_CTRL_AS = (1 << 19), + AX_MIXER_CTRL_DELTA_AS = (1 << 20), + + AX_MIXER_CTRL_BL = (1 << 21), + AX_MIXER_CTRL_BR = (1 << 22), + AX_MIXER_CTRL_DELTA_B = (1 << 23), + AX_MIXER_CTRL_BS = (1 << 24), + AX_MIXER_CTRL_DELTA_BS = (1 << 25), + + AX_MIXER_CTRL_CL = (1 << 26), + AX_MIXER_CTRL_CR = (1 << 27), + AX_MIXER_CTRL_DELTA_C = (1 << 28), + AX_MIXER_CTRL_CS = (1 << 29), + AX_MIXER_CTRL_DELTA_CS = (1 << 30) +}; + +typedef enum { + AX_MIXER_CTRL_RMT_M0 = (1 << 0), + AX_MIXER_CTRL_RMT_DELTA_M0 = (1 << 1), + AX_MIXER_CTRL_RMT_A0 = (1 << 2), + AX_MIXER_CTRL_RMT_DELTA_A0 = (1 << 3), + + AX_MIXER_CTRL_RMT_M1 = (1 << 4), + AX_MIXER_CTRL_RMT_DELTA_M1 = (1 << 5), + AX_MIXER_CTRL_RMT_A1 = (1 << 6), + AX_MIXER_CTRL_RMT_DELTA_A1 = (1 << 7), + + AX_MIXER_CTRL_RMT_M2 = (1 << 8), + AX_MIXER_CTRL_RMT_DELTA_M2 = (1 << 9), + AX_MIXER_CTRL_RMT_A2 = (1 << 10), + AX_MIXER_CTRL_RMT_DELTA_A2 = (1 << 11), + + AX_MIXER_CTRL_RMT_M3 = (1 << 12), + AX_MIXER_CTRL_RMT_DELTA_M3 = (1 << 13), + AX_MIXER_CTRL_RMT_A3 = (1 << 14), + AX_MIXER_CTRL_RMT_DELTA_A3 = (1 << 15) +}; + +typedef struct _AXPBMIX { + u16 vL; // at 0x0 + u16 vDeltaL; // at 0x2 + u16 vR; // at 0x4 + u16 vDeltaR; // at 0x6 + u16 vAuxAL; // at 0x8 + u16 vDeltaAuxAL; // at 0xA + u16 vAuxAR; // at 0xC + u16 vDeltaAuxAR; // at 0xE + u16 vAuxBL; // at 0x10 + u16 vDeltaAuxBL; // at 0x12 + u16 vAuxBR; // at 0x14 + u16 vDeltaAuxBR; // at 0x16 + u16 vAuxCL; // at 0x18 + u16 vDeltaAuxCL; // at 0x1A + u16 vAuxCR; // at 0x1C + u16 vDeltaAuxCR; // at 0x1E + u16 vS; // at 0x20 + u16 vDeltaS; // at 0x22 + u16 vAuxAS; // at 0x24 + u16 vDeltaAuxAS; // at 0x26 + u16 vAuxBS; // at 0x28 + u16 vDeltaAuxBS; // at 0x2A + u16 vAuxCS; // at 0x2C + u16 vDeltaAuxCS; // at 0x2E +} AXPBMIX; + +typedef struct _AXPBITD { + u16 flag; // at 0x0 + u16 bufferHi; // at 0x2 + u16 bufferLo; // at 0x4 + u16 shiftL; // at 0x6 + u16 shiftR; // at 0x8 + u16 targetShiftL; // at 0xA + u16 targetShiftR; // at 0xC +} AXPBITD; + +typedef struct _AXPBDPOP { + s16 aL; // at 0x0 + s16 aAuxAL; // at 0x2 + s16 aAuxBL; // at 0x4 + s16 aAuxCL; // at 0x6 + s16 aR; // at 0x8 + s16 aAuxAR; // at 0xA + s16 aAuxBR; // at 0xC + s16 aAuxCR; // at 0xE + s16 aS; // at 0x10 + s16 aAuxAS; // at 0x12 + s16 aAuxBS; // at 0x14 + s16 aAuxCS; // at 0x16 +} AXPBDPOP; + +typedef struct _AXPBVE { + u16 currentVolume; // at 0x0 + s16 currentDelta; // at 0x2 +} AXPBVE; + +typedef struct _AXPBADDR { + u16 loopFlag; // at 0x0 + u16 format; // at 0x2 + u16 loopAddressHi; // at 0x4 + u16 loopAddressLo; // at 0x6 + u16 endAddressHi; // at 0x8 + u16 endAddressLo; // at 0xA + u16 currentAddressHi; // at 0xC + u16 currentAddressLo; // at 0xE +} AXPBADDR; + +typedef struct _AXPBADPCM { + u16 a[8][2]; // at 0x0 + u16 gain; // at 0x20 + u16 pred_scale; // at 0x22 + u16 yn1; // at 0x24 + u16 yn2; // at 0x26 +} AXPBADPCM; + +typedef struct _AXPBSRC { + u16 ratioHi; // at 0x0 + u16 ratioLo; // at 0x2 + u16 currentAddressFrac; // at 0x4 + u16 last_samples[4]; // at 0x6 +} AXPBSRC; + +typedef struct _AXPBADPCMLOOP { + u16 loop_pred_scale; // at 0x0 + u16 loop_yn1; // at 0x2 + u16 loop_yn2; // at 0x4 +} AXPBADPCMLOOP; + +typedef struct _AXPBLPF { + u16 on; // at 0x0 + u16 yn1; // at 0x2 + u16 a0; // at 0x4 + u16 b0; // at 0x6 +} AXPBLPF; + +typedef struct _AXPBBIQUAD { + u16 on; // at 0x0 + u16 xn1; // at 0x2 + u16 xn2; // at 0x4 + u16 yn1; // at 0x6 + u16 yn2; // at 0x8 + u16 b0; // at 0xA + u16 b1; // at 0xC + u16 b2; // at 0xE + u16 a1; // at 0x10 + u16 a2; // at 0x12 +} AXPBBIQUAD; + +typedef struct _AXPBRMTMIX { + u16 vMain0; // at 0x0 + u16 vDeltaMain0; // at 0x2 + u16 vAux0; // at 0x4 + u16 vDeltaAux0; // at 0x6 + u16 vMain1; // at 0x8 + u16 vDeltaMain1; // at 0xA + u16 vAux1; // at 0xC + u16 vDeltaAux1; // at 0xE + u16 vMain2; // at 0x10 + u16 vDeltaMain2; // at 0x12 + u16 vAux2; // at 0x14 + u16 vDeltaAux2; // at 0x16 + u16 vMain3; // at 0x18 + u16 vDeltaMain3; // at 0x1A + u16 vAux3; // at 0x1C + u16 vDeltaAux3; // at 0x1E +} AXPBRMTMIX; + +typedef struct _AXPBRMTDPOP { + s16 aMain0; // at 0x0 + s16 aMain1; // at 0x2 + s16 aMain2; // at 0x4 + s16 aMain3; // at 0x6 + s16 aAux0; // at 0x8 + s16 aAux1; // at 0xA + s16 aAux2; // at 0xC + s16 aAux3; // at 0xE +} AXPBRMTDPOP; + +typedef struct _AXPBRMTSRC { + u16 currentAddressFrac; // at 0x0 + u16 last_samples[4]; // at 0x2 +} AXPBRMTSRC; + +typedef union __AXPBRMTIIR { + AXPBLPF lpf; + AXPBBIQUAD biquad; +} AXPBRMTIIR; + +typedef struct _AXPB { + u16 nextHi; // at 0x0 + u16 nextLo; // at 0x2 + u16 currHi; // at 0x4 + u16 currLo; // at 0x6 + u16 srcSelect; // at 0x8 + u16 coefSelect; // at 0xA + u32 mixerCtrl; // at 0xC + u16 state; // at 0x10 + u16 type; // at 0x12 + AXPBMIX mix; // at 0x14 + AXPBITD itd; // at 0x44 + AXPBDPOP dpop; // at 0x52 + AXPBVE ve; // at 0x6A + AXPBADDR addr; // at 0x6E + AXPBADPCM adpcm; // at 0x7E + AXPBSRC src; // at 0xA6 + AXPBADPCMLOOP adpcmLoop; // at 0xB4 + AXPBLPF lpf; // at 0xBA + AXPBBIQUAD biquad; // at 0xC2 + u16 remote; // at 0xD6 + u16 rmtMixerCtrl; // at 0xD8 + AXPBRMTMIX rmtMix; // at 0xDA + AXPBRMTDPOP rmtDpop; // at 0xFA + AXPBRMTSRC rmtSrc; // at 0x10A + AXPBRMTIIR rmtIIR; // at 0x114 + u8 padding[0x140 - 0x128]; // at 0x128 +} AXPB; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AX/AXProf.h b/include/rvl/AX/AXProf.h new file mode 100644 index 00000000..c0dc8f9f --- /dev/null +++ b/include/rvl/AX/AXProf.h @@ -0,0 +1,24 @@ +#ifndef RVL_SDK_AX_PROF_H +#define RVL_SDK_AX_PROF_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _AXPROFILE { + s64 timeBegin; // at 0x0 + s64 timeProcessAuxBegin; // at 0x8 + s64 timeProcessAuxEnd; // at 0x10 + s64 timeUserFrameBegin; // at 0x18 + s64 timeUserFrameEnd; // at 0x20 + s64 timeEnd; // at 0x28 + s32 numVoices; // at 0x30 + UNKWORD WORD_0x34; +} AXPROFILE; + +AXPROFILE *__AXGetCurrentProfile(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AX/AXSPB.h b/include/rvl/AX/AXSPB.h new file mode 100644 index 00000000..4e562cc3 --- /dev/null +++ b/include/rvl/AX/AXSPB.h @@ -0,0 +1,82 @@ +#ifndef RVL_SDK_AX_SPB_H +#define RVL_SDK_AX_SPB_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +#pragma pack(push, 1) +typedef struct _AXSTUDIO { + s32 L; + s16 dL; + + s32 R; + s16 dR; + + s32 S; + s16 dS; + + s32 AuxAL; + s16 dAuxAL; + + s32 AuxAR; + s16 dAuxAR; + + s32 AuxAS; + s16 dAuxAS; + + s32 AuxBL; + s16 dAuxBL; + + s32 AuxBR; + s16 dAuxBR; + + s32 AuxBS; + s16 dAuxBS; + + s32 AuxCL; + s16 dAuxCL; + + s32 AuxCR; + s16 dAuxCR; + + s32 AuxCS; + s16 dAuxCS; + + s32 Main0; + s16 dMain0; + + s32 Aux0; + s16 dAux0; + + s32 Main1; + s16 dMain1; + + s32 Aux1; + s16 dAux1; + + s32 Main2; + s16 dMain2; + + s32 Aux2; + s16 dAux2; + + s32 Main3; + s16 dMain3; + + s32 Aux3; + s16 dAux3; +} AXSTUDIO; +#pragma pack(pop) + +AXSTUDIO *__AXGetStudio(void); +void __AXDepopFadeMain(s32 *all, s32 *value, s16 *depop) DECOMP_DONT_INLINE; +void __AXDepopFadeRmt(s32 *all, s32 *value, s16 *depop) DECOMP_DONT_INLINE; +void __AXPrintStudio(void); +void __AXSPBInit(void); +void __AXDepopVoice(AXPB *pb); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AX/AXVPB.h b/include/rvl/AX/AXVPB.h new file mode 100644 index 00000000..4e39e7de --- /dev/null +++ b/include/rvl/AX/AXVPB.h @@ -0,0 +1,80 @@ +#ifndef RVL_SDK_AX_VPB_H +#define RVL_SDK_AX_VPB_H +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define AX_SAMPLE_RATE 32000 +#define AX_VOICE_MAX 96 + +typedef enum { + AX_PBSYNC_SELECT = (1 << 0), + AX_PBSYNC_MIXER_CTRL = (1 << 1), + AX_PBSYNC_STATE = (1 << 2), + AX_PBSYNC_TYPE = (1 << 3), + AX_PBSYNC_MIX = (1 << 4), + AX_PBSYNC_ITD = (1 << 5), + AX_PBSYNC_ITD_SHIFT = (1 << 6), + AX_PBSYNC_DPOP = (1 << 7), + AX_PBSYNC_VE = (1 << 8), + AX_PBSYNC_VE_DELTA = (1 << 9), + AX_PBSYNC_ADDR = (1 << 10), + AX_PBSYNC_LOOP_FLAG = (1 << 11), + AX_PBSYNC_LOOP_ADDR = (1 << 12), + AX_PBSYNC_END_ADDR = (1 << 13), + AX_PBSYNC_CURR_ADDR = (1 << 14), + AX_PBSYNC_ADPCM = (1 << 15), + AX_PBSYNC_SRC = (1 << 16), + AX_PBSYNC_SRC_RATIO = (1 << 17), + AX_PBSYNC_ADPCM_LOOP = (1 << 18), + AX_PBSYNC_LPF = (1 << 19), + AX_PBSYNC_LPF_COEFS = (1 << 20), + AX_PBSYNC_BIQUAD = (1 << 21), + AX_PBSYNC_BIQUAD_COEFS = (1 << 22), + AX_PBSYNC_REMOTE = (1 << 23), + AX_PBSYNC_RMT_MIXER_CTRL = (1 << 24), + AX_PBSYNC_RMTMIX = (1 << 25), + AX_PBSYNC_RMTDPOP = (1 << 26), + AX_PBSYNC_RMTSRC = (1 << 27), + AX_PBSYNC_RMTIIR = (1 << 28), + AX_PBSYNC_RMTIIR_LPF_COEFS = (1 << 29), + AX_PBSYNC_RMTIIR_BIQUAD_COEFS = (1 << 30), + AX_PBSYNC_ALL = (1 << 31), +}; + +typedef void (*AXVoiceCallback)(void *voice); + +typedef struct _AXVPB { + void *next; // at 0x0 + void *prev; // at 0x4 + void *next1; // at 0x8 + u32 priority; // at 0xC + AXVoiceCallback callback; // at 0x10 + u32 userContext; // at 0x14 + u32 index; // at 0x18 + u32 sync; // at 0x1C + u32 depop; // at 0x20 + void *itdBuffer; // at 0x24 + AXPB pb; // at 0x28 +} AXVPB; + +s32 __AXGetNumVoices(void); +void __AXServiceVPB(AXVPB *vpb); +void __AXDumpVPB(AXVPB *vpb); +void __AXSyncPBs(u32 baseCycles); +AXPB *__AXGetPBs(void); +void __AXSetPBDefault(AXVPB *vpb); +void __AXVPBInit(void); +void AXSetVoiceState(AXVPB *vpb, u16 state); +void AXSetVoiceAddr(AXVPB *vpb, AXPBADDR *addr); +void AXGetLpfCoefs(u16 freq, u16 *a, u16 *b); +void AXSetMaxDspCycles(u32 num); +s32 AXGetMaxVoices(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AX/DSPCode.h b/include/rvl/AX/DSPCode.h new file mode 100644 index 00000000..b7b5a1ac --- /dev/null +++ b/include/rvl/AX/DSPCode.h @@ -0,0 +1,17 @@ +#ifndef RVL_SDK_AX_DSP_CODE_H +#define RVL_SDK_AX_DSP_CODE_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +extern u16 axDspInitVector; +extern u16 axDspResumeVector; + +extern u8 axDspSlave[]; +extern u16 axDspSlaveLength; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AXFX.h b/include/rvl/AXFX.h new file mode 100644 index 00000000..8c6b192a --- /dev/null +++ b/include/rvl/AXFX.h @@ -0,0 +1,22 @@ +#ifndef RVL_SDK_PUBLIC_AXFX_H +#define RVL_SDK_PUBLIC_AXFX_H +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AXFX/AXFXChorus.h b/include/rvl/AXFX/AXFXChorus.h new file mode 100644 index 00000000..fc515746 --- /dev/null +++ b/include/rvl/AXFX/AXFXChorus.h @@ -0,0 +1,26 @@ +#ifndef RVL_SDK_AXFX_CHORUS_H +#define RVL_SDK_AXFX_CHORUS_H +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct AXFX_CHORUS { + AXFX_CHORUS_EXP exp; // at 0x0 + u32 baseDelay; // at 0xA0 + u32 variation; // at 0xA4 + u32 period; // at 0xA8 +} AXFX_CHORUS; + +u32 AXFXChorusGetMemSize(const AXFX_CHORUS *fx); +BOOL AXFXChorusInit(AXFX_CHORUS *fx); +BOOL AXFXChorusShutdown(AXFX_CHORUS *fx); +BOOL AXFXChorusSettings(AXFX_CHORUS *fx); +void AXFXChorusCallback(void *chans, void *context); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AXFX/AXFXChorusExp.h b/include/rvl/AXFX/AXFXChorusExp.h new file mode 100644 index 00000000..3892eda6 --- /dev/null +++ b/include/rvl/AXFX/AXFXChorusExp.h @@ -0,0 +1,59 @@ +#ifndef RVL_SDK_AXFX_CHORUS_EXP_H +#define RVL_SDK_AXFX_CHORUS_EXP_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +// Forward declarations +typedef struct AXFX_BUS; +typedef struct AXFX_BUFFERUPDATE; + +typedef struct AXFX_CHORUS_EXP_DELAY { + f32 *line[3]; // at 0x0 + u32 inPos; // at 0xC + u32 outPos; // at 0x10 + u32 lastPos; // at 0x14 + u32 sizeFP; // at 0x18 + u32 size; // at 0x1C +} AXFX_CHORUS_EXP_DELAY; + +typedef struct AXFX_CHORUS_EXP_LFO { + s32 *table; // at 0x0 + s32 phaseAdd; // at 0x4 + s32 stepSamp; // at 0x8 + s32 depthSamp; // at 0xC + u32 phase; // at 0x10 + u32 sign; // at 0x14 + u32 lastNum; // at 0x18 + s32 lastValue; // at 0x1C + s32 grad; // at 0x20 + s32 gradFactor; // at 0x24 +} AXFX_CHORUS_EXP_LFO; + +typedef struct AXFX_CHORUS_EXP { + AXFX_CHORUS_EXP_DELAY delay; // at 0x0 + AXFX_CHORUS_EXP_LFO lfo; // at 0x20 + f32 history[3][4]; // at 0x48 + u32 histIndex; // at 0x78 + u32 active; // at 0x7C + f32 delayTime; // at 0x80 + f32 depth; // at 0x84 + f32 rate; // at 0x88 + f32 feedback; // at 0x8C + struct AXFX_BUS *busIn; // at 0x90 + struct AXFX_BUS *busOut; // at 0x94 + f32 outGain; // at 0x98 + f32 sendGain; // at 0x9C +} AXFX_CHORUS_EXP; + +u32 AXFXChorusExpGetMemSize(const AXFX_CHORUS_EXP *fx); +BOOL AXFXChorusExpInit(AXFX_CHORUS_EXP *fx); +void AXFXChorusExpShutdown(AXFX_CHORUS_EXP *fx); +BOOL AXFXChorusExpSettings(AXFX_CHORUS_EXP *fx); +void AXFXChorusExpCallback(struct AXFX_BUFFERUPDATE *update, AXFX_CHORUS_EXP *fx); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AXFX/AXFXCommon.h b/include/rvl/AXFX/AXFXCommon.h new file mode 100644 index 00000000..ac72acb3 --- /dev/null +++ b/include/rvl/AXFX/AXFXCommon.h @@ -0,0 +1,30 @@ +#ifndef RVL_SDK_AXFX_COMMON_H +#define RVL_SDK_AXFX_COMMON_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct AXFX_BUS { + s32 *left; // at 0x0 + s32 *right; // at 0x4 + s32 *surround; // at 0x8 +} AXFX_BUS; + +typedef struct AXFX_BUFFERUPDATE { + s32 *left; // at 0x0 + s32 *right; // at 0x4 + s32 *surround; // at 0x8 +} AXFX_BUFFERUPDATE; + +typedef struct AXFX_BUFFERUPDATE_DPL2 { + s32 *left; // at 0x0 + s32 *right; // at 0x4 + s32 *left_surround; // at 0x8 + s32 *right_surround; // at 0xC +} AXFX_BUFFERUPDATE_DPL2; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AXFX/AXFXDelay.h b/include/rvl/AXFX/AXFXDelay.h new file mode 100644 index 00000000..54d35e13 --- /dev/null +++ b/include/rvl/AXFX/AXFXDelay.h @@ -0,0 +1,29 @@ +#ifndef RVL_SDK_AXFX_DELAY_H +#define RVL_SDK_AXFX_DELAY_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct AXFX_DELAY { + s32 *line[3]; // at 0x0 + u32 curPos[3]; // at 0xC + u32 length[3]; // at 0x18 + s32 feedbackGain[3]; // at 0x24 + s32 outGain[3]; // at 0x30 + u32 active; // at 0x3C + u32 delay[3]; // at 0x40 + u32 feedback[3]; // at 0x4C + u32 output[3]; // at 0x58 +} AXFX_DELAY; + +u32 AXFXDelayGetMemSize(const AXFX_DELAY *fx); +BOOL AXFXDelayInit(AXFX_DELAY *fx); +BOOL AXFXDelaySettings(AXFX_DELAY *fx); +void AXFXDelayShutdown(AXFX_DELAY *fx); +void AXFXDelayCallback(void *chans, void *context); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AXFX/AXFXHooks.h b/include/rvl/AXFX/AXFXHooks.h new file mode 100644 index 00000000..cb210591 --- /dev/null +++ b/include/rvl/AXFX/AXFXHooks.h @@ -0,0 +1,20 @@ +#ifndef RVL_SDK_AXFX_HOOKS_H +#define RVL_SDK_AXFX_HOOKS_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *(*AXFXAllocHook)(size_t size); +typedef void (*AXFXFreeHook)(void *block); + +extern AXFXAllocHook __AXFXAlloc; +extern AXFXFreeHook __AXFXFree; + +void AXFXSetHooks(AXFXAllocHook alloc, AXFXFreeHook free); +void AXFXGetHooks(AXFXAllocHook *alloc, AXFXFreeHook *free); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AXFX/AXFXLfoTable.h b/include/rvl/AXFX/AXFXLfoTable.h new file mode 100644 index 00000000..f2bbd753 --- /dev/null +++ b/include/rvl/AXFX/AXFXLfoTable.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_AXFX_LFO_TABLE_H +#define RVL_SDK_AXFX_LFO_TABLE_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +s32 *__AXFXGetLfoSinTable(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AXFX/AXFXReverbHi.h b/include/rvl/AXFX/AXFXReverbHi.h new file mode 100644 index 00000000..dcc8a379 --- /dev/null +++ b/include/rvl/AXFX/AXFXReverbHi.h @@ -0,0 +1,29 @@ +#ifndef RVL_SDK_AXFX_REVERB_HI_H +#define RVL_SDK_AXFX_REVERB_HI_H +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct AXFX_REVERBHI { + AXFX_REVERBHI_EXP exp; // at 0x0 + f32 coloration; // at 0x148 + f32 mix; // at 0x14C + f32 time; // at 0x150 + f32 damping; // at 0x154 + f32 preDelay; // at 0x158 + f32 crosstalk; // at 0x15C +} AXFX_REVERBHI; + +u32 AXFXReverbHiGetMemSize(AXFX_REVERBHI *fx); +BOOL AXFXReverbHiInit(AXFX_REVERBHI *fx); +BOOL AXFXReverbHiShutdown(AXFX_REVERBHI *fx); +BOOL AXFXReverbHiSettings(AXFX_REVERBHI *fx); +void AXFXReverbHiCallback(void *chans, void *context); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AXFX/AXFXReverbHiDpl2.h b/include/rvl/AXFX/AXFXReverbHiDpl2.h new file mode 100644 index 00000000..e7fdbfd4 --- /dev/null +++ b/include/rvl/AXFX/AXFXReverbHiDpl2.h @@ -0,0 +1,29 @@ +#ifndef RVL_SDK_AXFX_REVERB_HI_DPL2_H +#define RVL_SDK_AXFX_REVERB_HI_DPL2_H +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct AXFX_REVERBHI_DPL2 { + AXFX_REVERBHI_EXP_DPL2 exp; // at 0x0 + f32 coloration; // at 0x148 + f32 mix; // at 0x14C + f32 time; // at 0x150 + f32 damping; // at 0x154 + f32 preDelay; // at 0x158 + f32 crosstalk; // at 0x15C +} AXFX_REVERBHI_DPL2; + +u32 AXFXReverbHiGetMemSizeDpl2(AXFX_REVERBHI_DPL2 *fx); +BOOL AXFXReverbHiInitDpl2(AXFX_REVERBHI_DPL2 *fx); +BOOL AXFXReverbHiShutdownDpl2(AXFX_REVERBHI_DPL2 *fx); +BOOL AXFXReverbHiSettingsDpl2(AXFX_REVERBHI_DPL2 *fx); +void AXFXReverbHiCallbackDpl2(void *chans, void *context); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AXFX/AXFXReverbHiExp.h b/include/rvl/AXFX/AXFXReverbHiExp.h new file mode 100644 index 00000000..d0089190 --- /dev/null +++ b/include/rvl/AXFX/AXFXReverbHiExp.h @@ -0,0 +1,69 @@ +#ifndef RVL_SDK_AXFX_REVERB_HI_EXP_H +#define RVL_SDK_AXFX_REVERB_HI_EXP_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +// Forward declarations +typedef struct AXFX_BUS; +typedef struct AXFX_BUFFERUPDATE; + +typedef struct AXFX_REVERBHI_EXP { + f32 *earlyLine[3]; // at 0x0 + u32 earlyPos[3]; // at 0xC + u32 earlyLength; // at 0x18 + u32 earlyMaxLength; // at 0x1C + f32 earlyCoef[3]; // at 0x20 + + f32 *preDelayLine[3]; // at 0x2C + u32 preDelayPos; // at 0x38 + u32 preDelayLength; // at 0x3C + u32 preDelayMaxLength; // at 0x40 + + f32 *combLine[3][3]; // at 0x44 + u32 combPos[3]; // at 0x68 + u32 combLength[3]; // at 0x74 + u32 combMaxLength[3]; // at 0x80 + f32 combCoef[3]; // at 0x8C + + f32 *allpassLine[3][2]; // at 0x98 + u32 allpassPos[2]; // at 0xB0 + u32 allpassLength[2]; // at 0xB8 + u32 allpassMaxLength[2]; // at 0xC0 + + f32 *lastAllpassLine[3]; // at 0xC8 + u32 lastAllpassPos[3]; // at 0xD4 + u32 lastAllpassLength[3]; // at 0xE0 + u32 lastAllpassMaxLength[3]; // at 0xEC + + f32 allpassCoef; // at 0xF8 + f32 lastLpfOut[3]; // at 0xFC + f32 lpfCoef; // at 0x108 + u32 active; // at 0x10C + u32 earlyMode; // at 0x110 + f32 preDelayTimeMax; // at 0x114 + f32 preDelayTime; // at 0x118 + u32 fusedMode; // at 0x11C + f32 fusedTime; // at 0x120 + f32 coloration; // at 0x124 + f32 damping; // at 0x128 + f32 crosstalk; // at 0x12C + f32 earlyGain; // at 0x130 + f32 fusedGain; // at 0x134 + struct AXFX_BUS *busIn; // at 0x138 + struct AXFX_BUS *busOut; // at 0x13C + f32 outGain; // at 0x140 + f32 sendGain; // at 0x144 +} AXFX_REVERBHI_EXP; + +u32 AXFXReverbHiExpGetMemSize(const AXFX_REVERBHI_EXP *fx); +BOOL AXFXReverbHiExpInit(AXFX_REVERBHI_EXP *fx); +void AXFXReverbHiExpShutdown(AXFX_REVERBHI_EXP *fx); +BOOL AXFXReverbHiExpSettings(AXFX_REVERBHI_EXP *fx); +void AXFXReverbHiExpCallback(struct AXFX_BUFFERUPDATE *update, AXFX_REVERBHI_EXP *fx); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AXFX/AXFXReverbHiExpDpl2.h b/include/rvl/AXFX/AXFXReverbHiExpDpl2.h new file mode 100644 index 00000000..0fb21ae3 --- /dev/null +++ b/include/rvl/AXFX/AXFXReverbHiExpDpl2.h @@ -0,0 +1,65 @@ +#ifndef RVL_SDK_AXFX_REVERB_HI_EXP_DPL2_H +#define RVL_SDK_AXFX_REVERB_HI_EXP_DPL2_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct AXFX_REVERBHI_EXP_DPL2 { + f32 *earlyLine[4]; // at 0x0 + u32 earlyPos[3]; // at 0x10 + u32 earlyLength; // at 0x1C + u32 earlyMaxLength; // at 0x20 + f32 earlyCoef[3]; // at 0x24 + + f32 *preDelayLine[4]; // at 0x30 + u32 preDelayPos; // at 0x40 + u32 preDelayLength; // at 0x44 + u32 preDelayMaxLength; // at 0x48 + + f32 *combLine[4][3]; // at 0x4C + u32 combPos[3]; // at 0x7C + u32 combLength[3]; // at 0x88 + u32 combMaxLength[3]; // at 0x94 + f32 combCoef[3]; // at 0xA0 + + f32 *allpassLine[4][2]; // at 0xAC + u32 allpassPos[2]; // at 0xCC + u32 allpassLength[2]; // at 0xD4 + u32 allpassMaxLength[2]; // at 0xDC + + f32 *lastAllpassLine[4]; // at 0xE4 + u32 lastAllpassPos[4]; // at 0xF4 + u32 lastAllpassLength[4]; // at 0x104 + u32 lastAllpassMaxLength[4]; // at 0x114 + + f32 allpassCoef; // at 0x124 + f32 lastLpfOut[4]; // at 0x128 + f32 lpfCoef; // at 0x138 + u32 active; // at 0x13C + u32 earlyMode; // at 0x140 + f32 preDelayTimeMax; // at 0x144 + f32 preDelayTime; // at 0x148 + u32 fusedMode; // at 0x14C + f32 fusedTime; // at 0x150 + f32 coloration; // at 0x154 + f32 damping; // at 0x158 + f32 crosstalk; // at 0x15C + f32 earlyGain; // at 0x160 + f32 fusedGain; // at 0x164 + struct AXFX_BUS *busIn; // at 0x168 + struct AXFX_BUS *busOut; // at 0x16C + f32 outGain; // at 0x170 + f32 sendGain; // at 0x174 +} AXFX_REVERBHI_EXP_DPL2; + +u32 AXFXReverbHiExpGetMemSizeDpl2(const AXFX_REVERBHI_EXP_DPL2 *fx); +BOOL AXFXReverbHiExpInitDpl2(AXFX_REVERBHI_EXP_DPL2 *fx); +void AXFXReverbHiExpShutdownDpl2(AXFX_REVERBHI_EXP_DPL2 *fx); +BOOL AXFXReverbHiExpSettingsDpl2(AXFX_REVERBHI_EXP_DPL2 *fx); +void AXFXReverbHiExpCallbackDpl2(struct AXFX_BUFFERUPDATE_DPL2 *update, AXFX_REVERBHI_EXP_DPL2 *fx); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/AXFX/AXFXSrcCoef.h b/include/rvl/AXFX/AXFXSrcCoef.h new file mode 100644 index 00000000..aa0aaeef --- /dev/null +++ b/include/rvl/AXFX/AXFXSrcCoef.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_AXFX_SRC_COEF_H +#define RVL_SDK_AXFX_SRC_COEF_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +f32 *__AXFXGetSrcCoef(u32 i); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/KPAD/KPAD.h b/include/rvl/KPAD/KPAD.h new file mode 100644 index 00000000..8f46eb08 --- /dev/null +++ b/include/rvl/KPAD/KPAD.h @@ -0,0 +1,14 @@ +#ifndef REVOSDK_KPAD_H +#define REVOSDK_KPAD_H +#ifdef __cplusplus +#include +extern "C" { +#endif + +typedef struct { +} KPADStatus; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/OS/OSCache.h b/include/rvl/OS/OSCache.h index d8c995d6..1eecfb1f 100644 --- a/include/rvl/OS/OSCache.h +++ b/include/rvl/OS/OSCache.h @@ -5,6 +5,7 @@ extern "C" { #endif +#define OS_CACHE_BASE 0xE0000000 // Forward declarations typedef struct OSContext; diff --git a/include/rvl/WPAD.h b/include/rvl/WPAD.h new file mode 100644 index 00000000..f3cb5f35 --- /dev/null +++ b/include/rvl/WPAD.h @@ -0,0 +1,12 @@ +#ifndef RVL_SDK_PUBLIC_WPAD_H +#define RVL_SDK_PUBLIC_WPAD_H +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/rvl/WPAD/WPAD.h b/include/rvl/WPAD/WPAD.h new file mode 100644 index 00000000..67a16c43 --- /dev/null +++ b/include/rvl/WPAD/WPAD.h @@ -0,0 +1,30 @@ +#ifndef REVOSDK_WPAD_H +#define REVOSDK_WPAD_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*WPADCallback)(s32 chan, s32 result); + +typedef enum { WPAD_CHAN_0, WPAD_CHAN_1, WPAD_CHAN_2, WPAD_CHAN_3, WPAD_MAX_CONTROLLERS } WPADChan; + +typedef enum { + WPAD_RESULT_ERR_3 = -3, + WPAD_RESULT_ERR_2, + WPAD_RESULT_ERR_1, + + WPAD_RESULT_SUCCESS = 0, +} WPADResult; + +UNKTYPE WPADControlSpeaker(s32, UNKWORD, WPADCallback); +BOOL WPADCanSendStreamData(s32); +UNKWORD WPADSendStreamData(s32, UNKTYPE *, UNKWORD); + +s32 WPADProbe(s32 chan, u32 *type); +s32 WPADReadFaceData(s32 chan, void *dst, u32 size, u32 src, WPADCallback cb); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/m/m_mtx.cpp b/src/m/m_mtx.cpp index a4fb69ae..f72a6b65 100644 --- a/src/m/m_mtx.cpp +++ b/src/m/m_mtx.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include void mMtx_c::toRot(mAng3_c &out) const { f32 t1 = 0.0f; diff --git a/src/toBeSorted/misc_flag_managers.cpp b/src/toBeSorted/misc_flag_managers.cpp index 72a802c8..312d105f 100644 --- a/src/toBeSorted/misc_flag_managers.cpp +++ b/src/toBeSorted/misc_flag_managers.cpp @@ -1,11 +1,12 @@ -#include -#include -#include -#include +#include #include +#include +#include +#include + class CommittableFlagManager { - public: +public: bool mNeedsCommit; virtual void doCommit() = 0; @@ -31,16 +32,17 @@ bool CommittableFlagManager::commitIfNecessary() { } } -class TBoxFlagManager: public CommittableFlagManager { -// class TBoxFlagManager { +class TBoxFlagManager : public CommittableFlagManager { + // class TBoxFlagManager { // bool mNeedsCommit; // u32 pad; FlagSpace mFlagSpace; u16 mSceneIndex; BitwiseFlagHelper mFlagHelper; - static u16* sFlags; - public: + static u16 *sFlags; + +public: virtual void doCommit() override; bool checkUncommittedFlag(u16 flag); TBoxFlagManager(); @@ -66,7 +68,7 @@ bool TBoxFlagManager::checkUncommittedFlag(u16 flag) { return mFlagHelper.checkFlag(flag / 16, flag % 16, mFlagSpace.getFlagPtrUnchecked(), mFlagSpace.mCount); } -TBoxFlagManager::TBoxFlagManager(): CommittableFlagManager(false), mFlagSpace(sFlags, 2) { +TBoxFlagManager::TBoxFlagManager() : CommittableFlagManager(false), mFlagSpace(sFlags, 2) { mSceneIndex = 0xFFFF; } @@ -75,13 +77,14 @@ void TBoxFlagManager::init() {} void TBoxFlagManager::copyFromSave(u16 sceneIndex) { // mr should be a clrlwi mSceneIndex = sceneIndex; - u16* flags = FileManager::getInstance()->getTBoxFlagsConst(); + u16 *flags = FileManager::getInstance()->getTBoxFlagsConst(); mFlagSpace.copyFromSaveFile2(flags + (sceneIndex * 2), 0, 2); } bool TBoxFlagManager::checkFlag(u16 sceneIndex, u16 flag) { s32 actualFlag = (flag + sceneIndex * 0x20); - return mFlagHelper.checkFlag(actualFlag / 16, flag % 16, FileManager::getInstance()->getTBoxFlagsConst(), getFlagCount()); + return mFlagHelper.checkFlag(actualFlag / 16, flag % 16, FileManager::getInstance()->getTBoxFlagsConst(), + getFlagCount()); } u16 TBoxFlagManager::getFlagCount() const { @@ -101,7 +104,7 @@ public: BitwiseFlagHelper mFlagHelper; u16 mSceneIndex; - static u16* sFlags; + static u16 *sFlags; void clearSavedFlags(); bool checkUncommittedFlag(u16 flag); @@ -128,16 +131,13 @@ void EnemyDefeatManager::clearSavedFlags() { bool EnemyDefeatManager::checkUncommittedFlag(u16 flag) { if (checkIsValidFlag(flag)) { - - return mFlagHelper.checkFlag(flag / 16, flag % 16, mFlagSpace.getFlagPtrUnchecked(), mFlagSpace.mCount); + return mFlagHelper.checkFlag(flag / 16, flag % 16, mFlagSpace.getFlagPtrUnchecked(), mFlagSpace.mCount); } else { return false; } } -EnemyDefeatManager::EnemyDefeatManager(): CommittableFlagManager(false), mFlagSpace(sFlags, 12 /* later */) { - -} +EnemyDefeatManager::EnemyDefeatManager() : CommittableFlagManager(false), mFlagSpace(sFlags, 12 /* later */) {} void EnemyDefeatManager::init() { mSceneIndex = 0; @@ -147,7 +147,7 @@ void EnemyDefeatManager::init() { void EnemyDefeatManager::copyFromSave(u16 sceneIndex) { mSceneIndex = sceneIndex; u16 count = mFlagSpace.mCount; - u16* flags = FileManager::getInstance()->getEnemyDefeatFlagsConst(); + u16 *flags = FileManager::getInstance()->getEnemyDefeatFlagsConst(); mFlagSpace.copyFromSaveFile(flags, 0, count); } @@ -172,7 +172,7 @@ bool EnemyDefeatManager::checkFlag(u16 flag) { if (!checkIsValidFlag(flag)) { return false; } else { - u16* pData = FileManager::getInstance()->getEnemyDefeatFlagsConst(); + u16 *pData = FileManager::getInstance()->getEnemyDefeatFlagsConst(); return mFlagHelper.checkFlag(flag / 16, flag % 16, pData, getFlagCount()); } }