Rev 18 | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1 | pmbaty | 1 | #include "racestrt.h" |
| 20 | pmbaty | 2 | #include "brender/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; |
||
| 20 | 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) { |
||
| 20 | pmbaty | 622 | *pCar_index = gProgram_state.cars_available[gCurrent_race_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 | } |