1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-23 15:52:55 +01:00

add scenario loading and title script

This commit is contained in:
IntelOrca
2014-04-10 15:14:47 +01:00
parent 9e9daaedfa
commit b23c12d435
9 changed files with 323 additions and 43 deletions

View File

@@ -98,6 +98,8 @@
#define RCT2_ADDRESS_CURRENT_LOAN 0x013573E0
#define RCT2_ADDRESS_GUESTS_IN_PARK 0x01357844
#define RCT2_ADDRESS_CURRENT_PARK_RATING 0x01357CB0
#define RCT2_ADDRESS_PARK_RATING_HISTORY 0x01357CB2
#define RCT2_ADDRESS_CURRENT_PARK_VALUE 0x0135853C
#define RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED 0x013587F8

View File

@@ -61,7 +61,7 @@ void map_init()
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, sint16) = 150;
RCT2_GLOBAL(0x01358836, sint16) = 4767;
RCT2_GLOBAL(0x01359208, sint16) = 7;
tiles_init();
map_update_tile_pointers();
RCT2_CALLPROC_EBPSAFE(0x0068ADBC);
climate_reset(CLIMATE_WARM);
@@ -71,7 +71,7 @@ void map_init()
*
* rct2: 0x0068AFFD
*/
static void tiles_init()
void map_update_tile_pointers()
{
int i, x, y, lastTile;
@@ -93,3 +93,36 @@ static void tiles_init()
// Possible next free map element
RCT2_GLOBAL(0x0140E9A4, rct_map_element*) = mapElement;
}
/**
*
* rct2: 0x00662783
* UNFINISHED
*/
int sub_662783(int x, int y)
{
int i;
rct_map_element *mapElement;
if (x >= 8192 || y >= 8192)
return 16;
x &= 0xFFFFFFE0;
y &= 0xFFFFFFE0;
i = ((y * 256) + x) / 8;
mapElement = TILE_MAP_ELEMENT_POINTER(i);
while (mapElement->type & MAP_ELEMENT_TYPE_MASK) {
mapElement++;
}
uint32 result =
((mapElement->properties.surface.terrain & MAP_ELEMENT_WATER_HEIGHT_MASK) << 20) |
(mapElement->base_height << 3);
uint32 ebx = (mapElement->properties.surface.slope & MAP_ELEMENT_SLOPE_MASK) & ~0x16;
// slope logic
return result;
}

View File

