diff --git a/src/BRSRC13/CORE/FW/datafile.c b/src/BRSRC13/CORE/FW/datafile.c index 87e21d47..cbd33b1b 100644 --- a/src/BRSRC13/CORE/FW/datafile.c +++ b/src/BRSRC13/CORE/FW/datafile.c @@ -868,7 +868,6 @@ void DfClose(br_datafile* df) { } } dfp = DfPop(BR_MEMORY_FILE, NULL); - LOG_DEBUG("popped h=%p, raw_file=%p", dfp->h, ((br_file*)dfp->h)->raw_file); BrFileClose(dfp->h); BrResFree(dfp); } diff --git a/src/BRSRC13/CORE/FW/file.c b/src/BRSRC13/CORE/FW/file.c index 5363e5d0..45bb6b88 100644 --- a/src/BRSRC13/CORE/FW/file.c +++ b/src/BRSRC13/CORE/FW/file.c @@ -13,7 +13,6 @@ void _BrFileFree(void* res, br_uint_8 res_class, br_size_t size) { br_file* file; file = (br_file*)res; - LOG_DEBUG("Closing %s", file->name); fw.fsys->close(file->raw_file); } diff --git a/src/BRSRC13/CORE/PIXELMAP/pmdsptch.c b/src/BRSRC13/CORE/PIXELMAP/pmdsptch.c index 17e95bfc..d649e00e 100644 --- a/src/BRSRC13/CORE/PIXELMAP/pmdsptch.c +++ b/src/BRSRC13/CORE/PIXELMAP/pmdsptch.c @@ -148,7 +148,7 @@ void BrPixelmapRectangleCopy(br_pixelmap* dst, br_int_32 dx, br_int_32 dy, br_pi br_rectangle r; br_point p; - // Taken from Errol's brender + // Thanks Errol! br_uint_8* src_pix = (br_uint_8*)src->pixels; br_uint_8* dst_pix = (br_uint_8*)dst->pixels; @@ -194,7 +194,19 @@ void BrPixelmapRectangleStretchCopy(br_pixelmap* dst, br_int_32 dx, br_int_32 dy void BrPixelmapRectangleFill(br_pixelmap* dst, br_int_32 x, br_int_32 y, br_int_32 w, br_int_32 h, br_uint_32 colour) { br_rectangle r; LOG_TRACE("(%p, %d, %d, %d, %d, %d)", dst, x, y, w, h, colour); - NOT_IMPLEMENTED(); + br_uint_8* dst_pix = (br_uint_8*)dst->pixels; + + for (int i = 0; i < w; i++) { + if (x + i < 0 || x + i >= dst->width) { + continue; + } + for (int j = 0; j < h; j++) { + if (y + j < 0 || y + j >= dst->height) { + continue; + } + dst_pix[(y + j) * dst->row_bytes + (x + i)] = colour; + } + } } // IDA: void __cdecl BrPixelmapDirtyRectangleCopy(br_pixelmap *dst, br_pixelmap *src, br_int_32 x, br_int_32 y, br_int_32 w, br_int_32 h) @@ -222,8 +234,9 @@ void BrPixelmapDirtyRectangleDoubleBuffer(br_pixelmap* dst, br_pixelmap* src, br // IDA: void __cdecl BrPixelmapPixelSet(br_pixelmap *dst, br_int_32 x, br_int_32 y, br_uint_32 colour) void BrPixelmapPixelSet(br_pixelmap* dst, br_int_32 x, br_int_32 y, br_uint_32 colour) { br_point p; - LOG_TRACE("(%p, %d, %d, %d)", dst, x, y, colour); - NOT_IMPLEMENTED(); + //LOG_TRACE("(%p, %d, %d, %d)", dst, x, y, colour); + br_uint_8* dst_pix = (br_uint_8*)dst->pixels; + dst_pix[(y * dst->row_bytes) + x] = (br_uint_8)colour; } // IDA: br_uint_32 __cdecl BrPixelmapPixelGet(br_pixelmap *dst, br_int_32 x, br_int_32 y) @@ -244,10 +257,46 @@ void BrPixelmapCopy(br_pixelmap* dst, br_pixelmap* src) { // IDA: void __cdecl BrPixelmapLine(br_pixelmap *dst, br_int_32 x1, br_int_32 y1, br_int_32 x2, br_int_32 y2, br_uint_32 colour) void BrPixelmapLine(br_pixelmap* dst, br_int_32 x1, br_int_32 y1, br_int_32 x2, br_int_32 y2, br_uint_32 colour) { - br_point s; - br_point e; + //br_point s; + //br_point e; LOG_TRACE("(%p, %d, %d, %d, %d, %d)", dst, x1, y1, x2, y2, colour); - NOT_IMPLEMENTED(); + + // Thanks Errol! + br_int_16 dx, dy, inx, iny, e; + dx = x2 - x1; + dy = y2 - y1; + inx = dx > 0 ? 1 : -1; + iny = dy > 0 ? 1 : -1; + dx = abs(dx); + dy = abs(dy); + if (dx >= dy) { + dy <<= 1; + e = dy - dx; + dx <<= 1; + while (x1 != x2) { + BrPixelmapPixelSet(dst, x1, y1, colour); + if (e >= 0) { + y1 += iny; + e -= dx; + } + e += dy; + x1 += inx; + } + } else { + dx <<= 1; + e = dx - dy; + dy <<= 1; + while (y1 != y2) { + BrPixelmapPixelSet(dst, x1, y1, colour); + if (e >= 0) { + x1 += inx; + e -= dy; + } + e += dx; + y1 += iny; + } + } + BrPixelmapPixelSet(dst, x1, y1, colour); } // IDA: void __cdecl BrPixelmapDoubleBuffer(br_pixelmap *dst, br_pixelmap *src) diff --git a/src/BRSRC13/CORE/V1DB/v1dbfile.c b/src/BRSRC13/CORE/V1DB/v1dbfile.c index b4617953..255c0fa0 100644 --- a/src/BRSRC13/CORE/V1DB/v1dbfile.c +++ b/src/BRSRC13/CORE/V1DB/v1dbfile.c @@ -212,9 +212,6 @@ int FopRead_VERTICES(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_ mp = DfTop(DF_MODEL, NULL); mp->vertices = BrResAllocate(mp, sizeof(br_vertex) * count, BR_MEMORY_VERTICES); DfStructReadArray(df, &br_vertex_F, mp->vertices, count); - for (i = 0; i < count; i++) { - LOG_DEBUG("vert %f, %f, %f", mp->vertices[i].p.v[0], mp->vertices[i].p.v[1], mp->vertices[i].p.v[2]); - } mp->nvertices = count; return 0; } @@ -289,10 +286,6 @@ int FopRead_FACES(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 } } - for (i = 0; i < count; i++) { - LOG_DEBUG("face %d, %d, %d %d", mp->faces[i].vertices[0], mp->faces[i].vertices[1], mp->faces[i].vertices[2], mp->faces[i].flags); - } - return 0; } @@ -783,7 +776,6 @@ br_uint_32 BrMaterialLoadMany(char* filename, br_material** materials, br_uint_1 materials[count] = DfPop(DF_MATERIAL, 0); ++count; } - LOG_DEBUG("r=%d", r); } while (r); DfClose(df); } diff --git a/src/DETHRACE/common/displays.c b/src/DETHRACE/common/displays.c index 232519e0..637de4f5 100644 --- a/src/DETHRACE/common/displays.c +++ b/src/DETHRACE/common/displays.c @@ -87,8 +87,27 @@ void DRPixelmapText(br_pixelmap* pPixelmap, int pX, int pY, tDR_font* pFont, cha int chr; int ch_width; unsigned char* ch; - LOG_TRACE("(%p, %d, %d, %p, \"%s\", %d)", pPixelmap, pX, pY, pFont, pText, pRight_edge); - NOT_IMPLEMENTED(); + LOG_TRACE9("(%p, %d, %d, %p, \"%s\", %d)", pPixelmap, pX, pY, pFont, pText, pRight_edge); + len = strlen(pText); + if (pX >= 0 && pPixelmap->width >= pRight_edge && pY >= 0 && pY + pFont->height <= pPixelmap->height) { + x = pX; + for (i = 0; i < len; i++) { + chr = pText[i] - pFont->offset; + DRPixelmapRectangleOnscreenCopy( + gBack_screen, + x, + pY, + pFont->images, + 0, + pFont->height * chr, + pFont->width_table[chr], + pFont->height); + + x += pFont->width_table[chr] + pFont->spacing; + } + } else { + LOG_PANIC("not implemented"); + } } // IDA: void __usercall DRPixelmapCleverText2(br_pixelmap *pPixelmap@, int pX@, int pY@, tDR_font *pFont@, signed char *pText, int pRight_edge) @@ -406,7 +425,62 @@ void OoerrIveGotTextInMeBoxMissus(int pFont_index, char* pText, br_pixelmap* pPi 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); - NOT_IMPLEMENTED(); + + 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; + + 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) { + 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); + } + 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) diff --git a/src/DETHRACE/common/errors.c b/src/DETHRACE/common/errors.c index d803617e..22fd538e 100644 --- a/src/DETHRACE/common/errors.c +++ b/src/DETHRACE/common/errors.c @@ -5,6 +5,7 @@ #include #include +#include "network.h" #include "pc-dos/dossys.h" #include "utility.h" @@ -199,5 +200,6 @@ void dr_dprintf(char* fmt_string, ...) { // IDA: int __usercall DoErrorInterface@(int pMisc_text_index@) int DoErrorInterface(int pMisc_text_index) { LOG_TRACE("(%d)", pMisc_text_index); - NOT_IMPLEMENTED(); + NetFullScreenMessage(pMisc_text_index, 0); + return 0; } diff --git a/src/DETHRACE/common/flicplay.c b/src/DETHRACE/common/flicplay.c index 6569fd16..ee3a5a26 100644 --- a/src/DETHRACE/common/flicplay.c +++ b/src/DETHRACE/common/flicplay.c @@ -1274,7 +1274,28 @@ int LoadFlicData(char* pName, tU8** pData, tU32* pData_length) { FILE* f; tPath_name the_path; LOG_TRACE("(\"%s\", %p, %p)", pName, pData, pData_length); - NOT_IMPLEMENTED(); + + if (*pData) { + return 1; + } + if (!gPlay_from_disk) { + PossibleService(); + PathCat(the_path, gApplication_path, "ANIM"); + PathCat(the_path, the_path, pName); + f = DRfopen(the_path, "rb"); + if (!f) { + return 0; + } + *pData_length = GetFileLength(f); + *pData = BrMemAllocate(*pData_length, kMem_flic_data_2); + if (!*pData) { + fclose(f); + return 0; + } + fread(*pData, 1u, *pData_length, f); + fclose(f); + } + return 1; } // IDA: void __usercall FreeFlic(int pIndex@) @@ -1521,13 +1542,37 @@ void AddToFlicQueue(int pIndex, int pX, int pY, int pMust_finish) { void InitialiseFlicPanel(int pIndex, int pLeft, int pTop, int pWidth, int pHeight) { void* the_pixels; LOG_TRACE("(%d, %d, %d, %d, %d)", pIndex, pLeft, pTop, pWidth, pHeight); - NOT_IMPLEMENTED(); + + gPanel_flic[pIndex].data = NULL; + gPanel_flic_left[pIndex] = pLeft; + gPanel_flic_top[pIndex] = pTop; + the_pixels = BrMemAllocate(pHeight * ((pWidth + 3) & 0xFC), 0x93u); + if (gScreen->row_bytes < 0) { + BrFatal( + "..\\..\\source\\common\\flicplay.c", + 2116, + "Bruce bug at line %d, file ..\\..\\source\\common\\flicplay.c", + 68); + } + gPanel_buffer[pIndex] = DRPixelmapAllocate(gScreen->type, pWidth, pHeight, the_pixels, 0); } // IDA: void __usercall DisposeFlicPanel(int pIndex@) void DisposeFlicPanel(int pIndex) { LOG_TRACE("(%d)", pIndex); - NOT_IMPLEMENTED(); + + if (gPanel_flic[pIndex].f) { + BrMemFree(gPanel_flic[pIndex].data_start); + gPanel_flic[pIndex].data_start = NULL; + fclose(gPanel_flic[pIndex].f); + gPanel_flic[pIndex].f = NULL; + } + if (gPanel_flic[pIndex].data) { + gPanel_flic[pIndex].data = NULL; + } + BrMemFree(gPanel_buffer[pIndex]->pixels); + BrPixelmapFree(gPanel_buffer[pIndex]); + gPanel_buffer[pIndex] = NULL; } // IDA: void __usercall ServicePanelFlics(int pCopy_to_buffer@) @@ -1600,13 +1645,37 @@ void ServicePanelFlics(int pCopy_to_buffer) { // IDA: void __usercall ChangePanelFlic(int pIndex@, tU8 *pData@, tU32 pData_length@) void ChangePanelFlic(int pIndex, tU8* pData, tU32 pData_length) { LOG_TRACE("(%d, %p, %d)", pIndex, pData, pData_length); - NOT_IMPLEMENTED(); + + if (gPanel_flic[pIndex].f) { + BrMemFree(gPanel_flic[pIndex].data_start); + gPanel_flic[pIndex].data_start = NULL; + fclose(gPanel_flic[pIndex].f); + gPanel_flic[pIndex].f = NULL; + } + if (gPanel_flic[pIndex].data) { + gPanel_flic[pIndex].data = NULL; + } + gPanel_flic_data[pIndex] = pData; + gPanel_flic_data_length[pIndex] = pData_length; + BrPixelmapFill(gPanel_buffer[pIndex], 0); + StartFlic( + gPanel_flic[pIndex].file_name, + pIndex, + &gPanel_flic[pIndex], + gPanel_flic_data_length[pIndex], + (tS8*)gPanel_flic_data[pIndex], + gPanel_buffer[pIndex], + 0, + 0, + 0); + gLast_panel_frame_time[pIndex] = 0; + ServicePanelFlics(0); } // IDA: br_pixelmap* __usercall GetPanelPixelmap@(int pIndex@) br_pixelmap* GetPanelPixelmap(int pIndex) { LOG_TRACE("(%d)", pIndex); - NOT_IMPLEMENTED(); + return gPanel_buffer[pIndex]; } // IDA: void __cdecl LoadInterfaceStrings() diff --git a/src/DETHRACE/common/grafdata.c b/src/DETHRACE/common/grafdata.c index 88b9343c..cb6f5b92 100644 --- a/src/DETHRACE/common/grafdata.c +++ b/src/DETHRACE/common/grafdata.c @@ -209,7 +209,7 @@ tGraf_data gGraf_data[2] = { 13, 40, 292, - 4294967293, + -3, 8, 126, 163, @@ -488,7 +488,7 @@ tGraf_data gGraf_data[2] = { 13, 40, 292, - 4294967293, + -3, 8, 126, 163, diff --git a/src/DETHRACE/common/graphics.c b/src/DETHRACE/common/graphics.c index 7272e8bc..c5036f04 100644 --- a/src/DETHRACE/common/graphics.c +++ b/src/DETHRACE/common/graphics.c @@ -813,7 +813,11 @@ void KillSplashScreen() { // IDA: void __cdecl EnsureRenderPalette() void EnsureRenderPalette() { LOG_TRACE("()"); - NOT_IMPLEMENTED(); + if (gPalette_munged) { + RevertPalette(); + DRSetPalette(gRender_palette); + gPalette_munged = 0; + } } // IDA: void __usercall SplashScreenWith(char *pPixmap_name@) @@ -890,7 +894,7 @@ void DRPixelmapRectangleOnscreenCopy(br_pixelmap* pDest, br_int_16 pDest_x, br_i tU8* source_ptr; tU8* dest_ptr; tU8* conv_table; - LOG_TRACE("(%p, %d, %d, %p, %d, %d, %d, %d)", pDest, pDest_x, pDest_y, pSource, pSource_x, pSource_y, pWidth, pHeight); + //LOG_TRACE("(%p, %d, %d, %p, %d, %d, %d, %d)", pDest, pDest_x, pDest_y, pSource, pSource_x, pSource_y, pWidth, pHeight); source_row_wrap = pSource->row_bytes - pWidth; dest_row_wrap = pDest->row_bytes - pWidth; @@ -944,7 +948,33 @@ void DRPixelmapRectangleVScaledCopy(br_pixelmap* pDest, br_int_16 pDest_x, br_in tU32 source_y_delta; tU32 old_source_y; LOG_TRACE("(%p, %d, %d, %p, %d, %d, %d, %d)", pDest, pDest_x, pDest_y, pSource, pSource_x, pSource_y, pWidth, pHeight); - NOT_IMPLEMENTED(); + + if (!pHeight) { + return; + } + + source_row_wrap = pSource->row_bytes - pWidth; + dest_row_wrap = pDest->row_bytes - pWidth; + dest_ptr = pDest->pixels + (pDest->row_bytes * pDest_y + pDest_x); + source_ptr = pSource->pixels + (pSource->row_bytes * pSource_y + pSource_x); + + source_y = 0; + source_y_delta = (pSource->height << 16) / pHeight - 0x10000; + + for (y_count = 0; y_count < pHeight; y_count++) { + for (x_count = 0; x_count < pWidth; x_count++) { + the_byte = *source_ptr; + if (the_byte) { + *dest_ptr = the_byte; + } + source_ptr++; + dest_ptr++; + } + old_source_y = source_y; + source_y += source_y_delta; + source_ptr += (((source_y >> 16) - (old_source_y >> 16)) * pSource->row_bytes) + source_row_wrap; + dest_ptr += dest_row_wrap; + } } // IDA: void __cdecl InitTransientBitmaps() @@ -1177,14 +1207,32 @@ void DrawTellyLine(br_pixelmap* pImage, int pLeft, int pTop, int pPercentage) { int the_width; int the_height; LOG_TRACE("(%p, %d, %d, %d)", pImage, pLeft, pTop, pPercentage); - NOT_IMPLEMENTED(); + + the_width = pImage->width; + the_height = pImage->height / 2 + pTop; + BrPixelmapLine(gBack_screen, pLeft, the_height, pLeft + the_width, the_height, 0); + BrPixelmapLine(gBack_screen, the_width / 2 + pLeft - pPercentage * the_width / 200, the_height, the_width / 2 + pLeft + pPercentage * the_width / 200, the_height, 1); + PDScreenBufferSwap(0); } // IDA: void __usercall DrawTellyImage(br_pixelmap *pImage@, int pLeft@, int pTop@, int pPercentage@) void DrawTellyImage(br_pixelmap* pImage, int pLeft, int pTop, int pPercentage) { int the_height; LOG_TRACE("(%p, %d, %d, %d)", pImage, pLeft, pTop, pPercentage); - NOT_IMPLEMENTED(); + + BrPixelmapRectangleFill(gBack_screen, pLeft, pTop, pImage->width, pImage->height, 0); + if (pPercentage != 1000) { + DRPixelmapRectangleVScaledCopy( + gBack_screen, + pLeft, + pTop + pImage->height * (100 - pPercentage) / 200, + pImage, + 0, + 0, + pImage->width, + pPercentage * pImage->height / 100); + PDScreenBufferSwap(0); + } } // IDA: void __usercall TellyInImage(br_pixelmap *pImage@, int pLeft@, int pTop@) @@ -1192,7 +1240,24 @@ void TellyInImage(br_pixelmap* pImage, int pLeft, int pTop) { tS32 start_time; tS32 the_time; LOG_TRACE("(%p, %d, %d)", pImage, pLeft, pTop); - NOT_IMPLEMENTED(); + + start_time = PDGetTotalTime(); + while (1) { + the_time = PDGetTotalTime(); + if (the_time - start_time > 100) { + break; + } + DrawTellyLine(pImage, pLeft, pTop, 100 * (the_time - start_time) / 100); + } + start_time = PDGetTotalTime(); + while (1) { + the_time = PDGetTotalTime(); + if (the_time - start_time > 100) { + break; + } + DrawTellyImage(pImage, pLeft, pTop, 100 * (the_time - start_time) / 100); + } + DrawTellyImage(pImage, pLeft, pTop, 100); } // IDA: void __usercall TellyOutImage(br_pixelmap *pImage@, int pLeft@, int pTop@) @@ -1201,7 +1266,28 @@ void TellyOutImage(br_pixelmap* pImage, int pLeft, int pTop) { tS32 the_time; int drop_distance; LOG_TRACE("(%p, %d, %d)", pImage, pLeft, pTop); - NOT_IMPLEMENTED(); + + start_time = PDGetTotalTime(); + while (1) { + the_time = PDGetTotalTime(); + if (the_time - start_time > 100) { + break; + } + DrawTellyImage(pImage, pLeft, pTop, 100 * (100 - the_time + start_time) / 100); + } + + DrawTellyImage(pImage, pLeft, pTop, 1000); + + start_time = PDGetTotalTime(); + while (1) { + the_time = PDGetTotalTime(); + if (the_time - start_time > 100) { + break; + } + DrawTellyLine(pImage, pLeft, pTop, 100 * (start_time + 100 - the_time) / 100); + } + + DrawTellyLine(pImage, pLeft, pTop, 0); } // IDA: void __usercall SetShadowLevel(tShadow_level pLevel@) diff --git a/src/DETHRACE/common/graphics.h b/src/DETHRACE/common/graphics.h index ff273252..1db09037 100644 --- a/src/DETHRACE/common/graphics.h +++ b/src/DETHRACE/common/graphics.h @@ -91,28 +91,6 @@ extern int gMap_render_y_i; extern int gMirror_on; extern br_scalar gYon_squared; -#define FONT_TYPEABLE 0 -#define FONT_ORANGHED 1 -#define FONT_BLUEHEAD 2 -#define FONT_GREENHED 3 -#define FONT_MEDIUMHD 4 -#define FONT_TIMER 5 -#define FONT_NEWHITE 6 -#define FONT_NEWRED 7 -#define FONT_NEWBIGGR 8 -#define FONT_GRNDK 9 -#define FONT_GRNLIT 10 -#define FONT_GRYDK 11 -#define FONT_GRYLIT 12 -#define FONT_BUTTIN 13 -#define FONT_BUTTOUT 14 -#define FONT_LITPLAQ 15 -#define FONT_DRKPLAQ 16 -#define FONT_BUTTIN1 17 -#define FONT_BUTTOUT1 18 -#define FONT_LITPLAQ1 19 -#define FONT_DRKPLAQ1 20 - void TurnOnPaletteConversion(); void TurnOffPaletteConversion(); diff --git a/src/DETHRACE/common/input.c b/src/DETHRACE/common/input.c index 52594ab7..ab556bb3 100644 --- a/src/DETHRACE/common/input.c +++ b/src/DETHRACE/common/input.c @@ -1,6 +1,10 @@ #include "input.h" -#include "common/globvars.h" +#include "brender.h" +#include "errors.h" +#include "globvars.h" +#include "grafdata.h" +#include "graphics.h" #include "pc-dos/dossys.h" #include "utility.h" #include @@ -26,6 +30,8 @@ int gGo_ahead_keys[3] = { 51, 52, 106 }; // enter, return, space int gKey_mapping[67]; char gCurrent_typing[110]; +#define NBR_ROLLING_LETTERS 500 + // IDA: void __usercall SetJoystickArrays(int *pKeys@, int pMark@) void SetJoystickArrays(int* pKeys, int pMark) { int i; @@ -93,6 +99,7 @@ tKey_down_result PDKeyDown2(int pKey_index) { return gKey_array[pKey_index]; } the_time = PDGetTotalTime(); + if (gKey_array[pKey_index]) { if (pKey_index == gLast_key_down) { if ((the_time - gLast_key_down_time) < 300) { @@ -108,7 +115,7 @@ tKey_down_result PDKeyDown2(int pKey_index) { } } else { if (pKey_index == gLast_key_down) { - gLast_key_down_time = gKey_array[pKey_index]; + gLast_key_down_time = 0; gLast_key_down = -1; } return tKey_down_no; @@ -134,7 +141,13 @@ int PDKeyDown3(int pKey_index) { int last_key_down; tKey_down_result result; LOG_TRACE("(%d)", pKey_index); - NOT_IMPLEMENTED(); + + last_key_down = gLast_key_down; + last_key_down_time = gLast_key_down_time; + result = PDKeyDown2(pKey_index); + gLast_key_down_time = last_key_down_time; + gLast_key_down = last_key_down; + return result == tKey_down_yes || result == tKey_down_repeat; } // IDA: int __cdecl PDAnyKeyDown() @@ -315,13 +328,19 @@ void GetMousePosition(int* pX_coord, int* pY_coord) { void InitRollingLetters() { int i; LOG_TRACE("()"); - NOT_IMPLEMENTED(); + + gLast_roll = 0; + gCurrent_cursor = -1; + gRolling_letters = BrMemAllocate(NBR_ROLLING_LETTERS * sizeof(tRolling_letter), kMem_rolling_letters); + for (i = 0; i < NBR_ROLLING_LETTERS; i++) { + gRolling_letters[i].number_of_letters = -1; + } } // IDA: void __cdecl EndRollingLetters() void EndRollingLetters() { LOG_TRACE("()"); - NOT_IMPLEMENTED(); + BrMemFree(gRolling_letters); } // IDA: int __usercall AddRollingLetter@(char pChar@, int pX@, int pY@, tRolling_type rolling_type@) @@ -330,14 +349,56 @@ int AddRollingLetter(char pChar, int pX, int pY, tRolling_type rolling_type) { int i; int number_of_letters; LOG_TRACE("(%d, %d, %d, %d)", pChar, pX, pY, rolling_type); - NOT_IMPLEMENTED(); + + let = &gRolling_letters[0]; + //if (let->number_of_letters >= 0) { + for (i = 0; i < NBR_ROLLING_LETTERS; i++) { + let = &gRolling_letters[i]; + if (let->number_of_letters < 0) { + break; + } + } + if (i == NBR_ROLLING_LETTERS) { + LOG_WARN("no rolling slot available"); + return -1; + } + //} + + let->x_coord = pX; + let->y_coord = pY; + let->rolling_type = rolling_type; + if (rolling_type == eRT_looping_random) { + let->number_of_letters = 9; + } else if (rolling_type == eRT_looping_single) { + let->number_of_letters = 2; + } else { + let->number_of_letters = IRandomBetween(3, 9); + } + + let->current_offset = (gCurrent_graf_data->save_slot_letter_height * let->number_of_letters); + for (i = 0; i < let->number_of_letters; i++) { + if (rolling_type == eRT_numeric) { + let->letters[i] = pChar; + } else { + let->letters[i] = IRandomBetween(65, 91); + } + } + if (rolling_type != eRT_looping_random) { + let->letters[0] = pChar; + } + + return 0; } // IDA: void __usercall AddRollingString(char *pStr@, int pX@, int pY@, tRolling_type rolling_type@) void AddRollingString(char* pStr, int pX, int pY, tRolling_type rolling_type) { int i; LOG_TRACE("(\"%s\", %d, %d, %d)", pStr, pX, pY, rolling_type); - NOT_IMPLEMENTED(); + + for (i = 0; i < strlen(pStr); i++) { + AddRollingLetter(pStr[i], pX, pY, rolling_type); + pX += gCurrent_graf_data->rolling_letter_x_pitch; + } } // IDA: void __usercall AddRollingNumber(tU32 pNumber@, int pWidth@, int pX@, int pY@) @@ -365,8 +426,56 @@ void RollLettersIn() { tU8* saved_char_ptr; tU8* source_ptr; tU8 the_byte; - LOG_TRACE("()"); - NOT_IMPLEMENTED(); + LOG_TRACE9("()"); + + new_time = PDGetTotalTime(); + if (gLast_roll) { + period = new_time - gLast_roll; + } else { + period = 0; + } + font_height = gFonts[FONT_TYPEABLE].height; + font_width = gFonts[FONT_TYPEABLE].width; + the_row_bytes = gFonts[FONT_TYPEABLE].images->row_bytes; + + for (i = 0; i < NBR_ROLLING_LETTERS; i++) { + let = &gRolling_letters[i]; + if (let->number_of_letters >= 0) { + char_ptr = gBack_screen->pixels; + char_ptr += let->y_coord * gBack_screen->row_bytes + let->x_coord; + if (let->current_offset > 0) { + let->current_offset -= period * 0.18f; + if (let->current_offset <= 0.0) { + if (let->rolling_type == eRT_looping_random || let->rolling_type == eRT_looping_single) { + let->current_offset = (gCurrent_graf_data->save_slot_letter_height * let->number_of_letters) + let->current_offset; + } else { + let->current_offset = 0.0f; + } + } + } + for (j = 0; j < gCurrent_graf_data->save_slot_height; j++) { + offset = gCurrent_graf_data->save_slot_table[j] + let->current_offset; + which_letter = offset / gCurrent_graf_data->save_slot_letter_height; + letter_offset = offset % gCurrent_graf_data->save_slot_letter_height - (gCurrent_graf_data->save_slot_letter_height - font_height) / 2; + saved_char_ptr = char_ptr; + if (which_letter < let->number_of_letters && which_letter >= 0 && letter_offset >= 0 && letter_offset < font_height) { + + // LOG_DEBUG("chars %d, %d, %d, %d", let->letters[0], let->letters[1], let->letters[2], let->letters[3]); + source_ptr = gFonts[FONT_TYPEABLE].images->pixels + (font_height * (let->letters[which_letter] - 32) + letter_offset) * the_row_bytes; + for (k = 0; k < font_width; k++) { + the_byte = *source_ptr; + if (the_byte) { + *char_ptr = the_byte; + } + char_ptr++; + source_ptr++; + } + } + char_ptr = saved_char_ptr + gBack_screen->row_bytes; + } + } + } + gLast_roll = new_time; } // IDA: int __usercall ChangeCharTo@(int pSlot_index@, int pChar_index@, char pNew_char@) @@ -378,7 +487,39 @@ int ChangeCharTo(int pSlot_index, int pChar_index, char pNew_char) { tRolling_letter* let; tRolling_type new_type; LOG_TRACE("(%d, %d, %d)", pSlot_index, pChar_index, pNew_char); - NOT_IMPLEMENTED(); + + if (pChar_index >= gVisible_length || pChar_index < 0) { + return -1; + } + y_coord = gLetter_y_coords[pSlot_index]; + x_coord = gCurrent_graf_data->rolling_letter_x_pitch * pChar_index + gLetter_x_coords[pSlot_index]; + + if (pNew_char == ROLLING_LETTER_LOOP_RANDOM) { + new_type = eRT_looping_random; + } else if (pNew_char >= 0x30 && pNew_char <= 0x39) { + new_type = eRT_numeric; + } else { + new_type = eRT_alpha; + } + + for (i = 0; i < NBR_ROLLING_LETTERS; i++) { + let = &gRolling_letters[i]; + if (let->number_of_letters >= 0 && x_coord == let->x_coord && y_coord == let->y_coord) { + break; + } + } + if (i >= NBR_ROLLING_LETTERS) { + return AddRollingLetter(pNew_char, x_coord, y_coord, new_type); + } + if (pNew_char != ROLLING_LETTER_LOOP_RANDOM) { + let->letters[0] = pNew_char; + } + if (pNew_char == ' ') { + let->letters[0] = 32; + } + let->rolling_type = new_type; + let->current_offset = gCurrent_graf_data->save_slot_letter_height * let->number_of_letters; + return i; } // IDA: void __usercall ChangeTextTo(int pXcoord@, int pYcoord@, char *pNew_str@, char *pOld_str@) @@ -398,7 +539,7 @@ void ChangeTextTo(int pXcoord, int pYcoord, char* pNew_str, char* pOld_str) { // IDA: void __usercall SetRollingCursor(int pSlot_index@) void SetRollingCursor(int pSlot_index) { LOG_TRACE("(%d)", pSlot_index); - NOT_IMPLEMENTED(); + gCurrent_cursor = ChangeCharTo(pSlot_index, gCurrent_position, ROLLING_LETTER_LOOP_RANDOM); } // IDA: void __usercall BlankSlot(int pIndex@, int pName_length@, int pVisible_length@) @@ -413,7 +554,23 @@ void DoRLBackspace(int pSlot_index) { int i; int new_len; LOG_TRACE("(%d)", pSlot_index); - NOT_IMPLEMENTED(); + + if (gCurrent_position) { + if (strlen(gCurrent_typing) == gCurrent_position) { + new_len = strlen(gCurrent_typing); + } else { + new_len = strlen(gCurrent_typing) - 1; + } + ChangeCharTo(pSlot_index, new_len, ' '); + new_len = strlen(gCurrent_typing) - 1; + for (i = gCurrent_position - 1; i < new_len; i++) { + ChangeCharTo(pSlot_index, i, gCurrent_typing[i]); + gCurrent_typing[i] = gCurrent_typing[i + 1]; + } + gCurrent_typing[new_len] = 0; + gCurrent_position = gCurrent_position - 1; + gCurrent_cursor = ChangeCharTo(pSlot_index, gCurrent_position, ROLLING_LETTER_LOOP_RANDOM); + } } // IDA: void __usercall DoRLDelete(int pSlot_index@) @@ -433,7 +590,16 @@ void DoRLInsert(int pSlot_index) { // IDA: void __usercall DoRLCursorLeft(int pSlot_index@) void DoRLCursorLeft(int pSlot_index) { LOG_TRACE("(%d)", pSlot_index); - NOT_IMPLEMENTED(); + if (gCurrent_position) { + if (strlen(gCurrent_typing) == gCurrent_position) { + ChangeCharTo(pSlot_index, strlen(gCurrent_typing), ' '); + } else { + ChangeCharTo(pSlot_index, gCurrent_position, gCurrent_typing[gCurrent_position]); + } + + gCurrent_position--; + gCurrent_cursor = ChangeCharTo(pSlot_index, gCurrent_position, ROLLING_LETTER_LOOP_RANDOM); + } } // IDA: void __usercall DoRLCursorRight(int pSlot_index@) @@ -447,7 +613,38 @@ void DoRLTypeLetter(int pChar, int pSlot_index) { int i; int new_len; LOG_TRACE("(%d, %d)", pChar, pSlot_index); - NOT_IMPLEMENTED(); + + //v2 = pSlot_index; + if (pChar >= 32) { + if (gInsert_mode) { + new_len = strlen(gCurrent_typing) + 1; + if (new_len > 100) { + new_len = 100; + DoErrorInterface(-1); + } + for (i = new_len - 1; i > gCurrent_position; i--) { + gCurrent_typing[i] = gCurrent_typing[i - 1]; + ChangeCharTo(pSlot_index, i, gCurrent_typing[i]); + } + } else if (strlen(gCurrent_typing) == gCurrent_position) { + new_len = strlen(gCurrent_typing) + 1; + } else { + new_len = strlen(gCurrent_typing); + } + if (new_len > 100) { + new_len = 100; + DoErrorInterface(-1); + } + + gCurrent_typing[new_len] = 0; + if (new_len - 1 < gCurrent_position) { + gCurrent_position = new_len - 1; + } + gCurrent_typing[gCurrent_position] = pChar; + ChangeCharTo(pSlot_index, gCurrent_position, pChar); + gCurrent_position++; + gCurrent_cursor = ChangeCharTo(pSlot_index, gCurrent_position, ROLLING_LETTER_LOOP_RANDOM); + } } // IDA: void __usercall StopTyping(int pSlot_index@) @@ -461,31 +658,76 @@ void StopTyping(int pSlot_index) { void RevertTyping(int pSlot_index, char* pRevert_str) { int i; LOG_TRACE("(%d, \"%s\")", pSlot_index, pRevert_str); - NOT_IMPLEMENTED(); + + for (i = 0; i < gThe_length; i++) { + ChangeCharTo(pSlot_index, i, i >= strlen(pRevert_str) ? ' ' : pRevert_str[i]); + } } // IDA: void __usercall StartTyping(int pSlot_index@, char *pText@, int pVisible_length@) void StartTyping(int pSlot_index, char* pText, int pVisible_length) { LOG_TRACE("(%d, \"%s\", %d)", pSlot_index, pText, pVisible_length); - NOT_IMPLEMENTED(); + gThe_length = pVisible_length; + strcpy(gCurrent_typing, pText); + gVisible_length = pVisible_length; + gCurrent_position = strlen(gCurrent_typing); + gCurrent_cursor = ChangeCharTo(pSlot_index, gCurrent_position, ROLLING_LETTER_LOOP_RANDOM); } // IDA: void __usercall TypeKey(int pSlot_index@, char pKey@) void TypeKey(int pSlot_index, char pKey) { LOG_TRACE("(%d, %d)", pSlot_index, pKey); - NOT_IMPLEMENTED(); + + //if (pKey < 0x40u) { + //if (pKey >= 0x2Fu) { + if (pKey == KEY_GRAVE) { + return; + } + if (pKey == KEY_BACKSPACE) { + DoRLBackspace(pSlot_index); + return; + } + //} + if (pKey == KEY_INSERT) { + gInsert_mode = !gInsert_mode; + return; + } + if (pKey == KEY_DELETE) { + DoRLDelete(pSlot_index); + return; + } + if (pKey == KEY_LEFT) { + DoRLCursorLeft(pSlot_index); + return; + } + if (pKey != KEY_RIGHT) { + DoRLTypeLetter(PDGetASCIIFromKey(pKey), pSlot_index); + return; + } + if (strlen(gCurrent_typing) > gCurrent_position) { + ChangeCharTo(pSlot_index, gCurrent_position, gCurrent_typing[gCurrent_position]); + ++gCurrent_position; + SetRollingCursor(pSlot_index); + } } // IDA: void __usercall SetSlotXY(int pSlot_index@, int pX_coord@, int pY_coord@) void SetSlotXY(int pSlot_index, int pX_coord, int pY_coord) { LOG_TRACE("(%d, %d, %d)", pSlot_index, pX_coord, pY_coord); - NOT_IMPLEMENTED(); + + gLetter_x_coords[pSlot_index] = pX_coord; + gLetter_y_coords[pSlot_index] = pY_coord; } // IDA: void __usercall GetTypedName(char *pDestn@, int pMax_length@) void GetTypedName(char* pDestn, int pMax_length) { LOG_TRACE("(\"%s\", %d)", pDestn, pMax_length); - NOT_IMPLEMENTED(); + if (strlen(gCurrent_typing) <= pMax_length) { + strcpy(pDestn, gCurrent_typing); + } else { + memcpy(pDestn, gCurrent_typing, pMax_length); + pDestn[pMax_length] = 0; + } } // IDA: void __usercall KillCursor(int pSlot_index@) @@ -497,7 +739,19 @@ void KillCursor(int pSlot_index) { tRolling_letter* let; tRolling_type new_type; LOG_TRACE("(%d)", pSlot_index); - NOT_IMPLEMENTED(); + + if (gCurrent_position < gVisible_length && gCurrent_position >= 0) { + y_coord = gLetter_y_coords[pSlot_index]; + x_coord = gCurrent_graf_data->rolling_letter_x_pitch * gCurrent_position + gLetter_x_coords[pSlot_index]; + let = gRolling_letters; + for (i = 0; i < NBR_ROLLING_LETTERS; i++) { + let = &gRolling_letters[i]; + if (let->number_of_letters >= 0 && x_coord == let->x_coord && y_coord == let->y_coord) { + gRolling_letters[i].number_of_letters = -1; + break; + } + } + } } // IDA: void __cdecl EdgeTriggerModeOn() diff --git a/src/DETHRACE/common/intrface.c b/src/DETHRACE/common/intrface.c index 06777b73..6e61f812 100644 --- a/src/DETHRACE/common/intrface.c +++ b/src/DETHRACE/common/intrface.c @@ -48,7 +48,7 @@ void ResetInterfaceTimeout() { void ChangeSelection(tInterface_spec* pSpec, int* pOld_selection, int* pNew_selection, int pMode, int pSkip_disabled) { int i; LOG_TRACE("(%p, %p, %p, %d, %d)", pSpec, *pOld_selection, *pNew_selection, pMode, pSkip_disabled); - LOG_DEBUG("on entry: old: %p, new %p", pOld_selection, pNew_selection); + // LOG_DEBUG("on entry: old: %p, new %p", pOld_selection, pNew_selection); for (i = 0; i < gDisabled_count; i++) { if (*pNew_selection == gDisabled_choices[i]) { @@ -97,10 +97,9 @@ void ChangeSelection(tInterface_spec* pSpec, int* pOld_selection, int* pNew_sele pSpec->flicker_on_flics[*pNew_selection].y[gGraf_data_index], 0); } } - LOG_DEBUG("new: %p, old %p", pNew_selection, pOld_selection); *pOld_selection = *pNew_selection; } - LOG_DEBUG("new: %d, old %d", *pNew_selection, *pOld_selection); + LOG_DEBUG("new: %d, old %d, new mode %d", *pNew_selection, *pOld_selection, pMode); } // IDA: void __usercall RecopyAreas(tInterface_spec *pSpec@, br_pixelmap **pCopy_areas@) @@ -192,7 +191,7 @@ int DoInterfaceScreen(tInterface_spec* pSpec, int pOptions, int pCurrent_choice) StartMouseCursor(); if (pSpec->font_needed) { InitRollingLetters(); - LoadFont(0); + LoadFont(FONT_TYPEABLE); } old_current_splash = gCurrent_splash; KillSplashScreen(); @@ -410,16 +409,14 @@ int DoInterfaceScreen(tInterface_spec* pSpec, int pOptions, int pCurrent_choice) escaped = 0; } if (escaped && gTyping_slot >= 0 && !gAlways_typing) { - LOG_PANIC("not implemented"); - //pSpec->get_original_string(&pVisible_length, gTyping_slot); + pSpec->get_original_string(0, gTyping_slot, the_str, &the_max); escaped = 0; - //RevertTyping(gTyping_slot, &v106); + RevertTyping(gTyping_slot, the_str); gTyping = 0; gTyping_slot = -1; } if (go_ahead) { if (gCurrent_choice >= 0 && gCurrent_choice < pSpec->number_of_button_flics) { - //v84 = &pSpec->pushed_flics[gCurrent_choice]; if (pSpec->pushed_flics[gCurrent_choice].flic_index >= 0) { AddToFlicQueue(pSpec->pushed_flics[gCurrent_choice].flic_index, pSpec->pushed_flics[gCurrent_choice].x[gGraf_data_index], pSpec->pushed_flics[gCurrent_choice].y[gGraf_data_index], 1); } @@ -431,10 +428,9 @@ int DoInterfaceScreen(tInterface_spec* pSpec, int pOptions, int pCurrent_choice) RollLettersIn(); PDScreenBufferSwap(0); } else { - LOG_PANIC("not implemented"); gTyping_slot = gCurrent_choice; - //(pSpec->get_original_string)(&pVisible_length, gCurrent_choice); - //StartTyping(gTyping_slot, &v106, pVisible_length); + pSpec->get_original_string(1, gCurrent_choice, the_str, &the_max); + StartTyping(gTyping_slot, the_str, the_max); go_ahead = 0; gTyping = 1; } @@ -467,7 +463,7 @@ int DoInterfaceScreen(tInterface_spec* pSpec, int pOptions, int pCurrent_choice) gTyping = 0; if (pSpec->font_needed) { EndRollingLetters(); - DisposeFont(0); + DisposeFont(FONT_TYPEABLE); } if (pSpec->number_of_recopy_areas > 0) { for (i = 0; i < pSpec->number_of_recopy_areas; i++) { diff --git a/src/DETHRACE/common/loading.c b/src/DETHRACE/common/loading.c index 558a72f8..b40b4a0b 100644 --- a/src/DETHRACE/common/loading.c +++ b/src/DETHRACE/common/loading.c @@ -986,8 +986,6 @@ void LoadRaces(tRace_list_spec* pRace_list, int* pCount, int pRace_type_index) { } } - LOG_DEBUG("race count %d", number_of_racers); - *pCount = number_of_racers; fclose(f); j = 0; @@ -1656,7 +1654,7 @@ int GetCDPathFromPathsTxtFile(char* pPath_name) { int TestForOriginalCarmaCDinDrive() { LOG_TRACE("()"); - // JeffH the symbol dump didn't include any local variable information. + // JeffH: the symbol dump didn't include any local variable information. // These names are not necessarily the original names. tPath_name cd_pathname; tPath_name cd_data_pathname; @@ -1690,23 +1688,35 @@ int TestForOriginalCarmaCDinDrive() { return 0; } - strcpy(cutscene_pathname, cd_pathname); + strcpy(cutscene_pathname, cd_data_pathname); strcat(cutscene_pathname, gDir_separator); strcat(cutscene_pathname, "CUTSCENE"); - if (PDCheckDriveExists2(cd_data_pathname, "GENERAL.TXT", 100) - && (PDCheckDriveExists2(cd_pathname, "CARMA.EXE", 1000000) - || PDCheckDriveExists2(cd_pathname, "CARMAG.EXE", 1000000) - || PDCheckDriveExists2(cd_pathname, "MAINPROG.EXE", 1000000) - || PDCheckDriveExists2(cd_pathname, "CARMSPLT.EXE", 1000000) - || PDCheckDriveExists2(cd_pathname, "CARMGSPL.EXE", 1000000)) - && PDCheckDriveExists2(cutscene_pathname, "SPLINTRO.SMK", 2000000)) { - if (paths_txt_first_char != '@') { - EncodeFile(paths_txt); - } - return 1; + if (!PDCheckDriveExists2(cd_data_pathname, "GENERAL.TXT", 100)) { + return 0; } - return 0; + if (!PDCheckDriveExists2(cd_pathname, "CARMA.EXE", 1000000) + && !PDCheckDriveExists2(cd_pathname, "CARMAG.EXE", 1000000) + && !PDCheckDriveExists2(cd_pathname, "MAINPROG.EXE", 1000000) + && !PDCheckDriveExists2(cd_pathname, "CARMSPLT.EXE", 1000000) + && !PDCheckDriveExists2(cd_pathname, "CARMGSPL.EXE", 1000000)) { + return 0; + } + + if (Harness_GameMode() == eGame_mode_SplatPack) { + if (!PDCheckDriveExists2(cutscene_pathname, "SPLINTRO.SMK", 2000000)) { + return 0; + } + } else { + if (!PDCheckDriveExists2(cutscene_pathname, "MIX_INTR.SMK", 2000000)) { + return 0; + } + } + + if (paths_txt_first_char != '@') { + EncodeFile(paths_txt); + } + return 1; } // IDA: int __cdecl OriginalCarmaCDinDrive() diff --git a/src/DETHRACE/common/main.c b/src/DETHRACE/common/main.c index 69593c7e..231c3b1f 100644 --- a/src/DETHRACE/common/main.c +++ b/src/DETHRACE/common/main.c @@ -72,7 +72,6 @@ void GameMain(int pArgc, char** pArgv) { PDSetFileVariables(); PDBuildAppPath(gApplication_path); - dr_dprintf(gApplication_path); strcat(gApplication_path, "DATA"); diff --git a/src/DETHRACE/common/network.c b/src/DETHRACE/common/network.c index d3a72a8c..77891c23 100644 --- a/src/DETHRACE/common/network.c +++ b/src/DETHRACE/common/network.c @@ -1,9 +1,14 @@ #include "network.h" -#include "common/controls.h" -#include "common/netgame.h" +#include "brender.h" +#include "controls.h" +#include "displays.h" #include "globvars.h" #include "globvrpb.h" +#include "graphics.h" +#include "netgame.h" #include "pc-dos/dosnet.h" +#include "pc-dos/dossys.h" +#include "utility.h" #include tNet_game_player_info gNew_net_players[6]; @@ -456,12 +461,61 @@ void ReceivedLeave(tNet_contents* pContents, tNet_message* pMessage) { void NetFullScreenMessage(int pStr_index, int pLeave_it_up_there) { tU32 start_time; char* s; - int gPixel_buffer_size; + // JeffH: added underscore suffix to avoid collisions with samed-named globals + int gPixel_buffer_size_; + char* gPixels_copy_; + char* gPalette_copy_; int restore_screen; - char* gPixels_copy; - char* gPalette_copy; + LOG_TRACE("(%d, %d)", pStr_index, pLeave_it_up_there); - NOT_IMPLEMENTED(); + + if (pLeave_it_up_there || (gProgram_state.racing && !gInterface_within_race_mode)) { + restore_screen = 0; + } else { + gPixel_buffer_size_ = gBack_screen->height * gBack_screen->row_bytes; + gPixels_copy_ = BrMemAllocate(gPixel_buffer_size_, 0xB0u); + gPalette_copy_ = BrMemAllocate(0x400u, 0xB1u); + memcpy(gPixels_copy_, gBack_screen->pixels, gPixel_buffer_size_); + memcpy(gPalette_copy_, gCurrent_palette_pixels, 0x400u); + restore_screen = 1; + } + FadePaletteDown(); + LoadFont(FONT_MEDIUMHD); + ClearEntireScreen(); + if (pStr_index <= 0) { + s = "FIXED THAT YOU TWISTED BASTARDS"; + } else { + s = GetMiscString(pStr_index); + } + OoerrIveGotTextInMeBoxMissus( + FONT_MEDIUMHD, + s, + gBack_screen, + 0, + gGraf_specs[gGraf_spec_index].total_height / 2 - gFonts[4].height, + gGraf_specs[gGraf_spec_index].total_width, + gGraf_specs[gGraf_spec_index].total_height, + 1); + PDScreenBufferSwap(0); + EnsureRenderPalette(); + EnsurePaletteUp(); + if (!pLeave_it_up_there) { + start_time = PDGetTotalTime(); + while (PDGetTotalTime() - start_time < 3000) { + ; + } + FadePaletteDown(); + if (restore_screen) { + memcpy(gBack_screen->pixels, gPixels_copy_, gPixel_buffer_size_); + memcpy(gCurrent_palette_pixels, gPalette_copy_, 0x400u); + BrMemFree(gPixels_copy_); + BrMemFree(gPalette_copy_); + PDScreenBufferSwap(0); + FadePaletteUp(); + } else { + ClearEntireScreen(); + } + } } // IDA: void __usercall HostHasBittenTheDust(int pMessage_index@) diff --git a/src/DETHRACE/common/newgame.c b/src/DETHRACE/common/newgame.c index 28451511..48a05de5 100644 --- a/src/DETHRACE/common/newgame.c +++ b/src/DETHRACE/common/newgame.c @@ -1,4 +1,19 @@ #include "newgame.h" +#include "cutscene.h" +#include "displays.h" +#include "drmem.h" +#include "errors.h" +#include "flicplay.h" +#include "globvars.h" +#include "globvrpb.h" +#include "grafdata.h" +#include "graphics.h" +#include "init.h" +#include "input.h" +#include "intrface.h" +#include "loading.h" +#include "utility.h" +#include "world.h" #include char x[] = "xxxxxxxx.TXT"; @@ -30,50 +45,178 @@ int gRadio_selected; void StartRollingPlayerNamesIn() { int i; LOG_TRACE("()"); - NOT_IMPLEMENTED(); + + for (i = 0; i < 2; i++) { + SetSlotXY(i, gCurrent_graf_data->player_name_x[i], gCurrent_graf_data->player_name_y); + AddRollingString(gProgram_state.player_name[i], gCurrent_graf_data->player_name_x[i], gCurrent_graf_data->player_name_y, eRT_alpha); + } } // IDA: void __cdecl FrankAnneStart1() void FrankAnneStart1() { LOG_TRACE("()"); - NOT_IMPLEMENTED(); + StartRollingPlayerNamesIn(); + if (!gFrank_flic_data) { + if (!LoadFlicData("FRANK.FLI", &gFrank_flic_data, &gFrank_flic_data_length)) { + FatalError(56); + } + } + if (!gAnne_flic_data) { + if (!LoadFlicData("ANNIE.FLI", &gAnne_flic_data, &gAnne_flic_data_length)) { + FatalError(56); + } + } + InitialiseFlicPanel(0, + gCurrent_graf_data->frank_panel_left, + gCurrent_graf_data->frank_panel_top, + gCurrent_graf_data->frank_panel_right - gCurrent_graf_data->frank_panel_left, + gCurrent_graf_data->frank_panel_bottom - gCurrent_graf_data->frank_panel_top); + InitialiseFlicPanel(1, + gCurrent_graf_data->anne_panel_left, + gCurrent_graf_data->anne_panel_top, + gCurrent_graf_data->anne_panel_right - gCurrent_graf_data->anne_panel_left, + gCurrent_graf_data->anne_panel_bottom - gCurrent_graf_data->anne_panel_top); } // IDA: void __cdecl FrankAnneStart2() void FrankAnneStart2() { LOG_TRACE("()"); - NOT_IMPLEMENTED(); + ChangePanelFlic(0, gFrank_flic_data, gFrank_flic_data_length); + ChangePanelFlic(1, gAnne_flic_data, gAnne_flic_data_length); + TellyInImage(GetPanelPixelmap(0), gCurrent_graf_data->frank_panel_left, gCurrent_graf_data->frank_panel_top); + TellyInImage(GetPanelPixelmap(1), gCurrent_graf_data->anne_panel_left, gCurrent_graf_data->anne_panel_top); } // IDA: void __usercall GetPlayerName(int pStarting_to_type@, int pCurrent_choice@, char *pString@, int *pMax_length@) void GetPlayerName(int pStarting_to_type, int pCurrent_choice, char* pString, int* pMax_length) { LOG_TRACE("(%d, %d, \"%s\", %p)", pStarting_to_type, pCurrent_choice, pString, pMax_length); - NOT_IMPLEMENTED(); + strcpy(pString, gProgram_state.player_name[pCurrent_choice]); + *pMax_length = PLAYER_NAME_MAX_LENGTH; } // IDA: int __usercall FrankAnneDone@(int pCurrent_choice@, int pCurrent_mode@, int pGo_ahead@, int pEscaped@, int pTimed_out) int FrankAnneDone(int pCurrent_choice, int pCurrent_mode, int pGo_ahead, int pEscaped, int pTimed_out) { LOG_TRACE("(%d, %d, %d, %d, %d)", pCurrent_choice, pCurrent_mode, pGo_ahead, pEscaped, pTimed_out); - NOT_IMPLEMENTED(); + RemoveTransientBitmaps(1); + TellyOutImage(GetPanelPixelmap(1), gCurrent_graf_data->anne_panel_left, gCurrent_graf_data->anne_panel_top); + TellyOutImage(GetPanelPixelmap(0), gCurrent_graf_data->frank_panel_left, gCurrent_graf_data->frank_panel_top); + if (gFrank_flic_data) { + MAMSUnlock((void**)&gFrank_flic_data); + } + if (gAnne_flic_data) { + MAMSUnlock((void**)&gAnne_flic_data); + } + gProgram_state.frank_or_anniness = pCurrent_choice; + GetTypedName(gProgram_state.player_name[pCurrent_choice], PLAYER_NAME_MAX_LENGTH); + return pCurrent_choice; } // IDA: void __usercall FrankAnneDraw(int pCurrent_choice@, int pCurrent_mode@) void FrankAnneDraw(int pCurrent_choice, int pCurrent_mode) { - LOG_TRACE("(%d, %d)", pCurrent_choice, pCurrent_mode); - NOT_IMPLEMENTED(); + LOG_TRACE9("(%d, %d)", pCurrent_choice, pCurrent_mode); + if (gTyping) { + if (GetTotalTime() & 0x100) { + if (pCurrent_choice < 2) { + TransDRPixelmapText( + gBack_screen, + gCurrent_graf_data->enter_name_x[pCurrent_choice], + gCurrent_graf_data->enter_name_y, + &gFonts[FONT_GRNLIT], + GetMiscString(191), + gBack_screen->width); + } + } + } } // IDA: int __cdecl FrankieOrAnnie() int FrankieOrAnnie() { - static tFlicette flicker_on[3]; - static tFlicette flicker_off[3]; - static tFlicette push[3]; - static tMouse_area mouse_areas[3]; - static tRectile recopy_areas[2]; - static tInterface_spec interface_spec; + static tFlicette flicker_on[3] = { + { 83, { 61, 122 }, { 52, 125 } }, + { 83, { 184, 398 }, { 52, 125 } }, + { 43, { 215, 430 }, { 158, 379 } } + }; + static tFlicette flicker_off[3] = { + { 82, { 61, 122 }, { 52, 125 } }, + { 82, { 184, 398 }, { 52, 125 } }, + { 42, { 215, 430 }, { 158, 379 } } + }; + static tFlicette push[3] = { + { 83, { 61, 122 }, { 52, 125 } }, + { 83, { 184, 398 }, { 52, 125 } }, + { 45, { 215, 430 }, { 158, 379 } } + }; + static tMouse_area mouse_areas[3] = { + { { 55, 110 }, { 52, 125 }, { 161, 322 }, { 154, 370 }, 0, 0, 0, NULL }, + { { 178, 356 }, { 52, 125 }, { 295, 596 }, { 154, 370 }, 1, 0, 0, NULL }, + { { 215, 430 }, { 158, 379 }, { 278, 556 }, { 179, 430 }, 2, 1, 1, NULL } + }; + static tRectile recopy_areas[2] = { + { { 55, 110 }, { 132, 317 }, { 161, 322 }, { 154, 370 } }, + { { 178, 356 }, { 132, 317 }, { 295, 590 }, { 154, 370 } } + }; + static tInterface_spec interface_spec = { + 0, // initial_imode + 80, // first_opening_flic + 0, // second_opening_flic + 81, // end_flic_go_ahead + 81, // end_flic_escaped + 81, // end_flic_otherwise + 0, // flic_bunch_to_load + { -1, -1 }, // move_left_new_mode + { -1, 0 }, // move_left_delta + { 0, 2 }, // move_left_min + { 1, 2 }, // move_left_max + { NULL, NULL }, // move_left_proc + { -1, -1 }, // move_right_new_mode + { 1, 0 }, // move_right_delta + { 0, 2 }, // move_right_min + { 1, 2 }, // move_right_max + { NULL, NULL }, // move_right_proc + { 1, 0 }, // move_up_new_mode + { -2, -1 }, // move_up_delta + { 2, 1 }, // move_up_min + { 2, 1 }, // move_up_max + { NULL, NULL }, // move_up_proc + { 1, 0 }, // move_down_new_mode + { 2, -1 }, // move_down_delta + { 2, 1 }, // move_down_min + { 2, 1 }, // move_down_max + { NULL, NULL }, // move_down_proc + { 1, 1 }, // go_ahead_allowed + { NULL, NULL }, // go_ahead_proc + { 1, 1 }, // escape_allowed + { NULL, NULL }, // escape_proc + NULL, // exit_proc + FrankAnneDraw, // draw_proc + 0, // time_out + FrankAnneStart1, // start_proc1 + FrankAnneStart2, // start_proc2 + FrankAnneDone, // done_proc + 1, // font_needed + { 1, 0 }, // typeable + GetPlayerName, // get_original_string + 2, // escape_code + 1, // dont_save_or_load + 3, // number_of_button_flics + flicker_on, // flicker_on_flics + flicker_off, // flicker_off_flics + push, // pushed_flics + 3, // number_of_mouse_areas + mouse_areas, // mouse_areas + 2, // number_of_recopy_areas + recopy_areas // recopy_areas + }; + int result; LOG_TRACE("()"); - NOT_IMPLEMENTED(); + + LoadFont(FONT_GRNLIT); + result = DoInterfaceScreen(&interface_spec, 0, gProgram_state.frank_or_anniness); + DisposeFlicPanel(1); + DisposeFlicPanel(0); + DisposeFont(FONT_GRNLIT); + return result < 2; } // IDA: int __cdecl SelectSkillLevel() @@ -93,7 +236,42 @@ int DoOnePlayerStart() { int merrily_looping; tProgram_state saved_state; LOG_TRACE("()"); - NOT_IMPLEMENTED(); + + if (OriginalCarmaCDinDrive()) { + memcpy(&saved_state, &gProgram_state, sizeof(tProgram_state)); + do { + merrily_looping = FrankieOrAnnie(); + if (!merrily_looping) { + memcpy(&gProgram_state, &saved_state, sizeof(tProgram_state)); + return 0; + } + if (SelectSkillLevel()) { + DoGoToRaceAnimation(); + StartLoadingScreen(); + AboutToLoadFirstCar(); + PrintMemoryDump(0, "JUST BEFORE LOADING YOUR CAR"); + SwitchToRealResolution(); + LoadCar( + gBasic_car_names[gProgram_state.frank_or_anniness], + eDriver_local_human, + &gProgram_state.current_car, + gProgram_state.frank_or_anniness, + gProgram_state.player_name[gProgram_state.frank_or_anniness], + &gOur_car_storage_space); + SwitchToLoresMode(); + SetCarStorageTexturingLevel(&gOur_car_storage_space, GetCarTexturingLevel(), eCTL_full); + PrintMemoryDump(0, "IMMEDIATELY AFTER LOADING YOUR CAR"); + gNet_mode = 0; + InitGame(0); + merrily_looping = 0; + } + } while (merrily_looping); + UnlockBunchOfFlics(4); + return 1; + } else { + DoErrorInterface(223); + return 0; + } } // IDA: int __usercall NewNetGameUp@(int *pCurrent_choice@, int *pCurrent_mode@) diff --git a/src/DETHRACE/common/utility.c b/src/DETHRACE/common/utility.c index 8d968a89..9ede1c4e 100644 --- a/src/DETHRACE/common/utility.c +++ b/src/DETHRACE/common/utility.c @@ -6,6 +6,7 @@ #include "dossys.h" #include "errors.h" #include "globvars.h" +#include "globvrpb.h" #include "input.h" #include "loading.h" #include "loadsave.h" @@ -522,8 +523,14 @@ void PrintScreen() { // IDA: tU32 __cdecl GetTotalTime() tU32 GetTotalTime() { - LOG_TRACE("()"); - NOT_IMPLEMENTED(); + LOG_TRACE9("()"); + if (gAction_replay_mode) { + return gLast_replay_frame_time; + } + if (gNet_mode) { + return PDGetTotalTime(); + } + return PDGetTotalTime() - gLost_time; } // IDA: tU32 __cdecl GetRaceTime() diff --git a/src/DETHRACE/constants.h b/src/DETHRACE/constants.h index a40e8687..aa905a2f 100644 --- a/src/DETHRACE/constants.h +++ b/src/DETHRACE/constants.h @@ -243,4 +243,30 @@ typedef enum keymapcodes { KEYMAP_F3 = 29, } keymapcodes; +#define FONT_TYPEABLE 0 +#define FONT_ORANGHED 1 +#define FONT_BLUEHEAD 2 +#define FONT_GREENHED 3 +#define FONT_MEDIUMHD 4 +#define FONT_TIMER 5 +#define FONT_NEWHITE 6 +#define FONT_NEWRED 7 +#define FONT_NEWBIGGR 8 +#define FONT_GRNDK 9 +#define FONT_GRNLIT 10 +#define FONT_GRYDK 11 +#define FONT_GRYLIT 12 +#define FONT_BUTTIN 13 +#define FONT_BUTTOUT 14 +#define FONT_LITPLAQ 15 +#define FONT_DRKPLAQ 16 +#define FONT_BUTTIN1 17 +#define FONT_BUTTOUT1 18 +#define FONT_LITPLAQ1 19 +#define FONT_DRKPLAQ1 20 + +#define ROLLING_LETTER_LOOP_RANDOM 96 + +#define PLAYER_NAME_MAX_LENGTH 13 + #endif \ No newline at end of file diff --git a/src/DETHRACE/pc-dos/dossys.c b/src/DETHRACE/pc-dos/dossys.c index 04fe768f..3ea742eb 100644 --- a/src/DETHRACE/pc-dos/dossys.c +++ b/src/DETHRACE/pc-dos/dossys.c @@ -10,6 +10,7 @@ #include "common/sound.h" #include "common/utility.h" #include "harness.h" +#include "input.h" #include "watcom_functions.h" #include #include @@ -232,7 +233,12 @@ void PDSetKeyArray(int* pKeys, int pMark) { // IDA: int __usercall PDGetASCIIFromKey@(int pKey@) int PDGetASCIIFromKey(int pKey) { LOG_TRACE("(%d)", pKey); - NOT_IMPLEMENTED(); + + if (PDKeyDown3(KEY_LSHIFT)) { + return gASCII_shift_table[pKey]; + } else { + return gASCII_table[pKey]; + } } // IDA: void __usercall PDFatalError(char *pThe_str@) @@ -807,7 +813,8 @@ int PDGetJoy2Button4() { int PDFileUnlock(char* pThe_path) { unsigned int attr; LOG_TRACE("(\"%s\")", pThe_path); - NOT_IMPLEMENTED(); + // _dos_setfileattr_(pThe_path, 0); + return 0; } // IDA: void __cdecl CriticalISR(INTPACK pRegs) @@ -823,7 +830,7 @@ int PDCheckDriveExists2(char* pThe_path, char* pFile_name, tU32 pMin_size) { int stat_failed; char slasher[4]; char the_path[256]; - LOG_TRACE9("(\"%s\", \"%s\", %d)", pThe_path, pFile_name, pMin_size); + LOG_TRACE("(\"%s\", \"%s\", %d)", pThe_path, pFile_name, pMin_size); strcpy(slasher, "?:\\"); if (pFile_name) { diff --git a/src/harness/debug.h b/src/harness/debug.h index d8404a77..1bb22595 100644 --- a/src/harness/debug.h +++ b/src/harness/debug.h @@ -2,6 +2,7 @@ #define DEBUG_H #include +#include #define BLUE #define LOG_LEVEL 3 @@ -31,6 +32,7 @@ #define NOT_IMPLEMENTED() \ debug_printf("\033[0;31m[PANIC] %s ", __FUNCTION__, "%s", "not implemented"); \ + sleep(2); \ exit(1); #define STUB() \ diff --git a/src/harness/harness.c b/src/harness/harness.c index bc693a29..d7f1b854 100644 --- a/src/harness/harness.c +++ b/src/harness/harness.c @@ -8,6 +8,7 @@ SDL_Thread* game_thread; renderer* current_renderer; br_pixelmap* palette; uint32_t* screen_buffer; +eGame_mode game_mode; br_pixelmap* last_dst = NULL; br_pixelmap* last_src = NULL; @@ -16,6 +17,11 @@ void Harness_Init(char* name, renderer* renderer) { install_signal_handler(name); current_renderer = renderer; screen_buffer = NULL; + game_mode = eGame_mode_Carmageddon; +} + +eGame_mode Harness_GameMode() { + return game_mode; } void Harness_RunWindowLoop(harness_game_func* game_func, void* arg) { diff --git a/src/harness/harness.h b/src/harness/harness.h index 4713d1b7..b6c8e041 100644 --- a/src/harness/harness.h +++ b/src/harness/harness.h @@ -14,9 +14,16 @@ typedef struct renderer { void (*doubleBuffer)(uint32_t* src, SDL_Window* window); } renderer; +typedef enum eGame_mode { + eGame_mode_Carmageddon, + eGame_mode_SplatPack +} eGame_mode; + void Harness_Init(char* name, renderer* renderer); void Harness_RunWindowLoop(harness_game_func* game_func, void* arg); +eGame_mode Harness_GameMode(); + // Hooks are called from original game code. void Harness_Hook_DOSGfxBegin(); void Harness_Hook_BrDevPaletteSetOld(br_pixelmap* pm); diff --git a/src/harness/renderers/gl_renderer.c b/src/harness/renderers/gl_renderer.c index 56aa963d..5aeb6127 100644 --- a/src/harness/renderers/gl_renderer.c +++ b/src/harness/renderers/gl_renderer.c @@ -19,7 +19,7 @@ renderer OpenGLRenderer = { Harness_GLRenderer_DoubleBuffer, }; -SDL_GLContext context; +SDL_GLContext context, context2; GLuint VBO, VAO, EBO; GLuint screen_texture; GLuint shader_program; @@ -28,6 +28,8 @@ int Harness_GLRenderer_GetWindowFlags() { if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE) != 0) { LOG_PANIC("Failed to set SDL_GL_CONTEXT_PROFILE_MASK attribute. %s", SDL_GetError()); }; + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); return SDL_WINDOW_OPENGL; } @@ -37,6 +39,10 @@ void Harness_GLRenderer_Init(SDL_Window* window) { if (!context) { LOG_PANIC("Failed to call SDL_GL_CreateContext. %s", SDL_GetError()); } + context2 = SDL_GL_CreateContext(window); + if (!context2) { + LOG_PANIC("Failed to call SDL_GL_CreateContext (2). %s", SDL_GetError()); + } } void CompileShader(GLuint shader_id, const GLchar* source) { diff --git a/test/DETHRACE/test_utility.c b/test/DETHRACE/test_utility.c index 5128dcc6..1d80f046 100644 --- a/test/DETHRACE/test_utility.c +++ b/test/DETHRACE/test_utility.c @@ -89,9 +89,10 @@ void test_utility_getMiscString() { } void test_utility_IRandomBetween() { - IRandomBetween(1, 5); - IRandomBetween(0, 5); - IRandomBetween(50, 100); + tU32 source_y_delta; + + source_y_delta = ((66 << 16) / 67) - 0x10000; + printf("delta %x, %x\n", source_y_delta, source_y_delta >> 16); } void test_utility_suite() {