implement editor_read_s6, partial fix for #433

This commit is contained in:
IntelOrca 2014-11-24 02:58:48 +00:00
parent adb5f84f55
commit 73a6b1acea
15 changed files with 353 additions and 36 deletions

View File

@ -73,6 +73,7 @@
<ClCompile Include="..\src\localisation\language.c" />
<ClCompile Include="..\src\localisation\localisation.c" />
<ClCompile Include="..\src\localisation\real_names.c" />
<ClCompile Include="..\src\localisation\user.c" />
<ClCompile Include="..\src\management\award.c" />
<ClCompile Include="..\src\management\finance.c" />
<ClCompile Include="..\src\management\marketing.c" />

View File

@ -386,7 +386,6 @@
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\lib\libspeex\resample.c;..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\lib\libspeex\resample.c;..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\src\cmdline.c">
@ -467,6 +466,10 @@
<ClCompile Include="..\src\windows\editor_top_toolbar.c">
<Filter>Source\Windows</Filter>
</ClCompile>
<ClCompile Include="..\lib\libspeex\resample.c;..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\src\localisation\user.c">
<Filter>Source\Localisation</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\management\award.h">

View File

@ -64,7 +64,7 @@ void editor_load()
map_init();
RCT2_CALLPROC_EBPSAFE(0x006B9CB0);
reset_park_entrances();
reset_saved_strings();
user_string_clear_all();
reset_sprite_list();
ride_init_all();
window_guest_list_init_vars_a();
@ -219,7 +219,7 @@ void trackdesigner_load()
set_all_land_owned();
RCT2_CALLPROC_EBPSAFE(0x006B9CB0);
reset_park_entrances();
reset_saved_strings();
user_string_clear_all();
reset_sprite_list();
ride_init_all();
window_guest_list_init_vars_a();
@ -257,7 +257,7 @@ void trackmanager_load()
set_all_land_owned();
RCT2_CALLPROC_EBPSAFE(0x006B9CB0);
reset_park_entrances();
reset_saved_strings();
user_string_clear_all();
reset_sprite_list();
ride_init_all();
window_guest_list_init_vars_a();
@ -498,9 +498,226 @@ static int editor_read_s4(char *src)
*/
static int editor_read_s6(const char *path)
{
strcpy((char *)0x0141EF68, path);
RCT2_CALLPROC_EBPSAFE(0x006758FE);
return 1;
int i, j;
FILE *file;
rct_s6_header *s6Header = (rct_s6_header*)0x009E34E4;
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
// strcpy((char *)0x0141EF68, path);
// RCT2_CALLPROC_EBPSAFE(0x006758FE);
log_verbose("loading landscape, %s", path);
file = fopen(path, "rb");
if (file != NULL) {
if (!sawyercoding_validate_checksum(file)) {
fclose(file);
RCT2_GLOBAL(0x009AC31B, uint8) = 255;
RCT2_GLOBAL(0x009AC31C, uint16) = STR_FILE_CONTAINS_INVALID_DATA;
log_error("failed to load scenario, invalid checksum");
return 0;
}
// Read first chunk
sawyercoding_read_chunk(file, (uint8*)s6Header);
if (s6Header->type == S6_TYPE_SCENARIO) {
// Read second chunk
sawyercoding_read_chunk(file, (uint8*)s6Info);
if (s6Info->var_000 == 255)
s6Info->var_000 = 1;
} else {
s6Info->var_000 = 1;
s6Info->category = SCENARIO_CATEGORY_BUILDYOUROWN;
format_string(s6Info->details, STR_NO_DETAILS_YET, NULL);
}
// Read packed objects
if (s6Header->num_packed_objects > 0) {
j = 0;
for (i = 0; i < s6Header->num_packed_objects; i++)
j += object_load_packed(file);
if (j > 0)
object_list_load();
}
uint8 load_success = object_read_and_load_entries(file);
// Read flags (16 bytes). Loads:
// RCT2_ADDRESS_CURRENT_MONTH_YEAR
// RCT2_ADDRESS_CURRENT_MONTH_TICKS
// RCT2_ADDRESS_SCENARIO_TICKS
sawyercoding_read_chunk(file, (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(file, (uint8*)RCT2_ADDRESS_MAP_ELEMENTS);
// Read game data, including sprites
sawyercoding_read_chunk(file, (uint8*)0x010E63B8);
if (s6Header->type == S6_TYPE_SCENARIO) {
// Read number of guests in park and something else
sawyercoding_read_chunk(file, (uint8*)RCT2_ADDRESS_GUESTS_IN_PARK);
// Read ?
sawyercoding_read_chunk(file, (uint8*)0x01357BC8);
// Read park rating
sawyercoding_read_chunk(file, (uint8*)RCT2_ADDRESS_CURRENT_PARK_RATING);
// Read ?
sawyercoding_read_chunk(file, (uint8*)RCT2_ADDRESS_ACTIVE_RESEARCH_TYPES);
// Read ?
sawyercoding_read_chunk(file, (uint8*)RCT2_ADDRESS_CURRENT_EXPENDITURE);
// Read ?
sawyercoding_read_chunk(file, (uint8*)RCT2_ADDRESS_CURRENT_PARK_VALUE);
// Read more game data, including research items and rides
sawyercoding_read_chunk(file, (uint8*)RCT2_ADDRESS_COMPLETED_COMPANY_VALUE);
}
fclose(file);
if (!load_success){
log_error("failed to load all entries.");
set_load_objects_fail_reason();
return 0;
}
// Check expansion pack
// RCT2_CALLPROC_EBPSAFE(0x006757E6);
RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
map_update_tile_pointers();
map_remove_all_rides();
//
for (i = 0; i < MAX_BANNERS; i++)
if (gBanners[i].type == 255)
gBanners[i].flags &= ~BANNER_FLAG_2;
//
rct_ride *ride;
FOR_ALL_RIDES(i, ride)
user_string_free(ride->name);
ride_init_all();
//
for (i = 0; i < MAX_SPRITES; i++) {
rct_sprite *sprite = &g_sprite_list[i];
user_string_free(sprite->unknown.name_string_idx);
}
reset_sprite_list();
sub_6BD3A4();
RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_HEADING_FOR_PARK, uint16) = 0;
RCT2_GLOBAL(0x01357BC8, uint16) = 0;
RCT2_GLOBAL(0x013573FE, uint16) = 0;
if (s6Header->type != S6_TYPE_SCENARIO) {
RCT2_CALLPROC_EBPSAFE(0x00685675);
RCT2_CALLPROC_EBPSAFE(0x0068585B);
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY)
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_NO_MONEY_SCENARIO;
else
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_NO_MONEY_SCENARIO;
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_NO_MONEY;
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) == 0)
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_PARK_FREE_ENTRY;
else
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_PARK_FREE_ENTRY;
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_18;
RCT2_GLOBAL(RCT2_ADDRESS_GUEST_INITIAL_CASH, money16) = clamp(
MONEY(10,00),
RCT2_GLOBAL(RCT2_ADDRESS_GUEST_INITIAL_CASH, money16),
MONEY(100,00)
);
RCT2_GLOBAL(0x013573DC, uint32) = min(RCT2_GLOBAL(0x013573DC, uint32), 100000);
RCT2_CALLPROC_EBPSAFE(0x0069E89B);
RCT2_CALLPROC_EBPSAFE(0x0069E869);
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32) = clamp(
MONEY(0,00),
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32),
MONEY(5000000,00)
);
RCT2_GLOBAL(0x013580F0, money32) = clamp(
MONEY(0,00),
RCT2_GLOBAL(0x013580F0, money32),
MONEY(5000000,00)
);
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_INTEREST_RATE, uint8) = clamp(
5,
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_INTEREST_RATE, uint8),
80
);
}
climate_reset(RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE, uint8));
if (RCT2_GLOBAL(0x009ADAE4, uint32) != 0xFFFFFFFF) {
object_unload(0, (rct_object_entry_extended*)0x00F4287C);
RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
format_string(s6Info->details, STR_NO_DETAILS_YET, NULL);
s6Info->name[0] = 0;
}
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_SCENARIO_EDITOR;
viewport_init_all();
news_item_init_queue();
window_editor_main_open();
// Initialise main view
rct_window *w = window_get_main();
rct_viewport *viewport = w->viewport;
w->viewport_target_sprite = -1;
w->saved_view_x = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_X, sint16);
w->saved_view_y = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_Y, sint16);
viewport->zoom = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_ZOOM_AND_ROTATION, uint16) & 0xFF;
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8) = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_ZOOM_AND_ROTATION, uint16) >> 8;
int cx = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_ZOOM_AND_ROTATION, sint16) - viewport->zoom;
if (cx != 0) {
if (cx >= 0) {
viewport->view_width <<= cx;
viewport->view_height <<= cx;
} else {
cx = -cx;
viewport->view_width >>= cx;
viewport->view_height >>= cx;
}
}
w->saved_view_x -= viewport->view_width >> 1;
w->saved_view_y -= viewport->view_height >> 1;
window_invalidate(w);
sub_69E9A7();
RCT2_CALLPROC_EBPSAFE(0x006DFEE4);
window_new_ride_init_vars();
RCT2_GLOBAL(0x009DEB7C, uint16) = 0;
RCT2_CALLPROC_EBPSAFE(0x006837E3); // (palette related)
gfx_invalidate_screen();
return 1;
}
log_error("failed to find scenario file.");
RCT2_GLOBAL(0x009AC31B, uint8) = 255;
RCT2_GLOBAL(0x009AC31C, uint16) = STR_FILE_CONTAINS_INVALID_DATA;
return 0;
}
/**

View File

@ -583,8 +583,7 @@ static void load_landscape()
{
if (open_landscape_file_dialog() == 0) {
gfx_invalidate_screen();
}
else {
} else {
// Set default filename
char *esi = (char*)0x0141EF67;
while (1) {
@ -598,12 +597,11 @@ static void load_landscape()
}
strcpy((char*)RCT2_ADDRESS_SAVED_GAMES_PATH_2, (char*)0x0141EF68);
RCT2_CALLPROC_EBPSAFE(0x006758C0); // landscape_load
editor_load_landscape((char*)0x0141EF68);
if (1) {
gfx_invalidate_screen();
rct2_endupdate();
}
else {
} else {
RCT2_GLOBAL(0x009DEA66, uint16) = 0;
rct2_endupdate();
}

View File

@ -647,16 +647,6 @@ void generate_string_file()
fclose(f);
}
/**
*
* rct2: 0x006C4209
*/
void reset_saved_strings() {
for (int i = 0; i < 1024; i++) {
RCT2_ADDRESS(0x135A8F4, uint8)[i * 32] = 0;
}
}
/**
* Return the length of the string in buffer.
* note you can't use strlen as there can be inline sprites!

View File

@ -28,10 +28,15 @@
void format_string(char *dest, rct_string_id format, void *args);
void generate_string_file();
void reset_saved_strings();
void error_string_quit(int error, rct_string_id format);
int get_string_length(char* buffer);
void user_string_clear_all();
void user_string_free(rct_string_id id);
#define MAX_USER_STRINGS 1024
#define USER_STRING_MAX_LENGTH 32
// Real name data
extern const char real_name_initials[16];
extern const char *real_names[1024];

45
src/localisation/user.c Normal file
View File

@ -0,0 +1,45 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* This file is part of OpenRCT2.
*
* OpenRCT2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include "localisation.h"
char *gUserStrings = (char*)0x0135A8F4;
/**
*
* rct2: 0x006C4209
*/
void user_string_clear_all()
{
memset(gUserStrings, 0, MAX_USER_STRINGS * USER_STRING_MAX_LENGTH);
}
/**
*
* rct2: 0x006C42AC
*/
void user_string_free(rct_string_id id)
{
if (id < 0x8000 || id >= 0x9000)
return;
id %= MAX_USER_STRINGS;
gUserStrings[id * USER_STRING_MAX_LENGTH] = 0;
}