@@ -157,11 +157,15 @@ enum {
#define MAP_ELEMENT_TYPE_MASK 0x3C
#define MAP_ELEMENT_DIRECTION_MASK 0x03
#define MAP_ELEMENT_SLOPE_MASK 0x1F
#define MAP_ELEMENT_WATER_HEIGHT_MASK 0x1F
#define MAX_MAP_ELEMENTS 196608
#define MAX_TILE_MAP_ELEMENT_POINTERS (256 * 256)
#define TILE_UNDEFINED_MAP_ELEMENT -1
void map_init();
void map_update_tile_pointers();
#endif

View File

@@ -22,6 +22,7 @@
#include <windows.h>
#include "addresses.h"
#include "map.h"
#include "rct2.h"
#include "sawyercoding.h"
#include "scenario.h"
@@ -249,8 +250,6 @@ static void scenario_scores_save()
}
}
void sub_67685F(HFILE hFile, uint32 address);
/**
* Loads only the basic information from a scenario.
* rct2: 0x006761D6
@@ -262,8 +261,9 @@ static int scenario_load_basic(char *path)
rct_s6_header *s6Header = 0x009E34E4;
rct_s6_info *s6Info = 0x0141F570;
hFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_FLAG_RANDOM_ACCESS | FILE_ATTRIBUTE_NORMAL, NULL);
hFile = CreateFile(
path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS | FILE_ATTRIBUTE_NORMAL, NULL
);
if (hFile != INVALID_HANDLE_VALUE) {
RCT2_GLOBAL(0x009E382C, HANDLE*) = hFile;
@@ -294,9 +294,8 @@ static int scenario_load_basic(char *path)
loc_67628F :
return _eax;
}
} else {
CloseHandle(hFile);
}
CloseHandle(hFile);
}
RCT2_GLOBAL(0x009AC31B, sint8) = -1;
@@ -304,12 +303,112 @@ static int scenario_load_basic(char *path)
return 0;
}
/**
*
* rct2: 0x006AA2B7
*/
static int object_load_packed()
{
int eax, ebx, ecx, edx, esi, edi, ebp;
RCT2_CALLFUNC_X(0x006AA2B7, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
return eax;
}
/**
*
* rct2: 0x00676053
* scenario (ebx)
*/
void scenario_load(char *path)
{
HANDLE hFile;
int i, j;
rct_s6_header *s6Header = 0x009E34E4;
rct_s6_info *s6Info = 0x0141F570;
strcpy(RCT2_ADDRESS(0x0141EF68, char), path);
RCT2_CALLPROC_EBPSAFE(0x00676053);
return;
hFile = CreateFile(
path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS | FILE_ATTRIBUTE_NORMAL, NULL
);
if (hFile != INVALID_HANDLE_VALUE) {
RCT2_GLOBAL(0x009E382C, HANDLE*) = hFile;
// Read first chunk
sawyercoding_read_chunk(hFile, s6Header);
if (s6Header->type == S6_TYPE_SCENARIO) {
// Read second chunk
sawyercoding_read_chunk(hFile, s6Info);
// Read packed objects
if (s6Header->num_packed_objects > 0) {
j = 0;
for (i = 0; i < s6Header->num_packed_objects; i++)
j += object_load_packed();
if (j > 0)
RCT2_CALLPROC_EBPSAFE(0x006A8B40); // object_load_list
}
// Read available items (721 * 16)
RCT2_CALLPROC_EBPSAFE(0x006AA0C6);
// Read flags (16 bytes)
sawyercoding_read_chunk(hFile, RCT2_ADDRESS_CURRENT_MONTH_YEAR);
// Read map elements
memset(RCT2_ADDRESS_MAP_ELEMENTS, 0, MAX_MAP_ELEMENTS * sizeof(rct_map_element));
sawyercoding_read_chunk(hFile, RCT2_ADDRESS_MAP_ELEMENTS);
// Read game data, including sprites
sawyercoding_read_chunk(hFile, 0x010E63B8);
// Read number of guests in park and something else
sawyercoding_read_chunk(hFile, RCT2_ADDRESS_GUESTS_IN_PARK);
// Read ?
sawyercoding_read_chunk(hFile, 0x01357BC8);
// Read park rating
sawyercoding_read_chunk(hFile, RCT2_ADDRESS_CURRENT_PARK_RATING);
// Read ?
sawyercoding_read_chunk(hFile, 0x01357CF2);
// Read ?
sawyercoding_read_chunk(hFile, 0x0135832C);
// Read ?
sawyercoding_read_chunk(hFile, RCT2_ADDRESS_CURRENT_PARK_VALUE);
// Read more game data, including research items and rides
sawyercoding_read_chunk(hFile, 0x01358740);
CloseHandle(hFile);
// Check expansion pack
// RCT2_CALLPROC_EBPSAFE(0x006757E6);
RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
map_update_tile_pointers();
RCT2_CALLPROC_EBPSAFE(0x0069EBE4);
return;
}
CloseHandle(hFile);
}
RCT2_GLOBAL(0x009AC31B, uint8) = 255;
RCT2_GLOBAL(0x009AC31C, uint16) = 3011;
}
/**
*
* rct2: 0x00678282
* scenario (ebx)
*/
void scenario_load(rct_scenario_basic *scenario)
void scenario_load_and_play(rct_scenario_basic *scenario)
{
RCT2_CALLPROC_X(0x00678282, 0, scenario, 0, 0, 0, 0, 0);
}

View File

@@ -108,6 +108,7 @@ enum {
};
void scenario_load_list();
void scenario_load(rct_scenario_basic *scenario);
void scenario_load(char *path);
void scenario_load_and_play(rct_scenario_basic *scenario);
#endif

View File

@@ -1,22 +1,22 @@
/*****************************************************************************
* 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.
* 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.
* 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/>.
*****************************************************************************/
* 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 "addresses.h"
#include "date.h"
@@ -28,20 +28,58 @@
#include "park.h"
#include "rct2.h"
#include "ride.h"
#include "scenario.h"
#include "viewport.h"
static void title_create_windows();
static void title_init_showcase();
// External functions
void window_main_open();
void window_title_menu_open();
void window_title_exit_open();
void window_title_logo_open();
#pragma region Showcase script
enum {
TITLE_SCRIPT_WAIT,
TITLE_SCRIPT_LOAD,
TITLE_SCRIPT_LOCATION,
TITLE_SCRIPT_ROTATE,
TITLE_SCRIPT_RESTART,
};
#define WAIT(t) TITLE_SCRIPT_WAIT, t
#define LOAD() TITLE_SCRIPT_LOAD
#define LOCATION(x, y) TITLE_SCRIPT_LOCATION, x, y
#define ROTATE(n) TITLE_SCRIPT_ROTATE, n
#define RESTART() TITLE_SCRIPT_RESTART
static const uint8 _magicMountainScript[] = {
LOAD(),
LOCATION(210, 112), WAIT(13),
ROTATE(1), LOCATION(210, 112), WAIT(14),
ROTATE(3), LOCATION(167, 180), WAIT(12),
ROTATE(1), LOCATION(155, 189), WAIT(12),
LOCATION(106, 39), WAIT(12),
LOCATION(182, 50), WAIT(12),
ROTATE(3), LOCATION(209, 47), WAIT(12),
ROTATE(1), LOCATION(159, 93), WAIT(12),
RESTART(),
};
static const uint8* _currentScript;
static int _scriptWaitCounter;
static void title_init_showcase();
static void title_update_showcase();
#pragma endregion
static void title_create_windows();
/**
*
* rct2: 0x0068E8DA
*/
*
* rct2: 0x0068E8DA
*/
void title_load()
{
if (RCT2_GLOBAL(0x009DEA6E, uint8) & 1)
@@ -74,10 +112,10 @@ void title_load()
}
/**
* Creates the windows shown on the title screen; New game, load game,
* tutorial, toolbox and exit.
* rct2: 0x0066B5C0 (part of 0x0066B3E8)
*/
* Creates the windows shown on the title screen; New game, load game,
* tutorial, toolbox and exit.
* rct2: 0x0066B5C0 (part of 0x0066B3E8)
*/
static void title_create_windows()
{
// RCT2_CALLPROC_EBPSAFE(0x0066B3E8);
@@ -90,12 +128,104 @@ static void title_create_windows()
}
/**
*
* rct2: 0x00678680
*/
*
* rct2: 0x00678680
*/
static void title_init_showcase()
{
RCT2_CALLPROC_EBPSAFE(0x00678680);
_currentScript = _magicMountainScript;
_scriptWaitCounter = 0;
title_update_showcase();
}
/**
*
* rct2: 0x00678761
*/
static void title_update_showcase()
{
rct_window* w;
uint8 script_opcode, script_operand;
short x, y;
int i, _edx;
if (_scriptWaitCounter <= 0) {
do {
script_opcode = *_currentScript++;
switch (script_opcode) {
case TITLE_SCRIPT_WAIT:
_scriptWaitCounter = (*_currentScript++) * 32;
break;
case TITLE_SCRIPT_LOAD:
scenario_load(get_file_path(PATH_ID_SIXFLAGS_MAGICMOUNTAIN));
w = window_get_main();
w->var_4B0 = -1;
w->var_4B2 = RCT2_GLOBAL(0x0138869A, sint16);
w->var_4B4 = RCT2_GLOBAL(0x0138869C, sint16);
{
char _cl = (RCT2_GLOBAL(0x0138869E, sint16) & 0xFF) - w->viewport->zoom;
w->viewport->zoom = RCT2_GLOBAL(0x0138869E, sint16) & 0xFF;
*((char*)(&RCT2_GLOBAL(0x0141E9E0, sint32))) = RCT2_GLOBAL(0x0138869E, sint16) >> 8;
if (_cl != 0) {
if (_cl < 0) {
_cl = -_cl;
w->viewport->view_width >>= _cl;
w->viewport->view_height >>= _cl;
} else {
w->viewport->view_width <<= _cl;
w->viewport->view_height <<= _cl;
}
}
w->var_4B2 -= w->viewport->view_width >> 1;
w->var_4B4 -= w->viewport->view_height >> 1;
}
window_invalidate(w);
RCT2_CALLPROC_EBPSAFE(0x0069E9A7);
RCT2_CALLPROC_EBPSAFE(0x006ACA58);
RCT2_CALLPROC_EBPSAFE(0x00684AC3);
RCT2_CALLPROC_EBPSAFE(0x006DFEE4);
news_item_init_queue();
gfx_invalidate_screen();
RCT2_GLOBAL(0x009DEA66, sint16) = 0;
RCT2_GLOBAL(0x009DEA5C, sint16) = 0x0D6D8;
break;
case TITLE_SCRIPT_LOCATION:
x = (*_currentScript++) * 32 + 16;
y = (*_currentScript++) * 32 + 16;
// Set location
int eax, ebx, ecx, edx, esi, edi, ebp;
eax = x;
ecx = y;
RCT2_CALLFUNC_X(0x00662783, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
_edx = edx;
// Update viewport
w = window_get_main();
if (w != NULL) {
RCT2_CALLPROC_X(0x006E7C9C, x, 0, y, _edx, w, 0, 0);
w->flags &= ~0x08;
viewport_update_position(w);
}
break;
case TITLE_SCRIPT_ROTATE:
script_operand = (*_currentScript++);
w = window_get_main();
if (w != NULL)
for (i = 0; i < script_operand; i++)
window_rotate_camera(w);
break;
case TITLE_SCRIPT_RESTART:
_currentScript = _magicMountainScript;
break;
}
} while (_scriptWaitCounter == 0);
}
_scriptWaitCounter--;
}
void title_update()
@@ -103,7 +233,7 @@ void title_update()
int tmp;
if (RCT2_GLOBAL(0x009DEA6E, uint8) == 0) {
RCT2_CALLPROC_EBPSAFE(0x00678761); // screen_title_script_tick()
title_update_showcase();
game_logic_update();
}

View File

@@ -439,6 +439,15 @@ rct_window *window_get_main()
return NULL;
}
/**
*
* rct2: 0x0068881A
*/
void window_rotate_camera(rct_window *w)
{
RCT2_CALLPROC_X(0x0068881A, 0, 0, 0, 0, w, 0, 0);
}
/**
* Draws a window that is in the specified region.
* rct2: 0x006E756C

View File

@@ -283,6 +283,8 @@ rct_window *window_bring_to_front(rct_window *w);
rct_window *window_get_main();
void window_rotate_camera(rct_window *w);
void window_draw(rct_window *w, int left, int top, int right, int bottom);
void window_draw_widgets(rct_window *w, rct_drawpixelinfo *dpi);

View File

@@ -242,7 +242,7 @@ static void window_scenarioselect_scrollmousedown()
continue;
sound_play_panned(4, w->width / 2 + w->x);
scenario_load(scenario);
scenario_load_and_play(scenario);
break;
}
}