#include "displays.h" #include "brender/brender.h" #include "constants.h" #include "controls.h" #include "depth.h" #include "flicplay.h" #include "globvars.h" #include "globvrkm.h" #include "globvrpb.h" #include "grafdata.h" #include "graphics.h" #include "harness/trace.h" #include "netgame.h" #include "pd/sys.h" #include "utility.h" #include int gLast_fancy_index; int gLast_credit_headup__displays; // suffix added to avoid duplicate symbol int gLast_time_credit_headup; tDR_font* gCached_font; br_font* gBR_fonts[4]; tQueued_headup gQueued_headups[4]; int gOld_times[10]; int gLast_fancy_headup; tU32 gLast_time_earn_time; tU32 gLast_centre_headup; tU32 gLast_fancy_time; int gQueued_headup_count; tU32 gLast_earn_time; tU32 gLast_time_credit_amount; int gLast_credit_amount; tHeadup gHeadups[15]; int gLaps_headup; int gCar_kill_count_headup; int gTimer_headup; int gTime_awarded_headup; int gPed_kill_count_headup; int gDim_amount; br_pixelmap* gHeadup_images[32]; // Modified by DethRace for the demo int gNet_cash_headup; int gNet_ped_headup; int gCredits_lost_headup; int gCredits_won_headup; // IDA: void __usercall GetTimerString(char *pStr@, int pFudge_colon@) void GetTimerString(char* pStr, int pFudge_colon) { LOG_TRACE("(\"%s\", %d)", pStr, pFudge_colon); TimerString(gTimer, pStr, pFudge_colon, 0); } // IDA: void __cdecl InitHeadups() void InitHeadups() { int i; LOG_TRACE("()"); for (i = 0; i < 15; i++) { gHeadups[i].type = eHeadup_unused; } gBR_fonts[0] = BrFontProp7x9; gBR_fonts[1] = BrFontFixed3x5; gBR_fonts[2] = gFont_7; gBR_fonts[3] = gHeadup_font; } // IDA: void __usercall ClearHeadup(int pIndex@) void ClearHeadup(int pIndex) { LOG_TRACE("(%d)", pIndex); gHeadups[pIndex].type = eHeadup_unused; } // IDA: void __usercall ClearHeadupSlot(int pSlot_index@) void ClearHeadupSlot(int pSlot_index) { int i; tHeadup* the_headup; LOG_TRACE("(%d)", pSlot_index); the_headup = gHeadups; for (i = 0; i < COUNT_OF(gHeadups); i++) { if (the_headup->type != eHeadup_unused && the_headup->slot_index == pSlot_index) { ClearHeadup(i); return; } the_headup++; } } // IDA: void __cdecl ClearHeadups() void ClearHeadups() { int i; LOG_TRACE("()"); for (i = 0; i < COUNT_OF(gHeadups); i++) { if (gHeadups[i].type) { ClearHeadup(i); } } gLast_fancy_index = -1; gLast_credit_headup__displays = -1; gLast_time_credit_headup = -1; gLast_earn_time = 0; gLast_fancy_time = 0; gLast_time_earn_time = 0; for (i = 0; i < COUNT_OF(gOld_times); i++) { gOld_times[i] = 0; } gQueued_headup_count = 0; gLast_centre_headup = 0; } // IDA: int __usercall HeadupActive@(int pIndex@) int HeadupActive(int pIndex) { LOG_TRACE("(%d)", pIndex); return gHeadups[pIndex].type != eHeadup_unused; } // IDA: void __usercall DRPixelmapText(br_pixelmap *pPixelmap@, int pX@, int pY@, tDR_font *pFont@, char *pText, int pRight_edge) void DRPixelmapText(br_pixelmap* pPixelmap, int pX, int pY, tDR_font* pFont, char* pText, int pRight_edge) { int i; int x; int len; int chr; int ch_width; unsigned char* ch; LOG_TRACE9("(%p, %d, %d, %p, \"%s\", %d)", pPixelmap, pX, pY, pFont, pText, pRight_edge); len = strlen(pText); ch = (unsigned char*)pText; if (pX >= 0 && pPixelmap->width >= pRight_edge && pY >= 0 && (pY + pFont->height) <= pPixelmap->height) { x = pX; for (i = 0; i < len; i++) { chr = ch[i] - pFont->offset; ch_width = pFont->width_table[chr]; DRPixelmapRectangleOnscreenCopy( gBack_screen, x, pY, pFont->images, 0, pFont->height * chr, ch_width, pFont->height); x += ch_width + pFont->spacing; } } else { x = pX; for (i = 0; i < len; i++) { chr = ch[i] - pFont->offset; ch_width = pFont->width_table[chr]; DRPixelmapRectangleMaskedCopy( gBack_screen, x, pY, pFont->images, 0, pFont->height * chr, ch_width, pFont->height); x += ch_width + pFont->spacing; } } } // IDA: void __usercall DRPixelmapCleverText2(br_pixelmap *pPixelmap@, int pX@, int pY@, tDR_font *pFont@, signed char *pText, int pRight_edge) void DRPixelmapCleverText2(br_pixelmap* pPixelmap, int pX, int pY, tDR_font* pFont, signed char* pText, int pRight_edge) { int i; int x; int len; int chr; int ch_width; unsigned char* ch; tDR_font* new_font; LOG_TRACE("(%p, %d, %d, %p, %p, %d)", pPixelmap, pX, pY, pFont, pText, pRight_edge); x = pX; len = strlen((char*)pText); ch = (unsigned char*)pText; if (pX >= 0 && pPixelmap->width >= pRight_edge && pY >= 0 && pY + pFont->height <= pPixelmap->height) { for (i = 0; i < len; i++) { if (*ch < 224) { chr = *ch - pFont->offset; ch_width = pFont->width_table[chr]; DRPixelmapRectangleOnscreenCopy( gBack_screen, x, pY, pFont->images, 0, chr * pFont->height, ch_width, pFont->height); x += ch_width + pFont->spacing; } else { new_font = &gFonts[-*ch + 256]; pY -= (new_font->height - pFont->height) / 2; pFont = new_font; } ch++; } } else { for (i = 0; i < len; i++) { if (*ch < 224) { chr = *ch - pFont->offset; ch_width = pFont->width_table[chr]; DRPixelmapRectangleMaskedCopy( gBack_screen, x, pY, pFont->images, 0, chr * pFont->height, ch_width, pFont->height); x += ch_width + pFont->spacing; } else { new_font = &gFonts[-*ch + 256]; pY -= (new_font->height - pFont->height) / 2; pFont = new_font; } ch++; } } } // IDA: void __usercall DeviouslyDimRectangle(br_pixelmap *pPixelmap@, int pLeft@, int pTop@, int pRight@, int pBottom, int pKnock_out_corners) void DeviouslyDimRectangle(br_pixelmap* pPixelmap, int pLeft, int pTop, int pRight, int pBottom, int pKnock_out_corners) { LOG_TRACE("(%p, %d, %d, %d, %d, %d)", pPixelmap, pLeft, pTop, pRight, pBottom, pKnock_out_corners); NOT_IMPLEMENTED(); } // IDA: void __cdecl DimRectangle(br_pixelmap *pPixelmap, int pLeft, int pTop, int pRight, int pBottom, int pKnock_out_corners) void DimRectangle(br_pixelmap* pPixelmap, int pLeft, int pTop, int pRight, int pBottom, int pKnock_out_corners) { tU8* ptr; tU8* depth_table_ptr; tU8* right_ptr; int x; int y; int line_skip; int width; LOG_TRACE9("(%p, %d, %d, %d, %d, %d)", pPixelmap, pLeft, pTop, pRight, pBottom, pKnock_out_corners); ptr = (tU8*)pPixelmap->pixels + pLeft + pPixelmap->row_bytes * pTop; line_skip = pPixelmap->row_bytes - pRight + pLeft; depth_table_ptr = gDepth_shade_table->pixels; x = gDepth_shade_table->row_bytes * gDim_amount; width = pRight - pLeft; if (pKnock_out_corners) { ptr++; for (right_ptr = ptr + width - 2; ptr < right_ptr; ptr++) { *ptr = depth_table_ptr[*ptr + x]; } ptr += line_skip + 1; for (y = pTop + 1; y < (pBottom - 1); y++, ptr += line_skip) { for (right_ptr = ptr + width; ptr < right_ptr; ptr++) { *ptr = depth_table_ptr[*ptr + x]; } } ptr++; for (right_ptr = ptr + width - 2; ptr < right_ptr; ptr++) { *ptr = depth_table_ptr[*ptr + x]; } } else { for (y = pTop; y < pBottom; y++) { for (right_ptr = ptr + width; ptr < right_ptr; ptr++) { *ptr = depth_table_ptr[*ptr + x]; } ptr += line_skip; } } } // IDA: void __cdecl DimAFewBits() void DimAFewBits() { int i; LOG_TRACE("()"); int dim_index; // Added dim_index = gProgram_state.cockpit_on && gProgram_state.cockpit_image_index >= 0; for (i = 0; i < gProgram_state.current_car.dim_count[dim_index]; i++) { DimRectangle( gBack_screen, gProgram_state.current_car.dim_left[dim_index][i], gProgram_state.current_car.dim_top[dim_index][i], gProgram_state.current_car.dim_right[dim_index][i], gProgram_state.current_car.dim_bottom[dim_index][i], 1); } } // IDA: void __cdecl KillOldestQueuedHeadup() void KillOldestQueuedHeadup() { LOG_TRACE("()"); gQueued_headup_count--; memmove(&gQueued_headups[0], &gQueued_headups[1], gQueued_headup_count * sizeof(tQueued_headup)); } // IDA: void __usercall DubreyBar(int pX_index@, int pY@, int pColour@) void DubreyBar(int pX_index, int pY, int pColour) { int x; LOG_TRACE("(%d, %d, %d)", pX_index, pY, pColour); x = gCurrent_graf_data->ps_bar_left - gCurrent_graf_data->ps_x_pitch * pX_index; BrPixelmapLine(gBack_screen, x, pY, x, gCurrent_graf_data->ps_bar_height + pY, pColour); } // IDA: void __usercall DoPSPowerHeadup(int pY@, int pLevel@, char *pName@, int pBar_colour@) void DoPSPowerHeadup(int pY, int pLevel, char* pName, int pBar_colour) { char s[16]; int i; LOG_TRACE("(%d, %d, \"%s\", %d)", pY, pLevel, pName, pBar_colour); DimRectangle(gBack_screen, gCurrent_graf_data->ps_dim_left, pY, gCurrent_graf_data->ps_dim_right, gCurrent_graf_data->ps_dim_height + pY, 1); TransDRPixelmapText(gBack_screen, gCurrent_graf_data->ps_name_left, gCurrent_graf_data->ps_name_top_border + pY, gFonts + 6, pName, gBack_screen->width); for (i = (6 - gCurrent_graf_data->ps_bars_per_level) * gCurrent_graf_data->ps_bars_per_level + 1; i > (gCurrent_graf_data->ps_bars_per_level * pLevel + 1); i--) { DubreyBar(i, pY + gCurrent_graf_data->ps_bar_top_border, 0); } for (i = gCurrent_graf_data->ps_bars_per_level * pLevel + 1; i >= 0; i--) { DubreyBar(i, pY + gCurrent_graf_data->ps_bar_top_border, pBar_colour); } } // IDA: void __cdecl DoPSPowerupHeadups() void DoPSPowerupHeadups() { LOG_TRACE("()"); DoPSPowerHeadup(gCurrent_graf_data->armour_headup_y[gProgram_state.cockpit_on], gProgram_state.current_car.power_up_levels[0], "A", 45); DoPSPowerHeadup(gCurrent_graf_data->power_headup_y[gProgram_state.cockpit_on], gProgram_state.current_car.power_up_levels[1], "P", 99); DoPSPowerHeadup(gCurrent_graf_data->offense_headup_y[gProgram_state.cockpit_on], gProgram_state.current_car.power_up_levels[2], "O", 4); } // IDA: void __usercall DoHeadups(tU32 pThe_time@) void DoHeadups(tU32 pThe_time) { int i; int x_offset; int y_offset; tHeadup* the_headup; int time_factor; LOG_TRACE("(%d)", pThe_time); if (gNet_mode) { DoNetScores(); } if (gQueued_headup_count && PDGetTotalTime() - gLast_centre_headup >= 1000) { NewTextHeadupSlot(4, gQueued_headups[0].flash_rate, gQueued_headups[0].lifetime, gQueued_headups[0].font_index, gQueued_headups[0].text); KillOldestQueuedHeadup(); } for (i = 0; i < COUNT_OF(gHeadups); i++) { the_headup = &gHeadups[i]; if (the_headup->type != eHeadup_unused && (gProgram_state.which_view == eView_forward || !the_headup->cockpit_anchored) && (the_headup->type == eHeadup_image || the_headup->type == eHeadup_fancy || (the_headup->type == eHeadup_text && the_headup->data.text_info.text[0] != '\0') || ((the_headup->type == eHeadup_coloured_text || the_headup->type == eHeadup_box_text) && the_headup->data.text_info.text[0] != '\0'))) { if (the_headup->type == eHeadup_fancy || the_headup->end_time == 0 || pThe_time < the_headup->end_time) { if (the_headup->dimmed_background) { DimRectangle( gBack_screen, the_headup->dim_left, the_headup->dim_top, the_headup->dim_right, the_headup->dim_bottom, 1); } if (the_headup->flash_period == 0 || Flash(the_headup->flash_period, &the_headup->last_flash, &the_headup->flash_state)) { switch (the_headup->type) { case eHeadup_text: if (the_headup->cockpit_anchored) { y_offset = gScreen_wobble_y; } else { y_offset = 0; } if (the_headup->cockpit_anchored) { x_offset = gScreen_wobble_x; } else { x_offset = 0; } TransBrPixelmapText( gBack_screen, x_offset + the_headup->x, y_offset + the_headup->y, the_headup->data.text_info.colour, the_headup->data.text_info.font, (signed char*)the_headup->data.text_info.text); break; case eHeadup_coloured_text: if (the_headup->clever) { if (the_headup->cockpit_anchored) { y_offset = gScreen_wobble_y; } else { y_offset = 0; } if (the_headup->cockpit_anchored) { x_offset = gScreen_wobble_x; } else { x_offset = 0; } TransDRPixelmapCleverText( gBack_screen, x_offset + the_headup->x, y_offset + the_headup->y, the_headup->data.coloured_text_info.coloured_font, the_headup->data.coloured_text_info.text, the_headup->right_edge); } else { if (the_headup->cockpit_anchored) { y_offset = gScreen_wobble_y; } else { y_offset = 0; } if (the_headup->cockpit_anchored) { x_offset = gScreen_wobble_x; } else { x_offset = 0; } TransDRPixelmapText( gBack_screen, x_offset + the_headup->x, y_offset + the_headup->y, the_headup->data.coloured_text_info.coloured_font, the_headup->data.coloured_text_info.text, the_headup->right_edge); } break; case eHeadup_image: if (the_headup->cockpit_anchored) { y_offset = gScreen_wobble_y; } else { y_offset = 0; } if (the_headup->cockpit_anchored) { x_offset = gScreen_wobble_x; } else { x_offset = 0; } DRPixelmapRectangleMaskedCopy( gBack_screen, x_offset + the_headup->x, y_offset + the_headup->y, the_headup->data.image_info.image, 0, 0, the_headup->data.image_info.image->width, the_headup->data.image_info.image->height); break; case eHeadup_fancy: switch (the_headup->data.fancy_info.fancy_stage) { case eFancy_stage_incoming: the_headup->data.fancy_info.offset -= 500 * gFrame_period / 1000; if (the_headup->data.fancy_info.offset <= the_headup->data.fancy_info.shear_amount) { the_headup->data.fancy_info.offset = the_headup->data.fancy_info.shear_amount; the_headup->data.fancy_info.fancy_stage = eFancy_stage_halting; the_headup->data.fancy_info.start_time = GetTotalTime(); } DRPixelmapRectangleShearedCopy( gBack_screen, the_headup->x + the_headup->data.fancy_info.offset, the_headup->y, the_headup->data.fancy_info.image, 0, 0, the_headup->data.fancy_info.image->width, the_headup->data.fancy_info.image->height, -65536); break; case eFancy_stage_halting: time_factor = 1000 * (pThe_time - the_headup->data.fancy_info.start_time) / 100; if (time_factor > 1000) { if (time_factor > 1500) { time_factor = 1500; the_headup->data.fancy_info.fancy_stage = eFancy_stage_waiting; the_headup->data.fancy_info.start_time = GetTotalTime(); } DRPixelmapRectangleShearedCopy( gBack_screen, the_headup->x - (1500 - time_factor) * the_headup->data.fancy_info.shear_amount / 500, the_headup->y, the_headup->data.image_info.image, 0, 0, the_headup->data.image_info.image->width, the_headup->data.image_info.image->height, (((1500 - time_factor) * the_headup->data.fancy_info.shear_amount / 500) << 16) / the_headup->data.image_info.image->height); } else { DRPixelmapRectangleShearedCopy( gBack_screen, the_headup->x - the_headup->data.fancy_info.shear_amount * (time_factor - 500) / 500, the_headup->y, the_headup->data.image_info.image, 0, 0, the_headup->data.image_info.image->width, the_headup->data.image_info.image->height, ((the_headup->data.fancy_info.shear_amount * (time_factor - 500) / 500) << 16) / the_headup->data.image_info.image->height); } break; case eFancy_stage_waiting: if (pThe_time - the_headup->data.fancy_info.start_time > 1000) { the_headup->data.fancy_info.fancy_stage = eFancy_stage_readying; the_headup->data.fancy_info.start_time = GetTotalTime(); } DRPixelmapRectangleMaskedCopy( gBack_screen, the_headup->x, the_headup->y, the_headup->data.image_info.image, 0, 0, the_headup->data.image_info.image->width, the_headup->data.image_info.image->height); break; case eFancy_stage_readying: time_factor = 1000 * (pThe_time - the_headup->data.fancy_info.start_time) / 100; if (time_factor > 1000) { time_factor = 1000; the_headup->data.fancy_info.fancy_stage = eFancy_stage_leaving; the_headup->data.fancy_info.start_time = GetTotalTime(); the_headup->data.fancy_info.offset = 0; } DRPixelmapRectangleShearedCopy( gBack_screen, the_headup->x, the_headup->y, the_headup->data.image_info.image, 0, 0, the_headup->data.image_info.image->width, the_headup->data.image_info.image->height, -(((time_factor * the_headup->data.fancy_info.shear_amount / 1000) << 16) / the_headup->data.image_info.image->height)); break; case eFancy_stage_leaving: the_headup->data.fancy_info.offset -= 500 * gFrame_period / 1000; if (the_headup->data.fancy_info.offset <= the_headup->data.fancy_info.end_offset) { ClearHeadup(i); } else { DRPixelmapRectangleShearedCopy( gBack_screen, the_headup->data.fancy_info.offset + the_headup->x, the_headup->y, the_headup->data.image_info.image, 0, 0, the_headup->data.image_info.image->width, the_headup->data.image_info.image->height, -65536); } break; default: break; } break; case eHeadup_box_text: if (the_headup->cockpit_anchored) { y_offset = gScreen_wobble_y; } else { y_offset = 0; } if (the_headup->cockpit_anchored) { x_offset = gScreen_wobble_x; } else { x_offset = 0; } OoerrIveGotTextInMeBoxMissus( the_headup->data.coloured_text_info.coloured_font - gFonts, the_headup->data.coloured_text_info.text, gBack_screen, gBack_screen->width / 10, x_offset + the_headup->y, 9 * gBack_screen->width / 10, y_offset + the_headup->y + 60, 1); break; default: break; } } } else { ClearHeadup(i); } } } DoPSPowerupHeadups(); } // IDA: int __usercall FindAHeadupHoleWoofBarkSoundsABitRude@(int pSlot_index@) int FindAHeadupHoleWoofBarkSoundsABitRude(int pSlot_index) { int i; int empty_one; tHeadup* the_headup; LOG_TRACE("(%d)", pSlot_index); empty_one = -1; for (i = 0, the_headup = gHeadups; i < COUNT_OF(gHeadups); i++, the_headup++) { if (pSlot_index >= 0 && the_headup->slot_index == pSlot_index) { return i; } if (the_headup->type == eHeadup_unused) { empty_one = i; break; } } return empty_one; } // IDA: int __usercall DRTextWidth@(tDR_font *pFont@, char *pText@) int DRTextWidth(tDR_font* pFont, char* pText) { int i; int len; int result; char* c; LOG_TRACE("(%p, \"%s\")", pFont, pText); c = pText; result = 0; len = strlen(pText); for (i = 0; i < len; i++) { result += pFont->width_table[*c - pFont->offset]; c++; } return result + pFont->spacing * (len - 1); } // IDA: int __usercall DRTextCleverWidth@(tDR_font *pFont@, signed char *pText@) int DRTextCleverWidth(tDR_font* pFont, signed char* pText) { int i; int len; int result; unsigned char* c; LOG_TRACE("(%p, %p)", pFont, pText); result = 0; len = strlen((char*)pText) + 1; for (i = 0, c = (unsigned char*)pText; i < len; i++, c++) { if (*c < 224) { if (i < (len - 1)) { result += pFont->spacing; } result += pFont->width_table[*c - pFont->offset]; } else { pFont = &gFonts[256 - *c]; } } return result; } // IDA: void __usercall DRPixelmapCentredText(br_pixelmap *pPixelmap@, int pX@, int pY@, tDR_font *pFont@, char *pText) void DRPixelmapCentredText(br_pixelmap* pPixelmap, int pX, int pY, tDR_font* pFont, char* pText) { int width_over_2; LOG_TRACE("(%p, %d, %d, %p, \"%s\")", pPixelmap, pX, pY, pFont, pText); width_over_2 = DRTextWidth(pFont, pText) / 2; TransDRPixelmapText(pPixelmap, pX - width_over_2, pY, pFont, pText, width_over_2 + pX); } // IDA: int __usercall IsHeadupTextClever@(signed char *pText@) int IsHeadupTextClever(signed char* pText) { LOG_TRACE("(%p)", pText); while (*pText) { if (*pText < 0) { return 1; } pText++; } return 0; } // IDA: int __usercall MungeHeadupWidth@(tHeadup *pHeadup@) int MungeHeadupWidth(tHeadup* pHeadup) { int width; LOG_TRACE("(%p)", pHeadup); width = 0; if (pHeadup->type == eHeadup_box_text) { return 0; } if (pHeadup->type == eHeadup_coloured_text) { pHeadup->clever = IsHeadupTextClever((signed char*)(&pHeadup->data.text_info.text)); if (pHeadup->justification) { if (pHeadup->justification == eJust_right) { if (pHeadup->clever) { width = DRTextCleverWidth( pHeadup->data.coloured_text_info.coloured_font, (signed char*)(&pHeadup->data.text_info.text)); } else { width = DRTextWidth(pHeadup->data.coloured_text_info.coloured_font, pHeadup->data.text_info.text); } pHeadup->x = pHeadup->original_x - width; } else if (pHeadup->justification == eJust_centre) { if (pHeadup->clever) { width = DRTextCleverWidth( pHeadup->data.coloured_text_info.coloured_font, (signed char*)(&pHeadup->data.text_info.text)); } else { width = DRTextWidth(pHeadup->data.coloured_text_info.coloured_font, pHeadup->data.text_info.text); } pHeadup->x = pHeadup->original_x - width / 2; } } else { pHeadup->x = pHeadup->original_x; } } else { pHeadup->clever = 0; if (pHeadup->justification) { if (pHeadup->justification == eJust_right) { width = BrPixelmapTextWidth(gBack_screen, pHeadup->data.text_info.font, pHeadup->data.text_info.text); pHeadup->x = pHeadup->original_x - width; } else if (pHeadup->justification == eJust_centre) { width = BrPixelmapTextWidth(gBack_screen, pHeadup->data.text_info.font, pHeadup->data.text_info.text); pHeadup->x = pHeadup->original_x - width / 2; } } else { pHeadup->x = pHeadup->original_x; } } return width; } // IDA: int __usercall NewTextHeadupSlot2@(int pSlot_index@, int pFlash_rate@, int pLifetime@, int pFont_index@, char *pText, int pQueue_it) int NewTextHeadupSlot2(int pSlot_index, int pFlash_rate, int pLifetime, int pFont_index, char* pText, int pQueue_it) { int index; tHeadup* the_headup; tHeadup_slot* headup_slot; tU32 time; LOG_TRACE("(%d, %d, %d, %d, \"%s\", %d)", pSlot_index, pFlash_rate, pLifetime, pFont_index, pText, pQueue_it); time = PDGetTotalTime(); if (pQueue_it && pSlot_index == 4 && (unsigned int)(time - gLast_centre_headup) < 1000) { if (gQueued_headup_count == 4) { KillOldestQueuedHeadup(); } gQueued_headups[gQueued_headup_count].flash_rate = pFlash_rate; gQueued_headups[gQueued_headup_count].lifetime = pLifetime; gQueued_headups[gQueued_headup_count].font_index = pFont_index; strcpy(gQueued_headups[gQueued_headup_count].text, pText); gQueued_headup_count++; index = -1; } else { index = FindAHeadupHoleWoofBarkSoundsABitRude(pSlot_index); if (index >= 0) { if (pSlot_index == 4) { gLast_centre_headup = time; } headup_slot = &gProgram_state.current_car.headup_slots[gProgram_state.cockpit_on][pSlot_index]; the_headup = &gHeadups[index]; the_headup->data.coloured_text_info.coloured_font = &gFonts[-pFont_index]; if (pSlot_index == 4) { the_headup->type = eHeadup_box_text; } else { the_headup->type = eHeadup_coloured_text; } if (!pText) { LOG_PANIC("panic"); } strcpy(the_headup->data.text_info.text, pText); the_headup->slot_index = pSlot_index; the_headup->justification = headup_slot->justification; if (pSlot_index < 0) { the_headup->cockpit_anchored = 0; } else { the_headup->cockpit_anchored = headup_slot->cockpit_anchored; } the_headup->dimmed_background = headup_slot->dimmed_background; the_headup->dim_left = headup_slot->dim_left; the_headup->dim_top = headup_slot->dim_top; the_headup->dim_right = headup_slot->dim_right; the_headup->dim_bottom = headup_slot->dim_bottom; the_headup->original_x = headup_slot->x; the_headup->right_edge = MungeHeadupWidth(the_headup) + the_headup->x; the_headup->y = headup_slot->y; if (pFlash_rate) { the_headup->flash_period = 1000 / pFlash_rate; } else { the_headup->flash_period = 0; } the_headup->last_flash = 0; the_headup->flash_state = 0; if (pLifetime) { the_headup->end_time = GetTotalTime() + pLifetime; } else { the_headup->end_time = 0; } } } return index; } // IDA: int __usercall NewTextHeadupSlot@(int pSlot_index@, int pFlash_rate@, int pLifetime@, int pFont_index@, char *pText) int NewTextHeadupSlot(int pSlot_index, int pFlash_rate, int pLifetime, int pFont_index, char* pText) { LOG_TRACE("(%d, %d, %d, %d, \"%s\")", pSlot_index, pFlash_rate, pLifetime, pFont_index, pText); LOG_DEBUG("(%d, %d, %d, %d, \"%s\")", pSlot_index, pFlash_rate, pLifetime, pFont_index, pText); return NewTextHeadupSlot2(pSlot_index, pFlash_rate, pLifetime, pFont_index, pText, 1); } // IDA: int __usercall NewImageHeadupSlot@(int pSlot_index@, int pFlash_rate@, int pLifetime@, int pImage_index@) int NewImageHeadupSlot(int pSlot_index, int pFlash_rate, int pLifetime, int pImage_index) { int index; tHeadup* the_headup; tHeadup_slot* headup_slot; LOG_TRACE("(%d, %d, %d, %d)", pSlot_index, pFlash_rate, pLifetime, pImage_index); index = FindAHeadupHoleWoofBarkSoundsABitRude(pSlot_index); if (index >= 0) { headup_slot = &gProgram_state.current_car.headup_slots[gProgram_state.cockpit_on][pSlot_index]; the_headup = &gHeadups[index]; the_headup->type = eHeadup_image; the_headup->slot_index = pSlot_index; the_headup->justification = headup_slot->justification; if (pSlot_index < 0) { the_headup->cockpit_anchored = 0; } else { the_headup->cockpit_anchored = headup_slot->cockpit_anchored; } the_headup->dimmed_background = headup_slot->dimmed_background; the_headup->dim_left = headup_slot->dim_left; the_headup->dim_top = headup_slot->dim_top; the_headup->dim_right = headup_slot->dim_right; the_headup->dim_bottom = headup_slot->dim_bottom; the_headup->original_x = headup_slot->x; if (headup_slot->justification) { if (headup_slot->justification == eJust_right) { the_headup->x = the_headup->original_x - gHeadup_images[pImage_index]->width; } else if (headup_slot->justification == eJust_centre) { the_headup->x = the_headup->original_x - gHeadup_images[pImage_index]->width / 2; } } else { the_headup->x = the_headup->original_x; } the_headup->y = headup_slot->y; if (pFlash_rate) { the_headup->flash_period = 1000 / pFlash_rate; } else { the_headup->flash_period = 0; } the_headup->last_flash = 0; the_headup->flash_state = 0; if (pLifetime) { the_headup->end_time = GetTotalTime() + pLifetime; } else { the_headup->end_time = 0; } the_headup->data.image_info.image = gHeadup_images[pImage_index]; } return index; } // IDA: void __usercall DoFancyHeadup(int pIndex@) void DoFancyHeadup(int pIndex) { tU32 the_time; tHeadup* the_headup; int temp_ref; LOG_TRACE("(%d)", pIndex); the_time = GetTotalTime(); if (!gMap_mode && (gLast_fancy_index < 0 || the_time - gLast_fancy_time > 2000 || gLast_fancy_index <= pIndex)) { temp_ref = NewImageHeadupSlot(6, 0, 2000, pIndex + 10); if (temp_ref >= 0) { gLast_fancy_headup = temp_ref; gLast_fancy_index = pIndex; gLast_fancy_time = the_time; the_headup = &gHeadups[temp_ref]; the_headup->type = eHeadup_fancy; the_headup->data.fancy_info.offset = (the_headup->data.image_info.image->width + gBack_screen->width) / 2; the_headup->data.fancy_info.end_offset = -the_headup->data.fancy_info.offset; the_headup->data.fancy_info.fancy_stage = eFancy_stage_incoming; the_headup->data.fancy_info.shear_amount = the_headup->data.image_info.image->height; } } } // IDA: void __cdecl AdjustHeadups() void AdjustHeadups() { int i; int delta_x; int delta_y; tHeadup* the_headup; LOG_TRACE("()"); the_headup = gHeadups; for (i = 0; i < COUNT_OF(gHeadups); i++) { the_headup = &gHeadups[i]; if (the_headup->type == eHeadup_unused) { continue; } delta_x = gProgram_state.current_car.headup_slots[gProgram_state.cockpit_on && gProgram_state.cockpit_image_index >= 0][the_headup->slot_index].x - gProgram_state.current_car.headup_slots[!gProgram_state.cockpit_on || gProgram_state.cockpit_image_index < 0][the_headup->slot_index].x; delta_y = gProgram_state.current_car.headup_slots[gProgram_state.cockpit_on && gProgram_state.cockpit_image_index >= 0][the_headup->slot_index].y - gProgram_state.current_car.headup_slots[!gProgram_state.cockpit_on || gProgram_state.cockpit_image_index < 0][the_headup->slot_index].y; the_headup->x += delta_x; the_headup->original_x += delta_x; the_headup->y += delta_y; the_headup->dim_left += delta_x; the_headup->dim_top += delta_y; the_headup->dim_right += delta_x; the_headup->dim_bottom += delta_y; } } // IDA: void __usercall MoveHeadupTo(int pHeadup_index@, int pNew_x@, int pNew_y@) void MoveHeadupTo(int pHeadup_index, int pNew_x, int pNew_y) { int delta_x; tHeadup* the_headup; LOG_TRACE("(%d, %d, %d)", pHeadup_index, pNew_x, pNew_y); NOT_IMPLEMENTED(); } // IDA: void __usercall ChangeHeadupText(int pHeadup_index@, char *pNew_text@) void ChangeHeadupText(int pHeadup_index, char* pNew_text) { tHeadup* the_headup; LOG_TRACE("(%d, \"%s\")", pHeadup_index, pNew_text); if (pHeadup_index >= 0) { the_headup = &gHeadups[pHeadup_index]; strcpy(the_headup->data.text_info.text, pNew_text); MungeHeadupWidth(the_headup); } } // IDA: void __usercall ChangeHeadupImage(int pHeadup_index@, int pNew_image@) void ChangeHeadupImage(int pHeadup_index, int pNew_image) { tHeadup* the_headup; LOG_TRACE("(%d, %d)", pHeadup_index, pNew_image); if (pHeadup_index >= 0) { the_headup = &gHeadups[pHeadup_index]; the_headup->data.image_info.image = gHeadup_images[pNew_image]; switch (the_headup->justification) { case eJust_left: the_headup->x = the_headup->original_x; break; case eJust_right: the_headup->x = the_headup->original_x - the_headup->data.image_info.image->width; break; case eJust_centre: the_headup->x = the_headup->original_x - the_headup->data.image_info.image->width / 2; break; } } } // IDA: void __usercall ChangeHeadupColour(int pHeadup_index@, int pNew_colour@) void ChangeHeadupColour(int pHeadup_index, int pNew_colour) { LOG_TRACE("(%d, %d)", pHeadup_index, pNew_colour); if (pHeadup_index >= 0) { gHeadups[pHeadup_index].data.text_info.colour = gColours[pNew_colour]; } } // IDA: void __usercall DoDamageScreen(tU32 pThe_time@) void DoDamageScreen(tU32 pThe_time) { int i; int y_pitch; int the_step; int the_wobble_x; int the_wobble_y; br_pixelmap* the_image; tDamage_unit* the_damage; LOG_TRACE("(%d)", pThe_time); if (&gProgram_state.current_car != gCar_to_view || gProgram_state.current_car_index != gProgram_state.current_car.index) { return; } if (gProgram_state.cockpit_on && gProgram_state.cockpit_image_index >= 0) { if (gProgram_state.which_view != eView_forward) { return; } the_wobble_y = gScreen_wobble_x; the_wobble_x = gScreen_wobble_y; } else { the_wobble_y = gProgram_state.current_car.damage_x_offset; the_wobble_x = gProgram_state.current_car.damage_y_offset; if (gProgram_state.current_car.damage_background) { DRPixelmapRectangleMaskedCopy( gBack_screen, gProgram_state.current_car.damage_background_x, gProgram_state.current_car.damage_background_y, gProgram_state.current_car.damage_background, 0, 0, gProgram_state.current_car.damage_background->width, gProgram_state.current_car.damage_background->height); } } for (i = 0; i < COUNT_OF(gProgram_state.current_car.damage_units); i++) { the_damage = &gProgram_state.current_car.damage_units[i]; if (i != 2) { the_image = the_damage->images; the_step = 5 * the_damage->damage_level / 100; y_pitch = (the_image->height / 2) / 5; DRPixelmapRectangleMaskedCopy( gBack_screen, the_wobble_y + gProgram_state.current_car.damage_units[i].x_coord, the_wobble_x + gProgram_state.current_car.damage_units[i].y_coord, the_image, 0, y_pitch * (2 * (5 * the_damage->damage_level / 100) + ((pThe_time / the_damage->periods[5 * the_damage->damage_level / 100]) & 1)), the_image->width, y_pitch); } } } // IDA: void __cdecl PoshDrawLine(float pAngle, br_pixelmap *pDestn, int pX1, int pY1, int pX2, int pY2, int pColour) void PoshDrawLine(float pAngle, br_pixelmap* pDestn, int pX1, int pY1, int pX2, int pY2, int pColour) { LOG_TRACE("(%f, %p, %d, %d, %d, %d, %d)", pAngle, pDestn, pX1, pY1, pX2, pY2, pColour); if (pColour < 0) { if (pAngle >= 0.785 && pAngle <= 5.498 && (pAngle <= 2.356 || pAngle >= 3.926)) { if ((pAngle <= 0.785 || pAngle >= 1.57) && (pAngle <= 3.926 || pAngle >= 4.712)) { DRDrawLine(pDestn, pX1 - 1, pY1, pX2 - 1, pY2, -pColour - 1); DRDrawLine(pDestn, pX1 + 1, pY1, pX2 + 1, pY2, 1 - pColour); } else { DRDrawLine(pDestn, pX1 - 1, pY1, pX2 - 1, pY2, 1 - pColour); DRDrawLine(pDestn, pX1 + 1, pY1, pX2 + 1, pY2, -pColour - 1); } } else { DRDrawLine(pDestn, pX1, pY1 + 1, pX2, pY2 + 1, -pColour - 1); DRDrawLine(pDestn, pX1, pY1 - 1, pX2, pY2 - 1, 1 - pColour); } DRDrawLine(pDestn, pX1, pY1, pX2, pY2, -pColour); } else { DRDrawLine(pDestn, pX1, pY1, pX2, pY2, pColour); } } // IDA: void __usercall DoInstruments(tU32 pThe_time@) void DoInstruments(tU32 pThe_time) { br_pixelmap* speedo_image; br_pixelmap* tacho_image; int the_wobble_x; int the_wobble_y; int gear; double the_angle; double the_angle2; double sin_angle; double cos_angle; double speed_mph; LOG_TRACE("(%d)", pThe_time); if (gProgram_state.current_car_index == gProgram_state.current_car.index) { speed_mph = gCar_to_view->speedo_speed * WORLD_SCALE / 1600.0f * 3600000.0f; if (speed_mph < 0.0f) { speed_mph = 0.0f; } if (gProgram_state.cockpit_on && gProgram_state.cockpit_image_index >= 0) { if (gProgram_state.which_view != eView_forward) { return; } the_wobble_x = gScreen_wobble_x; the_wobble_y = gScreen_wobble_y; } else { the_wobble_x = 0; the_wobble_y = 0; } tacho_image = gProgram_state.current_car.tacho_image[gProgram_state.cockpit_on]; if (gProgram_state.current_car.tacho_radius_2[gProgram_state.cockpit_on] >= 0) { if (gCar_to_view->red_line >= gCar_to_view->revs) { the_angle = DEG_TO_RAD((double)(gProgram_state.current_car.tacho_end_angle[gProgram_state.cockpit_on] - gProgram_state.current_car.tacho_start_angle[gProgram_state.cockpit_on]) * gCar_to_view->revs / (double)gCar_to_view->red_line + (double)gProgram_state.current_car.tacho_start_angle[gProgram_state.cockpit_on]); } else { the_angle = DEG_TO_RAD((double)gProgram_state.current_car.tacho_end_angle[gProgram_state.cockpit_on]); } if (the_angle >= 0.0) { if (the_angle >= 6.283185307179586) { the_angle = the_angle - 6.283185307179586; } } else { the_angle = the_angle + 6.283185307179586; } the_angle2 = 1.570796326794897 - the_angle; if (the_angle2 < 0) { the_angle2 = the_angle2 + 6.283185307179586; } if (the_angle2 > 4.71238898038469) { cos_angle = gCosine_array[(unsigned int)((6.283185307179586 - the_angle2) / DR_PI * 128.0)]; } else if (the_angle2 > DR_PI) { cos_angle = -gCosine_array[(unsigned int)((the_angle2 - DR_PI) / DR_PI * 128.0)]; } else if (the_angle2 > 1.5707963267948966) { cos_angle = -gCosine_array[(unsigned int)((DR_PI - the_angle2) / DR_PI * 128.0)]; } else { cos_angle = gCosine_array[(unsigned int)(the_angle2 / DR_PI * 128.0)]; } if (the_angle > 4.71238898038469) { sin_angle = gCosine_array[(unsigned int)((6.283185307179586 - the_angle) / DR_PI * 128.0)]; } else if (the_angle > DR_PI) { sin_angle = -gCosine_array[(unsigned int)((the_angle - DR_PI) / DR_PI * 128.0)]; } else if (the_angle > 1.5707963267948966) { sin_angle = -gCosine_array[(unsigned int)((DR_PI - the_angle) / DR_PI * 128.0)]; } else { sin_angle = gCosine_array[(unsigned int)(the_angle / DR_PI * 128.0)]; } if (tacho_image != NULL) { DRPixelmapRectangleMaskedCopy( gBack_screen, the_wobble_x + gProgram_state.current_car.tacho_x[gProgram_state.cockpit_on], the_wobble_y + gProgram_state.current_car.tacho_y[gProgram_state.cockpit_on], tacho_image, 0, 0, tacho_image->width, tacho_image->height); } PoshDrawLine( the_angle, gBack_screen, ((double)gProgram_state.current_car.tacho_radius_1[gProgram_state.cockpit_on] * sin_angle + (double)gProgram_state.current_car.tacho_centre_x[gProgram_state.cockpit_on] + (double)the_wobble_x), ((double)gProgram_state.current_car.tacho_centre_y[gProgram_state.cockpit_on] - (double)gProgram_state.current_car.tacho_radius_1[gProgram_state.cockpit_on] * cos_angle + (double)the_wobble_y), ((double)gProgram_state.current_car.tacho_radius_2[gProgram_state.cockpit_on] * sin_angle + (double)gProgram_state.current_car.tacho_centre_x[gProgram_state.cockpit_on] + (double)the_wobble_x), ((double)gProgram_state.current_car.tacho_centre_y[gProgram_state.cockpit_on] - (double)gProgram_state.current_car.tacho_radius_2[gProgram_state.cockpit_on] * cos_angle + (double)the_wobble_y), gProgram_state.current_car.tacho_needle_colour[gProgram_state.cockpit_on]); } else if (tacho_image != NULL) { BrPixelmapRectangleCopy( gBack_screen, the_wobble_x + gProgram_state.current_car.tacho_x[gProgram_state.cockpit_on], the_wobble_y + gProgram_state.current_car.tacho_y[gProgram_state.cockpit_on], gProgram_state.current_car.tacho_image[gProgram_state.cockpit_on], 0, 0, ((gCar_to_view->revs - 1.0) / (double)gCar_to_view->red_line * (double)gProgram_state.current_car.tacho_image[gProgram_state.cockpit_on]->width + 1.0), gProgram_state.current_car.tacho_image[gProgram_state.cockpit_on]->height); } if (!gProgram_state.cockpit_on || gProgram_state.cockpit_image_index < 0 || gProgram_state.which_view == eView_forward) { if (gCar_to_view->gear < 0) { gear = -1; } else { gear = gCar_to_view->gear; } DRPixelmapRectangleMaskedCopy( gBack_screen, the_wobble_x + gProgram_state.current_car.gear_x[gProgram_state.cockpit_on], the_wobble_y + gProgram_state.current_car.gear_y[gProgram_state.cockpit_on], gProgram_state.current_car.gears_image, 0, (gear + 1) * ((int)gProgram_state.current_car.gears_image->height >> 3), gProgram_state.current_car.gears_image->width, (int)gProgram_state.current_car.gears_image->height >> 3); } speedo_image = gProgram_state.current_car.speedo_image[gProgram_state.cockpit_on]; if (gProgram_state.current_car.speedo_radius_2[gProgram_state.cockpit_on] >= 0) { if (speedo_image && (!gProgram_state.cockpit_on || gProgram_state.cockpit_image_index < 0)) { DRPixelmapRectangleMaskedCopy( gBack_screen, the_wobble_x + gProgram_state.current_car.speedo_x[gProgram_state.cockpit_on], the_wobble_y + gProgram_state.current_car.speedo_y[gProgram_state.cockpit_on], speedo_image, 0, 0, speedo_image->width, speedo_image->height); } if ((double)gProgram_state.current_car.max_speed >= speed_mph) { the_angle = DEG_TO_RAD((double)(gProgram_state.current_car.speedo_end_angle[gProgram_state.cockpit_on] - gProgram_state.current_car.speedo_start_angle[gProgram_state.cockpit_on]) * speed_mph / (double)gProgram_state.current_car.max_speed + (double)gProgram_state.current_car.speedo_start_angle[gProgram_state.cockpit_on]); } else { the_angle = DEG_TO_RAD((double)gProgram_state.current_car.speedo_end_angle[gProgram_state.cockpit_on]); } if (the_angle >= 0.0) { if (the_angle >= 6.283185307179586) { the_angle = the_angle - 6.283185307179586; } } else { the_angle = the_angle + 6.283185307179586; } the_angle2 = 1.570796326794897 - the_angle; if (the_angle2 < 0.0) { the_angle2 = the_angle2 + 6.283185307179586; } if (the_angle2 > 4.71238898038469) { cos_angle = gCosine_array[(unsigned int)((6.283185307179586 - the_angle2) / DR_PI * 128.0)]; } else if (the_angle2 > DR_PI) { cos_angle = -gCosine_array[(unsigned int)((the_angle2 - DR_PI) / DR_PI * 128.0)]; } else if (the_angle2 > 1.5707963267948966) { cos_angle = -gCosine_array[(unsigned int)((DR_PI - the_angle2) / DR_PI * 128.0)]; } else { cos_angle = gCosine_array[(unsigned int)(the_angle2 / DR_PI * 128.0)]; } if (the_angle > 4.71238898038469) { sin_angle = gCosine_array[(unsigned int)((6.283185307179586 - the_angle) / DR_PI * 128.0)]; } else if (the_angle > DR_PI) { sin_angle = -gCosine_array[(unsigned int)((the_angle - DR_PI) / DR_PI * 128.0)]; } else if (the_angle > 1.5707963267948966) { sin_angle = -gCosine_array[(unsigned int)((DR_PI - the_angle) / DR_PI * 128.0)]; } else { sin_angle = gCosine_array[(unsigned int)(the_angle / DR_PI * 128.0)]; } PoshDrawLine( the_angle, gBack_screen, ((double)gProgram_state.current_car.speedo_radius_1[gProgram_state.cockpit_on] * sin_angle + (double)gProgram_state.current_car.speedo_centre_x[gProgram_state.cockpit_on] + (double)the_wobble_x), ((double)gProgram_state.current_car.speedo_centre_y[gProgram_state.cockpit_on] - (double)gProgram_state.current_car.speedo_radius_1[gProgram_state.cockpit_on] * cos_angle + (double)the_wobble_y), ((double)gProgram_state.current_car.speedo_radius_2[gProgram_state.cockpit_on] * sin_angle + (double)gProgram_state.current_car.speedo_centre_x[gProgram_state.cockpit_on] + (double)the_wobble_x), ((double)gProgram_state.current_car.speedo_centre_y[gProgram_state.cockpit_on] - (double)gProgram_state.current_car.speedo_radius_2[gProgram_state.cockpit_on] * cos_angle + (double)the_wobble_y), gProgram_state.current_car.speedo_needle_colour[gProgram_state.cockpit_on]); if (speedo_image != NULL && gProgram_state.cockpit_on && gProgram_state.cockpit_image_index >= 0) { DRPixelmapRectangleMaskedCopy( gBack_screen, the_wobble_x + gProgram_state.current_car.speedo_x[gProgram_state.cockpit_on], the_wobble_y + gProgram_state.current_car.speedo_y[gProgram_state.cockpit_on], speedo_image, 0, 0, speedo_image->width, speedo_image->height); } } else if (speedo_image != NULL) { DrawNumberAt( speedo_image, the_wobble_x + gProgram_state.current_car.speedo_x[gProgram_state.cockpit_on], the_wobble_y + gProgram_state.current_car.speedo_y[gProgram_state.cockpit_on], gProgram_state.current_car.speedo_x_pitch[gProgram_state.cockpit_on], gProgram_state.current_car.speedo_y_pitch[gProgram_state.cockpit_on], speed_mph, 3, 1); } } } // IDA: void __usercall DoSteeringWheel(tU32 pThe_time@) void DoSteeringWheel(tU32 pThe_time) { br_pixelmap* hands_image; int hands_index; LOG_TRACE("(%d)", pThe_time); if (gProgram_state.current_car_index == gProgram_state.current_car.index && gProgram_state.cockpit_on && gProgram_state.cockpit_image_index >= 0 && gProgram_state.which_view == eView_forward) { hands_index = (int)floor(gProgram_state.current_car.number_of_hands_images * ((1.f - gProgram_state.current_car.steering_angle / 10.f) / 2.f)); if (hands_index < 0) { hands_index = 0; } else if (hands_index >= gProgram_state.current_car.number_of_hands_images) { hands_index = gProgram_state.current_car.number_of_hands_images - 1; } hands_image = gProgram_state.current_car.lhands_images[hands_index]; if (hands_image != NULL) { DRPixelmapRectangleMaskedCopy(gBack_screen, gProgram_state.current_car.lhands_x[hands_index] + gScreen_wobble_x, gProgram_state.current_car.lhands_y[hands_index] + gScreen_wobble_y, hands_image, 0, 0, hands_image->width, hands_image->height); } hands_image = gProgram_state.current_car.rhands_images[hands_index]; if (hands_image != NULL) { DRPixelmapRectangleMaskedCopy(gBack_screen, gProgram_state.current_car.rhands_x[hands_index] + gScreen_wobble_x, gProgram_state.current_car.rhands_y[hands_index] + gScreen_wobble_y, hands_image, 0, 0, hands_image->width, hands_image->height); } } } // IDA: void __cdecl ChangingView() void ChangingView() { tU32 the_time; LOG_TRACE("()"); if (gProgram_state.new_view == eView_undefined) { return; } the_time = PDGetTotalTime() - gProgram_state.view_change_start; gScreen_wobble_x = 0; gScreen_wobble_y = 0; if (the_time > 175 && gProgram_state.which_view == gProgram_state.new_view) { if (gProgram_state.pending_view != eView_undefined) { if (gProgram_state.pending_view == eView_left) { LookLeft(); return; } if (gProgram_state.pending_view == eView_forward) { LookForward(); return; } if (gProgram_state.pending_view == eView_right) { LookRight(); return; } gScreen_wobble_x = 0; gScreen_wobble_y = 0; return; } if (gProgram_state.which_view == gProgram_state.new_view) { gProgram_state.new_view = eView_undefined; gScreen_wobble_x = 0; gScreen_wobble_y = 0; return; } } if (the_time < 88) { if (gProgram_state.old_view < gProgram_state.new_view) { gScreen_wobble_x = -gCurrent_graf_data->cock_margin_x * the_time * 2.f / 175.f; } else { gScreen_wobble_x = gCurrent_graf_data->cock_margin_x * the_time * 2.f / 175.f; } } else { gProgram_state.which_view = gProgram_state.new_view; switch (gProgram_state.new_view) { case eView_left: gProgram_state.cockpit_image_index = 1; break; case eView_forward: gProgram_state.cockpit_image_index = 0; break; case eView_right: gProgram_state.cockpit_image_index = 2; break; default: break; } AdjustRenderScreenSize(); if (gProgram_state.old_view < gProgram_state.new_view) { gScreen_wobble_x = gCurrent_graf_data->cock_margin_x * (175 - the_time) * 2.f / 175.f; } else { gScreen_wobble_x = -gCurrent_graf_data->cock_margin_x * (175 - the_time) * 2.f / 175.f; } } } // IDA: void __usercall EarnCredits2(int pAmount@, char *pPrefix_text@) void EarnCredits2(int pAmount, char* pPrefix_text) { char s[256]; int original_amount; tU32 the_time; LOG_TRACE("(%d, \"%s\")", pAmount, pPrefix_text); if (gRace_finished) { return; } the_time = GetTotalTime(); if (pAmount == 0) { return; } if (gNet_mode != eNet_mode_none && (gProgram_state.credits_earned - gProgram_state.credits_lost + pAmount) < 0) { // Should this also substract pAmount? pAmount = gProgram_state.credits_lost - gProgram_state.credits_lost; } original_amount = pAmount; if (gLast_credit_headup__displays >= 0 && (the_time - gLast_earn_time) < 2000) { pAmount += gLast_credit_amount; } gLast_credit_amount = pAmount; if (pAmount >= 2) { sprintf(s, "%s%d %s", pPrefix_text, pAmount, GetMiscString(12)); gProgram_state.credits_earned += original_amount; } else if (pAmount >= 1) { sprintf(s, "%s1 %s", pPrefix_text, GetMiscString(13)); gProgram_state.credits_earned += original_amount; } else if (pAmount >= -1) { sprintf(s, "%s%s 1 %s", pPrefix_text, GetMiscString(14), GetMiscString(15)); gProgram_state.credits_lost -= original_amount; } else { sprintf(s, "%s%s %d %s", GetMiscString(14), pPrefix_text, -pAmount, GetMiscString(12)); gProgram_state.credits_lost -= original_amount; } gLast_credit_headup__displays = NewTextHeadupSlot(4, 0, 2000, -4, s); gLast_earn_time = the_time; } // IDA: void __usercall EarnCredits(int pAmount@) void EarnCredits(int pAmount) { LOG_TRACE("(%d)", pAmount); EarnCredits2(pAmount, ""); } // IDA: int __usercall SpendCredits@(int pAmount@) int SpendCredits(int pAmount) { int amount; LOG_TRACE("(%d)", pAmount); gProgram_state.credits_lost += pAmount; if (gNet_mode == eNet_mode_none) { return 0; } amount = gProgram_state.credits_earned - gProgram_state.credits_lost; if (gProgram_state.credits_earned - gProgram_state.credits_lost >= 0) { return 0; } gProgram_state.credits_lost = gProgram_state.credits_earned; return amount; } // IDA: void __usercall AwardTime(tU32 pTime@) void AwardTime(tU32 pTime) { char s[256]; tU32 original_amount; tU32 the_time; int i; LOG_TRACE("(%d)", pTime); if (gRace_finished || gFreeze_timer || gNet_mode == eNet_mode_none || pTime == 0) { return; } original_amount = pTime; the_time = GetTotalTime(); for (i = COUNT_OF(gOld_times) - 1; i > 0; i--) { gOld_times[i] = gOld_times[i - 1]; } gOld_times[0] = pTime; if (gLast_time_credit_headup >= 0 && (the_time - gLast_time_earn_time) < 2000) { pTime += gLast_time_credit_headup; } gLast_time_credit_headup = pTime; gTimer += original_amount * 1000; TimerString(1000 * pTime, s, 0, 0); gLast_time_credit_headup = NewTextHeadupSlot(11, 0, 2000, -2, s); gLast_time_earn_time = the_time; } // IDA: void __usercall DrawRectangle(br_pixelmap *pPixelmap@, int pLeft@, int pTop@, int pRight@, int pBottom, int pColour) void DrawRectangle(br_pixelmap* pPixelmap, int pLeft, int pTop, int pRight, int pBottom, int pColour) { LOG_TRACE("(%p, %d, %d, %d, %d, %d)", pPixelmap, pLeft, pTop, pRight, pBottom, pColour); BrPixelmapLine(pPixelmap, pLeft, pTop, pRight, pTop, pColour); BrPixelmapLine(pPixelmap, pLeft, pBottom, pRight, pBottom, pColour); BrPixelmapLine(pPixelmap, pLeft, pTop, pLeft, pBottom, pColour); BrPixelmapLine(pPixelmap, pRight, pTop, pRight, pBottom, pColour); } // IDA: void __usercall DrawRRectangle(br_pixelmap *pPixelmap@, int pLeft@, int pTop@, int pRight@, int pBottom, int pColour) void DrawRRectangle(br_pixelmap* pPixelmap, int pLeft, int pTop, int pRight, int pBottom, int pColour) { LOG_TRACE("(%p, %d, %d, %d, %d, %d)", pPixelmap, pLeft, pTop, pRight, pBottom, pColour); BrPixelmapLine(pPixelmap, pLeft + 1, pTop, pRight - 1, pTop, pColour); BrPixelmapLine(pPixelmap, pLeft + 1, pBottom, pRight - 1, pBottom, pColour); BrPixelmapLine(pPixelmap, pLeft, pTop + 1, pLeft, pBottom - 1, pColour); BrPixelmapLine(pPixelmap, pRight, pTop + 1, pRight, pBottom - 1, pColour); } // IDA: void __usercall OoerrIveGotTextInMeBoxMissus(int pFont_index@, char *pText@, br_pixelmap *pPixelmap@, int pLeft@, int pTop, int pRight, int pBottom, int pCentred) void OoerrIveGotTextInMeBoxMissus(int pFont_index, char* pText, br_pixelmap* pPixelmap, int pLeft, int pTop, int pRight, int pBottom, int pCentred) { tDR_font* font; int width; int current_width; int i; int centre; int line_char_index; int input_str_index; int start_line; int current_y; int font_needed_loading; char line[256]; LOG_TRACE("(%d, \"%s\", %p, %d, %d, %d, %d, %d)", pFont_index, pText, pPixelmap, pLeft, pTop, pRight, pBottom, pCentred); font = &gFonts[pFont_index]; current_width = 0; font_needed_loading = font->images == NULL; if (font_needed_loading) { LoadFont(pFont_index); } centre = (pRight + pLeft) / 2; current_y = pTop; width = pRight - pLeft; line_char_index = 0; input_str_index = 0; start_line = 0; while (pText[input_str_index]) { line[line_char_index] = pText[input_str_index]; line[line_char_index + 1] = 0; current_width += font->spacing + font->width_table[pText[input_str_index] - font->offset]; if (current_width > width) { for (i = input_str_index; i >= start_line; i--) { if (pText[i] == ' ') { break; } } if (i == start_line) { i = input_str_index; } line_char_index += i - input_str_index; input_str_index = i; if (pText[input_str_index] == ' ') { input_str_index++; } line[line_char_index] = 0; if (pCentred) { DRPixelmapCentredText(gBack_screen, centre, current_y, font, line); } else { TransDRPixelmapText(gBack_screen, pLeft, current_y, font, line, pRight); } current_width = 0; current_y += 3 * (font->height - (TranslationMode() ? 2 : 0)) / 2; line_char_index = 0; start_line = input_str_index; } else { line_char_index++; input_str_index++; } } if (line_char_index != 0) { if (pCentred) { TransDRPixelmapText(gBack_screen, centre - (DRTextWidth(font, line) / 2), current_y, font, line, (DRTextWidth(font, line) / 2) + centre); } else { TransDRPixelmapText(gBack_screen, pLeft, current_y, font, line, pRight); } } if (font_needed_loading) { DisposeFont(pFont_index); } } // IDA: void __usercall TransBrPixelmapText(br_pixelmap *pPixelmap@, int pX@, int pY@, br_uint_32 pColour@, br_font *pFont, signed char *pText) void TransBrPixelmapText(br_pixelmap* pPixelmap, int pX, int pY, br_uint_32 pColour, br_font* pFont, signed char* pText) { int len; LOG_TRACE("(%p, %d, %d, %d, %p, %p)", pPixelmap, pX, pY, pColour, pFont, pText); len = TranslationMode() ? 2 : 0; BrPixelmapText(pPixelmap, pX, pY - len, pColour, pFont, (char*)pText); } // IDA: void __usercall TransDRPixelmapText(br_pixelmap *pPixelmap@, int pX@, int pY@, tDR_font *pFont@, char *pText, int pRight_edge) void TransDRPixelmapText(br_pixelmap* pPixelmap, int pX, int pY, tDR_font* pFont, char* pText, int pRight_edge) { LOG_TRACE("(%p, %d, %d, %p, \"%s\", %d)", pPixelmap, pX, pY, pFont, pText, pRight_edge); if (gAusterity_mode && FlicsPlayedFromDisk() && pFont != gCached_font) { if (gCached_font != NULL && gCached_font - gFonts > 13) { DisposeFont(gCached_font - gFonts); } gCached_font = pFont; } LoadFont(pFont - gFonts); DRPixelmapText(pPixelmap, pX, pY - (TranslationMode() ? 2 : 0), pFont, pText, pRight_edge); } // IDA: void __usercall TransDRPixelmapCleverText(br_pixelmap *pPixelmap@, int pX@, int pY@, tDR_font *pFont@, char *pText, int pRight_edge) void TransDRPixelmapCleverText(br_pixelmap* pPixelmap, int pX, int pY, tDR_font* pFont, char* pText, int pRight_edge) { LOG_TRACE("(%p, %d, %d, %p, \"%s\", %d)", pPixelmap, pX, pY, pFont, pText, pRight_edge); if (gAusterity_mode && FlicsPlayedFromDisk() && gCached_font != pFont) { if (gCached_font && gCached_font - gFonts > 13) { DisposeFont(gCached_font - gFonts); } gCached_font = pFont; } LoadFont(pFont - gFonts); DRPixelmapCleverText2(pPixelmap, pX, pY - (TranslationMode() == 0 ? 0 : 2), pFont, (signed char*)pText, pRight_edge); }