1- #include < math.h >
1+ #include < cmath >
22#include < list>
33#include < vector>
44#include < functional>
5+ #include < algorithm>
56
67#include < sys/endian.h>
78#include < skyline/utils/cpputils.hpp>
@@ -55,34 +56,36 @@ typedef struct {
5556} StringWord_t;
5657
5758// From https://github.com/CommitteeOfZero/impacto/blob/bfc23774eeeb4bcf853cace270ac3ac58eb681f1/src/text.cpp#L38
58- enum class StringTokenType : uint8_t {
59- LineBreak = 0x00 ,
60- CharacterNameStart = 0x01 ,
61- DialogueLineStart = 0x02 ,
62- Present = 0x03 ,
63- SetColor = 0x04 ,
64- Present_Clear = 0x08 ,
65- RubyBaseStart = 0x09 ,
66- RubyTextStart = 0x0A ,
67- RubyTextEnd = 0x0B ,
68- SetFontSize = 0x0C ,
69- PrintInParallel = 0x0E ,
70- CenterText = 0x0F ,
71- SetTopMargin = 0x11 ,
72- SetLeftMargin = 0x12 ,
73- GetHardcodedValue = 0x13 ,
74- EvaluateExpression = 0x15 ,
75- UnlockTip = 0x16 ,
76- Present_0x18 = 0x18 ,
77- AutoForward = 0x19 ,
78- AutoForward_1A = 0x1A ,
79- RubyCenterPerCharacter = 0x1E ,
80- AltLineBreak = 0x1F ,
81-
82- // This is our own!
83- Character = 0xFE ,
84-
85- EndOfString = 0xFF
59+ struct StringTokenType {
60+ enum value : uint8_t {
61+ LineBreak = 0x00 ,
62+ CharacterNameStart = 0x01 ,
63+ DialogueLineStart = 0x02 ,
64+ Present = 0x03 ,
65+ SetColor = 0x04 ,
66+ Present_Clear = 0x08 ,
67+ RubyBaseStart = 0x09 ,
68+ RubyTextStart = 0x0A ,
69+ RubyTextEnd = 0x0B ,
70+ SetFontSize = 0x0C ,
71+ PrintInParallel = 0x0E ,
72+ CenterText = 0x0F ,
73+ SetTopMargin = 0x11 ,
74+ SetLeftMargin = 0x12 ,
75+ GetHardcodedValue = 0x13 ,
76+ EvaluateExpression = 0x15 ,
77+ UnlockTip = 0x16 ,
78+ Present_0x18 = 0x18 ,
79+ AutoForward = 0x19 ,
80+ AutoForward_1A = 0x1A ,
81+ RubyCenterPerCharacter = 0x1E ,
82+ AltLineBreak = 0x1F ,
83+
84+ // This is our own!
85+ Character = 0xFE ,
86+
87+ EndOfString = 0xFF
88+ };
8689};
8790
8891static float AtlasDialogueMargin = 0 .0f ;
@@ -157,8 +160,7 @@ void semiTokeniseSc3String(std::byte *sc3String, std::list<StringWord_t> &words,
157160 StringWord_t word = { sc3String, NULL , 0 , false , false };
158161
159162 while (sc3String != nullptr ) {
160- const StringTokenType type { std::to_integer<uint8_t >(*sc3String) };
161- switch (type) {
163+ switch (std::to_integer<std::underlying_type_t <StringTokenType::value>>(*sc3String)) {
162164 case StringTokenType::EndOfString:
163165 word.end = sc3String - 1 ;
164166 words.emplace_back (word);
@@ -236,8 +238,7 @@ void processSc3TokenList(int xOffset, int yOffset,int lineLength,
236238 std::byte *sc3String = it->start + (int )(!curLineLength && it->startsWithSpace ) * 2 ;
237239
238240 while (sc3String <= it->end ) {
239- StringTokenType c { std::to_integer<uint8_t >(*sc3String) };
240- switch (c) {
241+ switch (std::to_integer<std::underlying_type_t <StringTokenType::value>>(*sc3String)) {
241242 case StringTokenType::EndOfString:
242243 goto afterWord;
243244 break ;
@@ -414,28 +415,24 @@ void TipsDataInit::Callback(ulong thread, unsigned short *addr1, unsigned short
414415 rd::mem::Overwrite (patchInCmp2Addr + 8 , inst::CmpImmediate (reg::W8 , *EPmaxPtr - 5 ).Value ());
415416}
416417
417- void MESsetNGflag::Callback (int nameNewline, int rubyEnabled) {
418- auto isNGtop = [](unsigned short glyph)->bool {
419- for (uint32_t i = 0 ; i < *MESngFontListTopNumPtr; i++) {
420- if (MESngFontListTop[i] == glyph)
421- return true ;
422- }
423- return false ;
424- };
418+ void MESsetNGflag::Callback (bool nameNewline, bool rubyEnabled) {
425419
426- auto isNGlast = [](unsigned short glyph)->bool {
427- for (uint32_t i = 0 ; i < *MESngFontListLastNumPtr; i++) {
428- if (MESngFontListLast[i] == glyph)
429- return true ;
430- }
431- return false ;
420+ const auto isNGFunc = [](uint16_t *ptr, uint32_t length) {
421+ return [ptr, length](unsigned short glyph)->bool {
422+ return std::find (ptr, ptr + length, glyph) != ptr + length;
423+ };
432424 };
433425
434- auto isLetter = [&isNGtop, &isNGlast](unsigned short glyph)->bool {
435- return glyph < 0x8000 && !isNGtop (glyph) && !isNGlast (glyph);
426+ const auto isNGTop = isNGFunc (MESngFontListTop, *MESngFontListTopNumPtr);
427+
428+ const auto isNGLast = isNGFunc (MESngFontListLast, *MESngFontListLastNumPtr);
429+
430+
431+ const auto isLetter = [&isNGTop, &isNGLast](unsigned short glyph)->bool {
432+ return static_cast <int16_t >(glyph) > 0 && !isNGTop (glyph) && !isNGLast (glyph);
436433 };
437434
438- auto nextWord = [&isLetter](uint32_t &pos)->void {
435+ const auto nextWord = [&isLetter](uint32_t &pos)->void {
439436 int wordLen = 0 ;
440437 while (pos < *MEStextDatNumPtr && isLetter (MEStext[pos])) {
441438 MEStextFl[pos] = wordLen == 0 ? 0x0A : 0x0B ;
@@ -444,87 +441,79 @@ void MESsetNGflag::Callback(int nameNewline, int rubyEnabled) {
444441 MEStextFl[pos - 1 ] = wordLen == 1 ? 0x00 : 0x09 ;
445442 };
446443
447- int processingRuby = 0 ;
448- int processingRubyText = 0 ;
444+ bool processingRuby = false ;
445+ bool processingRubyText = false ;
449446 uint32_t pos = 0 ;
450447
451- const uint16_t nameStart = 0x8001 ;
452- const uint16_t nameEnd = 0x8002 ;
453-
454- if (MEStext[0 ] == nameStart) {
448+ if ((MEStext[0 ] & 0xFF ) == StringTokenType::CharacterNameStart) {
455449 MEStextFl[pos++] = 0x02 ;
456- while (MEStext[pos] != nameEnd) {
457- MEStextFl[pos] = 0x0B ;
458- pos++;
459- }
450+ while ((MEStext[pos] & 0xFF ) != StringTokenType::DialogueLineStart)
451+ MEStextFl[pos++] = 0x0B ;
460452 MEStextFl[pos++] = nameNewline ? 0x07 : 0x01 ;
461453 }
462454
463- while (pos < *MEStextDatNumPtr) {
464- unsigned short glyph = MEStext[pos];
465-
466- MEStextFl[pos] = 0 ;
467-
468- if (glyph & 0x8000 ) {
469- switch (glyph & 0xff ) {
470- case 0x00 :
471- MEStextFl[pos] = 0x07 ;
472- break ;
473- case 0x09 :
474- processingRuby = rubyEnabled;
475- MEStextFl[pos] = 0x02 ;
476- break ;
477- case 0x0a :
478- processingRubyText = rubyEnabled;
455+ while (pos < *MEStextDatNumPtr) {
456+ uint16_t glyph = MEStext[pos];
457+
458+ MEStextFl[pos] = 0 ;
459+
460+ if (glyph & 0x8000 ) {
461+ switch (glyph & 0xFF ) {
462+ case StringTokenType::LineBreak :
463+ MEStextFl[pos] = 0x07 ;
464+ break ;
465+ case StringTokenType::RubyBaseStart :
466+ processingRuby = rubyEnabled;
467+ MEStextFl[pos] = 0x02 ;
468+ break ;
469+ case StringTokenType::RubyTextStart :
470+ processingRubyText = rubyEnabled;
479471 MEStextFl[pos] = 0x0B ;
480- break ;
481- case 0x0b :
482- processingRuby = 0 ;
483- processingRubyText = 0 ;
484- MEStextFl[pos] = 0x01 ;
485- break ;
486- case 0x12 :
487- MEStextFl[pos] = 0x02 ;
488- break ;
489- case 0x1e :
490- MEStextFl[pos] = 0x0B ;
491- break ;
492- }
472+ break ;
473+ case StringTokenType::RubyTextEnd:
474+ processingRuby = processingRubyText = false ;
475+ MEStextFl[pos] = 0x01 ;
476+ break ;
477+ case StringTokenType::SetLeftMargin:
478+ MEStextFl[pos] = 0x02 ;
479+ break ;
480+ case StringTokenType::RubyCenterPerCharacter:
481+ MEStextFl[pos] = 0x0B ;
482+ break ;
483+ default :
484+ break ;
485+ }
493486 pos++;
494487 continue ;
495- }
496-
497- if (processingRubyText) {
498- MEStextFl[pos] = 0x1B ;
499- pos++;
500- } else if (processingRuby) {
501- MEStextFl[pos] = 0x0b ;
502- pos++;
503- } else if (isNGtop (glyph) && isNGlast (glyph)) {
504- MEStextFl[pos] = 0x01 | 0x02 ;
505- pos++;
506- } else if (isNGtop (glyph)) {
507- MEStextFl[pos] = 0x01 ;
488+ }
489+
490+ if (processingRubyText || processingRuby) {
491+ // processingRubyText -> 0x1B
492+ // processingRuby -> 0x0B
493+ MEStextFl[pos] = 0x0B | (processingRubyText << 4 );
508494 pos++;
509- } else if (isNGlast (glyph)) {
510- MEStextFl[pos] = 0x02 ;
495+ } else if (uint8_t topLast = isNGTop (glyph) | (isNGLast (glyph) << 1 )) {
496+ // NG top -> 0x01
497+ // NG last -> 0x02
498+ // NG both -> 0x03
499+ MEStextFl[pos] = topLast;
511500 pos++;
512501 } else {
513502 nextWord (pos);
514503 }
515- }
504+ }
516505
517- int lastLetter = 0 ;
506+ uint32_t lastLetter = 0 ;
518507
519- for (uint32_t i = 0 ; i < *MEStextDatNumPtr ; i++ ) {
520- if (MEStextFl[i] == 0x0B || MEStextFl[i] == 0x09 ) {
521- lastLetter = i;
522- }
508+ for (uint32_t i = *MEStextDatNumPtr - 1 ; i >= 0 ; i-- ) {
509+ if (MEStextFl[i] != 0x0B && MEStextFl[i] != 0x09 ) continue ;
510+ lastLetter = i;
511+ break ;
523512 }
513+
524514 for (uint32_t i = lastLetter; i < *MEStextDatNumPtr; i++) {
525- if (MEStextFl[i] != 0x07 ) {
526- MEStextFl[i] = 0x0B ;
527- }
515+ if (MEStextFl[i] == 0x07 ) continue ;
516+ MEStextFl[i] = 0x0B ;
528517 }
529518}
530519
0 commit comments