* Basic networking functions implemented to get the lobby functional * Apply suggestions from code review * PDNetObtainSystemUserName gets local system name --------- Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com>
This commit is contained in:
parent
7d475fc117
commit
1c10b74141
|
|
@ -1,3 +1,5 @@
|
|||
$ErrorActionPreference = "Stop"
|
||||
|
||||
if ($($Env:PLATFORM_ARCH) -eq "x86") {
|
||||
$sdl_path = "x86"
|
||||
} else {
|
||||
|
|
@ -18,7 +20,13 @@ Expand-Archive $Env:TEMP\SDL2-devel.zip -DestinationPath $Env:TEMP
|
|||
|
||||
# build
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_TESTS=ON "-DSDL2_ROOT_DIR=$($Env:TEMP)\SDL2-$sdl2_version" -B build
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Exit $LASTEXITCODE
|
||||
}
|
||||
cmake --build build --config RelWithDebInfo
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Exit $LASTEXITCODE
|
||||
}
|
||||
|
||||
# copy SDL2.dll to build folder, so tests can run
|
||||
cp $Env:TEMP\SDL2-$sdl2_version\lib\$sdl_path\SDL2.dll build
|
||||
|
|
|
|||
|
|
@ -48,7 +48,10 @@ endfunction()
|
|||
|
||||
test_big_endian(IS_BIGENDIAN)
|
||||
|
||||
find_package(SDL2 REQUIRED)
|
||||
find_package(SDL2 CONFIG)
|
||||
if(NOT SDL2_FOUND)
|
||||
find_package(SDL2 MODULE REQUIRED)
|
||||
endif()
|
||||
|
||||
add_subdirectory(lib/libsmacker)
|
||||
add_subdirectory(lib/glad)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ target_include_directories(dethrace_obj
|
|||
pd
|
||||
)
|
||||
|
||||
# add_compile_options(-fsanitize=address)
|
||||
# add_link_options(-fsanitize=address)
|
||||
|
||||
target_link_libraries(dethrace_obj PUBLIC SDL2::SDL2 smackw32 harness brender s3)
|
||||
|
||||
|
||||
|
|
@ -35,6 +38,7 @@ else()
|
|||
-Wstrict-prototypes
|
||||
)
|
||||
endif()
|
||||
target_compile_definitions(dethrace_obj PRIVATE INSIDE_DETHRACE)
|
||||
if(DETHRACE_FIX_BUGS)
|
||||
target_compile_definitions(dethrace_obj PRIVATE DETHRACE_FIX_BUGS)
|
||||
endif()
|
||||
|
|
@ -154,14 +158,15 @@ target_sources(dethrace_obj PRIVATE
|
|||
common/world.h
|
||||
constants.h
|
||||
dr_types.h
|
||||
pc-dos/dosnet.c
|
||||
pd/net.h
|
||||
pc-dos/dossys.c
|
||||
pd/sys.h
|
||||
pc-win95/win95sys.c
|
||||
pc-win95/dinput.h
|
||||
pc-win95/ssdx.c
|
||||
pc-win95/ssdx.h
|
||||
pc-win95/win95net.c
|
||||
pc-dos/dosnet.c
|
||||
pc-dos/dossys.c
|
||||
)
|
||||
|
||||
# Create our main game binary.
|
||||
|
|
@ -184,7 +189,7 @@ if(NOT MSVC)
|
|||
else()
|
||||
target_link_libraries(dethrace PRIVATE dbghelp)
|
||||
target_link_options(dethrace PRIVATE /subsystem:windows /ENTRY:mainCRTStartup)
|
||||
target_compile_definitions(dethrace PRIVATE -D_CRT_SECURE_NO_WARNINGS -DSDL_MAIN_HANDLED)
|
||||
target_compile_definitions(dethrace PRIVATE -D_CRT_SECURE_NO_WARNINGS -DSDL_MAIN_HANDLED -DWIN32_LEAN_AND_MEAN)
|
||||
endif()
|
||||
|
||||
if(DETHRACE_IDE_ROOT_DIR)
|
||||
|
|
|
|||
|
|
@ -494,36 +494,60 @@ void SetInitialPosition(tRace_info* pThe_race, int pCar_index, int pGrid_index)
|
|||
car = pThe_race->opponent_list[pCar_index].car_spec;
|
||||
BrMatrix34Identity(&car_actor->t.t.mat);
|
||||
place_on_grid = 1;
|
||||
if (gNet_mode && !gCurrent_net_game->options.grid_start && pThe_race->number_of_net_start_points) {
|
||||
TELL_ME_IF_WE_PASS_THIS_WAY();
|
||||
if (gNet_mode != eNet_mode_none && !gCurrent_net_game->options.grid_start && pThe_race->number_of_net_start_points != 0) {
|
||||
start_i = i = IRandomBetween(0, pThe_race->number_of_net_start_points - 1);
|
||||
do {
|
||||
PossibleService();
|
||||
for (j = 0; j < gNumber_of_net_players; j++) {
|
||||
if (j != pCar_index) {
|
||||
BrVector3Copy(&real_pos, &pThe_race->opponent_list[j].car_spec->car_master_actor->t.t.translate.t);
|
||||
if (real_pos.v[0] > 500.f) {
|
||||
real_pos.v[0] -= 1000.f;
|
||||
real_pos.v[1] -= 1000.f;
|
||||
real_pos.v[2] -= 1000.f;
|
||||
}
|
||||
BrVector3Sub(&dist, &real_pos, &pThe_race->net_starts[i].pos);
|
||||
if (BrVector3LengthSquared(&dist) < 16.f) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (j == gNumber_of_net_players) {
|
||||
BrVector3Copy(&car_actor->t.t.translate.t, &pThe_race->net_starts[i].pos);
|
||||
initial_yaw = BrDegreeToAngle(pThe_race->net_starts[i].yaw);
|
||||
place_on_grid = 0;
|
||||
}
|
||||
i++;
|
||||
if (i == pThe_race->number_of_net_start_points) {
|
||||
i = 0;
|
||||
}
|
||||
} while (start_i != i);
|
||||
}
|
||||
if (place_on_grid) {
|
||||
initial_yaw = (pThe_race->initial_yaw * 182.0444444444445);
|
||||
initial_yaw = BrDegreeToAngle(pThe_race->initial_yaw);
|
||||
BrMatrix34RotateY(&initial_yaw_matrix, initial_yaw);
|
||||
grid_offset.v[0] = 0.0 - pGrid_index % 2;
|
||||
grid_offset.v[1] = 0.0;
|
||||
grid_offset.v[2] = (double)(pGrid_index / 2) * 2.0 + (double)(pGrid_index % 2) * 0.40000001;
|
||||
grid_offset.v[0] = 0.0f - pGrid_index % 2;
|
||||
grid_offset.v[1] = 0.0f;
|
||||
grid_offset.v[2] = (br_scalar)(pGrid_index / 2) * 2.0f + (br_scalar)(pGrid_index % 2) * 0.4f;
|
||||
BrMatrix34ApplyV(&car_actor->t.t.translate.t, &grid_offset, &initial_yaw_matrix);
|
||||
BrVector3Accumulate(&car_actor->t.t.translate.t, &pThe_race->initial_position);
|
||||
}
|
||||
FindBestY(
|
||||
&car_actor->t.t.translate.t,
|
||||
gTrack_actor,
|
||||
10.0,
|
||||
10.0f,
|
||||
&nearest_y_above,
|
||||
&nearest_y_below,
|
||||
&above_model,
|
||||
&below_model,
|
||||
&above_face_index,
|
||||
&below_face_index);
|
||||
if (nearest_y_above == 30000.0) {
|
||||
if (nearest_y_below == -30000.0) {
|
||||
car_actor->t.t.translate.t.v[1] = 0.0;
|
||||
} else {
|
||||
car_actor->t.t.translate.t.v[1] = nearest_y_below;
|
||||
}
|
||||
} else {
|
||||
if (nearest_y_above != 30000.0f) {
|
||||
car_actor->t.t.translate.t.v[1] = nearest_y_above;
|
||||
} else if (nearest_y_below != -30000.0f) {
|
||||
car_actor->t.t.translate.t.v[1] = nearest_y_below;
|
||||
} else {
|
||||
car_actor->t.t.translate.t.v[1] = 0.0f;
|
||||
}
|
||||
BrMatrix34PreRotateY(&car_actor->t.t.mat, initial_yaw);
|
||||
if (gNet_mode) {
|
||||
|
|
@ -531,7 +555,7 @@ void SetInitialPosition(tRace_info* pThe_race, int pCar_index, int pGrid_index)
|
|||
&gNet_players[pThe_race->opponent_list[pCar_index].net_player_index].initial_position,
|
||||
&car->car_master_actor->t.t.mat);
|
||||
}
|
||||
if (gNet_mode && car->disabled && car_actor->t.t.translate.t.v[0] < 500.0) {
|
||||
if (gNet_mode != eNet_mode_none && car->disabled && car_actor->t.t.translate.t.v[0] < 500.0f) {
|
||||
DisableCar(car);
|
||||
}
|
||||
// Enable to start all opponent cars upside down ;)
|
||||
|
|
|
|||
|
|
@ -2500,7 +2500,34 @@ void InitAbuseomatic(void) {
|
|||
int i;
|
||||
int len;
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gString[20] = '\0';
|
||||
PDBuildAppPath(path);
|
||||
strcat(path, "ABUSE.TXT");
|
||||
for (i = 0; i < COUNT_OF(gAbuse_text); i++) {
|
||||
gAbuse_text[i] = NULL;
|
||||
}
|
||||
f = fopen(path, "rt");
|
||||
if (f == NULL) {
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < COUNT_OF(gAbuse_text); i++) {
|
||||
if (fgets(s, COUNT_OF(s) - 1, f) == NULL) {
|
||||
break;
|
||||
}
|
||||
len = strlen(s);
|
||||
if (len > 63) {
|
||||
s[63] = '\0';
|
||||
}
|
||||
len = strlen(s);
|
||||
while (len != 0 && s[len - 1] < ' ') {
|
||||
s[len - 1] = '\0';
|
||||
len--;
|
||||
}
|
||||
gAbuse_text[i] = BrMemAllocate(strlen(s) + 1, kMem_abuse_text);
|
||||
strcpy(gAbuse_text[i], s);
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
// IDA: void __cdecl DisposeAbuseomatic()
|
||||
|
|
|
|||
|
|
@ -242,6 +242,10 @@ void dr_dprintf(char* fmt_string, ...) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (gDiagnostic_file == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (first_time == 0) {
|
||||
first_time = GetTotalTime();
|
||||
}
|
||||
|
|
@ -254,6 +258,12 @@ void dr_dprintf(char* fmt_string, ...) {
|
|||
va_end(args);
|
||||
fputs("\n", gDiagnostic_file);
|
||||
fflush(gDiagnostic_file);
|
||||
|
||||
// Added by dethrace for debugging
|
||||
// va_start(args, fmt_string);
|
||||
// vprintf(fmt_string, args);
|
||||
// va_end(args);
|
||||
// printf("\n");
|
||||
}
|
||||
|
||||
// IDA: int __usercall DoErrorInterface@<EAX>(int pMisc_text_index@<EAX>)
|
||||
|
|
|
|||
|
|
@ -425,7 +425,7 @@ void InitGame(int pStart_race) {
|
|||
|
||||
gWaiting_for_unpause = 1;
|
||||
gWait_for_it = 1;
|
||||
if (gNet_mode) {
|
||||
if (gNet_mode != eNet_mode_none) {
|
||||
gCredit_period = gCredit_period_network[gCurrent_net_game->type];
|
||||
} else {
|
||||
gCredit_period = gCredit_period_single[gProgram_state.skill_level];
|
||||
|
|
@ -448,10 +448,10 @@ void InitGame(int pStart_race) {
|
|||
gProgram_state.current_car.power_up_levels[i] = 0;
|
||||
}
|
||||
}
|
||||
for (i = 0; gNumber_of_races > i; ++i) {
|
||||
for (i = 0; i < gNumber_of_races; i++) {
|
||||
gRace_list[i].been_there_done_that = 0;
|
||||
}
|
||||
for (i = 0; gNumber_of_racers > i; ++i) {
|
||||
for (i = 0; i < gNumber_of_racers; i++) {
|
||||
gOpponents[i].dead = 0;
|
||||
}
|
||||
gProgram_state.rank = gInitial_rank;
|
||||
|
|
@ -470,7 +470,7 @@ void DisposeGameIfNecessary(void) {
|
|||
int i;
|
||||
LOG_TRACE("()");
|
||||
|
||||
if (gNet_mode) {
|
||||
if (gNet_mode != eNet_mode_none) {
|
||||
NetLeaveGame(gCurrent_net_game);
|
||||
}
|
||||
if (gGame_initialized) {
|
||||
|
|
|
|||
|
|
@ -511,33 +511,29 @@ int DoInterfaceScreen(tInterface_spec* pSpec, int pOptions, int pCurrent_choice)
|
|||
} else {
|
||||
result = gCurrent_choice;
|
||||
}
|
||||
if (!go_ahead) {
|
||||
if (!escaped) {
|
||||
if (pSpec->end_flic_otherwise > 0) {
|
||||
DRS3StartSound(gEffects_outlet, 3007);
|
||||
RunFlic(pSpec->end_flic_otherwise);
|
||||
} else if (pSpec->end_flic_otherwise < 0) {
|
||||
FadePaletteDown();
|
||||
}
|
||||
goto LABEL_230;
|
||||
} else {
|
||||
if (pSpec->end_flic_escaped > 0) {
|
||||
DRS3StartSound(gEffects_outlet, 3007);
|
||||
RunFlic(pSpec->end_flic_escaped);
|
||||
} else if (pSpec->end_flic_escaped < 0) {
|
||||
FadePaletteDown();
|
||||
}
|
||||
goto LABEL_230;
|
||||
if (go_ahead) {
|
||||
if (pSpec->end_flic_go_ahead > 0) {
|
||||
DRS3StartSound(gIndexed_outlets[0], 3007);
|
||||
RunFlic(pSpec->end_flic_go_ahead);
|
||||
} else if (pSpec->end_flic_go_ahead < 0) {
|
||||
FadePaletteDown();
|
||||
}
|
||||
} else if (escaped) {
|
||||
if (pSpec->end_flic_escaped > 0) {
|
||||
DRS3StartSound(gIndexed_outlets[0], 3007);
|
||||
RunFlic(pSpec->end_flic_escaped);
|
||||
} else if (pSpec->end_flic_escaped < 0) {
|
||||
FadePaletteDown();
|
||||
}
|
||||
} else {
|
||||
if (pSpec->end_flic_otherwise > 0) {
|
||||
DRS3StartSound(gIndexed_outlets[0], 3007);
|
||||
RunFlic(pSpec->end_flic_otherwise);
|
||||
} else if (pSpec->end_flic_otherwise < 0) {
|
||||
FadePaletteDown();
|
||||
}
|
||||
}
|
||||
if (pSpec->end_flic_go_ahead > 0) {
|
||||
DRS3StartSound(gEffects_outlet, 3007);
|
||||
RunFlic(pSpec->end_flic_go_ahead);
|
||||
} else if (pSpec->end_flic_go_ahead < 0) {
|
||||
FadePaletteDown();
|
||||
}
|
||||
|
||||
LABEL_230:
|
||||
gProgram_state.dont_save_or_load = 0;
|
||||
EndMouseCursor();
|
||||
UnlockInterfaceStuff();
|
||||
|
|
|
|||
|
|
@ -3411,7 +3411,12 @@ int OriginalCarmaCDinDrive(void) {
|
|||
// IDA: int __cdecl CarmaCDinDriveOrFullGameInstalled()
|
||||
int CarmaCDinDriveOrFullGameInstalled(void) {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
if (gCD_fully_installed) {
|
||||
return 1;
|
||||
} else {
|
||||
return OriginalCarmaCDinDrive();
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall ReadNetworkSettings(FILE *pF@<EAX>, tNet_game_options *pOptions@<EDX>)
|
||||
|
|
|
|||
|
|
@ -323,10 +323,10 @@ int DoMainMenuInterface(tU32 pTime_out, int pContinue_allowed) {
|
|||
if (pContinue_allowed) {
|
||||
gMain_menu_spec = &interface_spec1;
|
||||
result = DoInterfaceScreen(&interface_spec1, gFaded_palette | 2, 0);
|
||||
if (result != 7 && result && result != 1 && result != 2) {
|
||||
RunFlic(12);
|
||||
} else {
|
||||
if (result == 0 || result == 1 || result == 2 || result == 7) {
|
||||
FadePaletteDown();
|
||||
} else {
|
||||
RunFlic(12);
|
||||
}
|
||||
switch (result) {
|
||||
case 0:
|
||||
|
|
@ -352,10 +352,10 @@ int DoMainMenuInterface(tU32 pTime_out, int pContinue_allowed) {
|
|||
} else {
|
||||
interface_spec2.time_out = pTime_out;
|
||||
result = DoInterfaceScreen(&interface_spec2, gFaded_palette, 0);
|
||||
if (result != 4 && result != -1) {
|
||||
RunFlic(32);
|
||||
} else {
|
||||
if (result == -1 || result == 4) {
|
||||
FadePaletteDown();
|
||||
} else {
|
||||
RunFlic(32);
|
||||
}
|
||||
switch (result) {
|
||||
case 0:
|
||||
|
|
|
|||
|
|
@ -1,11 +1,21 @@
|
|||
#include "netgame.h"
|
||||
#include "brender/brender.h"
|
||||
#include "car.h"
|
||||
#include "displays.h"
|
||||
#include "errors.h"
|
||||
#include "globvars.h"
|
||||
#include "globvrpb.h"
|
||||
#include "graphics.h"
|
||||
#include "harness/trace.h"
|
||||
#include "loading.h"
|
||||
#include "network.h"
|
||||
#include "newgame.h"
|
||||
#include "opponent.h"
|
||||
#include "pd/sys.h"
|
||||
#include "pedestrn.h"
|
||||
#include "powerup.h"
|
||||
#include "racestrt.h"
|
||||
#include "structur.h"
|
||||
#include "utility.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
@ -74,7 +84,20 @@ void SendAllNonCarPositions(void) {
|
|||
tNon_car_spec* non_car;
|
||||
tNet_contents* contents;
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
list = gProgram_state.track_spec.non_car_list;
|
||||
for (i = 0; i < gProgram_state.track_spec.ampersand_digits; ++i) {
|
||||
if (list[i]->type_data != NULL) {
|
||||
non_car = (tNon_car_spec*)list[i]->type_data;
|
||||
if (non_car->collision_info.driver == eDriver_non_car_unused_slot || non_car->collision_info.car_ID != i) {
|
||||
contents = NetGetBroadcastContents(NETMSGID_NONCARPOSITION, 0);
|
||||
BrMatrix34Copy(&contents->data.non_car_position.mat, &list[i]->t.t.mat);
|
||||
contents->data.non_car_position.ID = i;
|
||||
contents->data.non_car_position.flags = list[i]->identifier[3] == '!';
|
||||
}
|
||||
}
|
||||
}
|
||||
NetSendMessageStacks();
|
||||
}
|
||||
|
||||
// IDA: void __usercall ReceivedNonCarPosition(tNet_contents *pContents@<EAX>)
|
||||
|
|
@ -103,13 +126,60 @@ void SignalToStartRace2(int pIndex) {
|
|||
int i;
|
||||
int j;
|
||||
LOG_TRACE("(%d)", pIndex);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
if (gCurrent_race.number_of_racers > 6) {
|
||||
FadePaletteUp();
|
||||
dr_dprintf("AAAARRRGGGHHH!!!! More than 6 racers!!!!");
|
||||
PDFatalError("AAAARRRGGGHHH!!!! More than 6 racers!!!!");
|
||||
}
|
||||
gNeed_to_send_start_race = 0;
|
||||
gStart_race_sent = 1;
|
||||
the_message = NetBuildMessage(NETMSGID_STARTRACE, 0);
|
||||
the_message->contents.data.start_race.racing = gProgram_state.racing;
|
||||
if (pIndex >= 0) {
|
||||
gNet_players[pIndex].last_waste_message = 0;
|
||||
gNet_players[pIndex].wasteage_attributed = 0;
|
||||
the_message->contents.data.start_race.car_count = -1;
|
||||
the_message->contents.data.start_race.car_list[0].index = pIndex;
|
||||
BrMatrix34Copy(&the_message->contents.data.start_race.car_list[0].mat,
|
||||
&gCurrent_race.opponent_list[gNet_players[pIndex].opponent_list_index].car_spec->car_master_actor->t.t.mat);
|
||||
} else {
|
||||
the_message->contents.data.start_race.car_count = gCurrent_race.number_of_racers;
|
||||
for (i = 0; i < gCurrent_race.number_of_racers; i++) {
|
||||
BrMatrix34Copy(&the_message->contents.data.start_race.car_list[i].mat,
|
||||
&gCurrent_race.opponent_list[i].car_spec->car_master_actor->t.t.mat);
|
||||
for (j = 0; j < gNumber_of_net_players; j++) {
|
||||
if (gCurrent_race.opponent_list[i].car_spec == gNet_players[j].car) {
|
||||
the_message->contents.data.start_race.car_list[i].index = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gCurrent_net_game->options.random_car_choice && (gCurrent_net_game->options.car_choice == eNet_car_all || gCurrent_net_game->options.car_choice == eNet_car_both)) {
|
||||
if (gNet_players[the_message->contents.data.start_race.car_list[i].index].next_car_index < 0) {
|
||||
gNet_players[the_message->contents.data.start_race.car_list[i].index].next_car_index = PickARandomCar();
|
||||
gCar_details[gNet_players[the_message->contents.data.start_race.car_list[i].index].next_car_index].ownership = eCar_owner_someone;
|
||||
}
|
||||
the_message->contents.data.start_race.car_list[i].next_car_index = gNet_players[the_message->contents.data.start_race.car_list[i].index].next_car_index;
|
||||
}
|
||||
}
|
||||
if (gPending_race < 0) {
|
||||
gPending_race = PickNetRace(gProgram_state.current_race_index,
|
||||
gCurrent_net_game->options.race_sequence_type);
|
||||
}
|
||||
the_message->contents.data.start_race.next_race = gPending_race;
|
||||
}
|
||||
NetGuaranteedSendMessageToAllPlayers(gCurrent_net_game, the_message, NULL);
|
||||
if (gProgram_state.racing) {
|
||||
SendCurrentPowerups();
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __cdecl SignalToStartRace()
|
||||
void SignalToStartRace(void) {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gCurrent_net_game->no_races_yet = 0;
|
||||
SignalToStartRace2(-1);
|
||||
}
|
||||
|
||||
// IDA: void __cdecl SetUpNetCarPositions()
|
||||
|
|
@ -120,7 +190,62 @@ void SetUpNetCarPositions(void) {
|
|||
int grid_index;
|
||||
int racer_count;
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
DisableNetService();
|
||||
if (!gInitialised_grid) {
|
||||
for (i = 0; i < gNumber_of_net_players; i++) {
|
||||
gNet_players[i].grid_position_set = 0;
|
||||
gNet_players[i].last_waste_message = 0;
|
||||
gNet_players[i].wasteage_attributed = 0;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < gNumber_of_net_players; i++) {
|
||||
gCurrent_race.opponent_list[i].index = -1;
|
||||
gCurrent_race.opponent_list[i].ranking = IRandomBetween(0, 99);
|
||||
gCurrent_race.opponent_list[i].car_spec = gNet_players[i].car;
|
||||
gCurrent_race.opponent_list[i].net_player_index = i;
|
||||
gNet_players[i].opponent_list_index = i;
|
||||
}
|
||||
if (!gInitialised_grid && gCurrent_net_game->options.grid_start) {
|
||||
qsort(gCurrent_race.opponent_list, gNumber_of_net_players, sizeof(tOpp_spec), SortGridFunction);
|
||||
}
|
||||
gCurrent_race.number_of_racers = 0;
|
||||
for (i = 0; i < gNumber_of_net_players; i++) {
|
||||
gNet_players[gCurrent_race.opponent_list[i].net_player_index].opponent_list_index = i;
|
||||
}
|
||||
for (i = 0; i < gNumber_of_net_players; i++) {
|
||||
if ((gCurrent_race.opponent_list[i].car_spec->driver == eDriver_oppo && !gInitialised_grid)
|
||||
|| (gCurrent_race.opponent_list[i].car_spec->driver >= eDriver_net_human && !gNet_players[gCurrent_race.opponent_list[i].net_player_index].grid_position_set)) {
|
||||
grid_index = -1;
|
||||
racer_count = 0;
|
||||
while (racer_count < 6 && grid_index < 0) {
|
||||
grid_index = racer_count;
|
||||
for (k = 0; k < gNumber_of_net_players; k++) {
|
||||
if (k != i
|
||||
&& gNet_players[gCurrent_race.opponent_list[k].net_player_index].grid_position_set
|
||||
&& gNet_players[gCurrent_race.opponent_list[k].net_player_index].grid_index == racer_count) {
|
||||
grid_index = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
racer_count++;
|
||||
}
|
||||
if (grid_index < 0) {
|
||||
FatalError(kFatalError_NetworkCodeSelfCheck);
|
||||
}
|
||||
SetInitialPosition(&gCurrent_race, i, grid_index);
|
||||
gNet_players[gCurrent_race.opponent_list[i].net_player_index].grid_index = grid_index;
|
||||
if (gInitialised_grid) {
|
||||
InitialiseCar2(gCurrent_race.opponent_list[i].car_spec, 0);
|
||||
} else {
|
||||
gCurrent_race.number_of_racers = i + 1;
|
||||
}
|
||||
gNet_players[gCurrent_race.opponent_list[i].net_player_index].grid_position_set = 1;
|
||||
}
|
||||
}
|
||||
gCurrent_race.number_of_racers = gNumber_of_net_players;
|
||||
gInitialised_grid = 1;
|
||||
ReenableNetService();
|
||||
}
|
||||
|
||||
// IDA: void __usercall ReinitialiseCar(tCar_spec *pCar@<EAX>)
|
||||
|
|
@ -185,7 +310,56 @@ void DoNetworkHeadups(int pCredits) {
|
|||
static tU32 last_flash;
|
||||
static int flash_state;
|
||||
LOG_TRACE("(%d)", pCredits);
|
||||
STUB_ONCE();
|
||||
|
||||
if (gNot_shown_race_type_headup) {
|
||||
gNot_shown_race_type_headup = 0;
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(59 + gCurrent_net_game->type));
|
||||
}
|
||||
if (gTime_for_punishment && gTime_for_punishment <= PDGetTotalTime()) {
|
||||
gTime_for_punishment = 0;
|
||||
switch (gCurrent_net_game->type) {
|
||||
case eNet_game_type_carnage:
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(219));
|
||||
break;
|
||||
case eNet_game_type_checkpoint:
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(220));
|
||||
break;
|
||||
case eNet_game_type_sudden_death:
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(221));
|
||||
break;
|
||||
case eNet_game_type_foxy:
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(222));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gNet_mode == eNet_mode_none || gNet_recovery_cost[gCurrent_net_game->type] <= gProgram_state.credits_earned - gProgram_state.credits_lost || Flash(200, &last_flash, &flash_state)) {
|
||||
sprintf(s, "\xf8%d\xfa %s", pCredits, GetMiscString(94));
|
||||
ChangeHeadupText(gNet_cash_headup, s);
|
||||
} else {
|
||||
ChangeHeadupText(gNet_cash_headup, "");
|
||||
}
|
||||
switch (gCurrent_net_game->type) {
|
||||
case eNet_game_type_carnage:
|
||||
sprintf(s, "%s \xf8%d\xfa", GetMiscString(180), gPed_target);
|
||||
break;
|
||||
case eNet_game_type_car_crusher:
|
||||
sprintf(s, "%s \xf8%d\xfa", GetMiscString(181), gCurrent_net_game->options.race_end_target);
|
||||
break;
|
||||
case eNet_game_type_foxy:
|
||||
TimerString(gCurrent_net_game->options.race_end_target, s2, 1, 1);
|
||||
sprintf(s, "%s \xf8%s\xfa", GetMiscString(182), s2);
|
||||
break;
|
||||
case eNet_game_type_tag:
|
||||
TimerString(gCurrent_net_game->options.race_end_target, s2, 1, 1);
|
||||
sprintf(s, "%s \xf8%s\xfa", GetMiscString(183), s2);
|
||||
break;
|
||||
default:
|
||||
s[0] = '\0';
|
||||
break;
|
||||
}
|
||||
ChangeHeadupText(gNet_ped_headup, s);
|
||||
}
|
||||
|
||||
// IDA: int __usercall SortNetHeadAscending@<EAX>(void *pFirst_one@<EAX>, void *pSecond_one@<EDX>)
|
||||
|
|
@ -234,13 +408,29 @@ void DoNetScores(void) {
|
|||
// IDA: void __cdecl InitNetHeadups()
|
||||
void InitNetHeadups(void) {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gIcons_pix = LoadPixelmap("CARICONS.PIX");
|
||||
if (gIcons_pix != NULL) {
|
||||
BrMapAdd(gIcons_pix);
|
||||
}
|
||||
gDigits_pix = LoadPixelmap("HDIGITS.PIX");
|
||||
if (gDigits_pix != NULL) {
|
||||
BrMapAdd(gDigits_pix);
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __cdecl DisposeNetHeadups()
|
||||
void DisposeNetHeadups(void) {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
if (gIcons_pix != NULL) {
|
||||
BrMapRemove(gIcons_pix);
|
||||
BrPixelmapFree(gIcons_pix);
|
||||
}
|
||||
if (gDigits_pix != NULL) {
|
||||
BrMapRemove(gDigits_pix);
|
||||
BrPixelmapFree(gDigits_pix);
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __cdecl EverybodysLost()
|
||||
|
|
@ -323,13 +513,26 @@ void SendPlayerScores(void) {
|
|||
tNet_contents* the_contents;
|
||||
int i;
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
the_contents = NetGetBroadcastContents(NETMSGID_SCORES, 0);
|
||||
if (gCurrent_net_game->type == eNet_game_type_carnage) {
|
||||
the_contents->data.scores.general_score = gPed_target;
|
||||
} else if (gCurrent_net_game->type == eNet_game_type_tag || gCurrent_net_game->type == eNet_game_type_foxy) {
|
||||
the_contents->data.scores.general_score = gNet_players[gIt_or_fox].ID;
|
||||
}
|
||||
for (i = 0; i < gNumber_of_net_players; i++) {
|
||||
the_contents->data.scores.scores[i] = gNet_players[i].score;
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __cdecl DoNetGameManagement()
|
||||
void DoNetGameManagement(void) {
|
||||
LOG_TRACE("()");
|
||||
STUB_ONCE();
|
||||
|
||||
if (gNet_mode == eNet_mode_host) {
|
||||
CalcPlayerScores();
|
||||
SendPlayerScores();
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall InitialisePlayerScore(tNet_game_player_info *pPlayer@<EAX>)
|
||||
|
|
@ -442,14 +645,24 @@ void UseGeneralScore(int pScore) {
|
|||
// IDA: void __usercall NetSendEnvironmentChanges(tNet_game_player_info *pPlayer@<EAX>)
|
||||
void NetSendEnvironmentChanges(tNet_game_player_info* pPlayer) {
|
||||
LOG_TRACE("(%p)", pPlayer);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
SendAllPedestrianPositions(pPlayer->ID);
|
||||
SendAllNonCarPositions();
|
||||
}
|
||||
|
||||
// IDA: void __cdecl UpdateEnvironments()
|
||||
void UpdateEnvironments(void) {
|
||||
int i;
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
for (i = 1; i < gNumber_of_net_players; i++) {
|
||||
if (!gNet_players[i].race_stuff_initialised) {
|
||||
NetSendEnvironmentChanges(&gNet_players[i]);
|
||||
gNet_players[i].race_stuff_initialised = 1;
|
||||
}
|
||||
NetSendMessageStacks();
|
||||
SendGameplay(gNet_players[i].ID, eNet_gameplay_go_for_it, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall ReceivedGameplay(tNet_contents *pContents@<EAX>, tNet_message *pMessage@<EDX>, tU32 pReceive_time@<EBX>)
|
||||
|
|
@ -467,7 +680,14 @@ void ReceivedGameplay(tNet_contents* pContents, tNet_message* pMessage, tU32 pRe
|
|||
void SendGameplay(tPlayer_ID pPlayer, tNet_gameplay_mess pMess, int pParam_1, int pParam_2, int pParam_3, int pParam_4) {
|
||||
tNet_message* the_message;
|
||||
LOG_TRACE("(%d, %d, %d, %d, %d, %d)", pPlayer, pMess, pParam_1, pParam_2, pParam_3, pParam_4);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
the_message = NetBuildMessage(NETMSGID_GAMEPLAY, 0);
|
||||
the_message->contents.data.gameplay.mess = pMess;
|
||||
the_message->contents.data.gameplay.param_1 = pParam_1;
|
||||
the_message->contents.data.gameplay.param_2 = pParam_2;
|
||||
the_message->contents.data.gameplay.param_3 = pParam_3;
|
||||
the_message->contents.data.gameplay.param_4 = pParam_4;
|
||||
NetGuaranteedSendMessageToPlayer(gCurrent_net_game, the_message, pPlayer, 0);
|
||||
}
|
||||
|
||||
// IDA: void __usercall SendGameplayToAllPlayers(tNet_gameplay_mess pMess@<EAX>, int pParam_1@<EDX>, int pParam_2@<EBX>, int pParam_3@<ECX>, int pParam_4)
|
||||
|
|
@ -475,7 +695,13 @@ void SendGameplayToAllPlayers(tNet_gameplay_mess pMess, int pParam_1, int pParam
|
|||
tNet_message* the_message;
|
||||
LOG_TRACE("(%d, %d, %d, %d, %d)", pMess, pParam_1, pParam_2, pParam_3, pParam_4);
|
||||
|
||||
STUB_ONCE();
|
||||
the_message = NetBuildMessage(NETMSGID_GAMEPLAY, 0);
|
||||
the_message->contents.data.gameplay.mess = pMess;
|
||||
the_message->contents.data.gameplay.param_1 = pParam_1;
|
||||
the_message->contents.data.gameplay.param_2 = pParam_2;
|
||||
the_message->contents.data.gameplay.param_3 = pParam_3;
|
||||
the_message->contents.data.gameplay.param_4 = pParam_4;
|
||||
NetGuaranteedSendMessageToAllPlayers(gCurrent_net_game, the_message, NULL);
|
||||
}
|
||||
|
||||
// IDA: void __usercall SendGameplayToHost(tNet_gameplay_mess pMess@<EAX>, int pParam_1@<EDX>, int pParam_2@<EBX>, int pParam_3@<ECX>, int pParam_4)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -17,7 +17,7 @@ extern tU32 gLast_flush_message;
|
|||
extern int gRace_only_flags[33];
|
||||
extern int gJoin_list_mode;
|
||||
extern tNet_game_player_info gNew_net_players[6];
|
||||
extern tGuaranteed_message gGuarantee_list[150];
|
||||
extern tGuaranteed_message gGuarantee_list[100];
|
||||
extern tMid_message* gMid_messages;
|
||||
extern tU32 gLast_player_list_received;
|
||||
extern tMin_message* gMin_messages;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1989,13 +1989,13 @@ void SendPedestrian(tPedestrian_data* pPedestrian, int pIndex) {
|
|||
size_decider = 1;
|
||||
}
|
||||
the_message = NULL;
|
||||
the_contents = NetGetBroadcastContents(0x19, size_decider);
|
||||
the_contents = NetGetBroadcastContents(NETMSGID_PEDESTRIAN, size_decider);
|
||||
} else {
|
||||
size_decider = 2;
|
||||
if (pPedestrian->current_frame == pPedestrian->sequences[pPedestrian->current_sequence].number_of_frames - 1) {
|
||||
pPedestrian->sent_dead_message++;
|
||||
}
|
||||
the_message = NetBuildMessage(0x19, size_decider);
|
||||
the_message = NetBuildMessage(NETMSGID_PEDESTRIAN, size_decider);
|
||||
the_contents = &the_message->contents;
|
||||
}
|
||||
the_contents->data.pedestrian.index = pIndex;
|
||||
|
|
|
|||
|
|
@ -294,6 +294,12 @@ void PratcamEvent(int pIndex) {
|
|||
if (gInterface_within_race_mode) {
|
||||
return;
|
||||
}
|
||||
#if defined(DETHRACE_FIX_BUGS)
|
||||
// In low memory mode, `gPratcam_sequences`is not allocated and thus unsafe to access
|
||||
if (gAusterity_mode) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (gPratcam_sequences[pIndex].precedence <= gCurrent_pratcam_precedence) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,9 +14,12 @@
|
|||
#include "input.h"
|
||||
#include "intrface.h"
|
||||
#include "loading.h"
|
||||
#include "netgame.h"
|
||||
#include "network.h"
|
||||
#include "newgame.h"
|
||||
#include "opponent.h"
|
||||
#include "pd/sys.h"
|
||||
#include "racestrt.h"
|
||||
#include "sound.h"
|
||||
#include "structur.h"
|
||||
#include "utility.h"
|
||||
|
|
@ -37,7 +40,7 @@ tParts_category gPart_category;
|
|||
tU32 gNet_synch_start;
|
||||
tNet_game_details* gChoose_car_net_game;
|
||||
int gPart_index;
|
||||
int gChallenger_index__racestrt; // suffix added to avoid duplicate symbol
|
||||
int gChallenger_index__racestrt; // suffix added to avoid duplicate symbol
|
||||
tGrid_draw gDraw_grid_status;
|
||||
tNet_sequence_type gNet_race_sequence__racestrt; // suffix added to avoid duplicate symbol
|
||||
br_pixelmap* gTaken_image;
|
||||
|
|
@ -2495,20 +2498,38 @@ void CheckPlayersAreResponding(void) {
|
|||
tU32 time;
|
||||
tNet_message* message;
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
time = PDGetTotalTime();
|
||||
for (i = 0; i < gNumber_of_net_players; i++) {
|
||||
if (i != gThis_net_player_index && time - gNet_players[i].last_heard_from_him > 20000) {
|
||||
gNet_players[i].player_status = ePlayer_status_not_responding;
|
||||
}
|
||||
}
|
||||
if (gNet_mode == eNet_mode_client && gLast_host_query == 0) {
|
||||
message = NetBuildMessage(NETMSGID_HOSTQUERY, 0);
|
||||
NetGuaranteedSendMessageToHost(gCurrent_net_game, message, NULL);
|
||||
gLast_host_query = time;
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __cdecl NetSynchStartStart()
|
||||
void NetSynchStartStart(void) {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
CheckPlayersAreResponding();
|
||||
}
|
||||
|
||||
// IDA: void __usercall DrawAnItem(int pX@<EAX>, int pY_index@<EDX>, int pFont_index@<EBX>, char *pText@<ECX>)
|
||||
// Suffix added to avoid duplicate symbol
|
||||
void DrawAnItem__racestrt(int pX, int pY_index, int pFont_index, char* pText) {
|
||||
LOG_TRACE("(%d, %d, %d, \"%s\")", pX, pY_index, pFont_index, pText);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
TransBrPixelmapText(gBack_screen,
|
||||
pX,
|
||||
gCurrent_graf_data->start_synch_top + gCurrent_graf_data->start_synch_y_pitch * pY_index,
|
||||
pFont_index,
|
||||
gFont_7,
|
||||
pText);
|
||||
}
|
||||
|
||||
// IDA: void __usercall NetSynchStartDraw(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>)
|
||||
|
|
@ -2517,51 +2538,272 @@ void NetSynchStartDraw(int pCurrent_choice, int pCurrent_mode) {
|
|||
int number_ready;
|
||||
char s[256];
|
||||
LOG_TRACE("(%d, %d)", pCurrent_choice, pCurrent_mode);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
number_ready = 0;
|
||||
CheckPlayersAreResponding();
|
||||
NetPlayerStatusChanged(ePlayer_status_ready);
|
||||
for (i = 0; i < COUNT_OF(gNet_players); i++) {
|
||||
BrPixelmapRectangleFill(gBack_screen,
|
||||
gCurrent_graf_data->start_synch_x_0,
|
||||
gCurrent_graf_data->start_synch_y_pitch * i + gCurrent_graf_data->start_synch_top,
|
||||
gCurrent_graf_data->start_synch_x_r - gCurrent_graf_data->start_synch_x_1,
|
||||
gFont_7->glyph_y,
|
||||
0);
|
||||
}
|
||||
for (i = 0; i < gNumber_of_net_players; i++) {
|
||||
strcpy(s, gNet_players[i].player_name);
|
||||
if (gNet_players[i].host) {
|
||||
strcat(s, " -");
|
||||
strcat(s, GetMiscString(88));
|
||||
strcat(s, "-");
|
||||
}
|
||||
TurnOffPaletteConversion();
|
||||
DRPixelmapRectangleMaskedCopy(gBack_screen,
|
||||
gCurrent_graf_data->start_synch_x_0,
|
||||
gCurrent_graf_data->start_synch_top + 1 + gCurrent_graf_data->start_synch_y_pitch * i,
|
||||
gIcons_pix,
|
||||
0,
|
||||
gNet_players[i].car_index * gCurrent_graf_data->net_head_icon_height,
|
||||
gIcons_pix->width,
|
||||
gCurrent_graf_data->net_head_icon_height);
|
||||
TurnOnPaletteConversion();
|
||||
DrawAnItem__racestrt(
|
||||
gCurrent_graf_data->start_synch_x_1,
|
||||
i,
|
||||
(gNet_players[i].player_status == ePlayer_status_ready) ? 66 : 4,
|
||||
s);
|
||||
DrawAnItem__racestrt(gCurrent_graf_data->start_synch_x_2,
|
||||
i,
|
||||
(gNet_players[i].player_status == ePlayer_status_ready) ? 83 : ((gNet_players[i].player_status == ePlayer_status_not_responding) ? 247 : 4),
|
||||
GetMiscString(77 + gNet_players[i].player_status));
|
||||
if (gNet_players[i].player_status == ePlayer_status_ready) {
|
||||
number_ready++;
|
||||
}
|
||||
}
|
||||
if (gNet_mode == eNet_mode_host && gNumber_of_net_players == number_ready && gNumber_of_net_players > 1 && (!gNo_races_yet || gNumber_of_net_players == 6)) {
|
||||
SignalToStartRace();
|
||||
gSynch_race_start = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: int __usercall NetSynchStartDone@<EAX>(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>, int pGo_ahead@<EBX>, int pEscaped@<ECX>, int pTimed_out)
|
||||
int NetSynchStartDone(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();
|
||||
|
||||
if (pEscaped) {
|
||||
pCurrent_choice = -1;
|
||||
} else if (pCurrent_choice == 0) {
|
||||
gProgram_state.prog_status = eProg_idling;
|
||||
}
|
||||
return pCurrent_choice;
|
||||
}
|
||||
|
||||
// IDA: int __usercall NetSynchStartGoAhead@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
|
||||
int NetSynchStartGoAhead(int* pCurrent_choice, int* pCurrent_mode) {
|
||||
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
if (*pCurrent_choice == 0 || (gNet_mode == eNet_mode_host && *pCurrent_choice >= 0)) {
|
||||
if (*pCurrent_choice == 0) {
|
||||
gProgram_state.prog_status = eProg_idling;
|
||||
return 1;
|
||||
} else if (gNet_mode == eNet_mode_host && *pCurrent_choice == 1) {
|
||||
if (gNumber_of_net_players <= 1) {
|
||||
DRS3StartSound(gEffects_outlet, 3100);
|
||||
return 0;
|
||||
} else {
|
||||
SignalToStartRace();
|
||||
gSynch_race_start = 1;
|
||||
gNo_races_yet = 0;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
DRS3StartSound(gEffects_outlet, 3100);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: int __usercall ExitWhenReady@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
|
||||
int ExitWhenReady(int* pCurrent_choice, int* pCurrent_mode) {
|
||||
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
if (!gSynch_race_start && gProgram_state.prog_status != eProg_game_starting) {
|
||||
if (gProgram_state.prog_status == eProg_idling) {
|
||||
*pCurrent_choice = 0;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
*pCurrent_choice = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: tSO_result __usercall NetSynchRaceStart2@<EAX>(tNet_synch_mode pMode@<EAX>)
|
||||
tSO_result NetSynchRaceStart2(tNet_synch_mode pMode) {
|
||||
static tFlicette flicker_on_hf[2];
|
||||
static tFlicette flicker_off_hf[2];
|
||||
static tFlicette push_hf[2];
|
||||
static tMouse_area mouse_areas_hf[2];
|
||||
static tInterface_spec interface_spec_hf;
|
||||
static tFlicette flicker_on_hs[1];
|
||||
static tFlicette flicker_off_hs[1];
|
||||
static tFlicette push_hs[1];
|
||||
static tMouse_area mouse_areas_hs[1];
|
||||
static tInterface_spec interface_spec_hs;
|
||||
static tFlicette flicker_on_c[1];
|
||||
static tFlicette flicker_off_c[1];
|
||||
static tFlicette push_c[1];
|
||||
static tMouse_area mouse_areas_c[1];
|
||||
static tInterface_spec interface_spec_c;
|
||||
static tFlicette flicker_on_hf[2] = {
|
||||
{ 321, { 219, 112 }, { 172, 362 } },
|
||||
{ 321, { 39, 480 }, { 172, 379 } },
|
||||
};
|
||||
static tFlicette flicker_off_hf[2] = {
|
||||
{ 322, { 219, 112 }, { 172, 362 } },
|
||||
{ 322, { 39, 480 }, { 172, 379 } },
|
||||
};
|
||||
static tFlicette push_hf[2] = {
|
||||
{ 206, { 219, 112 }, { 172, 362 } },
|
||||
{ 205, { 39, 480 }, { 172, 379 } },
|
||||
};
|
||||
static tMouse_area mouse_areas_hf[2] = {
|
||||
{ { 219, 480 }, { 172, 379 }, { 282, 182 }, { 192, 427 }, 0, 0, 0, NULL },
|
||||
{ { 39, 112 }, { 172, 362 }, { 102, 182 }, { 192, 379 }, 1, 0, 0, NULL },
|
||||
};
|
||||
static tInterface_spec interface_spec_hf = {
|
||||
0,
|
||||
203,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
8,
|
||||
{ -1, 0 },
|
||||
{ 1, 0 },
|
||||
{ 0, 0 },
|
||||
{ 1, 0 },
|
||||
{ NULL, NULL },
|
||||
{ -1, 0 },
|
||||
{ 1, 0 },
|
||||
{ 0, 0 },
|
||||
{ 1, 0 },
|
||||
{ NULL, NULL },
|
||||
{ -1, 0 },
|
||||
{ 1, 0 },
|
||||
{ 0, 0 },
|
||||
{ 1, 0 },
|
||||
{ NULL, NULL },
|
||||
{ -1, 0 },
|
||||
{ 1, 0 },
|
||||
{ 0, 0 },
|
||||
{ 1, 0 },
|
||||
{ NULL, NULL },
|
||||
{ 1, 1 },
|
||||
{ NetSynchStartGoAhead, NetSynchStartGoAhead },
|
||||
{ 1, 1 },
|
||||
{ NULL, NULL },
|
||||
ExitWhenReady,
|
||||
NetSynchStartDraw,
|
||||
0,
|
||||
NULL,
|
||||
NetSynchStartStart,
|
||||
NetSynchStartDone,
|
||||
0,
|
||||
{ 0, 0 },
|
||||
NULL,
|
||||
-1,
|
||||
1,
|
||||
COUNT_OF(flicker_on_hf),
|
||||
flicker_on_hf,
|
||||
flicker_off_hf,
|
||||
push_hf,
|
||||
COUNT_OF(mouse_areas_hf),
|
||||
mouse_areas_hf,
|
||||
0,
|
||||
NULL,
|
||||
};
|
||||
static tFlicette flicker_on_hs[1] = {
|
||||
{ 321, { 219, 112 }, { 172, 362 } },
|
||||
};
|
||||
static tFlicette flicker_off_hs[1] = {
|
||||
{ 322, { 219, 112 }, { 172, 362 } },
|
||||
};
|
||||
static tFlicette push_hs[1] = {
|
||||
{ 206, { 219, 112 }, { 172, 362 } },
|
||||
};
|
||||
static tMouse_area mouse_areas_hs[1] = {
|
||||
{ { 219, 480 }, { 172, 379 }, { 282, 182 }, { 192, 427 }, 0, 0, 0, NULL },
|
||||
};
|
||||
static tInterface_spec interface_spec_hs = {
|
||||
0, 209, 0, 0, 0, 0, 8,
|
||||
{ -1, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL },
|
||||
{ -1, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL },
|
||||
{ -1, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL },
|
||||
{ -1, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL },
|
||||
{ 1, 1 }, { NetSynchStartGoAhead, NetSynchStartGoAhead }, { 1, 1 }, { NULL, NULL },
|
||||
ExitWhenReady, NetSynchStartDraw, 0, NULL, NetSynchStartStart, NetSynchStartDone, 0, { 0, 0 },
|
||||
NULL, -1, 1,
|
||||
COUNT_OF(flicker_on_hs), flicker_on_hs, flicker_off_hs, push_hs,
|
||||
COUNT_OF(mouse_areas_hs), mouse_areas_hs, 0, NULL
|
||||
};
|
||||
static tFlicette flicker_on_c[1] = {
|
||||
{ 321, { 219, 112 }, { 172, 362 } },
|
||||
};
|
||||
static tFlicette flicker_off_c[1] = {
|
||||
{ 322, { 219, 112 }, { 172, 362 } },
|
||||
};
|
||||
static tFlicette push_c[1] = {
|
||||
{ 207, { 219, 112 }, { 172, 362 } },
|
||||
};
|
||||
static tMouse_area mouse_areas_c[1] = {
|
||||
{ { 219, 112 }, { 172, 362 }, { 282, 182 }, { 192, 379 }, 0, 0, 0, NULL },
|
||||
};
|
||||
static tInterface_spec interface_spec_c = {
|
||||
0, 204, 0, 0, 0, 0, 8,
|
||||
{ -1, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL },
|
||||
{ -1, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL },
|
||||
{ -1, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL },
|
||||
{ -1, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL },
|
||||
{ 1, 1 }, { NetSynchStartGoAhead, NetSynchStartGoAhead }, { 1, 1 }, { NULL, NULL },
|
||||
ExitWhenReady, NetSynchStartDraw, 0, NULL, NetSynchStartStart, NetSynchStartDone, 0, { 0, 0 },
|
||||
NULL, -1, 1,
|
||||
COUNT_OF(flicker_on_c), flicker_on_c, flicker_off_c, push_c,
|
||||
COUNT_OF(mouse_areas_c), mouse_areas_c, 0, NULL
|
||||
};
|
||||
int result;
|
||||
LOG_TRACE("(%d)", pMode);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
if (pMode != eNet_synch_client) {
|
||||
if (gCurrent_net_game->status.stage == eNet_game_starting) {
|
||||
gCurrent_net_game->status.stage = eNet_game_ready;
|
||||
}
|
||||
SetUpNetCarPositions();
|
||||
// gNet_synch_start = PDGetTotalTime();
|
||||
}
|
||||
TurnOnPaletteConversion();
|
||||
switch (pMode) {
|
||||
case eNet_synch_host_first:
|
||||
result = DoInterfaceScreen(&interface_spec_hf, 0, 1);
|
||||
break;
|
||||
case eNet_synch_host_subsequent:
|
||||
result = DoInterfaceScreen(&interface_spec_hs, 0, -1);
|
||||
break;
|
||||
case eNet_synch_client:
|
||||
result = DoInterfaceScreen(&interface_spec_c, 0, -1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
TurnOffPaletteConversion();
|
||||
FadePaletteDown();
|
||||
if (result > -2 && result < 1) {
|
||||
NetLeaveGame(gCurrent_net_game);
|
||||
}
|
||||
return eSO_continue;
|
||||
}
|
||||
|
||||
// IDA: tSO_result __cdecl NetSynchRaceStart()
|
||||
tSO_result NetSynchRaceStart(void) {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
SuspendPendingFlic();
|
||||
if (gNet_mode == eNet_mode_host) {
|
||||
if (gNo_races_yet) {
|
||||
return NetSynchRaceStart2(eNet_synch_host_first);
|
||||
} else {
|
||||
return NetSynchRaceStart2(eNet_synch_host_subsequent);
|
||||
}
|
||||
} else {
|
||||
return NetSynchRaceStart2(eNet_synch_client);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -395,7 +395,31 @@ int PickNetRace(int pCurrent_race, tNet_sequence_type pNet_race_sequence) {
|
|||
int most_seldom_seen;
|
||||
int races_to_pick_from[50];
|
||||
LOG_TRACE("(%d, %d)", pCurrent_race, pNet_race_sequence);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
if (pNet_race_sequence == eNet_sequence_sequential) {
|
||||
pCurrent_race++;
|
||||
if (pCurrent_race >= gNumber_of_races) {
|
||||
pCurrent_race = 0;
|
||||
}
|
||||
} else {
|
||||
most_seldom_seen = 10000;
|
||||
for (i = 0; i < gNumber_of_races; i++) {
|
||||
if (gRace_list[i].been_there_done_that < most_seldom_seen) {
|
||||
most_seldom_seen = gRace_list[i].been_there_done_that;
|
||||
}
|
||||
}
|
||||
races_count = 0;
|
||||
for (i = 0; i < gNumber_of_races; i++) {
|
||||
if (gRace_list[i].been_there_done_that == most_seldom_seen && (i != pCurrent_race)) {
|
||||
races_to_pick_from[races_count] = i;
|
||||
races_count++;
|
||||
}
|
||||
}
|
||||
new_index = IRandomBetween(0, races_count - 1);
|
||||
pCurrent_race = races_to_pick_from[new_index];
|
||||
gRace_list[pCurrent_race].been_there_done_that++;
|
||||
}
|
||||
return pCurrent_race;
|
||||
}
|
||||
|
||||
// IDA: void __cdecl SwapNetCarsLoad()
|
||||
|
|
@ -445,7 +469,7 @@ void DoGame(void) {
|
|||
StartLoadingScreen();
|
||||
gProgram_state.prog_status = eProg_game_ongoing;
|
||||
second_select_race = 0;
|
||||
if (gNet_mode_of_last_game == gNet_mode) {
|
||||
if (gNet_mode == gNet_mode_of_last_game) {
|
||||
PrintMemoryDump(0, "BEFORE START RACE SCREEN");
|
||||
SelectOpponents(&gCurrent_race);
|
||||
if (gNet_mode != eNet_mode_none) {
|
||||
|
|
|
|||
|
|
@ -479,7 +479,6 @@ br_uint_32 DRPixelmapLoadMany(char* pFile_name, br_pixelmap** pPixelmaps, br_uin
|
|||
int i;
|
||||
br_uint_8 lobyte;
|
||||
LOG_TRACE("(\"%s\", %p, %d)", pFile_name, pPixelmaps, pNum);
|
||||
|
||||
number_loaded = BrPixelmapLoadMany(pFile_name, pPixelmaps, pNum);
|
||||
for (i = 0; i < number_loaded; i++) {
|
||||
the_map = pPixelmaps[i];
|
||||
|
|
|
|||
|
|
@ -453,6 +453,42 @@ enum {
|
|||
kFatalError_RandomNumberOutOfRange_S = 116,
|
||||
};
|
||||
|
||||
enum {
|
||||
NETMSGID_SENDMEDETAILS = 0x00,
|
||||
NETMSGID_DETAILS = 0x01,
|
||||
NETMSGID_JOIN = 0x02,
|
||||
NETMSGID_NEWPLAYERLIST = 0x03,
|
||||
NETMSGID_GUARANTEEREPLY = 0x04,
|
||||
NETMSGID_CARDETAILSREQ = 0x05,
|
||||
NETMSGID_CARDETAILS = 0x06,
|
||||
NETMSGID_LEAVE = 0x07,
|
||||
NETMSGID_HOSTICIDE = 0x08,
|
||||
NETMSGID_RACEOVER = 0x09,
|
||||
NETMSGID_STATUSREPORT = 0x0a,
|
||||
NETMSGID_STARTRACE = 0x0b,
|
||||
NETMSGID_HEADUP = 0x0c,
|
||||
NETMSGID_HOSTQUERY = 0x0d,
|
||||
NETMSGID_HOSTREPLY = 0x0e,
|
||||
NETMSGID_MECHANICS = 0x0f,
|
||||
NETMSGID_NONCAR_INFO = 0x10,
|
||||
NETMSGID_TIMESYNC = 0x11,
|
||||
NETMSGID_CONFIRM = 0x12,
|
||||
NETMSGID_DISABLECAR = 0x13,
|
||||
NETMSGID_ENABLECAR = 0x14,
|
||||
NETMSGID_POWERUP = 0x15,
|
||||
NETMSGID_RECOVER = 0x16,
|
||||
NETMSGID_SCORES = 0x17,
|
||||
NETMSGID_WASTED = 0x18,
|
||||
NETMSGID_PEDESTRIAN = 0x19,
|
||||
NETMSGID_GAMEPLAY = 0x1a,
|
||||
NETMSGID_NONCARPOSITION = 0x1b,
|
||||
NETMSGID_COPINFO = 0x1c,
|
||||
NETMSGID_GAMESCORES = 0x1d,
|
||||
NETMSGID_OILSPILL = 0x1e,
|
||||
NETMSGID_CRUSHPOINT = 0x1f,
|
||||
NETMSGID_NONE = 0x20,
|
||||
};
|
||||
|
||||
#define FONT_TYPEABLE 0
|
||||
#define FONT_ORANGHED 1
|
||||
#define FONT_BLUEHEAD 2
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,10 +1,16 @@
|
|||
#include "pd/net.h"
|
||||
|
||||
#include "errors.h"
|
||||
#include "globvrpb.h"
|
||||
#include "harness/hooks.h"
|
||||
#include "harness/trace.h"
|
||||
#include "network.h"
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __DOS__
|
||||
|
||||
tU32 gNetwork_init_flags;
|
||||
tPD_net_game_info* gJoinable_games;
|
||||
int gMatts_PC;
|
||||
|
|
@ -26,9 +32,11 @@ tU8* gSend_packet_ptr;
|
|||
W32 gSend_segment;
|
||||
tU8* gListen_packet;
|
||||
tU8* gListen_packet_ptr;
|
||||
|
||||
size_t gMsg_header_strlen;
|
||||
int gNumber_of_networks;
|
||||
int gNumber_of_hosts;
|
||||
|
||||
tRM_info RMI;
|
||||
_IPX_HEADER gLast_received_IPX_header;
|
||||
tU16 gSocket_number_network_order;
|
||||
|
|
@ -42,7 +50,7 @@ tU16 gSend_selector;
|
|||
/*static*/ int GetSocketNumberFromProfileFile(void);
|
||||
/*static*/ tU32 EthernetAddressToU32(_IPX_LOCAL_TARGET* pAddr_ipx);
|
||||
/*static*/ void NetNowIPXLocalTarget2String(char* pString, _IPX_LOCAL_TARGET* pSock_addr_ipx);
|
||||
/*static*/ int GetMessageTypeFromMessage(char* pMessage_str) ;
|
||||
/*static*/ int GetMessageTypeFromMessage(char* pMessage_str);
|
||||
/*static*/ int SameEthernetAddress(_IPX_LOCAL_TARGET* pAddr_ipx1, _IPX_LOCAL_TARGET* pAddr_ipx2);
|
||||
/*static*/ _IPX_LOCAL_TARGET* GetIPXAddrFromPlayerID(tPlayer_ID pPlayer_id);
|
||||
/*static*/ void MakeMessageToSend(int pMessage_type);
|
||||
|
|
@ -297,6 +305,7 @@ int PDNetInitialise(void) {
|
|||
tU32 netnum;
|
||||
char str[256];
|
||||
int mess_num;
|
||||
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
|
@ -326,7 +335,7 @@ int PDNetGetNextJoinGame(tNet_game_details* pGame, int pIndex) {
|
|||
int j;
|
||||
int number_of_hosts_has_changed;
|
||||
char str[256];
|
||||
LOG_TRACE("(%p, %d)", pGame, pIndex);
|
||||
LOG_TRACE9("(%p, %d)", pGame, pIndex);
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
|
|
@ -374,35 +383,7 @@ tPlayer_ID PDNetExtractPlayerID(tNet_game_details* pDetails) {
|
|||
|
||||
// IDA: void __usercall PDNetObtainSystemUserName(char *pName@<EAX>, int pMax_length@<EDX>)
|
||||
void PDNetObtainSystemUserName(char* pName, int pMax_length) {
|
||||
#ifdef _WIN32
|
||||
uint32_t size;
|
||||
char buffer[16];
|
||||
int result;
|
||||
|
||||
#endif
|
||||
|
||||
dr_dprintf("PDNetObtainSystemUserName()\n");
|
||||
// todo
|
||||
#if 0
|
||||
size = COUNT_OF(buffer);
|
||||
result = GetComputerNameA(buffer, &size);
|
||||
if (result == 0) {
|
||||
LOG_WARN("GetComputerNameA failed with code=%u", GetLastError());
|
||||
buffer[0] = '\0';
|
||||
size = 0;
|
||||
}
|
||||
strncpy(pName, buffer, pMax_length - 1);
|
||||
pName[pMax_length - 1] = '\0';
|
||||
while (1) {
|
||||
pName = strpbrk(pName, "_=(){}[]<>!$%^&*/:@~;'#,?\\|`\"");
|
||||
if (pName == NULL || *pName == '\0') {
|
||||
break;
|
||||
}
|
||||
*pName = '-';
|
||||
}
|
||||
#else
|
||||
strcpy(pName, "Ron Turn");
|
||||
#endif
|
||||
}
|
||||
|
||||
// IDA: int __usercall PDNetSendMessageToPlayer@<EAX>(tNet_game_details *pDetails@<EAX>, tNet_message *pMessage@<EDX>, tPlayer_ID pPlayer@<EBX>)
|
||||
|
|
@ -417,6 +398,7 @@ int PDNetSendMessageToPlayer(tNet_game_details* pDetails, tNet_message* pMessage
|
|||
int PDNetSendMessageToAllPlayers(tNet_game_details* pDetails, tNet_message* pMessage) {
|
||||
char str[256];
|
||||
int i;
|
||||
int r; // Added by dethrace
|
||||
LOG_TRACE("(%p, %p)", pDetails, pMessage);
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
|
@ -472,3 +454,5 @@ int PDNetGetHeaderSize(void) {
|
|||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,193 @@
|
|||
#include "dr_types.h"
|
||||
|
||||
#ifdef __DOS__
|
||||
|
||||
typedef struct _tagIPX_HEADER {
|
||||
unsigned short wChecksum;
|
||||
unsigned short wLength;
|
||||
unsigned char bTransportControl;
|
||||
unsigned char bPacketType;
|
||||
unsigned char bDestNetworkNumber[4];
|
||||
unsigned char bDestNetworkNode[6];
|
||||
unsigned short wDestNetworkSocket;
|
||||
unsigned char bSourceNetworkNumber[4];
|
||||
unsigned char bSourceNetworkNode[6];
|
||||
unsigned short wSourceNetworkSocket;
|
||||
} _IPX_HEADER;
|
||||
|
||||
typedef struct _PACKET {
|
||||
char* pData;
|
||||
unsigned short wLength;
|
||||
} _PACKET;
|
||||
|
||||
typedef struct _REAL_PACKET {
|
||||
short wOffset;
|
||||
short wSegment;
|
||||
unsigned short wLength;
|
||||
} _REAL_PACKET;
|
||||
|
||||
typedef struct _ECB_PACKET {
|
||||
_PACKET sPacket;
|
||||
_REAL_PACKET sRealPacket;
|
||||
} _ECB_PACKET;
|
||||
|
||||
typedef struct _tagIPX_ECB {
|
||||
char* pLinkAddress;
|
||||
char* pESRRoutine;
|
||||
unsigned char bInUse;
|
||||
unsigned char bCompletionCode;
|
||||
unsigned short wSocket;
|
||||
unsigned short wConnectionID;
|
||||
unsigned short wWorkSpace;
|
||||
unsigned char bDriverWorkSpace[12];
|
||||
unsigned char bImmediateAddress[6];
|
||||
unsigned short wPacketCount;
|
||||
_ECB_PACKET sPacket[2];
|
||||
} _IPX_ECB;
|
||||
|
||||
typedef struct _tagIPX_INTERNET_ADDR {
|
||||
unsigned char bNetwork[4];
|
||||
unsigned char bNode[6];
|
||||
} _IPX_INTERNET_ADDR;
|
||||
|
||||
typedef struct _tagIPX_NETWORK_ADDR {
|
||||
_IPX_INTERNET_ADDR sInternetAddr;
|
||||
unsigned char bSocket[2];
|
||||
} _IPX_NETWORK_ADDR;
|
||||
|
||||
typedef struct _tagIPX_LOCAL_TARGET {
|
||||
_IPX_INTERNET_ADDR sInternetAddr;
|
||||
unsigned char bImmediate[6];
|
||||
} _IPX_LOCAL_TARGET;
|
||||
|
||||
typedef struct _tagIPX_ELEMENT {
|
||||
unsigned short wFlags;
|
||||
unsigned short wOffset;
|
||||
_IPX_HEADER sHeader;
|
||||
_IPX_ECB sECB;
|
||||
_IPX_ECB* pECB;
|
||||
_IPX_HEADER* pIPXHeader;
|
||||
char* pHeader;
|
||||
unsigned short wHSize;
|
||||
} _IPX_ELEMENT;
|
||||
|
||||
typedef struct _PROT_PTR {
|
||||
char* pData;
|
||||
} _PROT_PTR;
|
||||
|
||||
typedef struct _REAL_PTR {
|
||||
short wOffset;
|
||||
short wSegment;
|
||||
} _REAL_PTR;
|
||||
|
||||
typedef struct _PTR {
|
||||
_PROT_PTR sPointer;
|
||||
_REAL_PTR sRealPtr;
|
||||
} _PTR;
|
||||
|
||||
typedef struct _tag_NETBIOS_NCB {
|
||||
unsigned char bCommand;
|
||||
unsigned char bReturnCode;
|
||||
unsigned char bLocalSession;
|
||||
unsigned char bNetworkNameNumber;
|
||||
_PTR sPtr;
|
||||
unsigned short wLength;
|
||||
unsigned char bCallName[16];
|
||||
unsigned char bName[16];
|
||||
unsigned char bReceiveTimeOut;
|
||||
unsigned char bSendTimeOut;
|
||||
char* pPostFunction;
|
||||
unsigned char bAdapter;
|
||||
unsigned char bCompletionCode;
|
||||
unsigned char bReserve[14];
|
||||
} _NETBIOS_NCB;
|
||||
|
||||
typedef struct _tagNETBIOS_ADAPTER_STATUS {
|
||||
unsigned char bCardID[6];
|
||||
unsigned char bReleaseLevel;
|
||||
unsigned char bReserved1;
|
||||
unsigned char bTypeOfAdapter;
|
||||
unsigned char bOldOrNewParameters;
|
||||
unsigned short wReportingPeriodMinutes;
|
||||
unsigned short wFrameRejectReceivedCount;
|
||||
unsigned short wFrameRejectSentCount;
|
||||
unsigned short wReceivedDataFrameErrors;
|
||||
unsigned short wUnsuccessfulTransmissions;
|
||||
long dwGoodTransmissions;
|
||||
long dwGoodReceptions;
|
||||
unsigned short wRetransmissions;
|
||||
unsigned short wExhaustedResourceCount;
|
||||
unsigned short wT1TimerExpiredCount;
|
||||
unsigned short wTITimerExpiredCount;
|
||||
unsigned char bReserved2[4];
|
||||
unsigned short wAvailableNCBS;
|
||||
unsigned short wMaxNCBSConfigured;
|
||||
unsigned short wMaxNCBSPossible;
|
||||
unsigned short wBufferOrStationBusyCount;
|
||||
unsigned short wMaxDatagramSize;
|
||||
unsigned short wPendingSessions;
|
||||
unsigned short wMaxSessionsConfigured;
|
||||
unsigned short wMaxSessionsPossible;
|
||||
unsigned short wMaxFrameSize;
|
||||
unsigned short wNameCount;
|
||||
struct {
|
||||
unsigned char bName[16];
|
||||
unsigned char bNameNumber;
|
||||
unsigned char bNameStatus;
|
||||
} sNameTable[20];
|
||||
} _NETBIOS_ADAPTER_STATUS;
|
||||
|
||||
typedef struct _tagNETBIOS_ELEMENT {
|
||||
unsigned short wFlags;
|
||||
unsigned short wOffset;
|
||||
_NETBIOS_NCB sNCB;
|
||||
_NETBIOS_NCB* pNCB;
|
||||
char* pHeader;
|
||||
unsigned short wHSize;
|
||||
} _NETBIOS_ELEMENT;
|
||||
|
||||
typedef struct _tagNETBIOS_LOCAL_TARGET {
|
||||
unsigned char bNode[16];
|
||||
} _NETBIOS_LOCAL_TARGET;
|
||||
|
||||
typedef struct _tagXFER_BLOCK_HEADER {
|
||||
unsigned int wSequence;
|
||||
unsigned int wType;
|
||||
unsigned int wID;
|
||||
unsigned int wLength;
|
||||
unsigned int wNode;
|
||||
unsigned int wUser1;
|
||||
} _XFER_BLOCK_HEADER;
|
||||
|
||||
typedef struct _NETNOW_NODE_ADDR {
|
||||
_IPX_LOCAL_TARGET sIPX;
|
||||
_NETBIOS_LOCAL_TARGET sNETBIOS;
|
||||
} _NETNOW_NODE_ADDR;
|
||||
|
||||
typedef struct _tagRMI_REGS _RMI_REGS;
|
||||
typedef struct _tagBREGS _HMI_BREGS;
|
||||
typedef struct _tagWREGS _HMI_WREGS;
|
||||
typedef struct _tagDREGS _HMI_DREGS;
|
||||
typedef struct _tagSREGS _HMI_SREGS;
|
||||
typedef struct _tagIPX_HEADER _IPX_HEADER;
|
||||
typedef struct _tagIPX_ECB _IPX_ECB;
|
||||
typedef struct _tagIPX_INTERNET_ADDR _IPX_INTERNET_ADDR;
|
||||
typedef struct _tagIPX_NETWORK_ADDR _IPX_NETWORK_ADDR;
|
||||
typedef struct _tagIPX_LOCAL_TARGET _IPX_LOCAL_TARGET;
|
||||
typedef struct _tagIPX_ELEMENT _IPX_ELEMENT;
|
||||
typedef struct _tag_NETBIOS_NCB _NETBIOS_NCB;
|
||||
typedef struct _tagNETBIOS_ADAPTER_STATUS _NETBIOS_ADAPTER_STATUS;
|
||||
typedef struct _tagNETBIOS_ELEMENT _NETBIOS_ELEMENT;
|
||||
typedef struct _tagNETBIOS_LOCAL_TARGET _NETBIOS_LOCAL_TARGET;
|
||||
typedef struct _tagXFER_BLOCK_HEADER _XFER_BLOCK_HEADER;
|
||||
|
||||
typedef struct tPD_net_player_info {
|
||||
_IPX_LOCAL_TARGET addr_ipx;
|
||||
} tPD_net_player_info;
|
||||
|
||||
typedef struct tPD_net_game_info {
|
||||
_IPX_LOCAL_TARGET addr_ipx;
|
||||
tU32 last_response;
|
||||
} tPD_net_game_info;
|
||||
|
||||
#endif
|
||||
|
|
@ -137,13 +137,16 @@ void PDInitialiseSystem(void) {
|
|||
}
|
||||
|
||||
// IDA: void __cdecl PDShutdownSystem()
|
||||
void PDShutdownSystem(void) {
|
||||
void PDShutdownSystem() {
|
||||
static int been_here = 0; // Added by dethrace
|
||||
LOG_TRACE("()");
|
||||
|
||||
Harness_Hook_PDShutdownSystem();
|
||||
|
||||
CloseDiagnostics();
|
||||
exit(0);
|
||||
if (!been_here) {
|
||||
Harness_Hook_PDShutdownSystem();
|
||||
} else {
|
||||
LOG_WARN("recursion detected => force exit");
|
||||
exit(8);
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __cdecl PDSaveOriginalPalette()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,668 @@
|
|||
#include "pd/net.h"
|
||||
|
||||
#include "brender/brender.h"
|
||||
#include "dr_types.h"
|
||||
#include "errors.h"
|
||||
#include "globvrpb.h"
|
||||
#include "harness/config.h"
|
||||
#include "harness/hooks.h"
|
||||
#include "harness/trace.h"
|
||||
#include "harness/winsock.h"
|
||||
#include "network.h"
|
||||
#include "pd/net.h"
|
||||
#include "pd/sys.h"
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// dethrace: have switched out IPX implementation for IP
|
||||
|
||||
tU32 gNetwork_init_flags;
|
||||
tPD_net_game_info* gJoinable_games;
|
||||
int gMatts_PC;
|
||||
tU16 gSocket_number_pd_format;
|
||||
//_IPX_ELEMENT gListen_elements[16];
|
||||
char gLocal_ipx_addr_string[32];
|
||||
//_IPX_ELEMENT gSend_elements[16];
|
||||
struct sockaddr_in* gLocal_addr_ipx;
|
||||
char gReceive_buffer[512];
|
||||
tPD_net_player_info gRemote_net_player_info;
|
||||
struct sockaddr_in* gBroadcast_addr_ipx;
|
||||
tPD_net_player_info gLocal_net_player_info;
|
||||
char gSend_buffer[512];
|
||||
tIPX_netnum gNetworks[16];
|
||||
struct sockaddr_in* gRemote_addr_ipx;
|
||||
tU8* gSend_packet;
|
||||
// W32 gListen_segment;
|
||||
tU8* gSend_packet_ptr;
|
||||
// W32 gSend_segment;
|
||||
tU8* gListen_packet;
|
||||
tU8* gListen_packet_ptr;
|
||||
size_t gMsg_header_strlen;
|
||||
int gNumber_of_networks;
|
||||
int gNumber_of_hosts;
|
||||
//_IPX_HEADER gLast_received_IPX_header;
|
||||
tU16 gSocket_number_network_order;
|
||||
// unsigned short gECB_offset;
|
||||
tU16 gListen_selector;
|
||||
tU16 gSend_selector;
|
||||
|
||||
struct sockaddr_in gLocal_addr;
|
||||
struct sockaddr_in gRemote_addr;
|
||||
struct sockaddr_in gBroadcast_addr;
|
||||
struct sockaddr_in gLast_received_addr;
|
||||
int gSocket;
|
||||
|
||||
#define MESSAGE_HEADER_STR "CW95MSG"
|
||||
#define JOINABLE_GAMES_CAPACITY 16
|
||||
|
||||
// IDA: void __cdecl ClearupPDNetworkStuff()
|
||||
void ClearupPDNetworkStuff(void) {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
// IDA: void __usercall MATTMessageCheck(char *pFunction_name@<EAX>, tNet_message *pMessage@<EDX>, int pAlleged_size@<EBX>)
|
||||
void MATTMessageCheck(char* pFunction_name, tNet_message* pMessage, int pAlleged_size) {
|
||||
LOG_TRACE("(\"%s\", %p, %d)", pFunction_name, pMessage, pAlleged_size);
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
// IDA: int __usercall GetProfileText@<EAX>(char *pDest@<EAX>, int pDest_len@<EDX>, char *pFname@<EBX>, char *pKeyname@<ECX>)
|
||||
int GetProfileText(char* pDest, int pDest_len, char* pFname, char* pKeyname) {
|
||||
FILE* fp;
|
||||
char in_buf[256];
|
||||
int i;
|
||||
int j;
|
||||
int len;
|
||||
LOG_TRACE("(\"%s\", %d, \"%s\", \"%s\")", pDest, pDest_len, pFname, pKeyname);
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
// IDA: int __cdecl GetSocketNumberFromProfileFile()
|
||||
int GetSocketNumberFromProfileFile(void) {
|
||||
char str[256];
|
||||
int sscanf_res;
|
||||
tU32 socknum;
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
// tU32 EthernetAddressToU32(SOCKADDR_IPX_* pAddr_ipx) {
|
||||
// LOG_TRACE("(%p)", pAddr_ipx);
|
||||
// NOT_IMPLEMENTED();
|
||||
// }
|
||||
|
||||
void NetNowIPXLocalTarget2String(char* pString, struct sockaddr_in* pSock_addr_ipx) {
|
||||
LOG_TRACE("(\"%s\", %p)", pString, pSock_addr_ipx);
|
||||
|
||||
char portbuf[10];
|
||||
|
||||
inet_ntop(AF_INET, &pSock_addr_ipx->sin_addr, pString, 32);
|
||||
sprintf(portbuf, ":%d", ntohs(pSock_addr_ipx->sin_port));
|
||||
strcat(pString, portbuf);
|
||||
}
|
||||
|
||||
// IDA: int __usercall GetMessageTypeFromMessage@<EAX>(char *pMessage_str@<EAX>)
|
||||
int GetMessageTypeFromMessage(char* pMessage_str) {
|
||||
char* real_msg;
|
||||
int msg_type_int;
|
||||
LOG_TRACE("(\"%s\")", pMessage_str);
|
||||
|
||||
real_msg = &pMessage_str[4];
|
||||
msg_type_int = 0;
|
||||
|
||||
// FIXME: "CW95MSG" value is used in and depends on platform
|
||||
if (strncmp(real_msg, MESSAGE_HEADER_STR, gMsg_header_strlen) == 0) {
|
||||
if (isdigit(real_msg[gMsg_header_strlen])) {
|
||||
msg_type_int = real_msg[gMsg_header_strlen] - '0';
|
||||
}
|
||||
if (msg_type_int != 0 && msg_type_int < 3) {
|
||||
return msg_type_int;
|
||||
}
|
||||
}
|
||||
return 999;
|
||||
}
|
||||
|
||||
int SameEthernetAddress(struct sockaddr_in* pAddr_ipx1, struct sockaddr_in* pAddr_ipx2) {
|
||||
LOG_TRACE("(%p, %p)", pAddr_ipx1, pAddr_ipx2);
|
||||
|
||||
return memcmp(pAddr_ipx1, pAddr_ipx2, sizeof(struct sockaddr_in)) == 0;
|
||||
}
|
||||
|
||||
/*SOCKADDR_IPX_* */ void* GetIPXAddrFromPlayerID(tPlayer_ID pPlayer_id) {
|
||||
int i;
|
||||
tU8* nodenum;
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
// IDA: void __usercall MakeMessageToSend(int pMessage_type@<EAX>)
|
||||
void MakeMessageToSend(int pMessage_type) {
|
||||
LOG_TRACE("(%d)", pMessage_type);
|
||||
|
||||
#ifdef DETHRACE_FIX_BUGS
|
||||
sprintf(gSend_buffer, "XXXX%s%1d", MESSAGE_HEADER_STR, pMessage_type);
|
||||
#else
|
||||
sprintf(gSend_buffer, "XXXX%s%0.1d", MESSAGE_HEADER_STR, pMessage_type);
|
||||
#endif
|
||||
}
|
||||
|
||||
// IDA: int __cdecl ReceiveHostResponses()
|
||||
int ReceiveHostResponses(void) {
|
||||
char str[256];
|
||||
int i;
|
||||
int already_registered;
|
||||
LOG_TRACE("()");
|
||||
|
||||
char addr_string[32];
|
||||
unsigned int sa_len;
|
||||
int wsa_error;
|
||||
|
||||
sa_len = sizeof(gRemote_addr);
|
||||
while (1) {
|
||||
if (recvfrom(gSocket, gReceive_buffer, sizeof(gReceive_buffer), 0, (struct sockaddr*)&gRemote_addr, &sa_len) == -1) {
|
||||
break;
|
||||
}
|
||||
NetNowIPXLocalTarget2String(addr_string, gRemote_addr_ipx);
|
||||
dr_dprintf("ReceiveHostResponses(): Received string '%s' from %s", gReceive_buffer, addr_string);
|
||||
|
||||
if (SameEthernetAddress(gLocal_addr_ipx, gRemote_addr_ipx)) {
|
||||
dr_dprintf("*** Discounting the above 'cos we sent it ***");
|
||||
continue;
|
||||
}
|
||||
if (GetMessageTypeFromMessage(gReceive_buffer) != 2) {
|
||||
dr_dprintf("*** Discounting the above 'cos it's not a host reply ***");
|
||||
continue;
|
||||
}
|
||||
|
||||
dr_dprintf("*** It's a host reply! ***");
|
||||
already_registered = 0;
|
||||
for (i = 0; i < gNumber_of_hosts; i++) {
|
||||
if (SameEthernetAddress(&gJoinable_games[i].addr_in, gRemote_addr_ipx)) {
|
||||
already_registered = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (already_registered) {
|
||||
dr_dprintf("That game already registered");
|
||||
gJoinable_games[i].last_response = PDGetTotalTime();
|
||||
} else {
|
||||
dr_dprintf("Adding joinable game to slot #%d", gNumber_of_hosts);
|
||||
gJoinable_games[gNumber_of_hosts].addr_in = *gRemote_addr_ipx;
|
||||
gJoinable_games[gNumber_of_hosts].last_response = PDGetTotalTime();
|
||||
gNumber_of_hosts++;
|
||||
dr_dprintf("Number of games found so far: %d", gNumber_of_hosts);
|
||||
}
|
||||
if (gNumber_of_hosts) {
|
||||
dr_dprintf("Currently registered net games:");
|
||||
for (i = 0; i < gNumber_of_hosts; i++) {
|
||||
NetNowIPXLocalTarget2String(str, &gJoinable_games[i].addr_in);
|
||||
dr_dprintf("%d: Host addr %s", i, str);
|
||||
}
|
||||
}
|
||||
}
|
||||
wsa_error = WSAGetLastError() != WSAEWOULDBLOCK;
|
||||
if (wsa_error == 0) {
|
||||
return 1;
|
||||
}
|
||||
dr_dprintf("ReceiveHostResponses(): Error on recvfrom() - WSAGetLastError=%d", wsa_error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// IDA: int __cdecl BroadcastMessage()
|
||||
int BroadcastMessage(void) {
|
||||
int i;
|
||||
int errors;
|
||||
char broadcast_addr_string[32];
|
||||
char* real_msg;
|
||||
LOG_TRACE("()");
|
||||
|
||||
errors = 0;
|
||||
for (i = 0; i < gNumber_of_networks; i++) {
|
||||
//*(_DWORD*)gBroadcast_addr_ipx->sa_netnum = gNetworks[i];
|
||||
NetNowIPXLocalTarget2String(broadcast_addr_string, gBroadcast_addr_ipx);
|
||||
dr_dprintf("Broadcasting on address '%s'", broadcast_addr_string);
|
||||
if (sendto(gSocket, gSend_buffer, strlen(gSend_buffer) + 1, 0, (struct sockaddr*)&gBroadcast_addr, sizeof(gBroadcast_addr)) == -1) {
|
||||
dr_dprintf("BroadcastMessage(): Error on sendto() - WSAGetLastError=%d", WSAGetLastError());
|
||||
errors = 1;
|
||||
}
|
||||
}
|
||||
return errors == 0;
|
||||
}
|
||||
|
||||
// IDA: int __cdecl PDNetInitialise()
|
||||
int PDNetInitialise(void) {
|
||||
tU32 timenow;
|
||||
char profile_string[32];
|
||||
char key_name[32];
|
||||
int sscanf_res;
|
||||
int i;
|
||||
tU32 netnum;
|
||||
char str[256];
|
||||
int mess_num;
|
||||
|
||||
struct linger so_linger;
|
||||
unsigned int sa_len;
|
||||
WSADATA wsadata;
|
||||
LOG_TRACE("()");
|
||||
|
||||
sa_len = sizeof(struct sockaddr_in);
|
||||
dr_dprintf("PDNetInitialise()");
|
||||
int ipx_socket_num = 12286;
|
||||
// Dont bother to handle network.ini
|
||||
// if (gWin32_should_load_network_ini) {
|
||||
// if (GetPrivateProfileStringA(
|
||||
// "Network",
|
||||
// "IPXSocket",
|
||||
// Default,
|
||||
// (LPSTR)ReturnedString,
|
||||
// 0x20u,
|
||||
// gNetwork_profile_fname)) {
|
||||
// v11 = sscanf(ReturnedString, "%x", &v9);
|
||||
// if (v11) {
|
||||
// if (v11 != -1) {
|
||||
// dr_dprintf("New IPX socket %4.4x", v9);
|
||||
// ipx_socket_num = sub_454930(v9);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
gLocal_addr_ipx = &gLocal_addr;
|
||||
gRemote_addr_ipx = &gRemote_addr;
|
||||
gBroadcast_addr_ipx = &gBroadcast_addr;
|
||||
memset(&gLocal_addr, 0, sizeof(struct sockaddr_in));
|
||||
memset(&gRemote_addr, 0, sizeof(struct sockaddr_in));
|
||||
memset(&gBroadcast_addr, 0, sizeof(struct sockaddr_in));
|
||||
|
||||
// gLocal_addr_ipx->sa_family = AF_IPX;
|
||||
// gRemote_addr_ipx->sa_family = AF_IPX;
|
||||
// gBroadcast_addr_ipx->sa_family = AF_IPX;
|
||||
// gLocal_addr_ipx->sa_socket = ipx_socket_num;
|
||||
// gRemote_addr_ipx->sa_socket = ipx_socket_num;
|
||||
// gBroadcast_addr_ipx->sa_socket = ipx_socket_num;
|
||||
|
||||
// // IPX broadcast
|
||||
// gBroadcast_addr_ipx->sa_nodenum[0] = -1;
|
||||
// gBroadcast_addr_ipx->sa_nodenum[1] = -1;
|
||||
// gBroadcast_addr_ipx->sa_nodenum[2] = -1;
|
||||
// gBroadcast_addr_ipx->sa_nodenum[3] = -1;
|
||||
// gBroadcast_addr_ipx->sa_nodenum[4] = -1;
|
||||
// gBroadcast_addr_ipx->sa_nodenum[5] = -1;
|
||||
|
||||
gLocal_addr.sin_family = AF_INET;
|
||||
gLocal_addr.sin_port = htons(12286);
|
||||
gLocal_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
gRemote_addr.sin_family = AF_INET;
|
||||
gRemote_addr.sin_port = htons(12286);
|
||||
gBroadcast_addr.sin_family = AF_INET;
|
||||
gBroadcast_addr.sin_port = htons(12286);
|
||||
|
||||
// original code was using MAKEWORD(1, 1)
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsadata) == -1) {
|
||||
dr_dprintf("PDNetInitialise(): WSAStartup() failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// gSocket = socket(6, 2, 1000);
|
||||
gSocket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (gSocket == -1) {
|
||||
dr_dprintf("PDNetInitialise(): Failed to create socket - WSAGetLastError=%d", WSAGetLastError());
|
||||
WSACleanup();
|
||||
return -1;
|
||||
}
|
||||
int broadcast = 1;
|
||||
setsockopt(gSocket, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast));
|
||||
so_linger.l_onoff = 1;
|
||||
so_linger.l_linger = 0;
|
||||
setsockopt(gSocket, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger));
|
||||
|
||||
unsigned long nobio = 1;
|
||||
if (ioctlsocket(gSocket, FIONBIO, &nobio) == -1) {
|
||||
dr_dprintf("Error on ioctlsocket() - WSAGetLastError=%d", WSAGetLastError());
|
||||
closesocket(gSocket);
|
||||
WSACleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (harness_game_config.no_bind == 0) {
|
||||
if (bind(gSocket, (struct sockaddr*)&gLocal_addr, sizeof(gLocal_addr)) == -1) {
|
||||
dr_dprintf("Error on bind() - WSAGetLastError=%d", WSAGetLastError());
|
||||
closesocket(gSocket);
|
||||
WSACleanup();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int res = getsockname(gSocket, (struct sockaddr*)&gLocal_addr, &sa_len);
|
||||
NetNowIPXLocalTarget2String(gLocal_ipx_addr_string, gLocal_addr_ipx);
|
||||
// gNetworks[0] = *(tIPX_netnum*)gLocal_addr_ipx->sa_netnum;
|
||||
gNumber_of_networks = 1;
|
||||
|
||||
// if (gWin32_should_load_network_ini) {
|
||||
// for (i = 1; i <= 15; ++i) {
|
||||
// sprintf(KeyName, "%s%d", "Network", i);
|
||||
// if (GetPrivateProfileStringA(
|
||||
// "Network",
|
||||
// KeyName,
|
||||
// Default,
|
||||
// (LPSTR)ReturnedString,
|
||||
// 0x20u,
|
||||
// gNetwork_profile_fname)) {
|
||||
// v11 = sscanf(ReturnedString, "%x", &network_nbr);
|
||||
// if (v11) {
|
||||
// if (v11 != -1) {
|
||||
// dr_dprintf("Found network number '%x' in INI file", network_nbr);
|
||||
// gNetworks[gNumber_of_networks].bNetwork[0] = HIBYTE(network_nbr);
|
||||
// gNetworks[gNumber_of_networks].bNetwork[1] = (network_nbr & 0xFF0000u) >> 16;
|
||||
// gNetworks[gNumber_of_networks].bNetwork[2] = BYTE1(network_nbr);
|
||||
// gNetworks[gNumber_of_networks].bNetwork[3] = network_nbr;
|
||||
// if (gNetworks[gNumber_of_networks].bNetwork[0] != gLocal_addr_ipx->sa_netnum[0]
|
||||
// || gNetworks[gNumber_of_networks].bNetwork[1] != gLocal_addr_ipx->sa_netnum[1]
|
||||
// || gNetworks[gNumber_of_networks].bNetwork[2] != gLocal_addr_ipx->sa_netnum[2]
|
||||
// || gNetworks[gNumber_of_networks].bNetwork[3] != gLocal_addr_ipx->sa_netnum[3]) {
|
||||
// ++gNumber_of_networks;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// dr_dprintf("Total networks = %d", gNumber_of_networks);
|
||||
// }
|
||||
// byte_536440 = *gLocal_addr_ipx;
|
||||
|
||||
dr_dprintf("Socket bound OK; local address is '%s'", gLocal_ipx_addr_string);
|
||||
gMsg_header_strlen = 7;
|
||||
if (strstr(gLocal_ipx_addr_string, "00a0240f9fac")) {
|
||||
gMatts_PC = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// IDA: int __cdecl PDNetShutdown()
|
||||
int PDNetShutdown(void) {
|
||||
LOG_TRACE("()");
|
||||
|
||||
dr_dprintf("PDNetShutdown()");
|
||||
if (gSocket != -1) {
|
||||
closesocket(gSocket);
|
||||
}
|
||||
gSocket = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// IDA: void __cdecl PDNetStartProducingJoinList()
|
||||
void PDNetStartProducingJoinList(void) {
|
||||
LOG_TRACE("()");
|
||||
|
||||
dr_dprintf("PDNetStartProducingJoinList()");
|
||||
gNumber_of_hosts = 0;
|
||||
gJoinable_games = BrMemAllocate(sizeof(tPD_net_game_info) * JOINABLE_GAMES_CAPACITY, 0x80u);
|
||||
if (gJoinable_games == NULL) {
|
||||
PDFatalError("Can't allocate memory for joinable games");
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __cdecl PDNetEndJoinList()
|
||||
void PDNetEndJoinList(void) {
|
||||
LOG_TRACE("()");
|
||||
|
||||
dr_dprintf("PDNetEndJoinList()");
|
||||
if (gJoinable_games) {
|
||||
BrMemFree(gJoinable_games);
|
||||
}
|
||||
gJoinable_games = NULL;
|
||||
}
|
||||
|
||||
// IDA: int __usercall PDNetGetNextJoinGame@<EAX>(tNet_game_details *pGame@<EAX>, int pIndex@<EDX>)
|
||||
int PDNetGetNextJoinGame(tNet_game_details* pGame, int pIndex) {
|
||||
static tU32 next_broadcast_time = 0;
|
||||
int i;
|
||||
int j;
|
||||
int number_of_hosts_has_changed;
|
||||
char str[256];
|
||||
LOG_TRACE9("(%p, %d)", pGame, pIndex);
|
||||
|
||||
dr_dprintf("PDNetGetNextJoinGame(): pIndex is %d", pIndex);
|
||||
if (pIndex == 0) {
|
||||
do {
|
||||
number_of_hosts_has_changed = 0;
|
||||
for (i = 0; i < gNumber_of_hosts; i++) {
|
||||
if (gJoinable_games[i].last_response + 10000 < PDGetTotalTime()) {
|
||||
number_of_hosts_has_changed = 1;
|
||||
for (j = i; j < gNumber_of_hosts - 1; j++) {
|
||||
memcpy(&gJoinable_games[j], &gJoinable_games[j + 1], sizeof(tPD_net_game_info));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (number_of_hosts_has_changed) {
|
||||
gNumber_of_hosts--;
|
||||
}
|
||||
} while (number_of_hosts_has_changed);
|
||||
if (PDGetTotalTime() > next_broadcast_time) {
|
||||
next_broadcast_time = PDGetTotalTime() + 3000;
|
||||
MakeMessageToSend(1);
|
||||
if (BroadcastMessage() == 0) {
|
||||
dr_dprintf("PDNetGetNextJoinGame(): Error on BroadcastMessage()");
|
||||
}
|
||||
}
|
||||
}
|
||||
ReceiveHostResponses();
|
||||
if (gNumber_of_hosts <= pIndex) {
|
||||
return 0;
|
||||
}
|
||||
dr_dprintf("PDNetGetNextJoinGame(): Adding game.");
|
||||
memcpy(&pGame->pd_net_info.addr_in, &gJoinable_games[pIndex].addr_in, sizeof(pGame->pd_net_info.addr_in));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// IDA: void __usercall PDNetDisposeGameDetails(tNet_game_details *pDetails@<EAX>)
|
||||
void PDNetDisposeGameDetails(tNet_game_details* pDetails) {
|
||||
LOG_TRACE("(%p)", pDetails);
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
// IDA: int __usercall PDNetHostGame@<EAX>(tNet_game_details *pDetails@<EAX>, char *pHost_name@<EDX>, void **pHost_address@<EBX>)
|
||||
int PDNetHostGame(tNet_game_details* pDetails, char* pHost_name, void** pHost_address) {
|
||||
LOG_TRACE("(%p, \"%s\", %p)", pDetails, pHost_name, pHost_address);
|
||||
|
||||
dr_dprintf("PDNetHostGame()");
|
||||
*pHost_address = &gLocal_addr;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// IDA: int __usercall PDNetJoinGame@<EAX>(tNet_game_details *pDetails@<EAX>, char *pPlayer_name@<EDX>)
|
||||
int PDNetJoinGame(tNet_game_details* pDetails, char* pPlayer_name) {
|
||||
LOG_TRACE("(%p, \"%s\")", pDetails, pPlayer_name);
|
||||
|
||||
dr_dprintf("PDNetJoinGame()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// IDA: void __usercall PDNetLeaveGame(tNet_game_details *pDetails@<EAX>)
|
||||
void PDNetLeaveGame(tNet_game_details* pDetails) {
|
||||
LOG_TRACE("(%p)", pDetails);
|
||||
|
||||
dr_dprintf("PDNetLeaveGame()");
|
||||
}
|
||||
|
||||
// IDA: void __usercall PDNetHostFinishGame(tNet_game_details *pDetails@<EAX>)
|
||||
void PDNetHostFinishGame(tNet_game_details* pDetails) {
|
||||
LOG_TRACE("(%p)", pDetails);
|
||||
|
||||
dr_dprintf("PDNetHostFinishGame()");
|
||||
}
|
||||
|
||||
// IDA: tU32 __usercall PDNetExtractGameID@<EAX>(tNet_game_details *pDetails@<EAX>)
|
||||
tU32 PDNetExtractGameID(tNet_game_details* pDetails) {
|
||||
LOG_TRACE("(%p)", pDetails);
|
||||
|
||||
dr_dprintf("PDNetExtractGameID()");
|
||||
return ntohs(pDetails->pd_net_info.addr_in.sin_port); // PDGetTotalTime();
|
||||
}
|
||||
|
||||
// IDA: tPlayer_ID __usercall PDNetExtractPlayerID@<EAX>(tNet_game_details *pDetails@<EAX>)
|
||||
tPlayer_ID PDNetExtractPlayerID(tNet_game_details* pDetails) {
|
||||
LOG_TRACE("(%p)", pDetails);
|
||||
|
||||
dr_dprintf("PDNetExtractPlayerID()");
|
||||
return ntohs(gLocal_addr_ipx->sin_port);
|
||||
}
|
||||
|
||||
// IDA: void __usercall PDNetObtainSystemUserName(char *pName@<EAX>, int pMax_length@<EDX>)
|
||||
void PDNetObtainSystemUserName(char* pName, int pMax_length) {
|
||||
int result;
|
||||
char* found;
|
||||
dr_dprintf("PDNetObtainSystemUserName()");
|
||||
|
||||
result = gethostname(pName, pMax_length);
|
||||
if (result == 0) {
|
||||
}
|
||||
|
||||
while (1) {
|
||||
found = strpbrk(pName, "_=(){}[]<>!$%^&*/:@~;'#,?\\|`\"");
|
||||
if (found == NULL) {
|
||||
break;
|
||||
}
|
||||
*found = '-';
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: int __usercall PDNetSendMessageToPlayer@<EAX>(tNet_game_details *pDetails@<EAX>, tNet_message *pMessage@<EDX>, tPlayer_ID pPlayer@<EBX>)
|
||||
int PDNetSendMessageToPlayer(tNet_game_details* pDetails, tNet_message* pMessage, tPlayer_ID pPlayer) {
|
||||
char str[256];
|
||||
// SOCKADDR_IPX_* remote_addr_ipx;
|
||||
LOG_TRACE("(%p, %p, %d)", pDetails, pMessage, pPlayer);
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
// IDA: int __usercall PDNetSendMessageToAllPlayers@<EAX>(tNet_game_details *pDetails@<EAX>, tNet_message *pMessage@<EDX>)
|
||||
int PDNetSendMessageToAllPlayers(tNet_game_details* pDetails, tNet_message* pMessage) {
|
||||
char str[256];
|
||||
int i;
|
||||
LOG_TRACE("(%p, %p)", pDetails, pMessage);
|
||||
|
||||
for (i = 0; i < gNumber_of_net_players; ++i) {
|
||||
if (i == gThis_net_player_index) {
|
||||
continue;
|
||||
}
|
||||
if (sendto(gSocket, (const char*)pMessage, pMessage->overall_size, 0, (struct sockaddr*)&gNet_players[i].pd_net_info.addr_in, sizeof(gNet_players[i].pd_net_info.addr_in)) == -1) {
|
||||
dr_dprintf("PDNetSendMessageToAllPlayers(): Error on sendto() - WSAGetLastError=%d", WSAGetLastError());
|
||||
NetDisposeMessage(pDetails, pMessage);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
NetDisposeMessage(pDetails, pMessage);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// IDA: tNet_message* __usercall PDNetGetNextMessage@<EAX>(tNet_game_details *pDetails@<EAX>, void **pSender_address@<EDX>)
|
||||
tNet_message* PDNetGetNextMessage(tNet_game_details* pDetails, void** pSender_address) {
|
||||
char* receive_buffer;
|
||||
char str[256];
|
||||
int msg_type;
|
||||
LOG_TRACE("(%p, %p)", pDetails, pSender_address);
|
||||
|
||||
char addr_str[32];
|
||||
unsigned int sa_len;
|
||||
int res;
|
||||
tNet_message* msg;
|
||||
|
||||
sa_len = sizeof(gRemote_addr);
|
||||
msg = NetAllocateMessage(512);
|
||||
receive_buffer = (char*)msg;
|
||||
res = recvfrom(gSocket, receive_buffer, 512, 0, (struct sockaddr*)&gRemote_addr, &sa_len);
|
||||
res = res != -1;
|
||||
if (res == 0) {
|
||||
res = WSAGetLastError() != WSAEWOULDBLOCK;
|
||||
if (res) {
|
||||
sprintf(str, "PDNetGetNextMessage(): Error on recvfrom() - WSAGetLastError=%d", res);
|
||||
PDFatalError(str);
|
||||
}
|
||||
} else {
|
||||
NetNowIPXLocalTarget2String(addr_str, gRemote_addr_ipx);
|
||||
if (!SameEthernetAddress(gLocal_addr_ipx, gRemote_addr_ipx)) {
|
||||
msg_type = GetMessageTypeFromMessage(receive_buffer);
|
||||
switch (msg_type) {
|
||||
case 1:
|
||||
if (gNet_mode == eNet_mode_host) {
|
||||
dr_dprintf("PDNetGetNextMessage(): Received '%s' from '%s', replying to joiner", receive_buffer, addr_str);
|
||||
MakeMessageToSend(2);
|
||||
if (sendto(gSocket, gSend_buffer, strlen(gSend_buffer) + 1, 0, (struct sockaddr*)&gRemote_addr, sizeof(gRemote_addr)) == -1) {
|
||||
dr_dprintf("PDNetGetNextMessage(): Error on sendto() - WSAGetLastError=%d", WSAGetLastError());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
// no-op
|
||||
break;
|
||||
default:
|
||||
dr_dprintf("PDNetGetNextMessage(): res is %d, received message type %d from '%s', passing up", res, msg->contents.header.type, addr_str);
|
||||
memcpy(&gLast_received_addr, gRemote_addr_ipx, sizeof(gLast_received_addr));
|
||||
*pSender_address = &gLast_received_addr;
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
msg->guarantee_number = 0;
|
||||
NetDisposeMessage(pDetails, msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// IDA: tNet_message* __usercall PDNetAllocateMessage@<EAX>(tU32 pSize@<EAX>, tS32 pSize_decider@<EDX>)
|
||||
tNet_message* PDNetAllocateMessage(tU32 pSize, tS32 pSize_decider) {
|
||||
LOG_TRACE("(%d, %d)", pSize, pSize_decider);
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
// IDA: void __usercall PDNetDisposeMessage(tNet_game_details *pDetails@<EAX>, tNet_message *pMessage@<EDX>)
|
||||
void PDNetDisposeMessage(tNet_game_details* pDetails, tNet_message* pMessage) {
|
||||
LOG_TRACE("(%p, %p)", pDetails, pMessage);
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
// IDA: void __usercall PDNetSetPlayerSystemInfo(tNet_game_player_info *pPlayer@<EAX>, void *pSender_address@<EDX>)
|
||||
void PDNetSetPlayerSystemInfo(tNet_game_player_info* pPlayer, void* pSender_address) {
|
||||
LOG_TRACE("(%p, %p)", pPlayer, pSender_address);
|
||||
|
||||
dr_dprintf("PDNetSetPlayerSystemInfo()");
|
||||
memcpy(&pPlayer->pd_net_info, pSender_address, sizeof(pPlayer->pd_net_info));
|
||||
}
|
||||
|
||||
// IDA: void __usercall PDNetDisposePlayer(tNet_game_player_info *pPlayer@<EAX>)
|
||||
void PDNetDisposePlayer(tNet_game_player_info* pPlayer) {
|
||||
LOG_TRACE("(%p)", pPlayer);
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
// IDA: int __usercall PDNetSendMessageToAddress@<EAX>(tNet_game_details *pDetails@<EAX>, tNet_message *pMessage@<EDX>, void *pAddress@<EBX>)
|
||||
int PDNetSendMessageToAddress(tNet_game_details* pDetails, tNet_message* pMessage, void* pAddress) {
|
||||
char str[256];
|
||||
LOG_TRACE("(%p, %p, %p)", pDetails, pMessage, pAddress);
|
||||
|
||||
NetNowIPXLocalTarget2String(str, (struct sockaddr_in*)pAddress);
|
||||
if (pDetails->pd_net_info.addr_in.sin_port == 0) {
|
||||
int i = 0;
|
||||
}
|
||||
|
||||
if (sendto(gSocket, (const char*)pMessage, pMessage->overall_size, 0, (const struct sockaddr*)pAddress, sizeof(struct sockaddr)) == -1) {
|
||||
dr_dprintf("PDNetSendMessageToAddress(): Error on sendto() - WSAGetLastError=%d", WSAGetLastError());
|
||||
NetDisposeMessage(pDetails, pMessage);
|
||||
return 1;
|
||||
}
|
||||
|
||||
NetDisposeMessage(pDetails, pMessage);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// IDA: int __usercall PDNetInitClient@<EAX>(tNet_game_details *pDetails@<EAX>)
|
||||
int PDNetInitClient(tNet_game_details* pDetails) {
|
||||
LOG_TRACE("(%p)", pDetails);
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
// IDA: int __cdecl PDNetGetHeaderSize()
|
||||
int PDNetGetHeaderSize(void) {
|
||||
LOG_TRACE("()");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef WIN95_NET_TYPES_H
|
||||
#define WIN95_NET_TYPES_H
|
||||
|
||||
// #include "dr_types.h"
|
||||
#include "harness/win95_polyfill.h"
|
||||
#include "harness/winsock.h"
|
||||
|
||||
// dethrace: have switched out IPX implementation for IP
|
||||
|
||||
typedef struct tPD_net_player_info {
|
||||
// struct sockaddr_ipx addr_ipx;
|
||||
struct sockaddr_in addr_in;
|
||||
} tPD_net_player_info;
|
||||
|
||||
typedef struct tPD_net_game_info {
|
||||
// struct sockaddr_ipx addr_ipx;
|
||||
struct sockaddr_in addr_in;
|
||||
tU32 last_response;
|
||||
} tPD_net_game_info;
|
||||
|
||||
// typedef struct tIPX_netnum {
|
||||
// unsigned char bNetwork[4];
|
||||
// } tIPX_netnum;
|
||||
|
||||
#endif
|
||||
|
|
@ -10,59 +10,17 @@
|
|||
#include "brender/br_types.h"
|
||||
#include "dr_types.h"
|
||||
|
||||
// void ClearupPDNetworkStuff(void);
|
||||
void ClearupPDNetworkStuff(void);
|
||||
|
||||
// void MATTMessageCheck(char* pFunction_name, tNet_message* pMessage, int pAlleged_size);
|
||||
void MATTMessageCheck(char* pFunction_name, tNet_message* pMessage, int pAlleged_size);
|
||||
|
||||
// int GetProfileText(char* pDest, int pDest_len, char* pFname, char* pKeyname);
|
||||
int GetMessageTypeFromMessage(char* pMessage_str);
|
||||
|
||||
// int GetSocketNumberFromProfileFile(void);
|
||||
void MakeMessageToSend(int pMessage_type);
|
||||
|
||||
// tU32 EthernetAddressToU32(_IPX_LOCAL_TARGET* pAddr_ipx);
|
||||
int ReceiveHostResponses(void);
|
||||
|
||||
// void NetNowIPXLocalTarget2String(char* pString, _IPX_LOCAL_TARGET* pSock_addr_ipx);
|
||||
|
||||
// int GetMessageTypeFromMessage(char* pMessage_str);
|
||||
|
||||
// int SameEthernetAddress(_IPX_LOCAL_TARGET* pAddr_ipx1, _IPX_LOCAL_TARGET* pAddr_ipx2);
|
||||
|
||||
// _IPX_LOCAL_TARGET* GetIPXAddrFromPlayerID(tPlayer_ID pPlayer_id);
|
||||
|
||||
// void MakeMessageToSend(int pMessage_type);
|
||||
|
||||
// int ReceiveHostResponses(void);
|
||||
|
||||
// int BroadcastMessage(void);
|
||||
|
||||
// int hmiIPXCloseSocket(W32 wSocket);
|
||||
|
||||
// void hmiIPXListenForPacket(_IPX_ECB* pECB_ptr, tU32 pOffset);
|
||||
|
||||
// int hmiIPXPostListen(_IPX_ECB* pECB_ptr, tU32 pOffset);
|
||||
|
||||
// int hmiIPXGetData(PSTR pData, tU32 wDSize);
|
||||
|
||||
// void hmiIPXSendPacket(_IPX_ECB* sECB, _IPX_ECB** pPacket, PSTR pHeader, W32 wSize);
|
||||
|
||||
// int hmiIPXSendDataDirect(PSTR pHeader, W32 wHSize, PSTR pData, W32 wDSize, _NETNOW_NODE_ADDR* sNode);
|
||||
|
||||
// void hmiIPXGetInternetworkAddr(_IPX_INTERNET_ADDR* sInterworkAddr);
|
||||
|
||||
// void hmiIPXGetLocalTarget(_IPX_LOCAL_TARGET* sNetworkAddr);
|
||||
|
||||
// int AllocateRealMem(W32 wSize, PSTR* pPtr, W32* pSegment, tU16* pSelector);
|
||||
|
||||
// int FreeRealMem(tU16 pSelector);
|
||||
|
||||
// int hmiIPXInstalled(void);
|
||||
|
||||
// int hmiIPXOpenSocket(W32 wSocket);
|
||||
|
||||
// void GetLargestPacketSizeOoErBetterInsertLinfordChristieJokeHere(void);
|
||||
|
||||
// int hmiIPXInitSystem(W32 wSocket);
|
||||
|
||||
// void GetIPXToStickItsEarToTheGround(void);
|
||||
int BroadcastMessage(void);
|
||||
|
||||
int PDNetInitialise(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,187 @@
|
|||
typedef unsigned int W32;
|
||||
|
||||
typedef struct _tag_sos_evds_struct _SOS_EVDS_STRUCT;
|
||||
typedef struct _tag_sos_vds_struct _SOS_VDS_STRUCT;
|
||||
typedef struct _tag_sos_sample _SOS_SAMPLE;
|
||||
typedef _SOS_SAMPLE* PSOSSAMPLE;
|
||||
typedef struct _tagCAPABILITIES _SOS_CAPABILITIES;
|
||||
typedef _SOS_CAPABILITIES* PSOSCAPABILITIES;
|
||||
typedef struct _SOS_HARDWARE* PSOSHARDWARE;
|
||||
typedef struct _tag_sos_driver _SOS_DIGI_DRIVER;
|
||||
typedef _SOS_DIGI_DRIVER* PSOSDIGIDRIVER;
|
||||
typedef struct _SOS_DRV_FILEHEADER* PSOSDRVFILEHEADER;
|
||||
typedef struct _SOS_DRV_DRIVERHEADER* PSOSDRVDRIVERHEADER;
|
||||
typedef struct _tag_sos_system _SOS_SYSTEM;
|
||||
typedef _SOS_SYSTEM* PSOSSYSTEM;
|
||||
typedef struct _tag_sos_det_system _SOS_DET_SYSTEM;
|
||||
typedef _SOS_DET_SYSTEM* PSOSDETSYSTEM;
|
||||
typedef struct _tag_sos_timer_system _SOS_TIMER_SYSTEM;
|
||||
typedef _SOS_TIMER_SYSTEM* PSOSTIMERSYSTEM;
|
||||
|
||||
typedef struct _tag_sos_evds_struct {
|
||||
unsigned int region_size;
|
||||
unsigned int offset;
|
||||
unsigned int segment;
|
||||
unsigned short number_available;
|
||||
unsigned short number_used;
|
||||
unsigned int page0;
|
||||
} _SOS_EVDS_STRUCT;
|
||||
|
||||
typedef struct _tag_sos_vds_struct {
|
||||
unsigned int region_size;
|
||||
unsigned int offset;
|
||||
unsigned short segment;
|
||||
unsigned short ID;
|
||||
unsigned int physical;
|
||||
} _SOS_VDS_STRUCT;
|
||||
|
||||
typedef struct _tag_sos_sample {
|
||||
char* pSample;
|
||||
char* pSampleCurrent;
|
||||
char* pSampleLoop;
|
||||
unsigned long wLength;
|
||||
unsigned long wLoopLength;
|
||||
unsigned long wLoopEndLength;
|
||||
unsigned long wLoopStage;
|
||||
unsigned long wID;
|
||||
unsigned long wFlags;
|
||||
unsigned long wPriority;
|
||||
unsigned long hSample;
|
||||
unsigned long wVolume;
|
||||
unsigned long wLoopCount;
|
||||
unsigned long wRate;
|
||||
unsigned long wBitsPerSample;
|
||||
unsigned long wChannels;
|
||||
unsigned long wFormat;
|
||||
unsigned long wPanPosition;
|
||||
unsigned long wPanSpeed;
|
||||
unsigned long wPanStart;
|
||||
unsigned long wPanEnd;
|
||||
unsigned long wPanMode;
|
||||
unsigned long wTotalBytesProcessed;
|
||||
void (*pfnSampleProcessed)(PSOSSAMPLE*);
|
||||
void (*pfnSampleDone)(PSOSSAMPLE*);
|
||||
void (*pfnSampleLoop)(PSOSSAMPLE*);
|
||||
unsigned long wSystem[16];
|
||||
unsigned long wUser[16];
|
||||
PSOSSAMPLE* pLink;
|
||||
PSOSSAMPLE* pNext;
|
||||
} _SOS_SAMPLE;
|
||||
|
||||
typedef struct _tagCAPABILITIES {
|
||||
unsigned char szDeviceName[32];
|
||||
W32 wDeviceVersion;
|
||||
W32 wBitsPerSample;
|
||||
W32 wChannels;
|
||||
W32 wMinRate;
|
||||
W32 wMaxRate;
|
||||
W32 wMixerOnBoard;
|
||||
W32 wMixerFlags;
|
||||
W32 wFlags;
|
||||
short* lpPortList;
|
||||
short* lpDMAList;
|
||||
short* lpIRQList;
|
||||
short* lpRateList;
|
||||
W32 fBackground;
|
||||
W32 wID;
|
||||
W32 wTimerID;
|
||||
} _SOS_CAPABILITIES;
|
||||
|
||||
typedef struct _SOS_HARDWARE {
|
||||
W32 wPort;
|
||||
W32 wIRQ;
|
||||
W32 wDMA;
|
||||
W32 wParam;
|
||||
} _SOS_HARDWARE;
|
||||
|
||||
typedef struct _tag_sos_driver {
|
||||
W32 wFlags;
|
||||
unsigned long wDriverRate;
|
||||
unsigned long wDriverChannels;
|
||||
unsigned long wDriverBitsPerSample;
|
||||
unsigned long wDriverFormat;
|
||||
unsigned long wMixerChannels;
|
||||
unsigned long wDMACountRegister;
|
||||
unsigned long wDMAPosition;
|
||||
unsigned long wDMALastPosition;
|
||||
unsigned long wDMADistance;
|
||||
char* pXFERPosition;
|
||||
unsigned long wXFERJumpAhead;
|
||||
_SOS_SAMPLE* pSampleList;
|
||||
void (*pfnPseudoDMAFunction)(void);
|
||||
char* pDMABuffer;
|
||||
char* pDMABufferEnd;
|
||||
unsigned long wDMABufferSize;
|
||||
char* pMixingBuffer;
|
||||
char* pMixingBufferEnd;
|
||||
unsigned long wMixingBufferSize;
|
||||
unsigned long wActiveChannels;
|
||||
_SOS_SAMPLE* pSamples;
|
||||
_SOS_HARDWARE sHardware;
|
||||
_SOS_CAPABILITIES sCaps;
|
||||
char* lpDriverDS;
|
||||
char* lpDriverCS;
|
||||
W32 wSize;
|
||||
unsigned long dwLinear;
|
||||
unsigned long dwDMAPhysical;
|
||||
char* lpDMABuffer;
|
||||
W32 hMemory;
|
||||
W32 wDMARealSeg;
|
||||
W32 wID;
|
||||
void (*pfnMixFunction)(void);
|
||||
} _SOS_DIGI_DRIVER;
|
||||
|
||||
typedef struct _SOS_DRV_FILEHEADER {
|
||||
unsigned char szName[32];
|
||||
W32 wDrivers;
|
||||
W32 lOffset;
|
||||
W32 lFileSize;
|
||||
} _SOS_DRV_FILEHEADER;
|
||||
|
||||
typedef struct _SOS_DRV_DRIVERHEADER {
|
||||
unsigned char szName[32];
|
||||
W32 lNextDriver;
|
||||
W32 wSize;
|
||||
W32 wDeviceID;
|
||||
W32 wExtenderType;
|
||||
} _SOS_DRV_DRIVERHEADER;
|
||||
|
||||
typedef struct _tag_sos_system {
|
||||
W32 wFlags;
|
||||
unsigned char szDriverPath[128];
|
||||
unsigned char szTempDriverPath[128];
|
||||
PSOSDIGIDRIVER pDriver[5];
|
||||
_SOS_VDS_STRUCT sVDS;
|
||||
_SOS_DRV_FILEHEADER sFileHeader;
|
||||
_SOS_DRV_DRIVERHEADER sDriverHeader;
|
||||
char* (*pMemAllocFunction)(unsigned long);
|
||||
void (*pMemFreeFunction)(char*, W32);
|
||||
} _SOS_SYSTEM;
|
||||
|
||||
typedef struct _tag_sos_det_system {
|
||||
W32 wFlags;
|
||||
unsigned char szDriverPath[128];
|
||||
unsigned char szTempDriverPath[128];
|
||||
_SOS_DRV_FILEHEADER sFileHeader;
|
||||
_SOS_DRV_DRIVERHEADER sDriverHeader;
|
||||
_SOS_CAPABILITIES sCaps;
|
||||
PSOSCAPABILITIES pCaps;
|
||||
char* lpBufferDS;
|
||||
char* lpBufferCS;
|
||||
W32 hFile;
|
||||
unsigned long dwDriverIndex;
|
||||
W32 wDriverIndexCur;
|
||||
W32 hMemory;
|
||||
unsigned long dwLinear;
|
||||
} _SOS_DET_SYSTEM;
|
||||
|
||||
typedef struct _tag_sos_timer_system {
|
||||
W32 wFlags;
|
||||
W32 wChipDivisor;
|
||||
void (*pfnEvent[16])(void);
|
||||
W32 wEventRate[16];
|
||||
unsigned long dwAdditiveFraction[16];
|
||||
unsigned long dwCurrentSummation[16];
|
||||
W32 wMIDIEventSongHandle[16];
|
||||
W32 wMIDIActiveSongHandle;
|
||||
} _SOS_TIMER_SYSTEM;
|
||||
|
|
@ -64,6 +64,7 @@ target_sources(harness PRIVATE
|
|||
sound/sound.c
|
||||
sound/sound.h
|
||||
win95/polyfill.c
|
||||
win95/winsock.c
|
||||
platforms/null.c
|
||||
platforms/null.h
|
||||
|
||||
|
|
@ -101,6 +102,7 @@ if(WIN32)
|
|||
target_sources(harness PRIVATE
|
||||
os/windows.c
|
||||
)
|
||||
target_link_libraries(harness PRIVATE ws2_32)
|
||||
elseif(APPLE)
|
||||
target_sources(harness PRIVATE
|
||||
os/macos.c
|
||||
|
|
|
|||
|
|
@ -161,6 +161,8 @@ void Harness_Init(int* argc, char* argv[]) {
|
|||
harness_game_config.start_full_screen = 0;
|
||||
// Emulate DOS behavior
|
||||
harness_game_config.dos_mode = 0;
|
||||
// Skip binding socket to allow local network testing
|
||||
harness_game_config.no_bind = 0;
|
||||
|
||||
// install signal handler by default
|
||||
harness_game_config.install_signalhandler = 1;
|
||||
|
|
@ -249,6 +251,9 @@ int Harness_ProcessCommandLine(int* argc, char* argv[]) {
|
|||
} else if (strcasecmp(argv[i], "--dos-mode") == 0) {
|
||||
harness_game_config.dos_mode = 1;
|
||||
handled = 1;
|
||||
} else if (strcasecmp(argv[i], "--no-bind") == 0) {
|
||||
harness_game_config.no_bind = 1;
|
||||
handled = 1;
|
||||
}
|
||||
|
||||
if (handled) {
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ typedef struct tHarness_game_config {
|
|||
float volume_multiplier;
|
||||
int start_full_screen;
|
||||
int dos_mode;
|
||||
int no_bind;
|
||||
|
||||
int install_signalhandler;
|
||||
} tHarness_game_config;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Inspiration taken from https://github.com/TheAssemblyArmada/Vanilla-Conquer/blob/vanilla/common/sockets.h
|
||||
*/
|
||||
|
||||
#ifndef HARNESS_WINSOCK_H
|
||||
#define HARNESS_WINSOCK_H
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define _WINSOCK_DEPRECATED_NO_WARNINGS
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#else /* Assume posix style sockets on non-windows */
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h> // for getaddrinfo() and freeaddrinfo()
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h> // for close()
|
||||
|
||||
#define closesocket(x) close(x)
|
||||
#define WSAEISCONN EISCONN
|
||||
#define WSAEINPROGRESS EINPROGRESS
|
||||
#define WSAEALREADY EALREADY
|
||||
#define WSAEADDRINUSE EADDRINUSE
|
||||
#define WSAEADDRNOTAVAIL EADDRNOTAVAIL
|
||||
#define WSAEBADF EBADF
|
||||
#define WSAECONNREFUSED ECONNREFUSED
|
||||
#define WSAEINTR EINTR
|
||||
#define WSAENOTSOCK ENOTSOCK
|
||||
#define WSAEWOULDBLOCK EWOULDBLOCK
|
||||
#define WSAEINVAL EINVAL
|
||||
#define WSAETIMEDOUT ETIMEDOUT
|
||||
|
||||
#define MAKEWORD(x, y) ((y) << 8 | (x))
|
||||
|
||||
typedef struct WSADATA {
|
||||
} WSADATA;
|
||||
|
||||
int WSAStartup(int version, WSADATA* data);
|
||||
int WSAGetLastError(void);
|
||||
int WSACleanup(void);
|
||||
int ioctlsocket(int handle, long cmd, unsigned long* argp);
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#include "harness/winsock.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
int WSAStartup(int version, WSADATA* data) {
|
||||
// very minimal, we don't care about the arguments
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WSAGetLastError(void) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
int WSACleanup(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Only implement non-blocking call for now
|
||||
int ioctlsocket(int handle, long cmd, unsigned long* argp) {
|
||||
assert(cmd == FIONBIO);
|
||||
|
||||
int flags = fcntl(handle, F_GETFL);
|
||||
flags |= O_NONBLOCK;
|
||||
return fcntl(handle, F_SETFL, flags);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -28,7 +28,7 @@ if(NOT MSVC)
|
|||
endif()
|
||||
endif()
|
||||
else()
|
||||
target_compile_definitions(dethrace_test PRIVATE -D_CRT_SECURE_NO_WARNINGS -DSDL_MAIN_HANDLED)
|
||||
target_compile_definitions(dethrace_test PRIVATE -D_CRT_SECURE_NO_WARNINGS -DSDL_MAIN_HANDLED -DWIN32_LEAN_AND_MEAN)
|
||||
target_link_libraries(dethrace_test PRIVATE dbghelp)
|
||||
endif()
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue