summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelijah-thomas774 <elijahthomas774@gmail.com>2024-05-05 22:27:50 -0400
committerelijah-thomas774 <elijahthomas774@gmail.com>2024-05-05 22:27:50 -0400
commit344348bc0508cc132b77bfb81404bfdb99ae3fcf (patch)
tree1a1eafebc8ad18fba08570d3f15b0031b25d733a
parent126c5db9431bef2b6f032bce673d7c3d61e62aa3 (diff)
nw4r ut almost matching
-rw-r--r--config/SOUE01/config.yml2
-rw-r--r--config/SOUE01/splits.txt24
-rw-r--r--config/SOUE01/symbols.txt269
-rw-r--r--configure.py17
-rw-r--r--include/MSL_C/MSL_Common/Src/ansi_files.h25
-rw-r--r--include/nw4r/ut/ut_CharWriter.h1
-rw-r--r--include/nw4r/ut/ut_DvdFileStream.h18
-rw-r--r--include/nw4r/ut/ut_DvdLockedFileStream.h19
-rw-r--r--include/nw4r/ut/ut_Font.h5
-rw-r--r--include/nw4r/ut/ut_IOStream.h6
-rw-r--r--include/nw4r/ut/ut_NandFileStream.h30
-rw-r--r--include/nw4r/ut/ut_ResFont.h5
-rw-r--r--include/nw4r/ut/ut_ResFontBase.h49
-rw-r--r--include/nw4r/ut/ut_RomFont.h3
-rw-r--r--include/nw4r/ut/ut_TextWriterBase.h51
-rw-r--r--include/rvl/DVD.h3
-rw-r--r--include/rvl/DVD/dvd.h101
-rw-r--r--include/rvl/DVD/dvd_broadway.h28
-rw-r--r--include/rvl/DVD/dvderror.h38
-rw-r--r--include/rvl/DVD/dvdfs.h36
-rw-r--r--include/rvl/DVD/dvdidutils.h14
-rw-r--r--include/rvl/DVD/dvdqueue.h28
-rw-r--r--include/rvl/GX/GXInit.h13
-rw-r--r--include/rvl/GX/GXPixel.h2
-rw-r--r--include/rvl/GX/GXTransform.h2
-rw-r--r--include/rvl/GX/GXTypes.h115
-rw-r--r--include/rvl/NAND/nand.h9
-rw-r--r--src/egg/core/eggAsyncDisplay.cpp4
-rw-r--r--src/nw4r/ut/ut_CharWriter.cpp260
-rw-r--r--src/nw4r/ut/ut_DvdFileStream.cpp180
-rw-r--r--src/nw4r/ut/ut_DvdLockedFileStream.cpp93
-rw-r--r--src/nw4r/ut/ut_Font.cpp25
-rw-r--r--src/nw4r/ut/ut_IOStream.cpp2
-rw-r--r--src/nw4r/ut/ut_LockedCache.cpp104
-rw-r--r--src/nw4r/ut/ut_NandFileStream.cpp178
-rw-r--r--src/nw4r/ut/ut_ResFont.cpp121
-rw-r--r--src/nw4r/ut/ut_ResFontBase.cpp221
-rw-r--r--src/nw4r/ut/ut_RomFont.cpp226
-rw-r--r--src/nw4r/ut/ut_TextWriterBase.cpp494
39 files changed, 2476 insertions, 345 deletions
diff --git a/config/SOUE01/config.yml b/config/SOUE01/config.yml
index 6b77249c..3615db70 100644
--- a/config/SOUE01/config.yml
+++ b/config/SOUE01/config.yml
@@ -10,6 +10,8 @@ force_active: [
"ProcessTab__Q34nw4r2ut19TagProcessorBase<c>FPQ34nw4r2ut15PrintContext<c>",
"ProcessLinefeed__Q34nw4r2ut19TagProcessorBase<w>FPQ34nw4r2ut15PrintContext<w>",
"ProcessTab__Q34nw4r2ut19TagProcessorBase<w>FPQ34nw4r2ut15PrintContext<w>",
+ # "RemoveResourceBuffer__Q44nw4r2ut6detail11ResFontBaseFv",
+ "RemoveResource__Q34nw4r2ut7ResFontFv",
]
# modules:
# - object: orig/SOUE01/rels/d_a_asura_bulletNP.rel
diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt
index 4973c05f..b30c84e6 100644
--- a/config/SOUE01/splits.txt
+++ b/config/SOUE01/splits.txt
@@ -253,34 +253,56 @@ nw4r/ut/ut_FileStream.cpp:
nw4r/ut/ut_DvdFileStream.cpp:
.text start:0x8042B6F0 end:0x8042BDAC
.ctors start:0x804DB940 end:0x804DB944
+ .data start:0x8056BD78 end:0x8056BDE0
+ .sbss start:0x805765A0 end:0x805765A8
nw4r/ut/ut_DvdLockedFileStream.cpp:
.text start:0x8042BDB0 end:0x8042C1DC
.ctors start:0x804DB944 end:0x804DB948
+ .data start:0x8056BDE0 end:0x8056BE48
+ .sbss start:0x805765A8 end:0x805765C0
+ .bss start:0x80636B20 end:0x80636B38
nw4r/ut/ut_NandFileStream.cpp:
.text start:0x8042C1E0 end:0x8042CA4C
.ctors start:0x804DB948 end:0x804DB94C
+ .data start:0x8056BE48 end:0x8056BEA8
+ .sbss start:0x805765C0 end:0x805765C8
nw4r/ut/ut_LockedCache.cpp:
.text start:0x8042CA50 end:0x8042CC28
.ctors start:0x804DB94C end:0x804DB950
+ .bss start:0x80636B38 end:0x80636B58
nw4r/ut/ut_Font.cpp:
- .text start:0x8042CC30 end:0x8042CD20
+ .text start:0x8042CC30 end:0x8042CCD4
+ .data start:0x8056BEA8 end:0x8056BED8
+
+nw4r/ut/ut_RomFont.cpp:
+ .text start:0x8042CCE0 end:0x8042CD20
+ .data start:0x8056BED8 end:0x8056BF38
nw4r/ut/ut_ResFontBase.cpp:
.text start:0x8042CD20 end:0x8042D4B8
+ .data start:0x8056BF38 end:0x8056BFA0
nw4r/ut/ut_ResFont.cpp:
.text start:0x8042D4C0 end:0x8042D7CC
+ .data start:0x8056BFA0 end:0x8056C000
nw4r/ut/ut_CharWriter.cpp:
.text start:0x8042D7D0 end:0x8042EF1C
+ .sbss start:0x805765C8 end:0x805765D0
+ .sdata2 start:0x8057EB70 end:0x8057EB90
+ .bss start:0x80636B58 end:0x80636B68
nw4r/ut/ut_TextWriterBase.cpp:
.text start:0x8042EF20 end:0x80434294
.ctors start:0x804DB950 end:0x804DB954
+ .sdata start:0x80574DC0 end:0x80574DC8
+ .sbss start:0x805765D0 end:0x805765E8
+ .sdata2 start:0x8057EB90 end:0x8057EBA8
+ .bss start:0x80636B68 end:0x80636B80
nw4r/db/db_directPrint.cpp:
.text start:0x804342A0 end:0x80434E9C
diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt
index f3114665..c0fbc182 100644
--- a/config/SOUE01/symbols.txt
+++ b/config/SOUE01/symbols.txt
@@ -17361,7 +17361,7 @@ searchBaseByGroupType__10fManager_cFUcPC7fBase_c = .text:0x802E2980; // type:fun
mainLoop__10fManager_cFv = .text:0x802E29E0; // type:function size:0xC0
__sinit_\f_manager_cpp = .text:0x802E2AA0; // type:function size:0x138 scope:local
__ct__9fLiMgBa_cFv = .text:0x802E2BE0; // type:function size:0x10
-__arraydtor$4018 = .text:0x802E2BF0; // type:function size:0x1C scope:local
+__arraydtor$4110 = .text:0x802E2BF0; // type:function size:0x1C scope:local
walkPack__11fTrMgPTMF_cFv = .text:0x802E2C10; // type:function size:0x84
searchNodeByProfName__9fTrMgBa_cCFUsPC9fTrNdBa_c = .text:0x802E2CA0; // type:function size:0x68
searchNodeByGroupType__9fTrMgBa_cCFUcPC9fTrNdBa_c = .text:0x802E2D10; // type:function size:0x68
@@ -21895,37 +21895,37 @@ DCInvalidateRange = .text:0x803A4560; // type:function size:0x2C scope:global
DCFlushRange = .text:0x803A4590; // type:function size:0x30 scope:global
DCStoreRange = .text:0x803A45C0; // type:function size:0x30
DCFlushRangeNoSync = .text:0x803A45F0; // type:function size:0x2C scope:global
-fn_803A4620 = .text:0x803A4620; // type:function size:0x2C
+DCStoreRangeNoSync = .text:0x803A4620; // type:function size:0x2C
DCZeroRange = .text:0x803A4650; // type:function size:0x2C scope:global
ICInvalidateRange = .text:0x803A4680; // type:function size:0x34 scope:global
ICFlashInvalidate = .text:0x803A46C0; // type:function size:0x10 scope:global
ICEnable = .text:0x803A46D0; // type:function size:0x14 scope:global
-fn_803A46F0 = .text:0x803A46F0; // type:function size:0xCC
-fn_803A47C0 = .text:0x803A47C0; // type:function size:0x38
+__LCEnable = .text:0x803A46F0; // type:function size:0xCC
+LCEnable = .text:0x803A47C0; // type:function size:0x38
LCDisable = .text:0x803A4800; // type:function size:0x28 scope:global
-fn_803A4830 = .text:0x803A4830; // type:function size:0x24
-fn_803A4860 = .text:0x803A4860; // type:function size:0x24
-fn_803A4890 = .text:0x803A4890; // type:function size:0xA0
-fn_803A4930 = .text:0x803A4930; // type:function size:0xC
-fn_803A4940 = .text:0x803A4940; // type:function size:0x14
+LCLoadBlocks = .text:0x803A4830; // type:function size:0x24
+LCStoreBlocks = .text:0x803A4860; // type:function size:0x24
+LCStoreData = .text:0x803A4890; // type:function size:0xA0
+LCQueueLength = .text:0x803A4930; // type:function size:0xC
+LCQueueWait = .text:0x803A4940; // type:function size:0x14
DMAErrorHandler = .text:0x803A4960; // type:function size:0x148 scope:global
__OSCacheInit = .text:0x803A4AB0; // type:function size:0xE8 scope:global
__OSLoadFPUContext = .text:0x803A4BA0; // type:function size:0x124 scope:local
__OSSaveFPUContext = .text:0x803A4CD0; // type:function size:0x128 scope:local
OSSaveFPUContext = .text:0x803A4E00; // type:function size:0x8 scope:global
OSSetCurrentContext = .text:0x803A4E10; // type:function size:0x5C scope:global
-fn_803A4E70 = .text:0x803A4E70; // type:function size:0xC
-fn_803A4E80 = .text:0x803A4E80; // type:function size:0x80
+OSGetCurrentContext = .text:0x803A4E70; // type:function size:0xC
+OSSaveContext = .text:0x803A4E80; // type:function size:0x80
OSLoadContext = .text:0x803A4F00; // type:function size:0xD8 scope:global
OSGetStackPointer = .text:0x803A4FE0; // type:function size:0x8 scope:global
-fn_803A4FF0 = .text:0x803A4FF0; // type:function size:0x30
-fn_803A5020 = .text:0x803A5020; // type:function size:0x30
+OSSwitchFiber = .text:0x803A4FF0; // type:function size:0x30
+OSSwitchFiberEx = .text:0x803A5020; // type:function size:0x30
OSClearContext = .text:0x803A5050; // type:function size:0x24 scope:global
-fn_803A5080 = .text:0x803A5080; // type:function size:0xBC
+OSInitContext = .text:0x803A5080; // type:function size:0xBC
OSDumpContext = .text:0x803A5140; // type:function size:0x260 scope:global
OSSwitchFPUContext = .text:0x803A53A0; // type:function size:0x84 scope:local
__OSContextInit = .text:0x803A5430; // type:function size:0x38 scope:global
-fn_803A5470 = .text:0x803A5470; // type:function size:0x12C
+OSFillFPUContext = .text:0x803A5470; // type:function size:0x12C
OSSetErrorHandler = .text:0x803A55A0; // type:function size:0x28C scope:global
__OSUnhandledException = .text:0x803A5830; // type:function size:0x2FC scope:global
fn_803A5B30 = .text:0x803A5B30; // type:function size:0x180
@@ -22000,7 +22000,7 @@ OSInitMutex = .text:0x803AAA90; // type:function size:0x38
OSLockMutex = .text:0x803AAAD0; // type:function size:0xDC
OSUnlockMutex = .text:0x803AABB0; // type:function size:0xC8
fn_803AAC80 = .text:0x803AAC80; // type:function size:0x6C
-fn_803AACF0 = .text:0x803AACF0; // type:function size:0xBC
+OSTryLockMutex = .text:0x803AACF0; // type:function size:0xBC
fn_803AADB0 = .text:0x803AADB0; // type:function size:0x6C
fn_803AAE20 = .text:0x803AAE20; // type:function size:0x14
OSRegisterShutdownFunction = .text:0x803AAE40; // type:function size:0x88 scope:global
@@ -22043,7 +22043,7 @@ fn_803AC810 = .text:0x803AC810; // type:function size:0x1A8
fn_803AC9C0 = .text:0x803AC9C0; // type:function size:0x50
SelectThread = .text:0x803ACA10; // type:function size:0x22C scope:local
__OSReschedule = .text:0x803ACC40; // type:function size:0x18 scope:global
-fn_803ACC60 = .text:0x803ACC60; // type:function size:0x3C
+OSYieldThread = .text:0x803ACC60; // type:function size:0x3C
OSCreateThread = .text:0x803ACCA0; // type:function size:0x26C
fn_803ACF10 = .text:0x803ACF10; // type:function size:0xE4
OSCancelThread = .text:0x803AD000; // type:function size:0x1D4 scope:global
@@ -22479,30 +22479,30 @@ fn_803C6650 = .text:0x803C6650; // type:function size:0x188
fn_803C67E0 = .text:0x803C67E0; // type:function size:0x24
fn_803C6810 = .text:0x803C6810; // type:function size:0x31C
fn_803C6B30 = .text:0x803C6B30; // type:function size:0x5B0
-fn_803C70E0 = .text:0x803C70E0; // type:function size:0x9E0
-fn_803C7AC0 = .text:0x803C7AC0; // type:function size:0xE4
+cbForStateBusy = .text:0x803C70E0; // type:function size:0x9E0
+DVDReadAbsAsyncPrio = .text:0x803C7AC0; // type:function size:0xE4
DVDInquiryAsync = .text:0x803C7BB0; // type:function size:0xD8 scope:global
-fn_803C7C90 = .text:0x803C7C90; // type:function size:0xC8
-fn_803C7D60 = .text:0x803C7D60; // type:function size:0x9C
-fn_803C7E00 = .text:0x803C7E00; // type:function size:0x10
-fn_803C7E10 = .text:0x803C7E10; // type:function size:0x50
-fn_803C7E60 = .text:0x803C7E60; // type:function size:0x364
-fn_803C81D0 = .text:0x803C81D0; // type:function size:0xC0
-fn_803C8290 = .text:0x803C8290; // type:function size:0x8
-fn_803C82A0 = .text:0x803C82A0; // type:function size:0x8
+DVDGetCommandBlockStatus = .text:0x803C7C90; // type:function size:0xC8
+DVDGetDriveStatus = .text:0x803C7D60; // type:function size:0x9C
+DVDSetAutoInvalidation = .text:0x803C7E00; // type:function size:0x10
+DVDResume = .text:0x803C7E10; // type:function size:0x50
+DVDCancelAsync = .text:0x803C7E60; // type:function size:0x364
+DVDCancel = .text:0x803C81D0; // type:function size:0xC0
+cbForCancelSync = .text:0x803C8290; // type:function size:0x8
+__BS2DVDLowCallback = .text:0x803C82A0; // type:function size:0x8
__DVDGetCoverStatus = .text:0x803C82B0; // type:function size:0xCC scope:global
-fn_803C8380 = .text:0x803C8380; // type:function size:0x238
-fn_803C85C0 = .text:0x803C85C0; // type:function size:0x11C
-fn_803C86E0 = .text:0x803C86E0; // type:function size:0xC
+DVDCheckDiskAsync = .text:0x803C8380; // type:function size:0x238
+__DVDPrepareResetAsync = .text:0x803C85C0; // type:function size:0x11C
+Callback = .text:0x803C86E0; // type:function size:0xC
__DVDPrepareReset = .text:0x803C86F0; // type:function size:0x138 scope:global
-fn_803C8830 = .text:0x803C8830; // type:function size:0x20
-fn_803C8850 = .text:0x803C8850; // type:function size:0x8
-fn_803C8860 = .text:0x803C8860; // type:function size:0x4
+__DVDTestAlarm = .text:0x803C8830; // type:function size:0x20
+__DVDStopMotorAsync = .text:0x803C8850; // type:function size:0x8
+__DVDRestartMotor = .text:0x803C8860; // type:function size:0x4
__DVDClearWaitingQueue = .text:0x803C8870; // type:function size:0x38 scope:global
-fn_803C88B0 = .text:0x803C88B0; // type:function size:0x68
-fn_803C8920 = .text:0x803C8920; // type:function size:0xA0
-fn_803C89C0 = .text:0x803C89C0; // type:function size:0x58
-fn_803C8A20 = .text:0x803C8A20; // type:function size:0x64
+__DVDPushWaitingQueue = .text:0x803C88B0; // type:function size:0x68
+__DVDPopWaitingQueue = .text:0x803C8920; // type:function size:0xA0
+__DVDCheckWaitingQueue = .text:0x803C89C0; // type:function size:0x58
+__DVDGetNextWaitingQueue = .text:0x803C8A20; // type:function size:0x64
fn_803C8A90 = .text:0x803C8A90; // type:function size:0x60
fn_803C8AF0 = .text:0x803C8AF0; // type:function size:0x2C
fn_803C8B20 = .text:0x803C8B20; // type:function size:0x5C
@@ -22639,18 +22639,18 @@ fn_803D0D60 = .text:0x803D0D60; // type:function size:0x78
fn_803D0DE0 = .text:0x803D0DE0; // type:function size:0xB0
fn_803D0E90 = .text:0x803D0E90; // type:function size:0x98
fn_803D0F30 = .text:0x803D0F30; // type:function size:0xC0
-fn_803D0FF0 = .text:0x803D0FF0; // type:function size:0x68
-fn_803D1060 = .text:0x803D1060; // type:function size:0x78
-fn_803D10E0 = .text:0x803D10E0; // type:function size:0x68
-fn_803D1150 = .text:0x803D1150; // type:function size:0x78
-fn_803D11D0 = .text:0x803D11D0; // type:function size:0x98
-fn_803D1270 = .text:0x803D1270; // type:function size:0xA8
+NANDRead = .text:0x803D0FF0; // type:function size:0x68
+NANDReadAsync = .text:0x803D1060; // type:function size:0x78
+NANDWrite = .text:0x803D10E0; // type:function size:0x68
+NANDWriteAsync = .text:0x803D1150; // type:function size:0x78
+NANDSeek = .text:0x803D11D0; // type:function size:0x98
+NANDSeekAsync = .text:0x803D1270; // type:function size:0xA8
fn_803D1320 = .text:0x803D1320; // type:function size:0x144
fn_803D1470 = .text:0x803D1470; // type:function size:0x74
fn_803D14F0 = .text:0x803D14F0; // type:function size:0x78
fn_803D1570 = .text:0x803D1570; // type:function size:0x1A8
fn_803D1720 = .text:0x803D1720; // type:function size:0x64
-fn_803D1790 = .text:0x803D1790; // type:function size:0x88
+NANDGetLength = .text:0x803D1790; // type:function size:0x88
fn_803D1820 = .text:0x803D1820; // type:function size:0x54
fn_803D1880 = .text:0x803D1880; // type:function size:0x8C
fn_803D1910 = .text:0x803D1910; // type:function size:0x154
@@ -22661,22 +22661,22 @@ fn_803D1BF0 = .text:0x803D1BF0; // type:function size:0x8
fn_803D1C00 = .text:0x803D1C00; // type:function size:0x8
fn_803D1C10 = .text:0x803D1C10; // type:function size:0x334
nandOpen = .text:0x803D1F50; // type:function size:0x110 scope:local
-fn_803D2060 = .text:0x803D2060; // type:function size:0x8C
-fn_803D20F0 = .text:0x803D20F0; // type:function size:0x8C
-fn_803D2180 = .text:0x803D2180; // type:function size:0x78
+NANDOpen = .text:0x803D2060; // type:function size:0x8C
+NANDPrivateOpen = .text:0x803D20F0; // type:function size:0x8C
+NANDOpenAsync = .text:0x803D2180; // type:function size:0x78
NANDPrivateOpenAsync = .text:0x803D2200; // type:function size:0x78 scope:global
nandOpenCallback = .text:0x803D2280; // type:function size:0x78 scope:local
-fn_803D2300 = .text:0x803D2300; // type:function size:0x6C
-fn_803D2370 = .text:0x803D2370; // type:function size:0x88
-fn_803D2400 = .text:0x803D2400; // type:function size:0xC
-fn_803D2410 = .text:0x803D2410; // type:function size:0x3A8
-fn_803D27C0 = .text:0x803D27C0; // type:function size:0x8
-fn_803D27D0 = .text:0x803D27D0; // type:function size:0x1D4
-fn_803D29B0 = .text:0x803D29B0; // type:function size:0x5C
-fn_803D2A10 = .text:0x803D2A10; // type:function size:0x1AC
-fn_803D2BC0 = .text:0x803D2BC0; // type:function size:0xD4
-fn_803D2CA0 = .text:0x803D2CA0; // type:function size:0xD4
-fn_803D2D80 = .text:0x803D2D80; // type:function size:0x98
+NANDClose = .text:0x803D2300; // type:function size:0x6C
+NANDCloseAsync = .text:0x803D2370; // type:function size:0x88
+NANDSimpleSafeOpen = .text:0x803D2400; // type:function size:0xC
+nandSafeOpen = .text:0x803D2410; // type:function size:0x3A8
+NANDSimpleSafeClose = .text:0x803D27C0; // type:function size:0x8
+nandSafeClose = .text:0x803D27D0; // type:function size:0x1D4
+nandCloseCallback = .text:0x803D29B0; // type:function size:0x5C
+NANDSimpleSafeCancel = .text:0x803D2A10; // type:function size:0x1AC
+nandRemoveTailToken = .text:0x803D2BC0; // type:function size:0xD4
+nandGetHeadToken = .text:0x803D2CA0; // type:function size:0xD4
+nandGetRelativeName = .text:0x803D2D80; // type:function size:0x98
nandConvertPath = .text:0x803D2E20; // type:function size:0x13C scope:global
fn_803D2F60 = .text:0x803D2F60; // type:function size:0x1C
nandIsPrivatePath = .text:0x803D2F80; // type:function size:0x34 scope:global
@@ -23984,19 +23984,19 @@ PeekAsync__Q34nw4r2ut13DvdFileStreamFPvUlPFlPQ34nw4r2ut8IOStreamPv_vPv = .text:0
Seek__Q34nw4r2ut13DvdFileStreamFlUl = .text:0x8042BC60; // type:function size:0x8
Cancel__Q34nw4r2ut13DvdFileStreamFv = .text:0x8042BC70; // type:function size:0x8
CancelAsync__Q34nw4r2ut13DvdFileStreamFPFlPQ34nw4r2ut8IOStreamPv_vPv = .text:0x8042BC80; // type:function size:0x5C
-GetBufferAlign__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BCE0; // type:function size:0x8
-GetSizeAlign__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BCF0; // type:function size:0x8
-GetOffsetAlign__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD00; // type:function size:0x8
-CanCancel__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD10; // type:function size:0x8
-CanWrite__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD20; // type:function size:0x8
-CanRead__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD30; // type:function size:0x8
-CanSeek__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD40; // type:function size:0x8
-CanAsync__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD50; // type:function size:0x8
-GetSize__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD60; // type:function size:0x8
-Tell__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD70; // type:function size:0x8
-IsBusy__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD80; // type:function size:0x8
-GetRuntimeTypeInfo__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD90; // type:function size:0x8
-__sinit_\ut_DvdFileStream_cpp = .text:0x8042BDA0; // type:function size:0xC
+GetBufferAlign__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BCE0; // type:function size:0x8 scope:weak
+GetSizeAlign__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BCF0; // type:function size:0x8 scope:weak
+GetOffsetAlign__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD00; // type:function size:0x8 scope:weak
+CanCancel__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD10; // type:function size:0x8 scope:weak
+CanWrite__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD20; // type:function size:0x8 scope:weak
+CanRead__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD30; // type:function size:0x8 scope:weak
+CanSeek__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD40; // type:function size:0x8 scope:weak
+CanAsync__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD50; // type:function size:0x8 scope:weak
+GetSize__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD60; // type:function size:0x8 scope:weak
+Tell__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD70; // type:function size:0x8 scope:weak
+IsBusy__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD80; // type:function size:0x8 scope:weak
+GetRuntimeTypeInfo__Q34nw4r2ut13DvdFileStreamCFv = .text:0x8042BD90; // type:function size:0x8 scope:weak
+__sinit_\ut_DvdFileStream_cpp = .text:0x8042BDA0; // type:function size:0xC scope:local
__ct__Q34nw4r2ut19DvdLockedFileStreamFl = .text:0x8042BDB0; // type:function size:0x84
__ct__Q34nw4r2ut19DvdLockedFileStreamFPC11DVDFileInfob = .text:0x8042BE40; // type:function size:0x84
__dt__Q34nw4r2ut19DvdLockedFileStreamFv = .text:0x8042BED0; // type:function size:0x58
@@ -24004,11 +24004,11 @@ Close__Q34nw4r2ut19DvdLockedFileStreamFv = .text:0x8042BF30; // type:function si
Read__Q34nw4r2ut19DvdLockedFileStreamFPvUl = .text:0x8042BF70; // type:function size:0xD4
Peek__Q34nw4r2ut19DvdLockedFileStreamFPvUl = .text:0x8042C050; // type:function size:0xD4
Cancel__Q34nw4r2ut19DvdLockedFileStreamFv = .text:0x8042C130; // type:function size:0x58
-CanAsync__Q34nw4r2ut19DvdLockedFileStreamCFv = .text:0x8042C190; // type:function size:0x8
-PeekAsync__Q34nw4r2ut19DvdLockedFileStreamFPvUlPFlPQ34nw4r2ut8IOStreamPv_vPv = .text:0x8042C1A0; // type:function size:0x8
-ReadAsync__Q34nw4r2ut19DvdLockedFileStreamFPvUlPFlPQ34nw4r2ut8IOStreamPv_vPv = .text:0x8042C1B0; // type:function size:0x8
-GetRuntimeTypeInfo__Q34nw4r2ut19DvdLockedFileStreamCFv = .text:0x8042C1C0; // type:function size:0x8
-__sinit_\ut_DvdLockedFileStream_cpp = .text:0x8042C1D0; // type:function size:0xC
+CanAsync__Q34nw4r2ut19DvdLockedFileStreamCFv = .text:0x8042C190; // type:function size:0x8 scope:weak
+PeekAsync__Q34nw4r2ut19DvdLockedFileStreamFPvUlPFlPQ34nw4r2ut8IOStreamPv_vPv = .text:0x8042C1A0; // type:function size:0x8 scope:weak
+ReadAsync__Q34nw4r2ut19DvdLockedFileStreamFPvUlPFlPQ34nw4r2ut8IOStreamPv_vPv = .text:0x8042C1B0; // type:function size:0x8 scope:weak
+GetRuntimeTypeInfo__Q34nw4r2ut19DvdLockedFileStreamCFv = .text:0x8042C1C0; // type:function size:0x8 scope:weak
+__sinit_\ut_DvdLockedFileStream_cpp = .text:0x8042C1D0; // type:function size:0xC scope:local
NandAsyncCallback___Q34nw4r2ut14NandFileStreamFlP16NANDCommandBlock = .text:0x8042C1E0; // type:function size:0x2C
__ct__Q34nw4r2ut14NandFileStreamFPCcUl = .text:0x8042C210; // type:function size:0x70
__ct__Q34nw4r2ut14NandFileStreamFPC12NANDFileInfoUlb = .text:0x8042C280; // type:function size:0x70
@@ -24021,19 +24021,19 @@ ReadAsync__Q34nw4r2ut14NandFileStreamFPvUlPFlPQ34nw4r2ut8IOStreamPv_vPv = .text:
Write__Q34nw4r2ut14NandFileStreamFPCvUl = .text:0x8042C840; // type:function size:0x7C
WriteAsync__Q34nw4r2ut14NandFileStreamFPCvUlPFlPQ34nw4r2ut8IOStreamPv_vPv = .text:0x8042C8C0; // type:function size:0xA8
Seek__Q34nw4r2ut14NandFileStreamFlUl = .text:0x8042C970; // type:function size:0x8
-GetBufferAlign__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042C980; // type:function size:0x8
-GetSizeAlign__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042C990; // type:function size:0x8
-GetOffsetAlign__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042C9A0; // type:function size:0x8
-CanCancel__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042C9B0; // type:function size:0x8
-CanWrite__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042C9C0; // type:function size:0x8
-CanRead__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042C9D0; // type:function size:0x8
-CanSeek__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042C9E0; // type:function size:0x8
-CanAsync__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042C9F0; // type:function size:0x8
-GetSize__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042CA00; // type:function size:0x8
-Tell__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042CA10; // type:function size:0x8
-IsBusy__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042CA20; // type:function size:0x8
-GetRuntimeTypeInfo__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042CA30; // type:function size:0x8
-__sinit_\ut_NandFileStream_cpp = .text:0x8042CA40; // type:function size:0xC
+GetBufferAlign__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042C980; // type:function size:0x8 scope:weak
+GetSizeAlign__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042C990; // type:function size:0x8 scope:weak
+GetOffsetAlign__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042C9A0; // type:function size:0x8 scope:weak
+CanCancel__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042C9B0; // type:function size:0x8 scope:weak
+CanWrite__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042C9C0; // type:function size:0x8 scope:weak
+CanRead__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042C9D0; // type:function size:0x8 scope:weak
+CanSeek__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042C9E0; // type:function size:0x8 scope:weak
+CanAsync__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042C9F0; // type:function size:0x8 scope:weak
+GetSize__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042CA00; // type:function size:0x8 scope:weak
+Tell__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042CA10; // type:function size:0x8 scope:weak
+IsBusy__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042CA20; // type:function size:0x8 scope:weak
+GetRuntimeTypeInfo__Q34nw4r2ut14NandFileStreamCFv = .text:0x8042CA30; // type:function size:0x8 scope:weak
+__sinit_\ut_NandFileStream_cpp = .text:0x8042CA40; // type:function size:0xC scope:local
Enable__Q34nw4r2ut2LCFv = .text:0x8042CA50; // type:function size:0x60
Disable__Q34nw4r2ut2LCFv = .text:0x8042CAB0; // type:function size:0x78
Lock__Q34nw4r2ut2LCFv = .text:0x8042CB30; // type:function size:0x70
@@ -24041,9 +24041,9 @@ Unlock__Q34nw4r2ut2LCFv = .text:0x8042CBA0; // type:function size:0x40
LoadBlocks__Q34nw4r2ut2LCFPvPvUl = .text:0x8042CBE0; // type:function size:0x4
StoreBlocks__Q34nw4r2ut2LCFPvPvUl = .text:0x8042CBF0; // type:function size:0x4
StoreData__Q34nw4r2ut2LCFPvPvUl = .text:0x8042CC00; // type:function size:0x4
-__sinit_\ut_LockedCache_cpp = .text:0x8042CC10; // type:function size:0x18
+__sinit_\ut_LockedCache_cpp = .text:0x8042CC10; // type:function size:0x18 scope:local
InitReaderFunc__Q34nw4r2ut4FontFQ34nw4r2ut12FontEncoding = .text:0x8042CC30; // type:function size:0xA4
-__dt__Q34nw4r2ut4FontFv = .text:0x8042CCE0; // type:function size:0x40
+__dt__Q34nw4r2ut4FontFv = .text:0x8042CCE0; // type:function size:0x40 scope:weak
__ct__Q44nw4r2ut6detail11ResFontBaseFv = .text:0x8042CD20; // type:function size:0x54
__dt__Q44nw4r2ut6detail11ResFontBaseFv = .text:0x8042CD80; // type:function size:0x40
SetResourceBuffer__Q44nw4r2ut6detail11ResFontBaseFPvPQ34nw4r2ut15FontInformation = .text:0x8042CDC0; // type:function size:0xC
@@ -36945,14 +36945,17 @@ jumptable_8056BCD8 = .data:0x8056BCD8; // type:object size:0x20 scope:local
lbl_8056BD20 = .data:0x8056BD20; // type:object size:0x30
__vt__Q34nw4r2ut19TagProcessorBase<w> = .data:0x8056BD50; // type:object size:0x14 scope:weak
__vt__Q34nw4r2ut19TagProcessorBase<c> = .data:0x8056BD64; // type:object size:0x14 scope:weak
-lbl_8056BD78 = .data:0x8056BD78; // type:object size:0x68
-lbl_8056BDE0 = .data:0x8056BDE0; // type:object size:0x68
-lbl_8056BE48 = .data:0x8056BE48; // type:object size:0x60
-lbl_8056BEA8 = .data:0x8056BEA8; // type:object size:0x30 data:4byte
-lbl_8056BED8 = .data:0x8056BED8; // type:object size:0x60
-lbl_8056BF38 = .data:0x8056BF38; // type:object size:0xC data:4byte
-lbl_8056BF44 = .data:0x8056BF44; // type:object size:0x5C
-lbl_8056BFA0 = .data:0x8056BFA0; // type:object size:0x60
+__vt__Q34nw4r2ut13DvdFileStream = .data:0x8056BD78; // type:object size:0x64
+__vt__Q34nw4r2ut19DvdLockedFileStream = .data:0x8056BDE0; // type:object size:0x64
+__vt__Q34nw4r2ut14NandFileStream = .data:0x8056BE48; // type:object size:0x5C
+lbl_8056BEA8 = .data:0x8056BEA8; // type:object size:0xC scope:local data:4byte
+lbl_8056BEB4 = .data:0x8056BEB4; // type:object size:0xC scope:local data:4byte
+lbl_8056BEC0 = .data:0x8056BEC0; // type:object size:0xC scope:local data:4byte
+lbl_8056BECC = .data:0x8056BECC; // type:object size:0xC scope:local data:4byte
+__vt__Q34nw4r2ut4Font = .data:0x8056BED8; // type:object size:0x5C scope:weak
+@3746 = .data:0x8056BF38; // type:object size:0xC scope:local data:4byte
+__vt__Q44nw4r2ut6detail11ResFontBase = .data:0x8056BF44; // type:object size:0x5C
+__vt__Q34nw4r2ut7ResFont = .data:0x8056BFA0; // type:object size:0x5C
twiceBit__Q24nw4r2db = .data:0x8056C000; // type:object size:0x10 scope:local
lbl_8056C010 = .data:0x8056C010; // type:object size:0x10
lbl_8056C020 = .data:0x8056C020; // type:object size:0x18
@@ -39538,8 +39541,8 @@ __fsFd = .sdata:0x80574DA0; // type:object size:0x4 scope:local data:4byte
@1688 = .sdata:0x80574DA8; // type:object size:0x8 scope:local data:string
lbl_80574DB0 = .sdata:0x80574DB0; // type:object size:0x8
lbl_80574DB8 = .sdata:0x80574DB8; // type:object size:0x8 data:byte
-lbl_80574DC0 = .sdata:0x80574DC0; // type:object size:0x4 data:4byte
-lbl_80574DC4 = .sdata:0x80574DC4; // type:object size:0x4 data:4byte
+mFormatBufferSize__Q34nw4r2ut17TextWriterBase<c> = .sdata:0x80574DC0; // type:object size:0x4 scope:weak data:4byte
+mFormatBufferSize__Q34nw4r2ut17TextWriterBase<w> = .sdata:0x80574DC4; // type:object size:0x4 scope:weak data:4byte
lbl_80574DC8 = .sdata:0x80574DC8; // type:object size:0x4 data:string
lbl_80574DCC = .sdata:0x80574DCC; // type:object size:0x4
lbl_80574DD0 = .sdata:0x80574DD0; // type:object size:0x4 data:string
@@ -40604,8 +40607,8 @@ FstStart = .sbss:0x80576248; // type:object size:0x4 scope:local data:4byte
BootInfo = .sbss:0x8057624C; // type:object size:0x4 scope:local data:4byte
lbl_80576260 = .sbss:0x80576260; // type:object size:0x4 data:4byte
lbl_80576264 = .sbss:0x80576264; // type:object size:0x4 data:4byte
-lbl_80576268 = .sbss:0x80576268; // type:object size:0x4 data:4byte
-lbl_8057626C = .sbss:0x8057626C; // type:object size:0x4 data:4byte
+PausingFlag = .sbss:0x80576268; // type:object size:0x4 scope:local data:4byte
+FatalErrorFlag = .sbss:0x8057626C; // type:object size:0x4 scope:local data:4byte
lbl_80576270 = .sbss:0x80576270; // type:object size:0x4 data:4byte
lbl_80576274 = .sbss:0x80576274; // type:object size:0x4 data:4byte
lbl_80576278 = .sbss:0x80576278; // type:object size:0x4 data:4byte
@@ -40634,7 +40637,7 @@ lbl_805762E0 = .sbss:0x805762E0; // type:object size:0x4 data:4byte
lbl_805762E4 = .sbss:0x805762E4; // type:object size:0x4 data:4byte
bootInfo = .sbss:0x805762E8; // type:object size:0x4 scope:local data:4byte
IDShouldBe = .sbss:0x805762EC; // type:object size:0x4 scope:local data:4byte
-lbl_805762F0 = .sbss:0x805762F0; // type:object size:0x4 data:4byte
+executing = .sbss:0x805762F0; // type:object size:0x4 scope:local data:4byte
lbl_805762F4 = .sbss:0x805762F4; // type:object size:0x4 data:4byte
lbl_805762F8 = .sbss:0x805762F8; // type:object size:0x4 data:4byte
lbl_805762FC = .sbss:0x805762FC; // type:object size:0x4 data:4byte
@@ -40810,19 +40813,19 @@ lbl_80576584 = .sbss:0x80576584; // type:object size:0x4 data:4byte
lbl_80576588 = .sbss:0x80576588; // type:object size:0x8 data:4byte
typeInfo__Q34nw4r2ut8IOStream = .sbss:0x80576590; // type:object size:0x4 data:4byte
typeInfo__Q34nw4r2ut10FileStream = .sbss:0x80576598; // type:object size:0x4 data:4byte
-lbl_805765A0 = .sbss:0x805765A0; // type:object size:0x8 data:4byte
-lbl_805765A8 = .sbss:0x805765A8; // type:object size:0x8 data:4byte
-lbl_805765B0 = .sbss:0x805765B0; // type:object size:0x8
-lbl_805765B8 = .sbss:0x805765B8; // type:object size:0x8 data:byte
-lbl_805765C0 = .sbss:0x805765C0; // type:object size:0x8 data:4byte
-lbl_805765C8 = .sbss:0x805765C8; // type:object size:0x1 data:byte
-lbl_805765CC = .sbss:0x805765CC; // type:object size:0x4 data:4byte
-lbl_805765D0 = .sbss:0x805765D0; // type:object size:0x4 data:4byte
-lbl_805765D4 = .sbss:0x805765D4; // type:object size:0x4
-lbl_805765D8 = .sbss:0x805765D8; // type:object size:0x4 data:4byte
-lbl_805765DC = .sbss:0x805765DC; // type:object size:0x4
-lbl_805765E0 = .sbss:0x805765E0; // type:object size:0x1 data:byte
-lbl_805765E1 = .sbss:0x805765E1; // type:object size:0x7 data:byte
+typeInfo__Q34nw4r2ut13DvdFileStream = .sbss:0x805765A0; // type:object size:0x4 data:4byte
+typeInfo__Q34nw4r2ut19DvdLockedFileStream = .sbss:0x805765A8; // type:object size:0x4 data:4byte
+sThreadQueue__Q34nw4r2ut19DvdLockedFileStream = .sbss:0x805765B0; // type:object size:0x8
+sInitialized__Q34nw4r2ut19DvdLockedFileStream = .sbss:0x805765B8; // type:object size:0x1 data:byte
+typeInfo__Q34nw4r2ut14NandFileStream = .sbss:0x805765C0; // type:object size:0x4 data:4byte
+@GUARD@SetupGXCommon__27@unnamed@ut_CharWriter_cpp@Fv@fog = .sbss:0x805765C8; // type:object size:0x1 scope:local data:byte
+@LOCAL@SetupGXCommon__27@unnamed@ut_CharWriter_cpp@Fv@fog = .sbss:0x805765CC; // type:object size:0x4 scope:local data:4byte
+mFormatBuffer__Q34nw4r2ut17TextWriterBase<c> = .sbss:0x805765D0; // type:object size:0x4 scope:weak data:4byte
+mDefaultTagProcessor__Q34nw4r2ut17TextWriterBase<c> = .sbss:0x805765D4; // type:object size:0x4 scope:weak
+mFormatBuffer__Q34nw4r2ut17TextWriterBase<w> = .sbss:0x805765D8; // type:object size:0x4 scope:weak data:4byte
+mDefaultTagProcessor__Q34nw4r2ut17TextWriterBase<w> = .sbss:0x805765DC; // type:object size:0x4 scope:weak
+@GUARD@mDefaultTagProcessor__Q34nw4r2ut17TextWriterBase<c> = .sbss:0x805765E0; // type:object size:0x1 scope:weak data:byte
+@GUARD@mDefaultTagProcessor__Q34nw4r2ut17TextWriterBase<w> = .sbss:0x805765E1; // type:object size:0x1 scope:weak data:byte
sInitialized__Q24nw4r2db = .sbss:0x805765E8; // type:object size:0x4 scope:local data:4byte
lbl_805765F0 = .sbss:0x805765F0; // type:object size:0x4 data:4byte
lbl_805765F4 = .sbss:0x805765F4; // type:object size:0x1 data:byte
@@ -47230,16 +47233,16 @@ lbl_8057EB54 = .sdata2:0x8057EB54; // type:object size:0x1 data:byte
lbl_8057EB55 = .sdata2:0x8057EB55; // type:object size:0x1 data:byte
lbl_8057EB58 = .sdata2:0x8057EB58; // type:object size:0x8
lbl_8057EB60 = .sdata2:0x8057EB60; // type:object size:0x8 data:double
-lbl_8057EB68 = .sdata2:0x8057EB68; // type:object size:0x8 data:double
-lbl_8057EB70 = .sdata2:0x8057EB70; // type:object size:0x4 data:float
-lbl_8057EB74 = .sdata2:0x8057EB74; // type:object size:0x4 data:float
-lbl_8057EB78 = .sdata2:0x8057EB78; // type:object size:0x8 data:double
-lbl_8057EB80 = .sdata2:0x8057EB80; // type:object size:0x4 data:float
-lbl_8057EB88 = .sdata2:0x8057EB88; // type:object size:0x8 data:double
-lbl_8057EB90 = .sdata2:0x8057EB90; // type:object size:0x4 data:float
-lbl_8057EB94 = .sdata2:0x8057EB94; // type:object size:0x4 data:float
-lbl_8057EB98 = .sdata2:0x8057EB98; // type:object size:0x8 data:double
-lbl_8057EBA0 = .sdata2:0x8057EBA0; // type:object size:0x8 data:float
+lbl_8057EB68 = .sdata2:0x8057EB68; // type:object size:0x8 scope:local data:double
+lbl_8057EB70 = .sdata2:0x8057EB70; // type:object size:0x4 scope:local data:float
+lbl_8057EB74 = .sdata2:0x8057EB74; // type:object size:0x4 scope:local data:float
+lbl_8057EB78 = .sdata2:0x8057EB78; // type:object size:0x8 scope:local data:double
+lbl_8057EB80 = .sdata2:0x8057EB80; // type:object size:0x4 scope:local data:float
+lbl_8057EB88 = .sdata2:0x8057EB88; // type:object size:0x8 scope:local data:double
+lbl_8057EB90 = .sdata2:0x8057EB90; // type:object size:0x4 scope:local data:float
+lbl_8057EB94 = .sdata2:0x8057EB94; // type:object size:0x4 scope:local data:float
+lbl_8057EB98 = .sdata2:0x8057EB98; // type:object size:0x8 scope:local data:double
+lbl_8057EBA0 = .sdata2:0x8057EBA0; // type:object size:0x4 scope:local data:float
lbl_8057EBA8 = .sdata2:0x8057EBA8; // type:object size:0x8 data:float
lbl_8057EBB0 = .sdata2:0x8057EBB0; // type:object size:0x4 data:float
lbl_8057EBB4 = .sdata2:0x8057EBB4; // type:object size:0x4 data:float
@@ -49215,7 +49218,7 @@ lbl_805E8910 = .bss:0x805E8910; // type:object size:0x730 data:4byte
__DVDTicketViewBuffer = .bss:0x805E9040; // type:object size:0xE0 scope:local
__DVDTmdBuffer = .bss:0x805E9140; // type:object size:0x4A00 scope:local
lbl_805EDB40 = .bss:0x805EDB40; // type:object size:0x20
-lbl_805EDB60 = .bss:0x805EDB60; // type:object size:0x30
+DummyCommandBlock = .bss:0x805EDB60; // type:object size:0x30 scope:local
lbl_805EDB90 = .bss:0x805EDB90; // type:object size:0x30
lbl_805EDBC0 = .bss:0x805EDBC0; // type:object size:0x40
lbl_805EDC00 = .bss:0x805EDC00; // type:object size:0x20
@@ -49287,11 +49290,11 @@ __timeout_alarm = .bss:0x80632FB0; // type:object size:0x30 scope:local
lbl_80632FE0 = .bss:0x80632FE0; // type:object size:0x40
lbl_80633020 = .bss:0x80633020; // type:object size:0x80 data:4byte
lbl_806330A0 = .bss:0x806330A0; // type:object size:0x3A80 data:4byte
-lbl_80636B20 = .bss:0x80636B20; // type:object size:0x18
-lbl_80636B38 = .bss:0x80636B38; // type:object size:0x20 data:byte
-lbl_80636B58 = .bss:0x80636B58; // type:object size:0x10 data:4byte
-lbl_80636B68 = .bss:0x80636B68; // type:object size:0xC
-lbl_80636B74 = .bss:0x80636B74; // type:object size:0xC
+sMutex__Q34nw4r2ut19DvdLockedFileStream = .bss:0x80636B20; // type:object size:0x18
+sLCImpl__Q34nw4r2ut28@unnamed@ut_LockedCache_cpp@ = .bss:0x80636B38; // type:object size:0x1C data:byte
+mLoadingTexture__Q34nw4r2ut10CharWriter = .bss:0x80636B58; // type:object size:0x10 data:4byte
+@3766 = .bss:0x80636B68; // type:object size:0xC scope:local
+@3896 = .bss:0x80636B74; // type:object size:0xC scope:local
sFrameBufferInfo__Q24nw4r2db = .bss:0x80636B80; // type:object size:0x10 data:4byte
sFrameBufferColor__Q24nw4r2db = .bss:0x80636B90; // type:object size:0x14 data:byte
lbl_80636BA8 = .bss:0x80636BA8; // type:object size:0x18
diff --git a/configure.py b/configure.py
index 3123135c..cb417508 100644
--- a/configure.py
+++ b/configure.py
@@ -334,14 +334,15 @@ config.libs = [
Object(Matching, "nw4r/ut/ut_IOStream.cpp"),
Object(Matching, "nw4r/ut/ut_TagProcessorBase.cpp"),
Object(Matching, "nw4r/ut/ut_FileStream.cpp"),
- Object(NonMatching, "nw4r/ut/ut_DvdFileStream.cpp"),
- Object(NonMatching, "nw4r/ut/ut_DvdLockedFileStream.cpp"),
- Object(NonMatching, "nw4r/ut/ut_NandFileStream.cpp"),
- Object(NonMatching, "nw4r/ut/ut_LockedCache.cpp"),
- Object(NonMatching, "nw4r/ut/ut_Font.cpp"),
- Object(NonMatching, "nw4r/ut/ut_ResFontBase.cpp"),
- Object(NonMatching, "nw4r/ut/ut_ResFont.cpp"),
- Object(NonMatching, "nw4r/ut/ut_CharWriter.cpp"),
+ Object(Matching, "nw4r/ut/ut_DvdFileStream.cpp"),
+ Object(Matching, "nw4r/ut/ut_DvdLockedFileStream.cpp"),
+ Object(Matching, "nw4r/ut/ut_NandFileStream.cpp"),
+ Object(Matching, "nw4r/ut/ut_LockedCache.cpp"),
+ Object(Matching, "nw4r/ut/ut_Font.cpp"),
+ Object(Matching, "nw4r/ut/ut_RomFont.cpp"),
+ Object(Matching, "nw4r/ut/ut_ResFontBase.cpp"),
+ Object(Matching, "nw4r/ut/ut_ResFont.cpp"),
+ Object(Matching, "nw4r/ut/ut_CharWriter.cpp"),
Object(NonMatching, "nw4r/ut/ut_TextWriterBase.cpp"),
],
),
diff --git a/include/MSL_C/MSL_Common/Src/ansi_files.h b/include/MSL_C/MSL_Common/Src/ansi_files.h
index 4aee7fc1..8e8d7673 100644
--- a/include/MSL_C/MSL_Common/Src/ansi_files.h
+++ b/include/MSL_C/MSL_Common/Src/ansi_files.h
@@ -17,10 +17,10 @@ typedef unsigned long fpos_t;
typedef unsigned short wchar_t;
#endif
-#define set_error(file) \
- do { \
- (file)->file_state.error = 1; \
- (file)->buffer_length = 0; \
+#define set_error(file) \
+ do { \
+ (file)->file_state.error = 1; \
+ (file)->buffer_length = 0; \
} while (0)
enum __file_kinds {
@@ -73,9 +73,8 @@ typedef struct _file_states {
} file_states;
typedef void (*__idle_proc)(void);
-typedef int (*__pos_proc)(__file_handle file, fpos_t* position, int mode, __idle_proc idle_proc);
-typedef int (*__io_proc)(__file_handle file, unsigned char* buff, size_t* count,
- __idle_proc idle_proc);
+typedef int (*__pos_proc)(__file_handle file, fpos_t *position, int mode, __idle_proc idle_proc);
+typedef int (*__io_proc)(__file_handle file, unsigned char *buff, size_t *count, __idle_proc idle_proc);
typedef int (*__close_proc)(__file_handle file);
typedef struct _FILE {
@@ -88,9 +87,9 @@ typedef struct _FILE {
/* 0x0F */ char ungetc_buffer[2];
/* 0x12 */ wchar_t ungetc_wide_buffer[2];
/* 0x18 */ unsigned long position;
- /* 0x1C */ unsigned char* buffer;
+ /* 0x1C */ unsigned char *buffer;
/* 0x20 */ unsigned long buffer_size;
- /* 0x24 */ unsigned char* buffer_ptr;
+ /* 0x24 */ unsigned char *buffer_ptr;
/* 0x28 */ unsigned long buffer_length;
/* 0x2C */ unsigned long buffer_alignment;
/* 0x30 */ unsigned long save_buffer_length;
@@ -100,7 +99,7 @@ typedef struct _FILE {
/* 0x40 */ __io_proc write_fn;
/* 0x44 */ __close_proc close_fn;
/* 0x48 */ __idle_proc idle_fn;
- /* 0x4C */ struct _FILE* next_file;
+ /* 0x4C */ struct _FILE *next_file;
} FILE;
typedef struct _files {
@@ -116,10 +115,8 @@ typedef struct _files {
extern files __files;
extern int __close_console(__file_handle file);
-extern int __write_console(__file_handle file, unsigned char* buf, size_t* count,
- __idle_proc idle_fn);
-extern int __read_console(__file_handle file, unsigned char* buf, size_t* count,
- __idle_proc idle_fn);
+extern int __write_console(__file_handle file, unsigned char *buf, size_t *count, __idle_proc idle_fn);
+extern int __read_console(__file_handle file, unsigned char *buf, size_t *count, __idle_proc idle_fn);
unsigned int __flush_all(void);
void __close_all(void);
diff --git a/include/nw4r/ut/ut_CharWriter.h b/include/nw4r/ut/ut_CharWriter.h
index e5801516..0ef0cee4 100644
--- a/include/nw4r/ut/ut_CharWriter.h
+++ b/include/nw4r/ut/ut_CharWriter.h
@@ -159,6 +159,7 @@ public:
void SetupGX();
void SetFontSize(f32 width, f32 height);
+ void SetFontSize(f32 height);
f32 GetFontWidth() const;
f32 GetFontHeight() const;
f32 GetFontAscent() const;
diff --git a/include/nw4r/ut/ut_DvdFileStream.h b/include/nw4r/ut/ut_DvdFileStream.h
index 5b000b6e..2f305e6b 100644
--- a/include/nw4r/ut/ut_DvdFileStream.h
+++ b/include/nw4r/ut/ut_DvdFileStream.h
@@ -24,7 +24,7 @@ public:
};
public:
- DvdFileStream(s32 entrynum);
+ DvdFileStream(long entrynum);
DvdFileStream(const DVDFileInfo *info, bool close);
virtual ~DvdFileStream(); // at 0xC
@@ -67,15 +67,15 @@ public:
virtual void Close(); // at 0x10
- virtual s32 Read(void *dst, u32 size); // at 0x14
- virtual bool ReadAsync(void *dst, u32 size, AsyncCallback callback,
+ virtual long Read(void *dst, unsigned long size); // at 0x14
+ virtual bool ReadAsync(void *dst, unsigned long 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,
+ virtual long Peek(void *dst, unsigned long size); // at 0x5C
+ virtual bool PeekAsync(void *dst, unsigned long size, AsyncCallback callback,
void *arg); // at 0x60
- virtual void Seek(s32 offset, u32 origin); // at 0x44
+ virtual void Seek(long offset, unsigned long origin); // at 0x44
virtual void Cancel(); // at 0x48
virtual bool CancelAsync(AsyncCallback callback, void *arg); // at 0x4C
@@ -88,11 +88,11 @@ public:
bool Open(const DVDFileInfo *info, bool close);
private:
- static void DvdAsyncCallback_(s32 result, DVDFileInfo *info);
- static void DvdCBAsyncCallback_(s32 result, DVDCommandBlock *block);
+ static void DvdAsyncCallback_(long result, DVDFileInfo *info);
+ static void DvdCBAsyncCallback_(long result, DVDCommandBlock *block);
void Initialize_();
- u32 AdjustReadLength_(u32 len);
+ unsigned long AdjustReadLength_(unsigned long len);
private:
FilePosition mFilePosition; // at 0x14
diff --git a/include/nw4r/ut/ut_DvdLockedFileStream.h b/include/nw4r/ut/ut_DvdLockedFileStream.h
index 8bbf85af..501bbc18 100644
--- a/include/nw4r/ut/ut_DvdLockedFileStream.h
+++ b/include/nw4r/ut/ut_DvdLockedFileStream.h
@@ -11,17 +11,19 @@ class DvdLockedFileStream : public DvdFileStream {
public:
NW4R_UT_RTTI_DECL(DvdLockedFileStream);
- DvdLockedFileStream(s32 entrynum);
+ DvdLockedFileStream(long 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) {
+ virtual void Close(); // at 0x10
+
+ virtual long Read(void *dst, unsigned long size); // at 0x14
+ virtual bool ReadAsync(void *dst, unsigned long 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) {
+ virtual long Peek(void *dst, unsigned long size); // at 0x5C
+ virtual bool PeekAsync(void *dst, unsigned long size, AsyncCallback callback, void *arg) {
return false;
} // at 0x60
@@ -29,11 +31,18 @@ public:
return false;
} // at 0x28
+ void Cancel();
+
private:
static void InitMutex_();
+ bool LockMutex();
+ static void UnlockMutex();
+ void CancelMutex();
private:
+ volatile bool mCancelFlag; // 0x6f
static bool sInitialized;
+ static OSThreadQueue sThreadQueue;
static OSMutex sMutex;
};
diff --git a/include/nw4r/ut/ut_Font.h b/include/nw4r/ut/ut_Font.h
index 0aefe054..4cda439a 100644
--- a/include/nw4r/ut/ut_Font.h
+++ b/include/nw4r/ut/ut_Font.h
@@ -52,13 +52,12 @@ public:
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 bool HasGlyph(u16 c) const = 0; // at 0x50
virtual FontEncoding GetEncoding() const = 0; // at 0x54
void InitReaderFunc(FontEncoding encode);
- CharStrmReader GetCharStrmReader() const {
- return CharStrmReader(mReadFunc);
- }
+ CharStrmReader GetCharStrmReader() const;
private:
CharStrmReader::ReadFunc mReadFunc; // at 0x4
diff --git a/include/nw4r/ut/ut_IOStream.h b/include/nw4r/ut/ut_IOStream.h
index 33545909..88e7af7a 100644
--- a/include/nw4r/ut/ut_IOStream.h
+++ b/include/nw4r/ut/ut_IOStream.h
@@ -15,11 +15,11 @@ public:
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 void Close() = 0; // at 0x10
+ virtual long Read(void *dst, unsigned long size) = 0; // at 0x14
virtual bool ReadAsync(void *dst, unsigned long size, AsyncCallback callback,
void *arg); // at 0x18
- virtual bool Write(const void *src, unsigned long size); // at 0x1C
+ virtual long Write(const void *src, unsigned long size); // at 0x1C
virtual bool WriteAsync(const void *src, unsigned long size, AsyncCallback callback,
void *arg); // at 0x20
virtual bool IsBusy() const; // at 0x24
diff --git a/include/nw4r/ut/ut_NandFileStream.h b/include/nw4r/ut/ut_NandFileStream.h
index 1e1ef805..d672e46b 100644
--- a/include/nw4r/ut/ut_NandFileStream.h
+++ b/include/nw4r/ut/ut_NandFileStream.h
@@ -25,8 +25,8 @@ public:
};
public:
- NandFileStream(const char *path, u32 access);
- NandFileStream(const NANDFileInfo *info, u32 access, bool close);
+ NandFileStream(const char *path, unsigned long access);
+ NandFileStream(const NANDFileInfo *info, unsigned long access, bool close);
virtual ~NandFileStream(); // at 0xC
virtual bool IsBusy() const {
@@ -68,32 +68,32 @@ public:
virtual void Close(); // at 0x10
- virtual s32 Read(void *dst, u32 size); // at 0x14
- virtual bool ReadAsync(void *dst, u32 size, AsyncCallback callback,
+ virtual long Read(void *dst, unsigned long size); // at 0x14
+ virtual bool ReadAsync(void *dst, unsigned long 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,
+ virtual long Write(const void *src, unsigned long size); // at 0x1C
+ virtual bool WriteAsync(const void *src, unsigned long size, AsyncCallback callback,
void *arg); // at 0x20
- virtual void Seek(s32 offset, u32 origin); // at 0x44
+ virtual void Seek(long offset, unsigned long origin); // at 0x44
- bool Open(const char *path, u32 access);
- bool Open(const NANDFileInfo *info, u32 access, bool close) DECOMP_DONT_INLINE;
+ bool Open(const char *path, unsigned long access);
+ bool Open(const NANDFileInfo *info, unsigned long access, bool close) DECOMP_DONT_INLINE;
private:
- static void NandAsyncCallback_(s32 result, NANDCommandBlock *block);
+ static void NandAsyncCallback_(long 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
+ bool mCanRead; // at 0x168
+ bool mCanWrite; // at 0x169
+ volatile bool mIsBusy; // at 0x16A
+ bool mCloseOnDestroy; // at 0x16B
+ bool mAllowClose; // at 0x16C
};
} // namespace ut
diff --git a/include/nw4r/ut/ut_ResFont.h b/include/nw4r/ut/ut_ResFont.h
index 61e4e778..c1dc3109 100644
--- a/include/nw4r/ut/ut_ResFont.h
+++ b/include/nw4r/ut/ut_ResFont.h
@@ -8,12 +8,13 @@ namespace ut {
class ResFont : public detail::ResFontBase {
public:
- static FontInformation* Rebuild(BinaryFileHeader* header);
+ static FontInformation *Rebuild(BinaryFileHeader *header);
ResFont();
~ResFont();
- bool SetResource(void* buffer);
+ bool SetResource(void *buffer);
+ void *RemoveResource();
};
} // namespace ut
diff --git a/include/nw4r/ut/ut_ResFontBase.h b/include/nw4r/ut/ut_ResFontBase.h
index 35870190..6d7bad76 100644
--- a/include/nw4r/ut/ut_ResFontBase.h
+++ b/include/nw4r/ut/ut_ResFontBase.h
@@ -6,11 +6,7 @@
namespace nw4r {
namespace ut {
-enum FontMapMethod {
- FONT_MAPMETHOD_LINEAR,
- FONT_MAPMETHOD_ARRAY,
- FONT_MAPMETHOD_SCAN
-};
+enum FontMapMethod { FONT_MAPMETHOD_LINEAR, FONT_MAPMETHOD_ARRAY, FONT_MAPMETHOD_SCAN };
struct FontTextureGlyph {
u8 cellWidth; // at 0x0
@@ -24,13 +20,13 @@ struct FontTextureGlyph {
u16 sheetLine; // at 0xE
u16 sheetWidth; // at 0x10
u16 sheetHeight; // at 0x12
- u8* sheetImage; // at 0x14
+ u8 *sheetImage; // at 0x14
};
struct FontWidth {
u16 firstChar; // at 0x0
u16 lastChar; // at 0x2
- FontWidth* next; // at 0x4
+ FontWidth *next; // at 0x4
CharWidths widthTable[]; // at 0x8
};
@@ -39,7 +35,7 @@ struct FontCodeMap {
u16 lastChar; // at 0x2
u16 mappingMethod; // at 0x4
u16 reserved; // at 0x6
- FontCodeMap* next; // at 0x8
+ FontCodeMap *next; // at 0x8
u16 mapInfo[]; // at 0xc
};
@@ -49,9 +45,9 @@ struct FontInformation {
u16 alterCharIndex; // at 0x2
CharWidths defaultWidth; // at 0x4
u8 encoding; // at 0x7
- FontTextureGlyph* fontGlyph; // at 0x8
- FontWidth* fontWidth; // at 0xC
- FontCodeMap* fontMap; // at 0x10
+ FontTextureGlyph *fontGlyph; // at 0x8
+ FontWidth *fontWidth; // at 0xC
+ FontCodeMap *fontMap; // at 0x10
u8 height; // at 0x14
u8 width; // at 0x15
u8 ascent; // at 0x16
@@ -76,34 +72,37 @@ public:
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 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
+ virtual void GetGlyph(Glyph *out, u16 c) const; // at 0x50
+ virtual bool HasGlyph(u16 c) const; // at 0x54
+ virtual FontEncoding GetEncoding() const; // at 0x58
- bool IsManaging(const void* buffer) const { return mResource == buffer; }
+ bool IsManaging(const void *buffer) const {
+ return mResource == buffer;
+ }
- void SetResourceBuffer(void* buffer, FontInformation* info);
+ void SetResourceBuffer(void *buffer, FontInformation *info);
+ void *RemoveResourceBuffer();
u16 GetGlyphIndex(u16 c) const;
u16 FindGlyphIndex(u16 c) const;
- u16 FindGlyphIndex(const FontCodeMap* map, 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;
+ const CharWidths &GetCharWidthsFromIndex(u16 index) const;
+ const CharWidths &GetCharWidthsFromIndex(const FontWidth *width, u16 index) const;
- void GetGlyphFromIndex(Glyph* out, 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
+ void *mResource; // at 0x10
+ FontInformation *mFontInfo; // at 0x14
+ mutable u16 mLastCharCode; // at 0x18
+ mutable u16 mLastGlyphIndex; // at 0x1A
};
} // namespace detail
diff --git a/include/nw4r/ut/ut_RomFont.h b/include/nw4r/ut/ut_RomFont.h
index 30fc5425..e444d362 100644
--- a/include/nw4r/ut/ut_RomFont.h
+++ b/include/nw4r/ut/ut_RomFont.h
@@ -30,7 +30,8 @@ public:
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
+ virtual bool HasGlyph(u16 c) const; // at 0x54
+ virtual FontEncoding GetEncoding() const; // at 0x58
bool Load(void *buffer);
u32 GetRequireBufferSize();
diff --git a/include/nw4r/ut/ut_TextWriterBase.h b/include/nw4r/ut/ut_TextWriterBase.h
index 0dd9e271..71291fbe 100644
--- a/include/nw4r/ut/ut_TextWriterBase.h
+++ b/include/nw4r/ut/ut_TextWriterBase.h
@@ -64,7 +64,7 @@ public:
void SetDrawFlag(u32 flag) {
mDrawFlag = flag;
}
- bool IsDrawFlagSet(u32 mask, u32 flag) const {
+ bool IsDrawFlagSet(unsigned long mask, u32 flag) const {
return (mDrawFlag & mask) == flag;
}
@@ -78,20 +78,39 @@ public:
mTagProcessor = &mDefaultTagProcessor;
}
+ void SetLineHeight(f32 height);
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;
+ f32 CalcFormatStringWidth(const T *str, ...) const;
+ f32 CalcFormatStringHeight(const T *str, ...) const;
+ void CalcFormatStringRect(Rect *rect, const T *str, ...) const;
+ void CalcVStringRect(Rect *rect, const T *str, va_list args) const;
- int VSNPrintf(T *buffer, u32 count, const T *fmt, va_list args);
+ f32 CalcStringWidth(const T *format, int len) const;
+ f32 CalcStringHeight(const T *format, int len) const;
+ void CalcStringRect(Rect *rect, const T *format, int len) const;
+
+ f32 Printf(const T *format, ...);
f32 VPrintf(const T *str, va_list args);
f32 Print(const T *str, int len);
+ f32 PrintfMutable(const T *format, ...);
+ f32 VPrintfMutable(const T *format, va_list args);
+ f32 PrintMutable(const T *str, int n);
+
+ // static int VSNPrintf(T *buffer, unsigned long count, const T *fmt, va_list args);
+
+ static int VSNPrintf(char *buffer, unsigned long count, const char *fmt, va_list args) {
+ return vsnprintf(buffer, count, fmt, args);
+ }
+ static int VSNPrintf(wchar_t *buffer, unsigned long count, const wchar_t *fmt, va_list args) {
+ return vswprintf(buffer, count, fmt, args);
+ }
+
+ f32 CalcLineWidth(const T *format, 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 PrintImpl(const T *str, int len, bool m);
f32 AdjustCursor(f32 *x1, f32 *y1, const T *str, int len);
private:
@@ -103,19 +122,19 @@ private:
TagProcessorBase<T> *mTagProcessor; // at 0x60
static T *mFormatBuffer;
- static u32 mFormatBufferSize;
+ static int mFormatBufferSize;
static TagProcessorBase<T> mDefaultTagProcessor;
};
-template <>
-inline int TextWriterBase<char>::VSNPrintf(char *buffer, u32 count, const char *fmt, va_list args) {
- return vsnprintf(buffer, count, fmt, args);
-}
+// template <>
+// int TextWriterBase<char>::VSNPrintf(char *buffer, unsigned long count, const char *fmt, va_list args) {
+// return vsnprintf(buffer, count, fmt, args);
+// }
-template <>
-inline int TextWriterBase<wchar_t>::VSNPrintf(wchar_t *buffer, u32 count, const wchar_t *fmt, va_list args) {
- return vswprintf(buffer, count, fmt, args);
-}
+// template <>
+// int TextWriterBase<wchar_t>::VSNPrintf(wchar_t *buffer, unsigned long count, const wchar_t *fmt, va_list args) {
+// return vswprintf(buffer, count, fmt, args);
+// }
} // namespace ut
} // namespace nw4r
diff --git a/include/rvl/DVD.h b/include/rvl/DVD.h
index 00b87a44..35fc9f78 100644
--- a/include/rvl/DVD.h
+++ b/include/rvl/DVD.h
@@ -6,9 +6,12 @@ extern "C" {
#include "rvl/DVD/dvd.h"
#include "rvl/DVD/dvd_broadway.h"
+#include "rvl/DVD/dvderror.h"
#include "rvl/DVD/dvdfatal.h"
#include "rvl/DVD/dvdfs.h"
#include "rvl/DVD/dvdidutils.h"
+#include "rvl/DVD/dvdqueue.h"
+
#ifdef __cplusplus
}
diff --git a/include/rvl/DVD/dvd.h b/include/rvl/DVD/dvd.h
index 254cdf12..ff968863 100644
--- a/include/rvl/DVD/dvd.h
+++ b/include/rvl/DVD/dvd.h
@@ -5,14 +5,75 @@
extern "C" {
#endif
+// OS sets MSB to signal that the device code was successfully read
+#define DVD_DEVICE_CODE_READ (1 << 15)
+#define MAKE_DVD_DEVICE_CODE(x) (DVD_DEVICE_CODE_READ | (x))
+
// Forward declarations
+typedef struct DVDCommandBlock;
+typedef struct DVDFileInfo;
typedef struct OSAlarm;
-typedef struct DVDDriveBlock {
- char UNK_0x0[0xC];
- UNKWORD WORD_0xC;
- char UNK_0x10[0x30 - 0x10];
-} DVDDriveBlock;
+typedef enum {
+ DVD_RESULT_COVER_CLOSED = -4,
+ DVD_RESULT_CANCELED,
+ DVD_RESULT_M2,
+ DVD_RESULT_FATAL,
+ DVD_RESULT_OK,
+} DVDResult;
+
+typedef enum {
+ DVD_STATE_FATAL = -1,
+ DVD_STATE_IDLE,
+ DVD_STATE_BUSY,
+ DVD_STATE_WAITING,
+ DVD_STATE_COVER_CLOSED,
+ DVD_STATE_NO_DISK,
+ DVD_STATE_COVER_OPENED,
+ DVD_STATE_WRONG_DISK_ID,
+ DVD_STATE_7,
+ DVD_STATE_PAUSED,
+ DVD_STATE_9,
+ DVD_STATE_CANCELED,
+ DVD_STATE_DISK_ERROR,
+ DVD_STATE_MOTOR_STOPPED,
+} DVDAsyncState;
+
+typedef enum {
+ DVD_COVER_BUSY,
+ DVD_COVER_OPENED,
+ DVD_COVER_CLOSED,
+} DVDCoverState;
+
+typedef void (*DVDAsyncCallback)(long result, struct DVDFileInfo *info);
+typedef void (*DVDCommandCallback)(long result, struct DVDCommandBlock *block);
+
+typedef struct DVDDiskID {
+ char game[4]; // at 0x0
+ char company[2]; // at 0x4
+ u8 disk; // at 0x6
+ u8 version; // at 0x7
+ u8 strmEnable; // at 0x8
+ u8 strmBufSize; // at 0x9
+ u8 padding[14]; // at 0xA
+ u32 rvlMagic; // at 0x18
+ u32 gcMagic; // at 0x1C
+} DVDDiskID;
+
+typedef struct DVDCommandBlock {
+ struct DVDCommandBlock *next; // at 0x0
+ struct DVDCommandBlock *prev; // at 0x4
+ u32 command; // at 0x8
+ volatile s32 state; // at 0xC
+ u32 offset; // at 0x10
+ u32 length; // at 0x14
+ void *addr; // at 0x18
+ u32 transferSize; // at 0x1C
+ u32 transferTotal; // at 0x20
+ DVDDiskID *id; // at 0x24
+ DVDCommandCallback callback; // at 0x28
+ void *userData; // at 0x2C
+} DVDCommandBlock;
typedef struct DVDDriveInfo {
u16 revision; // at 0x0
@@ -21,16 +82,34 @@ typedef struct DVDDriveInfo {
char padding[32 - 0x8];
} DVDDriveInfo;
-typedef void (*DVDInquiryCallback)(s32, DVDDriveBlock *);
-
-void DVDInit(void);
+typedef struct DVDFileInfo {
+ DVDCommandBlock block; // at 0x0
+ u32 offset; // at 0x30
+ u32 size; // at 0x34
+ DVDAsyncCallback callback; // at 0x38
+} DVDFileInfo;
-BOOL DVDInquiryAsync(DVDDriveBlock *, DVDDriveInfo *, DVDInquiryCallback);
+extern volatile u32 __DVDLayoutFormat;
+void DVDInit(void);
+BOOL DVDReadAbsAsyncPrio(DVDCommandBlock *block, void *dst, u32 size, u32 offset, DVDCommandCallback callback,
+ s32 prio);
+BOOL DVDInquiryAsync(DVDCommandBlock *block, DVDDriveInfo *info, DVDCommandCallback callback);
+s32 DVDGetCommandBlockStatus(const DVDCommandBlock *block);
+s32 DVDGetDriveStatus(void);
+void DVDPause(void);
+void DVDResume(void);
+BOOL DVDCancelAsync(DVDCommandBlock *block, DVDCommandCallback callback);
+s32 DVDCancel(DVDCommandBlock *block);
+BOOL DVDCancelAllAsync(DVDCommandCallback callback);
+const DVDDiskID *DVDGetCurrentDiskID(void);
u32 __DVDGetCoverStatus(void);
-
+void __DVDPrepareResetAsync(DVDCommandCallback callback);
void __DVDPrepareReset(void);
-BOOL __DVDTestAlarm(struct OSAlarm *);
+BOOL __DVDTestAlarm(const struct OSAlarm *alarm);
+BOOL __DVDLowBreak(void);
+BOOL __DVDStopMotorAsync(DVDCommandBlock *block, DVDCommandCallback callback);
+void __DVDRestartMotor(void);
#ifdef __cplusplus
}
diff --git a/include/rvl/DVD/dvd_broadway.h b/include/rvl/DVD/dvd_broadway.h
index 6329e2f0..01016ade 100644
--- a/include/rvl/DVD/dvd_broadway.h
+++ b/include/rvl/DVD/dvd_broadway.h
@@ -5,6 +5,9 @@
extern "C" {
#endif
+#define DVD_LOW_OFFSET(x) ((x) >> 2)
+#define DVD_LOW_SPEED(x) (((x) & 3) << 16)
+
// Forward declarations
typedef struct DVDDiskID;
typedef struct DVDDriveInfo;
@@ -12,21 +15,22 @@ typedef struct ESPTicket;
typedef struct ESPTmd;
typedef struct OSAlarm;
-/**
- * https://wiibrew.org/wiki//dev/di
- * Names adjusted to be closer to those seen in assertions
- */
typedef enum {
- DVD_INTTYPE_TC = (1 << 0), //!< Transaction callback?
- DVD_INTTYPE_DE = (1 << 1), //!< Drive error
- DVD_INTTYPE_CVR = (1 << 2), //!< Something with DVD cover
- DVD_INTTYPE_BR = (1 << 3), //!< Break requested
- DVD_INTTYPE_TIME = (1 << 4), //!< Time out
- DVD_INTTYPE_SERR = (1 << 5), //!< Security error
- DVD_INTTYPE_VERR = (1 << 6), //!< Verify error
- DVD_INTTYPE_ARGS = (1 << 7), //!< Bad arguments
+ DVD_INTTYPE_TC = (1 << 0), // Transaction callback?
+ DVD_INTTYPE_DE = (1 << 1), // Drive error
+ DVD_INTTYPE_CVR = (1 << 2), // Something with DVD cover
+ DVD_INTTYPE_BR = (1 << 3), // Break requested
+ DVD_INTTYPE_TIME = (1 << 4), // Time out
+ DVD_INTTYPE_SERR = (1 << 5), // Security error
+ DVD_INTTYPE_VERR = (1 << 6), // Verify error
+ DVD_INTTYPE_ARGS = (1 << 7), // Bad arguments
} DVDLowIntType;
+// DICVR - DI Cover Register (via DVDLowGetCoverRegister)
+#define DVD_DICVR_CVR (1 << 0)
+#define DVD_DICVR_CVRINTMASK (1 << 1)
+#define DVD_DICVR_CVRINT (1 << 2)
+
typedef void (*DVDLowCallback)(u32 intType);
BOOL DVDLowInit(void);
diff --git a/include/rvl/DVD/dvderror.h b/include/rvl/DVD/dvderror.h
new file mode 100644
index 00000000..1b5fc4e1
--- /dev/null
+++ b/include/rvl/DVD/dvderror.h
@@ -0,0 +1,38 @@
+#ifndef RVL_SDK_DVD_ERROR_H
+#define RVL_SDK_DVD_ERROR_H
+#include <common.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*DVDErrorCallback)(s32 result, s32 arg1);
+
+#define DVD_ERROR_CMD_MAX 5
+
+typedef struct DVDErrorInfo {
+ char game[4]; // at 0x0
+ u8 disk; // at 0x4
+ u8 version; // at 0x5
+ u32 error; // at 0x8
+ s32 sec; // at 0xC
+ u32 disr; // at 0x10
+ u32 dicr; // at 0x14
+ u32 next; // at 0x18
+
+ struct {
+ u32 command; // at 0x1C
+ u32 param1; // at 0x20
+ u32 param2; // at 0x24
+ u32 intType; // at 0x28
+ u32 tick; // at 0x2C
+ } info[DVD_ERROR_CMD_MAX];
+} DVDErrorInfo;
+
+extern DVDErrorInfo __ErrorInfo;
+
+void __DVDStoreErrorCode(u32 error, DVDErrorCallback callback);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/rvl/DVD/dvdfs.h b/include/rvl/DVD/dvdfs.h
index 7458692c..c0747f47 100644
--- a/include/rvl/DVD/dvdfs.h
+++ b/include/rvl/DVD/dvdfs.h
@@ -1,36 +1,24 @@
#ifndef RVL_SDK_DVD_FS_H
#define RVL_SDK_DVD_FS_H
+#include <RVL/DVD/dvd.h>
+#include <RVL/OS.h>
#include <common.h>
+
#ifdef __cplusplus
extern "C" {
#endif
+extern OSThreadQueue __DVDThreadQueue;
extern BOOL __DVDLongFileNameFlag;
-typedef void (*DVDCommandCallback)(s32, struct DVDCommandBlock *);
-typedef void (*DVDFileCallback)(s32, struct DVDFileInfo *);
-
-typedef struct DVDCommandBlock {
- /* 0x00 */ struct DVDCommandBlock *next;
- /* 0x04 */ struct DVDCommandBlock *prev;
- /* 0x08 */ u32 command;
- /* 0x0c */ s32 state;
- /* 0x10 */ u32 offset;
- /* 0x14 */ u32 length;
- /* 0x18 */ void *addr;
- /* 0x1c */ u32 currTransferSize;
- /* 0x20 */ u32 transferredSize;
- /* 0x24 */ DVDDiskID *id;
- /* 0x28 */ DVDCommandCallback callback;
- /* 0x2c */ void *userData;
-} DVDCommandBlock;
-
-typedef struct DVDFileInfo {
- /* 0x00 */ DVDCommandBlock cb;
- /* 0x30 */ u32 startAddr;
- /* 0x34 */ u32 length;
- /* 0x38 */ DVDFileCallback *callback;
-} DVDFileInfo;
+void __DVDFSInit(void);
+s32 DVDConvertPathToEntrynum(const char *path);
+BOOL DVDFastOpen(s32 entrynum, DVDFileInfo *info);
+BOOL DVDOpen(const char *path, DVDFileInfo *info);
+BOOL DVDClose(DVDFileInfo *info);
+BOOL DVDGetCurrentDir(char *buffer, u32 maxlen);
+BOOL DVDReadAsyncPrio(DVDFileInfo *info, void *dst, s32 size, s32 offset, DVDAsyncCallback callback, s32 prio);
+s32 DVDReadPrio(DVDFileInfo *info, void *dst, s32 size, s32 offset, s32 prio);
#ifdef __cplusplus
}
diff --git a/include/rvl/DVD/dvdidutils.h b/include/rvl/DVD/dvdidutils.h
index 2dceb761..23a7d3df 100644
--- a/include/rvl/DVD/dvdidutils.h
+++ b/include/rvl/DVD/dvdidutils.h
@@ -1,22 +1,12 @@
#ifndef RVL_SDK_DVD_ID_UTILS_H
#define RVL_SDK_DVD_ID_UTILS_H
+#include <RVL/DVD/dvd.h>
#include <common.h>
+
#ifdef __cplusplus
extern "C" {
#endif
-typedef struct DVDDiskID {
- char game[4]; // at 0x0
- char company[2]; // at 0x4
- u8 disk; // at 0x6
- u8 version; // at 0x7
- u8 strmEnable; // at 0x8
- u8 strmBufSize; // at 0x9
- u8 padding[14]; // at 0xA
- u32 rvlMagic; // at 0x18
- u32 gcMagic; // at 0x1C
-} DVDDiskID;
-
BOOL DVDCompareDiskID(const DVDDiskID *id1, const DVDDiskID *id2);
#ifdef __cplusplus
diff --git a/include/rvl/DVD/dvdqueue.h b/include/rvl/DVD/dvdqueue.h
new file mode 100644
index 00000000..0b3a7a3d
--- /dev/null
+++ b/include/rvl/DVD/dvdqueue.h
@@ -0,0 +1,28 @@
+#ifndef RVL_SDK_DVD_QUEUE_H
+#define RVL_SDK_DVD_QUEUE_H
+#include <RVL/DVD/dvd.h>
+#include <common.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ DVD_PRIO_HIGHEST,
+ DVD_PRIO_HIGH,
+ DVD_PRIO_MEDIUM,
+ DVD_PRIO_LOW,
+
+ DVD_PRIO_MAX,
+} DVDQueuePriority;
+
+void __DVDClearWaitingQueue(void);
+BOOL __DVDPushWaitingQueue(s32 prio, DVDCommandBlock *block);
+DVDCommandBlock *__DVDPopWaitingQueue(void);
+BOOL __DVDCheckWaitingQueue(void);
+DVDCommandBlock *__DVDGetNextWaitingQueue(void);
+BOOL __DVDDequeueWaitingQueue(const DVDCommandBlock *block);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/rvl/GX/GXInit.h b/include/rvl/GX/GXInit.h
index 32369c91..cdae0895 100644
--- a/include/rvl/GX/GXInit.h
+++ b/include/rvl/GX/GXInit.h
@@ -1,5 +1,6 @@
#ifndef RVL_SDK_GX_INIT_H
#define RVL_SDK_GX_INIT_H
+#include <RVL/GX/GXFifo.h>
#include <common.h>
#ifdef __cplusplus
extern "C" {
@@ -49,11 +50,11 @@ typedef struct _GXData {
char UNK_0x230[0x254 - 0x230];
u32 genMode; // at 0x254
char UNK_0x258[0x520 - 0x258];
- GXAttrType normalType; // at 0x520
- GXBool normal; // at 0x524
- GXBool binormal; // at 0x525
- GXProjMtxType projType; // at 0x528
- f32 proj[6]; // at 0x52C
+ GXAttrType normalType; // at 0x520
+ GXBool normal; // at 0x524
+ GXBool binormal; // at 0x525
+ GXProjectionType projType; // at 0x528
+ f32 proj[6]; // at 0x52C
union {
struct {
f32 vpOx; // at 0x544
@@ -80,6 +81,8 @@ extern GXData *const __GXData;
// I hate typing this name out
#define gxdt __GXData
+GXFifoObj *GXInit(void *, u32);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/rvl/GX/GXPixel.h b/include/rvl/GX/GXPixel.h
index 64637b06..cc110d67 100644
--- a/include/rvl/GX/GXPixel.h
+++ b/include/rvl/GX/GXPixel.h
@@ -19,7 +19,7 @@ void GXSetColorUpdate(GXBool enable);
void GXSetAlphaUpdate(GXBool enable);
void GXSetZMode(GXBool enableTest, GXCompare func, GXBool enableUpdate);
void GXSetZCompLoc(GXBool beforeTex);
-void GXSetPixelFmt(GXPixelFmt pixelFmt, GXZFmt zFmt);
+void GXSetPixelFmt(GXPixelFmt pixelFmt, GXZFmt16 zFmt);
void GXSetDither(GXBool enable);
void GXSetDstAlpha(GXBool enable, u8 alpha);
void GXSetFieldMask(GXBool enableEven, GXBool enableOdd);
diff --git a/include/rvl/GX/GXTransform.h b/include/rvl/GX/GXTransform.h
index 2842d634..780af102 100644
--- a/include/rvl/GX/GXTransform.h
+++ b/include/rvl/GX/GXTransform.h
@@ -7,7 +7,7 @@
extern "C" {
#endif
-void GXSetProjection(const Mtx44 proj, GXProjMtxType type);
+void GXSetProjection(const Mtx44 proj, GXProjectionType type);
void GXSetProjectionv(const f32 proj[7]);
void GXGetProjectionv(f32 proj[7]);
void GXLoadPosMtxImm(const Mtx mtx, u32 id);
diff --git a/include/rvl/GX/GXTypes.h b/include/rvl/GX/GXTypes.h
index c2c1c424..99094c37 100644
--- a/include/rvl/GX/GXTypes.h
+++ b/include/rvl/GX/GXTypes.h
@@ -158,7 +158,17 @@ typedef enum _GXChannelID {
GX_COLOR_NULL = 255
} GXChannelID;
-// TODO: Fabricated names from patent
+typedef enum _GXCITexFmt {
+ GX_TF_C4 = 8,
+ GX_TF_C8,
+ GX_TF_C14X2,
+} GXCITexFmt;
+
+typedef enum _GXClearZ {
+ GX_CLEAR_Z_MIN = 0,
+ GX_CLEAR_Z_MAX = (1 << 24) - 1,
+} GXClearZ;
+
typedef enum _GXClipMode {
// "ClipDisable" in XF mem, so 0 = enable
GX_CLIP_ENABLE,
@@ -208,6 +218,13 @@ typedef enum _GXCompType {
GX_RGBA8
} GXCompType;
+typedef enum _GXCopyClamp {
+ GX_CLAMP_NONE,
+ GX_CLAMP_TOP,
+ GX_CLAMP_BOTTOM,
+ GX_CLAMP_ALL,
+} GXCopyClamp;
+
typedef enum _GXCullMode { GX_CULL_NONE, GX_CULL_FRONT, GX_CULL_BACK, GX_CULL_ALL } GXCullMode;
typedef enum _GXDiffuseFn { GX_DF_NONE, GX_DF_SIGN, GX_DF_CLAMP } GXDiffuseFn;
@@ -354,16 +371,16 @@ typedef enum _GXIndTexWrap {
} GXIndTexWrap;
typedef enum _GXLightID {
- GX_LIGHT0 = 1,
- GX_LIGHT1 = 2,
- GX_LIGHT2 = 4,
- GX_LIGHT3 = 8,
- GX_LIGHT4 = 16,
- GX_LIGHT5 = 32,
- GX_LIGHT6 = 64,
- GX_LIGHT7 = 128,
-
- GX_MAX_LIGHT = 256,
+ GX_LIGHT0 = (1 << 0),
+ GX_LIGHT1 = (1 << 1),
+ GX_LIGHT2 = (1 << 2),
+ GX_LIGHT3 = (1 << 3),
+ GX_LIGHT4 = (1 << 4),
+ GX_LIGHT5 = (1 << 5),
+ GX_LIGHT6 = (1 << 6),
+ GX_LIGHT7 = (1 << 7),
+
+ GX_MAX_LIGHT = (1 << 8),
GX_LIGHT_NULL = 0
} GXLightID;
@@ -386,7 +403,6 @@ typedef enum _GXLogicOp {
GX_LO_SET
} GXLogicOp;
-// TODO: Fabricated name
typedef enum _GXMtxType {
GX_MTX_3x4,
GX_MTX_2x4,
@@ -432,7 +448,7 @@ typedef enum _GXPrimitive {
GX_QUADS = 0x80,
} GXPrimitive;
-typedef enum _GXProjMtxType { GX_PERSPECTIVE, GX_ORTHOGRAPHIC } GXProjMtxType;
+typedef enum _GXProjectionType { GX_PERSPECTIVE, GX_ORTHOGRAPHIC } GXProjectionType;
typedef enum _GXSpotFn { GX_SP_OFF, GX_SP_FLAT, GX_SP_COS, GX_SP_COS2, GX_SP_SHARP, GX_SP_RING1, GX_SP_RING2 } GXSpotFn;
@@ -509,10 +525,12 @@ typedef enum _GXTevRegID {
} GXTevRegID;
typedef enum _GXTevScale {
- GX_TEV_SCALE_0,
- GX_TEV_SCALE_1,
- GX_TEV_SCALE_2,
- GX_TEV_SCALE_3,
+ GX_CS_SCALE_1,
+ GX_CS_SCALE_2,
+ GX_CS_SCALE_4,
+ GX_CS_DIVIDE_2,
+
+ GX_MAX_TEVSCALE
} GXTevScale;
typedef enum _GXTevStageID {
@@ -624,6 +642,8 @@ typedef enum _GXTevKColorSel {
GX_TEV_KCSEL_K3_A
} GXTevKColorSel;
+typedef enum _GXTevMode { GX_MODULATE, GX_DECAL, GX_REPLACE, GX_PASSCLR, GX_BLEND } GXTevMode;
+
typedef enum _GXTexCoordID {
GX_TEXCOORD0,
GX_TEXCOORD1,
@@ -733,9 +753,9 @@ typedef enum _GXTexMapID {
GX_TEX_DISABLE
} GXTexMapID;
-// TODO: Fabricated names
typedef enum _GXTexMtx {
// Any dimension (in standard XF matrix memory)
+ // Enum represents base row of matrix
GX_TEXMTX0 = 30,
GX_TEXMTX1 = 33,
GX_TEXMTX2 = 36,
@@ -746,18 +766,31 @@ typedef enum _GXTexMtx {
GX_TEXMTX7 = 51,
GX_TEXMTX8 = 54,
GX_TEXMTX9 = 57,
+ GX_TEXMTX_IDENT = 60,
// 3x4 matrices (in dual-tex XF matrix memory)
- GX_DTEXMTX0 = 64,
- GX_DTEXMTX1 = 67,
- GX_DTEXMTX2 = 70,
- GX_DTEXMTX3 = 73,
- GX_DTEXMTX4 = 76,
- GX_DTEXMTX5 = 79,
- GX_DTEXMTX6 = 82,
- GX_DTEXMTX7 = 85,
- GX_DTEXMTX8 = 88,
- GX_DTEXMTX9 = 91,
+ // Enum represents base row of matrix
+ GX_DUALMTX0 = 64,
+ GX_DUALMTX1 = 67,
+ GX_DUALMTX2 = 70,
+ GX_DUALMTX3 = 73,
+ GX_DUALMTX4 = 76,
+ GX_DUALMTX5 = 79,
+ GX_DUALMTX6 = 82,
+ GX_DUALMTX7 = 85,
+ GX_DUALMTX8 = 88,
+ GX_DUALMTX9 = 91,
+ GX_DUALMTX10 = 94,
+ GX_DUALMTX11 = 97,
+ GX_DUALMTX12 = 100,
+ GX_DUALMTX13 = 103,
+ GX_DUALMTX14 = 106,
+ GX_DUALMTX15 = 109,
+ GX_DUALMTX16 = 112,
+ GX_DUALMTX17 = 115,
+ GX_DUALMTX18 = 118,
+ GX_DUALMTX19 = 121,
+ GX_DUALMTX_IDENT = 125,
} GXTexMtx;
typedef enum _GXTexWrapMode {
@@ -776,9 +809,8 @@ typedef enum _GXTlutFmt {
GX_MAX_TLUTFMT
} GXTlutFmt;
-// TODO: Fabricated name
typedef enum _GXVtxFmt {
- GX_VTXFMT0, // from patent
+ GX_VTXFMT0,
GX_VTXFMT1,
GX_VTXFMT2,
GX_VTXFMT3,
@@ -787,15 +819,24 @@ typedef enum _GXVtxFmt {
GX_VTXFMT6,
GX_VTXFMT7,
- GX_MAX_VTXFMT,
+ GX_MAX_VTXFMT
} GXVtxFmt;
-typedef enum _GXZFmt {
- GX_ZC_LINEAR, // from patent
- GX_ZC_NEAR, // from Dolphin
- GX_ZC_MID, // from Dolphin
- GX_ZC_FAR, // from Dolphin
-} GXZFmt;
+typedef enum _GXZFmt16 {
+ GX_ZC_LINEAR,
+ GX_ZC_NEAR,
+ GX_ZC_MID,
+ GX_ZC_FAR,
+} GXZFmt16;
+
+// From patent
+typedef enum _GXZTexOp {
+ GX_ZT_DISABLE,
+ GX_ZT_ADD,
+ GZ_ZT_REPLACE,
+
+ GX_MAX_ZTEXOP
+} GXZTexOp;
#ifdef __cplusplus
}
diff --git a/include/rvl/NAND/nand.h b/include/rvl/NAND/nand.h
index bae91f37..eb803253 100644
--- a/include/rvl/NAND/nand.h
+++ b/include/rvl/NAND/nand.h
@@ -66,7 +66,7 @@ typedef enum {
NAND_PERM_RWALL = NAND_PERM_RALL | NAND_PERM_WALL
} NANDPermission;
-typedef void (*NANDAsyncCallback)(s32 result, struct NANDCommandBlock *block);
+typedef void (*NANDAsyncCallback)(long result, struct NANDCommandBlock *block);
typedef struct NANDStatus {
u32 ownerId; // at 0x0
@@ -76,8 +76,8 @@ typedef struct NANDStatus {
} NANDStatus;
typedef struct NANDFileInfo {
- s32 fd; // at 0x0
- s32 tempFd; // at 0x4
+ long fd; // at 0x0
+ long tempFd; // at 0x4
char openPath[FS_MAX_PATH]; // at 0x8
char tempPath[FS_MAX_PATH]; // at 0x48
u8 access; // at 0x88
@@ -118,6 +118,7 @@ typedef struct NANDCommandBlock {
u32 workBlocks; // at 0xAC
u32 workInodes; // at 0xB0
const char **dir; // at 0xB4
+ int simpleFlag; //
} NANDCommandBlock;
typedef struct NANDBanner {
@@ -157,7 +158,7 @@ NANDResult NANDPrivateCreateDirAsync(const char *path, u8 perm, u8 attr, NANDAsy
NANDResult NANDMove(const char *from, const char *to);
-NANDResult NANDGetLength(NANDFileInfo *info, u32 *length);
+NANDResult NANDGetLength(NANDFileInfo *info, unsigned long *length);
NANDResult NANDGetLengthAsync(NANDFileInfo *info, u32 *lengthOut, NANDAsyncCallback callback, NANDCommandBlock *block);
NANDResult NANDGetStatus(const char *path, NANDStatus *status);
diff --git a/src/egg/core/eggAsyncDisplay.cpp b/src/egg/core/eggAsyncDisplay.cpp
index 0901271f..d2b4bf81 100644
--- a/src/egg/core/eggAsyncDisplay.cpp
+++ b/src/egg/core/eggAsyncDisplay.cpp
@@ -196,9 +196,9 @@ void AsyncDisplay::clearEFB(u16 fbWidth, u16 fbHeight, u16 x, u16 y, u16 width,
GXSetTevColor(GX_TEVREG0, color);
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_C0);
- GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_TEV_SCALE_0, 1, GX_TEVPREV);
+ GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV);
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0);
- GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_TEV_SCALE_0, 1, GX_TEVPREV);
+ GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV);
GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0);
GXSetZTexture(2, GX_TF_Z24X8, 0);
GXSetZCompLoc(false);
diff --git a/src/nw4r/ut/ut_CharWriter.cpp b/src/nw4r/ut/ut_CharWriter.cpp
index e69de29b..1281dc01 100644
--- a/src/nw4r/ut/ut_CharWriter.cpp
+++ b/src/nw4r/ut/ut_CharWriter.cpp
@@ -0,0 +1,260 @@
+
+#include <nw4r/ut.h>
+
+namespace {
+
+static void SetupGXCommon() {
+ static const nw4r::ut::Color fog = 0;
+
+ GXSetFog(GX_FOG_NONE, fog, 0.0f, 0.0f, 0.0f, 0.0f);
+ GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA);
+ GXSetZTexture(GX_ZT_DISABLE, GX_TF_Z8, 0);
+ GXSetNumChans(1);
+ GXSetChanCtrl(GX_COLOR0A0, FALSE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
+ GXSetChanCtrl(GX_COLOR1A1, FALSE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
+ GXSetNumTexGens(1);
+ GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX_IDENT, FALSE, GX_DUALMTX_IDENT);
+ GXSetNumIndStages(0);
+ GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET);
+}
+
+} // namespace
+
+namespace nw4r {
+namespace ut {
+
+CharWriter::CharWriter() : mAlpha(255), mIsWidthFixed(false), mFixedWidth(0.0f), mFont(NULL) {
+ mLoadingTexture.Reset();
+ ResetColorMapping();
+ SetGradationMode(GRADMODE_NONE);
+ SetTextColor(Color(0xFFFFFFFF));
+ SetScale(1.0f, 1.0f);
+ SetCursor(0.0f, 0.0f, 0.0f);
+ EnableLinearFilter(true, true);
+}
+
+CharWriter::~CharWriter() {}
+
+void CharWriter::SetupGX() {
+ ResetTextureCache();
+
+ if (mColorMapping.min != 0x00000000 || mColorMapping.max != 0xFFFFFFFF) {
+ SetupGXWithColorMapping(mColorMapping.min, mColorMapping.max);
+ } else if (mFont != NULL) {
+ switch (mFont->GetTextureFormat()) {
+ case GX_TF_I4:
+ case GX_TF_I8:
+ SetupGXForI();
+ break;
+ case GX_TF_IA4:
+ case GX_TF_IA8:
+ SetupGXDefault();
+ break;
+ case GX_TF_RGB565:
+ case GX_TF_RGB5A3:
+ case GX_TF_RGBA8:
+ SetupGXForRGBA();
+ break;
+ default:
+ SetupGXDefault();
+ break;
+ }
+ } else {
+ SetupGXDefault();
+ }
+}
+
+void CharWriter::SetFontSize(f32 width, f32 height) {
+ SetScale(width / mFont->GetWidth(), height / mFont->GetHeight());
+}
+
+void CharWriter::SetFontSize(f32 height) {
+ f32 scale = height / mFont->GetHeight();
+ SetScale(scale, scale);
+}
+
+f32 CharWriter::GetFontWidth() const {
+ return mScale.x * mFont->GetWidth();
+}
+
+f32 CharWriter::GetFontHeight() const {
+ return mScale.y * mFont->GetHeight();
+}
+
+f32 CharWriter::GetFontAscent() const {
+ return mScale.y * mFont->GetAscent();
+}
+
+f32 CharWriter::GetFontDescent() const {
+ return mScale.y * mFont->GetDescent();
+}
+
+void CharWriter::EnableLinearFilter(bool atSmall, bool atLarge) {
+ mFilter.atSmall = atSmall ? GX_LINEAR : GX_NEAR;
+ mFilter.atLarge = atLarge ? GX_LINEAR : GX_NEAR;
+}
+
+f32 CharWriter::Print(u16 ch) {
+ f32 width;
+ f32 left;
+
+ Glyph glyph;
+ mFont->GetGlyph(&glyph, ch);
+
+ if (mIsWidthFixed) {
+ width = mFixedWidth;
+ left = (width - glyph.widths.charWidth * mScale.x) / 2 + (glyph.widths.leftSpacing * mScale.x);
+ } else {
+ width = glyph.widths.charWidth * mScale.x;
+ left = glyph.widths.leftSpacing * mScale.x;
+ }
+
+ PrintGlyph(mCursorPos.x + left, mCursorPos.y, mCursorPos.z, glyph);
+ mCursorPos.x += width;
+
+ return width;
+}
+
+void CharWriter::PrintGlyph(f32 x, f32 y, f32 z, const Glyph &glyph) {
+ f32 x2 = x + (glyph.widths.glyphWidth * mScale.x);
+ f32 y2 = y + (glyph.height * mScale.y);
+
+ u32 posLeft = glyph.cellX;
+ u16 texLeft = 0x8000 * posLeft / glyph.texWidth;
+
+ u32 posTop = glyph.cellY;
+ u16 texTop = 0x8000 * posTop / glyph.texHeight;
+
+ u32 posRight = posLeft + glyph.widths.glyphWidth;
+ u16 texRight = 0x8000 * posRight / glyph.texWidth;
+
+ u32 posBottom = posTop + glyph.height;
+ u16 texBottom = 0x8000 * posBottom / glyph.texHeight;
+
+ LoadTexture(glyph, GX_TEXMAP0);
+
+ GXBegin(GX_QUADS, GX_VTXFMT0, 4);
+ {
+ GXPosition3f32(x, y, z);
+ GXColor1u32(mVertexColor.tl);
+ GXTexCoord2s16(texLeft, texTop);
+
+ GXPosition3f32(x2, y, z);
+ GXColor1u32(mVertexColor.tr);
+ GXTexCoord2s16(texRight, texTop);
+
+ GXPosition3f32(x2, y2, z);
+ GXColor1u32(mVertexColor.br);
+ GXTexCoord2s16(texRight, texBottom);
+
+ GXPosition3f32(x, y2, z);
+ GXColor1u32(mVertexColor.bl);
+ GXTexCoord2s16(texLeft, texBottom);
+ }
+ // GXEnd();
+}
+
+void CharWriter::LoadTexture(const Glyph &glyph, GXTexMapID slot) {
+ LoadingTexture loadingTexture;
+
+ loadingTexture.slot = slot;
+ loadingTexture.texture = glyph.texture;
+ loadingTexture.filter = mFilter;
+
+ if (loadingTexture != mLoadingTexture) {
+ GXTexObj texObj;
+ GXInitTexObj(&texObj, glyph.texture, glyph.texWidth, glyph.texHeight, glyph.format, GX_CLAMP, GX_CLAMP, FALSE);
+ GXInitTexObjLOD(&texObj, mFilter.atSmall, mFilter.atLarge, 0.0f, 0.0f, 0.0f, FALSE, FALSE, GX_ANISO_1);
+ GXLoadTexObj(&texObj, slot);
+
+ mLoadingTexture = loadingTexture;
+ }
+}
+
+void CharWriter::UpdateVertexColor() {
+ // clang-format off
+ mVertexColor.tl = mTextColor.start;
+ mVertexColor.tr = mTextColor.gradMode != GRADMODE_H ? mTextColor.start : mTextColor.end;
+ mVertexColor.bl = mTextColor.gradMode != GRADMODE_V ? mTextColor.start : mTextColor.end;
+ mVertexColor.br = mTextColor.gradMode == GRADMODE_NONE ? mTextColor.start : mTextColor.end;
+ // clang-format on
+
+ mVertexColor.tl.a = (mVertexColor.tl.a * mAlpha) / 255, mVertexColor.tr.a = (mVertexColor.tr.a * mAlpha) / 255;
+ mVertexColor.bl.a = (mVertexColor.bl.a * mAlpha) / 255;
+ mVertexColor.br.a = (mVertexColor.br.a * mAlpha) / 255;
+}
+
+void CharWriter::SetupVertexFormat() {
+ GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
+ GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
+ GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_U16, 15);
+
+ GXClearVtxDesc();
+ GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
+ GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
+ GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
+}
+
+void CharWriter::SetupGXDefault() {
+ SetupGXCommon();
+
+ GXSetNumTevStages(1);
+ GXSetTevDirect(GX_TEVSTAGE0);
+ GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0);
+ GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
+ GXSetTevOp(GX_TEVSTAGE0, GX_MODULATE);
+
+ SetupVertexFormat();
+}
+
+void CharWriter::SetupGXWithColorMapping(Color min, Color max) {
+ SetupGXCommon();
+
+ GXSetNumTevStages(2);
+ GXSetTevDirect(GX_TEVSTAGE0);
+ GXSetTevDirect(GX_TEVSTAGE1);
+
+ GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0);
+ GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0);
+ GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
+
+ GXSetTevColor(GX_TEVREG0, min);
+ GXSetTevColor(GX_TEVREG1, max);
+
+ GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_C0, GX_CC_C1, GX_CC_TEXC, GX_CC_ZERO);
+ GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_A0, GX_CA_A1, GX_CA_TEXA, GX_CA_ZERO);
+ GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, TRUE, GX_TEVPREV);
+ GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, TRUE, GX_TEVPREV);
+
+ GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
+ GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_CPREV, GX_CC_RASC, GX_CC_ZERO);
+ GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_APREV, GX_CA_RASA, GX_CA_ZERO);
+ GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, TRUE, GX_TEVPREV);
+ GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, TRUE, GX_TEVPREV);
+
+ SetupVertexFormat();
+}
+
+void CharWriter::SetupGXForI() {
+ SetupGXCommon();
+
+ GXSetNumTevStages(1);
+ GXSetTevDirect(GX_TEVSTAGE0);
+ GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0);
+ GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
+ GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC);
+ GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_TEXA, GX_CA_RASA, GX_CA_ZERO);
+ GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, TRUE, GX_TEVPREV);
+ GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, TRUE, GX_TEVPREV);
+
+ SetupVertexFormat();
+}
+
+void CharWriter::SetupGXForRGBA() {
+ SetupGXDefault();
+}
+
+CharWriter::LoadingTexture CharWriter::mLoadingTexture;
+
+} // namespace ut
+} // namespace nw4r
diff --git a/src/nw4r/ut/ut_DvdFileStream.cpp b/src/nw4r/ut/ut_DvdFileStream.cpp
index e69de29b..317bbc40 100644
--- a/src/nw4r/ut/ut_DvdFileStream.cpp
+++ b/src/nw4r/ut/ut_DvdFileStream.cpp
@@ -0,0 +1,180 @@
+#include <nw4r/ut.h>
+
+namespace nw4r {
+namespace ut {
+
+NW4R_UT_RTTI_DEF_DERIVED(DvdFileStream, FileStream);
+
+void DvdFileStream::DvdAsyncCallback_(long result, DVDFileInfo *info) {
+ DvdFileStream *self = reinterpret_cast<AsyncContext *>(info)->stream;
+
+ self->mIsBusy = false;
+ self->mResult = result;
+
+ if (self->mCallback != NULL) {
+ self->mCallback(result, self, self->mCallbackArg);
+ }
+}
+
+void DvdFileStream::DvdCBAsyncCallback_(long result, DVDCommandBlock *block) {
+ DvdFileStream *self = reinterpret_cast<AsyncContext *>(block)->stream;
+
+ self->mIsCancelling = false;
+
+ if (self->mCancelCallback != NULL) {
+ self->mCancelCallback(result, self, self->mCancelCallbackArg);
+ }
+}
+
+void DvdFileStream::Initialize_() {
+ mCloseOnDestroy = false;
+ mAllowClose = false;
+ mIsOpen = false;
+ mPriority = DVD_PRIO_MEDIUM;
+ mIsBusy = false;
+ mCallback = NULL;
+ mCallbackArg = NULL;
+ mResult = DVD_RESULT_OK;
+ mCancelCallback = NULL;
+ mIsCancelling = false;
+ mCancelCallbackArg = NULL;
+ mAsyncContext.stream = this;
+}
+
+DvdFileStream::DvdFileStream(long entrynum) {
+ Initialize_();
+ Open(entrynum);
+}
+
+DvdFileStream::DvdFileStream(const DVDFileInfo *info, bool close) {
+ Initialize_();
+ Open(info, close);
+}
+
+DvdFileStream::~DvdFileStream() {
+ if (mCloseOnDestroy) {
+ Close();
+ }
+}
+
+bool DvdFileStream::Open(s32 entrynum) {
+ if (mCloseOnDestroy) {
+ Close();
+ }
+
+ if (DVDFastOpen(entrynum, &mAsyncContext.info)) {
+ mFilePosition.SetFileSize(mAsyncContext.info.size);
+ mFilePosition.Seek(0, SEEK_BEG);
+
+ mCloseOnDestroy = true;
+ mAllowClose = true;
+ mIsOpen = true;
+
+ return true;
+ }
+
+ return false;
+}
+
+bool DvdFileStream::Open(const DVDFileInfo *info, bool close) {
+ if (mCloseOnDestroy) {
+ Close();
+ }
+
+ mAsyncContext.info = *info;
+ mFilePosition.SetFileSize(mAsyncContext.info.size);
+ mFilePosition.Seek(0, SEEK_BEG);
+
+ mCloseOnDestroy = false;
+ mAllowClose = close;
+ mIsOpen = true;
+
+ return true;
+}
+
+void DvdFileStream::Close() {
+ if (mAllowClose && mIsOpen) {
+ DVDClose(&mAsyncContext.info);
+ mIsOpen = false;
+ }
+}
+
+long DvdFileStream::Read(void *dst, unsigned long size) {
+ size = AdjustReadLength_(size);
+
+ long result = DVDReadPrio(&mAsyncContext.info, dst, size, mFilePosition.Tell(), mPriority);
+
+ if (result > 0) {
+ mFilePosition.Skip(result);
+ }
+
+ return result;
+}
+
+bool DvdFileStream::ReadAsync(void *dst, unsigned long size, AsyncCallback callback, void *arg) {
+ size = AdjustReadLength_(size);
+
+ bool success = DvdFileStream::PeekAsync(dst, size, callback, arg);
+
+ if (success) {
+ mFilePosition.Skip(size);
+ } else {
+ mIsBusy = false;
+ }
+
+ return success;
+}
+
+long DvdFileStream::Peek(void *dst, unsigned long size) {
+ size = AdjustReadLength_(size);
+
+ return DVDReadPrio(&mAsyncContext.info, dst, size, mFilePosition.Tell(), mPriority);
+}
+
+bool DvdFileStream::PeekAsync(void *dst, unsigned long size, AsyncCallback callback, void *arg) {
+ mCallback = callback;
+ mCallbackArg = arg;
+ mIsBusy = true;
+
+ size = AdjustReadLength_(size);
+
+ return DVDReadAsyncPrio(&mAsyncContext.info, dst, size, mFilePosition.Tell(), DvdAsyncCallback_, mPriority);
+}
+
+void DvdFileStream::Seek(long offset, unsigned long origin) {
+ mFilePosition.Seek(offset, origin);
+}
+
+void DvdFileStream::Cancel() {
+ DVDCancel(&mAsyncContext.info.block);
+}
+
+bool DvdFileStream::CancelAsync(AsyncCallback callback, void *arg) {
+ mCancelCallback = callback;
+ mCancelCallbackArg = arg;
+
+ BOOL success = DVDCancelAsync(&mAsyncContext.info.block, DvdCBAsyncCallback_);
+
+ if (success) {
+ mIsCancelling = true;
+ }
+
+ return success;
+}
+
+unsigned long DvdFileStream::AdjustReadLength_(unsigned long len) {
+ u32 fileOffset = mFilePosition.Tell();
+ u32 fileSize = mFilePosition.GetFileSize();
+
+ u32 alignSize = RoundUp(fileSize, 32);
+ u32 alignPos = RoundUp(fileOffset + len, 32);
+
+ if (alignPos > alignSize) {
+ len = RoundUp(fileSize - fileOffset, 32);
+ }
+
+ return len;
+}
+
+} // namespace ut
+} // namespace nw4r
diff --git a/src/nw4r/ut/ut_DvdLockedFileStream.cpp b/src/nw4r/ut/ut_DvdLockedFileStream.cpp
index e69de29b..eb18ac54 100644
--- a/src/nw4r/ut/ut_DvdLockedFileStream.cpp
+++ b/src/nw4r/ut/ut_DvdLockedFileStream.cpp
@@ -0,0 +1,93 @@
+#include <RVL/OS.h>
+#include <nw4r/ut.h>
+
+namespace nw4r {
+namespace ut {
+
+NW4R_UT_RTTI_DEF_DERIVED(DvdLockedFileStream, DvdFileStream);
+
+OSThreadQueue DvdLockedFileStream::sThreadQueue;
+OSMutex DvdLockedFileStream::sMutex;
+bool DvdLockedFileStream::sInitialized = false;
+
+void DvdLockedFileStream::InitMutex_() {
+ BOOL enabled = OSDisableInterrupts();
+
+ if (!sInitialized) {
+ OSInitMutex(&sMutex);
+ OSInitThreadQueue(&sThreadQueue);
+ sInitialized = true;
+ }
+
+ OSRestoreInterrupts(enabled);
+}
+
+DvdLockedFileStream::DvdLockedFileStream(long entrynum) : DvdFileStream(entrynum) {
+ mCancelFlag = false;
+ InitMutex_();
+}
+
+DvdLockedFileStream::DvdLockedFileStream(const DVDFileInfo *info, bool close) : DvdFileStream(info, close) {
+ mCancelFlag = false;
+ InitMutex_();
+}
+
+DvdLockedFileStream::~DvdLockedFileStream() {}
+
+void DvdLockedFileStream::Close() {
+ DvdFileStream::Close();
+ mCancelFlag = false;
+}
+
+long DvdLockedFileStream::Read(void *dst, unsigned long size) {
+ if (!LockMutex()) {
+ return DVD_RESULT_CANCELED;
+ }
+ long ret = DvdFileStream::Read(dst, size);
+ UnlockMutex();
+ return ret;
+}
+
+long DvdLockedFileStream::Peek(void *dst, unsigned long size) {
+ if (!LockMutex()) {
+ return DVD_RESULT_CANCELED;
+ }
+ long ret = DvdFileStream::Peek(dst, size);
+ UnlockMutex();
+ return ret;
+}
+
+void DvdLockedFileStream::Cancel() {
+ CancelMutex();
+ DvdFileStream::Cancel();
+}
+
+bool DvdLockedFileStream::LockMutex() {
+ BOOL enabled = OSDisableInterrupts();
+ while (!OSTryLockMutex(&sMutex)) {
+ OSSleepThread(&sThreadQueue);
+ if (mCancelFlag) {
+ OSRestoreInterrupts(enabled);
+ return false;
+ }
+ };
+ OSRestoreInterrupts(enabled);
+ return true;
+}
+
+void DvdLockedFileStream::UnlockMutex() {
+ BOOL enabled = OSDisableInterrupts();
+ OSUnlockMutex(&sMutex);
+ OSWakeupThread(&sThreadQueue);
+ OSRestoreInterrupts(enabled);
+}
+
+void DvdLockedFileStream::CancelMutex() {
+ BOOL enabled = OSDisableInterrupts();
+ mCancelFlag = true;
+ OSWakeupThread(&sThreadQueue);
+ OSRestoreInterrupts(enabled);
+}
+
+} // namespace ut
+} // namespace nw4r
diff --git a/src/nw4r/ut/ut_Font.cpp b/src/nw4r/ut/ut_Font.cpp
index e69de29b..0032e911 100644
--- a/src/nw4r/ut/ut_Font.cpp
+++ b/src/nw4r/ut/ut_Font.cpp
@@ -0,0 +1,25 @@
+#include <nw4r/ut.h>
+
+namespace nw4r {
+namespace ut {
+
+void Font::InitReaderFunc(FontEncoding encode) {
+ switch (encode) {
+ case FONT_ENCODE_UTF8:
+ mReadFunc = &CharStrmReader::ReadNextCharUTF8;
+ break;
+ case FONT_ENCODE_UTF16:
+ mReadFunc = &CharStrmReader::ReadNextCharUTF16;
+ break;
+ case FONT_ENCODE_SJIS:
+ mReadFunc = &CharStrmReader::ReadNextCharSJIS;
+ break;
+ case FONT_ENCODE_CP1252:
+ default:
+ mReadFunc = &CharStrmReader::ReadNextCharCP1252;
+ break;
+ }
+}
+
+} // namespace ut
+} // namespace nw4r
diff --git a/src/nw4r/ut/ut_IOStream.cpp b/src/nw4r/ut/ut_IOStream.cpp
index dec6c090..01c7fed0 100644
--- a/src/nw4r/ut/ut_IOStream.cpp
+++ b/src/nw4r/ut/ut_IOStream.cpp
@@ -9,7 +9,7 @@ bool IOStream::ReadAsync(void *dst, unsigned long size, AsyncCallback callback,
return false;
}
-bool IOStream::Write(const void *src, unsigned long size) {
+long IOStream::Write(const void *src, unsigned long size) {
return false;
}
diff --git a/src/nw4r/ut/ut_LockedCache.cpp b/src/nw4r/ut/ut_LockedCache.cpp
index e69de29b..3972e471 100644
--- a/src/nw4r/ut/ut_LockedCache.cpp
+++ b/src/nw4r/ut/ut_LockedCache.cpp
@@ -0,0 +1,104 @@
+#include <nw4r/ut.h>
+
+namespace nw4r {
+namespace ut {
+namespace {
+
+class LCImpl {
+public:
+ class Lock_ {
+ public:
+ Lock_(LCImpl &lc) : mMutex(lc.mMutex) {
+ OSLockMutex(&mMutex);
+ }
+ ~Lock_() {
+ OSUnlockMutex(&mMutex);
+ }
+
+ private:
+ OSMutex &mMutex; // at 0x0
+ };
+
+public:
+ LCImpl() : mIsEnabled(false) {
+ OSInitMutex(&mMutex);
+ }
+
+ void Enable() {
+ Lock_ lock(*this);
+
+ if (!mIsEnabled) {
+ LCEnable();
+ mIsEnabled = true;
+ }
+ }
+
+ void Disable() {
+ Lock_ lock(*this);
+
+ if (mIsEnabled) {
+ LC::QueueWaitEx(0);
+ LCDisable();
+ mIsEnabled = false;
+ }
+ }
+
+ bool Lock() {
+ OSLockMutex(&mMutex);
+
+ if (mIsEnabled) {
+ LC::QueueWaitEx(0);
+ return true;
+ }
+
+ OSUnlockMutex(&mMutex);
+ return false;
+ }
+
+ void Unlock() {
+ LC::QueueWaitEx(0);
+ OSUnlockMutex(&mMutex);
+ }
+
+private:
+ bool mIsEnabled; // at 0x0
+ OSMutex mMutex; // at 0x4
+};
+
+static LCImpl sLCImpl;
+
+} // namespace
+
+namespace LC {
+
+void Enable() {
+ sLCImpl.Enable();
+}
+
+void Disable() {
+ sLCImpl.Disable();
+}
+
+bool Lock() {
+ return sLCImpl.Lock();
+}
+
+void Unlock() {
+ sLCImpl.Unlock();
+}
+
+void LoadBlocks(void *dst, void *src, unsigned long size) {
+ LCLoadBlocks(dst, src, size);
+}
+
+void StoreBlocks(void *dst, void *src, unsigned long size) {
+ LCStoreBlocks(dst, src, size);
+}
+
+void StoreData(void *dst, void *src, unsigned long size) {
+ LCStoreData(dst, src, size);
+}
+
+} // namespace LC
+} // namespace ut
+} // namespace nw4r
diff --git a/src/nw4r/ut/ut_NandFileStream.cpp b/src/nw4r/ut/ut_NandFileStream.cpp
index e69de29b..29c7a0b8 100644
--- a/src/nw4r/ut/ut_NandFileStream.cpp
+++ b/src/nw4r/ut/ut_NandFileStream.cpp
@@ -0,0 +1,178 @@
+
+#include <nw4r/ut.h>
+
+namespace nw4r {
+namespace ut {
+
+NW4R_UT_RTTI_DEF_DERIVED(NandFileStream, FileStream);
+
+void NandFileStream::NandAsyncCallback_(long result, NANDCommandBlock *block) {
+ NandFileStream *self = reinterpret_cast<AsyncContext *>(block)->stream;
+
+ self->mIsBusy = false;
+ self->mResult = result;
+
+ if (self->mCallback != NULL) {
+ self->mCallback(result, self, self->mCallbackArg);
+ }
+}
+
+void NandFileStream::Initialize_() {
+ mCanRead = false;
+ mCanWrite = false;
+ mCloseOnDestroy = false;
+ mAllowClose = false;
+ mIsOpen = false;
+ mIsBusy = false;
+ mCallback = NULL;
+ mCallbackArg = NULL;
+ mResult = NAND_RESULT_OK;
+ mAsyncContext.stream = this;
+}
+
+NandFileStream::NandFileStream(const char *path, unsigned long access) {
+ Initialize_();
+ Open(path, access);
+}
+
+NandFileStream::NandFileStream(const NANDFileInfo *info, unsigned long access, bool close) {
+ Initialize_();
+ Open(info, access, close);
+}
+
+NandFileStream::~NandFileStream() {
+ if (mCloseOnDestroy) {
+ Close();
+ }
+}
+
+bool NandFileStream::Open(const char *path, unsigned long access) {
+ if (mCloseOnDestroy) {
+ Close();
+ }
+
+ mCanRead = access & NAND_ACCESS_READ;
+ mCanWrite = access & NAND_ACCESS_WRITE;
+
+ if (NANDOpen(path, &mAsyncContext.info, access) != NAND_RESULT_OK) {
+ return false;
+ }
+
+ if (mCanRead) {
+ unsigned long fileSize;
+
+ if (NANDGetLength(&mAsyncContext.info, &fileSize) != NAND_RESULT_OK) {
+ NANDClose(&mAsyncContext.info);
+ return false;
+ }
+
+ mFilePosition.SetFileSize(fileSize);
+ }
+
+ mFilePosition.Seek(0, SEEK_BEG);
+
+ mCloseOnDestroy = true;
+ mAllowClose = true;
+ mIsOpen = true;
+
+ return true;
+}
+
+bool NandFileStream::Open(const NANDFileInfo *info, unsigned long access, bool close) {
+ if (mCloseOnDestroy) {
+ Close();
+ }
+
+ mCanRead = access & NAND_ACCESS_READ;
+ mCanWrite = access & NAND_ACCESS_WRITE;
+
+ mAsyncContext.info = *info;
+
+ unsigned long fileSize;
+ if (mCanRead) {
+ if (NANDGetLength(&mAsyncContext.info, &fileSize) != NAND_RESULT_OK) {
+ if (close) {
+ NANDClose(&mAsyncContext.info);
+ }
+ return false;
+ }
+ mFilePosition.SetFileSize(fileSize);
+ }
+ mFilePosition.Seek(0, SEEK_BEG);
+
+ mCloseOnDestroy = false;
+ mAllowClose = close;
+ mIsOpen = true;
+ return true;
+}
+
+void NandFileStream::Close() {
+ if (mAllowClose && mIsOpen) {
+ NANDClose(&mAsyncContext.info);
+ mIsOpen = false;
+ }
+}
+
+long NandFileStream::Read(void *dst, unsigned long size) {
+ NANDSeek(&mAsyncContext.info, mFilePosition.Tell(), NAND_SEEK_BEG);
+
+ long result = NANDRead(&mAsyncContext.info, dst, size);
+ if (result > 0) {
+ mFilePosition.Skip(result);
+ }
+
+ return result;
+}
+
+bool NandFileStream::ReadAsync(void *dst, unsigned long size, AsyncCallback callback, void *arg) {
+ mCallback = callback;
+ mCallbackArg = arg;
+ mIsBusy = true;
+
+ NANDSeek(&mAsyncContext.info, mFilePosition.Tell(), NAND_SEEK_BEG);
+
+ bool success =
+ NANDReadAsync(&mAsyncContext.info, dst, size, NandAsyncCallback_, &mAsyncContext.block) == NAND_RESULT_OK;
+
+ if (success) {
+ mFilePosition.Skip(size);
+ } else {
+ mIsBusy = false;
+ }
+
+ return success;
+}
+
+long NandFileStream::Write(const void *src, unsigned long size) {
+ NANDSeek(&mAsyncContext.info, mFilePosition.Tell(), NAND_SEEK_BEG);
+ long result = NANDWrite(&mAsyncContext.info, src, size);
+ if (result > 0) {
+ mFilePosition.Append(result);
+ }
+ return result;
+}
+
+bool NandFileStream::WriteAsync(const void *src, unsigned long size, AsyncCallback callback, void *arg) {
+ mCallback = callback;
+ mCallbackArg = arg;
+ mIsBusy = true;
+
+ NANDSeek(&mAsyncContext.info, mFilePosition.Tell(), NAND_SEEK_BEG);
+
+ long result = NANDWriteAsync(&mAsyncContext.info, src, size, NandAsyncCallback_, &mAsyncContext.block);
+
+ if (result == NAND_RESULT_OK) {
+ mFilePosition.Append(size);
+ } else {
+ mIsBusy = false;
+ }
+
+ return result == NAND_RESULT_OK;
+}
+
+void NandFileStream::Seek(long offset, unsigned long origin) {
+ mFilePosition.Seek(offset, origin);
+}
+
+} // namespace ut
+} // namespace nw4r
diff --git a/src/nw4r/ut/ut_ResFont.cpp b/src/nw4r/ut/ut_ResFont.cpp
index e69de29b..1dfc9f3b 100644
--- a/src/nw4r/ut/ut_ResFont.cpp
+++ b/src/nw4r/ut/ut_ResFont.cpp
@@ -0,0 +1,121 @@
+#include <nw4r/ut.h>
+
+const u32 MAGIC_RESFONT = 'RFNT';
+const u32 MAGIC_UNPACKED = 'RFNU';
+
+const u32 MAGIC_FONTINFO = 'FINF';
+const u32 MAGIC_TEXGLYPH = 'TGLP';
+const u32 MAGIC_CHARWIDTH = 'CWDH';
+const u32 MAGIC_CHARMAP = 'CMAP';
+const u32 MAGIC_GLGR = 'GLGR';
+
+namespace nw4r {
+namespace ut {
+namespace {
+
+template <typename T>
+void ResolveOffset(T *&ptr, void *base) {
+ ptr = reinterpret_cast<T *>(static_cast<char *>(base) + reinterpret_cast<ptrdiff_t>(ptr));
+}
+
+} // namespace
+
+ResFont::ResFont() {}
+
+ResFont::~ResFont() {}
+
+bool ResFont::SetResource(void *buffer) {
+ BinaryFileHeader *header = static_cast<BinaryFileHeader *>(buffer);
+ FontInformation *info = NULL;
+
+ if (!IsManaging(NULL)) {
+ return false;
+ }
+
+ if (header->magic == MAGIC_UNPACKED) {
+ BinaryBlockHeader *block =
+ reinterpret_cast<BinaryBlockHeader *>(reinterpret_cast<char *>(header) + header->headerSize);
+
+ for (int i = 0; i < header->numBlocks; i++) {
+ if (block->magic == MAGIC_FONTINFO) {
+ info = reinterpret_cast<FontInformation *>(block + 1);
+ break;
+ }
+
+ block = reinterpret_cast<BinaryBlockHeader *>(reinterpret_cast<char *>(block) + block->length);
+ }
+ } else {
+ if (header->version == NW4R_VERSION(1, 04)) {
+ if (!IsValidBinaryFile(header, MAGIC_RESFONT, NW4R_VERSION(1, 04), 2)) {
+ return false;
+ }
+ } else if (!IsValidBinaryFile(header, MAGIC_RESFONT, NW4R_VERSION(1, 02), 2)) {
+ return false;
+ }
+
+ info = Rebuild(header);
+ }
+
+ if (info == NULL) {
+ return false;
+ }
+
+ SetResourceBuffer(header, info);
+ InitReaderFunc(GetEncoding());
+
+ return true;
+}
+
+void *ResFont::RemoveResource() {
+ return ResFontBase::RemoveResourceBuffer();
+}
+
+FontInformation *ResFont::Rebuild(BinaryFileHeader *header) {
+ BinaryBlockHeader *block =
+ reinterpret_cast<BinaryBlockHeader *>(reinterpret_cast<char *>(header) + header->headerSize);
+ FontInformation *info = NULL;
+
+ for (int i = 0; i < header->numBlocks; i++) {
+ switch (block->magic) {
+ case MAGIC_FONTINFO:
+ info = reinterpret_cast<FontInformation *>(block + 1);
+ ResolveOffset<FontTextureGlyph>(info->fontGlyph, header);
+
+ if (info->fontWidth != 0) {
+ ResolveOffset<FontWidth>(info->fontWidth, header);
+ }
+
+ if (info->fontMap != 0) {
+ ResolveOffset<FontCodeMap>(info->fontMap, header);
+ }
+ break;
+ case MAGIC_TEXGLYPH:
+ ResolveOffset<u8>(reinterpret_cast<FontTextureGlyph *>(block + 1)->sheetImage, header);
+ break;
+ case MAGIC_CHARWIDTH:
+ FontWidth *width = reinterpret_cast<FontWidth *>(block + 1);
+ if (width->next != 0) {
+ ResolveOffset<FontWidth>(width->next, header);
+ }
+ break;
+ case MAGIC_CHARMAP:
+ FontCodeMap *map = reinterpret_cast<FontCodeMap *>(block + 1);
+ if (map->next != 0) {
+ ResolveOffset<FontCodeMap>(map->next, header);
+ }
+ break;
+ case MAGIC_GLGR:
+ break;
+ default:
+ return NULL;
+ }
+
+ block = reinterpret_cast<BinaryBlockHeader *>(reinterpret_cast<char *>(block) + block->length);
+ }
+
+ header->magic = MAGIC_UNPACKED;
+ return info;
+}
+
+} // namespace ut
+} // namespace nw4r
diff --git a/src/nw4r/ut/ut_ResFontBase.cpp b/src/nw4r/ut/ut_ResFontBase.cpp
index e69de29b..40068a17 100644
--- a/src/nw4r/ut/ut_ResFontBase.cpp
+++ b/src/nw4r/ut/ut_ResFontBase.cpp
@@ -0,0 +1,221 @@
+#include <nw4r/ut.h>
+
+namespace nw4r {
+namespace ut {
+namespace detail {
+
+ResFontBase::ResFontBase() : mResource(NULL), mFontInfo(NULL), mLastCharCode(0), mLastGlyphIndex(-1) {}
+
+ResFontBase::~ResFontBase() {}
+
+void ResFontBase::SetResourceBuffer(void *buffer, FontInformation *info) {
+ mResource = buffer;
+ mFontInfo = info;
+}
+
+void *ResFontBase::RemoveResourceBuffer() {
+ void *pUserData = mResource;
+ mFontInfo = NULL;
+ mResource = NULL;
+ return pUserData;
+}
+
+int ResFontBase::GetWidth() const {
+ return mFontInfo->width;
+}
+
+int ResFontBase::GetHeight() const {
+ return mFontInfo->height;
+}
+
+int ResFontBase::GetAscent() const {
+ return mFontInfo->ascent;
+}
+
+int ResFontBase::GetDescent() const {
+ return mFontInfo->height - mFontInfo->ascent;
+}
+
+int ResFontBase::GetBaselinePos() const {
+ return mFontInfo->fontGlyph->baselinePos;
+}
+
+int ResFontBase::GetCellHeight() const {
+ return mFontInfo->fontGlyph->cellHeight;
+}
+
+int ResFontBase::GetCellWidth() const {
+ return mFontInfo->fontGlyph->cellWidth;
+}
+
+int ResFontBase::GetMaxCharWidth() const {
+ return mFontInfo->fontGlyph->maxCharWidth;
+}
+
+Font::Type ResFontBase::GetType() const {
+ return TYPE_RESOURCE;
+}
+
+GXTexFmt ResFontBase::GetTextureFormat() const {
+ return static_cast<GXTexFmt>(mFontInfo->fontGlyph->sheetFormat);
+}
+
+int ResFontBase::GetLineFeed() const {
+ return mFontInfo->lineFeed;
+}
+
+CharWidths ResFontBase::GetDefaultCharWidths() const {
+ return mFontInfo->defaultWidth;
+}
+
+void ResFontBase::SetDefaultCharWidths(const CharWidths &widths) {
+ mFontInfo->defaultWidth = widths;
+}
+
+bool ResFontBase::SetAlternateChar(u16 ch) {
+ u32 index = FindGlyphIndex(ch);
+ if (index != 0xFFFF) {
+ mFontInfo->alterCharIndex = index;
+ return true;
+ }
+
+ return false;
+}
+
+void ResFontBase::SetLineFeed(int lf) {
+ mFontInfo->lineFeed = lf;
+}
+
+int ResFontBase::GetCharWidth(u16 ch) const {
+ return GetCharWidths(ch).charWidth;
+}
+
+CharWidths ResFontBase::GetCharWidths(u16 ch) const {
+ u16 index = GetGlyphIndex(ch);
+ return GetCharWidthsFromIndex(index);
+}
+
+void ResFontBase::GetGlyph(Glyph *out, u16 ch) const {
+ u16 index = GetGlyphIndex(ch);
+ GetGlyphFromIndex(out, index);
+}
+
+bool ResFontBase::HasGlyph(u16 c) const {
+ return FindGlyphIndex(c) != 0xFFFF;
+}
+
+FontEncoding ResFontBase::GetEncoding() const {
+ return static_cast<FontEncoding>(mFontInfo->encoding);
+}
+
+u16 ResFontBase::GetGlyphIndex(u16 c) const {
+ u16 index = FindGlyphIndex(c);
+ return (index != 0xFFFF) ? index : mFontInfo->alterCharIndex;
+}
+
+u16 ResFontBase::FindGlyphIndex(u16 c) const {
+ if (c == mLastCharCode) {
+ return mLastGlyphIndex;
+ }
+ mLastCharCode = c;
+
+ for (FontCodeMap *it = mFontInfo->fontMap; it != NULL; it = it->next) {
+ if (it->firstChar <= c && c <= it->lastChar) {
+ mLastGlyphIndex = FindGlyphIndex(it, c);
+ return mLastGlyphIndex;
+ }
+ }
+
+ mLastGlyphIndex = 0xFFFF;
+ return mLastGlyphIndex;
+}
+
+u16 ResFontBase::FindGlyphIndex(const FontCodeMap *map, u16 c) const {
+ struct CMapScanEntry {
+ u16 code; // at 0x0
+ u16 index; // at 0x2
+ };
+
+ struct CMapInfoScan {
+ u16 num; // at 0x0
+ CMapScanEntry entries[]; // at 0x2
+ };
+
+ u16 index = 0xFFFF;
+
+ switch (map->mappingMethod) {
+ case FONT_MAPMETHOD_LINEAR:
+ index = map->mapInfo[0] + (c - map->firstChar);
+ break;
+ case FONT_MAPMETHOD_ARRAY:
+ index = map->mapInfo[c - map->firstChar];
+ break;
+ case FONT_MAPMETHOD_SCAN:
+ const CMapInfoScan *info = reinterpret_cast<const CMapInfoScan *>(map->mapInfo);
+
+ const CMapScanEntry *s = info->entries;
+ const CMapScanEntry *e = &info->entries[info->num - 1];
+
+ while (s <= e) {
+ const CMapScanEntry *m = s + (e - s) / 2;
+
+ if (m->code < c) {
+ s = m + 1;
+ } else if (c < m->code) {
+ e = m - 1;
+ } else {
+ return m->index;
+ }
+ }
+
+ break;
+ }
+
+ return index;
+}
+
+const CharWidths &ResFontBase::GetCharWidthsFromIndex(u16 index) const {
+ for (const FontWidth *it = mFontInfo->fontWidth; it != NULL; it = it->next) {
+ if (it->firstChar <= index && index <= it->lastChar) {
+ return GetCharWidthsFromIndex(it, index);
+ }
+ }
+
+ return mFontInfo->defaultWidth;
+}
+
+const CharWidths &ResFontBase::GetCharWidthsFromIndex(const FontWidth *width, u16 index) const {
+ return width->widthTable[index - width->firstChar];
+}
+
+void ResFontBase::GetGlyphFromIndex(Glyph *out, u16 index) const {
+ const FontTextureGlyph *texGlyph = mFontInfo->fontGlyph;
+
+ u32 cellsInASheet = texGlyph->sheetRow * texGlyph->sheetLine;
+
+ u32 glyphCell = index % cellsInASheet;
+ u32 glyphSheet = index / cellsInASheet;
+
+ u32 unitX = glyphCell % texGlyph->sheetRow;
+ u32 unitY = glyphCell / texGlyph->sheetRow;
+
+ u32 pixelX = unitX * (texGlyph->cellWidth + 1);
+ u32 pixelY = unitY * (texGlyph->cellHeight + 1);
+
+ out->texture = texGlyph->sheetImage + (glyphSheet * texGlyph->sheetSize);
+
+ out->widths = GetCharWidthsFromIndex(index);
+ out->height = texGlyph->cellHeight;
+
+ out->format = static_cast<GXTexFmt>(texGlyph->sheetFormat);
+
+ out->texWidth = texGlyph->sheetWidth;
+ out->texHeight = texGlyph->sheetHeight;
+
+ out->cellX = pixelX + 1;
+ out->cellY = pixelY + 1;
+}
+
+} // namespace detail
+} // namespace ut
+} // namespace nw4r
diff --git a/src/nw4r/ut/ut_RomFont.cpp b/src/nw4r/ut/ut_RomFont.cpp
new file mode 100644
index 00000000..f3cb29f6
--- /dev/null
+++ b/src/nw4r/ut/ut_RomFont.cpp
@@ -0,0 +1,226 @@
+#include <nw4r/ut.h>
+
+namespace nw4r {
+namespace ut {
+
+u16 RomFont::mFontEncode = 0xFFFF;
+
+namespace {
+
+bool IsCP1252Char(u16 c) {
+ return c >= 0x20 && c <= 0xFF;
+}
+
+bool IsSJISHalfWidthChar(u16 c) {
+ if (c > 0xFF) {
+ return false;
+ }
+
+ return (c >= 0x20 && c <= 0x7E) || (c >= 0xA1 && c <= 0xDF);
+}
+
+bool IsSJISFullWidthChar(u16 c) {
+ u8 hi = BitExtract<u16>(c, 8, 8);
+ u8 lo = BitExtract<u16>(c, 0, 8);
+
+ return hi >= 0x81 && hi <= 0x98 && lo >= 0x40 && lo <= 0xFC;
+}
+
+} // namespace
+
+RomFont::RomFont() : mFontHeader(NULL), mAlternateChar('?') {
+ mDefaultWidths.leftSpacing = 0;
+ mDefaultWidths.glyphWidth = 0;
+ mDefaultWidths.charWidth = 0;
+}
+
+RomFont::~RomFont() {}
+
+bool RomFont::Load(void *buffer) {
+ if (mFontHeader != NULL) {
+ return false;
+ }
+
+ BOOL success = OSInitFont(static_cast<OSFontHeader *>(buffer));
+
+ if (success) {
+ mFontEncode = OSGetFontEncode();
+ mFontHeader = static_cast<OSFontHeader *>(buffer);
+
+ mDefaultWidths.leftSpacing = 0;
+ mDefaultWidths.glyphWidth = GetCellWidth();
+ mDefaultWidths.charWidth = GetMaxCharWidth();
+
+ InitReaderFunc(GetEncoding());
+ }
+
+ return success;
+}
+
+u32 RomFont::GetRequireBufferSize() {
+ switch (OSGetFontEncode()) {
+ case OS_FONT_ENCODE_ANSI:
+ return 0x00020120;
+ case OS_FONT_ENCODE_SJIS:
+ return 0x00120F00;
+ }
+
+ return 0;
+}
+
+int RomFont::GetWidth() const {
+ return mFontHeader->width;
+}
+
+int RomFont::GetHeight() const {
+ return GetAscent() + GetDescent();
+}
+
+int RomFont::GetAscent() const {
+ return mFontHeader->ascent;
+}
+
+int RomFont::GetDescent() const {
+ return mFontHeader->descent;
+}
+
+int RomFont::GetBaselinePos() const {
+ return mFontHeader->ascent;
+}
+
+int RomFont::GetCellHeight() const {
+ return mFontHeader->cellHeight;
+}
+
+int RomFont::GetCellWidth() const {
+ return mFontHeader->cellWidth;
+}
+
+int RomFont::GetMaxCharWidth() const {
+ return mFontHeader->width;
+}
+
+Font::Type RomFont::GetType() const {
+ return TYPE_ROM;
+}
+
+GXTexFmt RomFont::GetTextureFormat() const {
+ return GX_TF_I4;
+}
+
+int RomFont::GetLineFeed() const {
+ return mFontHeader->leading;
+}
+
+CharWidths RomFont::GetDefaultCharWidths() const {
+ return mDefaultWidths;
+}
+
+void RomFont::SetDefaultCharWidths(const CharWidths &widths) {
+ mDefaultWidths = widths;
+}
+
+bool RomFont::SetAlternateChar(u16 c) {
+ const u16 prev = mAlternateChar;
+ mAlternateChar = 0xFFFF;
+
+ u16 undef = HandleUndefinedChar(c);
+ if (undef != 0xFFFF) {
+ mAlternateChar = c;
+ return true;
+ } else {
+ mAlternateChar = prev;
+ return false;
+ }
+}
+
+void RomFont::SetLineFeed(int lf) {
+ mFontHeader->leading = lf;
+}
+
+int RomFont::GetCharWidth(u16 c) const {
+ u32 width;
+ char buffer[4];
+
+ MakeCharPtr(buffer, c);
+ OSGetFontWidth(buffer, &width);
+
+ return width;
+}
+
+CharWidths RomFont::GetCharWidths(u16 c) const {
+ int width = GetCharWidth(c);
+
+ CharWidths widths;
+ widths.leftSpacing = 0;
+ widths.glyphWidth = width;
+ widths.charWidth = width;
+
+ return widths;
+}
+
+void RomFont::GetGlyph(Glyph *out, u16 c) const {
+ void *texture;
+ u32 x, y, width;
+ char buffer[4];
+
+ MakeCharPtr(buffer, c);
+ OSGetFontTexture(buffer, &texture, &x, &y, &width);
+
+ out->texture = texture;
+
+ out->widths.leftSpacing = 0;
+ out->widths.glyphWidth = width;
+ out->widths.charWidth = width;
+
+ out->height = mFontHeader->cellHeight;
+ out->format = GX_TF_I4;
+
+ out->texWidth = mFontHeader->sheetWidth;
+ out->texHeight = mFontHeader->sheetHeight;
+
+ out->cellX = x;
+ out->cellY = y;
+}
+
+FontEncoding RomFont::GetEncoding() const {
+ switch (mFontEncode) {
+ case OS_FONT_ENCODE_ANSI:
+ return FONT_ENCODE_CP1252;
+ case OS_FONT_ENCODE_SJIS:
+ return FONT_ENCODE_SJIS;
+ }
+
+ return FONT_ENCODE_CP1252;
+}
+
+void RomFont::MakeCharPtr(char *buffer, u16 c) const {
+ c = HandleUndefinedChar(c);
+
+ if (BitExtract<u16>(c, 8, 8) == 0) {
+ buffer[0] = c & 0x00FF;
+ buffer[1] = '\0';
+ } else {
+ buffer[0] = BitExtract<u16>(c, 8, 8);
+ buffer[1] = c & 0x00FF;
+ buffer[2] = '\0';
+ }
+}
+
+u16 RomFont::HandleUndefinedChar(u16 c) const {
+ bool valid;
+
+ switch (mFontEncode) {
+ case OS_FONT_ENCODE_ANSI:
+ valid = IsCP1252Char(c);
+ break;
+ case OS_FONT_ENCODE_SJIS:
+ valid = IsSJISHalfWidthChar(c) || IsSJISFullWidthChar(c);
+ break;
+ }
+
+ return valid ? c : mAlternateChar;
+}
+
+} // namespace ut
+} // namespace nw4r
diff --git a/src/nw4r/ut/ut_TextWriterBase.cpp b/src/nw4r/ut/ut_TextWriterBase.cpp
index e69de29b..c3fc3032 100644
--- a/src/nw4r/ut/ut_TextWriterBase.cpp
+++ b/src/nw4r/ut/ut_TextWriterBase.cpp
@@ -0,0 +1,494 @@
+
+#include <Runtime.PPCEABI.H/__va_arg.h>
+#include <nw4r/ut.h>
+
+namespace nw4r {
+namespace ut {
+
+template <typename T>
+T *TextWriterBase<T>::mFormatBuffer;
+template <typename T>
+int TextWriterBase<T>::mFormatBufferSize = 0x100;
+
+template <typename T>
+TagProcessorBase<T> TextWriterBase<T>::mDefaultTagProcessor;
+
+template <typename T>
+TextWriterBase<T>::TextWriterBase()
+ : mCharSpace(0.0f), mWidthLimit(NW4R_MATH_FLT_MAX), mLineSpace(0.0f), mTabWidth(4), mDrawFlag(0),
+ mTagProcessor(&mDefaultTagProcessor) {}
+
+template <typename T>
+TextWriterBase<T>::~TextWriterBase() {}
+
+template <typename T>
+void TextWriterBase<T>::SetLineHeight(f32 height) {
+ const Font *font = GetFont();
+ int lf = font != NULL ? font->GetLineFeed() : 0;
+ mLineSpace = height - lf * GetScaleV();
+}
+
+template <typename T>
+f32 TextWriterBase<T>::GetLineHeight() const {
+ const Font *font = GetFont();
+ int lf = font != NULL ? font->GetLineFeed() : 0;
+ return mLineSpace + GetScaleV() * lf;
+}
+
+template <typename T>
+f32 TextWriterBase<T>::CalcFormatStringWidth(const T *format, ...) const {
+ Rect rect;
+ _va_list_struct args;
+
+ va_start(args, format);
+ CalcVStringRect(&rect, format, &args);
+ va_end(args);
+
+ return rect.GetWidth();
+}
+
+template <typename T>
+f32 TextWriterBase<T>::CalcFormatStringHeight(const T *format, ...) const {
+ Rect rect;
+ _va_list_struct args;
+
+ va_start(args, format);
+ CalcVStringRect(&rect, format, &args);
+ va_end(args);
+
+ return rect.GetHeight();
+}
+
+template <typename T>
+void TextWriterBase<T>::CalcFormatStringRect(Rect *rect, const T *format, ...) const {
+ _va_list_struct args;
+
+ va_start(args, format);
+ CalcVStringRect(rect, format, &args);
+ va_end(args);
+}
+
+template <typename T>
+void TextWriterBase<T>::CalcVStringRect(Rect *rect, const T *format, va_list args) const {
+ T *pBuffer;
+
+ if (mFormatBuffer != NULL) {
+ pBuffer = mFormatBuffer;
+ } else {
+ pBuffer = static_cast<T *>(__alloca(mFormatBufferSize));
+ }
+
+ int len = VSNPrintf(pBuffer, mFormatBufferSize, format, args);
+ len = Min(len, mFormatBufferSize - 1);
+
+ CalcStringRect(rect, pBuffer, len);
+}
+
+template <typename T>
+f32 TextWriterBase<T>::CalcStringWidth(const T *str, int len) const {
+ Rect rect;
+ CalcStringRect(&rect, str, len);
+ return rect.GetWidth();
+}
+
+template <typename T>
+f32 TextWriterBase<T>::CalcStringHeight(const T *str, int len) const {
+ Rect rect;
+ CalcStringRect(&rect, str, len);
+ return rect.GetHeight();
+}
+
+template <typename T>
+void TextWriterBase<T>::CalcStringRect(Rect *rect, const T *str, int len) const {
+ TextWriterBase<T> clone(*this);
+ clone.CalcStringRectImpl(rect, str, len);
+}
+
+template <typename T>
+f32 TextWriterBase<T>::Printf(const T *format, ...) {
+ va_list args;
+ va_start(args[0], format);
+ f32 width = VPrintf(format, args);
+ va_end(args[0]);
+ return width;
+}
+
+template <typename T>
+f32 TextWriterBase<T>::VPrintf(const T *str, va_list args) {
+ T *pBuffer;
+
+ if (mFormatBuffer != NULL) {
+ pBuffer = mFormatBuffer;
+ } else {
+ pBuffer = static_cast<T *>(__alloca(mFormatBufferSize));
+ }
+
+ int len = VSNPrintf(pBuffer, mFormatBufferSize, str, args);
+ len = Min(len, mFormatBufferSize - 1);
+ return Print(pBuffer, len);
+}
+
+template <typename T>
+f32 TextWriterBase<T>::Print(const T *str, int len) {
+ TextWriterBase<T> clone(*this);
+
+ f32 width = clone.PrintImpl(str, len, false);
+ SetCursor(clone.GetCursorX(), clone.GetCursorY());
+
+ return width;
+}
+
+template <typename T>
+f32 TextWriterBase<T>::PrintfMutable(const T *format, ...) {
+ va_list args;
+ va_start(args[0], format);
+ f32 width = VPrintfMutable(format, args);
+ va_end(args[0]);
+ return width;
+}
+
+template <typename T>
+f32 TextWriterBase<T>::VPrintfMutable(const T *format, va_list args) {
+ T *pBuffer;
+
+ if (mFormatBuffer != NULL) {
+ pBuffer = mFormatBuffer;
+ } else {
+ pBuffer = static_cast<T *>(__alloca(mFormatBufferSize));
+ }
+
+ int len = VSNPrintf(pBuffer, mFormatBufferSize, format, args);
+ len = Min(len, mFormatBufferSize - 1);
+ return PrintMutable(pBuffer, len);
+}
+
+template <typename T>
+f32 TextWriterBase<T>::PrintMutable(const T *str, int len) {
+ return PrintImpl(str, len, true);
+}
+
+template <typename T>
+f32 TextWriterBase<T>::CalcLineWidth(const T *str, int len) {
+ Rect rect;
+ TextWriterBase<T> clone(*this);
+
+ clone.SetCursor(0.0f, 0.0f);
+ clone.CalcLineRectImpl(&rect, &str, len);
+
+ return rect.GetWidth();
+}
+
+template <typename T>
+bool TextWriterBase<T>::CalcLineRectImpl(Rect *rect, const T **str, int len) {
+ const T *strBegin = *str;
+ const T *strEnd = strBegin + len;
+ const bool useLimit = mWidthLimit < NW4R_MATH_FLT_MAX;
+
+ PrintContext<T> context = {this, strBegin};
+
+ f32 x = 0.0f;
+ bool charSpace = false;
+ bool overLimit = false;
+
+ const T *prevStream = NULL;
+ Rect prevRect;
+
+ CharStrmReader reader = GetFont()->GetCharStrmReader();
+
+ rect->left = 0.0f;
+ rect->right = 0.0f;
+ rect->top = Min(0.0f, GetLineHeight());
+ rect->bottom = Max(0.0f, GetLineHeight());
+ prevRect = *rect;
+
+ reader.Set(strBegin);
+ prevStream = NULL;
+
+ u16 ch = reader.Next();
+
+ while (static_cast<const T *>(reader.GetCurrentPos()) <= strEnd) {
+ if (ch < ' ') {
+ Rect r(x, 0.0f, 0.0f, 0.0f);
+ context.str = static_cast<const T *>(reader.GetCurrentPos());
+ context.flags = charSpace ? 0 : PRINTFLAGS_CHARSPACE;
+ SetCursorX(x);
+
+ if (useLimit && ch != '\n' && prevStream != NULL) {
+ PrintContext<T> context2 = context;
+ TextWriterBase<T> clone(*this);
+
+ Rect r;
+ context2.writer = &clone;
+ mTagProcessor->CalcRect(&r, ch, &context2);
+
+ if (r.GetWidth() > 0.0f && clone.GetCursorX() - context.x > mWidthLimit) {
+ overLimit = true;
+ ch = '\n';
+ reader.Set(prevStream);
+ continue;
+ }
+ }
+
+ Operation oper = mTagProcessor->CalcRect(&r, ch, &context);
+ reader.Set(context.str);
+
+ rect->left = Min(rect->left, r.left);
+ rect->top = Min(rect->top, r.top);
+ rect->right = Max(rect->right, r.right);
+ rect->bottom = Max(rect->bottom, r.bottom);
+
+ x = GetCursorX();
+
+ if (oper == OPERATION_END_DRAW) {
+ *str += len;
+ return false;
+ }
+
+ if (oper == OPERATION_NO_CHAR_SPACE) {
+ charSpace = false;
+ } else if (oper == OPERATION_CHAR_SPACE) {
+ charSpace = true;
+ } else if (oper == OPERATION_NEXT_LINE) {
+ break;
+ }
+ } else {
+ f32 dx = 0.0f;
+
+ if (charSpace) {
+ dx += GetCharSpace();
+ }
+
+ if (IsWidthFixed()) {
+ dx += GetFixedWidth();
+ } else {
+ dx += GetFont()->GetCharWidth(ch) * GetScaleH();
+ }
+
+ if (useLimit && prevStream != NULL && x + dx > mWidthLimit) {
+ overLimit = true;
+ ch = '\n';
+ reader.Set(prevStream);
+ continue;
+ }
+
+ x += dx;
+ rect->left = Min(rect->left, x);
+ rect->right = Max(rect->right, x);
+
+ charSpace = true;
+ }
+
+ if (useLimit) {
+ prevStream = static_cast<const T *>(reader.GetCurrentPos());
+ }
+
+ ch = reader.Next();
+ }
+
+ *str = static_cast<const T *>(reader.GetCurrentPos());
+ return overLimit;
+}
+
+template <typename T>
+void TextWriterBase<T>::CalcStringRectImpl(Rect *rect, const T *str, int len) {
+ const T *end = str + len;
+ int remain = len;
+
+ rect->left = 0.0f;
+ rect->right = 0.0f;
+ rect->top = 0.0f;
+ rect->bottom = 0.0f;
+
+ SetCursor(0.0f, 0.0f);
+
+ do {
+ Rect r;
+ CalcLineRectImpl(&r, &str, remain);
+ remain = end - str;
+
+ rect->left = Min(rect->left, r.left);
+ rect->top = Min(rect->top, r.top);
+ rect->right = Max(rect->right, r.right);
+ rect->bottom = Max(rect->bottom, r.bottom);
+ } while (remain > 0);
+}
+
+template <typename T>
+f32 TextWriterBase<T>::PrintImpl(const T *str, int len, bool m) {
+ f32 cursorX = GetCursorX();
+ f32 cursorY = GetCursorY();
+
+ bool useLimit = mWidthLimit < NW4R_MATH_FLT_MAX;
+
+ f32 orgCursorX = cursorX;
+ f32 orgCursorY = cursorY;
+
+ f32 cursorXAdj = 0.0f;
+ f32 cursorYAdj = 0.0f;
+
+ bool charSpace = false;
+
+ const T *prevStream = str;
+ const T *prevNewline = str;
+
+ f32 textWidth = AdjustCursor(&cursorX, &cursorY, str, len);
+
+ cursorXAdj = orgCursorX - GetCursorX();
+ cursorYAdj = orgCursorY - GetCursorY();
+
+ PrintContext<T> context = {this, str, cursorX, cursorY};
+
+ CharStrmReader reader = GetFont()->GetCharStrmReader();
+ reader.Set(str);
+
+ Operation oper;
+ u16 ch = reader.Next();
+
+ while (static_cast<const T *>(reader.GetCurrentPos()) - str <= len) {
+ if (ch < ' ') {
+ context.str = static_cast<const T *>(reader.GetCurrentPos());
+ context.flags = charSpace ? 0 : PRINTFLAGS_CHARSPACE;
+
+ if (useLimit && ch != '\n' && prevStream != prevNewline) {
+ PrintContext<T> context2 = context;
+ TextWriterBase<T> clone(*this);
+ Rect rect;
+
+ context2.writer = &clone;
+ oper = mTagProcessor->CalcRect(&rect, ch, &context2);
+
+ if (rect.GetWidth() > 0.0f && clone.GetCursorX() - context.x > mWidthLimit) {
+ ch = '\n';
+ reader.Set(prevStream);
+ continue;
+ }
+ }
+
+ oper = mTagProcessor->Process(ch, &context);
+ if (oper == OPERATION_NEXT_LINE) {
+ if (IsDrawFlagSet(0x3, 0x1)) {
+ int remain = len - (context.str - str);
+ f32 width = CalcLineWidth(context.str, remain);
+ f32 offset = (textWidth - width) / 2.0f;
+ SetCursorX(context.x + offset);
+ } else if (IsDrawFlagSet(0x3, 0x2)) {
+ int remain = len - (context.str - str);
+ f32 width = CalcLineWidth(context.str, remain);
+ f32 offset = textWidth - width;
+ SetCursorX(context.x + offset);
+ } else {
+ f32 width = GetCursorX() - context.x;
+ textWidth = Max(textWidth, width);
+ SetCursorX(context.x);
+ }
+
+ if (useLimit) {
+ prevNewline = static_cast<const T *>(reader.GetCurrentPos());
+ }
+
+ charSpace = false;
+ } else if (oper == OPERATION_NO_CHAR_SPACE) {
+ charSpace = false;
+ } else if (oper == OPERATION_CHAR_SPACE) {
+ charSpace = true;
+ } else if (oper == OPERATION_END_DRAW) {
+ break;
+ }
+
+ reader.Set(context.str);
+ } else {
+ f32 baseY = GetCursorY();
+ if (useLimit && prevStream != prevNewline) {
+ f32 baseX = GetCursorX();
+ f32 space = charSpace ? GetCharSpace() : 0.0f;
+ f32 width = IsWidthFixed() ? GetFixedWidth() : GetFont()->GetCharWidth(ch) * GetScaleH();
+ if (baseX - cursorX + space + width > mWidthLimit) {
+ ch = '\n';
+ reader.Set(prevStream);
+ continue;
+ }
+ }
+
+ if (charSpace) {
+ MoveCursorX(GetCharSpace());
+ }
+
+ charSpace = true;
+
+ const Font *font = GetFont();
+ f32 adj = -font->GetBaselinePos() * GetScaleV();
+ MoveCursorY(adj);
+ CharWriter::Print(ch);
+ SetCursorY(baseY);
+ }
+
+ if (useLimit) {
+ prevStream = static_cast<const T *>(reader.GetCurrentPos());
+ }
+
+ ch = reader.Next();
+ }
+
+ f32 width = GetCursorX() - context.x;
+ textWidth = Max(textWidth, width);
+
+ if (IsDrawFlagSet(0x300, 0x100) || IsDrawFlagSet(0x300, 0x200)) {
+ SetCursorY(orgCursorY);
+ } else {
+ MoveCursorY(cursorYAdj);
+ }
+
+ return textWidth;
+}
+
+template <typename T>
+f32 TextWriterBase<T>::AdjustCursor(f32 *x1, f32 *y1, const T *str, int len) {
+ f32 textWidth = 0.0f;
+ f32 textHeight = 0.0f;
+
+ if (!IsDrawFlagSet(0x333, 0x300) && !IsDrawFlagSet(0x333, 0)) {
+ Rect rect;
+ CalcStringRect(&rect, str, len);
+
+ textWidth = rect.left + rect.right;
+ textHeight = rect.top + rect.bottom;
+
+ if (textWidth > mWidthLimit) {
+ textWidth = mWidthLimit;
+ }
+ }
+
+ if (IsDrawFlagSet(0x30, 0x10)) {
+ *x1 -= textWidth / 2;
+ } else if (IsDrawFlagSet(0x30, 0x20)) {
+ *x1 -= textWidth;
+ }
+
+ if (IsDrawFlagSet(0x300, 0x100)) {
+ *y1 -= textHeight / 2;
+ } else if (IsDrawFlagSet(0x300, 0x200)) {
+ *y1 -= textHeight;
+ }
+
+ if (IsDrawFlagSet(0x3, 0x1)) {
+ SetCursorX(*x1 + (textWidth - CalcLineWidth(str, len)) / 2);
+ } else if (IsDrawFlagSet(0x3, 0x2)) {
+ SetCursorX(*x1 + (textWidth - CalcLineWidth(str, len)));
+ } else {
+ SetCursorX(*x1);
+ }
+
+ if (IsDrawFlagSet(0x300, 0x300)) {
+ SetCursorY(*y1);
+ } else {
+ SetCursorY(*y1 + GetFontAscent());
+ }
+
+ return textWidth;
+}
+
+template struct TextWriterBase<char>;
+template struct TextWriterBase<wchar_t>;
+
+} // namespace ut
+} // namespace nw4r