From a2e4b33742e9cb20d9e621cc763a0e2123d47a90 Mon Sep 17 00:00:00 2001 From: sup39 Date: Wed, 7 Feb 2024 20:34:27 +0900 Subject: [PATCH] feat: add PatternSelector --- PatternSelector/@code-data.txt | 8 + PatternSelector/@code.xml | 280 +++++++++++++++++++++++++++++ PatternSelector/info.xml | 88 +++++++++ PatternSelector/make.py | 34 ++++ PatternSelector/src/draw.s | 95 ++++++++++ PatternSelector/src/pattern-data.s | 25 +++ PatternSelector/src/selector.s | 77 ++++++++ 7 files changed, 607 insertions(+) create mode 100644 PatternSelector/@code-data.txt create mode 100644 PatternSelector/@code.xml create mode 100644 PatternSelector/info.xml create mode 100644 PatternSelector/make.py create mode 100644 PatternSelector/src/draw.s create mode 100644 PatternSelector/src/pattern-data.s create mode 100644 PatternSelector/src/selector.s diff --git a/PatternSelector/@code-data.txt b/PatternSelector/@code-data.txt new file mode 100644 index 0000000..af61b72 --- /dev/null +++ b/PatternSelector/@code-data.txt @@ -0,0 +1,8 @@ +077F0441 00000035 +452020FF 213200FF +621CFF1D 32005025 +25252630 01FF4520 +20213001 FFFF621C +1D300151 0707FF08 +3102FF36 01FF0231 +021E6E20 FF000000 diff --git a/PatternSelector/@code.xml b/PatternSelector/@code.xml new file mode 100644 index 0000000..25d0c0c --- /dev/null +++ b/PatternSelector/@code.xml @@ -0,0 +1,280 @@ + + qol + PatternSelector + Pattern Selector + パターン選択 + sup39(サポミク) + 0.4 + Jan 31, 2023 + drawText + + Ⓑ is the cursor to select the pattern, + and the three digits are the numbers representing the pattern. + See below for more information. + + | Combination | Result | + |---------------|-------------------------------------------------| + |L + D-Pad Left |Move cursor(Ⓑ) one digit to the left | + |L + D-Pad Right|Move cursor(Ⓑ) one digit to the right | + |L + D-Pad Up |Increase the number at the right of the cursor(Ⓑ)| + |L + D-Pad Down |Decrease the number at the right of the cursor(Ⓑ)| + + When the cursor(Ⓑ) is not shown, you can press L+D-Pad Left/Right to make it appear. + + You can change the position and color of the text [here](#PatternSelector-config). + + ### Chain Chomp (PV4) + + Use the [1st digit]{.emph} to select the pattern. The 2nd and 3rd are ignored. + + |1st digit|Direction at the beginning| + |:-------:|:------------------------:| + | 1 | ← | + | 2 | ↑ | + | 3 | → | + | o.w. | Random | + + ### Chain Chomplets (PV1) + Each digit represents the pattern of each Chain Chomplet. + Numbers not on the graph (e.g. 0) mean random. + + #### 1st digit + %object[]{data="/img/PatternSelector/PV1-1.svg"} + + #### 2nd digit + %object[]{data="/img/PatternSelector/PV1-2.svg"} + + #### 3rd digit + %object[]{data="/img/PatternSelector/PV1-3.svg"} + + + Ⓑはパターンを選択するためのカーソルであり、三つの数字はパターンの番号を表します。 + 各パターンの番号は下記を参照してください。 + + | ボタン | 動作 | + |--------------|------------------------------| + |L + 十字キー左|カーソル(Ⓑ)を左一桁に移動 | + |L + 十字キー右|カーソル(Ⓑ)を右一桁に移動 | + |L + 十字キー上|カーソル(Ⓑ)の右の数字を1増やす| + |L + 十字キー下|カーソル(Ⓑ)の右の数字を1減らす| + + カーソル(Ⓑ)が表示されない時、L+十字キー左/右を押せば出てきます。 + + [ここ](#PatternSelector-config)で文字の位置や色を変えることができます。 + + ### ワンワン(PV4) + + [1桁目]{.emph}でパターンを選択します。2桁目と3桁目は無視されます。 + + | 1桁目 | 最初の向き | + |:-------:|:----------:| + | 1 | ← | + | 2 | ↑ | + | 3 | → | + | その他 | ランダム | + + ### キャンキャン(PV1) + 各桁は各キャンキャンのパターンを表します。図上にない数字(例えば0)はランダムを表します。 + + #### 1桁目 + %object[]{data="/img/PatternSelector/PV1-1.svg"} + + #### 2桁目 + %object[]{data="/img/PatternSelector/PV1-2.svg"} + + #### 3桁目 + %object[]{data="/img/PatternSelector/PV1-3.svg"} + + + C224F32C 00000013 + 801F0000 3D80817F + 61880440 618A0024 + 6C0C803D 280CA9C0 + 41820054 6C0C803D + 280C87C0 40820034 + 819F0004 898C0013 + 508C442E 39280031 + 88080007 7CEA00AE + A0080005 7C006040 + 41820034 39080007 + 7C084840 4180FFE4 + 3D808026 618C0224 + 7D8803A6 4E800021 + 4800002C 2C05FFFF + 4082FFE8 88EA0000 + 39080031 7CE73B79 + 4182FFD8 7C0838AE + 280000FF 4182FFCC + 7C030378 00000000 + C22069DC 00000019 + 3C60817F 60630410 + 38830010 3D808020 + 618C1EA8 7D8803A6 + 4E800021 3C808040 + A4040D82 3C60817F + 85630024 70000040 + 41A20050 88840019 + 548007FE 7D605850 + 5480FFFE 7D6B0214 + 556B07BE 5480F7BF + 41A20030 280B0003 + 41A00008 39600000 + 5480EFFE 5080077A + 7D8358AE 7D8C0214 + 280C0005 41A00008 + 398CFFFB 7D8359AE + 99630003 3C002020 + 60002023 556C183E + 5C00603E 5405063E + 5407C63E 5409863E + 88C30000 89030001 + 89430002 3D80817F + 61830424 61840434 + 618C0238 7D8803A6 + 4E800021 00000000 + + + C203B6FC 00000013 + 801F0000 3D80817F + 61880440 618A0024 + 6C0C803B 280C6178 + 41820054 6C0C803B + 280C3F88 40820034 + 819F0004 898C0013 + 508C442E 39280031 + 88080007 7CEA00AE + A0080005 7C006040 + 41820034 39080007 + 7C084840 4180FFE4 + 3D808004 618CD0D4 + 7D8803A6 4E800021 + 4800002C 2C05FFFF + 4082FFE8 88EA0000 + 39080031 7CE73B79 + 4182FFD8 7C0838AE + 280000FF 4182FFCC + 7C030378 00000000 + C21441BC 00000019 + 3C60817F 60630410 + 38830010 3D808014 + 618C0390 7D8803A6 + 4E800021 3C808040 + A4044486 3C60817F + 85630024 70000040 + 41A20050 88840019 + 548007FE 7D605850 + 5480FFFE 7D6B0214 + 556B07BE 5480F7BF + 41A20030 280B0003 + 41A00008 39600000 + 5480EFFE 5080077A + 7D8358AE 7D8C0214 + 280C0005 41A00008 + 398CFFFB 7D8359AE + 99630003 3C002020 + 60002023 556C183E + 5C00603E 5405063E + 5407C63E 5409863E + 88C30000 89030001 + 89430002 3D80817F + 61830424 61840434 + 618C0238 7D8803A6 + 4E800021 00000000 + + + C203B54C 00000013 + 801F0000 3D80817F + 61880440 618A0024 + 6C0C803A 280CDF98 + 41820054 6C0C803A + 280CBDA8 40820034 + 819F0004 898C0013 + 508C442E 39280031 + 88080007 7CEA00AE + A0080005 7C006040 + 41820034 39080007 + 7C084840 4180FFE4 + 3D808004 618CC228 + 7D8803A6 4E800021 + 4800002C 2C05FFFF + 4082FFE8 88EA0000 + 39080031 7CE73B79 + 4182FFD8 7C0838AE + 280000FF 4182FFCC + 7C030378 00000000 + C2138DF8 00000019 + 3C60817F 60630410 + 38830010 3D808013 + 618C4F0C 7D8803A6 + 4E800021 3C808040 + A404BC26 3C60817F + 85630024 70000040 + 41A20050 88840019 + 548007FE 7D605850 + 5480FFFE 7D6B0214 + 556B07BE 5480F7BF + 41A20030 280B0003 + 41A00008 39600000 + 5480EFFE 5080077A + 7D8358AE 7D8C0214 + 280C0005 41A00008 + 398CFFFB 7D8359AE + 99630003 3C002020 + 60002023 556C183E + 5C00603E 5405063E + 5407C63E 5409863E + 88C30000 89030001 + 89430002 3D80817F + 61830424 61840434 + 618C0238 7D8803A6 + 4E800021 00000000 + + + C2027900 00000013 + 801F0000 3D80817F + 61880440 618A0024 + 6C0C803A 280C6D70 + 41820054 6C0C803A + 280C4B80 40820034 + 819F0004 898C0013 + 508C442E 39280031 + 88080007 7CEA00AE + A0080005 7C006040 + 41820034 39080007 + 7C084840 4180FFE4 + 3D808003 618C8684 + 7D8803A6 4E800021 + 4800002C 2C05FFFF + 4082FFE8 88EA0000 + 39080031 7CE73B79 + 4182FFD8 7C0838AE + 280000FF 4182FFCC + 7C030378 00000000 + C2125548 00000019 + 3C60817F 60630410 + 38830010 3D808012 + 618C1660 7D8803A6 + 4E800021 3C80803F + A404545A 3C60817F + 85630024 70000040 + 41A20050 88840019 + 548007FE 7D605850 + 5480FFFE 7D6B0214 + 556B07BE 5480F7BF + 41A20030 280B0003 + 41A00008 39600000 + 5480EFFE 5080077A + 7D8358AE 7D8C0214 + 280C0005 41A00008 + 398CFFFB 7D8359AE + 99630003 3C002020 + 60002023 556C183E + 5C00603E 5405063E + 5407C63E 5409863E + 88C30000 89030001 + 89430002 3D80817F + 61830424 61840434 + 618C0238 7D8803A6 + 4E800021 00000000 + + diff --git a/PatternSelector/info.xml b/PatternSelector/info.xml new file mode 100644 index 0000000..49a5b4d --- /dev/null +++ b/PatternSelector/info.xml @@ -0,0 +1,88 @@ + + qol + PatternSelector + Pattern Selector + パターン選択 + sup39(サポミク) + 0.4 + Jan 31, 2023 + drawText + + Ⓑ is the cursor to select the pattern, + and the three digits are the numbers representing the pattern. + See below for more information. + + | Combination | Result | + |---------------|-------------------------------------------------| + |L + D-Pad Left |Move cursor(Ⓑ) one digit to the left | + |L + D-Pad Right|Move cursor(Ⓑ) one digit to the right | + |L + D-Pad Up |Increase the number at the right of the cursor(Ⓑ)| + |L + D-Pad Down |Decrease the number at the right of the cursor(Ⓑ)| + + When the cursor(Ⓑ) is not shown, you can press L+D-Pad Left/Right to make it appear. + + You can change the position and color of the text [here](#PatternSelector-config). + + ### Chain Chomp (PV4) + + Use the [1st digit]{.emph} to select the pattern. The 2nd and 3rd are ignored. + + |1st digit|Direction at the beginning| + |:-------:|:------------------------:| + | 1 | ← | + | 2 | ↑ | + | 3 | → | + | o.w. | Random | + + ### Chain Chomplets (PV1) + Each digit represents the pattern of each Chain Chomplet. + Numbers not on the graph (e.g. 0) mean random. + + #### 1st digit + %object[]{data="/img/PatternSelector/PV1-1.svg"} + + #### 2nd digit + %object[]{data="/img/PatternSelector/PV1-2.svg"} + + #### 3rd digit + %object[]{data="/img/PatternSelector/PV1-3.svg"} + + + Ⓑはパターンを選択するためのカーソルであり、三つの数字はパターンの番号を表します。 + 各パターンの番号は下記を参照してください。 + + | ボタン | 動作 | + |--------------|------------------------------| + |L + 十字キー左|カーソル(Ⓑ)を左一桁に移動 | + |L + 十字キー右|カーソル(Ⓑ)を右一桁に移動 | + |L + 十字キー上|カーソル(Ⓑ)の右の数字を1増やす| + |L + 十字キー下|カーソル(Ⓑ)の右の数字を1減らす| + + カーソル(Ⓑ)が表示されない時、L+十字キー左/右を押せば出てきます。 + + [ここ](#PatternSelector-config)で文字の位置や色を変えることができます。 + + ### ワンワン(PV4) + + [1桁目]{.emph}でパターンを選択します。2桁目と3桁目は無視されます。 + + | 1桁目 | 最初の向き | + |:-------:|:----------:| + | 1 | ← | + | 2 | ↑ | + | 3 | → | + | その他 | ランダム | + + ### キャンキャン(PV1) + 各桁は各キャンキャンのパターンを表します。図上にない数字(例えば0)はランダムを表します。 + + #### 1桁目 + %object[]{data="/img/PatternSelector/PV1-1.svg"} + + #### 2桁目 + %object[]{data="/img/PatternSelector/PV1-2.svg"} + + #### 3桁目 + %object[]{data="/img/PatternSelector/PV1-3.svg"} + + diff --git a/PatternSelector/make.py b/PatternSelector/make.py new file mode 100644 index 0000000..fc9460f --- /dev/null +++ b/PatternSelector/make.py @@ -0,0 +1,34 @@ +from supSMSGecko import build, make_xml, symbols + +extra_ld_input = ''' +drawText = 0x817f0238; + +/** struct {u8 patterns[3], u8 cursor} */ +$patterns = 0x817f0024; + +/* size = 0x14 */ +$rectOpt = 0x817f0410; + +/* size = 0x10 */ +$textOpt = 0x817f0424; + +/* size = 13 "%c%X%c%X%c%X" */ +$fmt = 0x817f0434; + +/* size = 53 */ +$data = 0x817f0441; +''' + +def main(g, ver): + S = symbols[ver] + g.C2(S['TSpineEnemy_goToRandomNextGraphNode'] + 0x50, 'src/selector.s', extra_ld_input=extra_ld_input) + g.C2(S['drawWater'] - 0x24, 'src/draw.s', extra_ld_input=extra_ld_input) + +def main_data(g, ver): + g.c_kit(0x817f0441, 'src/pattern-data.s', entries=[]) + +# compile main code to @code.xml +make_xml(main) +# compile pattern-data.s to @code-data.txt +with open('@code-data.txt', 'w') as fw: + print(build(main_data, 'GMSJ01').dump_txt(''), file=fw) diff --git a/PatternSelector/src/draw.s b/PatternSelector/src/draw.s new file mode 100644 index 0000000..b1b75ba --- /dev/null +++ b/PatternSelector/src/draw.s @@ -0,0 +1,95 @@ +.set rPats, 3 +.set rPad, 4 +.set rCS, 11 +.set btnMask, 0x40 # L + +.draw2d: + +### check stage +# lis r3, gpApplication+0xE@ha +# lhz r3, gpApplication+0xE@l(r3) +# cmplwi r3, 0x0800 +# cmplwi cr1, r3, 0x0803 +# cror 4*cr0+eq, 4*cr0+eq, 4*cr1+eq +# bne .draw2d.done + +.draw.background: + lis r3, 0x817F + ori r3, r3, $rectOpt@l + addi r4, r3, 0x10 + lis r12, fill_rect@h + ori r12, r12, fill_rect@l + mtlr r12 + blrl + +.update.state: + lis rPad, mPadButton+2@ha + lhzu r0, mPadButton+2@l(rPad) + lis rPats, $patterns@h + lwzu rCS, $patterns@l(rPats) # cs = [3] +### L is pressed + andi. r0, r0, btnMask + beq+ .update.state.end +## rPad = effective D-Pad + lbz rPad, -2+0x18+3(rPad) +.update.cursor: + rlwinm r0, rPad, 0, 0x1 # DL + sub rCS, rCS, r0 # -1 + rlwinm r0, rPad, 32-1, 0x1 # DR + add rCS, rCS, r0 # +1 + rlwinm rCS, rCS, 0, 0x3 # %4 +.update.patterns: + rlwinm. r0, rPad, 32-2, 0x3 # DU,DD + beq+ .update.state.end +## cursor = 0 if < 3 + cmplwi rCS, 3 + blt+ .update.cs3.end + li rCS, 0 +.update.cs3.end: +## r0 = diff + rlwinm r0, rPad, 32-3, 0x1 # DU>>3 +1 + rlwimi r0, rPad, 0, 0x4 # DD>>2<<2 +4 +## r12 = patterns[cs] + lbzx r12, rPats, rCS + add r12, r12, r0 # patterns[cs] += diff +## pattern %= 5 + cmplwi r12, 5 + blt+ .update.pat5.end + addi r12, r12, -5 +.update.pat5.end: +## store + stbx r12, rPats, rCS +.update.state.end: + stb rCS, 3(rPats) + +.draw: +## cursor + .set magic, 0x20202023 + #.set magic, 0x4040409a ## star + #.set magic, 0x404040a8 ## right arrow + #.set magic, 0x2020207d ## right arrow (EU) + lis r0, magic@h + ori r0, r0, magic@l +### 1st digit + rlwinm r12, rCS, 3, 0, 31 # r12 = rCS*8 + rlwnm r0, r0, r12, 0, 31 # r0 = cursor value (24 bit) + rlwinm r5, r0, 0, 0xFF # 1st cursor +### 2nd digit + rlwinm r7, r0, 32-8, 0xFF # 2nd cursor: rotate right 8 +### 3rd digit + rlwinm r9, r0, 32-16, 0xFF # 3rd cursor: rotate right 16 +## patterns + lbz r6, 0(rPats) + lbz r8, 1(rPats) + lbz r10, 2(rPats) +## params + lis r12, 0x817F + ori r3, r12, $textOpt@l + ori r4, r12, $fmt@l + ori r12, r12, drawText@l + mtlr r12 + blrl + +.draw2d.done: + +# vi:se ft=asm: diff --git a/PatternSelector/src/pattern-data.s b/PatternSelector/src/pattern-data.s new file mode 100644 index 0000000..323e9f4 --- /dev/null +++ b/PatternSelector/src/pattern-data.s @@ -0,0 +1,25 @@ +.set .sizeof.entry.PV1, 7 +.data.patterns.PV1: +/** next[4], cur, name[19], pid */ + /**** case '2' ****/ + /* 33: up, right */ + .byte 69, 32, 32, -1, 33, 0x32, 0 + /* 29: up, right */ + .byte -1, 98, 28, -1, 29, 0x32, 0 + /**** case '0' ****/ + /* 38: up, right */ + .byte 80, 37, 37, 37, 38, 0x30, 1 + /* 33: up, right */ + .byte -1, 69, 32, 32, 33, 0x30, 1 + /* 29: up, right */ + .byte -1, -1, 98, 28, 29, 0x30, 1 + /**** case '1' ****/ + /* 8: down, left */ + .byte 81, 7, 7, -1, 8, 0x31, 2 + /* 2: down, left */ + .byte -1, 54, 1, -1, 2, 0x31, 2 +.data.patterns.PV1.end: + +.data.patterns.PV4: + /* left, middle, right */ + .byte 30, 110, 32, -1 diff --git a/PatternSelector/src/selector.s b/PatternSelector/src/selector.s new file mode 100644 index 0000000..2010b29 --- /dev/null +++ b/PatternSelector/src/selector.s @@ -0,0 +1,77 @@ +.set .data.PV1.entrySize, 7 +.set .data.PV1.entryCount, 7 +.set .data.PV1.size, .data.PV1.entrySize * .data.PV1.entryCount +.set .data.PV4.offset, .data.PV1.size + +## Do not change r3~r6 for fallback function call +.set rCur, 4 +.set rPrev, 5 +.set rPid, 7 +.set rEntry, 8 # offset of pattern entry +.set rEntryEnd, 9 +.set rPats, 10 + +.getRandomNextIndex: +## r0 = vt + lwz r0, 0(r31) + lis r12, 0x817F + ori rEntry, r12, $data-1@l + ori rPats, r12, $patterns@l +### PV4 + xoris r12, r0, TBossWanwan___vt@h + cmplwi r12, TBossWanwan___vt@l + beq .getRandomNextIndex.PV4 +### PV1 + xoris r12, r0, TFireWanwan___vt@h + cmplwi r12, TFireWanwan___vt@l + bne .fallback +.getRandomNextIndex.PV1: +## r12 = (curIdx, name[19]) + lwz r12, 4(r31) # name + lbz r12, 19(r12) # name[19] + rlwimi r12, rCur, 8, 0x10, 0x17 +## foreach entry + addi rEntryEnd, rEntry, .data.PV1.size +.getRandomNextIndex.PV1.loop: +### pid + lbz r0, 1+6(rEntry) + lbzx rPid, rPats, r0 +### check id + lhz r0, 1+4(rEntry) + cmplw r0, r12 + beq- .getRandomNextIndex.result + addi rEntry, rEntry, .data.PV1.entrySize + cmplw rEntry, rEntryEnd + blt+ .getRandomNextIndex.PV1.loop + +.fallback: + lis r12, getRandomNextIndex@h + ori r12, r12, getRandomNextIndex@l + mtlr r12 + blrl + b .getRandomNextIndex.done + +.getRandomNextIndex.PV4: +## handle initial node only + cmpwi rPrev, -1 + bne+ .fallback +## use patterns[0] + lbz rPid, 0(rPats) + addi rEntry, rEntry, .data.PV4.offset +## DONE + #b .getRandomNextIndex.result + +.getRandomNextIndex.result: +## if pid == 0, goto fallback + mr. rPid, rPid # TODO pid>4 + beq .fallback +## ans = patterns[idx][pid-1] = entry[pid] + lbzx r0, rEntry, rPid + cmplwi r0, 255 # invalid + beq .fallback +## valid result (r0) as return value (r3) + mr r3, r0 + +.getRandomNextIndex.done: + +# vi:se ft=asm: