Rev 1 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | pmbaty | 1 | #include "racestrt.h" |
18 | pmbaty | 2 | #include "brender.h" |
1 | pmbaty | 3 | #include "cutscene.h" |
4 | #include "displays.h" |
||
5 | #include "drmem.h" |
||
6 | #include "errors.h" |
||
7 | #include "flicplay.h" |
||
8 | #include "globvars.h" |
||
9 | #include "globvrpb.h" |
||
10 | #include "grafdata.h" |
||
11 | #include "graphics.h" |
||
12 | #include "harness/config.h" |
||
13 | #include "harness/trace.h" |
||
14 | #include "input.h" |
||
15 | #include "intrface.h" |
||
16 | #include "loading.h" |
||
17 | #include "netgame.h" |
||
18 | #include "network.h" |
||
19 | #include "newgame.h" |
||
20 | #include "opponent.h" |
||
21 | #include "pd/sys.h" |
||
22 | #include "racestrt.h" |
||
23 | #include "sound.h" |
||
24 | #include "structur.h" |
||
25 | #include "utility.h" |
||
26 | #include "world.h" |
||
27 | #include <stdlib.h> |
||
28 | |||
29 | int gGrid_number_colour[4] = { 49u, 201u, 1u, 201u }; |
||
30 | int gJust_bought_part; |
||
31 | tU32 gLast_host_query; |
||
32 | br_pixelmap* gDead_car; |
||
33 | int gFade_away_parts_shop; |
||
34 | tU32 gDare_start_time; |
||
35 | int gRefund_rate; |
||
36 | int gSwap_grid_2; |
||
37 | int gSwap_grid_1; |
||
38 | int gChange_race_net_mode; |
||
39 | tParts_category gPart_category; |
||
40 | tU32 gNet_synch_start; |
||
41 | tNet_game_details* gChoose_car_net_game; |
||
42 | int gPart_index; |
||
18 | pmbaty | 43 | int gChallenger_index__racestrt; // suffix added to avoid duplicate symbol |
1 | pmbaty | 44 | tGrid_draw gDraw_grid_status; |
45 | tNet_sequence_type gNet_race_sequence__racestrt; // suffix added to avoid duplicate symbol |
||
46 | br_pixelmap* gTaken_image; |
||
47 | int gGrid_number_x_coords[31]; |
||
48 | int gGrid_transition_stage; |
||
49 | int gGrid_y_adjust; |
||
50 | br_pixelmap* gBullet_image; |
||
51 | br_pixelmap* gDeceased_image; |
||
52 | int gBest_pos_available; |
||
53 | int gChallenger_position; |
||
54 | int gOpponent_index; |
||
55 | int gChallenge_time; |
||
56 | int gOriginal_position; |
||
57 | int gCurrent_race_index; |
||
58 | tInterface_spec* gStart_interface_spec; |
||
59 | int gCurrent_car_index; |
||
60 | int gOur_starting_position; |
||
61 | |||
62 | // IDA: void __usercall DrawRaceList(int pOffset@<EAX>) |
||
63 | void DrawRaceList(int pOffset) { |
||
64 | int i; |
||
65 | //int font_height; // Pierre-Marie Baty -- unused variable |
||
66 | int pitch; |
||
67 | int y; |
||
68 | int left_most; |
||
69 | int right_most; |
||
70 | int rank_colour; |
||
71 | int text_colour; |
||
72 | //int box_bot; // Pierre-Marie Baty -- unused variable |
||
73 | //int text_width; // Pierre-Marie Baty -- unused variable |
||
74 | int text_x; |
||
75 | char rank_str[256]; |
||
76 | LOG_TRACE("(%d)", pOffset); |
||
77 | |||
78 | left_most = (gCurrent_graf_data->choose_race_rank_right - 2 * gBig_font->width[48] + gCurrent_graf_data->choose_race_left) / 2; |
||
79 | right_most = gCurrent_graf_data->choose_race_right - (left_most - gCurrent_graf_data->choose_race_left); |
||
80 | BrPixelmapRectangleFill(gBack_screen, |
||
81 | left_most, |
||
82 | gCurrent_graf_data->choose_race_y_top, |
||
83 | gCurrent_graf_data->choose_race_right - gCurrent_graf_data->choose_race_left - 2 * (left_most - gCurrent_graf_data->choose_race_left), |
||
84 | gCurrent_graf_data->choose_race_y_bottom - gCurrent_graf_data->choose_race_y_top, |
||
85 | 0); |
||
86 | pitch = gCurrent_graf_data->choose_race_y_pitch; |
||
87 | for (i = 0; i < gNumber_of_races; i++) { |
||
88 | y = pitch * i + gCurrent_graf_data->choose_race_curr_y - pOffset; |
||
89 | if (gCurrent_graf_data->choose_race_y_top <= (y - (TranslationMode() ? 2 : 0)) && (y + gBig_font->glyph_y) < gCurrent_graf_data->choose_race_line_y) { |
||
90 | if ((gProgram_state.rank > gRace_list[i].rank_required || gProgram_state.rank < gRace_list[i].best_rank) && !gProgram_state.game_completed && !gChange_race_net_mode) { |
||
91 | rank_colour = 44; |
||
92 | text_colour = 49; |
||
93 | } else if (gCurrent_graf_data->choose_race_curr_y == y) { |
||
94 | rank_colour = 5; |
||
95 | text_colour = 1; |
||
96 | } else { |
||
97 | rank_colour = 198; |
||
98 | text_colour = 201; |
||
99 | } |
||
100 | if (!gChange_race_net_mode) { |
||
101 | sprintf(rank_str, "%2d", gRace_list[i].rank_required); |
||
102 | TransBrPixelmapText(gBack_screen, |
||
103 | gCurrent_graf_data->choose_race_rank_right - BrPixelmapTextWidth(gBack_screen, gBig_font, rank_str), |
||
104 | y, |
||
105 | rank_colour, |
||
106 | gBig_font, |
||
107 | rank_str); |
||
108 | } |
||
109 | TransBrPixelmapText(gBack_screen, |
||
110 | gCurrent_graf_data->choose_race_name_left, |
||
111 | y, |
||
112 | text_colour, |
||
113 | gBig_font, |
||
114 | gRace_list[i].name); |
||
115 | if (gRace_list[i].been_there_done_that && gBullet_image != NULL) { |
||
116 | BrPixelmapRectangleCopy(gBack_screen, |
||
117 | gCurrent_graf_data->choose_race_bullet_left, |
||
118 | y + (gBig_font->glyph_y - gBullet_image->height) / 2, |
||
119 | gBullet_image, |
||
120 | 0, |
||
121 | 0, |
||
122 | gBullet_image->width, |
||
123 | gBullet_image->height); |
||
124 | } |
||
125 | } |
||
126 | } |
||
127 | if (gChange_race_net_mode) { |
||
128 | strcpy(rank_str, GetMiscString(gNet_race_sequence__racestrt == 1 ? kMiscString_SUBSEQUENT_RACES_WILL_BE_RANDOM : kMiscString_RACES_WILL_CONTINUE_DOWN_THIS_LIST)); |
||
129 | TransBrPixelmapText(gBack_screen, |
||
130 | (right_most + left_most - BrPixelmapTextWidth(gBack_screen, gBig_font, rank_str)) / 2, |
||
131 | gCurrent_graf_data->choose_race_current_text_y, |
||
132 | 5, |
||
133 | gBig_font, |
||
134 | rank_str); |
||
135 | } else { |
||
136 | sprintf(rank_str, "%s%d", GetMiscString(kMiscString_YourCurrentRankIs), gProgram_state.rank); |
||
137 | text_x = (gCurrent_graf_data->choose_race_left + gCurrent_graf_data->choose_race_right) / 2 - BrPixelmapTextWidth(gBack_screen, gBig_font, rank_str) / 2; |
||
138 | TransBrPixelmapText(gBack_screen, |
||
139 | text_x, |
||
140 | gCurrent_graf_data->choose_race_current_text_y, |
||
141 | 3, |
||
142 | gBig_font, |
||
143 | GetMiscString(kMiscString_YourCurrentRankIs)); |
||
144 | sprintf(rank_str, "%d", gProgram_state.rank); |
||
145 | TransBrPixelmapText(gBack_screen, |
||
146 | text_x + BrPixelmapTextWidth(gBack_screen, gBig_font, GetMiscString(kMiscString_YourCurrentRankIs)), |
||
147 | gCurrent_graf_data->choose_race_current_text_y, |
||
148 | 5, |
||
149 | gBig_font, |
||
150 | rank_str); |
||
151 | } |
||
152 | BrPixelmapLine(gBack_screen, |
||
153 | left_most, |
||
154 | gCurrent_graf_data->choose_race_line_y, |
||
155 | right_most, |
||
156 | gCurrent_graf_data->choose_race_line_y, |
||
157 | 6); |
||
158 | DrawRectangle(gBack_screen, |
||
159 | left_most, |
||
160 | gCurrent_graf_data->choose_race_box_top - 1, |
||
161 | right_most, |
||
162 | 2 * gCurrent_graf_data->choose_race_curr_y - gCurrent_graf_data->choose_race_box_top + gBig_font->glyph_y, |
||
163 | 3); |
||
164 | PDScreenBufferSwap(0); |
||
165 | } |
||
166 | |||
167 | // IDA: void __usercall MoveRaceList(int pFrom@<EAX>, int pTo@<EDX>, tS32 pTime_to_move@<EBX>) |
||
168 | void MoveRaceList(int pFrom, int pTo, tS32 pTime_to_move) { |
||
169 | tS32 start_time; |
||
170 | tS32 the_time; |
||
171 | //int move_distance; // Pierre-Marie Baty -- unused variable |
||
172 | int pitch; |
||
173 | LOG_TRACE("(%d, %d, %d)", pFrom, pTo, pTime_to_move); |
||
174 | |||
175 | pitch = gCurrent_graf_data->choose_race_y_pitch; |
||
176 | start_time = PDGetTotalTime(); |
||
177 | while (1) { |
||
178 | the_time = PDGetTotalTime(); |
||
179 | if (start_time + pTime_to_move <= the_time) |
||
180 | break; |
||
181 | DrawRaceList((the_time - start_time) * (pTo - pFrom) * pitch / pTime_to_move + pitch * pFrom); |
||
182 | } |
||
183 | DrawRaceList(pitch * pTo); |
||
184 | } |
||
185 | |||
186 | // IDA: int __usercall UpRace@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
187 | int UpRace(int* pCurrent_choice, int* pCurrent_mode) { |
||
188 | LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
189 | |||
190 | AddToFlicQueue(gStart_interface_spec->pushed_flics[2].flic_index, |
||
191 | gStart_interface_spec->pushed_flics[2].x[gGraf_data_index], |
||
192 | gStart_interface_spec->pushed_flics[2].y[gGraf_data_index], |
||
193 | 1); |
||
194 | DRS3StartSound(gEffects_outlet, 3000); |
||
195 | if (gCurrent_race_index != 0 && (gRace_list[gCurrent_race_index - 1].best_rank <= gProgram_state.rank || gProgram_state.game_completed || gChange_race_net_mode)) { |
||
196 | RemoveTransientBitmaps(1); |
||
197 | MoveRaceList(gCurrent_race_index, gCurrent_race_index - 1, 150); |
||
198 | gCurrent_race_index--; |
||
199 | } |
||
200 | return 0; |
||
201 | } |
||
202 | |||
203 | // IDA: int __usercall DownRace@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
204 | int DownRace(int* pCurrent_choice, int* pCurrent_mode) { |
||
205 | LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
206 | |||
207 | AddToFlicQueue(gStart_interface_spec->pushed_flics[3].flic_index, |
||
208 | gStart_interface_spec->pushed_flics[3].x[gGraf_data_index], |
||
209 | gStart_interface_spec->pushed_flics[3].y[gGraf_data_index], |
||
210 | 1); |
||
211 | DRS3StartSound(gEffects_outlet, 3000); |
||
212 | if (gCurrent_race_index < gNumber_of_races - 1 && (gProgram_state.rank <= gRace_list[gCurrent_race_index + 1].rank_required || gProgram_state.game_completed || gChange_race_net_mode)) { |
||
213 | RemoveTransientBitmaps(1); |
||
214 | MoveRaceList(gCurrent_race_index, gCurrent_race_index + 1, 150); |
||
215 | gCurrent_race_index++; |
||
216 | } |
||
217 | return 0; |
||
218 | } |
||
219 | |||
220 | // IDA: int __usercall ClickOnRace@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>) |
||
221 | int ClickOnRace(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) { |
||
222 | int x_coord; |
||
223 | int y_coord; |
||
224 | int race_delta; |
||
225 | LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset); |
||
226 | |||
227 | GetMousePosition(&x_coord, &y_coord); |
||
228 | race_delta = (y_coord - (gCurrent_graf_data->choose_race_curr_y - 5 * (gCurrent_graf_data->choose_race_y_pitch / 2) + gBig_font->glyph_y / 2)) / gCurrent_graf_data->choose_race_y_pitch - 2; |
||
229 | if (race_delta >= -2 && race_delta <= -1) { |
||
230 | do { |
||
231 | UpRace(pCurrent_choice, pCurrent_mode); |
||
232 | race_delta++; |
||
233 | } while (race_delta != 0); |
||
234 | } else if (race_delta > 0 && race_delta < 3) { |
||
235 | do { |
||
236 | DownRace(pCurrent_choice, pCurrent_mode); |
||
237 | race_delta--; |
||
238 | } while (race_delta != 0); |
||
239 | } |
||
240 | return 0; |
||
241 | } |
||
242 | |||
243 | // IDA: int __usercall UpClickRace@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>) |
||
244 | int UpClickRace(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) { |
||
245 | LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset); |
||
246 | |||
247 | UpRace(pCurrent_choice, pCurrent_mode); |
||
248 | return 0; |
||
249 | } |
||
250 | |||
251 | // IDA: int __usercall DownClickRace@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>) |
||
252 | int DownClickRace(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) { |
||
253 | LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset); |
||
254 | |||
255 | DownRace(pCurrent_choice, pCurrent_mode); |
||
256 | return 0; |
||
257 | } |
||
258 | |||
259 | // IDA: void __cdecl StartChangeRace() |
||
260 | void StartChangeRace(void) { |
||
261 | LOG_TRACE("()"); |
||
262 | |||
263 | MoveRaceList(-3, gCurrent_race_index, 400); |
||
264 | } |
||
265 | |||
266 | // IDA: int __usercall ChangeRace@<EAX>(int *pRace_index@<EAX>, int pNet_mode@<EDX>, tNet_sequence_type pNet_race_sequence@<EBX>) |
||
267 | int ChangeRace(int* pRace_index, int pNet_mode, tNet_sequence_type pNet_race_sequence) { |
||
268 | static tFlicette flicker_on[4] = { |
||
269 | { 43, { 60, 120 }, { 154, 370 } }, |
||
270 | { 43, { 221, 442 }, { 154, 370 } }, |
||
271 | { 221, { 30, 60 }, { 78, 187 } }, |
||
272 | { 221, { 30, 60 }, { 78, 187 } }, |
||
273 | }; |
||
274 | static tFlicette flicker_off[4] = { |
||
275 | { 42, { 60, 120 }, { 154, 370 } }, |
||
276 | { 42, { 221, 442 }, { 154, 370 } }, |
||
277 | { 220, { 30, 60 }, { 78, 187 } }, |
||
278 | { 220, { 30, 60 }, { 78, 187 } }, |
||
279 | }; |
||
280 | static tFlicette push[4] = { |
||
281 | { 154, { 60, 120 }, { 154, 370 } }, |
||
282 | { 45, { 221, 442 }, { 154, 370 } }, |
||
283 | { 222, { 30, 60 }, { 78, 187 } }, |
||
284 | { 225, { 30, 60 }, { 118, 283 } }, |
||
285 | }; |
||
286 | static tMouse_area mouse_areas[5] = { |
||
287 | { { 60, 120 }, { 154, 370 }, { 125, 250 }, { 174, 418 }, 0, 0, 0, NULL }, |
||
288 | { { 221, 442 }, { 154, 370 }, { 286, 572 }, { 174, 418 }, 1, 0, 0, NULL }, |
||
289 | { { 30, 60 }, { 78, 187 }, { 45, 90 }, { 104, 250 }, -1, 0, 0, UpClickRace }, |
||
290 | { { 30, 60 }, { 118, 283 }, { 45, 90 }, { 145, 348 }, -1, 0, 0, DownClickRace }, |
||
291 | { { 66, 132 }, { 33, 79 }, { 278, 556 }, { 144, 346 }, -1, 0, 0, ClickOnRace }, |
||
292 | }; |
||
293 | static tInterface_spec interface_spec = { |
||
294 | 0, 230, 60, 231, 231, 231, 6, |
||
295 | { -1, 0 }, { -1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL }, |
||
296 | { -1, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL }, |
||
297 | { -1, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { UpRace, NULL }, |
||
298 | { -1, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { DownRace, NULL }, |
||
299 | { 1, 1 }, { NULL, NULL }, { 1, 1 }, { NULL, NULL }, |
||
300 | NULL, NULL, 0, NULL, StartChangeRace, NULL, 0, { 0, 0 }, |
||
301 | NULL, 1, 1, COUNT_OF(flicker_on), flicker_on, flicker_off, push, |
||
302 | COUNT_OF(mouse_areas), mouse_areas, 0, NULL |
||
303 | }; |
||
304 | int result; |
||
305 | LOG_TRACE("(%p, %d, %d)", pRace_index, pNet_mode, pNet_race_sequence); |
||
306 | |||
307 | gNet_race_sequence__racestrt = pNet_race_sequence; |
||
308 | gChange_race_net_mode = pNet_mode; |
||
309 | gStart_interface_spec = &interface_spec; |
||
310 | gCurrent_race_index = *pRace_index; |
||
311 | if (pNet_mode == 0) { |
||
312 | gBullet_image = LoadPixelmap("BULLET.PIX"); |
||
313 | } else { |
||
314 | gBullet_image = NULL; |
||
315 | } |
||
316 | result = DoInterfaceScreen(&interface_spec, pNet_mode != 0, 0); |
||
317 | if (result == 0) { |
||
318 | *pRace_index = gCurrent_race_index; |
||
319 | } |
||
320 | if (gBullet_image != NULL) { |
||
321 | BrPixelmapFree(gBullet_image); |
||
322 | } |
||
323 | return result == 0; |
||
324 | } |
||
325 | |||
326 | // IDA: void __cdecl DoChangeRace() |
||
327 | void DoChangeRace(void) { |
||
328 | LOG_TRACE("()"); |
||
329 | |||
330 | if (ChangeRace(&gProgram_state.current_race_index, 0, eNet_sequence_sequential) != 0) { |
||
331 | gProgram_state.current_race_index = gCurrent_race_index; |
||
332 | } |
||
333 | } |
||
334 | |||
335 | // IDA: void __usercall DrawCar(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>) |
||
336 | void DrawCar(int pCurrent_choice, int pCurrent_mode) { |
||
337 | char s[64]; |
||
338 | int text_x; |
||
339 | int text_width; |
||
340 | LOG_TRACE("(%d, %d)", pCurrent_choice, pCurrent_mode); |
||
341 | |||
342 | // Added by dethrace to ignore warnings about using sprintf without a literal format string |
||
343 | #ifndef _MSC_VER // Pierre-Marie Baty -- exclude MSVC |
||
344 | #pragma GCC diagnostic push |
||
345 | #pragma GCC diagnostic ignored "-Wformat-security" |
||
346 | #endif // !_MSC_VER |
||
347 | |||
348 | PollCarDetails(gChoose_car_net_game); |
||
349 | if (gChange_race_net_mode == 0) { |
||
350 | if (gProgram_state.number_of_cars == 1) { |
||
351 | sprintf(s, GetMiscString(kMiscString_NoOtherCarsToChooseFromYet)); |
||
352 | } else if (gProgram_state.cars_available[gCurrent_car_index] == gProgram_state.frank_or_anniness) { |
||
353 | sprintf(s, GetMiscString(kMiscString_YourOriginalCar)); |
||
354 | } else { |
||
355 | sprintf(s, "%s %s", GetMiscString(kMiscString_OriginalDriverWas), gOpponents[gProgram_state.cars_available[gCurrent_car_index]].name); |
||
356 | } |
||
357 | } else if (gCar_details[gProgram_state.cars_available[gCurrent_car_index]].ownership == eCar_owner_someone) { |
||
358 | sprintf(s, "%s %s", GetMiscString(kMiscString_THIS_CAR_ALREADY_TAKEN_BY), gCar_details[gProgram_state.cars_available[gCurrent_car_index]].name); |
||
359 | } else { |
||
360 | sprintf(s, GetMiscString(kMiscString_AVAILABLE)); |
||
361 | } |
||
362 | |||
363 | #ifndef _MSC_VER // Pierre-Marie Baty -- exclude MSVC |
||
364 | #pragma GCC diagnostic pop |
||
365 | #endif // !_MSC_VER |
||
366 | |||
367 | text_width = BrPixelmapTextWidth(gBack_screen, gFont_7, s); |
||
368 | text_x = (gCurrent_graf_data->change_car_line_right + gCurrent_graf_data->change_car_line_left - text_width) / 2; |
||
369 | BrPixelmapRectangleFill(gBack_screen, |
||
370 | gCurrent_graf_data->change_car_line_left, |
||
371 | gCurrent_graf_data->change_car_text_y, |
||
372 | gCurrent_graf_data->change_car_line_right - gCurrent_graf_data->change_car_line_left, |
||
373 | gFont_7->glyph_y, |
||
374 | 0); |
||
375 | TransBrPixelmapText(gBack_screen, |
||
376 | text_x, |
||
377 | gCurrent_graf_data->change_car_text_y, |
||
378 | 3, |
||
379 | gFont_7, |
||
380 | s); |
||
381 | BrPixelmapLine(gBack_screen, |
||
382 | gCurrent_graf_data->change_car_line_left, |
||
383 | gCurrent_graf_data->change_car_line_y, |
||
384 | gCurrent_graf_data->change_car_line_right, |
||
385 | gCurrent_graf_data->change_car_line_y, |
||
386 | 6); |
||
387 | if (gChange_race_net_mode && gCar_details[gProgram_state.cars_available[gCurrent_car_index]].ownership == eCar_owner_someone) { |
||
388 | DRPixelmapRectangleMaskedCopy( |
||
389 | gBack_screen, |
||
390 | (gCurrent_graf_data->change_car_panel_left + gCurrent_graf_data->change_car_panel_right - gTaken_image->width) / 2, |
||
391 | (gCurrent_graf_data->change_car_panel_bottom + gCurrent_graf_data->change_car_panel_bottom - gTaken_image->height) / 2, |
||
392 | gTaken_image, |
||
393 | 0, |
||
394 | 0, |
||
395 | gTaken_image->width, |
||
396 | gTaken_image->height); |
||
397 | } |
||
398 | } |
||
399 | |||
400 | // IDA: void __cdecl SetCarFlic() |
||
401 | void SetCarFlic(void) { |
||
402 | LOG_TRACE("()"); |
||
403 | |||
404 | ChangePanelFlic(0, |
||
405 | gOpponents[gProgram_state.cars_available[gCurrent_car_index]].stolen_car_image_data, |
||
406 | gOpponents[gProgram_state.cars_available[gCurrent_car_index]].stolen_car_image_data_length); |
||
407 | } |
||
408 | |||
409 | // IDA: int __usercall UpCar@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
410 | int UpCar(int* pCurrent_choice, int* pCurrent_mode) { |
||
411 | LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
412 | |||
413 | AddToFlicQueue(gStart_interface_spec->pushed_flics[2].flic_index, |
||
414 | gStart_interface_spec->pushed_flics[2].x[gGraf_data_index], |
||
415 | gStart_interface_spec->pushed_flics[2].y[gGraf_data_index], |
||
416 | 1); |
||
417 | DRS3StartSound(gEffects_outlet, 3000); |
||
418 | if (gCurrent_car_index != 0) { |
||
419 | RemoveTransientBitmaps(1); |
||
420 | DropOutImageThruBottom(GetPanelPixelmap(0), |
||
421 | gCurrent_graf_data->change_car_panel_left, |
||
422 | gCurrent_graf_data->change_car_panel_top, |
||
423 | gCurrent_graf_data->change_car_panel_top_clip, |
||
424 | gCurrent_graf_data->change_car_panel_bottom_clip); |
||
425 | gCurrent_car_index--; |
||
426 | SetCarFlic(); |
||
427 | DropInImageFromTop(GetPanelPixelmap(0), |
||
428 | gCurrent_graf_data->change_car_panel_left, |
||
429 | gCurrent_graf_data->change_car_panel_top, |
||
430 | gCurrent_graf_data->change_car_panel_top_clip, |
||
431 | gCurrent_graf_data->change_car_panel_bottom_clip); |
||
432 | } |
||
433 | return 0; |
||
434 | } |
||
435 | |||
436 | // IDA: int __usercall DownCar@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
437 | int DownCar(int* pCurrent_choice, int* pCurrent_mode) { |
||
438 | LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
439 | |||
440 | AddToFlicQueue(gStart_interface_spec->pushed_flics[3].flic_index, |
||
441 | gStart_interface_spec->pushed_flics[3].x[gGraf_data_index], |
||
442 | gStart_interface_spec->pushed_flics[3].y[gGraf_data_index], |
||
443 | 1); |
||
444 | DRS3StartSound(gEffects_outlet, 3000); |
||
445 | if (gCurrent_car_index < gProgram_state.number_of_cars - 1) { |
||
446 | RemoveTransientBitmaps(1); |
||
447 | DropOutImageThruTop(GetPanelPixelmap(0), |
||
448 | gCurrent_graf_data->change_car_panel_left, |
||
449 | gCurrent_graf_data->change_car_panel_top, |
||
450 | gCurrent_graf_data->change_car_panel_top_clip, |
||
451 | gCurrent_graf_data->change_car_panel_bottom_clip); |
||
452 | gCurrent_car_index++; |
||
453 | SetCarFlic(); |
||
454 | DropInImageFromBottom(GetPanelPixelmap(0), |
||
455 | gCurrent_graf_data->change_car_panel_left, |
||
456 | gCurrent_graf_data->change_car_panel_top, |
||
457 | gCurrent_graf_data->change_car_panel_top_clip, |
||
458 | gCurrent_graf_data->change_car_panel_bottom_clip); |
||
459 | } |
||
460 | return 0; |
||
461 | } |
||
462 | |||
463 | // IDA: int __usercall UpClickCar@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>) |
||
464 | int UpClickCar(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) { |
||
465 | LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset); |
||
466 | |||
467 | UpCar(pCurrent_choice, pCurrent_mode); |
||
468 | return 0; |
||
469 | } |
||
470 | |||
471 | // IDA: int __usercall DownClickCar@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>) |
||
472 | int DownClickCar(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) { |
||
473 | LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset); |
||
474 | |||
475 | DownCar(pCurrent_choice, pCurrent_mode); |
||
476 | return 0; |
||
477 | } |
||
478 | |||
479 | // IDA: int __usercall ChangeCarGoAhead@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
480 | int ChangeCarGoAhead(int* pCurrent_choice, int* pCurrent_mode) { |
||
481 | LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
482 | |||
483 | if (gChange_race_net_mode == 0 || gCar_details[gProgram_state.cars_available[gCurrent_car_index]].ownership != eCar_owner_someone) { |
||
484 | return 1; |
||
485 | } else { |
||
486 | DRS3StartSound(gEffects_outlet, 3100); |
||
487 | return 0; |
||
488 | } |
||
489 | } |
||
490 | |||
491 | // IDA: int __usercall ChangeCar@<EAX>(int pNet_mode@<EAX>, int *pCar_index@<EDX>, tNet_game_details *pNet_game@<EBX>) |
||
492 | int ChangeCar(int pNet_mode, int* pCar_index, tNet_game_details* pNet_game) { |
||
493 | static tFlicette flicker_on[4] = { |
||
494 | { 43, { 60, 120 }, { 154, 370 } }, |
||
495 | { 43, { 221, 442 }, { 154, 370 } }, |
||
496 | { 221, { 30, 60 }, { 78, 187 } }, |
||
497 | { 221, { 30, 60 }, { 78, 187 } }, |
||
498 | }; |
||
499 | static tFlicette flicker_off[4] = { |
||
500 | { 42, { 60, 120 }, { 154, 370 } }, |
||
501 | { 42, { 221, 442 }, { 154, 370 } }, |
||
502 | { 220, { 30, 60 }, { 78, 187 } }, |
||
503 | { 220, { 30, 60 }, { 78, 187 } }, |
||
504 | }; |
||
505 | static tFlicette push[4] = { |
||
506 | { 154, { 60, 120 }, { 154, 370 } }, |
||
507 | { 45, { 221, 442 }, { 154, 370 } }, |
||
508 | { 222, { 30, 60 }, { 78, 187 } }, |
||
509 | { 225, { 30, 60 }, { 118, 283 } }, |
||
510 | }; |
||
511 | static tMouse_area mouse_areas[4] = { |
||
512 | { { 60, 120 }, { 154, 370 }, { 125, 250 }, { 174, 418 }, 0, 0, 0, NULL }, |
||
513 | { { 221, 442 }, { 154, 370 }, { 286, 572 }, { 174, 418 }, 1, 0, 0, NULL }, |
||
514 | { { 30, 60 }, { 78, 187 }, { 45, 90 }, { 104, 250 }, -1, 0, 0, UpClickCar }, |
||
515 | { { 30, 60 }, { 118, 283 }, { 45, 90 }, { 145, 348 }, -1, 0, 0, DownClickCar }, |
||
516 | }; |
||
517 | static tInterface_spec interface_spec = { |
||
518 | 0, |
||
519 | 236, |
||
520 | 62, |
||
521 | 0, |
||
522 | 0, |
||
523 | 0, |
||
524 | -1, |
||
525 | { -1, 0 }, |
||
526 | { -1, 0 }, |
||
527 | { 0, 0 }, |
||
528 | { 1, 0 }, |
||
529 | { NULL, NULL }, |
||
530 | { -1, 0 }, |
||
531 | { 1, 0 }, |
||
532 | { 0, 0 }, |
||
533 | { 1, 0 }, |
||
534 | { NULL, NULL }, |
||
535 | { -1, 0 }, |
||
536 | { 0, 0 }, |
||
537 | { 0, 0 }, |
||
538 | { 0, 0 }, |
||
539 | { UpCar, NULL }, |
||
540 | { -1, 0 }, |
||
541 | { 0, 0 }, |
||
542 | { 0, 0 }, |
||
543 | { 0, 0 }, |
||
544 | { DownCar, NULL }, |
||
545 | { 1, 1 }, |
||
546 | { ChangeCarGoAhead, NULL }, |
||
547 | { 1, 1 }, |
||
548 | { NULL, NULL }, |
||
549 | NULL, |
||
550 | DrawCar, |
||
551 | 0, |
||
552 | NULL, |
||
553 | NULL, |
||
554 | NULL, |
||
555 | 0, |
||
556 | { 0, 0 }, |
||
557 | NULL, |
||
558 | 1, |
||
559 | 1, |
||
560 | COUNT_OF(flicker_on), |
||
561 | flicker_on, |
||
562 | flicker_off, |
||
563 | push, |
||
564 | COUNT_OF(mouse_areas), |
||
565 | mouse_areas, |
||
566 | 0, |
||
567 | NULL, |
||
568 | }; |
||
569 | int i; |
||
570 | int result; |
||
571 | int power_up_levels[3]; |
||
572 | LOG_TRACE("(%d, %p, %p)", pNet_mode, pCar_index, pNet_game); |
||
573 | |||
574 | gChoose_car_net_game = pNet_game; |
||
575 | gChange_race_net_mode = pNet_mode; |
||
576 | gStart_interface_spec = &interface_spec; |
||
577 | for (i = 0; i < gProgram_state.number_of_cars; i++) { |
||
578 | if (gProgram_state.cars_available[i] == *pCar_index) { |
||
579 | gCurrent_car_index = i; |
||
580 | break; |
||
581 | } |
||
582 | } |
||
583 | if (gProgram_state.game_completed) { |
||
584 | gProgram_state.number_of_cars = gNumber_of_racers; |
||
585 | for (i = 0; i < gProgram_state.number_of_cars; i++) { |
||
586 | gProgram_state.cars_available[i] = i; |
||
587 | } |
||
588 | } |
||
589 | for (i = 0; i < gProgram_state.number_of_cars; i++) { |
||
590 | if (gOpponents[gProgram_state.cars_available[i]].stolen_car_image_data == NULL) { |
||
591 | LoadFlicData(gOpponents[gProgram_state.cars_available[i]].stolen_car_flic_name, |
||
592 | &gOpponents[gProgram_state.cars_available[i]].stolen_car_image_data, |
||
593 | &gOpponents[gProgram_state.cars_available[i]].stolen_car_image_data_length); |
||
594 | } else { |
||
595 | MAMSLock((void**)&gOpponents[gProgram_state.cars_available[i]].stolen_car_image_data); |
||
596 | } |
||
597 | } |
||
598 | InitialiseFlicPanel(0, |
||
599 | gCurrent_graf_data->change_car_panel_left, |
||
600 | gCurrent_graf_data->change_car_panel_top, |
||
601 | gCurrent_graf_data->change_car_panel_right - gCurrent_graf_data->change_car_panel_left, |
||
602 | gCurrent_graf_data->change_car_panel_bottom - gCurrent_graf_data->change_car_panel_top); |
||
603 | SetCarFlic(); |
||
604 | if (pNet_mode) { |
||
605 | gTaken_image = LoadPixelmap("TAKEN.PIX"); |
||
606 | } |
||
607 | result = DoInterfaceScreen(&interface_spec, pNet_mode, 0); |
||
608 | if (pNet_mode) { |
||
609 | FadePaletteDown(); |
||
610 | } else { |
||
611 | RunFlic(237); |
||
612 | } |
||
613 | for (i = 0; i < gProgram_state.number_of_cars; i++) { |
||
614 | MAMSUnlock((void**)&gOpponents[gProgram_state.cars_available[i]].stolen_car_image_data); |
||
615 | } |
||
616 | DisposeFlicPanel(0); |
||
617 | if (pNet_mode) { |
||
618 | BrPixelmapFree(gTaken_image); |
||
619 | } |
||
620 | if (result == 0) { |
||
621 | if (pNet_mode) { |
||
18 | pmbaty | 622 | *pCar_index = gProgram_state.cars_available[gCurrent_car_index]; |
1 | pmbaty | 623 | } else { |
624 | AboutToLoadFirstCar(); |
||
625 | SwitchToRealResolution(); |
||
626 | for (i = 0; i < COUNT_OF(power_up_levels); i++) { |
||
627 | power_up_levels[i] = gProgram_state.current_car.power_up_levels[i]; |
||
628 | } |
||
629 | LoadCar(gOpponents[gProgram_state.cars_available[gCurrent_car_index]].car_file_name, |
||
630 | eDriver_local_human, |
||
631 | &gProgram_state.current_car, |
||
632 | gProgram_state.cars_available[gCurrent_car_index], |
||
633 | gProgram_state.player_name[gProgram_state.frank_or_anniness], |
||
634 | &gOur_car_storage_space); |
||
635 | for (i = 0; i < COUNT_OF(power_up_levels); i++) { |
||
636 | gProgram_state.current_car.power_up_levels[i] = power_up_levels[i]; |
||
637 | } |
||
638 | SwitchToLoresMode(); |
||
639 | SetCarStorageTexturingLevel(&gOur_car_storage_space, GetCarTexturingLevel(), eCTL_full); |
||
640 | DisposeRaceInfo(&gCurrent_race); |
||
641 | SelectOpponents(&gCurrent_race); |
||
642 | LoadRaceInfo(gProgram_state.current_race_index, &gCurrent_race); |
||
643 | } |
||
644 | return 1; |
||
645 | } else { |
||
646 | return 0; |
||
647 | } |
||
648 | } |
||
649 | |||
650 | // IDA: void __cdecl DoChangeCar() |
||
651 | void DoChangeCar(void) { |
||
652 | LOG_TRACE("()"); |
||
653 | |||
654 | ChangeCar(0, &gProgram_state.current_car.index, NULL); |
||
655 | } |
||
656 | |||
657 | // IDA: int __cdecl PartsShopRecommended() |
||
658 | int PartsShopRecommended(void) { |
||
659 | int running_cost; |
||
660 | int i; |
||
661 | int current_index; |
||
662 | int counter; |
||
663 | LOG_TRACE("()"); |
||
664 | |||
665 | running_cost = 0; |
||
666 | counter = 0; |
||
667 | for (i = 0; i < eParts_count; i++) { |
||
668 | current_index = gProgram_state.current_car.power_up_levels[i]; |
||
669 | if (current_index + 1 < gProgram_state.current_car.power_ups[i].number_of_parts && (gProgram_state.rank <= gProgram_state.current_car.power_ups[i].info[current_index + 1].rank_required || gProgram_state.game_completed)) { |
||
670 | running_cost += gProgram_state.current_car.power_ups[i].info[current_index + 1].prices[gProgram_state.skill_level]; |
||
671 | counter++; |
||
672 | } |
||
673 | } |
||
674 | return running_cost != 0 && ((float)running_cost / counter * 1.5f <= gProgram_state.credits); |
||
675 | } |
||
676 | |||
677 | // IDA: void __usercall CalcPartPrice(int pCategory@<EAX>, int pIndex@<EDX>, int *pPrice@<EBX>, int *pCost@<ECX>) |
||
678 | void CalcPartPrice(int pCategory, int pIndex, int* pPrice, int* pCost) { |
||
679 | //int current_value; // Pierre-Marie Baty -- unused variable |
||
680 | LOG_TRACE("(%d, %d, %p, %p)", pCategory, pIndex, pPrice, pCost); |
||
681 | |||
682 | *pPrice = gProgram_state.current_car.power_ups[pCategory].info[pIndex].prices[gProgram_state.skill_level]; |
||
683 | if (gProgram_state.current_car.power_up_levels[pCategory] == pIndex) { |
||
684 | *pCost = 0; |
||
685 | } else { |
||
686 | *pCost = *pPrice - 10 * (gRefund_rate * gProgram_state.current_car.power_ups[pCategory].info[gProgram_state.current_car.power_up_levels[pCategory]].prices[gProgram_state.skill_level] / 1000); |
||
687 | } |
||
688 | } |
||
689 | |||
690 | // IDA: int __usercall BuyPart@<EAX>(int pCategory@<EAX>, int pIndex@<EDX>) |
||
691 | int BuyPart(int pCategory, int pIndex) { |
||
692 | int price; |
||
693 | int cost; |
||
694 | LOG_TRACE("(%d, %d)", pCategory, pIndex); |
||
695 | |||
696 | CalcPartPrice(pCategory, pIndex, &price, &cost); |
||
697 | if (cost == 0) { |
||
698 | return 1; |
||
699 | } else if (gProgram_state.credits < cost) { |
||
700 | return 0; |
||
701 | } else { |
||
702 | gProgram_state.credits -= cost; |
||
703 | if (gProgram_state.credits > 999999) { |
||
704 | gProgram_state.credits = 999999; |
||
705 | } |
||
706 | gProgram_state.current_car.power_up_levels[pCategory] = pIndex; |
||
707 | return 1; |
||
708 | } |
||
709 | } |
||
710 | |||
711 | // IDA: void __cdecl DoAutoParts() |
||
712 | void DoAutoParts(void) { |
||
713 | int i; |
||
714 | int lowest_yet; |
||
715 | int lowest_one; |
||
716 | int price; |
||
717 | int cost; |
||
718 | int current_level; |
||
719 | LOG_TRACE("()"); |
||
720 | |||
721 | while (1) { |
||
722 | if (!PartsShopRecommended()) { |
||
723 | return; |
||
724 | } |
||
725 | lowest_yet = COUNT_OF(((tParts_spec*)NULL)->info); |
||
726 | for (i = 0; i < eParts_count; i++) { |
||
727 | current_level = gProgram_state.current_car.power_up_levels[i]; |
||
728 | if (current_level + 1 < gProgram_state.current_car.power_ups[i].number_of_parts && (gProgram_state.rank <= gProgram_state.current_car.power_ups[i].info[current_level + 1].rank_required || gProgram_state.game_completed)) { |
||
729 | CalcPartPrice(i, current_level + 1, &price, &cost); |
||
730 | if (cost != 0 && cost <= gProgram_state.credits && current_level < lowest_yet) { |
||
731 | lowest_one = i; |
||
732 | lowest_yet = current_level + 1; |
||
733 | } |
||
734 | } |
||
735 | } |
||
736 | if (lowest_yet == COUNT_OF(((tParts_spec*)NULL)->info)) { |
||
737 | break; |
||
738 | } |
||
739 | if (!BuyPart(lowest_one, lowest_yet)) { |
||
740 | return; |
||
741 | } |
||
742 | } |
||
743 | } |
||
744 | |||
745 | // IDA: void __cdecl DrawPartsLabel() |
||
746 | void DrawPartsLabel(void) { |
||
747 | LOG_TRACE("()"); |
||
748 | |||
749 | switch (gPart_category) { |
||
750 | case eParts_armour: |
||
751 | RunFlicAt(262, gCurrent_graf_data->parts_label_x, gCurrent_graf_data->parts_label_y); |
||
752 | break; |
||
753 | case eParts_power: |
||
754 | RunFlicAt(263, gCurrent_graf_data->parts_label_x, gCurrent_graf_data->parts_label_y); |
||
755 | break; |
||
756 | case eParts_offensive: |
||
757 | RunFlicAt(264, gCurrent_graf_data->parts_label_x, gCurrent_graf_data->parts_label_y); |
||
758 | break; |
||
759 | default: |
||
760 | break; |
||
761 | } |
||
762 | } |
||
763 | |||
764 | // IDA: void __usercall ErasePartsText(int pTotal_as_well@<EAX>) |
||
765 | void ErasePartsText(int pTotal_as_well) { |
||
766 | LOG_TRACE("(%d)", pTotal_as_well); |
||
767 | |||
768 | BrPixelmapRectangleFill(gBack_screen, |
||
769 | gCurrent_graf_data->parts_cost_x, |
||
770 | gCurrent_graf_data->parts_cost_y, |
||
771 | gCurrent_graf_data->parts_image_width - (gCurrent_graf_data->parts_cost_x - gCurrent_graf_data->parts_image_x), |
||
772 | gFont_7->glyph_y + gCurrent_graf_data->parts_net_y - gCurrent_graf_data->parts_cost_y, |
||
773 | 0); |
||
774 | if (pTotal_as_well) { |
||
775 | BrPixelmapRectangleFill(gBack_screen, |
||
776 | gCurrent_graf_data->parts_total_x, |
||
777 | gCurrent_graf_data->parts_total_y, |
||
778 | gCurrent_graf_data->parts_image_width - (gCurrent_graf_data->parts_total_x - gCurrent_graf_data->parts_image_x), |
||
779 | gFont_7->glyph_y, |
||
780 | 0); |
||
781 | } |
||
782 | } |
||
783 | |||
784 | // IDA: void __cdecl DrawPartsText() |
||
785 | void DrawPartsText(void) { |
||
786 | int price; |
||
787 | int cost; |
||
788 | LOG_TRACE("()"); |
||
789 | |||
790 | CalcPartPrice(gPart_category, gPart_index, &price, &cost); |
||
791 | TransBrPixelmapText(gBack_screen, gCurrent_graf_data->parts_cost_x, gCurrent_graf_data->parts_cost_y, 5, gFont_7, GetMiscString(kMiscString_RetailColon)); |
||
792 | BrPixelmapTextF(gBack_screen, gCurrent_graf_data->parts_numbers_x, gCurrent_graf_data->parts_cost_y - (TranslationMode() ? 2 : 0), 5, gFont_7, "%d", price); |
||
793 | if (cost > 0) { |
||
794 | TransBrPixelmapText(gBack_screen, gCurrent_graf_data->parts_net_x, gCurrent_graf_data->parts_net_y, 45, gFont_7, GetMiscString(kMiscString_YouPayColon)); |
||
795 | BrPixelmapTextF(gBack_screen, gCurrent_graf_data->parts_numbers_x, gCurrent_graf_data->parts_net_y - (TranslationMode() ? 2 : 0), 45, gFont_7, "%d", cost); |
||
796 | } else if (cost < 0) { |
||
797 | TransBrPixelmapText(gBack_screen, gCurrent_graf_data->parts_net_x, gCurrent_graf_data->parts_net_y, 201, gFont_7, GetMiscString(kMiscString_RefundColon)); |
||
798 | BrPixelmapTextF(gBack_screen, gCurrent_graf_data->parts_numbers_x, gCurrent_graf_data->parts_net_y - (TranslationMode() ? 2 : 0), 201, gFont_7, "%d", -cost); |
||
799 | } else if (gJust_bought_part) { |
||
800 | TransBrPixelmapText(gBack_screen, gCurrent_graf_data->parts_net_x, gCurrent_graf_data->parts_net_y, 134, gFont_7, GetMiscString(kMiscString_YouGotIt)); |
||
801 | } else { |
||
802 | TransBrPixelmapText(gBack_screen, gCurrent_graf_data->parts_net_x, gCurrent_graf_data->parts_net_y, 134, gFont_7, GetMiscString(kMiscString_YoursAlready)); |
||
803 | } |
||
804 | TransBrPixelmapText(gBack_screen, gCurrent_graf_data->parts_total_x, gCurrent_graf_data->parts_total_y, 2, gFont_7, GetMiscString(kMiscString_CreditsColon)); |
||
805 | BrPixelmapTextF(gBack_screen, gCurrent_graf_data->parts_numbers_x, gCurrent_graf_data->parts_total_y - (TranslationMode() ? 2 : 0), 2, gFont_7, "%d", gProgram_state.credits); |
||
806 | } |
||
807 | |||
808 | // IDA: void __cdecl SetPartsImage() |
||
809 | void SetPartsImage(void) { |
||
810 | LOG_TRACE("()"); |
||
811 | |||
812 | ChangePanelFlic(0, |
||
813 | gProgram_state.current_car.power_ups[gPart_category].info[gPart_index].data_ptr, |
||
814 | gProgram_state.current_car.power_ups[gPart_category].info[gPart_index].data_length); |
||
815 | TellyInImage(GetPanelPixelmap(0), gCurrent_graf_data->parts_image_x, gCurrent_graf_data->parts_image_y); |
||
816 | DrawPartsText(); |
||
817 | } |
||
818 | |||
819 | // IDA: int __cdecl GetPartsMax() |
||
820 | int GetPartsMax(void) { |
||
821 | int i; |
||
822 | LOG_TRACE("()"); |
||
823 | |||
824 | for (i = gProgram_state.current_car.power_ups[gPart_category].number_of_parts - 1; i >= 0; i--) { |
||
825 | if (gProgram_state.rank <= gProgram_state.current_car.power_ups[gPart_category].info[i].rank_required) { |
||
826 | return i; |
||
827 | } |
||
828 | if (gProgram_state.game_completed) { |
||
829 | return i; |
||
830 | } |
||
831 | } |
||
832 | return 0; |
||
833 | } |
||
834 | |||
835 | // IDA: void __cdecl CalcPartsIndex() |
||
836 | void CalcPartsIndex(void) { |
||
837 | //int current_index; // Pierre-Marie Baty -- unused variable |
||
838 | LOG_TRACE("()"); |
||
839 | |||
840 | gPart_index = gProgram_state.current_car.power_up_levels[gPart_category]; |
||
841 | if (gPart_index + 1 < gProgram_state.current_car.power_ups[gPart_category].number_of_parts && (gProgram_state.rank <= gProgram_state.current_car.power_ups[gPart_category].info[gPart_index + 1].rank_required || gProgram_state.game_completed)) { |
||
842 | gPart_index += 1; |
||
843 | } |
||
844 | } |
||
845 | |||
846 | // IDA: void __cdecl DoExchangePart() |
||
847 | void DoExchangePart(void) { |
||
848 | int price; |
||
849 | int cost; |
||
850 | LOG_TRACE("()"); |
||
851 | |||
852 | CalcPartPrice(gPart_category, gPart_index, &price, &cost); |
||
853 | if (cost == 0 || gProgram_state.credits < cost) { |
||
854 | DRS3StartSound(gEffects_outlet, 3100); |
||
855 | } else { |
||
856 | gJust_bought_part = 1; |
||
857 | DRS3StartSound(gEffects_outlet, 3101); |
||
858 | BuyPart(gPart_category, gPart_index); |
||
859 | ErasePartsText(1); |
||
860 | DrawPartsText(); |
||
861 | } |
||
862 | } |
||
863 | |||
864 | // IDA: int __usercall PartsShopGoAhead@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
865 | int PartsShopGoAhead(int* pCurrent_choice, int* pCurrent_mode) { |
||
866 | //int flic_index; // Pierre-Marie Baty -- unused variable |
||
867 | LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
868 | |||
869 | if (*pCurrent_choice < 3 && *pCurrent_mode == 0) { |
||
870 | RemoveTransientBitmaps(1); |
||
871 | DontLetFlicFuckWithPalettes(); |
||
872 | TurnFlicTransparencyOn(); |
||
873 | RunFlicAt( |
||
874 | gStart_interface_spec->pushed_flics[*pCurrent_choice].flic_index, |
||
875 | gStart_interface_spec->pushed_flics[*pCurrent_choice].x[gGraf_data_index], |
||
876 | gStart_interface_spec->pushed_flics[*pCurrent_choice].y[gGraf_data_index]); |
||
877 | TurnFlicTransparencyOff(); |
||
878 | LetFlicFuckWithPalettes(); |
||
879 | gJust_bought_part = 0; |
||
880 | ErasePartsText(1); |
||
881 | TellyOutImage(GetPanelPixelmap(0), gCurrent_graf_data->parts_image_x, gCurrent_graf_data->parts_image_y); |
||
882 | gPart_category = *pCurrent_choice; |
||
883 | CalcPartsIndex(); |
||
884 | RunFlic(261); |
||
885 | AddToFlicQueue( |
||
886 | gStart_interface_spec->flicker_on_flics[*pCurrent_choice].flic_index, |
||
887 | gStart_interface_spec->flicker_on_flics[*pCurrent_choice].x[gGraf_data_index], |
||
888 | gStart_interface_spec->flicker_on_flics[*pCurrent_choice].y[gGraf_data_index], |
||
889 | 1); |
||
890 | DrawPartsLabel(); |
||
891 | SetPartsImage(); |
||
892 | ProcessFlicQueue(gFrame_period); |
||
893 | DoMouseCursor(); |
||
894 | PDScreenBufferSwap(0); |
||
895 | return 0; |
||
896 | } else if (*pCurrent_mode == 1) { |
||
897 | AddToFlicQueue( |
||
898 | gStart_interface_spec->flicker_on_flics[4].flic_index, |
||
899 | gStart_interface_spec->flicker_on_flics[4].x[gGraf_data_index], |
||
900 | gStart_interface_spec->flicker_on_flics[4].y[gGraf_data_index], |
||
901 | 1); |
||
902 | DoExchangePart(); |
||
903 | return 0; |
||
904 | } else { |
||
905 | return 1; |
||
906 | } |
||
907 | } |
||
908 | |||
909 | // IDA: int __usercall UpPart@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
910 | int UpPart(int* pCurrent_choice, int* pCurrent_mode) { |
||
911 | LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
912 | |||
913 | gJust_bought_part = 0; |
||
914 | AddToFlicQueue( |
||
915 | gStart_interface_spec->pushed_flics[5].flic_index, |
||
916 | gStart_interface_spec->pushed_flics[5].x[gGraf_data_index], |
||
917 | gStart_interface_spec->pushed_flics[5].y[gGraf_data_index], |
||
918 | 1); |
||
919 | DRS3StartSound(gEffects_outlet, 3000); |
||
920 | RemoveTransientBitmaps(1); |
||
921 | ErasePartsText(0); |
||
922 | |||
923 | gPart_index = (gPart_index == 0) ? GetPartsMax() : (gPart_index - 1); |
||
924 | |||
925 | DropOutImageThruBottom( |
||
926 | GetPanelPixelmap(0), |
||
927 | gCurrent_graf_data->parts_image_x, |
||
928 | gCurrent_graf_data->parts_image_y, |
||
929 | gCurrent_graf_data->parts_top_clip, |
||
930 | gCurrent_graf_data->parts_bottom_clip); |
||
931 | ChangePanelFlic(0, |
||
932 | gProgram_state.current_car.power_ups[gPart_category].info[gPart_index].data_ptr, |
||
933 | gProgram_state.current_car.power_ups[gPart_category].info[gPart_index].data_length); |
||
934 | DropInImageFromTop( |
||
935 | GetPanelPixelmap(0), |
||
936 | gCurrent_graf_data->parts_image_x, |
||
937 | gCurrent_graf_data->parts_image_y, |
||
938 | gCurrent_graf_data->parts_top_clip, |
||
939 | gCurrent_graf_data->parts_bottom_clip); |
||
940 | DrawPartsText(); |
||
941 | return 0; |
||
942 | } |
||
943 | |||
944 | // IDA: int __usercall DownPart@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
945 | int DownPart(int* pCurrent_choice, int* pCurrent_mode) { |
||
946 | LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
947 | |||
948 | gJust_bought_part = 0; |
||
949 | AddToFlicQueue( |
||
950 | gStart_interface_spec->pushed_flics[6].flic_index, |
||
951 | gStart_interface_spec->pushed_flics[6].x[gGraf_data_index], |
||
952 | gStart_interface_spec->pushed_flics[6].y[gGraf_data_index], |
||
953 | 1); |
||
954 | DRS3StartSound(gEffects_outlet, 3000); |
||
955 | RemoveTransientBitmaps(1); |
||
956 | ErasePartsText(0); |
||
957 | |||
958 | gPart_index = (gPart_index == GetPartsMax()) ? 0 : (gPart_index + 1); |
||
959 | |||
960 | DropOutImageThruTop( |
||
961 | GetPanelPixelmap(0), |
||
962 | gCurrent_graf_data->parts_image_x, |
||
963 | gCurrent_graf_data->parts_image_y, |
||
964 | gCurrent_graf_data->parts_top_clip, |
||
965 | gCurrent_graf_data->parts_bottom_clip); |
||
966 | ChangePanelFlic(0, |
||
967 | gProgram_state.current_car.power_ups[gPart_category].info[gPart_index].data_ptr, |
||
968 | gProgram_state.current_car.power_ups[gPart_category].info[gPart_index].data_length); |
||
969 | DropInImageFromBottom( |
||
970 | GetPanelPixelmap(0), |
||
971 | gCurrent_graf_data->parts_image_x, |
||
972 | gCurrent_graf_data->parts_image_y, |
||
973 | gCurrent_graf_data->parts_top_clip, |
||
974 | gCurrent_graf_data->parts_bottom_clip); |
||
975 | DrawPartsText(); |
||
976 | return 0; |
||
977 | } |
||
978 | |||
979 | // IDA: int __usercall UpClickPart@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>) |
||
980 | int UpClickPart(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) { |
||
981 | LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset); |
||
982 | |||
983 | UpPart(pCurrent_choice, pCurrent_mode); |
||
984 | return 0; |
||
985 | } |
||
986 | |||
987 | // IDA: int __usercall DownClickPart@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>) |
||
988 | int DownClickPart(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) { |
||
989 | LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset); |
||
990 | |||
991 | DownPart(pCurrent_choice, pCurrent_mode); |
||
992 | return 0; |
||
993 | } |
||
994 | |||
995 | // IDA: int __usercall PartsArrowsOn@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
996 | int PartsArrowsOn(int* pCurrent_choice, int* pCurrent_mode) { |
||
997 | LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
998 | |||
999 | AddToFlicQueue( |
||
1000 | gStart_interface_spec->flicker_on_flics[5].flic_index, |
||
1001 | gStart_interface_spec->flicker_on_flics[5].x[gGraf_data_index], |
||
1002 | gStart_interface_spec->flicker_on_flics[5].y[gGraf_data_index], |
||
1003 | 1); |
||
1004 | AddToFlicQueue(gStart_interface_spec->flicker_on_flics[6].flic_index, |
||
1005 | gStart_interface_spec->flicker_on_flics[6].x[gGraf_data_index], |
||
1006 | gStart_interface_spec->flicker_on_flics[6].y[gGraf_data_index], |
||
1007 | 1); |
||
1008 | return 0; |
||
1009 | } |
||
1010 | |||
1011 | // IDA: int __usercall PartsArrowsOff@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
1012 | int PartsArrowsOff(int* pCurrent_choice, int* pCurrent_mode) { |
||
1013 | LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
1014 | |||
1015 | AddToFlicQueue(gStart_interface_spec->flicker_off_flics[5].flic_index, |
||
1016 | gStart_interface_spec->flicker_off_flics[5].x[gGraf_data_index], |
||
1017 | gStart_interface_spec->flicker_off_flics[5].y[gGraf_data_index], |
||
1018 | 1); |
||
1019 | AddToFlicQueue(gStart_interface_spec->flicker_off_flics[6].flic_index, |
||
1020 | gStart_interface_spec->flicker_off_flics[6].x[gGraf_data_index], |
||
1021 | gStart_interface_spec->flicker_off_flics[6].y[gGraf_data_index], |
||
1022 | 1); |
||
1023 | return 0; |
||
1024 | } |
||
1025 | |||
1026 | // IDA: void __cdecl StartPartsShop() |
||
1027 | void StartPartsShop(void) { |
||
1028 | LOG_TRACE("()"); |
||
1029 | |||
1030 | DrawPartsLabel(); |
||
1031 | SetPartsImage(); |
||
1032 | } |
||
1033 | |||
1034 | // IDA: int __usercall DonePartsShop@<EAX>(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>, int pGo_ahead@<EBX>, int pEscaped@<ECX>, int pTimed_out) |
||
1035 | int DonePartsShop(int pCurrent_choice, int pCurrent_mode, int pGo_ahead, int pEscaped, int pTimed_out) { |
||
1036 | LOG_TRACE("(%d, %d, %d, %d, %d)", pCurrent_choice, pCurrent_mode, pGo_ahead, pEscaped, pTimed_out); |
||
1037 | |||
1038 | if (gFade_away_parts_shop) { |
||
1039 | FadePaletteDown(); |
||
1040 | } else { |
||
1041 | RunFlic(251); |
||
1042 | } |
||
1043 | return pGo_ahead; |
||
1044 | } |
||
1045 | |||
1046 | // IDA: void __usercall DrawPartsShop(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>) |
||
1047 | void DrawPartsShop(int pCurrent_choice, int pCurrent_mode) { |
||
1048 | LOG_TRACE("(%d, %d)", pCurrent_choice, pCurrent_mode); |
||
1049 | |||
1050 | DrawPartsText(); |
||
1051 | } |
||
1052 | |||
1053 | // IDA: void __usercall DoPartsShop(int pFade_away@<EAX>) |
||
1054 | void DoPartsShop(int pFade_away) { |
||
1055 | static tFlicette flicker_on[7] = { |
||
1056 | { 43, { 225, 450 }, { 30, 72 } }, |
||
1057 | { 43, { 225, 450 }, { 60, 144 } }, |
||
1058 | { 43, { 225, 450 }, { 89, 214 } }, |
||
1059 | { 43, { 225, 450 }, { 152, 365 } }, |
||
1060 | { 43, { 85, 170 }, { 152, 365 } }, |
||
1061 | { 221, { 30, 60 }, { 79, 190 } }, |
||
1062 | { 221, { 30, 60 }, { 79, 190 } }, |
||
1063 | }; |
||
1064 | static tFlicette flicker_off[7] = { |
||
1065 | { 42, { 225, 450 }, { 30, 72 } }, |
||
1066 | { 42, { 225, 450 }, { 60, 144 } }, |
||
1067 | { 42, { 225, 450 }, { 89, 214 } }, |
||
1068 | { 42, { 225, 450 }, { 152, 365 } }, |
||
1069 | { 42, { 85, 170 }, { 152, 365 } }, |
||
1070 | { 220, { 30, 60 }, { 79, 190 } }, |
||
1071 | { 220, { 30, 60 }, { 79, 190 } }, |
||
1072 | }; |
||
1073 | static tFlicette push[7] = { |
||
1074 | { 254, { 225, 450 }, { 30, 72 } }, |
||
1075 | { 255, { 225, 450 }, { 60, 144 } }, |
||
1076 | { 256, { 225, 450 }, { 89, 214 } }, |
||
1077 | { 154, { 225, 450 }, { 152, 365 } }, |
||
1078 | { 260, { 85, 170 }, { 152, 365 } }, |
||
1079 | { 222, { 30, 60 }, { 79, 190 } }, |
||
1080 | { 225, { 30, 60 }, { 120, 288 } }, |
||
1081 | }; |
||
1082 | static tMouse_area mouse_areas[7] = { |
||
1083 | { { 225, 450 }, { 30, 72 }, { 288, 576 }, { 50, 120 }, 0, 0, 0, NULL }, |
||
1084 | { { 225, 450 }, { 60, 144 }, { 288, 576 }, { 80, 192 }, 1, 0, 0, NULL }, |
||
1085 | { { 225, 450 }, { 89, 214 }, { 288, 576 }, { 109, 262 }, 2, 0, 0, NULL }, |
||
1086 | { { 225, 450 }, { 152, 365 }, { 288, 576 }, { 172, 413 }, 3, 0, 0, NULL }, |
||
1087 | { { 85, 170 }, { 152, 365 }, { 148, 296 }, { 172, 413 }, 4, 1, 0, NULL }, |
||
1088 | { { 30, 60 }, { 79, 190 }, { 45, 90 }, { 106, 254 }, -1, 1, 0, UpClickPart }, |
||
1089 | { { 30, 60 }, { 120, 288 }, { 45, 90 }, { 147, 353 }, -1, 1, 0, DownClickPart }, |
||
1090 | }; |
||
1091 | static tInterface_spec interface_spec = { |
||
1092 | 0, 250, 190, 0, 0, 0, 6, |
||
1093 | { 1, 0 }, { 4, -1 }, { 4, 0 }, { 4, 3 }, { PartsArrowsOn, PartsArrowsOff }, |
||
1094 | { 1, 0 }, { 4, -1 }, { 4, 0 }, { 4, 3 }, { PartsArrowsOn, PartsArrowsOff }, |
||
1095 | { -1, -1 }, { -1, 0 }, { 0, 4 }, { 3, 4 }, { NULL, UpPart }, |
||
1096 | { -1, -1 }, { 1, 0 }, { 0, 4 }, { 3, 4 }, { NULL, DownPart }, |
||
1097 | { 1, 1 }, { PartsShopGoAhead, PartsShopGoAhead }, |
||
1098 | { 1, 1 }, { NULL, NULL }, |
||
1099 | NULL, DrawPartsShop, 0, NULL, StartPartsShop, DonePartsShop, |
||
1100 | 0, { 0, 0 }, NULL, 3, 1, |
||
1101 | COUNT_OF(flicker_on), |
||
1102 | flicker_on, |
||
1103 | flicker_off, |
||
1104 | push, |
||
1105 | COUNT_OF(mouse_areas), |
||
1106 | mouse_areas, |
||
1107 | 0, |
||
1108 | NULL |
||
1109 | }; |
||
1110 | //int result; // Pierre-Marie Baty -- unused variable |
||
1111 | LOG_TRACE("(%d)", pFade_away); |
||
1112 | |||
1113 | LoadParts(); |
||
1114 | gFade_away_parts_shop = pFade_away; |
||
1115 | InitialiseFlicPanel(0, |
||
1116 | gCurrent_graf_data->parts_image_x, |
||
1117 | gCurrent_graf_data->parts_image_y, |
||
1118 | gCurrent_graf_data->parts_image_width, |
||
1119 | gCurrent_graf_data->parts_image_height); |
||
1120 | gStart_interface_spec = &interface_spec; |
||
1121 | gPart_category = eParts_armour; |
||
1122 | gJust_bought_part = 0; |
||
1123 | gRefund_rate = 75; |
||
1124 | CalcPartsIndex(); |
||
1125 | DoInterfaceScreen(&interface_spec, gFaded_palette, 3); |
||
1126 | DisposeFlicPanel(0); |
||
1127 | UnlockParts(); |
||
1128 | gProgram_state.parts_shop_visited = 1; |
||
1129 | } |
||
1130 | |||
1131 | // IDA: int __usercall AutoPartsDone@<EAX>(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>, int pGo_ahead@<EBX>, int pEscaped@<ECX>, int pTimed_out) |
||
1132 | int AutoPartsDone(int pCurrent_choice, int pCurrent_mode, int pGo_ahead, int pEscaped, int pTimed_out) { |
||
1133 | LOG_TRACE("(%d, %d, %d, %d, %d)", pCurrent_choice, pCurrent_mode, pGo_ahead, pEscaped, pTimed_out); |
||
1134 | |||
1135 | if (pEscaped) { |
||
1136 | pCurrent_choice = -1; |
||
1137 | } |
||
1138 | return pCurrent_choice; |
||
1139 | } |
||
1140 | |||
1141 | // IDA: tSO_result __cdecl DoAutoPartsShop() |
||
1142 | tSO_result DoAutoPartsShop(void) { |
||
1143 | static tFlicette flicker_on[3] = { |
||
1144 | { 43, { 84, 168 }, { 67, 161 } }, |
||
1145 | { 43, { 84, 168 }, { 95, 228 } }, |
||
1146 | { 43, { 84, 168 }, { 124, 298 } }, |
||
1147 | }; |
||
1148 | static tFlicette flicker_off[3] = { |
||
1149 | { 42, { 84, 168 }, { 67, 161 } }, |
||
1150 | { 42, { 84, 168 }, { 95, 228 } }, |
||
1151 | { 42, { 84, 168 }, { 124, 298 } }, |
||
1152 | }; |
||
1153 | static tFlicette push[3] = { |
||
1154 | { 284, { 84, 168 }, { 67, 161 } }, |
||
1155 | { 284, { 84, 168 }, { 95, 228 } }, |
||
1156 | { 284, { 84, 168 }, { 124, 298 } }, |
||
1157 | }; |
||
1158 | static tMouse_area mouse_areas[3] = { |
||
1159 | { { 84, 168 }, { 32, 77 }, { 147, 294 }, { 87, 209 }, 0, 0, 0, NULL }, |
||
1160 | { { 84, 168 }, { 95, 228 }, { 147, 294 }, { 115, 276 }, 1, 0, 0, NULL }, |
||
1161 | { { 84, 168 }, { 124, 298 }, { 147, 294 }, { 144, 346 }, 2, 0, 0, NULL }, |
||
1162 | }; |
||
1163 | static tInterface_spec interface_spec = { |
||
1164 | 0, 280, 0, 0, 0, 0, 6, |
||
1165 | { -1, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { NULL, NULL }, |
||
1166 | { -1, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { NULL, NULL }, |
||
1167 | { -1, -1 }, { -1, 0 }, { 0, 0 }, { 2, 0 }, { NULL, NULL }, |
||
1168 | { -1, -1 }, { 1, 0 }, { 0, 0 }, { 2, 0 }, { NULL, NULL }, |
||
1169 | { 1, 1 }, { NULL, NULL }, |
||
1170 | { 1, 1 }, { NULL, NULL }, |
||
1171 | NULL, NULL, 0, NULL, NULL, AutoPartsDone, 0, |
||
1172 | { 0, 0 }, NULL, -1, 1, |
||
1173 | COUNT_OF(flicker_on), flicker_on, flicker_off, push, |
||
1174 | COUNT_OF(mouse_areas), mouse_areas, |
||
1175 | 0, NULL |
||
1176 | }; |
||
1177 | int result; |
||
1178 | LOG_TRACE("()"); |
||
1179 | |||
1180 | gProgram_state.dont_load = 1; |
||
1181 | result = DoInterfaceScreen(&interface_spec, 0, gProgram_state.auto_parts_reply); |
||
1182 | gProgram_state.dont_load = 0; |
||
1183 | if (result < 0) { |
||
1184 | RunFlic(281); |
||
1185 | return eSO_main_menu_invoked; |
||
1186 | } else { |
||
1187 | gProgram_state.auto_parts_reply = result; |
||
1188 | switch (result) { |
||
1189 | case eAP_auto: |
||
1190 | DoAutoParts(); |
||
1191 | break; |
||
1192 | case eAP_manual: |
||
1193 | RunFlic(281); |
||
1194 | DoPartsShop(1); |
||
1195 | break; |
||
1196 | } |
||
1197 | FadePaletteDown(); |
||
1198 | return eSO_continue; |
||
1199 | } |
||
1200 | } |
||
1201 | |||
1202 | // IDA: void __cdecl SetOpponentFlic() |
||
1203 | void SetOpponentFlic(void) { |
||
1204 | LOG_TRACE("()"); |
||
1205 | ChangePanelFlic(0, |
||
1206 | gOpponents[gCurrent_race.opponent_list[gOpponent_index].index].mug_shot_image_data, |
||
1207 | gOpponents[gCurrent_race.opponent_list[gOpponent_index].index].mug_shot_image_data_length); |
||
1208 | } |
||
1209 | |||
1210 | // IDA: void __cdecl DrawSceneyMappyInfoVieweyThing() |
||
1211 | void DrawSceneyMappyInfoVieweyThing(void) { |
||
1212 | LOG_TRACE("()"); |
||
1213 | |||
1214 | RemoveTransientBitmaps(1); |
||
1215 | if (gProgram_state.view_type) { |
||
1216 | if (gProgram_state.view_type == eVT_Info) { |
||
1217 | ChangePanelFlic(0, gCurrent_race.info_image_data, gCurrent_race.info_image_data_length); |
||
1218 | } else if (gProgram_state.view_type == eVT_Opponents) { |
||
1219 | SetOpponentFlic(); |
||
1220 | } |
||
1221 | } else { |
||
1222 | ChangePanelFlic(0, gCurrent_race.scene_image_data, gCurrent_race.scene_image_data_length); |
||
1223 | } |
||
1224 | TellyInImage(GetPanelPixelmap(0), gCurrent_graf_data->start_race_panel_left, gCurrent_graf_data->start_race_panel_top); |
||
1225 | } |
||
1226 | |||
1227 | // IDA: void __cdecl DismissSceneyMappyInfoVieweyThing() |
||
1228 | void DismissSceneyMappyInfoVieweyThing(void) { |
||
1229 | LOG_TRACE("()"); |
||
1230 | |||
1231 | RemoveTransientBitmaps(1); |
||
1232 | TellyOutImage(GetPanelPixelmap(0), gCurrent_graf_data->start_race_panel_left, gCurrent_graf_data->start_race_panel_top); |
||
1233 | } |
||
1234 | |||
1235 | // IDA: int __usercall SelectRaceDone@<EAX>(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>, int pGo_ahead@<EBX>, int pEscaped@<ECX>, int pTimed_out) |
||
1236 | int SelectRaceDone(int pCurrent_choice, int pCurrent_mode, int pGo_ahead, int pEscaped, int pTimed_out) { |
||
1237 | LOG_TRACE("(%d, %d, %d, %d, %d)", pCurrent_choice, pCurrent_mode, pGo_ahead, pEscaped, pTimed_out); |
||
1238 | |||
1239 | DismissSceneyMappyInfoVieweyThing(); |
||
1240 | if (pEscaped) { |
||
1241 | return -1; |
||
1242 | } |
||
1243 | return pCurrent_choice; |
||
1244 | } |
||
1245 | |||
1246 | // IDA: int __usercall StartRaceGoAhead@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
1247 | int StartRaceGoAhead(int* pCurrent_choice, int* pCurrent_mode) { |
||
1248 | LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
1249 | |||
1250 | if (*pCurrent_choice != 1 || *pCurrent_mode) { |
||
1251 | return 1; |
||
1252 | } |
||
1253 | RemoveTransientBitmaps(1); |
||
1254 | DismissSceneyMappyInfoVieweyThing(); |
||
1255 | gProgram_state.view_type++; |
||
1256 | if (gProgram_state.view_type > eVT_Opponents) { |
||
1257 | gProgram_state.view_type = eVT_Scene; |
||
1258 | } |
||
1259 | if (gProgram_state.view_type) { |
||
1260 | if (gProgram_state.view_type == eVT_Info) { |
||
1261 | RunFlic(210); |
||
1262 | } else if (gProgram_state.view_type == eVT_Opponents) { |
||
1263 | RunFlic(212); |
||
1264 | } |
||
1265 | } else { |
||
1266 | RunFlic(213); |
||
1267 | } |
||
1268 | DrawSceneyMappyInfoVieweyThing(); |
||
1269 | return 0; |
||
1270 | } |
||
1271 | |||
1272 | // IDA: int __usercall TryToMoveToArrows@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
1273 | int TryToMoveToArrows(int* pCurrent_choice, int* pCurrent_mode) { |
||
1274 | LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
1275 | |||
1276 | if (gProgram_state.view_type != eVT_Opponents) { |
||
1277 | return 0; |
||
1278 | } |
||
1279 | *pCurrent_choice = 5; |
||
1280 | *pCurrent_mode = 1; |
||
1281 | DRS3StartSound(gEffects_outlet, 3000); |
||
1282 | return 1; |
||
1283 | } |
||
1284 | |||
1285 | // IDA: int __usercall UpOpponent@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
1286 | int UpOpponent(int* pCurrent_choice, int* pCurrent_mode) { |
||
1287 | LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
1288 | |||
1289 | #if defined(DETHRACE_FIX_BUGS) |
||
1290 | // fixes bug where racers could be scrolled in other race menu modes |
||
1291 | if (gProgram_state.view_type != eVT_Opponents) { |
||
1292 | return 0; |
||
1293 | } |
||
1294 | #endif |
||
1295 | AddToFlicQueue(gStart_interface_spec->pushed_flics[5].flic_index, |
||
1296 | gStart_interface_spec->pushed_flics[5].x[gGraf_data_index], |
||
1297 | gStart_interface_spec->pushed_flics[5].y[gGraf_data_index], |
||
1298 | 1); |
||
1299 | DRS3StartSound(gEffects_outlet, 3000); |
||
1300 | RemoveTransientBitmaps(1); |
||
1301 | DropOutImageThruBottom(GetPanelPixelmap(0), |
||
1302 | gCurrent_graf_data->start_race_panel_left, |
||
1303 | gCurrent_graf_data->start_race_panel_top, |
||
1304 | gCurrent_graf_data->start_race_panel_top_clip, |
||
1305 | gCurrent_graf_data->start_race_panel_bottom_clip); |
||
1306 | if (gOpponent_index == 0) { |
||
1307 | gOpponent_index = gCurrent_race.number_of_racers; |
||
1308 | } |
||
1309 | gOpponent_index--; |
||
1310 | SetOpponentFlic(); |
||
1311 | DropInImageFromTop(GetPanelPixelmap(0), |
||
1312 | gCurrent_graf_data->start_race_panel_left, |
||
1313 | gCurrent_graf_data->start_race_panel_top, |
||
1314 | gCurrent_graf_data->start_race_panel_top_clip, |
||
1315 | gCurrent_graf_data->start_race_panel_bottom_clip); |
||
1316 | return 0; |
||
1317 | } |
||
1318 | |||
1319 | // IDA: int __usercall DownOpponent@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
1320 | int DownOpponent(int* pCurrent_choice, int* pCurrent_mode) { |
||
1321 | LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
1322 | |||
1323 | #if defined(DETHRACE_FIX_BUGS) |
||
1324 | // fixes bug where racers could be scrolled in other race menu modes |
||
1325 | if (gProgram_state.view_type != eVT_Opponents) { |
||
1326 | return 0; |
||
1327 | } |
||
1328 | #endif |
||
1329 | AddToFlicQueue(gStart_interface_spec->pushed_flics[6].flic_index, |
||
1330 | gStart_interface_spec->pushed_flics[6].x[gGraf_data_index], |
||
1331 | gStart_interface_spec->pushed_flics[6].y[gGraf_data_index], |
||
1332 | 1); |
||
1333 | DRS3StartSound(gEffects_outlet, 3000); |
||
1334 | RemoveTransientBitmaps(1); |
||
1335 | DropOutImageThruTop(GetPanelPixelmap(0), |
||
1336 | gCurrent_graf_data->start_race_panel_left, |
||
1337 | gCurrent_graf_data->start_race_panel_top, |
||
1338 | gCurrent_graf_data->start_race_panel_top_clip, |
||
1339 | gCurrent_graf_data->start_race_panel_bottom_clip); |
||
1340 | gOpponent_index++; |
||
1341 | if (gOpponent_index == gCurrent_race.number_of_racers) { |
||
1342 | gOpponent_index = 0; |
||
1343 | } |
||
1344 | SetOpponentFlic(); |
||
1345 | DropInImageFromBottom(GetPanelPixelmap(0), |
||
1346 | gCurrent_graf_data->start_race_panel_left, |
||
1347 | gCurrent_graf_data->start_race_panel_top, |
||
1348 | gCurrent_graf_data->start_race_panel_top_clip, |
||
1349 | gCurrent_graf_data->start_race_panel_bottom_clip); |
||
1350 | return 0; |
||
1351 | } |
||
1352 | |||
1353 | // IDA: int __usercall UpClickOpp@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>) |
||
1354 | int UpClickOpp(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) { |
||
1355 | LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset); |
||
1356 | |||
1357 | UpOpponent(pCurrent_choice, pCurrent_mode); |
||
1358 | return 0; |
||
1359 | } |
||
1360 | |||
1361 | // IDA: int __usercall DownClickOpp@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>) |
||
1362 | int DownClickOpp(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) { |
||
1363 | LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset); |
||
1364 | |||
1365 | DownOpponent(pCurrent_choice, pCurrent_mode); |
||
1366 | return 0; |
||
1367 | } |
||
1368 | |||
1369 | // IDA: void __cdecl SelectRaceStart() |
||
1370 | void SelectRaceStart(void) { |
||
1371 | LOG_TRACE("()"); |
||
1372 | |||
1373 | DrawSceneyMappyInfoVieweyThing(); |
||
1374 | PrintMemoryDump(0, "INSIDE START RACE"); |
||
1375 | } |
||
1376 | |||
1377 | // IDA: int __cdecl SuggestRace() |
||
1378 | int SuggestRace(void) { |
||
1379 | int i; |
||
1380 | int least_done; |
||
1381 | int suggested_so_far; |
||
1382 | int suggested_race; |
||
1383 | int new_suggestion; |
||
1384 | int number_of_visits; |
||
1385 | LOG_TRACE("()"); |
||
1386 | |||
1387 | suggested_so_far = 32767; |
||
1388 | suggested_race = 0; |
||
1389 | if (gProgram_state.game_completed) { |
||
1390 | return IRandomBetween(0, gNumber_of_races - 1); |
||
1391 | } |
||
1392 | if (gProgram_state.redo_race_index >= 0) { |
||
1393 | return gProgram_state.redo_race_index; |
||
1394 | } |
||
1395 | for (i = 0; i < gNumber_of_races; i++) { |
||
1396 | if (gRace_list[i].suggested_rank <= suggested_so_far && gRace_list[i].suggested_rank >= gProgram_state.rank) { |
||
1397 | suggested_so_far = gRace_list[i].suggested_rank; |
||
1398 | suggested_race = i; |
||
1399 | } |
||
1400 | } |
||
1401 | number_of_visits = gRace_list[suggested_race].been_there_done_that; |
||
1402 | new_suggestion = suggested_race; |
||
1403 | |||
1404 | if (number_of_visits) { |
||
1405 | // Jeff: if we have already completed the suggested race, look backwards for a race that we haven't completed as many times |
||
1406 | for (i = suggested_race - 1; i >= 0 && i >= suggested_race - 5; i--) { |
||
1407 | if (gRace_list[i].rank_required < gProgram_state.rank || gRace_list[i].best_rank > gProgram_state.rank) { |
||
1408 | continue; |
||
1409 | } |
||
1410 | least_done = gRace_list[i].been_there_done_that < number_of_visits; |
||
1411 | if (!gRace_list[i].been_there_done_that |
||
1412 | || (least_done && suggested_race - 3 <= i)) { |
||
1413 | new_suggestion = i; |
||
1414 | number_of_visits = gRace_list[i].been_there_done_that; |
||
1415 | } |
||
1416 | } |
||
1417 | // Jeff: look forwards for a race that we haven't completed as many times as the previous suggestion |
||
1418 | for (i = suggested_race + 1; i < gNumber_of_races; i++) { |
||
1419 | least_done = gRace_list[i].been_there_done_that < number_of_visits; |
||
1420 | if (!least_done) { |
||
1421 | continue; |
||
1422 | } |
||
1423 | |||
1424 | if ((gRace_list[i].rank_required >= gProgram_state.rank && gRace_list[i].best_rank <= gProgram_state.rank) |
||
1425 | || gProgram_state.game_completed) { |
||
1426 | new_suggestion = i; |
||
1427 | number_of_visits = gRace_list[i].been_there_done_that; |
||
1428 | } |
||
1429 | } |
||
1430 | } |
||
1431 | return new_suggestion; |
||
1432 | } |
||
1433 | |||
1434 | // IDA: void __usercall SelectRaceDraw(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>) |
||
1435 | void SelectRaceDraw(int pCurrent_choice, int pCurrent_mode) { |
||
1436 | tOpponent* the_opponent; |
||
1437 | tText_chunk* the_chunk; |
||
1438 | int j; |
||
1439 | int k; |
||
1440 | int y_coord; |
||
1441 | //char s[256]; // Pierre-Marie Baty -- unused variable |
||
1442 | //char temp_str[256]; // Pierre-Marie Baty -- unused variable |
||
1443 | //char* sub_pt; // Pierre-Marie Baty -- unused variable |
||
1444 | //char sub_str[16]; // Pierre-Marie Baty -- unused variable |
||
1445 | tU32* test; |
||
1446 | static tU32 test2; |
||
1447 | LOG_TRACE8("(%d, %d)", pCurrent_choice, pCurrent_mode); |
||
1448 | |||
1449 | if (gProgram_state.view_type == eVT_Opponents) { |
||
1450 | the_opponent = &gOpponents[gCurrent_race.opponent_list[gOpponent_index].index]; |
||
1451 | for (j = 0; j < the_opponent->text_chunk_count; j++) { |
||
1452 | the_chunk = &the_opponent->text_chunks[j]; |
||
1453 | if (GetPanelFlicFrameIndex(0) >= the_chunk->frame_cue && GetPanelFlicFrameIndex(0) < the_chunk->frame_end) { |
||
1454 | y_coord = the_chunk->y_coord * gGraf_specs[gGraf_spec_index].total_height / 200 |
||
1455 | + gCurrent_graf_data->start_race_panel_top; |
||
1456 | for (k = 0; k < the_chunk->line_count; k++) { |
||
1457 | TransBrPixelmapText( |
||
1458 | gBack_screen, |
||
1459 | the_chunk->x_coord * gGraf_specs[gGraf_spec_index].total_width / 320 |
||
1460 | + gCurrent_graf_data->start_race_panel_left, |
||
1461 | y_coord, |
||
1462 | 201, |
||
1463 | gFont_7, |
||
1464 | the_chunk->text[k]); |
||
1465 | y_coord += gFont_7->glyph_y + gFont_7->glyph_y / 2; |
||
1466 | } |
||
1467 | } |
||
1468 | } |
||
1469 | } else if (gProgram_state.view_type == eVT_Info) { |
||
1470 | for (j = 0; j < gCurrent_race.text_chunk_count; j++) { |
||
1471 | the_chunk = &gCurrent_race.text_chunks[j]; |
||
1472 | if (GetPanelFlicFrameIndex(0) >= the_chunk->frame_cue && GetPanelFlicFrameIndex(0) < the_chunk->frame_end) { |
||
1473 | y_coord = the_chunk->y_coord * gGraf_specs[gGraf_spec_index].total_height / 200 |
||
1474 | + gCurrent_graf_data->start_race_panel_top; |
||
1475 | for (k = 0; k < the_chunk->line_count; k++) { |
||
1476 | TransBrPixelmapText( |
||
1477 | gBack_screen, |
||
1478 | the_chunk->x_coord * gGraf_specs[gGraf_spec_index].total_width / 320 |
||
1479 | + gCurrent_graf_data->start_race_panel_left, |
||
1480 | y_coord, |
||
1481 | 201, |
||
1482 | gFont_7, |
||
1483 | the_chunk->text[k]); |
||
1484 | y_coord += gFont_7->glyph_y + gFont_7->glyph_y / 2; |
||
1485 | } |
||
1486 | } |
||
1487 | } |
||
1488 | } |
||
1489 | test = KevKeyService(); |
||
1490 | if (*test) { |
||
1491 | test2 = *test; |
||
1492 | } |
||
1493 | if (test[0] == 0x27645433 && test[1] == 0x758f0015) { |
||
1494 | // cheat code: "KEVWOZEAR" |
||
1495 | gProgram_state.game_completed = 1; |
||
1496 | DRS3StartSound(gEffects_outlet, 3202); |
||
1497 | DRS3StartSound(gEffects_outlet, 3202); |
||
1498 | } |
||
1499 | if (test[0] == 0x33f75455 && test[1] == 0xC10AAAF2) { |
||
1500 | // cheat code: "IWANTTOFIDDLE" |
||
1501 | |||
1502 | char s[128]; |
||
1503 | FILE* f; |
||
1504 | size_t i; // Pierre-Marie Baty -- fixed type |
||
1505 | |||
1506 | // Jeff |
||
1507 | assert(strlen(gApplication_path) < 120); |
||
1508 | |||
1509 | PathCat(s, gApplication_path, "ACTORS"); |
||
1510 | PathCat(s, s, "PROG.ACT"); |
||
1511 | PDFileUnlock(s); |
||
1512 | f = fopen(s, "wb"); |
||
1513 | if (f != NULL) { |
||
1514 | DRS3StartSound(gEffects_outlet, 9000); |
||
1515 | if (gDecode_thing) { |
||
1516 | for (i = 0; i < strlen(gDecode_string); i++) { |
||
1517 | gDecode_string[i] -= 50; |
||
1518 | } |
||
1519 | fputs(gDecode_string, f); |
||
1520 | for (i = 0; i < strlen(gDecode_string); i++) { |
||
1521 | gDecode_string[i] += 50; |
||
1522 | } |
||
1523 | } else { |
||
1524 | for (i = 0; i < 20; i++) { |
||
1525 | fputs("*************", f); |
||
1526 | } |
||
1527 | } |
||
1528 | gDecode_thing ^= 0x40u; |
||
1529 | fclose(f); |
||
1530 | EncodeAllFilesInDirectory(""); |
||
1531 | EncodeAllFilesInDirectory("CARS"); |
||
1532 | EncodeAllFilesInDirectory("NONCARS"); |
||
1533 | EncodeAllFilesInDirectory("RACES"); |
||
1534 | EncodeAllFilesInDirectory("32X20X8"); |
||
1535 | EncodeAllFilesInDirectory("64X48X8"); |
||
1536 | PathCat(s, "32X20X8", "CARS"); |
||
1537 | EncodeAllFilesInDirectory(s); |
||
1538 | PathCat(s, "64X48X8", "CARS"); |
||
1539 | EncodeAllFilesInDirectory(s); |
||
1540 | PathCat(s, "32X20X8", "FONTS"); |
||
1541 | EncodeAllFilesInDirectory(s); |
||
1542 | PathCat(s, "64X48X8", "FONTS"); |
||
1543 | EncodeAllFilesInDirectory(s); |
||
1544 | } |
||
1545 | DRS3StartSound(gEffects_outlet, 9000); |
||
1546 | } |
||
1547 | } |
||
1548 | |||
1549 | // IDA: tSO_result __usercall DoSelectRace@<EAX>(int *pSecond_time_around@<EAX>) |
||
1550 | tSO_result DoSelectRace(int* pSecond_time_around) { |
||
1551 | static tFlicette flicker_on[7] = { |
||
1552 | { 43, { 224, 448 }, { 28, 67 } }, |
||
1553 | { 43, { 224, 448 }, { 56, 134 } }, |
||
1554 | { 43, { 224, 448 }, { 85, 204 } }, |
||
1555 | { 43, { 224, 448 }, { 113, 271 } }, |
||
1556 | { 43, { 224, 448 }, { 147, 353 } }, |
||
1557 | { 221, { 30, 60 }, { 79, 190 } }, |
||
1558 | { 221, { 30, 60 }, { 79, 190 } } |
||
1559 | }; |
||
1560 | |||
1561 | static tFlicette flicker_off[7] = { |
||
1562 | { 42, { 224, 448 }, { 28, 67 } }, |
||
1563 | { 42, { 224, 448 }, { 56, 134 } }, |
||
1564 | { 42, { 224, 448 }, { 85, 204 } }, |
||
1565 | { 42, { 224, 448 }, { 113, 271 } }, |
||
1566 | { 42, { 224, 448 }, { 147, 353 } }, |
||
1567 | { 220, { 30, 60 }, { 79, 190 } }, |
||
1568 | { 220, { 30, 60 }, { 79, 190 } } |
||
1569 | }; |
||
1570 | |||
1571 | static tFlicette push[7] = { |
||
1572 | { 195, { 224, 448 }, { 28, 67 } }, |
||
1573 | { -1, { 224, 448 }, { 56, 134 } }, |
||
1574 | { 200, { 224, 448 }, { 85, 204 } }, |
||
1575 | { 202, { 224, 448 }, { 113, 271 } }, |
||
1576 | { 201, { 224, 448 }, { 147, 353 } }, |
||
1577 | { 222, { 30, 60 }, { 79, 190 } }, |
||
1578 | { 225, { 30, 60 }, { 119, 286 } } |
||
1579 | }; |
||
1580 | |||
1581 | static tMouse_area mouse_areas[7] = { |
||
1582 | { { 224, 448 }, { 28, 67 }, { 287, 574 }, { 48, 115 }, 0, 0, 0, NULL }, |
||
1583 | { { 224, 448 }, { 56, 134 }, { 287, 574 }, { 76, 182 }, 1, 0, 0, NULL }, |
||
1584 | { { 224, 448 }, { 85, 204 }, { 287, 574 }, { 105, 252 }, 2, 0, 0, NULL }, |
||
1585 | { { 224, 448 }, { 113, 271 }, { 287, 574 }, { 133, 319 }, 3, 0, 0, NULL }, |
||
1586 | { { 224, 448 }, { 147, 353 }, { 287, 574 }, { 167, 401 }, 4, 0, 0, NULL }, |
||
1587 | { { 30, 60 }, |
||
1588 | { 79, 190 }, |
||
1589 | { 45, 90 }, |
||
1590 | { 106, 254 }, |
||
1591 | -1, |
||
1592 | 0, |
||
1593 | 0, |
||
1594 | &UpClickOpp }, |
||
1595 | { { 30, 60 }, |
||
1596 | { 119, 286 }, |
||
1597 | { 45, 90 }, |
||
1598 | { 146, 350 }, |
||
1599 | -1, |
||
1600 | 0, |
||
1601 | 0, |
||
1602 | &DownClickOpp } |
||
1603 | }; |
||
1604 | |||
1605 | static tInterface_spec interface_spec = { |
||
1606 | 0, // initial_imode |
||
1607 | 191, // first_opening_flic |
||
1608 | 190, // second_opening_flic |
||
1609 | 0, // end_flic_go_ahead |
||
1610 | 0, // end_flic_escaped |
||
1611 | 0, // end_flic_otherwise |
||
1612 | 6, // flic_bunch_to_load |
||
1613 | { -1, 0 }, // move_left_new_mode |
||
1614 | { 0, -4 }, // move_left_delta |
||
1615 | { 0, 1 }, // move_left_min |
||
1616 | { 0, 1 }, // move_left_max |
||
1617 | { &TryToMoveToArrows, NULL }, // move_left_proc |
||
1618 | { -1, 0 }, // move_right_new_mode |
||
1619 | { 0, -4 }, // move_right_delta |
||
1620 | { 0, 1 }, // move_right_min |
||
1621 | { 0, 1 }, // move_right_max |
||
1622 | { &TryToMoveToArrows, NULL }, // move_right_proc |
||
1623 | { -1, -1 }, // move_up_new_mode |
||
1624 | { -1, 0 }, // move_up_delta |
||
1625 | { 0, 5 }, // move_up_min |
||
1626 | { 4, 5 }, // move_up_max |
||
1627 | { NULL, &UpOpponent }, // move_up_proc |
||
1628 | { -1, -1 }, // move_down_new_mode |
||
1629 | { 1, 0 }, // move_down_delta |
||
1630 | { 0, 5 }, // move_down_min |
||
1631 | { 4, 5 }, // move_down_max |
||
1632 | { NULL, &DownOpponent }, // move_down_proc |
||
1633 | { 1, 1 }, // go_ahead_allowed |
||
1634 | { &StartRaceGoAhead, NULL }, // go_ahead_proc |
||
1635 | { 1, 1 }, // escape_allowed |
||
1636 | { NULL, NULL }, // escape_proc |
||
1637 | NULL, // exit_proc |
||
1638 | &SelectRaceDraw, // draw_proc |
||
1639 | 0u, // time_out |
||
1640 | NULL, // start_proc1 |
||
1641 | &SelectRaceStart, // start_proc2 |
||
1642 | &SelectRaceDone, // done_proc |
||
1643 | 0, // font_needed |
||
1644 | { 0, 0 }, // typeable |
||
1645 | NULL, // get_original_string |
||
1646 | -1, // escape_code |
||
1647 | 1, // dont_save_or_load |
||
1648 | 7, // number_of_button_flics |
||
1649 | flicker_on, // flicker_on_flics |
||
1650 | flicker_off, // flicker_off_flics |
||
1651 | push, // pushed_flics |
||
1652 | 7, // number_of_mouse_areas |
||
1653 | mouse_areas, // mouse_areas |
||
1654 | 0, // number_of_recopy_areas |
||
1655 | NULL // recopy_areas |
||
1656 | }; |
||
1657 | |||
1658 | int result; |
||
1659 | //int default_choice; // Pierre-Marie Baty -- unused variable |
||
1660 | int suggested; |
||
1661 | int old_current_race; |
||
1662 | LOG_TRACE("(%p)", pSecond_time_around); |
||
1663 | |||
1664 | suggested = SuggestRace(); |
||
1665 | if (!*pSecond_time_around) { |
||
1666 | gProgram_state.current_race_index = suggested; |
||
1667 | SelectOpponents(&gCurrent_race); |
||
1668 | } |
||
1669 | gProgram_state.parts_shop_visited = 0; |
||
1670 | gProgram_state.dont_load = 1; |
||
1671 | gDeceased_image = LoadPixelmap("DECEASED.PIX"); |
||
1672 | InitialiseFlicPanel( |
||
1673 | 0, |
||
1674 | gCurrent_graf_data->start_race_panel_left, |
||
1675 | gCurrent_graf_data->start_race_panel_top, |
||
1676 | gCurrent_graf_data->start_race_panel_right - gCurrent_graf_data->start_race_panel_left, |
||
1677 | gCurrent_graf_data->start_race_panel_bottom - gCurrent_graf_data->start_race_panel_top); |
||
1678 | LoadRaceInfo(gProgram_state.current_race_index, &gCurrent_race); |
||
1679 | do { |
||
1680 | gProgram_state.view_type = 0; |
||
1681 | gOpponent_index = 0; |
||
1682 | gStart_interface_spec = &interface_spec; |
||
1683 | if (gFaded_palette || gCurrent_splash) { |
||
1684 | result = DoInterfaceScreen(&interface_spec, 1, 4); |
||
1685 | } else { |
||
1686 | result = DoInterfaceScreen(&interface_spec, 0, 4); |
||
1687 | } |
||
1688 | |||
1689 | if (result == 0 || result == 2 || result == 3) { |
||
1690 | DisposeFlicPanel(0); |
||
1691 | |||
1692 | if (result == 2) { |
||
1693 | if (harness_game_info.mode == eGame_carmageddon_demo || harness_game_info.mode == eGame_splatpack_demo || harness_game_info.mode == eGame_splatpack_xmas_demo) { |
||
1694 | DoFeatureUnavailableInDemo(); |
||
1695 | } else { |
||
1696 | RunFlic(192); |
||
1697 | DoPartsShop(0); |
||
1698 | } |
||
1699 | } else if (result == 3) { |
||
1700 | RunFlic(192); |
||
1701 | DoChangeCar(); |
||
1702 | } else if (result == 0) { |
||
1703 | RunFlic(192); |
||
1704 | old_current_race = gProgram_state.current_race_index; |
||
1705 | DoChangeRace(); |
||
1706 | if (gProgram_state.current_race_index != old_current_race) { |
||
1707 | DisposeRaceInfo(&gCurrent_race); |
||
1708 | SelectOpponents(&gCurrent_race); |
||
1709 | LoadRaceInfo(gProgram_state.current_race_index, &gCurrent_race); |
||
1710 | } |
||
1711 | } |
||
1712 | InitialiseFlicPanel( |
||
1713 | 0, |
||
1714 | gCurrent_graf_data->start_race_panel_left, |
||
1715 | gCurrent_graf_data->start_race_panel_top, |
||
1716 | gCurrent_graf_data->start_race_panel_right - gCurrent_graf_data->start_race_panel_left, |
||
1717 | gCurrent_graf_data->start_race_panel_bottom - gCurrent_graf_data->start_race_panel_top); |
||
1718 | } |
||
1719 | } while (result >= 0 && result != 4); |
||
1720 | BrPixelmapFree(gDeceased_image); |
||
1721 | FillInRaceInfo(&gCurrent_race); |
||
1722 | DisposeRaceInfo(&gCurrent_race); |
||
1723 | DisposeFlicPanel(0); |
||
1724 | *pSecond_time_around = 1; |
||
1725 | gProgram_state.dont_load = 0; |
||
1726 | if (result >= 0) { |
||
1727 | *pSecond_time_around = 1; |
||
1728 | if (gProgram_state.parts_shop_visited || !PartsShopRecommended()) { |
||
1729 | FadePaletteDown(); |
||
1730 | return eSO_continue; |
||
1731 | } else { |
||
1732 | RunFlic(192); |
||
1733 | return DoAutoPartsShop(); |
||
1734 | } |
||
1735 | } else { |
||
1736 | RunFlic(192); |
||
1737 | gDisallow_abandon_race = 1; |
||
1738 | return eSO_main_menu_invoked; |
||
1739 | } |
||
1740 | } |
||
1741 | |||
1742 | // IDA: void __usercall DrawGridCar(int pX@<EAX>, int pY@<EDX>, br_pixelmap *pImage@<EBX>) |
||
1743 | void DrawGridCar(int pX, int pY, br_pixelmap* pImage) { |
||
1744 | LOG_TRACE("(%d, %d, %p)", pX, pY, pImage); |
||
1745 | |||
1746 | if (gCurrent_graf_data->grid_left_clip <= pX && pX + pImage->width < gCurrent_graf_data->grid_right_clip) { |
||
1747 | DRPixelmapRectangleMaskedCopy(gBack_screen, pX, pY, pImage, 0, 0, pImage->width, pImage->height); |
||
1748 | } |
||
1749 | } |
||
1750 | |||
1751 | // IDA: void __usercall DrawGrid(int pOffset@<EAX>, int pDraw_it@<EDX>) |
||
1752 | void DrawGrid(int pOffset, int pDraw_it) { |
||
1753 | int i; |
||
1754 | int j; |
||
1755 | int y; |
||
1756 | int x; |
||
1757 | int str_x; |
||
1758 | //int width_job; // Pierre-Marie Baty -- unused variable |
||
1759 | int done_highest; |
||
1760 | int str_index; |
||
1761 | int swap_1_x = 0; |
||
1762 | int swap_1_y = 0; |
||
1763 | int swap_2_x = 0; |
||
1764 | int swap_2_y = 0; |
||
1765 | br_pixelmap* the_image = NULL; |
||
1766 | br_pixelmap* swap_1_image = NULL; |
||
1767 | br_pixelmap* swap_2_image = NULL; |
||
1768 | char numbers_str[4][100]; |
||
1769 | char total_str[256]; |
||
1770 | tU32 the_time; |
||
1771 | LOG_TRACE("(%d, %d)", pOffset, pDraw_it); |
||
1772 | |||
1773 | done_highest = 0; |
||
1774 | str_index = 0; |
||
1775 | |||
1776 | memset(numbers_str, 0, sizeof(numbers_str)); |
||
1777 | memset(total_str, 0, sizeof(total_str)); |
||
1778 | |||
1779 | the_time = PDGetTotalTime(); |
||
1780 | BrPixelmapRectangleFill( |
||
1781 | gBack_screen, |
||
1782 | gCurrent_graf_data->grid_left_clip, |
||
1783 | gCurrent_graf_data->grid_top_clip, |
||
1784 | gCurrent_graf_data->grid_right_clip - gCurrent_graf_data->grid_left_clip, |
||
1785 | gCurrent_graf_data->grid_bottom_clip - gCurrent_graf_data->grid_top_clip, |
||
1786 | 0); |
||
1787 | for (i = 0; i < gCurrent_race.number_of_racers; i++) { |
||
1788 | if (gCurrent_race.opponent_list[i].index == -1) { |
||
1789 | the_image = gProgram_state.current_car.grid_icon_image; |
||
1790 | } else { |
||
1791 | the_image = gCurrent_race.opponent_list[i].car_spec->grid_icon_image; |
||
1792 | } |
||
1793 | y = gCurrent_graf_data->grid_top_y |
||
1794 | + i % 2 * gCurrent_graf_data->grid_y_pitch |
||
1795 | - the_image->height / 2 |
||
1796 | - gGrid_y_adjust; |
||
1797 | x = gCurrent_graf_data->grid_left_x |
||
1798 | + i % 2 * gCurrent_graf_data->grid_x_stagger |
||
1799 | + i / 2 * gCurrent_graf_data->grid_x_pitch |
||
1800 | - pOffset; |
||
1801 | if (i == gSwap_grid_1) { |
||
1802 | swap_1_x = x; |
||
1803 | swap_1_y = y; |
||
1804 | swap_1_image = the_image; |
||
1805 | } else if (i == gSwap_grid_2) { |
||
1806 | swap_2_x = x; |
||
1807 | swap_2_y = y; |
||
1808 | swap_2_image = the_image; |
||
1809 | } else if (gCurrent_race.opponent_list[i].index != -1 || the_time % 900 / 300) { |
||
1810 | DrawGridCar(x, y, the_image); |
||
1811 | } |
||
1812 | if (!done_highest && gCurrent_race.opponent_list[i].ranking >= gProgram_state.rank) { |
||
1813 | done_highest = 1; |
||
1814 | if (x - gCurrent_graf_data->grid_marker_margin >= gCurrent_graf_data->grid_left_clip |
||
1815 | && x + the_image->width < gCurrent_graf_data->grid_right_clip) { |
||
1816 | BrPixelmapLine( |
||
1817 | gBack_screen, |
||
1818 | x - gCurrent_graf_data->grid_marker_margin, |
||
1819 | y - gCurrent_graf_data->grid_marker_margin, |
||
1820 | x - gCurrent_graf_data->grid_marker_margin, |
||
1821 | y + gCurrent_graf_data->grid_marker_margin + the_image->height, |
||
1822 | 45); |
||
1823 | BrPixelmapLine( |
||
1824 | gBack_screen, |
||
1825 | x - gCurrent_graf_data->grid_marker_margin, |
||
1826 | y - gCurrent_graf_data->grid_marker_margin, |
||
1827 | x + gCurrent_graf_data->grid_marker_x_len, |
||
1828 | y - gCurrent_graf_data->grid_marker_margin, |
||
1829 | 45); |
||
1830 | BrPixelmapLine( |
||
1831 | gBack_screen, |
||
1832 | x - gCurrent_graf_data->grid_marker_margin, |
||
1833 | y + gCurrent_graf_data->grid_marker_margin + the_image->height, |
||
1834 | x + gCurrent_graf_data->grid_marker_x_len, |
||
1835 | y + gCurrent_graf_data->grid_marker_margin + the_image->height, |
||
1836 | 45); |
||
1837 | } |
||
1838 | } |
||
1839 | if (gCurrent_race.opponent_list[i].index < 0) { |
||
1840 | str_index = 2; |
||
1841 | } else if (gProgram_state.rank <= gCurrent_race.opponent_list[i].ranking) { |
||
1842 | if (str_index >= 2) { |
||
1843 | str_index = 3; |
||
1844 | } else { |
||
1845 | str_index = 1; |
||
1846 | } |
||
1847 | } |
||
1848 | if (gCurrent_race.opponent_list[i].index >= 0) { |
||
1849 | if (gOpponents[gCurrent_race.opponent_list[i].index].car_number <= 0 |
||
1850 | || gOpponents[gCurrent_race.opponent_list[i].index].car_number >= 100) { |
||
1851 | if (gOpponents[gCurrent_race.opponent_list[i].index].car_number < 0) { |
||
1852 | sprintf(&numbers_str[str_index][strlen(numbers_str[str_index])], "%c ", ':'); |
||
1853 | } |
||
1854 | } else { |
||
1855 | sprintf( |
||
1856 | &numbers_str[str_index][strlen(numbers_str[str_index])], |
||
1857 | "%d ", |
||
1858 | gOpponents[gCurrent_race.opponent_list[i].index].car_number); |
||
1859 | } |
||
1860 | } else { |
||
1861 | if (gProgram_state.frank_or_anniness == eAnnie) { |
||
1862 | sprintf(&numbers_str[str_index][strlen(numbers_str[str_index])], "%c ", '<'); |
||
1863 | } else { |
||
1864 | sprintf(&numbers_str[str_index][strlen(numbers_str[str_index])], "%c ", ';'); |
||
1865 | } |
||
1866 | } |
||
1867 | } |
||
1868 | if (gSwap_grid_1 >= 0) { |
||
1869 | DrawGridCar( |
||
1870 | gGrid_transition_stage * (swap_2_x - swap_1_x) / 100 + swap_1_x, |
||
1871 | gGrid_transition_stage * (swap_2_y - swap_1_y) / 100 + swap_1_y, |
||
1872 | swap_1_image); |
||
1873 | DrawGridCar( |
||
1874 | gGrid_transition_stage * (swap_1_x - swap_2_x) / 100 + swap_2_x, |
||
1875 | gGrid_transition_stage * (swap_1_y - swap_2_y) / 100 + swap_2_y, |
||
1876 | swap_2_image); |
||
1877 | } |
||
1878 | if (gDraw_grid_status == eGrid_draw_all) { |
||
1879 | if (strlen(numbers_str[3])) { |
||
1880 | numbers_str[3][strlen(numbers_str[3]) - 1] = '\0'; |
||
1881 | } else { |
||
1882 | numbers_str[2][strlen(numbers_str[2]) - 1] = '\0'; |
||
1883 | } |
||
1884 | strcpy(total_str, numbers_str[0]); |
||
1885 | for (i = 1; i < COUNT_OF(numbers_str); i++) { |
||
1886 | strcat(total_str, numbers_str[i]); |
||
1887 | } |
||
1888 | str_x = (gCurrent_graf_data->grid_numbers_left + gCurrent_graf_data->grid_numbers_right) / 2 |
||
1889 | - (BrPixelmapTextWidth(gBack_screen, gBig_font, total_str) / 2); |
||
1890 | BrPixelmapRectangleFill( |
||
1891 | gBack_screen, |
||
1892 | gCurrent_graf_data->grid_numbers_left, |
||
1893 | gCurrent_graf_data->grid_numbers_top, |
||
1894 | gCurrent_graf_data->grid_numbers_right - gCurrent_graf_data->grid_numbers_left, |
||
1895 | gBig_font->glyph_y, |
||
1896 | 0); |
||
1897 | gGrid_number_x_coords[0] = str_x - 3 - gCurrent_graf_data->grid_numbers_left; |
||
1898 | for (i = 0; i < 4; ++i) { |
||
1899 | if (i != 2 || the_time % 900 / 300) { |
||
1900 | TransBrPixelmapText( |
||
1901 | gBack_screen, |
||
1902 | str_x, |
||
1903 | gCurrent_graf_data->grid_numbers_top, |
||
1904 | gGrid_number_colour[i], |
||
1905 | gBig_font, |
||
1906 | numbers_str[i]); |
||
1907 | } |
||
1908 | str_x += BrPixelmapTextWidth(gBack_screen, gBig_font, numbers_str[i]); |
||
1909 | } |
||
1910 | for (i = gCurrent_race.number_of_racers - 1; i > 0; i--) { |
||
1911 | for (j = strlen(total_str) - 2; j >= 0; j--) { |
||
1912 | if (total_str[j] == ' ') { |
||
1913 | total_str[j + 1] = '\0'; |
||
1914 | break; |
||
1915 | } |
||
1916 | } |
||
1917 | gGrid_number_x_coords[i] = gGrid_number_x_coords[0] + BrPixelmapTextWidth(gBack_screen, gBig_font, total_str); |
||
1918 | } |
||
1919 | } |
||
1920 | if (pDraw_it) { |
||
1921 | PDScreenBufferSwap(0); |
||
1922 | } |
||
1923 | } |
||
1924 | |||
1925 | // IDA: void __usercall MoveGrid(int pFrom@<EAX>, int pTo@<EDX>, tS32 pTime_to_move@<EBX>) |
||
1926 | void MoveGrid(int pFrom, int pTo, tS32 pTime_to_move) { |
||
1927 | tS32 start_time; |
||
1928 | tS32 the_time; |
||
1929 | //int move_distance; // Pierre-Marie Baty -- unused variable |
||
1930 | int pitch; |
||
1931 | LOG_TRACE("(%d, %d, %d)", pFrom, pTo, pTime_to_move); |
||
1932 | |||
1933 | pitch = gCurrent_graf_data->grid_x_pitch; |
||
1934 | start_time = PDGetTotalTime(); |
||
1935 | while (1) { |
||
1936 | the_time = PDGetTotalTime(); |
||
1937 | if (start_time + pTime_to_move <= the_time) { |
||
1938 | break; |
||
1939 | } |
||
1940 | DrawGrid(pitch * pFrom + pitch * (pTo - pFrom) * (the_time - start_time) / pTime_to_move, 1); |
||
1941 | } |
||
1942 | DrawGrid(pitch * pTo, 1); |
||
1943 | } |
||
1944 | |||
1945 | // IDA: int __usercall CalcGridOffset@<EAX>(int pPosition@<EAX>) |
||
1946 | int CalcGridOffset(int pPosition) { |
||
1947 | LOG_TRACE("(%d)", pPosition); |
||
1948 | |||
1949 | return pPosition / 2 - 1; |
||
1950 | } |
||
1951 | |||
1952 | // IDA: void __usercall GridDraw(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>) |
||
1953 | void GridDraw(int pCurrent_choice, int pCurrent_mode) { |
||
1954 | LOG_TRACE8("(%d, %d)", pCurrent_choice, pCurrent_mode); |
||
1955 | |||
1956 | if (gDraw_grid_status > eGrid_draw_none) { |
||
1957 | DrawGrid(gCurrent_graf_data->grid_x_pitch * CalcGridOffset(gOur_starting_position), 0); |
||
1958 | } |
||
1959 | } |
||
1960 | |||
1961 | // IDA: void __usercall ActuallySwapOrder(int pFirst_index@<EAX>, int pSecond_index@<EDX>) |
||
1962 | void ActuallySwapOrder(int pFirst_index, int pSecond_index) { |
||
1963 | tOpp_spec temp_opp; |
||
1964 | LOG_TRACE("(%d, %d)", pFirst_index, pSecond_index); |
||
1965 | |||
1966 | temp_opp = gCurrent_race.opponent_list[pFirst_index]; |
||
1967 | gCurrent_race.opponent_list[pFirst_index] = gCurrent_race.opponent_list[pSecond_index]; |
||
1968 | gCurrent_race.opponent_list[pSecond_index] = temp_opp; |
||
1969 | gOur_starting_position = pSecond_index; |
||
1970 | |||
1971 | // LOG_DEBUG("first %d, second %d", gCurrent_race.opponent_list[pFirst_index].index, gCurrent_race.opponent_list[pSecond_index].index); |
||
1972 | } |
||
1973 | |||
1974 | // IDA: void __usercall DoGridTransition(int pFirst_index@<EAX>, int pSecond_index@<EDX>) |
||
1975 | void DoGridTransition(int pFirst_index, int pSecond_index) { |
||
1976 | tU32 start_time; |
||
1977 | tU32 the_time; |
||
1978 | LOG_TRACE("(%d, %d)", pFirst_index, pSecond_index); |
||
1979 | |||
1980 | if (pFirst_index != pSecond_index) { |
||
1981 | start_time = PDGetTotalTime(); |
||
1982 | gSwap_grid_1 = pFirst_index; |
||
1983 | gSwap_grid_2 = pSecond_index; |
||
1984 | while (1) { |
||
1985 | the_time = PDGetTotalTime(); |
||
1986 | if (start_time + 150 <= the_time) { |
||
1987 | break; |
||
1988 | } |
||
1989 | RemoveTransientBitmaps(1); |
||
1990 | gGrid_transition_stage = 100 * (the_time - start_time) / 150; |
||
1991 | DrawGrid(gCurrent_graf_data->grid_x_pitch * CalcGridOffset(gOur_starting_position), 0); |
||
1992 | ProcessFlicQueue(gFrame_period); |
||
1993 | DoMouseCursor(); |
||
1994 | PDScreenBufferSwap(0); |
||
1995 | } |
||
1996 | gSwap_grid_1 = -1; |
||
1997 | gSwap_grid_2 = -1; |
||
1998 | ActuallySwapOrder(pFirst_index, pSecond_index); |
||
1999 | MoveGrid(CalcGridOffset(pFirst_index), CalcGridOffset(pSecond_index), 150); |
||
2000 | } |
||
2001 | } |
||
2002 | |||
2003 | // IDA: void __cdecl ChallengeStart() |
||
2004 | void ChallengeStart(void) { |
||
2005 | br_pixelmap* the_map; |
||
2006 | int i; |
||
2007 | int j; |
||
2008 | int line_count; |
||
2009 | int dare_index; |
||
2010 | FILE* f; |
||
2011 | tPath_name the_path; |
||
2012 | char s[256]; |
||
2013 | LOG_TRACE("()"); |
||
2014 | |||
2015 | InitialiseFlicPanel( |
||
2016 | 0, |
||
2017 | gCurrent_graf_data->start_race_panel_left, |
||
2018 | gCurrent_graf_data->start_race_panel_top, |
||
2019 | gCurrent_graf_data->start_race_panel_right - gCurrent_graf_data->start_race_panel_left, |
||
2020 | gCurrent_graf_data->start_race_panel_bottom - gCurrent_graf_data->start_race_panel_top); |
||
2021 | ChangePanelFlic( |
||
2022 | 0, |
||
2023 | gOpponents[gChallenger_index__racestrt].mug_shot_image_data, |
||
2024 | gOpponents[gChallenger_index__racestrt].mug_shot_image_data_length); |
||
2025 | if (gScreen->row_bytes < 0) { |
||
2026 | BrFatal("C:\\Msdev\\Projects\\DethRace\\Racestrt.c", 2610, "Bruce bug at line %d, file C:\\Msdev\\Projects\\DethRace\\Racestrt.c", 50); |
||
2027 | } |
||
2028 | the_map = DRPixelmapAllocate( |
||
2029 | gScreen->type, |
||
2030 | gCurrent_graf_data->dare_mugshot_width, |
||
2031 | gCurrent_graf_data->dare_mugshot_height, |
||
2032 | 0, |
||
2033 | 0); |
||
2034 | |||
2035 | BrPixelmapRectangleCopy(the_map, 0, 0, GetPanelPixelmap(0), gCurrent_graf_data->dare_mug_left_margin, gCurrent_graf_data->dare_mug_top_margin, gCurrent_graf_data->dare_mugshot_width, gCurrent_graf_data->dare_mugshot_height); |
||
2036 | DisposeFlicPanel(0); |
||
2037 | TellyInImage(the_map, gCurrent_graf_data->dare_mugshot_left, gCurrent_graf_data->dare_mugshot_top); |
||
2038 | BrPixelmapFree(the_map); |
||
2039 | the_map = DRPixelmapAllocate(gScreen->type, gCurrent_graf_data->dare_text_width, gCurrent_graf_data->dare_mugshot_height, 0, 0); |
||
2040 | BrPixelmapFill(the_map, 0); |
||
2041 | TransBrPixelmapText(the_map, 0, 0, 1u, gBig_font, gOpponents[gChallenger_index__racestrt].abbrev_name); |
||
2042 | PathCat(the_path, gApplication_path, "DARES.TXT"); |
||
2043 | f = DRfopen(the_path, "rt"); |
||
2044 | if (f == NULL) { |
||
2045 | FatalError(kFatalError_OpenDareTxt); |
||
2046 | } |
||
2047 | |||
2048 | dare_index = IRandomBetween(0, GetAnInt(f) - 1); |
||
2049 | for (i = 0; i < dare_index; i++) { |
||
2050 | line_count = GetAnInt(f); |
||
2051 | for (j = 0; j < line_count; j++) { |
||
2052 | GetALineAndDontArgue(f, s); |
||
2053 | } |
||
2054 | } |
||
2055 | line_count = GetAnInt(f); |
||
2056 | for (i = 0; i < line_count; i++) { |
||
2057 | GetALineAndDontArgue(f, s); |
||
2058 | TransBrPixelmapText(the_map, 0, 2 * (i + 1) * gBig_font->glyph_y, 0x86u, gBig_font, s); |
||
2059 | } |
||
2060 | fclose(f); |
||
2061 | BrPixelmapLine(the_map, 0, gBig_font->glyph_y + 2, the_map->width, gBig_font->glyph_y + 2, 45); |
||
2062 | TellyInImage(the_map, gCurrent_graf_data->dare_text_left, gCurrent_graf_data->dare_mugshot_top); |
||
2063 | BrPixelmapFree(the_map); |
||
2064 | UnlockOpponentMugshot(gChallenger_index__racestrt); |
||
2065 | gDare_start_time = PDGetTotalTime(); |
||
2066 | } |
||
2067 | |||
2068 | // IDA: int __usercall CheckNextStage@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
2069 | int CheckNextStage(int* pCurrent_choice, int* pCurrent_mode) { |
||
2070 | LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
2071 | |||
2072 | if (gDare_start_time && (unsigned int)(PDGetTotalTime() - gDare_start_time) >= 7500) { |
||
2073 | BrPixelmapRectangleFill( |
||
2074 | gBack_screen, |
||
2075 | gCurrent_graf_data->grid_left_clip, |
||
2076 | gCurrent_graf_data->dare_mugshot_top, |
||
2077 | gCurrent_graf_data->grid_right_clip - gCurrent_graf_data->grid_left_clip, |
||
2078 | gCurrent_graf_data->dare_mugshot_height, |
||
2079 | 0); |
||
2080 | DoGridTransition(gOur_starting_position, gChallenger_position); |
||
2081 | gDraw_grid_status = eGrid_draw_icons_only; |
||
2082 | gDare_start_time = 0; |
||
2083 | } |
||
2084 | return 0; |
||
2085 | } |
||
2086 | |||
2087 | // IDA: int __usercall ChallengeDone@<EAX>(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>, int pGo_ahead@<EBX>, int pEscaped@<ECX>, int pTimed_out) |
||
2088 | int ChallengeDone(int pCurrent_choice, int pCurrent_mode, int pGo_ahead, int pEscaped, int pTimed_out) { |
||
2089 | LOG_TRACE("(%d, %d, %d, %d, %d)", pCurrent_choice, pCurrent_mode, pGo_ahead, pEscaped, pTimed_out); |
||
2090 | |||
2091 | if (!pEscaped || gDare_start_time) { |
||
2092 | if (!pEscaped && gDare_start_time) { |
||
2093 | ActuallySwapOrder(gOur_starting_position, gChallenger_position); |
||
2094 | ChallengeOccurred(gChallenger_index__racestrt, 1); |
||
2095 | } |
||
2096 | } else { |
||
2097 | DoGridTransition(gOur_starting_position, gOriginal_position); |
||
2098 | ActuallySwapOrder(gOur_starting_position, gOriginal_position); |
||
2099 | ChallengeOccurred(gChallenger_index__racestrt, 0); |
||
2100 | } |
||
2101 | ChallengeOccurred(gChallenger_index__racestrt, pEscaped == 0); |
||
2102 | if (pTimed_out) { |
||
2103 | return 0; |
||
2104 | } else { |
||
2105 | return pCurrent_choice; |
||
2106 | } |
||
2107 | } |
||
2108 | |||
2109 | // IDA: void __cdecl DoChallengeScreen() |
||
2110 | void DoChallengeScreen(void) { |
||
2111 | static tFlicette flicker_on[2] = { { 43, { 54, 108 }, { 157, 377 } }, { 43, { 218, 436 }, { 157, 377 } } }; |
||
2112 | static tFlicette flicker_off[2] = { { 42, { 54, 108 }, { 157, 377 } }, { 42, { 218, 436 }, { 157, 377 } } }; |
||
2113 | static tFlicette push[2] = { { 304, { 54, 108 }, { 157, 377 } }, { 305, { 218, 436 }, { 157, 377 } } }; |
||
2114 | static tMouse_area mouse_areas[2] = { |
||
2115 | { { 54, 108 }, { 157, 377 }, { 117, 234 }, { 178, 427 }, 0, 0, 0, NULL }, |
||
2116 | { { 218, 436 }, { 157, 377 }, { 281, 562 }, { 178, 427 }, 1, 0, 0, NULL } |
||
2117 | }; |
||
2118 | static tInterface_spec interface_spec = { |
||
2119 | 0, // initial_imode |
||
2120 | 301, // first_opening_flic |
||
2121 | 0, // second_opening_flic |
||
2122 | -1, // end_flic_go_ahead |
||
2123 | -1, // end_flic_escaped |
||
2124 | -1, // end_flic_otherwise |
||
2125 | 0, // flic_bunch_to_load |
||
2126 | { -1, 0 }, // move_left_new_mode |
||
2127 | { -1, 0 }, // move_left_delta |
||
2128 | { 0, 0 }, // move_left_min |
||
2129 | { 1, 0 }, // move_left_max |
||
2130 | { NULL, NULL }, // move_left_proc |
||
2131 | { -1, 0 }, // move_right_new_mode |
||
2132 | { 1, 0 }, // move_right_delta |
||
2133 | { 0, 0 }, // move_right_min |
||
2134 | { 1, 0 }, // move_right_max |
||
2135 | { NULL, NULL }, // move_right_proc |
||
2136 | { -1, 0 }, // move_up_new_mode |
||
2137 | { 0, 0 }, // move_up_delta |
||
2138 | { 0, 0 }, // move_up_min |
||
2139 | { 0, 0 }, // move_up_max |
||
2140 | { NULL, NULL }, // move_up_proc |
||
2141 | { -1, 0 }, // move_down_new_mode |
||
2142 | { 0, 0 }, // move_down_delta |
||
2143 | { 0, 0 }, // move_down_min |
||
2144 | { 0, 0 }, // move_down_max |
||
2145 | { NULL, NULL }, // move_down_proc |
||
2146 | { 1, 1 }, // go_ahead_allowed |
||
2147 | { NULL, NULL }, // go_ahead_proc |
||
2148 | { 1, 1 }, // escape_allowed |
||
2149 | { NULL, NULL }, // escape_proc |
||
2150 | &CheckNextStage, // exit_proc |
||
2151 | &GridDraw, // draw_proc |
||
2152 | 0u, // time_out |
||
2153 | NULL, // start_proc1 |
||
2154 | &ChallengeStart, // start_proc2 |
||
2155 | &ChallengeDone, // done_proc |
||
2156 | 0, // font_needed |
||
2157 | { 0, 0 }, // typeable |
||
2158 | NULL, // get_original_string |
||
2159 | 1, // escape_code |
||
2160 | 1, // dont_save_or_load |
||
2161 | 2, // number_of_button_flics |
||
2162 | flicker_on, // flicker_on_flics |
||
2163 | flicker_off, // flicker_off_flics |
||
2164 | push, // pushed_flics |
||
2165 | 2, // number_of_mouse_areas |
||
2166 | mouse_areas, // mouse_areas |
||
2167 | 0, // number_of_recopy_areas |
||
2168 | NULL // recopy_areas |
||
2169 | }; |
||
2170 | |||
2171 | //int result; // Pierre-Marie Baty -- unused variable |
||
2172 | LOG_TRACE("()"); |
||
2173 | |||
2174 | gOriginal_position = gOur_starting_position; |
||
2175 | gChallenger_position = IRandomBetween(0, 1); |
||
2176 | if (gOpponents[gCurrent_race.opponent_list[gChallenger_position].index].car_number < 0) { |
||
2177 | gChallenger_position ^= 1u; |
||
2178 | } |
||
2179 | gChallenger_index__racestrt = gCurrent_race.opponent_list[gChallenger_position].index; |
||
2180 | LoadOpponentMugShot(gChallenger_index__racestrt); |
||
2181 | gDraw_grid_status = eGrid_draw_none; |
||
2182 | gGrid_y_adjust = gCurrent_graf_data->dare_y_adjust; |
||
2183 | DoInterfaceScreen(&interface_spec, 0, 0); |
||
2184 | } |
||
2185 | |||
2186 | // IDA: int __usercall GridDone@<EAX>(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>, int pGo_ahead@<EBX>, int pEscaped@<ECX>, int pTimed_out) |
||
2187 | int GridDone(int pCurrent_choice, int pCurrent_mode, int pGo_ahead, int pEscaped, int pTimed_out) { |
||
2188 | LOG_TRACE("(%d, %d, %d, %d, %d)", pCurrent_choice, pCurrent_mode, pGo_ahead, pEscaped, pTimed_out); |
||
2189 | |||
2190 | if (pTimed_out) { |
||
2191 | return 0; |
||
2192 | } |
||
2193 | if (pEscaped) { |
||
2194 | return -1; |
||
2195 | } |
||
2196 | return pCurrent_choice; |
||
2197 | } |
||
2198 | |||
2199 | // IDA: void __cdecl GridStart() |
||
2200 | void GridStart(void) { |
||
2201 | LOG_TRACE("()"); |
||
2202 | |||
2203 | MoveGrid(-2, CalcGridOffset(gOur_starting_position), 400); |
||
2204 | PrintMemoryDump(0, "IN GRID SCREEN"); |
||
2205 | } |
||
2206 | |||
2207 | // IDA: int __usercall GridMoveLeft@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
2208 | int GridMoveLeft(int* pCurrent_choice, int* pCurrent_mode) { |
||
2209 | LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
2210 | |||
2211 | if (gOur_starting_position |
||
2212 | && gCurrent_race.opponent_list[gOur_starting_position - 1].ranking >= gProgram_state.rank) { |
||
2213 | AddToFlicQueue( |
||
2214 | gStart_interface_spec->pushed_flics[1].flic_index, |
||
2215 | gStart_interface_spec->pushed_flics[1].x[gGraf_data_index], |
||
2216 | gStart_interface_spec->pushed_flics[1].y[gGraf_data_index], |
||
2217 | 1); |
||
2218 | DRS3StartSound(gEffects_outlet, 3000); |
||
2219 | DoGridTransition(gOur_starting_position, gOur_starting_position - 1); |
||
2220 | } |
||
2221 | return 0; |
||
2222 | } |
||
2223 | |||
2224 | // IDA: int __usercall GridMoveRight@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
2225 | int GridMoveRight(int* pCurrent_choice, int* pCurrent_mode) { |
||
2226 | LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
2227 | |||
2228 | if (gOur_starting_position < gCurrent_race.number_of_racers - 1) { |
||
2229 | AddToFlicQueue( |
||
2230 | gStart_interface_spec->pushed_flics[2].flic_index, |
||
2231 | gStart_interface_spec->pushed_flics[2].x[gGraf_data_index], |
||
2232 | gStart_interface_spec->pushed_flics[2].y[gGraf_data_index], |
||
2233 | 1); |
||
2234 | DRS3StartSound(gEffects_outlet, 3000); |
||
2235 | DoGridTransition(gOur_starting_position, gOur_starting_position + 1); |
||
2236 | } |
||
2237 | return 0; |
||
2238 | } |
||
2239 | |||
2240 | // IDA: int __usercall GridClickCar@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>) |
||
2241 | int GridClickCar(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) { |
||
2242 | int rel_pos; |
||
2243 | int new_pos; |
||
2244 | //int base_pos; // Pierre-Marie Baty -- unused variable |
||
2245 | int x_coord; |
||
2246 | LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset); |
||
2247 | |||
2248 | rel_pos = ((gCurrent_graf_data->grid_bottom_clip - gCurrent_graf_data->grid_top_clip) / 2) < pY_offset; |
||
2249 | if (rel_pos) { |
||
2250 | pX_offset -= gCurrent_graf_data->grid_x_stagger; |
||
2251 | } |
||
2252 | x_coord = pX_offset / gCurrent_graf_data->grid_x_pitch; |
||
2253 | if (x_coord > 2) { |
||
2254 | x_coord = 2; |
||
2255 | } |
||
2256 | new_pos = 2 * x_coord + rel_pos + (gOur_starting_position & ~1) - 2; |
||
2257 | if (new_pos >= 0 && new_pos < gCurrent_race.number_of_racers && gProgram_state.rank < gCurrent_race.opponent_list[new_pos].ranking) { |
||
2258 | DRS3StartSound(gEffects_outlet, 3000); |
||
2259 | DoGridTransition(gOur_starting_position, new_pos); |
||
2260 | } |
||
2261 | return 0; |
||
2262 | } |
||
2263 | |||
2264 | // IDA: int __usercall GridClickNumbers@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>) |
||
2265 | int GridClickNumbers(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) { |
||
2266 | int new_pos; |
||
2267 | int i; |
||
2268 | LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset); |
||
2269 | |||
2270 | new_pos = -1; |
||
2271 | for (i = 0; i < gCurrent_race.number_of_racers; i++) { |
||
2272 | if (gGrid_number_x_coords[i] <= pX_offset && (gCurrent_race.number_of_racers - 1 == i || pX_offset < gGrid_number_x_coords[i + 1])) { |
||
2273 | new_pos = i; |
||
2274 | break; |
||
2275 | } |
||
2276 | } |
||
2277 | if (new_pos >= 0 && new_pos < gCurrent_race.number_of_racers && gProgram_state.rank <= gCurrent_race.opponent_list[new_pos].ranking) { |
||
2278 | DRS3StartSound(gEffects_outlet, 3000); |
||
2279 | DoGridTransition(gOur_starting_position, new_pos); |
||
2280 | } |
||
2281 | return 0; |
||
2282 | } |
||
2283 | |||
2284 | // IDA: int __usercall GridClickLeft@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>) |
||
2285 | int GridClickLeft(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) { |
||
2286 | LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset); |
||
2287 | |||
2288 | GridMoveLeft(pCurrent_choice, pCurrent_mode); |
||
2289 | return 0; |
||
2290 | } |
||
2291 | |||
2292 | // IDA: int __usercall GridClickRight@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>) |
||
2293 | int GridClickRight(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) { |
||
2294 | LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset); |
||
2295 | |||
2296 | GridMoveRight(pCurrent_choice, pCurrent_mode); |
||
2297 | return 0; |
||
2298 | } |
||
2299 | |||
2300 | // IDA: int __usercall CheckChallenge@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
2301 | int CheckChallenge(int* pCurrent_choice, int* pCurrent_mode) { |
||
2302 | LOG_TRACE8("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
2303 | |||
2304 | if (!gChallenge_time || PDGetTotalTime() < gChallenge_time) { |
||
2305 | return 0; |
||
2306 | } |
||
2307 | *pCurrent_choice = -2; |
||
2308 | return 1; |
||
2309 | } |
||
2310 | |||
2311 | // IDA: int __usercall FindBestPos@<EAX>(int pOur_rank@<EAX>) |
||
2312 | int FindBestPos(int pOur_rank) { |
||
2313 | int i; |
||
2314 | LOG_TRACE("(%d)", pOur_rank); |
||
2315 | |||
2316 | for (i = gCurrent_race.number_of_racers - 1; i >= 0; i--) { |
||
2317 | if (gCurrent_race.opponent_list[i].ranking < pOur_rank) { |
||
2318 | return i + 1; |
||
2319 | } |
||
2320 | } |
||
2321 | return 0; |
||
2322 | } |
||
2323 | |||
2324 | // IDA: int __usercall SortGridFunction@<EAX>(void *pFirst_one@<EAX>, void *pSecond_one@<EDX>) |
||
2325 | int SortGridFunction(const void* pFirst_one, const void* pSecond_one) { |
||
2326 | LOG_TRACE("(%p, %p)", pFirst_one, pSecond_one); |
||
2327 | |||
2328 | return ((tOpp_spec*)pFirst_one)->ranking - ((tOpp_spec*)pSecond_one)->ranking; |
||
2329 | } |
||
2330 | |||
2331 | // IDA: void __cdecl SortOpponents() |
||
2332 | void SortOpponents(void) { |
||
2333 | int i; |
||
2334 | LOG_TRACE("()"); |
||
2335 | |||
2336 | for (i = 0; gCurrent_race.number_of_racers > i; ++i) { |
||
2337 | if (gCurrent_race.opponent_list[i].index < 0) { |
||
2338 | return; |
||
2339 | } |
||
2340 | } |
||
2341 | qsort(gCurrent_race.opponent_list, gCurrent_race.number_of_racers, sizeof(tOpp_spec), SortGridFunction); |
||
2342 | gBest_pos_available = FindBestPos(gProgram_state.rank); |
||
2343 | gOur_starting_position = gCurrent_race.number_of_racers - 70 * (gCurrent_race.number_of_racers - gBest_pos_available) / 100; |
||
2344 | for (i = gCurrent_race.number_of_racers; i > gOur_starting_position; i--) { |
||
2345 | gCurrent_race.opponent_list[i] = gCurrent_race.opponent_list[i - 1]; |
||
2346 | } |
||
2347 | gCurrent_race.opponent_list[gOur_starting_position].index = -1; |
||
2348 | gCurrent_race.opponent_list[gOur_starting_position].ranking = gProgram_state.rank; |
||
2349 | gCurrent_race.opponent_list[gOur_starting_position].car_spec = &gProgram_state.current_car; |
||
2350 | gCurrent_race.number_of_racers++; |
||
2351 | } |
||
2352 | |||
2353 | // IDA: tSO_result __cdecl DoGridPosition() |
||
2354 | tSO_result DoGridPosition(void) { |
||
2355 | static tFlicette flicker_on[3] = { |
||
2356 | { 43, { 240, 480 }, { 158, 379 } }, |
||
2357 | { 293, { 56, 112 }, { 151, 362 } }, |
||
2358 | { 296, { 136, 272 }, { 151, 362 } } |
||
2359 | }; |
||
2360 | |||
2361 | static tFlicette flicker_off[3] = { |
||
2362 | { 42, { 240, 480 }, { 158, 379 } }, |
||
2363 | { 292, { 56, 112 }, { 151, 362 } }, |
||
2364 | { 295, { 136, 272 }, { 151, 362 } } |
||
2365 | }; |
||
2366 | |||
2367 | static tFlicette push[3] = { |
||
2368 | { 154, { 240, 480 }, { 158, 379 } }, |
||
2369 | { 294, { 56, 112 }, { 151, 362 } }, |
||
2370 | { 297, { 136, 272 }, { 151, 362 } } |
||
2371 | }; |
||
2372 | static tMouse_area mouse_areas[5] = { |
||
2373 | { { 240, 480 }, { 158, 379 }, { 305, 610 }, { 178, 427 }, 0, 0, 0, NULL }, |
||
2374 | { { 56, 112 }, |
||
2375 | { 151, 362 }, |
||
2376 | { 91, 182 }, |
||
2377 | { 158, 379 }, |
||
2378 | -1, |
||
2379 | 0, |
||
2380 | 0, |
||
2381 | GridClickLeft }, |
||
2382 | { { 136, 272 }, |
||
2383 | { 151, 362 }, |
||
2384 | { 171, 342 }, |
||
2385 | { 158, 379 }, |
||
2386 | -1, |
||
2387 | 0, |
||
2388 | 0, |
||
2389 | GridClickRight }, |
||
2390 | { { 52, 104 }, |
||
2391 | { 56, 134 }, |
||
2392 | { 269, 538 }, |
||
2393 | { 141, 338 }, |
||
2394 | -1, |
||
2395 | 0, |
||
2396 | 0, |
||
2397 | GridClickCar }, |
||
2398 | { { 60, 120 }, |
||
2399 | { 163, 391 }, |
||
2400 | { 235, 470 }, |
||
2401 | { 176, 422 }, |
||
2402 | -1, |
||
2403 | 0, |
||
2404 | 0, |
||
2405 | GridClickNumbers } |
||
2406 | }; |
||
2407 | |||
2408 | static tInterface_spec interface_spec = { |
||
2409 | 0, // initial_imode |
||
2410 | 290, // first_opening_flic |
||
2411 | 0, // second_opening_flic |
||
2412 | 0, // end_flic_go_ahead |
||
2413 | 0, // end_flic_escaped |
||
2414 | 0, // end_flic_otherwise |
||
2415 | 8, // flic_bunch_to_load |
||
2416 | { -1, 0 }, // move_left_new_mode |
||
2417 | { 0, 0 }, // move_left_delta |
||
2418 | { 0, 0 }, // move_left_min |
||
2419 | { 0, 0 }, // move_left_max |
||
2420 | { GridMoveLeft, NULL }, // move_left_proc |
||
2421 | { -1, 0 }, // move_right_new_mode |
||
2422 | { 0, 0 }, // move_right_delta |
||
2423 | { 0, 0 }, // move_right_min |
||
2424 | { 0, 0 }, // move_right_max |
||
2425 | { GridMoveRight, NULL }, // move_right_proc |
||
2426 | { -1, 0 }, // move_up_new_mode |
||
2427 | { 0, 0 }, // move_up_delta |
||
2428 | { 0, 0 }, // move_up_min |
||
2429 | { 0, 0 }, // move_up_max |
||
2430 | { GridMoveLeft, NULL }, // move_up_proc |
||
2431 | { -1, 0 }, // move_down_new_mode |
||
2432 | { 0, 0 }, // move_down_delta |
||
2433 | { 0, 0 }, // move_down_min |
||
2434 | { 0, 0 }, // move_down_max |
||
2435 | { GridMoveRight, NULL }, // move_down_proc |
||
2436 | { 1, 1 }, // go_ahead_allowed |
||
2437 | { NULL, NULL }, // go_ahead_proc |
||
2438 | { 1, 1 }, // escape_allowed |
||
2439 | { NULL, NULL }, // escape_proc |
||
2440 | CheckChallenge, // exit_proc |
||
2441 | GridDraw, // draw_proc |
||
2442 | 0u, // time_out |
||
2443 | NULL, // start_proc1 |
||
2444 | GridStart, // start_proc2 |
||
2445 | GridDone, // done_proc |
||
2446 | 0, // font_needed |
||
2447 | { 0, 0 }, // typeable |
||
2448 | NULL, // get_original_string |
||
2449 | -1, // escape_code |
||
2450 | 1, // dont_save_or_load |
||
2451 | 3, // number_of_button_flics |
||
2452 | flicker_on, // flicker_on_flics |
||
2453 | flicker_off, // flicker_off_flics |
||
2454 | push, // pushed_flics |
||
2455 | 5, // number_of_mouse_areas |
||
2456 | mouse_areas, // mouse_areas |
||
2457 | 0, // number_of_recopy_areas |
||
2458 | NULL // recopy_areas |
||
2459 | }; |
||
2460 | |||
2461 | int result; |
||
2462 | LOG_TRACE("()"); |
||
2463 | |||
2464 | gStart_interface_spec = &interface_spec; |
||
2465 | if (!gAusterity_mode) { |
||
2466 | LoadGridIcons(&gCurrent_race); |
||
2467 | } |
||
2468 | gSwap_grid_1 = -1; |
||
2469 | gSwap_grid_2 = -1; |
||
2470 | gDraw_grid_status = eGrid_draw_all; |
||
2471 | gGrid_y_adjust = 0; |
||
2472 | SortOpponents(); |
||
2473 | if (!gAusterity_mode) { |
||
2474 | if (gBest_pos_available > 1 |
||
2475 | && (gOpponents[gCurrent_race.opponent_list[0].index].car_number >= 0 |
||
2476 | || gOpponents[gCurrent_race.opponent_list[1].index].car_number >= 0) |
||
2477 | && PercentageChance(10)) { |
||
2478 | gChallenge_time = PDGetTotalTime() + IRandomBetween(1000, 10000); |
||
2479 | } else { |
||
2480 | gChallenge_time = 0; |
||
2481 | } |
||
2482 | result = DoInterfaceScreen(&interface_spec, 0, 0); |
||
2483 | if (result >= 0) { |
||
2484 | FadePaletteDown(); |
||
2485 | } else { |
||
2486 | RunFlic(291); |
||
2487 | } |
||
2488 | if (result == -1) { |
||
2489 | return eSO_main_menu_invoked; |
||
2490 | } |
||
2491 | if (result == -2) { |
||
2492 | DoChallengeScreen(); |
||
2493 | } |
||
2494 | DisposeGridIcons(&gCurrent_race); |
||
2495 | } |
||
2496 | return eSO_continue; |
||
2497 | } |
||
2498 | |||
2499 | // IDA: void __cdecl CheckPlayersAreResponding() |
||
2500 | void CheckPlayersAreResponding(void) { |
||
2501 | int i; |
||
2502 | tU32 time; |
||
2503 | tNet_message* message; |
||
2504 | LOG_TRACE("()"); |
||
2505 | |||
2506 | time = PDGetTotalTime(); |
||
2507 | for (i = 0; i < gNumber_of_net_players; i++) { |
||
2508 | if (i != gThis_net_player_index && time - gNet_players[i].last_heard_from_him > 20000) { |
||
2509 | gNet_players[i].player_status = ePlayer_status_not_responding; |
||
2510 | } |
||
2511 | } |
||
2512 | if (gNet_mode == eNet_mode_client && gLast_host_query == 0) { |
||
2513 | message = NetBuildMessage(NETMSGID_HOSTQUERY, 0); |
||
2514 | NetGuaranteedSendMessageToHost(gCurrent_net_game, message, NULL); |
||
2515 | gLast_host_query = time; |
||
2516 | } |
||
2517 | } |
||
2518 | |||
2519 | // IDA: void __cdecl NetSynchStartStart() |
||
2520 | void NetSynchStartStart(void) { |
||
2521 | LOG_TRACE("()"); |
||
2522 | |||
2523 | CheckPlayersAreResponding(); |
||
2524 | } |
||
2525 | |||
2526 | // IDA: void __usercall DrawAnItem(int pX@<EAX>, int pY_index@<EDX>, int pFont_index@<EBX>, char *pText@<ECX>) |
||
2527 | // Suffix added to avoid duplicate symbol |
||
2528 | void DrawAnItem__racestrt(int pX, int pY_index, int pFont_index, char* pText) { |
||
2529 | LOG_TRACE("(%d, %d, %d, \"%s\")", pX, pY_index, pFont_index, pText); |
||
2530 | |||
2531 | TransBrPixelmapText(gBack_screen, |
||
2532 | pX, |
||
2533 | gCurrent_graf_data->start_synch_top + gCurrent_graf_data->start_synch_y_pitch * pY_index, |
||
2534 | pFont_index, |
||
2535 | gFont_7, |
||
2536 | pText); |
||
2537 | } |
||
2538 | |||
2539 | // IDA: void __usercall NetSynchStartDraw(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>) |
||
2540 | void NetSynchStartDraw(int pCurrent_choice, int pCurrent_mode) { |
||
2541 | int i; |
||
2542 | int number_ready; |
||
2543 | char s[256]; |
||
2544 | LOG_TRACE("(%d, %d)", pCurrent_choice, pCurrent_mode); |
||
2545 | |||
2546 | number_ready = 0; |
||
2547 | CheckPlayersAreResponding(); |
||
2548 | NetPlayerStatusChanged(ePlayer_status_ready); |
||
2549 | for (i = 0; i < COUNT_OF(gNet_players); i++) { |
||
2550 | BrPixelmapRectangleFill(gBack_screen, |
||
2551 | gCurrent_graf_data->start_synch_x_0, |
||
2552 | gCurrent_graf_data->start_synch_y_pitch * i + gCurrent_graf_data->start_synch_top, |
||
2553 | gCurrent_graf_data->start_synch_x_r - gCurrent_graf_data->start_synch_x_1, |
||
2554 | gFont_7->glyph_y, |
||
2555 | 0); |
||
2556 | } |
||
2557 | for (i = 0; i < gNumber_of_net_players; i++) { |
||
2558 | strcpy(s, gNet_players[i].player_name); |
||
2559 | if (gNet_players[i].host) { |
||
2560 | strcat(s, " -"); |
||
2561 | strcat(s, GetMiscString(kMiscString_HOST)); |
||
2562 | strcat(s, "-"); |
||
2563 | } |
||
2564 | TurnOffPaletteConversion(); |
||
2565 | DRPixelmapRectangleMaskedCopy(gBack_screen, |
||
2566 | gCurrent_graf_data->start_synch_x_0, |
||
2567 | gCurrent_graf_data->start_synch_top + 1 + gCurrent_graf_data->start_synch_y_pitch * i, |
||
2568 | gIcons_pix_low_res, /* DOS version uses low res, Windows version uses normal res */ |
||
2569 | 0, |
||
2570 | gNet_players[i].car_index * gCurrent_graf_data->net_head_icon_height, |
||
2571 | gIcons_pix_low_res->width, /* DOS version uses low res, Windows version uses normal res */ |
||
2572 | gCurrent_graf_data->net_head_icon_height); |
||
2573 | TurnOnPaletteConversion(); |
||
2574 | DrawAnItem__racestrt( |
||
2575 | gCurrent_graf_data->start_synch_x_1, |
||
2576 | i, |
||
2577 | (gNet_players[i].player_status == ePlayer_status_ready) ? 66 : 4, |
||
2578 | s); |
||
2579 | DrawAnItem__racestrt(gCurrent_graf_data->start_synch_x_2, |
||
2580 | i, |
||
2581 | (gNet_players[i].player_status == ePlayer_status_ready) ? 83 : ((gNet_players[i].player_status == ePlayer_status_not_responding) ? 247 : 4), |
||
2582 | GetMiscString(kMiscString_NetworkPlayerStatus_START + gNet_players[i].player_status)); |
||
2583 | if (gNet_players[i].player_status == ePlayer_status_ready) { |
||
2584 | number_ready++; |
||
2585 | } |
||
2586 | } |
||
2587 | if (gNet_mode == eNet_mode_host && gNumber_of_net_players == number_ready && gNumber_of_net_players > 1 && (!gNo_races_yet || gNumber_of_net_players == 6)) { |
||
2588 | SignalToStartRace(); |
||
2589 | gSynch_race_start = 1; |
||
2590 | } |
||
2591 | } |
||
2592 | |||
2593 | // IDA: int __usercall NetSynchStartDone@<EAX>(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>, int pGo_ahead@<EBX>, int pEscaped@<ECX>, int pTimed_out) |
||
2594 | int NetSynchStartDone(int pCurrent_choice, int pCurrent_mode, int pGo_ahead, int pEscaped, int pTimed_out) { |
||
2595 | LOG_TRACE("(%d, %d, %d, %d, %d)", pCurrent_choice, pCurrent_mode, pGo_ahead, pEscaped, pTimed_out); |
||
2596 | |||
2597 | if (pEscaped) { |
||
2598 | pCurrent_choice = -1; |
||
2599 | } else if (pCurrent_choice == 0) { |
||
2600 | gProgram_state.prog_status = eProg_idling; |
||
2601 | } |
||
2602 | return pCurrent_choice; |
||
2603 | } |
||
2604 | |||
2605 | // IDA: int __usercall NetSynchStartGoAhead@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
2606 | int NetSynchStartGoAhead(int* pCurrent_choice, int* pCurrent_mode) { |
||
2607 | LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
2608 | |||
2609 | if (*pCurrent_choice == 0 || (gNet_mode == eNet_mode_host && *pCurrent_choice >= 0)) { |
||
2610 | if (*pCurrent_choice == 0) { |
||
2611 | gProgram_state.prog_status = eProg_idling; |
||
2612 | return 1; |
||
2613 | } else if (gNet_mode == eNet_mode_host && *pCurrent_choice == 1) { |
||
2614 | if (gNumber_of_net_players <= 1) { |
||
2615 | DRS3StartSound(gEffects_outlet, 3100); |
||
2616 | return 0; |
||
2617 | } else { |
||
2618 | SignalToStartRace(); |
||
2619 | gSynch_race_start = 1; |
||
2620 | gNo_races_yet = 0; |
||
2621 | return 1; |
||
2622 | } |
||
2623 | } else { |
||
2624 | return 1; |
||
2625 | } |
||
2626 | } else { |
||
2627 | DRS3StartSound(gEffects_outlet, 3100); |
||
2628 | return 0; |
||
2629 | } |
||
2630 | } |
||
2631 | |||
2632 | // IDA: int __usercall ExitWhenReady@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>) |
||
2633 | int ExitWhenReady(int* pCurrent_choice, int* pCurrent_mode) { |
||
2634 | LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode); |
||
2635 | |||
2636 | if (!gSynch_race_start && gProgram_state.prog_status != eProg_game_starting) { |
||
2637 | if (gProgram_state.prog_status == eProg_idling) { |
||
2638 | *pCurrent_choice = 0; |
||
2639 | return 1; |
||
2640 | } else { |
||
2641 | return 0; |
||
2642 | } |
||
2643 | } else { |
||
2644 | *pCurrent_choice = 1; |
||
2645 | return 1; |
||
2646 | } |
||
2647 | } |
||
2648 | |||
2649 | // IDA: tSO_result __usercall NetSynchRaceStart2@<EAX>(tNet_synch_mode pMode@<EAX>) |
||
2650 | tSO_result NetSynchRaceStart2(tNet_synch_mode pMode) { |
||
2651 | static tFlicette flicker_on_hf[2] = { |
||
2652 | { 321, { 219, 112 }, { 172, 362 } }, |
||
2653 | { 321, { 39, 480 }, { 172, 379 } }, |
||
2654 | }; |
||
2655 | static tFlicette flicker_off_hf[2] = { |
||
2656 | { 322, { 219, 112 }, { 172, 362 } }, |
||
2657 | { 322, { 39, 480 }, { 172, 379 } }, |
||
2658 | }; |
||
2659 | static tFlicette push_hf[2] = { |
||
2660 | { 206, { 219, 112 }, { 172, 362 } }, |
||
2661 | { 205, { 39, 480 }, { 172, 379 } }, |
||
2662 | }; |
||
2663 | static tMouse_area mouse_areas_hf[2] = { |
||
2664 | { { 219, 480 }, { 172, 379 }, { 282, 182 }, { 192, 427 }, 0, 0, 0, NULL }, |
||
2665 | { { 39, 112 }, { 172, 362 }, { 102, 182 }, { 192, 379 }, 1, 0, 0, NULL }, |
||
2666 | }; |
||
2667 | static tInterface_spec interface_spec_hf = { |
||
2668 | 0, |
||
2669 | 203, |
||
2670 | 0, |
||
2671 | 0, |
||
2672 | 0, |
||
2673 | 0, |
||
2674 | 8, |
||
2675 | { -1, 0 }, |
||
2676 | { 1, 0 }, |
||
2677 | { 0, 0 }, |
||
2678 | { 1, 0 }, |
||
2679 | { NULL, NULL }, |
||
2680 | { -1, 0 }, |
||
2681 | { 1, 0 }, |
||
2682 | { 0, 0 }, |
||
2683 | { 1, 0 }, |
||
2684 | { NULL, NULL }, |
||
2685 | { -1, 0 }, |
||
2686 | { 1, 0 }, |
||
2687 | { 0, 0 }, |
||
2688 | { 1, 0 }, |
||
2689 | { NULL, NULL }, |
||
2690 | { -1, 0 }, |
||
2691 | { 1, 0 }, |
||
2692 | { 0, 0 }, |
||
2693 | { 1, 0 }, |
||
2694 | { NULL, NULL }, |
||
2695 | { 1, 1 }, |
||
2696 | { NetSynchStartGoAhead, NetSynchStartGoAhead }, |
||
2697 | { 1, 1 }, |
||
2698 | { NULL, NULL }, |
||
2699 | ExitWhenReady, |
||
2700 | NetSynchStartDraw, |
||
2701 | 0, |
||
2702 | NULL, |
||
2703 | NetSynchStartStart, |
||
2704 | NetSynchStartDone, |
||
2705 | 0, |
||
2706 | { 0, 0 }, |
||
2707 | NULL, |
||
2708 | -1, |
||
2709 | 1, |
||
2710 | COUNT_OF(flicker_on_hf), |
||
2711 | flicker_on_hf, |
||
2712 | flicker_off_hf, |
||
2713 | push_hf, |
||
2714 | COUNT_OF(mouse_areas_hf), |
||
2715 | mouse_areas_hf, |
||
2716 | 0, |
||
2717 | NULL, |
||
2718 | }; |
||
2719 | static tFlicette flicker_on_hs[1] = { |
||
2720 | { 321, { 219, 112 }, { 172, 362 } }, |
||
2721 | }; |
||
2722 | static tFlicette flicker_off_hs[1] = { |
||
2723 | { 322, { 219, 112 }, { 172, 362 } }, |
||
2724 | }; |
||
2725 | static tFlicette push_hs[1] = { |
||
2726 | { 206, { 219, 112 }, { 172, 362 } }, |
||
2727 | }; |
||
2728 | static tMouse_area mouse_areas_hs[1] = { |
||
2729 | { { 219, 480 }, { 172, 379 }, { 282, 182 }, { 192, 427 }, 0, 0, 0, NULL }, |
||
2730 | }; |
||
2731 | static tInterface_spec interface_spec_hs = { |
||
2732 | 0, 209, 0, 0, 0, 0, 8, |
||
2733 | { -1, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL }, |
||
2734 | { -1, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL }, |
||
2735 | { -1, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL }, |
||
2736 | { -1, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL }, |
||
2737 | { 1, 1 }, { NetSynchStartGoAhead, NetSynchStartGoAhead }, { 1, 1 }, { NULL, NULL }, |
||
2738 | ExitWhenReady, NetSynchStartDraw, 0, NULL, NetSynchStartStart, NetSynchStartDone, 0, { 0, 0 }, |
||
2739 | NULL, -1, 1, |
||
2740 | COUNT_OF(flicker_on_hs), flicker_on_hs, flicker_off_hs, push_hs, |
||
2741 | COUNT_OF(mouse_areas_hs), mouse_areas_hs, 0, NULL |
||
2742 | }; |
||
2743 | static tFlicette flicker_on_c[1] = { |
||
2744 | { 321, { 219, 112 }, { 172, 362 } }, |
||
2745 | }; |
||
2746 | static tFlicette flicker_off_c[1] = { |
||
2747 | { 322, { 219, 112 }, { 172, 362 } }, |
||
2748 | }; |
||
2749 | static tFlicette push_c[1] = { |
||
2750 | { 207, { 219, 112 }, { 172, 362 } }, |
||
2751 | }; |
||
2752 | static tMouse_area mouse_areas_c[1] = { |
||
2753 | { { 219, 112 }, { 172, 362 }, { 282, 182 }, { 192, 379 }, 0, 0, 0, NULL }, |
||
2754 | }; |
||
2755 | static tInterface_spec interface_spec_c = { |
||
2756 | 0, 204, 0, 0, 0, 0, 8, |
||
2757 | { -1, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL }, |
||
2758 | { -1, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL }, |
||
2759 | { -1, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL }, |
||
2760 | { -1, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL }, |
||
2761 | { 1, 1 }, { NetSynchStartGoAhead, NetSynchStartGoAhead }, { 1, 1 }, { NULL, NULL }, |
||
2762 | ExitWhenReady, NetSynchStartDraw, 0, NULL, NetSynchStartStart, NetSynchStartDone, 0, { 0, 0 }, |
||
2763 | NULL, -1, 1, |
||
2764 | COUNT_OF(flicker_on_c), flicker_on_c, flicker_off_c, push_c, |
||
2765 | COUNT_OF(mouse_areas_c), mouse_areas_c, 0, NULL |
||
2766 | }; |
||
2767 | int result; |
||
2768 | LOG_TRACE("(%d)", pMode); |
||
2769 | |||
2770 | if (pMode != eNet_synch_client) { |
||
2771 | if (gCurrent_net_game->status.stage == eNet_game_starting) { |
||
2772 | gCurrent_net_game->status.stage = eNet_game_ready; |
||
2773 | } |
||
2774 | SetUpNetCarPositions(); |
||
2775 | // gNet_synch_start = PDGetTotalTime(); |
||
2776 | } |
||
2777 | TurnOnPaletteConversion(); |
||
2778 | switch (pMode) { |
||
2779 | case eNet_synch_host_first: |
||
2780 | result = DoInterfaceScreen(&interface_spec_hf, 0, 1); |
||
2781 | break; |
||
2782 | case eNet_synch_host_subsequent: |
||
2783 | result = DoInterfaceScreen(&interface_spec_hs, 0, -1); |
||
2784 | break; |
||
2785 | case eNet_synch_client: |
||
2786 | result = DoInterfaceScreen(&interface_spec_c, 0, -1); |
||
2787 | break; |
||
2788 | default: |
||
2789 | break; |
||
2790 | } |
||
2791 | TurnOffPaletteConversion(); |
||
2792 | FadePaletteDown(); |
||
2793 | if (result > -2 && result < 1) { |
||
2794 | NetLeaveGame(gCurrent_net_game); |
||
2795 | } |
||
2796 | return eSO_continue; |
||
2797 | } |
||
2798 | |||
2799 | // IDA: tSO_result __cdecl NetSynchRaceStart() |
||
2800 | tSO_result NetSynchRaceStart(void) { |
||
2801 | LOG_TRACE("()"); |
||
2802 | |||
2803 | SuspendPendingFlic(); |
||
2804 | if (gNet_mode == eNet_mode_host) { |
||
2805 | if (gNo_races_yet) { |
||
2806 | return NetSynchRaceStart2(eNet_synch_host_first); |
||
2807 | } else { |
||
2808 | return NetSynchRaceStart2(eNet_synch_host_subsequent); |
||
2809 | } |
||
2810 | } else { |
||
2811 | return NetSynchRaceStart2(eNet_synch_client); |
||
2812 | } |
||
2813 | } |