Start To Mouse (#109)

* Detour fopen to an OS-specific implementation of fopen

* Set opponent count to 5

* Implement switching opponents in 'View opponent' sub-panel
This commit is contained in:
Anonymous Maarten 2022-03-25 00:36:11 +01:00 committed by GitHub
parent 21f3ef3631
commit 80f5fceff9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 585 additions and 174 deletions

View File

@ -43,24 +43,6 @@ void* BrFileOpenRead(char* name, br_size_t n_magics, br_mode_test_cbfn* mode_tes
raw_file = fw.fsys->open_read(name, n_magics, mode_test, &bin_mode);
}
#ifdef BRENDER_FIX_BUGS
// Try all-uppercase filename for case sensitive file systems
if (raw_file == NULL) {
for (s = name + strlen(name); s != name;) {
s--;
if (*s == '\\' || *s == '/') {
break;
}
*s = toupper(*s);
}
if (mode_result != NULL) {
raw_file = fw.fsys->open_read(name, n_magics, mode_test, mode_result);
} else {
raw_file = fw.fsys->open_read(name, n_magics, mode_test, &bin_mode);
}
}
#endif
if (raw_file == NULL) {
return NULL;
}

View File

@ -1,6 +1,7 @@
#include "brstdfile.h"
#include "CORE/FW/diag.h"
#include "harness/hooks.h"
#include "harness/trace.h"
#include <stdio.h>
#include <string.h>
@ -73,9 +74,9 @@ void* BrStdioOpenWrite(char* name, int mode) {
FILE* fh;
if (mode == BR_FS_MODE_TEXT) {
fh = fopen(name, "w");
fh = Harness_Hook_fopen(name, "w");
} else {
fh = fopen(name, "wb");
fh = Harness_Hook_fopen(name, "wb");
}
return fh;

View File

@ -276,8 +276,8 @@ void DoDepthByShadeTable(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer
if (depth_shift_amount <= 0) {
if (depth_shift_amount >= 0) {
for (y = 0; pRender_buffer->height > y; ++y) {
for (x = 0; pRender_buffer->width > x; ++x) {
for (y = 0; y < pRender_buffer->height; ++y) {
for (x = 0; x < pRender_buffer->width; ++x) {
if (*depth_ptr != 0xFFFF) {
depth_value = *depth_ptr - too_near;
if (depth_value < -(int16_t)too_near) {
@ -477,8 +477,8 @@ void DepthEffect(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_act
void DepthEffectSky(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world) {
LOG_TRACE("(%p, %p, %p, %p)", pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);
if (gProgram_state.current_depth_effect.sky_texture
&& (!gLast_camera_special_volume || gLast_camera_special_volume->sky_col < 0)) {
if (gProgram_state.current_depth_effect.sky_texture != NULL
&& (gLast_camera_special_volume == NULL || gLast_camera_special_volume->sky_col < 0)) {
DoHorizon(pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);
}
}

View File

@ -673,7 +673,7 @@ int StartFlic(char* pFile_name, int pIndex, tFlic_descriptor_ptr pFlic_info, tU3
PathCat(the_path, the_path, pFile_name);
pFlic_info->f = DRfopen(the_path, "rb");
if (!pFlic_info->f) {
if (pFlic_info->f == NULL) {
FatalError(13, pFile_name);
}
total_size = GetFileLength(pFlic_info->f);
@ -1408,7 +1408,7 @@ int LoadFlicData(char* pName, tU8** pData, tU32* pData_length) {
PathCat(the_path, gApplication_path, "ANIM");
PathCat(the_path, the_path, pName);
f = DRfopen(the_path, "rb");
if (!f) {
if (f == NULL) {
return 0;
}
*pData_length = GetFileLength(f);
@ -1490,12 +1490,9 @@ void PreloadBunchOfFlics(int pBunch_index) {
// IDA: void __usercall UnlockBunchOfFlics(int pBunch_index@<EAX>)
void UnlockBunchOfFlics(int pBunch_index) {
int i;
for (i = 0; i < gFlic_bunch[pBunch_index].count; i++) {
if (gFlic_bunch[pBunch_index].indexes[i] >= 0) {
if (gMain_flic_list[gFlic_bunch[pBunch_index].indexes[i]].data_ptr) {
MAMSUnlock((void**)&gMain_flic_list[gFlic_bunch[pBunch_index].indexes[i]].data_ptr);
}
}
UnlockFlic(gFlic_bunch[pBunch_index].indexes[i]);
}
}
@ -1503,7 +1500,10 @@ void UnlockBunchOfFlics(int pBunch_index) {
void FlushAllFlics(int pBunch_index) {
int i;
LOG_TRACE("(%d)", pBunch_index);
NOT_IMPLEMENTED();
for (i = 0; i < COUNT_OF(gMain_flic_list); i++) {
FreeFlic(i);
}
}
// IDA: void __cdecl InitFlicQueue()
@ -1517,7 +1517,7 @@ int FlicQueueFinished() {
LOG_TRACE("()");
the_flic = gFirst_flic;
while (the_flic) {
while (the_flic != NULL) {
if (the_flic->must_finish) {
return 0;
}
@ -1540,7 +1540,7 @@ void ProcessFlicQueue(tU32 pInterval) {
the_flic = gFirst_flic;
last_flic = NULL;
new_time = PDGetTotalTime();
while (the_flic) {
while (the_flic != NULL) {
if (new_time - the_flic->last_frame < the_flic->frame_period) {
finished_playing = 0;
} else {
@ -1549,7 +1549,7 @@ void ProcessFlicQueue(tU32 pInterval) {
}
if (finished_playing) {
EndFlic(the_flic);
if (last_flic) {
if (last_flic != NULL) {
last_flic->next = the_flic->next;
} else {
gFirst_flic = the_flic->next;
@ -1583,7 +1583,7 @@ void FlushFlicQueue() {
PDScreenBufferSwap(0);
}
the_flic = gFirst_flic;
while (the_flic) {
while (the_flic != NULL) {
old_flic = the_flic;
EndFlic(the_flic);
the_flic = the_flic->next;
@ -1601,7 +1601,7 @@ void AddToFlicQueue(int pIndex, int pX, int pY, int pMust_finish) {
LOG_TRACE("(%d, %d, %d, %d)", pIndex, pX, pY, pMust_finish);
the_flic = gFirst_flic;
while (the_flic) {
while (the_flic != NULL) {
if (pX == the_flic->x_offset && pY == the_flic->y_offset) {
doomed_flic = the_flic;
break;
@ -1610,9 +1610,9 @@ void AddToFlicQueue(int pIndex, int pX, int pY, int pMust_finish) {
the_flic = the_flic->next;
}
if (doomed_flic) {
if (doomed_flic != NULL) {
EndFlic(doomed_flic);
if (last_flic) {
if (last_flic != NULL) {
last_flic->next = doomed_flic->next;
} else {
gFirst_flic = doomed_flic->next;
@ -1624,8 +1624,8 @@ void AddToFlicQueue(int pIndex, int pX, int pY, int pMust_finish) {
new_flic = BrMemAllocate(sizeof(tFlic_descriptor), kMem_queued_flic);
new_flic->next = NULL;
the_flic = gFirst_flic;
if (gFirst_flic) {
while (the_flic->next) {
if (gFirst_flic != NULL) {
while (the_flic->next != NULL) {
the_flic = the_flic->next;
}
the_flic->next = new_flic;
@ -1633,7 +1633,7 @@ void AddToFlicQueue(int pIndex, int pX, int pY, int pMust_finish) {
gFirst_flic = new_flic;
}
new_flic->last_frame = 0;
new_flic->data_start = 0;
new_flic->data_start = NULL;
new_flic->the_index = pIndex;
new_flic->must_finish = pMust_finish;
@ -1657,7 +1657,7 @@ void InitialiseFlicPanel(int pIndex, int pLeft, int pTop, int pWidth, int pHeigh
gPanel_flic[pIndex].data = NULL;
gPanel_flic_left[pIndex] = pLeft;
gPanel_flic_top[pIndex] = pTop;
the_pixels = BrMemAllocate(pHeight * ((pWidth + 3) & 0xFC), kFlic_panel_pixels);
the_pixels = BrMemAllocate(pHeight * ((pWidth + 3) & ~3), kFlic_panel_pixels);
if (gScreen->row_bytes < 0) {
BrFatal(
"..\\..\\source\\common\\flicplay.c",
@ -1695,10 +1695,10 @@ void ServicePanelFlics(int pCopy_to_buffer) {
DontLetFlicFuckWithPalettes();
TurnFlicTransparencyOn();
for (i = 0; i < 2; i++) {
for (i = 0; i < COUNT_OF(gPanel_flic); i++) {
old_last_time[i] = gLast_panel_frame_time[i];
if (gPanel_buffer[i] && gPanel_flic[i].data) {
if (old_last_time[i]) {
if (gPanel_buffer[i] != NULL && gPanel_flic[i].data != NULL) {
if (old_last_time[i] != 0) {
time_diff = the_time - old_last_time[i];
iteration_count = time_diff / gPanel_flic[i].frame_period;
} else {
@ -1734,8 +1734,8 @@ void ServicePanelFlics(int pCopy_to_buffer) {
}
}
}
gTransparency_on = 0;
gPalette_fuck_prevention = 0;
TurnFlicTransparencyOff();
LetFlicFuckWithPalettes();
}
// IDA: void __usercall ChangePanelFlic(int pIndex@<EAX>, tU8 *pData@<EDX>, tU32 pData_length@<EBX>)

View File

@ -12,9 +12,10 @@
#include "globvars.h"
#include "globvrpb.h"
#include "grafdata.h"
#include "harness/hooks.h"
#include "harness/os.h"
#include "harness/trace.h"
#include "init.h"
#include "input.h"
#include "loading.h"
#include "netgame.h"
#include "network.h"
@ -38,15 +39,20 @@
int gPalette_munged;
int gColourValues[1];
int gNext_transient;
int gCursor_x_offsets[8];
int gCursor_y_offsets[8];
int gCursor_gib_x_offsets[8];
int gCursor_gib_y_offsets[8];
int gCursor_giblet_sequence0[7];
int gCursor_giblet_sequence1[5];
int gCursor_giblet_sequence2[5];
int gCursor_giblet_sequence3[5];
int* gCursor_giblet_sequences[4];
int gCursor_x_offsets[8] = { 6, 8, 16, 36, 6, 8, 16, 36, };
int gCursor_y_offsets[8] = { 26, 19, 12, 5, 26, 19, 12, 5, };
int gCursor_gib_x_offsets[8] = { 82, 72, 66, 36, 82, 72, 66, 36, };
int gCursor_gib_y_offsets[8] = { 74, 86, 93, 106, 74, 86, 93, 106, };
int gCursor_giblet_sequence0[7] = { 6, 0, 1, 2, 3, 4, 5, };
int gCursor_giblet_sequence1[5] = { 4, 6, 7, 8, 9, };
int gCursor_giblet_sequence2[5] = { 4, 10, 11, 12, 13, };
int gCursor_giblet_sequence3[5] = { 4, 14, 15, 16, 17, };
int* gCursor_giblet_sequences[4] = {
gCursor_giblet_sequence0,
gCursor_giblet_sequence1,
gCursor_giblet_sequence2,
gCursor_giblet_sequence3,
};
char* gFont_names[21] = {
"TYPEABLE",
"ORANGHED",
@ -1242,7 +1248,7 @@ void ProcessShadow(tCar_spec* pCar, br_actor* pWorld, tTrack_spec* pTrack_spec,
material = gShadow_model->faces[i].material;
if (material) {
if (material->colour_map && (material->flags & BR_MATF_LIGHT) != 0) {
material->flags &= 0xFFFFFFF8;
material->flags &= ~(BR_MATF_LIGHT |BR_MATF_PRELIT | BR_MATF_SMOOTH);
BrMaterialUpdate(material, BR_MATU_RENDERING);
}
}
@ -1950,43 +1956,57 @@ void DRPixelmapRectangleMaskedCopy(br_pixelmap* pDest, br_int_16 pDest_x, br_int
dest_ptr -= pDest_y * pDest->row_bytes;
pDest_y = 0;
}
if (pDest->height > pDest_y) {
if (pDest_y + pHeight > pDest->height) {
pHeight = pDest->height - pDest_y;
if (pDest_y >= pDest->height) {
return;
}
if (pDest_y + pHeight > pDest->height) {
pHeight = pDest->height - pDest_y;
}
if (pDest_x < 0) {
pWidth += pDest_x;
if (pWidth <= 0) {
return;
}
if (pDest_x < 0) {
pWidth += pDest_x;
if (pWidth <= 0) {
return;
}
source_ptr -= pDest_x;
dest_ptr -= pDest_x;
source_row_wrap -= pDest_x;
dest_row_wrap -= pDest_x;
pDest_x = 0;
}
if (pDest->width > pDest_x) {
if (pDest_x + pWidth > pDest->width) {
pWidth = pDest->width - pDest_x;
source_row_wrap += pDest_x + pWidth - pDest->width;
dest_row_wrap += pDest_x + pWidth - pDest->width;
}
if (gCurrent_conversion_table) {
TELL_ME_IF_WE_PASS_THIS_WAY();
} else {
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++;
}
source_ptr += source_row_wrap;
dest_ptr += dest_row_wrap;
source_ptr -= pDest_x;
dest_ptr -= pDest_x;
source_row_wrap -= pDest_x;
dest_row_wrap -= pDest_x;
pDest_x = 0;
}
if (pDest_x >= pDest->width) {
return;
}
if (pDest_x + pWidth > pDest->width) {
source_row_wrap += pDest_x + pWidth - pDest->width;
dest_row_wrap += pDest_x + pWidth - pDest->width;
pWidth = pDest->width - pDest_x;
}
if (gCurrent_conversion_table != NULL) {
conv_table = gCurrent_conversion_table->pixels;
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 != 0) {
*dest_ptr = conv_table[the_byte];
}
source_ptr++;
dest_ptr++;
}
source_ptr += source_row_wrap;
dest_ptr += dest_row_wrap;
}
} else {
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 != 0) {
*dest_ptr = the_byte;
}
source_ptr++;
dest_ptr++;
}
source_ptr += source_row_wrap;
dest_ptr += dest_row_wrap;
}
}
}
@ -2166,7 +2186,8 @@ void DRPixelmapRectangleVScaledCopy(br_pixelmap* pDest, br_int_16 pDest_x, br_in
void InitTransientBitmaps() {
int i;
LOG_TRACE("()");
for (i = 0; i < 50; i++) {
for (i = 0; i < COUNT_OF(gTransient_bitmaps); i++) {
gTransient_bitmaps[i].pixmap = NULL;
gTransient_bitmaps[i].in_use = 0;
}
@ -2176,40 +2197,100 @@ void InitTransientBitmaps() {
int AllocateTransientBitmap(int pWidth, int pHeight, int pUser_data) {
int bm_index;
LOG_TRACE("(%d, %d, %d)", pWidth, pHeight, pUser_data);
NOT_IMPLEMENTED();
for (bm_index = 0; bm_index < COUNT_OF(gTransient_bitmaps); bm_index++) {
if (gTransient_bitmaps[bm_index].pixmap == NULL) {
gTransient_bitmaps[bm_index].pixmap = DRPixelmapAllocate(BR_PMT_INDEX_8, pWidth + 8, pHeight, NULL, 0);
gTransient_bitmaps[bm_index].in_use = 0;
gTransient_bitmaps[bm_index].user_data = pUser_data;
return bm_index;
}
}
FatalError(18);
}
// IDA: void __usercall DeallocateTransientBitmap(int pIndex@<EAX>)
void DeallocateTransientBitmap(int pIndex) {
LOG_TRACE("(%d)", pIndex);
NOT_IMPLEMENTED();
if (gTransient_bitmaps[pIndex].pixmap != NULL) {
BrPixelmapFree(gTransient_bitmaps[pIndex].pixmap);
gTransient_bitmaps[pIndex].pixmap = NULL;
gTransient_bitmaps[pIndex].in_use = 0;
}
}
// IDA: void __cdecl DeallocateAllTransientBitmaps()
void DeallocateAllTransientBitmaps() {
int i;
LOG_TRACE("()");
NOT_IMPLEMENTED();
for (i = 0; i < COUNT_OF(gTransient_bitmaps); i++) {
DeallocateTransientBitmap(i);
}
}
// IDA: void __usercall RemoveTransientBitmaps(int pGraphically_remove_them@<EAX>)
void RemoveTransientBitmaps(int pGraphically_remove_them) {
int i;
int order_number;
STUB_ONCE();
if (pGraphically_remove_them) {
for (order_number = gNext_transient - 1; order_number >= 0; order_number--) {
for (i = 0; i < COUNT_OF(gTransient_bitmaps); i++) {
if (gTransient_bitmaps[i].pixmap != NULL && gTransient_bitmaps[i].order_number == order_number) {
if (gTransient_bitmaps[i].in_use) {
BrPixelmapRectangleCopy(gBack_screen,
gTransient_bitmaps[i].x_coord,
gTransient_bitmaps[i].y_coord,
gTransient_bitmaps[i].pixmap,
0,
0,
gTransient_bitmaps[i].pixmap->width,
gTransient_bitmaps[i].pixmap->height);
}
break;
}
}
}
}
gNext_transient = 0;
}
// IDA: void __usercall SaveTransient(int pIndex@<EAX>, int pX_coord@<EDX>, int pY_coord@<EBX>)
void SaveTransient(int pIndex, int pX_coord, int pY_coord) {
LOG_TRACE("(%d, %d, %d)", pIndex, pX_coord, pY_coord);
NOT_IMPLEMENTED();
gTransient_bitmaps[pIndex].x_coord = pX_coord & ~3;
gTransient_bitmaps[pIndex].y_coord = pY_coord;
gTransient_bitmaps[pIndex].in_use = 1;
gTransient_bitmaps[pIndex].order_number = gNext_transient;
gNext_transient++;
BrPixelmapRectangleCopy(gTransient_bitmaps[pIndex].pixmap,
0,
0,
gBack_screen,
gTransient_bitmaps[pIndex].x_coord,
gTransient_bitmaps[pIndex].y_coord,
gTransient_bitmaps[pIndex].pixmap->width,
gTransient_bitmaps[pIndex].pixmap->height);
}
// IDA: void __usercall DrawCursorGiblet(tCursor_giblet *pGib@<EAX>)
void DrawCursorGiblet(tCursor_giblet* pGib) {
br_pixelmap* the_image;
LOG_TRACE("(%p)", pGib);
NOT_IMPLEMENTED();
SaveTransient(pGib->transient_index, pGib->x_coord, pGib->y_coord);
the_image = gCursor_giblet_images[gCursor_giblet_sequences[pGib->sequence_index][pGib->current_giblet]];
DRPixelmapRectangleMaskedCopy(gBack_screen,
pGib->x_coord,
pGib->y_coord,
the_image,
0,
0,
the_image->width,
the_image->height);
}
// IDA: void __usercall ProcessCursorGiblets(int pPeriod@<EAX>)
@ -2219,7 +2300,57 @@ void ProcessCursorGiblets(int pPeriod) {
tU32 time_now;
tCursor_giblet* gib;
LOG_TRACE("(%d)", pPeriod);
NOT_IMPLEMENTED();
time_now = PDGetTotalTime();
for (i = 0; i < COUNT_OF(gCursor_giblets); i++) {
gib = &gCursor_giblets[i];
kill_the_giblet = 0;
if (gib->current_giblet == -1) {
continue;
}
if (!gib->landed && gib->e_t_a <= time_now) {
gib->landed = 1;
gib->the_speed = 0.f;
}
if (gib->landed) {
gib->giblet_change_period -= pPeriod / 2;
if (gib->giblet_change_period < 50) {
gib->giblet_change_period = 50;
}
if (gib->giblet_change_period <= time_now - gib->last_giblet_change) {
if (gCursor_giblet_sequences[gib->sequence_index][0] == gib->current_giblet) {
gib->current_giblet = 1;
} else {
gib->current_giblet++;
}
gib->last_giblet_change = time_now;
}
gib->y_coord += pPeriod * gib->the_speed / 1000.f;
if (gib->y_coord <= gGraf_data[gGraf_data_index].height) {
if (gib->the_speed < gGraf_specs[gGraf_spec_index].total_height * 160 / 480) {
gib->the_speed += pPeriod * gGraf_specs[gGraf_spec_index].total_height * 60 / 480 / 1000.f;
}
} else {
kill_the_giblet = 1;
}
} else {
if (gib->y_speed < gGraf_specs[gGraf_spec_index].total_height * 160 / 480) {
gib->y_speed += pPeriod * gGraf_specs[gGraf_spec_index].total_height * 60 / 480 / 1000.f * 2.f;
}
gib->x_coord += pPeriod * gib->x_speed / 1000.f;
gib->y_coord += pPeriod * gib->y_speed / 1000.f;
if (gib->x_coord < 0.f || gib->x_coord >= gGraf_data[gGraf_spec_index].width || gib->y_coord < 0.f || gib->y_coord >= gGraf_data[gGraf_spec_index].height) {
kill_the_giblet = 1;
}
}
if (kill_the_giblet) {
gib->current_giblet = -1;
DeallocateTransientBitmap(gib->transient_index);
} else {
DrawCursorGiblet(gib);
}
}
}
// IDA: int __usercall NewCursorGiblet@<EAX>(int pX_coord@<EAX>, int pY_coord@<EDX>, float pX_speed, float pY_speed, tU32 pDrop_time)
@ -2229,11 +2360,34 @@ int NewCursorGiblet(int pX_coord, int pY_coord, float pX_speed, float pY_speed,
int the_height;
int sequence_number;
LOG_TRACE("(%d, %d, %f, %f, %d)", pX_coord, pY_coord, pX_speed, pY_speed, pDrop_time);
NOT_IMPLEMENTED();
sequence_number = IRandomBetween(0, COUNT_OF(gCursor_giblet_sequences) - 1);
if (pX_coord >= 0 && pX_coord < gGraf_data[gGraf_data_index].width && pY_coord >= 0 && pY_coord < gGraf_data[gGraf_data_index].height) {
for (i = 0; i < COUNT_OF(gCursor_giblets); i++) {
if (gCursor_giblets[i].current_giblet == -1) {
the_width = gCursor_giblet_images[gCursor_giblet_sequences[sequence_number][1]]->width;
the_height = gCursor_giblet_images[gCursor_giblet_sequences[sequence_number][1]]->height;
gCursor_giblets[i].transient_index = AllocateTransientBitmap(the_width, the_height, 1);
gCursor_giblets[i].current_giblet = 1;
gCursor_giblets[i].sequence_index = sequence_number;
gCursor_giblets[i].landed = 0;
gCursor_giblets[i].x_coord = sequence_number * gGraf_specs[gGraf_spec_index].total_width / 640 - the_width / 2 + pX_coord;
gCursor_giblets[i].y_coord = FRandomPosNeg(6.f) * gGraf_specs[gGraf_spec_index].total_height / 480 - the_height / 2 + pY_coord;
gCursor_giblets[i].x_speed = pX_speed;
gCursor_giblets[i].y_speed = pY_speed;
gCursor_giblets[i].last_giblet_change = 0;
gCursor_giblets[i].giblet_change_period = 1000;
gCursor_giblets[i].e_t_a = PDGetTotalTime() + pDrop_time;
return i;
}
}
}
return -1;
}
// IDA: int __cdecl DoMouseCursor()
int DoMouseCursor() {
int x_coord; // Added by DethRace
int y_coord;
int mouse_moved;
int new_required;
@ -2251,8 +2405,84 @@ int DoMouseCursor() {
static int required_cursor;
static int zero_count;
static int button_was_down;
STUB_ONCE();
return 0;
period = 0;
this_call_time = PDGetTotalTime();
if (last_call_time == 0) {
period = 1000;
}
while (period <= 20) {
// Sleep 1 ms to avoid 100% CPU usage
OS_Sleep(1);
this_call_time = PDGetTotalTime();
period = this_call_time - last_call_time;
}
GetMousePosition(&x_coord, &y_coord);
mouse_moved = x_coord != gMouse_last_x_coord || y_coord != gMouse_last_y_coord;
button_is_down = EitherMouseButtonDown();
cursor_offset = button_is_down ? 4 : 0;
if (gMouse_in_use || mouse_moved) {
gMouse_in_use = 1;
if (gMouse_last_x_coord == x_coord) {
if (zero_count >= 5) {
delta_x = 0;
}
zero_count++;
} else {
zero_count = 0;
delta_x = (x_coord - gMouse_last_x_coord) * 1000 / period;
}
if (delta_x < -10) {
new_required = 0;
} else if (delta_x < 11) {
new_required = 2;
} else {
new_required = 3;
}
if (new_required != required_cursor && this_call_time - last_required_change >= 200) {
last_required_change = this_call_time;
required_cursor = new_required;
}
if (gCurrent_cursor_index != required_cursor && PDGetTotalTime() - last_cursor_change >= 50) {
if (required_cursor < gCurrent_cursor_index) {
gCurrent_cursor_index--;
} else {
gCurrent_cursor_index++;
}
last_cursor_change = PDGetTotalTime();
}
giblet_chance = Chance(1.f + 20.f * (abs(x_coord - gMouse_last_x_coord) + abs(y_coord - gMouse_last_y_coord)) / (float)period, period);
if (gProgram_state.sausage_eater_mode) {
giblet_count = 0;
} else {
giblet_count = 6 * BooleanTo1Or0(button_is_down && !button_was_down) + BooleanTo1Or0(giblet_chance);
}
for (; giblet_count != 0; giblet_count--) {
NewCursorGiblet(
x_coord + gCursor_gib_x_offsets[gCurrent_cursor_index + cursor_offset] * gGraf_specs[gGraf_spec_index].total_width / 640,
y_coord + gCursor_gib_y_offsets[gCurrent_cursor_index + cursor_offset] * gGraf_specs[gGraf_spec_index].total_height / 480,
((float)(x_coord - gMouse_last_x_coord)) / period * 1000.f / 4.f,
((float)(y_coord - gMouse_last_y_coord)) / period * 1000.f / 3.f,
(button_is_down && !button_was_down) ? 50 : 400);
}
ProcessCursorGiblets(period);
SaveTransient(gCursor_transient_index,
x_coord - gCursor_x_offsets[gCurrent_cursor_index + cursor_offset] * gGraf_specs[gGraf_spec_index].total_width / 640,
y_coord - gCursor_y_offsets[gCurrent_cursor_index + cursor_offset] * gGraf_specs[gGraf_spec_index].total_height / 480);
DRPixelmapRectangleMaskedCopy(gBack_screen,
x_coord - gCursor_x_offsets[gCurrent_cursor_index + cursor_offset] * gGraf_specs[gGraf_spec_index].total_width / 640,
y_coord - gCursor_y_offsets[gCurrent_cursor_index + cursor_offset] * gGraf_specs[gGraf_spec_index].total_height / 480,
gCursors[gCurrent_cursor_index + cursor_offset],
0,
0,
gCursors[gCurrent_cursor_index + cursor_offset]->width,
gCursors[gCurrent_cursor_index + cursor_offset]->height);
}
last_call_time = this_call_time;
button_was_down = button_is_down;
gMouse_last_x_coord = x_coord;
gMouse_last_y_coord = y_coord;
return mouse_moved;
}
// IDA: int __cdecl AllocateCursorTransient()
@ -2261,17 +2491,43 @@ int AllocateCursorTransient() {
int largest_width;
int largest_height;
LOG_TRACE("()");
NOT_IMPLEMENTED();
largest_width = 0;
largest_height = 0;
for (i = 0; i < COUNT_OF(gCursors); i++) {
if (largest_width < gCursors[i]->width) {
largest_width = gCursors[i]->width;
}
if (largest_height < gCursors[i]->height) {
largest_height = gCursors[i]->height;
}
}
return AllocateTransientBitmap(largest_width, largest_height, 0);
}
// IDA: void __cdecl StartMouseCursor()
void StartMouseCursor() {
STUB();
int i;
LOG_TRACE("()");
gNext_transient = 0;
gCursor_transient_index = AllocateCursorTransient();
GetMousePosition(&gMouse_last_x_coord, &gMouse_last_y_coord);
gMouse_in_use = 0;
gCurrent_cursor_index = 2;
for (i = 0; i < COUNT_OF(gCursor_giblets); i++) {
gCursor_giblets[i].current_giblet = -1;
}
gMouse_started = 1;
}
// IDA: void __cdecl EndMouseCursor()
void EndMouseCursor() {
STUB();
LOG_TRACE("()");
RemoveTransientBitmaps(1);
DeallocateAllTransientBitmaps();
gMouse_started = 0;
}
// IDA: void __usercall LoadFont(int pFont_ID@<EAX>)

View File

@ -66,23 +66,23 @@ void ChangeSelection(tInterface_spec* pSpec, int* pOld_selection, int* pNew_sele
} else if (*pOld_selection < *pNew_selection) {
do {
*pNew_selection = *pNew_selection + 1;
if (pSpec->move_up_min[pMode] != *pNew_selection && *pNew_selection <= pSpec->move_up_min[pMode]) {
if (*pNew_selection < pSpec->move_up_min[pMode]) {
*pNew_selection = pSpec->move_up_max[pMode];
}
if (pSpec->move_up_max[pMode] < *pNew_selection) {
if (*pNew_selection > pSpec->move_up_max[pMode]) {
*pNew_selection = pSpec->move_up_min[pMode];
}
} while (*pNew_selection != *pOld_selection && !ChoiceDisabled(*pNew_selection));
} while (*pNew_selection != *pOld_selection && ChoiceDisabled(*pNew_selection));
} else {
do {
*pNew_selection = *pNew_selection - 1;
if (pSpec->move_up_min[pMode] != *pNew_selection && *pNew_selection <= pSpec->move_up_min[pMode]) {
if (*pNew_selection < pSpec->move_up_min[pMode]) {
*pNew_selection = pSpec->move_up_max[pMode];
}
if (pSpec->move_up_max[pMode] < *pNew_selection) {
if (*pNew_selection > pSpec->move_up_max[pMode]) {
*pNew_selection = pSpec->move_up_min[pMode];
}
} while (*pNew_selection != *pOld_selection && !ChoiceDisabled(*pNew_selection));
} while (*pNew_selection != *pOld_selection && ChoiceDisabled(*pNew_selection));
}
}
@ -157,7 +157,7 @@ int DoInterfaceScreen(tInterface_spec* pSpec, int pOptions, int pCurrent_choice)
tProg_status entry_status; //
int x_coord; //
int y_coord; //
int mouse_in_somewhere;
int mouse_in_somewhere = 0;
int i; //
int key2;
int mouse_was_started;
@ -170,8 +170,8 @@ int DoInterfaceScreen(tInterface_spec* pSpec, int pOptions, int pCurrent_choice)
int the_key; //
int the_max;
int mouse_down; //
int new_mouse_down = 0; //
int last_mouse_down;
int new_mouse_down; //
int last_mouse_down = 0;
int defeat_mode_change; //
int selection_changed; //
char the_str[256];
@ -233,9 +233,9 @@ int DoInterfaceScreen(tInterface_spec* pSpec, int pOptions, int pCurrent_choice)
copy_areas = BrMemAllocate(sizeof(void*) * pSpec->number_of_recopy_areas, kMem_intf_copy_areas);
for (i = 0; i < pSpec->number_of_recopy_areas; i++) {
copy_areas[i] = BrPixelmapAllocate(BR_MEMORY_PIXELS,
((pSpec->recopy_areas[i].right[gGraf_data_index] - pSpec->recopy_areas[i].left[gGraf_data_index]) + 3) & 0xFC,
((pSpec->recopy_areas[i].right[gGraf_data_index] - pSpec->recopy_areas[i].left[gGraf_data_index]) + 3) & ~3,
pSpec->recopy_areas[i].bottom[gGraf_data_index] - pSpec->recopy_areas[i].top[gGraf_data_index],
0, 0);
NULL, 0);
}
}
@ -374,9 +374,11 @@ int DoInterfaceScreen(tInterface_spec* pSpec, int pOptions, int pCurrent_choice)
PDScreenBufferSwap(0);
if (gMouse_in_use && !selection_changed) {
GetMousePosition(&x_coord, &y_coord);
mouse_down = EitherMouseButtonDown();
last_choice = 0;
new_mouse_down = mouse_down && !new_mouse_down;
new_mouse_down = EitherMouseButtonDown();
mouse_down = new_mouse_down && !last_mouse_down;
last_mouse_down = new_mouse_down;
mouse_in_somewhere = 0;
for (i = 0; i < pSpec->number_of_mouse_areas; i++) {
if (x_coord >= pSpec->mouse_areas[i].left[gGraf_data_index]
&& y_coord >= pSpec->mouse_areas[i].top[gGraf_data_index]
@ -393,10 +395,10 @@ int DoInterfaceScreen(tInterface_spec* pSpec, int pOptions, int pCurrent_choice)
}
if (pSpec->mouse_areas[i].new_mode >= 0 || pSpec->mouse_areas[i].new_choice >= 0) {
last_choice = 1;
mouse_in_somewhere = 1;
}
if (mouse_down) {
if (pSpec->mouse_areas[i].mouse_click) {
if (pSpec->mouse_areas[i].mouse_click != NULL) {
mouse_down = pSpec->mouse_areas[i].mouse_click(&gCurrent_choice, &gCurrent_mode,
x_coord - pSpec->mouse_areas[i].left[gGraf_data_index],
y_coord - pSpec->mouse_areas[i].top[gGraf_data_index]);
@ -407,7 +409,7 @@ int DoInterfaceScreen(tInterface_spec* pSpec, int pOptions, int pCurrent_choice)
}
}
if (PDKeyDown(KEY_RETURN) || PDKeyDown(KEY_KP_ENTER) || (gTyping_slot < 0 && PDKeyDown(KEY_SPACE)) || (gMouse_in_use && last_choice && new_mouse_down)) {
if (PDKeyDown(KEY_RETURN) || PDKeyDown(KEY_KP_ENTER) || (gTyping_slot < 0 && PDKeyDown(KEY_SPACE)) || (gMouse_in_use && mouse_in_somewhere && mouse_down)) {
DRS3StartSound(gIndexed_outlets[0], 3004);
go_ahead = pSpec->go_ahead_allowed[gCurrent_mode];
if (pSpec->go_ahead_proc[gCurrent_mode]) {
@ -474,7 +476,7 @@ int DoInterfaceScreen(tInterface_spec* pSpec, int pOptions, int pCurrent_choice)
if (entry_status != eProg_idling && gProgram_state.prog_status == eProg_idling) {
escaped = 1;
}
} while ((!pSpec->exit_proc || !(pSpec->exit_proc)(&gCurrent_choice, &gCurrent_mode)) && !go_ahead && !timed_out && !escaped);
} while ((pSpec->exit_proc == NULL || !(pSpec->exit_proc)(&gCurrent_choice, &gCurrent_mode)) && !go_ahead && !timed_out && !escaped);
LOG_WARN("OUT OF LOOP %d %d %d", go_ahead, timed_out, escaped);
gTyping = 0;

View File

@ -20,8 +20,6 @@
#include "globvrpb.h"
#include "grafdata.h"
#include "graphics.h"
#include "harness/config.h"
#include "harness/trace.h"
#include "init.h"
#include "input.h"
#include "newgame.h"
@ -33,6 +31,9 @@
#include "spark.h"
#include "utility.h"
#include "world.h"
#include "harness/config.h"
#include "harness/hooks.h"
#include "harness/trace.h"
#include <errno.h>
#define HITHER_MULTIPLIER 2.0f
@ -550,7 +551,7 @@ void DRLoadPalette(char* pPath_name) {
br_pixelmap* palette_array[100];
int number_of_palettes;
number_of_palettes = DRPixelmapLoadMany(pPath_name, palette_array, 100);
number_of_palettes = DRPixelmapLoadMany(pPath_name, palette_array, COUNT_OF(palette_array));
BrTableAddMany(palette_array, number_of_palettes);
}
@ -559,7 +560,7 @@ void DRLoadShadeTable(char* pPath_name) {
br_pixelmap* table_array[100];
int number_of_tables;
number_of_tables = DRPixelmapLoadMany(pPath_name, table_array, 100);
number_of_tables = DRPixelmapLoadMany(pPath_name, table_array, COUNT_OF(table_array));
BrTableAddMany(table_array, number_of_tables);
}
@ -581,7 +582,7 @@ void DRLoadPixelmaps(char* pPath_name) {
int i;
PossibleService();
number_of_pixelmaps = DRPixelmapLoadMany(pPath_name, pixelmap_array, 100);
number_of_pixelmaps = DRPixelmapLoadMany(pPath_name, pixelmap_array, COUNT_OF(pixelmap_array));
RezeroPixelmaps(pixelmap_array, number_of_pixelmaps);
BrMapAddMany(pixelmap_array, number_of_pixelmaps);
@ -593,7 +594,7 @@ void DRLoadMaterials(char* pPath_name) {
int number_of_materials;
PossibleService();
number_of_materials = BrMaterialLoadMany(pPath_name, material_array, 100);
number_of_materials = BrMaterialLoadMany(pPath_name, material_array, COUNT_OF(material_array));
BrMaterialAddMany(material_array, number_of_materials);
}
@ -700,7 +701,7 @@ void LoadInterfaceStuff(int pWithin_race) {
strcpy(path, "HANDX.PIX");
}
PossibleService();
if (!gCursors[0] && !LoadPixelmaps(path, gCursors, 4)) {
if (gCursors[0] == NULL && LoadPixelmaps(path, gCursors, 4) == 0) {
FatalError(22);
}
if (gProgram_state.sausage_eater_mode) {
@ -709,11 +710,11 @@ void LoadInterfaceStuff(int pWithin_race) {
strcpy(path, "HANDPX.PIX");
}
PossibleService();
if (!gCursors[4] && !LoadPixelmaps(path, &gCursors[4], 4)) {
if (gCursors[4] == NULL && LoadPixelmaps(path, &gCursors[4], 4) == 0) {
FatalError(22);
}
PossibleService();
if (!gCursor_giblet_images[0] && !LoadPixelmaps("CURSGIBX.PIX", gCursor_giblet_images, 18u)) {
if (gCursor_giblet_images[0] == NULL && LoadPixelmaps("CURSGIBX.PIX", gCursor_giblet_images, COUNT_OF(gCursor_giblet_images)) == 0) {
FatalError(23);
}
}
@ -2633,7 +2634,7 @@ void LoadOpponents() {
GetPairOfInts(f, &the_chunk->x_coord, &the_chunk->y_coord);
GetPairOfInts(f, &the_chunk->frame_cue, &the_chunk->frame_end);
the_chunk->line_count = GetAnInt(f);
while (the_chunk->line_count > 8) {
while (the_chunk->line_count > COUNT_OF(the_chunk->text)) {
the_chunk->line_count--;
GetALineAndDontArgue(f, s);
}
@ -3070,9 +3071,9 @@ FILE* OldDRfopen(char* pFilename, char* pMode) {
LOG_TRACE("(\"%s\", \"%s\")", pFilename, pMode);
fp = fopen(pFilename, pMode);
fp = Harness_Hook_fopen(pFilename, pMode);
if (fp) {
if (fp != NULL) {
// Demo does not check gDecode_thing ("i am fiddling" in PROG.ACT)
// If the text file starts with a '@' character, it will be decoded, otherwise used as-is.

View File

@ -168,22 +168,22 @@ int DoMainMenuInterface(tU32 pTime_out, int pContinue_allowed) {
0, // end_flic_escaped
0, // end_flic_otherwise
0, // flic_bunch_to_load
{ 0x0FFFFFFFF, 0 }, // move_left_new_mode
{ -1, 0 }, // move_left_new_mode
{ 0, 0 }, // move_left_delta
{ 0, 0 }, // move_left_min
{ 0, 0 }, // move_left_max
{ NULL, NULL }, // move_left_proc
{ 0x0FFFFFFFF, 0 }, // move_right_new_mode
{ -1, 0 }, // move_right_new_mode
{ 0, 0 }, // move_right_delta
{ 0, 0 }, // move_right_min
{ 0, 0 }, // move_right_max
{ NULL, NULL }, // move_right_proc
{ 0x0FFFFFFFF, 0 }, // move_up_new_mode
{ 0x0FFFFFFFF, 0 }, // move_up_delta
{ -1, 0 }, // move_up_new_mode
{ -1, 0 }, // move_up_delta
{ 0, 0 }, // move_up_min
{ 7, 0 }, // move_up_max
{ NULL, NULL }, // move_up_proc
{ 0x0FFFFFFFF, 0 }, // move_down_new_mode
{ -1, 0 }, // move_down_new_mode
{ 1, 0 }, // move_down_delta
{ 0, 0 }, // move_down_min
{ 7, 0 }, // move_down_max
@ -203,11 +203,11 @@ int DoMainMenuInterface(tU32 pTime_out, int pContinue_allowed) {
NULL, // get_original_string
0, // escape_code
0, // dont_save_or_load
8, // number_of_button_flics
COUNT_OF(flicker_on1), // number_of_button_flics
flicker_on1, // flicker_on_flics
flicker_off1, // flicker_off_flics
push1, // pushed_flics
8, // number_of_mouse_areas
COUNT_OF(mouse_areas1), // number_of_mouse_areas
mouse_areas1, // mouse_areas
0, // number_of_recopy_areas
NULL // recopy_areas
@ -249,22 +249,22 @@ int DoMainMenuInterface(tU32 pTime_out, int pContinue_allowed) {
0, // end_flic_escaped
0, // end_flic_otherwise
0, // flic_bunch_to_load
{ 0x0FFFFFFFF, 0 }, // move_left_new_mode
{ -1, 0 }, // move_left_new_mode
{ 0, 0 }, // move_left_delta
{ 0, 0 }, // move_left_min
{ 0, 0 }, // move_left_max
{ NULL, NULL }, // move_left_proc
{ 0x0FFFFFFFF, 0 }, // move_right_new_mode
{ -1, 0 }, // move_right_new_mode
{ 0, 0 }, // move_right_delta
{ 0, 0 }, // move_right_min
{ 0, 0 }, // move_right_max
{ NULL, NULL }, // move_right_proc
{ 0x0FFFFFFFF, 0 }, // move_up_new_mode
{ 0x0FFFFFFFF, 0 }, // move_up_delta
{ -1, 0 }, // move_up_new_mode
{ -1, 0 }, // move_up_delta
{ 0, 0 }, // move_up_min
{ 4, 0 }, // move_up_max
{ NULL, NULL }, // move_up_proc
{ 0x0FFFFFFFF, 0 }, // move_down_new_mode
{ -1, 0 }, // move_down_new_mode
{ 1, 0 }, // move_down_delta
{ 0, 0 }, // move_down_min
{ 4, 0 }, // move_down_max
@ -284,11 +284,11 @@ int DoMainMenuInterface(tU32 pTime_out, int pContinue_allowed) {
NULL, // get_original_string
4, // escape_code
0, // dont_save_or_load
5, // number_of_button_flics
COUNT_OF(flicker_on2), // number_of_button_flics
flicker_on2, // flicker_on_flics
flicker_off2, // flicker_off_flics
push2, // pushed_flics
5, // number_of_mouse_areas
COUNT_OF(mouse_areas2), // number_of_mouse_areas
mouse_areas2, // mouse_areas
0, // number_of_recopy_areas
NULL // recopy_areas

View File

@ -431,7 +431,15 @@ int GraphOptDown(int* pCurrent_choice, int* pCurrent_mode) {
int RadioClick(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) {
int i;
LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset);
NOT_IMPLEMENTED();
for (i = gRadio_bastards__options[*pCurrent_choice - 2].count - 1; i >= 0; i--) {
if (gThe_interface_spec__options->mouse_areas[2].left[gGraf_data_index] + pX_offset + 3 >= gRadio_bastards__options[*pCurrent_choice - 2].left[i]) {
DRS3StartSound(gIndexed_outlets[0], 3000);
RadioChanged(*pCurrent_choice - 2, i);
return 0;
}
}
return 0;
}
// IDA: int __usercall GraphOptGoAhead@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)

View File

@ -777,7 +777,9 @@ tSO_result DoAutoPartsShop() {
// IDA: void __cdecl SetOpponentFlic()
void SetOpponentFlic() {
LOG_TRACE("()");
ChangePanelFlic(0, gOpponents[gCurrent_race.opponent_list[gOpponent_index].index].mug_shot_image_data, gOpponents[gCurrent_race.opponent_list[gOpponent_index].index].mug_shot_image_data_length);
ChangePanelFlic(0,
gOpponents[gCurrent_race.opponent_list[gOpponent_index].index].mug_shot_image_data,
gOpponents[gCurrent_race.opponent_list[gOpponent_index].index].mug_shot_image_data_length);
}
// IDA: void __cdecl DrawSceneyMappyInfoVieweyThing()
@ -858,25 +860,69 @@ int TryToMoveToArrows(int* pCurrent_choice, int* pCurrent_mode) {
// IDA: int __usercall UpOpponent@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
int UpOpponent(int* pCurrent_choice, int* pCurrent_mode) {
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
NOT_IMPLEMENTED();
AddToFlicQueue(gStart_interface_spec->pushed_flics[5].flic_index,
gStart_interface_spec->pushed_flics[5].x[gGraf_data_index],
gStart_interface_spec->pushed_flics[5].y[gGraf_data_index],
1);
DRS3StartSound(gIndexed_outlets[0], 3000);
DropOutImageThruBottom(GetPanelPixelmap(0),
gCurrent_graf_data->start_race_panel_left,
gCurrent_graf_data->start_race_panel_top,
gCurrent_graf_data->start_race_panel_top_clip,
gCurrent_graf_data->start_race_panel_bottom_clip);
if (gOpponent_index == 0) {
gOpponent_index = gCurrent_race.number_of_racers;
}
gOpponent_index--;
SetOpponentFlic();
DropInImageFromTop(GetPanelPixelmap(0),
gCurrent_graf_data->start_race_panel_left,
gCurrent_graf_data->start_race_panel_top,
gCurrent_graf_data->start_race_panel_top_clip,
gCurrent_graf_data->start_race_panel_bottom_clip);
}
// IDA: int __usercall DownOpponent@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
int DownOpponent(int* pCurrent_choice, int* pCurrent_mode) {
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
NOT_IMPLEMENTED();
AddToFlicQueue(gStart_interface_spec->pushed_flics[6].flic_index,
gStart_interface_spec->pushed_flics[6].x[gGraf_data_index],
gStart_interface_spec->pushed_flics[6].y[gGraf_data_index],
1);
DRS3StartSound(gIndexed_outlets[0], 3000);
DropOutImageThruTop(GetPanelPixelmap(0),
gCurrent_graf_data->start_race_panel_left,
gCurrent_graf_data->start_race_panel_top,
gCurrent_graf_data->start_race_panel_top_clip,
gCurrent_graf_data->start_race_panel_bottom_clip);
gOpponent_index++;
if (gOpponent_index == gCurrent_race.number_of_racers) {
gOpponent_index = 0;
}
SetOpponentFlic();
DropInImageFromBottom(GetPanelPixelmap(0),
gCurrent_graf_data->start_race_panel_left,
gCurrent_graf_data->start_race_panel_top,
gCurrent_graf_data->start_race_panel_top_clip,
gCurrent_graf_data->start_race_panel_bottom_clip);
}
// IDA: int __usercall UpClickOpp@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>)
int UpClickOpp(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) {
LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset);
NOT_IMPLEMENTED();
UpOpponent(pCurrent_choice, pCurrent_mode);
return 0;
}
// IDA: int __usercall DownClickOpp@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>)
int DownClickOpp(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) {
LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset);
NOT_IMPLEMENTED();
DownOpponent(pCurrent_choice, pCurrent_mode);
return 0;
}
// IDA: void __cdecl SelectRaceStart()
@ -1757,7 +1803,21 @@ int GridClickCar(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY
int base_pos;
int x_coord;
LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset);
NOT_IMPLEMENTED();
rel_pos = ((gCurrent_graf_data->grid_bottom_clip - gCurrent_graf_data->grid_top_clip) / 2) < pY_offset;
if (rel_pos) {
pX_offset -= gCurrent_graf_data->grid_x_stagger;
}
x_coord = pX_offset / gCurrent_graf_data->grid_x_pitch;
if (x_coord > 2) {
x_coord = 2;
}
new_pos = 2 * x_coord + rel_pos + (gOur_starting_position & ~1) - 2;
if (new_pos >= 0 && new_pos < gCurrent_race.number_of_racers && gProgram_state.rank < gCurrent_race.opponent_list[new_pos].ranking) {
DRS3StartSound(gIndexed_outlets[0], 3000);
DoGridTransition(gOur_starting_position, new_pos);
}
return 0;
}
// IDA: int __usercall GridClickNumbers@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>)
@ -1765,19 +1825,33 @@ int GridClickNumbers(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, in
int new_pos;
int i;
LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset);
NOT_IMPLEMENTED();
new_pos = -1;
for (i = 0; i < gCurrent_race.number_of_racers; i++) {
if (gGrid_number_x_coords[i] <= pX_offset && (gCurrent_race.number_of_racers - 1 == i || pX_offset < gGrid_number_x_coords[i + 1])) {
new_pos = i;
break;
}
}
if (new_pos >= 0 && new_pos < gCurrent_race.number_of_racers && gProgram_state.rank <= gCurrent_race.opponent_list[new_pos].ranking) {
DRS3StartSound(gIndexed_outlets[0], 3000);
DoGridTransition(gOur_starting_position, new_pos);
}
return 0;
}
// IDA: int __usercall GridClickLeft@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>)
int GridClickLeft(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) {
LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset);
NOT_IMPLEMENTED();
GridMoveLeft(pCurrent_choice, pCurrent_mode);
}
// IDA: int __usercall GridClickRight@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>)
int GridClickRight(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) {
LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset);
NOT_IMPLEMENTED();
GridMoveRight(pCurrent_choice, pCurrent_mode);
}
// IDA: int __usercall CheckChallenge@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)

View File

@ -673,7 +673,6 @@ void PrintScreenFile(FILE* pF) {
offset -= 2 * gBack_screen->row_bytes;
}
WriteU16L(pF, 0);
;
}
// IDA: void __usercall PrintScreenFile16(FILE *pF@<EAX>)

View File

@ -294,7 +294,7 @@ typedef enum keymapcodes {
#define TIME_CONV_THING 0.00050000002
#define OPPONENT_COUNT 0
#define OPPONENT_COUNT 5
#define WORLD_SCALE 6.9f

View File

@ -532,9 +532,7 @@ void PDMouseButtons(int* pButton_1, int* pButton_2) {
br_int_32 mouse_y;
LOG_TRACE("(%p, %p)", pButton_1, pButton_2);
STUB_ONCE();
*pButton_1 = 0;
*pButton_2 = 0;
Harness_Hook_GetMouseButtons(pButton_1, pButton_2);
}
// IDA: void __usercall PDGetMousePosition(int *pX_coord@<EAX>, int *pY_coord@<EDX>)
@ -547,7 +545,8 @@ void PDGetMousePosition(int* pX_coord, int* pY_coord) {
static br_int_32 mouse_x;
static br_int_32 mouse_y;
LOG_TRACE("(%p, %p)", pX_coord, pY_coord);
NOT_IMPLEMENTED();
Harness_Hook_GetMousePosition(pX_coord, pY_coord);
}
// IDA: int __cdecl PDGetTotalTime()

View File

@ -252,6 +252,10 @@ void Harness_Hook_PDSetKeyArray() {
Window_PollEvents();
}
void Harness_Hook_FlushRenderer() {
renderer->FlushBuffers(last_colour_buffer, last_depth_buffer);
}
void Harness_Hook_BrMaterialUpdate(br_material* mat, br_uint_16 flags) {
renderer->BufferMaterial(mat);
}
@ -264,6 +268,16 @@ void Harness_Hook_BrBufferUpdate(br_pixelmap* pm, br_token use, br_uint_16 flags
}
}
// Input hooks
void Harness_Hook_GetMousePosition(int* pX, int* pY) {
Input_GetMousePosition(pX, pY);
}
void Harness_Hook_GetMouseButtons(int* pButton1, int* pButton2) {
Input_GetMouseButtons(pButton1, pButton2);
}
// Sound hooks
void Harness_Hook_S3Service(int unk1, int unk2) {
Sound_Service();
}
@ -271,6 +285,7 @@ void Harness_Hook_S3Service(int unk1, int unk2) {
void Harness_Hook_S3StopAllOutletSounds() {
}
void Harness_Hook_FlushRenderer() {
renderer->FlushBuffers(last_colour_buffer, last_depth_buffer);
// Filesystem hooks
FILE* Harness_Hook_fopen(const char* pathname, const char* mode) {
return OS_fopen(pathname, mode);
}

View File

@ -3,6 +3,8 @@
#include "brender/br_types.h"
#include <stdio.h>
void Harness_Init(int* argc, char* argv[]);
// Hooks are called from original game code.
@ -27,8 +29,15 @@ void Harness_Hook_BrZbSceneRenderEnd();
void Harness_Hook_BrBufferUpdate(br_pixelmap* pm, br_token use, br_uint_16 flags);
void Harness_Hook_BrMaterialUpdate(br_material* mat, br_uint_16 flags);
// Input hooks
void Harness_Hook_GetMousePosition(int* pX, int* pY);
void Harness_Hook_GetMouseButtons(int* pButton1, int* pButton2);
// Sound hooks
void Harness_Hook_S3Service(int unk1, int unk2);
void Harness_Hook_S3StopAllOutletSounds();
#endif
// Filesystem hooks
FILE* Harness_Hook_fopen(const char* pathname, const char* mode);
#endif

View File

@ -2,6 +2,7 @@
#define HARNESS_OS_H
#include <stdint.h>
#include <stdio.h>
#if defined(_WIN32) || defined(_WIN64)
#include <direct.h>
@ -43,4 +44,6 @@ int OS_IsDebuggerPresent(void);
// Optional: install a handler to print stack trace during a crash
void OS_InstallSignalHandler(char* program_name);
FILE* OS_fopen(const char* pathname, const char* mode);
#endif

View File

@ -8,5 +8,7 @@ void Window_PollEvents(void);
void Window_Swap(int delay_ms_after_swap);
int* Input_GetKeyMap(void);
int Input_IsKeyDown(unsigned char scan_code);
void Input_GetMousePosition(int* pX, int* pY);
void Input_GetMouseButtons(int* pButton1, int* pButton2);
#endif
#endif

View File

@ -122,6 +122,10 @@ int keymap[123] = {
SDL_Window* window;
SDL_GLContext context;
uint8_t sdl_key_state[256];
struct {
float x;
float y;
} sdl_window_scale;
tRenderer gl_renderer = {
GLRenderer_Init,
@ -155,7 +159,7 @@ tRenderer* Window_Create(char* title, int width, int height, int pRender_width,
width, height,
SDL_WINDOW_OPENGL);
if (!window) {
if (window == NULL) {
LOG_PANIC("Failed to create window");
}
@ -164,6 +168,9 @@ tRenderer* Window_Create(char* title, int width, int height, int pRender_width,
SDL_SetRelativeMouseMode(SDL_TRUE);
}
sdl_window_scale.x = ((float)pRender_width) / width;
sdl_window_scale.y = ((float)pRender_height) / height;
// SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
context = SDL_GL_CreateContext(window);
@ -224,3 +231,15 @@ int* Input_GetKeyMap() {
int Input_IsKeyDown(unsigned char scan_code) {
return sdl_key_state[scan_code];
}
void Input_GetMousePosition(int* pX, int* pY) {
SDL_GetMouseState(pX, pY);
*pX *= sdl_window_scale.x;
*pY *= sdl_window_scale.y;
}
void Input_GetMouseButtons(int* pButton1, int* pButton2) {
int state = SDL_GetMouseState(NULL, NULL);
*pButton1 = state & SDL_BUTTON_LMASK;
*pButton2 = state & SDL_BUTTON_RMASK;
}

View File

@ -17,7 +17,6 @@
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
@ -285,3 +284,28 @@ void OS_InstallSignalHandler(char* program_name) {
}
}
}
FILE* OS_fopen(const char* pathname, const char* mode) {
FILE* f = fopen(pathname, mode);
if (f != NULL) {
return f;
}
char buffer[512];
char buffer2[512];
strcpy(buffer, pathname);
strcpy(buffer2, pathname);
char* pDirName = dirname(buffer);
char* pBaseName = basename(buffer2);
DIR* pDir = opendir(pDirName);
if (pDir == NULL) {
return NULL;
}
for (struct dirent* pDirent = readdir(pDir); pDirent != NULL; pDirent = readdir(pDir)) {
if (strcasecmp(pBaseName, pDirent->d_name) == 0) {
strcat(pDirName, "/");
strcat(pDirName, pDirent->d_name);
return fopen(pDirName, mode);
}
}
return NULL;
}

View File

@ -284,3 +284,7 @@ void OS_InstallSignalHandler(char* program_name) {
}
}
}
FILE* OS_fopen(const char* pathname, const char* mode) {
return fopen(pathname, mode);
}

View File

@ -203,4 +203,17 @@ LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS* ExceptionInfo) {
void OS_InstallSignalHandler(char* program_name) {
strcpy(_program_name, program_name);
SetUnhandledExceptionFilter(windows_exception_handler);
}
}
FILE* OS_fopen(const char* pathname, const char* mode) {
FILE* f;
errno_t err;
f = NULL;
err = fopen_s(&f, pathname, mode);
if (err != 0) {
fprintf(stderr, "Failed to open \"%s\"", pathname);
}
return f;
}