1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-15 11:03:00 +01:00

map load on join

This commit is contained in:
zsilencer
2015-07-31 08:14:44 -06:00
parent a4267990b8
commit ad70dbb84c
6 changed files with 135 additions and 7 deletions

View File

@@ -780,6 +780,63 @@ int game_load_sv6(SDL_RWops* rw)
return 1;
}
// Load game state for multiplayer
int game_load_network(SDL_RWops* rw)
{
int i, j;
rct_s6_header *s6Header = (rct_s6_header*)0x009E34E4;
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
// Read first chunk
sawyercoding_read_chunk(rw, (uint8*)s6Header);
if (s6Header->type == S6_TYPE_SAVEDGAME) {
// Read packed objects
if (s6Header->num_packed_objects > 0) {
j = 0;
for (i = 0; i < s6Header->num_packed_objects; i++)
j += object_load_packed(rw);
if (j > 0)
object_list_load();
}
}
uint8 load_success = object_read_and_load_entries(rw);
// Read flags (16 bytes)
sawyercoding_read_chunk(rw, (uint8*)RCT2_ADDRESS_CURRENT_MONTH_YEAR);
// Read map elements
memset((void*)RCT2_ADDRESS_MAP_ELEMENTS, 0, MAX_MAP_ELEMENTS * sizeof(rct_map_element));
sawyercoding_read_chunk(rw, (uint8*)RCT2_ADDRESS_MAP_ELEMENTS);
// Read game data, including sprites
sawyercoding_read_chunk(rw, (uint8*)0x010E63B8);
// Read checksum
uint32 checksum;
SDL_RWread(rw, &checksum, sizeof(uint32), 1);
if (!load_success){
set_load_objects_fail_reason();
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_5){
RCT2_GLOBAL(0x14241BC, uint32) = 2;
//call 0x0040705E Sets cursor position and something else. Calls maybe wind func 8 probably pointless
RCT2_GLOBAL(0x14241BC, uint32) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~INPUT_FLAG_5;
}
return 0;//This never gets called
}
// The rest is the same as in scenario load and play
reset_loaded_objects();
map_update_tile_pointers();
reset_0x69EBE4();
openrct2_reset_object_tween_locations();
return 1;
}
/**
*
* rct2: 0x00675E1B
@@ -860,8 +917,6 @@ void game_load_init()
gGameSpeed = 1;
scenario_set_filename((char*)0x0135936C);
RCT2_GLOBAL(0x01388698, uint16) = 0;
}
/*

View File

@@ -127,6 +127,7 @@ void game_reduce_game_speed();
void game_load_or_quit_no_save_prompt();
int game_load_sv6(SDL_RWops* rw);
int game_load_network(SDL_RWops* rw);
int game_load_save(const char *path);
void game_load_init();
void game_pause_toggle(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);

View File

@@ -492,12 +492,12 @@ void Network::Client_Send_AUTH(const char* gameversion, const char* name, const
server_connection.QueuePacket(std::move(packet));
}
void Network::Server_Send_MAP()
void Network::Server_Send_MAP(NetworkConnection* connection)
{
int buffersize = 0x600000;
std::vector<uint8> buffer(buffersize);
SDL_RWops* rw = SDL_RWFromMem(&buffer[0], buffersize);
scenario_save(rw, 0);
scenario_save_network(rw);
int size = (int)SDL_RWtell(rw);
int chunksize = 1000;
for (int i = 0; i < size; i += chunksize) {
@@ -505,7 +505,11 @@ void Network::Server_Send_MAP()
std::unique_ptr<NetworkPacket> packet = std::move(NetworkPacket::Allocate());
*packet << (uint32)NETWORK_COMMAND_MAP << (uint32)size << (uint32)i;
packet->Write(&buffer[i], datasize);
SendPacketToClients(*packet);
if (connection) {
connection->QueuePacket(std::move(packet));
} else {
SendPacketToClients(*packet);
}
}
SDL_RWclose(rw);
}
@@ -744,6 +748,7 @@ int Network::Server_Handle_AUTH(NetworkConnection& connection, NetworkPacket& pa
sprintf(&text[2], "%s has joined the game", player->name);
chat_history_add(text);
gNetwork.Server_Send_CHAT(text);
Server_Send_MAP(&connection);
}
}
std::unique_ptr<NetworkPacket> responsepacket = std::move(NetworkPacket::Allocate());
@@ -774,7 +779,7 @@ int Network::Client_Handle_MAP(NetworkConnection& connection, NetworkPacket& pac
memcpy(&chunk_buffer[offset], (void*)packet.Read(chunksize), chunksize);
if (offset + chunksize == size) {
SDL_RWops* rw = SDL_RWFromMem(&chunk_buffer[0], size);
if (game_load_sv6(rw)) {
if (game_load_network(rw)) {
game_load_init();
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) & 1)
pause_toggle();

View File

@@ -138,7 +138,7 @@ public:
bool CheckSRAND(uint32 tick, uint32 srand0);
void Client_Send_AUTH(const char* gameversion, const char* name, const char* password);
void Server_Send_MAP();
void Server_Send_MAP(NetworkConnection* connection = nullptr);
void Client_Send_CHAT(const char* text);
void Server_Send_CHAT(const char* text);
void Client_Send_GAMECMD(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp, uint8 callback);

View File

@@ -979,6 +979,72 @@ int scenario_save(SDL_RWops* rw, int flags)
return 1;
}
// Save game state without modifying any of the state for multiplayer
int scenario_save_network(SDL_RWops* rw)
{
rct_window *w;
rct_viewport *viewport;
int viewX, viewY, viewZoom, viewRotation;
/*map_reorganise_elements();
reset_0x69EBE4();
sprite_clear_all_unused();
sub_677552();
sub_674BCF();*/
// Set saved view
w = window_get_main();
if (w != NULL) {
viewport = w->viewport;
viewX = viewport->view_width / 2 + viewport->view_x;
viewY = viewport->view_height / 2 + viewport->view_y;
viewZoom = viewport->zoom;
viewRotation = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8);
} else {
viewX = 0;
viewY = 0;
viewZoom = 0;
viewRotation = 0;
}
RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_X, uint16) = viewX;
RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_Y, uint16) = viewY;
RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_ZOOM_AND_ROTATION, uint16) = viewZoom | (viewRotation << 8);
// Prepare S6
rct_s6_data *s6 = malloc(sizeof(rct_s6_data));
s6->header.type = S6_TYPE_SAVEDGAME;
s6->header.num_packed_objects = scenario_get_num_packed_objects_to_write();
s6->header.version = S6_RCT2_VERSION;
s6->header.magic_number = S6_MAGIC_NUMBER;
memcpy(&s6->info, (rct_s6_info*)0x0141F570, sizeof(rct_s6_info));
for (int i = 0; i < 721; i++) {
uint32 chunkPtr = RCT2_ADDRESS(0x009ACFA4, uint32)[i];
rct_object_entry_extended *entry = &(RCT2_ADDRESS(0x00F3F03C, rct_object_entry_extended)[i]);
if (RCT2_ADDRESS(0x009ACFA4, uint32)[i] == 0xFFFFFFFF) {
memset(&s6->objects[i], 0xFF, sizeof(rct_object_entry));
} else {
s6->objects[i] = *((rct_object_entry*)entry);
}
}
memcpy(&s6->elapsed_months, (void*)0x00F663A8, 16);
memcpy(s6->map_elements, (void*)0x00F663B8, 0x180000);
memcpy(&s6->dword_010E63B8, (void*)0x010E63B8, 0x2E8570);
scenario_fix_ghosts(s6);
scenario_save_s6(rw, s6);
free(s6);
gfx_invalidate_screen();
return 1;
}
bool scenario_save_s6(SDL_RWops* rw, rct_s6_data *s6)
{
char *buffer;

View File

@@ -427,6 +427,7 @@ unsigned int scenario_rand();
unsigned int scenario_rand_max(unsigned int max);
int scenario_prepare_for_save();
int scenario_save(SDL_RWops* rw, int flags);
int scenario_save_network(SDL_RWops* rw);
bool scenario_save_s6(SDL_RWops* rw, rct_s6_data *s6);
void scenario_set_filename(const char *value);
void scenario_failure();