View File

@ -104,7 +104,7 @@ int rct2_init()
news_item_init_queue();
get_local_time();
reset_park_entrances();
reset_saved_strings();
user_string_clear_all();
reset_sprite_list();
ride_init_all();
window_guest_list_init_vars_a();

View File

@ -95,7 +95,7 @@ void title_load()
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_TITLE_DEMO;
reset_park_entrances();
reset_saved_strings();
user_string_clear_all();
reset_sprite_list();
ride_init_all();
window_guest_list_init_vars_a();

View File

@ -293,8 +293,7 @@ static void window_banner_dropdown()
if (string_id){
rct_string_id prev_string_id = banner->string_idx;
banner->string_idx = string_id;
// De-allocate previous string id?
RCT2_CALLPROC_X(0x6C42AC, prev_string_id, 0, 0, 0, 0, 0, 0);
user_string_free(prev_string_id);
window_invalidate(w);
}
else{
@ -330,8 +329,7 @@ static void window_banner_textinput()
if (string_id){
rct_string_id prev_string_id = banner->string_idx;
banner->string_idx = string_id;
// De-allocate previous string id?
RCT2_CALLPROC_X(0x6C42AC, prev_string_id, 0, 0, 0, 0, 0, 0);
user_string_free(prev_string_id);
window_invalidate(w);
}
else{

View File

@ -367,8 +367,7 @@ static void window_sign_textinput()
if (string_id){
rct_string_id prev_string_id = banner->string_idx;
banner->string_idx = string_id;
// De-allocate previous string id?
RCT2_CALLPROC_X(0x6C42AC, prev_string_id, 0, 0, 0, 0, 0, 0);
user_string_free(prev_string_id);
banner->flags &= ~(BANNER_FLAG_2);
gfx_invalidate_screen();
@ -386,7 +385,7 @@ static void window_sign_textinput()
rct_string_id prev_string_id = banner->string_idx;
banner->string_idx = 778;
RCT2_CALLPROC_X(0x6C42AC, prev_string_id, 0, 0, 0, 0, 0, 0);
user_string_free(prev_string_id);
gfx_invalidate_screen();
}
}

View File

@ -36,8 +36,8 @@ typedef struct {
} rct_banner;
enum{
BANNER_FLAG_NO_ENTRY = (1<<0),
BANNER_FLAG_2 = (1<<2)
BANNER_FLAG_NO_ENTRY = (1 << 0),
BANNER_FLAG_2 = (1 << 2)
} BANNER_FLAGS;
extern rct_banner *gBanners;

View File

@ -552,7 +552,7 @@ money32 map_try_clear_scenery(int x, int y, rct_map_element *mapElement, int fla
// Remove element
if (flags & 1) {
map_invalidate_tile_full(x, y);
RCT2_CALLPROC_X(0x0068B280, 0, 0, 0, 0, (int)mapElement, 0, 0);
map_element_remove(mapElement);
}
return RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY ? 0 : cost;
}
@ -701,4 +701,62 @@ void map_invalidate_tile_full(int x, int y)
int map_get_station(rct_map_element *mapElement)
{
return (mapElement->properties.track.sequence & 0x70) >> 4;
}
/**
*
* rct2: 0x0068B280
*/
void map_element_remove(rct_map_element *mapElement)
{
RCT2_CALLPROC_X(0x0068B280, 0, 0, 0, 0, (int)mapElement, 0, 0);
}
/**
*
* rct2: 0x006A6AA7
* @param x x-coordinate in units (not tiles)
* @param y y-coordinate in units (not tiles)
*/
void sub_6A6AA7(int x, int y, rct_map_element *mapElement)
{
RCT2_CALLPROC_X(0x006A6AA7, x, 0, y, 0, (int)mapElement, 0, 0);
}
/**
*
* rct2: 0x00675A8E
*/
void map_remove_all_rides()
{
int x, y;
rct_map_element *mapElement;
for (y = 0; y < 256; y++) {
for (x = 0; x < 256; x++) {
repeat_tile:
mapElement = TILE_MAP_ELEMENT_POINTER(y * 256 + x);
do {
switch (mapElement->type & MAP_ELEMENT_TYPE_MASK) {
case MAP_ELEMENT_TYPE_PATH:
if (mapElement->type & 1) {
mapElement->properties.path.type &= ~8;
mapElement->properties.path.addition_status = 255;
}
break;
case MAP_ELEMENT_TYPE_ENTRANCE:
if (mapElement->properties.entrance.type == ENTRANCE_TYPE_PARK_ENTRANCE)
break;
// fall-through
case MAP_ELEMENT_TYPE_TRACK:
RCT2_CALLPROC_EBPSAFE(0x006A7594);
sub_6A6AA7(x * 32, y * 32, mapElement);
map_element_remove(mapElement);
goto repeat_tile;
}
} while (!((mapElement++)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
}
}
}

View File

@ -211,6 +211,9 @@ int map_is_location_in_park(int x, int y);
void map_invalidate_tile(int x, int y, int zLow, int zHigh);
void map_invalidate_tile_full(int x, int y);
int map_get_station(rct_map_element *mapElement);
void map_element_remove(rct_map_element *mapElement);
void sub_6A6AA7(int x, int y, rct_map_element *mapElement);
void map_remove_all_rides();
void fountain_update_all();

View File

@ -27,7 +27,7 @@
#define SPRITE_INDEX_NULL 0xFFFF
#define SPRITE_LOCATION_NULL 0x8000
#define MAX_SPRITES 10000
enum SPRITE_IDENTIFIER{
SPRITE_IDENTIFIER_VEHICLE = 0,