-
Notifications
You must be signed in to change notification settings - Fork 3
/
faq.html
871 lines (789 loc) · 47.5 KB
/
faq.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
{{define "<q>"}}<section id="{{.}}"><a href="#{{.}}">🔗</a><h3>{{end}}
{{define "</q>"}}</section>{{end}}
<h2>FAQ</h2>
{{template "<q>" "what"}}
What is this about?
</h3>
<p>
For now, the aim is to perfectly reconstruct the lost<sup>[citation
needed]</sup> source code of the first five
<a href="https://en.wikipedia.org/wiki/Touhou_Project">Touhou Project</a>
games by <i>ZUN Soft</i> (now <i>Team Shanghai Alice</i>), which were
originally released exclusively for the NEC PC-9801 platform.
</p><p>
The original games being:
</p><dl>
<dt>TH01:</dt>
<dd>
<span lang="ja">東方靈異伝 ~ </span>
The Highly Responsive to Prayers (1997)
</dd>
<dt>TH02:</dt>
<dd>
<span lang="ja">東方封魔録 ~ </span>
the Story of Eastern Wonderland (1997)
</dd>
<dt>TH03:</dt>
<dd>
<span lang="ja">東方夢時空 ~ </span>
Phantasmagoria of Dim.Dream (1997)
</dd>
<dt>TH04:</dt>
<dd>
<span lang="ja">東方幻想郷 ~ </span>
Lotus Land Story (1998)
</dd>
<dt>TH05:</dt>
<dd>
<span lang="ja">東方怪綺談 ~ </span>
Mystic Square (1998)
</dd>
</dl><p>
Since we only have the binaries, we obviously can't know how ZUN named any
variables and functions, and which comments the original code was
surrounded with. <i>Perfect</i> therefore means that the binaries compiled
from the code in the <a href="https://github.com/nmlgc/ReC98">ReC98
repository</a> are <a href="https://github.com/nmlgc/mzdiff">
indistinguishable</a> from ZUN's original builds, making it impossible to
<i>disprove</i> that the original code <i>couldn't</i> have looked like
this. This property is maintained for every Git commit along the way.
</p><p>
Aside from the preservation angle and the resulting deep insight into the
games' mechanics, the code can then serve as the foundation for any type
of mod, or any port to non-PC-98 platforms, developed by the community.
</p>
{{template "</q>"}}
{{template "<q>" "who"}}Who are you?</h3>
<p>
I created the <a href="https://github.com/thpatch/thcrap">Touhou Community
Reliant Automatic Patcher</a> and <a href="https://thpatch.net">Touhou
Patch Center</a> in 2012, and remained a core developer of both before
retiring in March 2019. Older Touhou fans might also remember me for
<i>Touhou Music Room</i> (2010/2011) and the <i>Touhou Vorbis
Compressor</i> (2011).
</p><p>
Check my <a href="https://github.com/nmlgc">GitHub page</a> as well as the
<a href="/fundlog">crowdfunding log</a> here for more proof of my track
record.
</p>
{{template "</q>"}}
{{template "<q>" "three"}}
What's the split between <code>OP</code>, <code>MAIN</code> and
<code>MAINE</code>? What things are they responsible for? How do they
interact with each other?
</h3>
<ul><li>
<code>OP.EXE</code> contains the game's main menu and all other menus
reachable from there. In TH04 and TH05, it also contains the <i>ZUN
Soft</i> animation and the initial sound configuration menu. As a modder,
you'd care about this file if you want to add anything involving new
menus, like practice modes or a replay selection.
</li><li>
As soon as you start the game, you're in <code>MAIN.EXE</code>
(<code>REIIDEN.EXE</code> for TH01). As the biggest executable, it handles
everything happening within a stage. Most notably, boss behavior – unlike
the Windows games, where this is stored in the separate
<a href="https://en.touhouwiki.net/wiki/User:Mddass/Touhou_File_Format_Specification/ECL">
ECL script files, found in the main <code>.dat</code> archive</a>.
</li><li>
<code>MAINE.EXE</code> (<code>FUUIN.EXE</code> for TH01,
<code>MAINL.EXE</code> for TH03) then contains code for the ending
cutscenes, the staff roll, and anything after that. In TH03, it also
contains the stage start and end screens with the character pictures, as
well as the cutscenes before stages 8 and 9.
</li></ul><p>
Since only one executable can be active at any given time, there has to be
some way of sharing data between them. This is done using a resident
<code>"Config"</code> structure, kept at the top of conventional DOS RAM.
{{Blog_PostLink "2020-02-23" "As of 2020-02-23"}}, we've
reverse-engineered the contents of this structure for all 5 games.
(<a href="https://github.com/nmlgc/ReC98/blob/e0d90dbdc39941d775d5b38cbef33fd56522d846/th01/th01.h#L43">TH01</a>,
<a href="https://github.com/nmlgc/ReC98/blob/aa56a7cb18881fbc602c0324b727c1578cac825e/th02/th02.h#L224">TH02</a>,
<a href="https://github.com/nmlgc/ReC98/blob/484730e31969e55eb590dea6051641532dffb7c5/th03/resident.hpp">TH03</a>,
<a href="https://github.com/nmlgc/ReC98/blob/042b7802bf070aede7f67d9aaec91f9b8e80c971/th04/resident.hpp">TH04</a>,
<a href="https://github.com/nmlgc/ReC98/blob/042b7802bf070aede7f67d9aaec91f9b8e80c971/th05/resident.hpp">TH05</a>)
</p>
{{template "</q>"}}
{{template "<q>" "pi-what"}}
What is this "position independence" thing about?
</h3>
<p>
Position <i>dependence</i> means that a binary's references to global
variables are expressed as raw number constants, rather than being named
with identifiers:
</p><pre>mov ax, some_data ; Position-independent
mov ax, 1234h ; Position-dependent; assumes that
; [some_data] is at address 1234h
</pre><p>
If you increase or decrease the number of bytes anywhere in the non-header
parts of an executable, you'll end up breaking most of these
position-dependent references, since global variables no longer are where
the game expects them to be. This will lead to quite some instability.
</p><p>
Now, why is this such an issue for PC-98 Touhou? 16-bit x86 code has to
take <a href="https://en.wikipedia.org/wiki/X86_memory_segmentation">
segmentation</a> into account for all its memory accesses. This means that
each actual address is built out of two 16-bit values, the <i>segment</i>
and the <i>offset</i>. Since offsets therefore can only range from 0 to
2<sup>16</sup>-1, the line between actual memory offsets and numeric
constants becomes blurred. Most disassemblers I know of that target this
architecture therefore only do a very superficial attempt at identifying
data references, and give up once arrays are involved, just leaving a
numeric constant in place of such a reference. And for good reason: Doing
this properly effectively requires an emulator, running the game and
performing control flow analysis. Anything less than that –
<i>especially</i> anything parsing individual lines of ASM – and you're
bound to
</p><ul>
<li>miss addresses that are <i>calculated</i> from other constants</li>
<li>mistake function pointers for data pointers</li>
<li>mistake pointers into special memory segments (graphics RAM, BIOS RAM,
etc.) for data pointers</li>
<li>or confuse <i>actual</i> numeric constants for memory addresses.
</ul><p>
And even <i>with</i> an emulator, you're still faced with the fact that on
the low level of ASM and C,
<a href="https://www.youtube.com/watch?v=i2fhNVQPb5I&t=43s">the declared
size of an array is simply advisory anyway</a>. So what do you put,
especially when being confronted with out-of-bounds array access bugs in
the original game itself?
</p><p>
So if you've chosen to deliver quality instead of delivering experimental
research, the best choice is to give up, don't pretend to be
position-independent in the first place, and treat <i>every</i> numeric
constant that falls within the range of any data segment as a possible
memory reference. Sure, this means that the <i>actual</i> number of memory
references are lower, and thus, the actual percentage of
position-independence is higher than the front page may suggest. But
<i>we can't tell</i>, and erring on the side of caution is, in my opinion,
better than pretending that the code is more position-independent than it
actually is, just because it ran through some sort of experimental tool.
</p><p>
While position-dependent code is still a significant step up from modding
game binaries via hex-editing, it effectively still suffers from most of
the same constraints, despite looking like regular source code that you
can just arbitrarily edit and recompile. So while modding the game in all
sorts of ways is definitely <i>possible</i> right now, it's definitely
harder than it needs to be. Once a binary reaches 100% position
independence though, developing any sort of mod, in either C/C++ or ASM,
will become trivial.
</p>
{{template "</q>"}}
{{template "<q>" "pi-how"}}
How is position independence calculated?
</h3>
<p>
The <a href="/progress">absolute number</a> is the sum of all remaining
hexadecimal literals in all code segments of a binary's big
<kbd>.asm</kbd> dump file that fall into all of these categories:
</p><h4>
1) Matches the regex <code>(-?[0-9][0-9a-fA-F]{1,4})h</code> for
hexadecimal literals in TASM/MASM syntax
</h4><p>
IDA dumps all number literals ≥10 as hex by default. Restricting the PI
calculation to hex numbers allows us to clearly mark false positives by
simply converting those numbers to decimal. Having to do this manually
further communicates that every such conversion was a conscious decision,
based on the newly RE'd context the number is used in.
</p><p>
This might seem like useless work at first, only necessary because it's
dictated by some counting algorithm on a website. However, most of those
false positives turn out to be things like (sub)pixel coordinates, number
of score points, frame counts… which the typical person <i>does</i> prefer
and expect to be expressed in decimal. Thus, this conversion turns into
quite a quality-of-life improvement for anyone reading and modding the
code. <i>Especially</i> with the fixed-point 12.4 "subpixel" type used for
playfield-space coordinates in TH03-TH05, which we can abstract away even
at the ASM level.
</p><h4>
2) Falls within the <a href="https://github.com/nmlgc/rec98.nmlgc.net/blob/43a9f1d51602eeb224a55ffeb384f2ad12d20798/rec98repo.go#L160">
data segment ranges occupied by ZUN data</a>
</h4><p>
This means that <i>structure size independence</i> is an explicit non-goal
of PI. The reason becomes clear if you look at all the things a 16-bit
number literal can represent:
</p><figure>
<embed src="{{call $.StaticFileURL "faq-pi-ranges.svg"}}" alt="Value ranges" />
</figure><p>
If we don't limit the value range to ZUN data,
<a href="https://en.wikipedia.org/wiki/Benford%27s_law">all the low
numbers</a> would vastly drown out the actual memory references we are
trying to identify, resulting in a number that's even less representative
of the code's actual position independence. And since structures can have
any size, we'll necessarily have to leave them to reverse-engineering.
</p><h4>
3) Not the argument to any x86 instruction unrelated to memory accesses
</h4><p>
These include
</p><ul>
<li>the I/O port instructions <code>IN</code> and <code>OUT</code> (which
take architecture-specific port numbers),</li>
<li><code>INT</code> (which takes a software interrupt number),</li>
<li>and <code>ENTER</code> (which takes the size of a function's stack
allocation for local variables).</li>
</ul>
{{template "</q>"}}
{{template "<q>" "why"}}
Why crowdfunding?
</h3>
<p>
I'm trying to steadily grow this project into an actual job so that I can
spend more time working on it. Even though I don't particularly <i>like</i>
Touhou these days, I can do a much better job here than in any corporate RL
software development position, where I am typically limited by people, dumb
tech stacks, and the fact that ReC98 is just a much more interesting project
in general. The demand on part of the fandom is also clearly there, as
evidenced by the success of this crowdfunding and this store being sold out
for almost the entirety of 2021.
</p><p>
Another advantage: It's <i>you</i>, the patrons, who then get to choose
which game I focus on. This has always felt wrong for me to decide, and I've
never had much of a preference for a specific game to begin with.
</p>
{{template "</q>"}}
{{template "<q>" "automate"}}
Can't a machine automate all this work? It all seems very blue-collar and
mechanical.
</h3>
<p>
Maybe. While it would have been an option to collect lots of money for
developing an automated decompilation solution, that would have been a
huge risk, and my previous attempts at it failed spectacularly. In
contrast, selling small chunks of progress for an hourly wage leads to a
stream of tiny, but immediate results. It may take longer in the end, but
even partially reverse-engineered game code can be a tremendous help to
modders. Also, naming variables, contextualizing numeric constants, and the
resulting insights into the game mechanics, is something you simply can't
get out of an automated solution.
</p><p>
Consider this piece of ASM:
</p><pre>; Somewhere…
mov byte_2CEC2, 40
; Somewhere else…
cmp byte_25351, 0
jz @@return_from_function
; …
cmp byte_2CEC2, 0
jz @@down
cmp byte_2CEC2, 32
jbe @@return_from_function
mov byte_2CEC2, 0
; …
@@down:
dec byte_25351
</pre><p>
Now, I could simply decompile this into
</p><pre>// Somewhere…
byte_2CEC2 = 40;
// Somewhere else…
if(byte_25351 == 0) {
return;
}
; …
if(byte_2CEC2 != 0) {
if(byte_2CEC2 <= 32) {
return;
}
byte_2CEC2 = 0;
}
byte_25351--;
</pre><p>
However, that doesn't really tell you anything that you couldn't already
tell from looking at the assembly. After manually reverse-engineering
the meaning of these variables, we learn that
</p><ul>
<li><code>byte_2CEC2</code> is the <i>miss countdown</i> – set to 40 if
you collide with anything, playing an explosion animation while it's
nonzero, then decremented each frame, and actually removing the life once
it <i>reaches</i> zero</li>
<li>and that <code>byte_25351</code> is the number of bombs in stock.</li>
</ul><p>
And lo and behold, we just proved the existence of an 8-frame deathbomb
window,
<a href="https://twitter.com/ReC98Project/status/1176592461155713026">
ending up with an insight that's immediately valuable to many fans</a>.
Finally, let's define some symbols:
</p><pre>MISS_FRAMES = 32
DEATHBOMB_WINDOW = 8
; Somewhere…
mov _miss_time, MISS_FRAMES + DEATHBOMB_WINDOW
; Somewhere else…
cmp _bombs, 0
jz @@return_from_function
; …
cmp _miss_time, 0
jz @@down
cmp _miss_time, MISS_FRAMES
jbe @@return_from_function
mov _miss_time, 0
; …
@@down:
dec _bombs
</pre><p>
And suddenly, it becomes both obvious <i>and easily moddable</i> to
whoever reads the code, even while it's still assembly. <i>This is the
level I operate at.</i> Decompilation only becomes mere syntactic sugar
at this point.
</p>
{{template "</q>"}}
{{template "<q>" "duration"}}
How long is this crowdfunding campaign going to run?
</h3>
<p>
Indefinitely – and that's the beauty of it. Whenever someone is
interested, they can insert a coin, and see how that money gets turned into
tangible progress towards their goal of choice. Effectively, this project
will run for as long as the market deems it valuable. Maybe we get enough to
complete one game, maybe we won't. Maybe there will be no interest
whatsoever for a few months, and then a small number of big transactions.
Who knows.
</p><p>
In a way, this is therefore closer to art commissions than it is to your
typical video game crowdfunding campaign.
</p>
{{template "</q>"}}
{{template "<q>" "prices"}}
How does pricing work? What is a "push"?
</h3>
<p>
A push is a reasonably long stretch of work towards a given goal, currently
sold for {{HTML_PushPrice}} a piece. You can purchase any partial amount of
that sum of money though – and definitely should, if only just to signal
your interest in a particular goal to the wider community and maybe drum up
more support for it. However, any goal requires at least one fully funded
push first before I start working on it. This approach works well with
reverse-engineering, as it ensures that I get to concentrate on newly RE'd
code for a while, leading to more accurate picture of the details and
interactions and keeping the high standard that this project has developed
over the years.
</p><p>
Smaller stretches of work do make sense for modding-related goals and Seihou
though. For these goals, you can bypass the regular push system via
<i>microtransactions</i>, and get immediate deliveries of any small piece of
work without the upfront investment of a full push.
{{template "</q>"}}
{{template "<q>" "dosbox-x"}}
PC-98 emulation is getting better and better, DOSBox-X even has dynamic
recompilation now. Are source ports of a single game series even worth it?
</h3>
<p>
Again, you decide.
</p>
{{template "</q>"}}
{{template "<q>" "recomp"}}
The N64 community is doing <i>recompilations</i> now. Aren't decompilations outdated?
</h3>
<p>
I’d just like to interject for a moment. What you’re referring to as "N64 recompilation", is in fact, a combination of five different efforts developed in parallel by the N64 community over many years:
</p><ol start="0">
<li>Emulators that define the hardware's behavior in software and can accurately run the game</li>
<li>A renderer that takes N64 display lists and microcode and produces modern HD images</li>
<li>Bugfix and quality-of-life patches developed as a result of reverse-engineering the game</li>
<li>A runtime that splits apart the individual subsystems of N64 hardware (i.e., graphics, sound, and peripherals) into standalone modules with their own APIs that can run independently from the CPU and the hardware's interfaces</li>
<li>The raw decompiler from MIPS assembly instructions into (unreadable) C</li>
</ol><p>
The bare minimum features required for such a recompilation port are 3) and 4). Recompilation in the pure meaning of the word – raw translation of one assembly language to another – provides exactly one benefit to players, and that's reducing system requirements by cutting out CPU emulation. The CPU is an essential part of a console, but useless by itself; it can only play games in the context of further graphics, sound, and input hardware, provided by the runtime.<br />
So if all you had was a recompiler and a hardware runtime, you'd get… exactly the original game running at the original resolution and the original frame rate, just maybe with reduced loading times. If all you care about is <i>a</i> native port, recompilation does indeed accelerate the process by freeing port authors from the need to bother with game logic. But from a player's point of view, such a port looks barely any different from the game being wrapped into a standalone emulator. And the further back in gaming history you go, the less value such a recompilation can provide, as typical emulators for older systems have long been able to run these games at full speed on modern hardware anyway.
</p><p>
Thus, it's actually 1) that delivers most of the perceived value of these ports. So much of it, in fact, that branding them as <i>recompilations</i> takes all the justified hype and excitement about how all these community efforts have been coming together, and redirects it to its least important component. A glance into the comment sections confirms that the average fan now thinks that <i>"recompilation"</i> means <i>"magic instant porting box for a system's entire library"</i> and is already expecting legal action from Nintendo, without understanding that this is legally no different from regular emulation. But how can you blame them if everyone in these videos is saying <q>no emulation</q> as if, again, the N64 solely consisted of its CPU?<br />
From what I can tell, recompiling the game wasn't even necessary to achieve the high frame rates, which instead are the result of <a href="https://github.com/rt64/rt64/tree/e4af592195bf1903df9d58e2b350e8183fb0e9ef?tab=readme-ov-file#architecture">lots of clever processing, optimization, and interpolation in the renderer itself</a>. This code always runs natively on the host CPU and GPU regardless of whether it's an <a href="https://x.com/dariosamo/status/1532736513183731713">emulator plugin</a> or linked into a recompiled game. Meanwhile, even a recompiled game has to run its logic at the original frame rate to avoid bugs.
</p><p>
<img
src="data:image/png;base64,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"
alt="Mima's sprite from TH05, 4× upscaled using the classic XBRz algorithm"
style="float: right;"
/>
And <i>that's</i> why we're now seeing all these developments for an early 3D console, and not for an undoubtedly less complex 2D system. If graphics are defined as geometry data and textures, it makes intuitive sense to rasterize it all at higher resolutions and wider aspect ratios, and then go the extra mile towards frame interpolation. But due to the custom way that each 2D system implements its graphics <i>and</i> the already rasterized nature of each game's artwork, you can't just simply flip a switch and have such games render at a wider aspect ratio. The most intuitive game-independent renderer feature for those systems, therefore, is the same old filtered upscaling that emulators have been doing for decades already, such as the classic XBRz algorithm used for the sprite on the right.<br />
Sure, maybe you might want to develop a fancier spin on the same concept by filling the new pixels with their statistically most likely value according to a training set of similar games (or, as it's more commonly referred to, "AI upscaling"). Even AI frame interpolation could be possible if someone puts in the time to develop a {{Blog_PostLink "2024-04-24" "rollback mechanism"}} that would predictively render multiple frames ahead and somehow detect sprites from logged VRAM writes. But all of this can be done independently from ReC98, within just an emulator. If this had been our goal, we wouldn't ever have had to look at any Touhou game code.
</p><p style="clear: both;">
This brings us to 2). On the surface, recompilation simplifies modding a lot – just add new C code before compiling, without any ROM size constraints or ASM to worry about, right? Except that the generated code is as readable and unannotated as a raw disassembly, which brings you back to reverse-engineering the game <i>anyway</i> to figure out what's going on. A recompilation might provide a more efficient starting point if no one has done <i>any</i> RE or classic decompilation on the game yet, but doesn't change the fact that <i>some</i> RE will <i>always</i> be required, if only to work around the inevitable issues introduced by 1).<br />
Note how all the YouTube videos that presented these ports in May 2024 focused on Majora's Mask, a game that had been <a href="https://zelda64.dev/games/mm">94% decompiled</a> by the time its recompiled port was released. Hence, they already knew where the patches needed to go and how they would look like. These videos rarely explore this technology in the context of other games, and if they do, the results are not nearly as impressive.<br />
In short, the added value of a recompilation will <i>always</i> be proportional to the reverse-engineered knowledge about a game.
</p><p>
And for now, this has been ReC98's trajectory – reverse-engineering PC-98 Touhou to document every detail about these games and how they run on PC-98 hardware, storing the RE'd knowledge in the form of a perfect decompilation that has yielded identical binaries from Day 1, and facilitating bugfixes and mods way before it's viable to port these games away from PC-98. This was the most immediately useful choice in 2014, and continues to be the most useful choice in 2024 as the PC-98 hacking scene has only significantly grown in the emulation and translation patching departments since then. Besides, both RE and bugfixing are quite tough already if you're faced with an underdocumented platform running engine-less spaghetti code written by a beginner programmer. It's {{Blog_PostLink "2023-03-14" "so easy to get it wrong"}} even <i>with</i> a 100% decompilation, and requires great care to not accidentally modify game logic. After all, ReC98 can only ever earn the trust of the {{HTML_TagInline "gameplay"}} community if its bugfixes retain hypothetical replay compatibility. Recompilation does not help with any of that.
</p><p>
That's not to say that ReC98 won't <i>ever</i> work on those other prerequisites of recompiled PC-98 ports. In fact, I hinted towards that in {{Blog_PostLink "2022-08-15" "the announcement blog post for TH01's 100% decompilation"}}:
</p><blockquote>[…] maybe you can just merge in a PC-98 emulator core and get started with something halfway decent in a short amount of time.</blockquote><p>
If we wanted to have the PC-98 version of 3), this is the route we should have followed. Building a PC-98 runtime that can be easily linked into a decompiled PC-98-native code base is the hard part – once we've solved <i>that</i>, we could probably leverage <a href="https://github.com/M-HT/SR">an existing x86 recompilation project</a> to apply this runtime to other PC-98 games beyond Touhou. Instead, my backers have invested exactly {{HTML_Currency 100}} into portability in the 21 months after TH01's 100% decompilation. So it would seem that people agree with the original goal of first getting <i>all</i> 5 games to 100% before starting any porting work?<br />
In the end, it's all down to the priorities of each individual backer, including you.
</p>
{{template "</q>"}}
{{template "<q>" "uth05win"}}
Isn't <a href="http://m.newsmth.net/article/TouHou/single/11992">
uth05win</a> already what you wanted to achieve? We even have
<a href="https://github.com/Wintiger0222/uth05win">source code</a> for it.
</h3>
<p>
Initially, I thought the same, and had the impression that uth05win's
source code release would immediately obsolete ReC98.
</p><p>
Fast-forward to 2022 though, and TH05 has been one of the most requested
games among ReC98 backers. uth05win <i>did</i> legitimately reverse-engineer
most of TH05, and it definitely was a tremendous help during the initial
reverse-engineering phases of not only TH05, but also TH04 and, to a lesser
extent, even the previous three games. However, the final port has taken
quite some liberties, ranging from
{{Blog_PostLink "2020-08-16" "fanfiction fixes for even just minor inconsistencies within ZUN's original code"}}
to
{{Blog_PostLink "2022-04-30" "flat-out wrong code in certain boss scripts"}}.
It's completely understandable why die-hard PC-98 Touhou fans immediately
dismiss it as <i>"not the real thing"</i>. Which, ironically, led to ReC98's
approach of a provably legit source code reconstruction being appreciated
<i>more</i>, not less, among this group of people.
</p><p>
Also, the obvious reason I don't restrict myself to just one game.
</p>
{{template "</q>"}}
{{template "<q>" "identical-code"}}
Why do pushes that are geared towards one specific game also tend to come
with progress in other games? Aren't you wasting time there by not focusing
100% on what your patrons wanted you to do?
</h3>
<p>
If the same function appears in more than one game, more or less
unchanged, I'd only be wasting time re-familiarizing myself with all the
involved concepts months later. I think it makes more sense to immediately
cover identical functionality in all games. It's basically free progress
for everyone else.
</p><p>
Then again, the more progress is made, the more infrequently this will
happen, as the amount of not yet reverse-engineered code shared between
the games approaches zero.
</p>
{{template "</q>"}}
{{template "<q>" "refunds"}}
Do you have a refund policy?
</h3>
<p>
Yes! You can request refunds for every push I haven't started working on
yet. I <i>will</i> keep the money after having delivered a push though.
</p>
{{template "</q>"}}
{{template "<q>" "mod-bugs"}}
I found a bug in one of your mod releases!
</h3>
<p>
Please tell me! I will release a bugfix for free, together with a short
explanatory blog post, if the bug is
</p><ul>
<li>a clear regression (i.e., I broke something that worked fine in the
original game), and</li>
<li>not actually related to a bug or missing feature in the original game
that would be addressed in a future push or microtransaction.</li>
</ul><p>
An example: The <a
href="https://github.com/nmlgc/ReC98/releases/tag/P0234">P0234 build of the
TH01 Anniversary Edition</a> had a bug during the transition between
Sariel's two forms that caused certain pellets to be rendered as white
streaks. This was due to a quirk I didn't keep in mind when writing the new
pellet rendering code that this release was all about, so I
{{Blog_PostLink "2023-03-14" "fixed it shortly after I received the bug report, for free"}}.
</p><p>
Two counterexamples:
</p><ul>
<li>The same P0234 build broke the <code>s</code> command-line parameter
that would start TH01 with just a stage selection and no debug features. A
quick investigation showed that it only ever worked in the original game if
a specific byte in memory was written to before launching the game, which
turned the issue into a ZUN bug. But since it was easy to fix, I prioritized
the issue after the bug report, and shipped the fix in the <a
href="https://github.com/nmlgc/ReC98/releases/tag/P0239">subsequent P0239
build.</a></li>
<li>The <a href="https://github.com/nmlgc/ssg/releases/tag/P0226">P0226
release of Shuusou Gyoku</a> added 32-bit rendering support to allow the
game to run at full speed on Windows ≥8, but did not include a windowed mode
or any scaling support. This is a separate feature that requires separate,
dedicated attention, and <a
href="https://github.com/nmlgc/ssg/issues/7">already had an entry in the
issue tracker</a>.</li>
</ul>
{{template "</q>"}}
{{template "<q>" "tsa-takedown"}}
Can't Team Shanghai Alice take down this project and crowdfunding at any
time?
</h3>
<p>
While I can't promise that they <i>won't</i>, the same kind of source code
reconstruction has been done for the
<a href="https://github.com/pret/pokered#see-also">Generation I-III
Pokémon games</a>, <a href="https://github.com/n64decomp/sm64">Super Mario
64</a>, <a href="https://github.com/zeldaret/oot">Ocarina of Time</a>, and
<a href="https://github.com/diasurgical/devilution">Diablo</a>,
all of which still generate revenue for their rights holders. PC-98 Touhou,
on the other hand, is both no longer sold <i>and</i>
unlikely to be ever sold again in its original form due to
{{Blog_PostLink "2019-11-06" "various copyright infringements in the games themselves"}}.
That fact should even make them an inherently safer choice for a
decompilation project than any of the aforementioned ones…
</p><p>
… or so you would think. Despite all that, full downloads for the PC-98
games <i>are</i> <a
href="https://github.com/github/dmca/blob/a695b94/2022/04/2022-04-11-touhou-project.md">actively
being DMCA'd by Team Shanghai Alice as of April 2022</a>, officially robbing
the games of their perceived abandonware status. Now, it is still unclear
whether they plan to extend their copyright enforcement to the source code
and research level that this project exists at. Without a precedent inside
the Touhou scene, ReC98 does seem safe for the time being – especially since
it has never included any asset data from the original games, and is
unusable without supplying that data from existing game copies.<br />
Takedowns of decompilation projects <i>have</i> happened outside Touhou
though, most notably with <a
href="https://github.com/github/dmca/blob/3ce1c94/2021/02/2021-02-19-take-two.md">Take-Two's
DMCA claim against the GTA 3 / Vice City project</a>. And as
long as that court case is still pending, Team Shanghai Alice might very
well try the same, even surpassing Nintendo in terms of corporate
anti-consumer conduct in the process.
</p><p>
That said, it would take quite a bit more than a simple DMCA claim to GitHub
to take down this project. Everything about it has always been self-hosted
outside the US, and the GitHub presence of both the game code and website
repositories only fulfills four reasons:
</p><ol>
<li>Providing a nice code and commit browser</li>
<li>Offering another expendable place for issues to be reported, in addition to my usual Internet presence</li>
<li>Easy discoverability</li>
<li>Participating in the ⭐ star count popularity contest</li>
</ol><p>
Yes, no "web hosting" on this list, and no essential reliance on GitHub
infrastructure anywhere else. 1) could even be implemented as part of this
website in a push or two, if you all consider that a worthwhile thing to
have.
</p><p>
There is certainly an argument in favor of taking down the project at the
first sign of resistance. Why continue working in the hostile environment
that is canon Touhou if the perceived "free culture spirit" has been nothing
but a misunderstanding from the very beginning, and the rights holders are
more corporate, controlling, and distant than actual big corporations? The
rational choice would definitely be to leave the sinking ship. I'd love if
there was enough money in the non-Touhou parts of the PC-98 scene for a
follow-up project, it would be a shame to let my experience on the platform
go to waste. <a href="https://www.mobygames.com/game/pc98/rusty">Meme</a> <a
href="https://www.mobygames.com/game/pc98/possessioner">games</a>, <a
href="https://www.mobygames.com/game/pc98/sex-2">anyone</a>?
</p><p>
<a
href="https://twitter.com/WishMakers_TH/status/1513921407989829635">Seihou
also looks rather welcoming, don't you think?</a>
</p><p>
But that's not what <a href="/fundlog">all the backers</a> signed up for. I
have several ideas for transforming the project after a takedown notice
while still keeping its essence. I <i>will</i> keep it running as long as
possible – even if that will someday mean that I have to manually send out
the source code to people. And the blog – arguably the main attraction while
development is still ongoing – should be, in theory, even safer than that.
Let's wait and see how far Team Shanghai Alice will actually escalate this.
There <i>are</i> risks, and you should be aware of them and invest
responsibly, but I'm far from panicking.
</p><p>
Until then (and let's all hope we'll never reach that point): Always keep in
mind that <i>the product is both the code and the documentation, in the form
of new commits in a Git repository. Nothing more, nothing less</i>.
Perform a <code>git clone</code> after I pushed the commits you bought, and
you now have a DRM-free digital copy of the progress you paid for. Even if I
have to start manually sending out the source code to people, rest assured
that nothing I produce will ever be put behind a paywall. (The only thing
that <i>is</i> behind a paywall is the time it takes to make it all happen.)
</p><p>
And finally, because it seems to be frequently misunderstood: I have
<i>never</i> sold the promise of a finished Windows/Linux/phone release of
any of the games, and <i>still</i> don't sell the promise of any Team
Shanghai Alice release in relation to the completion of ReC98. Sure, in a
fair world, Team Shanghai Alice would leave this project alive until it
reached its core goal, and then acquire and commercially exploit it. They
have every right to do this, and it would be fine by me, as I will have been
paid my fair share at that point. But throughout all its Windows history,
Touhou has always been a poster child of the <a
href="https://youtu.be/qW61xJNJ9m8?t=20">"not invented here" mentality
prevalent in Japanese business</a>. Even the currently unlikely event of a
takedown is much, <i>much</i> more likely than them acknowledging or even
using my work. Heck, I remember hearing about offers for professional
localization from people who are much closer to ZUN than I am<sup>[citation
needed]</sup>, and they've all been turned down…
</p>
{{template "</q>"}}
{{template "<q>" "pull-requests"}}
Can I still help out with the reverse-engineering by contributing to the
ReC98 repository?
</h3>
<p>
The amount of time I spend on raw reverse-engineering and decompilation
almost pales in comparison to the deeper research and documentation work
that this project evolved towards. Unless you can deliver at a similar
level, I would spend almost as much time reviewing your changes as if I just
did everything myself, if not more. Frequent RE pull requests also reduce
the chance for me to turn this into my only job, which I would very much
like to do.
</p><p>
If you still want to help by coding, I've got a bunch of other
{{HTML_TagInline "contribution-ideas"}}. These are slightly out of scope of
the main project, but interesting for the big picture nonetheless. They come
with a lower barrier to entry, offer more freedom than regular
reverse-engineering work, <i>and</i> I would actually appreciate your help
there.
</p><p>
In all honesty though, spending your time contributing to any other project
would probably bring you much further in life than anything related to the
main Touhou series ever will.
</p>
{{template "</q>"}}
{{template "<q>" "website-contributions"}}
What about contributing code to the website?
</h3>
<p>
There is a wide array of potential features that could be added to this
site. Better accessibility for progress tables and syntax highlighting for
code snippets are two examples of features that I already have in mind for
future website pushes. Other features might be cool to have, but are maybe
too expensive relative to their usefulness, such as {{Blog_PostLink
"2022-10-31" "porting the ZMBV codec to the Web for efficient lossless video support on the blog"}}. And of course, there might be features that I
haven't even thought about so far.<br />
Unlike the core reverse-engineering business, improving the website is
something I only get to do maybe once or twice a year, as a side project.
That's why I would also highly appreciate you helping out in that regard.
</p><p>
Note that any code contributions to the website will be licensed under the
<a href="https://github.com/nmlgc/rec98.nmlgc.net/blob/master/LICENSE.md">AGPL.</a>
</p>
{{template "</q>"}}
{{template "<q>" "cap-why"}}
Why a cap?
</h3>
<p>
The cap corresponds to the maximum time I can healthily allocate to this
project within the next 4 weeks. It is meant to
</p><ul>
<li>protect all of <i>you</i> from throwing more money at me than I can
reasonably convert into progress, and to</li>
<li>ensure that at any point, I will be at most 4 weeks behind any
commissioned pushes. Therefore, it will also protects <i>me</i> from
burning out.</li>
</ul>
{{template "</q>"}}
{{template "<q>" "cap-too-low"}}
With the current rate of progress, and the cap being at the low level that
it is, the project is never going to finish!
</h3>
<p>
If you all manage to regularly sell out the store at higher and higher
prices per push, I will be able to increase the cap ever so slightly by
reducing those pesky RL work hours. If those reach zero and I can turn ReC98
into my only job, I can remove the cap entirely and go for a proportional
"bidding war" model instead, allocating my constant amount of time relative
to how much money comes in for a particular goal.
</p><p>
But as of December 2021, that's still far off. Meanwhile, the steadily
increasing amount of care and documentation I put into this project has
proved highly popular, while no one has ever requested me to compromise on
that and instead rush towards 100% RE as fast as possible. So, getting
everything 100% done within the foreseeable future doesn't actually seem to
be much of a concern for my existing audience.
</p>
{{template "</q>"}}
{{template "<q>" "slow-2018"}}
Some of the 2018 pushes were delivered months or even years after they were
paid…
</h3>
<p>
Back then, I not only didn't have a cap, but also vastly undersold myself,
while also offering crowdfunded features for thcrap in parallel. That's
why the latter are sometimes referred to in the old blog posts here. But
compare that to now:
</p><ul>
<li>I've resigned from thcrap</li>
<li>The aforementioned cap is in place</li>
<li>The build system for this project is now pretty close to optimal,
providing quick turnaround times, minimizing frustration, and keeping me
nicely focused.</li>
</ul><p>
However, if you <i>absolutely request</i> me to prioritize an element of a
game that requires a ton of not yet reverse-engineered knowledge to fully
grasp, and you <i>absolutely</i> don't accept your money going to anything
else, I <i>will</i> have to put that on the back burner. It will be made
clear in the backlog whenever that happens, though.
</p>
{{template "</q>"}}
{{template "<q>" "policenauts"}}
I'd like to see PC-98 Policenauts (or any other DOS program compiled using
Borland/Turbo C++) decompiled. What's in it for me?
</h3>
<p>
The ReC98 repository includes
<a href="https://github.com/nmlgc/ReC98/blob/master/Research/Borland%20C%2B%2B%20decompilation.md">
a currently incomplete file with the ASM→C++ patterns, as well as
information about the limits of decompilability</a>. This file will be
continuously updated with new insights. So while you probably wouldn't
want to support this project until the very end, it might be worth
supporting ReC98 for just a bit – at least until it becomes obvious that I
completely figured out Turbo C++, and that other decompilation project
you wanted to see made significant progress.
</p><p>
And who knows, maybe we <i>will</i> see a somewhat automated decompilation
solution come out of this.
</p>
{{template "</q>"}}
{{template "<q>" "replays"}}
I want replays! What's in it for me?
</h3>
<p>
As of January 2022, I also offer to develop PC-98-native replay mods, if you
don't want to wait for your favorite game to get 100% decompiled and ported
to a modern system first. There's a separate option in the order form just
for that goal.
</p>
{{template "</q>"}}
{{template "<q>" "translations"}}
I want translations into languages with non-ASCII characters! What's in it
for me?
</h3>
<p>
In 2023, {{DB_CustomerByID 9}} commissioned the basic feature set that would allow such translations, and I expect to deliver it during 2024, after completing the <a href="https://github.com/nmlgc/ssg/issues/42">Shuusou Gyoku Linux port</a>. However, you probably want more than the basic features, so feel free to further support this goal by donating to their {{HTML_Emoji "opencollective"}} <a href="https://opencollective.com/thpatch">Open Collective</a> page. There's no cap there, and every bit will help to improve the end product. {{Blog_PostLink "2023-07-28" "Check my announcement blog post for details and feature ideas"}}.
</p>
{{template "</q>"}}
{{template "<q>" "netplay"}}
I want TH03 netplay! What's in it for me?
</h3>
<p>
{{Blog_PostLink "2024-04-24" "This blog post details all possible approaches for implementing it"}}, together with their advantages, disadvantages, and prerequisites. I will start dedicated funding campaigns shortly after we've met the first of these prerequisites.
</p>
{{template "</q>"}}
{{template "<q>" "ads"}}
Do you sell ad space on this site?
</h3>
<p>
Every contributor, no matter how much they paid, has the option to have
their name be turned into a link to a URL of their choice. So if you
consider that to be advertising, then yes. If you had more than that in
mind, hit me up, and we might make it happen. No JavaScript or remote
content, though!
</p>
{{template "</q>"}}
{{template "<q>" "take-my-money"}}
Alright! I have understood what this project is about, and am convinced
that I want to support it. Take me to the order form!
</h3>
<form action="/order">
<p class="row">
<input type="checkbox" id="consent_takedown" required>
<label for="consent_takedown">
I have understood the <a href="#tsa-takedown">potential risk of
takedown claims by Team Shanghai Alice against this project</a>.
While the amount of progress I am about to purchase will either be
delivered or refunded, there is no guarantee that the project will
stay alive for further progress beyond that. (This does not apply to
Seihou-related goals.)
</label>
</p><p class="row">
<input type="checkbox" id="consent_gdpr" required>
<label for="consent_gdpr">
I agree that the data of my contribution will be processed, stored,
and made publicly available as seen in the <a
href="/fundlog">crowdfunding log</a>, under a <a
href="https://github.com/nmlgc/rec98.nmlgc.net/blob/master/LICENSE.md">public-domain
license</a>.<br />
I will have the option to stay anonymous though.
</label>
</p><p>
<button>Order</button>
</p>
</form>
{{template "</q>"}}