re(challenge): the unlock is a bit test, and the mission table is on disc

Static only. Bounding each GamePart's code block by its factory creator thunk
(id -> creator recovered for 22 of 24 registrations at 0x8280C000-0x8280F800)
puts GamePart_ChallengeMission at 0x82187E60-0x8218CF10. Resolving every string
that block references gives the screen's config schema, and the record itself is
on disc -- tables.pak schema 54a10697, one copy per language, English entry #64.

Six missions: TimeAttack (record Time), ScoreAttack (record Points) and
Extra01..Extra04, each with MISSION_ID / REQUIREMENT / REQUIREMENT_DESC /
THUMBNAIL / STAGE_DESC / NEW_STAGE and a NORMAL_BUTTON / GRAY_BUTTON pair -- so
the screen always lists all six and greys out what is not earned.

THE GATE (0x82189970-0x821899D8), read off the code:

  REQUIREMENT absent      -> available
  REQUIREMENT == "Always" -> available
  else n = atoi(REQUIREMENT)
      n == 0              -> locked
      n <  24             -> test bit n      of the word at singleton+80
      n >= 24             -> test bit (n-24) of the word at singleton+1956

The singleton is 0x821707C0 (lazy, global 0x828F48BC). So availability is one
bit in a progress bitfield and REQUIREMENT is a bit INDEX -- not a stage number,
score or difficulty.

Values per mission are 🟡: the pool's numeric tokens are 16/25/26/27/29 and
24/28 already appear earlier as font metrics, so they would be deduped -- which
fits 24..29 but IDXD dedup makes positional pairing unsound here, so it is
recorded as a hypothesis, not a table.

Negative: the requirement TEXT is not in GP_CHALLENGE.pak (TextIndex over it =
0 entries; its only prose is embedded font copyright). Its PATH is a per-language
branch the loader does not currently reproduce.

Next: three stores to +1956 sit in 0x822C7DD0 / 0x822C8748, the same region as
the save serializer 0x822C00E8 -- if the bits are save-backed, a hand-written
save unlocks all six challenge missions and the last 42 units become one run.
This commit is contained in:
2026-08-13 19:14:48 +00:00
parent 10a96844ba
commit 8ecd70f1bc
3 changed files with 908 additions and 3 deletions

View File

