diff --git a/config/SOUE01/config.yml b/config/SOUE01/config.yml index 9bd91d28..6b77249c 100644 --- a/config/SOUE01/config.yml +++ b/config/SOUE01/config.yml @@ -6,6 +6,10 @@ mw_comment_version: 8 quick_analysis: true force_active: [ "searchBaseByID__10fManager_cF9fBaseID_e", + "ProcessLinefeed__Q34nw4r2ut19TagProcessorBaseFPQ34nw4r2ut15PrintContext", + "ProcessTab__Q34nw4r2ut19TagProcessorBaseFPQ34nw4r2ut15PrintContext", + "ProcessLinefeed__Q34nw4r2ut19TagProcessorBaseFPQ34nw4r2ut15PrintContext", + "ProcessTab__Q34nw4r2ut19TagProcessorBaseFPQ34nw4r2ut15PrintContext", ] # modules: # - object: orig/SOUE01/rels/d_a_asura_bulletNP.rel diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index bb76869b..fc39b065 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -181,6 +181,8 @@ nw4r/ut/ut_CharStrmReader.cpp: nw4r/ut/ut_TagProcessorBase.cpp: .text start:0x8042AB80 end:0x8042B4D4 + .data start:0x8056BD50 end:0x8056BD78 + .sdata2 start:0x8057EB68 end:0x8057EB70 nw4r/ut/ut_IOStream.cpp: .text start:0x8042B4E0 end:0x8042B55C diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index cea99b0e..bcdb8b36 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -23946,7 +23946,7 @@ ReadNextCharCP1252__Q34nw4r2ut14CharStrmReaderFv = .text:0x8042AB00; // type:fun ReadNextCharSJIS__Q34nw4r2ut14CharStrmReaderFv = .text:0x8042AB20; // type:function size:0x60 __ct__Q34nw4r2ut19TagProcessorBaseFv = .text:0x8042AB80; // type:function size:0x10 __dt__Q34nw4r2ut19TagProcessorBaseFv = .text:0x8042AB90; // type:function size:0x40 -Process__Q34nw4r2ut19TagProcessorBase = .text:0x8042ABD0; // type:function size:0x12C +Process__Q34nw4r2ut19TagProcessorBaseFUsPQ34nw4r2ut15PrintContext = .text:0x8042ABD0; // type:function size:0x12C CalcRect__Q34nw4r2ut19TagProcessorBaseFPQ34nw4r2ut4RectUsPQ34nw4r2ut15PrintContext = .text:0x8042AD00; // type:function size:0x1E4 ProcessLinefeed__Q34nw4r2ut19TagProcessorBaseFPQ34nw4r2ut15PrintContext = .text:0x8042AEF0; // type:function size:0x64 ProcessTab__Q34nw4r2ut19TagProcessorBaseFPQ34nw4r2ut15PrintContext = .text:0x8042AF60; // type:function size:0xC4 @@ -36943,8 +36943,8 @@ jumptable_8056BCB8 = .data:0x8056BCB8; // type:object size:0x20 scope:local jumptable_8056BCD8 = .data:0x8056BCD8; // type:object size:0x20 scope:local @1687 = .data:0x8056BCF8; // type:object size:0x21 scope:local data:string lbl_8056BD20 = .data:0x8056BD20; // type:object size:0x30 -lbl_8056BD50 = .data:0x8056BD50; // type:object size:0x14 -lbl_8056BD64 = .data:0x8056BD64; // type:object size:0x14 +__vt__Q34nw4r2ut19TagProcessorBase = .data:0x8056BD50; // type:object size:0x14 scope:weak +__vt__Q34nw4r2ut19TagProcessorBase = .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 diff --git a/configure.py b/configure.py index 5336a084..f86cf316 100644 --- a/configure.py +++ b/configure.py @@ -201,6 +201,7 @@ cflags_egg = [ cflags_nw4r = [ *cflags_base, "-ipa file", + "-fp_contract off", ] # REL flags @@ -321,7 +322,7 @@ config.libs = [ Object(Matching, "nw4r/ut/ut_LinkList.cpp"), Object(Matching, "nw4r/ut/ut_binaryFileFormat.cpp"), Object(NonMatching, "nw4r/ut/ut_CharStrmReader.cpp"), - Object(NonMatching, "nw4r/ut/ut_TagProcessorBase.cpp"), + Object(Matching, "nw4r/ut/ut_TagProcessorBase.cpp"), Object(NonMatching, "nw4r/ut/ut_IOStream.cpp"), Object(NonMatching, "nw4r/ut/ut_FileStream.cpp"), Object(NonMatching, "nw4r/ut/ut_DvdFileStream.cpp"), diff --git a/include/nw4r/ut/ut_TagProcessorBase.h b/include/nw4r/ut/ut_TagProcessorBase.h index f58ff6d7..3c8f19ea 100644 --- a/include/nw4r/ut/ut_TagProcessorBase.h +++ b/include/nw4r/ut/ut_TagProcessorBase.h @@ -10,9 +10,10 @@ enum PrintFlags { PRINTFLAGS_CHARSPACE = (1 << 0), }; -template struct PrintContext { - TextWriterBase* writer; // at 0x0 - const T* str; // at 0x4 +template +struct PrintContext { + TextWriterBase *writer; // at 0x0 + const T *str; // at 0x4 f32 x; // at 0x8 f32 y; // at 0xC u32 flags; // at 0x10 @@ -26,17 +27,18 @@ enum Operation { OPERATION_END_DRAW }; -template class TagProcessorBase { +template +class TagProcessorBase { public: TagProcessorBase(); virtual ~TagProcessorBase(); // at 0x8 - virtual Operation Process(u16 ch, PrintContext* ctx); // at 0xC - virtual Operation CalcRect(Rect* rect, u16 ch, - PrintContext* ctx); // at 0x10 + virtual Operation Process(u16 ch, PrintContext *ctx); // at 0xC + virtual Operation CalcRect(Rect *rect, u16 ch, + PrintContext *ctx); // at 0x10 - void ProcessTab(PrintContext* ctx); - void ProcessLinefeed(PrintContext* ctx); + void ProcessLinefeed(PrintContext *ctx); + void ProcessTab(PrintContext *ctx); }; } // namespace ut diff --git a/src/nw4r/ut/ut_TagProcessorBase.cpp b/src/nw4r/ut/ut_TagProcessorBase.cpp index e69de29b..dc001042 100644 --- a/src/nw4r/ut/ut_TagProcessorBase.cpp +++ b/src/nw4r/ut/ut_TagProcessorBase.cpp @@ -0,0 +1,88 @@ +#include + +namespace nw4r { +namespace ut { + +template +TagProcessorBase::TagProcessorBase() {} + +template +TagProcessorBase::~TagProcessorBase() {} + +template +Operation TagProcessorBase::Process(u16 ch, PrintContext *ctx) { + switch (ch) { + case '\n': + ProcessLinefeed(ctx); + return OPERATION_NEXT_LINE; + case '\t': + ProcessTab(ctx); + return OPERATION_NO_CHAR_SPACE; + } + + return OPERATION_DEFAULT; +} + +template +Operation TagProcessorBase::CalcRect(Rect *rect, u16 ch, PrintContext *ctx) { + switch (ch) { + case '\n': { + const TextWriterBase &writer = *ctx->writer; + rect->right = writer.GetCursorX(); + rect->top = writer.GetCursorY(); + ProcessLinefeed(ctx); + rect->left = writer.GetCursorX(); + rect->bottom = writer.GetCursorY() + ctx->writer->GetFontHeight(); + rect->Normalize(); + return OPERATION_NEXT_LINE; + } + case '\t': { + const TextWriterBase &writer = *ctx->writer; + rect->left = writer.GetCursorX(); + ProcessTab(ctx); + rect->right = writer.GetCursorX(); + rect->top = writer.GetCursorY(); + rect->bottom = rect->top + writer.GetFontHeight(); + rect->Normalize(); + return OPERATION_NO_CHAR_SPACE; + } + } + + return OPERATION_DEFAULT; +} + +template +void TagProcessorBase::ProcessTab(PrintContext *ctx) { + TextWriterBase &writer = *ctx->writer; + + int tabWidth = writer.GetTabWidth(); + if (tabWidth <= 0) { + return; + } + + f32 charWidth = writer.IsWidthFixed() ? writer.GetFixedWidth() : writer.GetFontWidth(); + + f32 dx = writer.GetCursorX() - ctx->x; + f32 tabPixel = tabWidth * charWidth; + int numTab = static_cast(dx / tabPixel) + 1; + f32 x = ctx->x + (tabPixel * numTab); + + writer.SetCursorX(x); +} + +template +void TagProcessorBase::ProcessLinefeed(PrintContext *ctx) { + TextWriterBase &writer = *ctx->writer; + + f32 x = ctx->x; + f32 y = writer.GetCursorY() + writer.GetLineHeight(); + + writer.SetCursorX(x); + writer.SetCursorY(y); +} + +template class TagProcessorBase; +template class TagProcessorBase; + +} // namespace ut +} // namespace nw4r