@@ -0,0 +1,750 @@
===== tables.pak entry #60 schema 54a10697 123 tokens [dat\GP_CHALLENGE.pak+fra\] =====
0 xBASE_INFO
1 0x061031
2 VERSION
3 dat\GP_CHALLENGE.pak+fra\
4 PATH
5 strings.tbl
6 STRINGS
7 py_menu_scr.prt
8 MENU
9 CHIPS
10 py_menu_n_btn1.prt
11 Button_TimeAttack
12 py_menu_n_btn2.prt
13 Button_ScoreAttack
14 py_menu_n_btn3.prt
15 Button_Extra01
16 py_menu_n_btn4.prt
17 Button_Extra02
18 py_menu_n_btn5.prt
19 Button_Extra03
20 py_menu_n_btn6.prt
21 Button_Extra04
22 py_menu_b_btn1.prt
23 Button_TimeAttack_Gray
24 py_menu_b_btn2.prt
25 Button_ScoreAttack_Gray
26 py_menu_b_btn3.prt
27 Button_Extra01_Gray
28 py_menu_b_btn4.prt
29 Button_Extra02_Gray
30 py_menu_b_btn5.prt
31 Button_Extra03_Gray
32 py_menu_b_btn6.prt
33 Button_Extra04_Gray
34 py_menu_challenge1.t32
35 Thumbnail_TimeAttack
36 py_menu_challenge2.t32
37 Thumbnail_ScoreAttack
38 py_menu_challenge3.t32
39 Thumbnail_Extra01
40 py_menu_challenge4.t32
41 Thumbnail_Extra02
42 py_menu_challenge5.t32
43 Thumbnail_Extra03
44 py_menu_challenge6.t32
45 Thumbnail_Extra04
46 py_menu_str_time.t32
47 Record_Time
48 py_menu_str_point.t32
49 Record_Point
50 py_menu_str_p.t32
51 Unit_Point
52 py_menu_new.prt
53 New_Stage
54 FONTS
55 Font_Desc
56 Font_Record
57 CONTM___.TTF
58 FONT
59 24
60 HEIGHT
61 28
62 Desc_Stage
63 580,400
64 LOCATE
65 8
66 LINE_SPACE
67 Desc_Time
68 1048,608,R
69 0
70 INDEX
71 Desc_Points
72 1032,608,R
73 UNIT
74 New_Stage01
75 New_Stage02
76 0,60
77 INDEX_ADJUST
78 New_Stage03
79 0,120
80 New_Stage04
81 0,180
82 New_Stage05
83 0,240
84 New_Stage06
85 0,300
86 MISSIONS
87 TimeAttack
88 ScoreAttack
89 Extra01
90 Extra02
91 Extra03
92 Extra04
93 MISSION_ID
94 Time
95 RECORD_TYPE
96 16
97 REQUIREMENT
98 NORMAL_BUTTON
99 GRAY_BUTTON
100 THUMBNAIL
101 TimeAttackRequirement
102 REQUIREMENT_DESC
103 TimeAttackStageDesc
104 STAGE_DESC
105 TEXT_STAGE
106 TEXT_RECORD
107 NEW_STAGE
108 25
109 Points
110 ScoreAttackRequirement
111 ScoreAttackStageDesc
112 26
113 Extra01Requirement
114 ExtraStage01Desc
115 27
116 Extra02Requirement
117 ExtraStage02Desc
118 Extra03Requirement
119 ExtraStage03Desc
120 29
121 Extra04Requirement
122 ExtraStage04Desc
===== tables.pak entry #64 schema 54a10697 123 tokens [dat\GP_CHALLENGE.pak+eng\] =====
0 xBASE_INFO
1 0x061031
2 VERSION
3 dat\GP_CHALLENGE.pak+eng\
4 PATH
5 strings.tbl
6 STRINGS
7 py_menu_scr.prt
8 MENU
9 CHIPS
10 py_menu_n_btn1.prt
11 Button_TimeAttack
12 py_menu_n_btn2.prt
13 Button_ScoreAttack
14 py_menu_n_btn3.prt
15 Button_Extra01
16 py_menu_n_btn4.prt
17 Button_Extra02
18 py_menu_n_btn5.prt
19 Button_Extra03
20 py_menu_n_btn6.prt
21 Button_Extra04
22 py_menu_b_btn1.prt
23 Button_TimeAttack_Gray
24 py_menu_b_btn2.prt
25 Button_ScoreAttack_Gray
26 py_menu_b_btn3.prt
27 Button_Extra01_Gray
28 py_menu_b_btn4.prt
29 Button_Extra02_Gray
30 py_menu_b_btn5.prt
31 Button_Extra03_Gray
32 py_menu_b_btn6.prt
33 Button_Extra04_Gray
34 py_menu_challenge1.t32
35 Thumbnail_TimeAttack
36 py_menu_challenge2.t32
37 Thumbnail_ScoreAttack
38 py_menu_challenge3.t32
39 Thumbnail_Extra01
40 py_menu_challenge4.t32
41 Thumbnail_Extra02
42 py_menu_challenge5.t32
43 Thumbnail_Extra03
44 py_menu_challenge6.t32
45 Thumbnail_Extra04
46 py_menu_str_time.t32
47 Record_Time
48 py_menu_str_point.t32
49 Record_Point
50 py_menu_str_p.t32
51 Unit_Point
52 py_menu_new.prt
53 New_Stage
54 FONTS
55 Font_Desc
56 Font_Record
57 CONTM___.TTF
58 FONT
59 24
60 HEIGHT
61 28
62 Desc_Stage
63 580,400
64 LOCATE
65 8
66 LINE_SPACE
67 Desc_Time
68 1048,608,R
69 0
70 INDEX
71 Desc_Points
72 1032,608,R
73 UNIT
74 New_Stage01
75 New_Stage02
76 0,60
77 INDEX_ADJUST
78 New_Stage03
79 0,120
80 New_Stage04
81 0,180
82 New_Stage05
83 0,240
84 New_Stage06
85 0,300
86 MISSIONS
87 TimeAttack
88 ScoreAttack
89 Extra01
90 Extra02
91 Extra03
92 Extra04
93 MISSION_ID
94 Time
95 RECORD_TYPE
96 16
97 REQUIREMENT
98 NORMAL_BUTTON
99 GRAY_BUTTON
100 THUMBNAIL
101 TimeAttackRequirement
102 REQUIREMENT_DESC
103 TimeAttackStageDesc
104 STAGE_DESC
105 TEXT_STAGE
106 TEXT_RECORD
107 NEW_STAGE
108 25
109 Points
110 ScoreAttackRequirement
111 ScoreAttackStageDesc
112 26
113 Extra01Requirement
114 ExtraStage01Desc
115 27
116 Extra02Requirement
117 ExtraStage02Desc
118 Extra03Requirement
119 ExtraStage03Desc
120 29
121 Extra04Requirement
122 ExtraStage04Desc
===== tables.pak entry #67 schema 54a10697 123 tokens [dat\GP_CHALLENGE.pak+deu\] =====
0 xBASE_INFO
1 0x061031
2 VERSION
3 dat\GP_CHALLENGE.pak+deu\
4 PATH
5 strings.tbl
6 STRINGS
7 py_menu_scr.prt
8 MENU
9 CHIPS
10 py_menu_n_btn1.prt
11 Button_TimeAttack
12 py_menu_n_btn2.prt
13 Button_ScoreAttack
14 py_menu_n_btn3.prt
15 Button_Extra01
16 py_menu_n_btn4.prt
17 Button_Extra02
18 py_menu_n_btn5.prt
19 Button_Extra03
20 py_menu_n_btn6.prt
21 Button_Extra04
22 py_menu_b_btn1.prt
23 Button_TimeAttack_Gray
24 py_menu_b_btn2.prt
25 Button_ScoreAttack_Gray
26 py_menu_b_btn3.prt
27 Button_Extra01_Gray
28 py_menu_b_btn4.prt
29 Button_Extra02_Gray
30 py_menu_b_btn5.prt
31 Button_Extra03_Gray
32 py_menu_b_btn6.prt
33 Button_Extra04_Gray
34 py_menu_challenge1.t32
35 Thumbnail_TimeAttack
36 py_menu_challenge2.t32
37 Thumbnail_ScoreAttack
38 py_menu_challenge3.t32
39 Thumbnail_Extra01
40 py_menu_challenge4.t32
41 Thumbnail_Extra02
42 py_menu_challenge5.t32
43 Thumbnail_Extra03
44 py_menu_challenge6.t32
45 Thumbnail_Extra04
46 py_menu_str_time.t32
47 Record_Time
48 py_menu_str_point.t32
49 Record_Point
50 py_menu_str_p.t32
51 Unit_Point
52 py_menu_new.prt
53 New_Stage
54 FONTS
55 Font_Desc
56 Font_Record
57 CONTM___.TTF
58 FONT
59 24
60 HEIGHT
61 28
62 Desc_Stage
63 580,400
64 LOCATE
65 8
66 LINE_SPACE
67 Desc_Time
68 1048,608,R
69 0
70 INDEX
71 Desc_Points
72 1032,608,R
73 UNIT
74 New_Stage01
75 New_Stage02
76 0,60
77 INDEX_ADJUST
78 New_Stage03
79 0,120
80 New_Stage04
81 0,180
82 New_Stage05
83 0,240
84 New_Stage06
85 0,300
86 MISSIONS
87 TimeAttack
88 ScoreAttack
89 Extra01
90 Extra02
91 Extra03
92 Extra04
93 MISSION_ID
94 Time
95 RECORD_TYPE
96 16
97 REQUIREMENT
98 NORMAL_BUTTON
99 GRAY_BUTTON
100 THUMBNAIL
101 TimeAttackRequirement
102 REQUIREMENT_DESC
103 TimeAttackStageDesc
104 STAGE_DESC
105 TEXT_STAGE
106 TEXT_RECORD
107 NEW_STAGE
108 25
109 Points
110 ScoreAttackRequirement
111 ScoreAttackStageDesc
112 26
113 Extra01Requirement
114 ExtraStage01Desc
115 27
116 Extra02Requirement
117 ExtraStage02Desc
118 Extra03Requirement
119 ExtraStage03Desc
120 29
121 Extra04Requirement
122 ExtraStage04Desc
===== tables.pak entry #68 schema 54a10697 123 tokens [dat\GP_CHALLENGE.pak+ita\] =====
0 xBASE_INFO
1 0x061031
2 VERSION
3 dat\GP_CHALLENGE.pak+ita\
4 PATH
5 strings.tbl
6 STRINGS
7 py_menu_scr.prt
8 MENU
9 CHIPS
10 py_menu_n_btn1.prt
11 Button_TimeAttack
12 py_menu_n_btn2.prt
13 Button_ScoreAttack
14 py_menu_n_btn3.prt
15 Button_Extra01
16 py_menu_n_btn4.prt
17 Button_Extra02
18 py_menu_n_btn5.prt
19 Button_Extra03
20 py_menu_n_btn6.prt
21 Button_Extra04
22 py_menu_b_btn1.prt
23 Button_TimeAttack_Gray
24 py_menu_b_btn2.prt
25 Button_ScoreAttack_Gray
26 py_menu_b_btn3.prt
27 Button_Extra01_Gray
28 py_menu_b_btn4.prt
29 Button_Extra02_Gray
30 py_menu_b_btn5.prt
31 Button_Extra03_Gray
32 py_menu_b_btn6.prt
33 Button_Extra04_Gray
34 py_menu_challenge1.t32
35 Thumbnail_TimeAttack
36 py_menu_challenge2.t32
37 Thumbnail_ScoreAttack
38 py_menu_challenge3.t32
39 Thumbnail_Extra01
40 py_menu_challenge4.t32
41 Thumbnail_Extra02
42 py_menu_challenge5.t32
43 Thumbnail_Extra03
44 py_menu_challenge6.t32
45 Thumbnail_Extra04
46 py_menu_str_time.t32
47 Record_Time
48 py_menu_str_point.t32
49 Record_Point
50 py_menu_str_p.t32
51 Unit_Point
52 py_menu_new.prt
53 New_Stage
54 FONTS
55 Font_Desc
56 Font_Record
57 CONTM___.TTF
58 FONT
59 24
60 HEIGHT
61 28
62 Desc_Stage
63 580,400
64 LOCATE
65 8
66 LINE_SPACE
67 Desc_Time
68 1048,608,R
69 0
70 INDEX
71 Desc_Points
72 1032,608,R
73 UNIT
74 New_Stage01
75 New_Stage02
76 0,60
77 INDEX_ADJUST
78 New_Stage03
79 0,120
80 New_Stage04
81 0,180
82 New_Stage05
83 0,240
84 New_Stage06
85 0,300
86 MISSIONS
87 TimeAttack
88 ScoreAttack
89 Extra01
90 Extra02
91 Extra03
92 Extra04
93 MISSION_ID
94 Time
95 RECORD_TYPE
96 16
97 REQUIREMENT
98 NORMAL_BUTTON
99 GRAY_BUTTON
100 THUMBNAIL
101 TimeAttackRequirement
102 REQUIREMENT_DESC
103 TimeAttackStageDesc
104 STAGE_DESC
105 TEXT_STAGE
106 TEXT_RECORD
107 NEW_STAGE
108 25
109 Points
110 ScoreAttackRequirement
111 ScoreAttackStageDesc
112 26
113 Extra01Requirement
114 ExtraStage01Desc
115 27
116 Extra02Requirement
117 ExtraStage02Desc
118 Extra03Requirement
119 ExtraStage03Desc
120 29
121 Extra04Requirement
122 ExtraStage04Desc
===== tables.pak entry #74 schema 54a10697 123 tokens [dat\GP_CHALLENGE.pak+jpn\] =====
0 BASE_INFO
1 0x061031
2 VERSION
3 dat\GP_CHALLENGE.pak+jpn\
4 PATH
5 strings.tbl
6 STRINGS
7 py_menu_scr.prt
8 MENU
9 CHIPS
10 py_menu_n_btn1.prt
11 Button_TimeAttack
12 py_menu_n_btn2.prt
13 Button_ScoreAttack
14 py_menu_n_btn3.prt
15 Button_Extra01
16 py_menu_n_btn4.prt
17 Button_Extra02
18 py_menu_n_btn5.prt
19 Button_Extra03
20 py_menu_n_btn6.prt
21 Button_Extra04
22 py_menu_b_btn1.prt
23 Button_TimeAttack_Gray
24 py_menu_b_btn2.prt
25 Button_ScoreAttack_Gray
26 py_menu_b_btn3.prt
27 Button_Extra01_Gray
28 py_menu_b_btn4.prt
29 Button_Extra02_Gray
30 py_menu_b_btn5.prt
31 Button_Extra03_Gray
32 py_menu_b_btn6.prt
33 Button_Extra04_Gray
34 py_menu_challenge1.t32
35 Thumbnail_TimeAttack
36 py_menu_challenge2.t32
37 Thumbnail_ScoreAttack
38 py_menu_challenge3.t32
39 Thumbnail_Extra01
40 py_menu_challenge4.t32
41 Thumbnail_Extra02
42 py_menu_challenge5.t32
43 Thumbnail_Extra03
44 py_menu_challenge6.t32
45 Thumbnail_Extra04
46 py_menu_str_time.t32
47 Record_Time
48 py_menu_str_point.t32
49 Record_Point
50 py_menu_str_p.t32
51 Unit_Point
52 py_menu_new.prt
53 New_Stage
54 FONTS
55 Font_Desc
56 Font_Record
57 DFSOGE5.TTC
58 FONT
59 24
60 HEIGHT
61 CONTM___.TTF
62 28
63 Desc_Stage
64 580,400
65 LOCATE
66 8
67 LINE_SPACE
68 Desc_Time
69 1048,608,R
70 INDEX
71 Desc_Points
72 1032,608,R
73 UNIT
74 New_Stage01
75 New_Stage02
76 0,60
77 INDEX_ADJUST
78 New_Stage03
79 0,120
80 New_Stage04
81 0,180
82 New_Stage05
83 0,240
84 New_Stage06
85 0,300
86 MISSIONS
87 TimeAttack
88 ScoreAttack
89 Extra01
90 Extra02
91 Extra03
92 Extra04
93 MISSION_ID
94 Time
95 RECORD_TYPE
96 16
97 REQUIREMENT
98 NORMAL_BUTTON
99 GRAY_BUTTON
100 THUMBNAIL
101 TimeAttackRequirement
102 REQUIREMENT_DESC
103 TimeAttackStageDesc
104 STAGE_DESC
105 TEXT_STAGE
106 TEXT_RECORD
107 NEW_STAGE
108 25
109 Points
110 ScoreAttackRequirement
111 ScoreAttackStageDesc
112 26
113 Extra01Requirement
114 ExtraStage01Desc
115 27
116 Extra02Requirement
117 ExtraStage02Desc
118 Extra03Requirement
119 ExtraStage03Desc
120 29
121 Extra04Requirement
122 ExtraStage04Desc
===== tables.pak entry #75 schema 54a10697 123 tokens [dat\GP_CHALLENGE.pak+esp\] =====
0 xBASE_INFO
1 0x061031
2 VERSION
3 dat\GP_CHALLENGE.pak+esp\
4 PATH
5 strings.tbl
6 STRINGS
7 py_menu_scr.prt
8 MENU
9 CHIPS
10 py_menu_n_btn1.prt
11 Button_TimeAttack
12 py_menu_n_btn2.prt
13 Button_ScoreAttack
14 py_menu_n_btn3.prt
15 Button_Extra01
16 py_menu_n_btn4.prt
17 Button_Extra02
18 py_menu_n_btn5.prt
19 Button_Extra03
20 py_menu_n_btn6.prt
21 Button_Extra04
22 py_menu_b_btn1.prt
23 Button_TimeAttack_Gray
24 py_menu_b_btn2.prt
25 Button_ScoreAttack_Gray
26 py_menu_b_btn3.prt
27 Button_Extra01_Gray
28 py_menu_b_btn4.prt
29 Button_Extra02_Gray
30 py_menu_b_btn5.prt
31 Button_Extra03_Gray
32 py_menu_b_btn6.prt
33 Button_Extra04_Gray
34 py_menu_challenge1.t32
35 Thumbnail_TimeAttack
36 py_menu_challenge2.t32
37 Thumbnail_ScoreAttack
38 py_menu_challenge3.t32
39 Thumbnail_Extra01
40 py_menu_challenge4.t32
41 Thumbnail_Extra02
42 py_menu_challenge5.t32
43 Thumbnail_Extra03
44 py_menu_challenge6.t32
45 Thumbnail_Extra04
46 py_menu_str_time.t32
47 Record_Time
48 py_menu_str_point.t32
49 Record_Point
50 py_menu_str_p.t32
51 Unit_Point
52 py_menu_new.prt
53 New_Stage
54 FONTS
55 Font_Desc
56 Font_Record
57 CONTM___.TTF
58 FONT
59 24
60 HEIGHT
61 28
62 Desc_Stage
63 580,400
64 LOCATE
65 8
66 LINE_SPACE
67 Desc_Time
68 1048,608,R
69 0
70 INDEX
71 Desc_Points
72 1032,608,R
73 UNIT
74 New_Stage01
75 New_Stage02
76 0,60
77 INDEX_ADJUST
78 New_Stage03
79 0,120
80 New_Stage04
81 0,180
82 New_Stage05
83 0,240
84 New_Stage06
85 0,300
86 MISSIONS
87 TimeAttack
88 ScoreAttack
89 Extra01
90 Extra02
91 Extra03
92 Extra04
93 MISSION_ID
94 Time
95 RECORD_TYPE
96 16
97 REQUIREMENT
98 NORMAL_BUTTON
99 GRAY_BUTTON
100 THUMBNAIL
101 TimeAttackRequirement
102 REQUIREMENT_DESC
103 TimeAttackStageDesc
104 STAGE_DESC
105 TEXT_STAGE
106 TEXT_RECORD
107 NEW_STAGE
108 25
109 Points
110 ScoreAttackRequirement
111 ScoreAttackStageDesc
112 26
113 Extra01Requirement
114 ExtraStage01Desc
115 27
116 Extra02Requirement
117 ExtraStage02Desc
118 Extra03Requirement
119 ExtraStage03Desc
120 29
121 Extra04Requirement
122 ExtraStage04Desc