Merge pull request #1 from IntelOrca/master

Just update
This commit is contained in:
Jeroen Sack 2014-07-09 22:57:14 +02:00
commit 194326817b
38 changed files with 1621 additions and 700 deletions

View File

@ -110,6 +110,7 @@
<ClCompile Include="..\src\window_map.c" />
<ClCompile Include="..\src\window_new_ride.c" />
<ClCompile Include="..\src\window_options.c" />
<ClCompile Include="..\src\window_peep.c" />
<ClCompile Include="..\src\window_ride_list.c" />
<ClCompile Include="..\src\window_save_prompt.c" />
<ClCompile Include="..\src\window_staff.c" />

View File

@ -332,6 +332,9 @@
<ClCompile Include="..\src\award.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\window_peep.c">
<Filter>Windows</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\openrct2.exe">

View File

@ -258,11 +258,20 @@
#define RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID 0x0141E9AE
#define RCT2_ADDRESS_CURRENT_ROTATION 0x0141E9E0
#define RCT2_ADDRESS_FONT_CHAR_WIDTH 0x0141E9E8
#define RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER 0x0141ED68
#define RCT2_ADDRESS_WATER_RAISE_COST 0x0141F738
#define RCT2_ADDRESS_WATER_LOWER_COST 0x0141F73C
#define RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_1 0x0141F740
#define RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_2 0x0141F741
#define RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_3 0x0141F742
#define RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_4 0x0141F743
#define RCT2_ADDRESS_WINDOW_LIST 0x01420078
#define RCT2_ADDRESS_NEW_WINDOW_PTR 0x014234B8
#define RCT2_ADDRESS_VIEWPORT_LIST 0x014234BC

View File

@ -283,9 +283,11 @@ static void climate_update_thunder()
_thunderStereoEcho = 1;
}
} else {
_thunderSoundId = (randomNumber & 0x20000) ? SOUND_THUNDER_1 : SOUND_THUNDER_2;
int pan = (((randomNumber >> 18) & 0xFF) - 128) * 16;
climate_play_thunder(0, _thunderSoundId, 0, pan);
if (_thunderStatus[0] == THUNDER_STATUS_NULL){
_thunderSoundId = (randomNumber & 0x20000) ? SOUND_THUNDER_1 : SOUND_THUNDER_2;
int pan = (((randomNumber >> 18) & 0xFF) - 128) * 16;
climate_play_thunder(0, _thunderSoundId, 0, pan);
}
}
}

View File

@ -125,7 +125,7 @@ void config_load()
{
FILE *fp=NULL;
char* path = get_file_path(PATH_ID_GAMECFG);
const char *path = get_file_path(PATH_ID_GAMECFG);
fp = fopen(path, "rb");

View File

@ -32,6 +32,7 @@
#include "viewport.h"
#include "finance.h"
#include "audio.h"
#include "sprite.h"
#include "string_ids.h"
static void set_all_land_owned();
@ -53,7 +54,7 @@ void editor_load()
RCT2_CALLPROC_EBPSAFE(0x006B9CB0);
reset_park_entrances();
reset_saved_strings();
RCT2_CALLPROC_EBPSAFE(0x0069EB13); // sprites_init
reset_sprite_list();
ride_init_all();
window_guest_list_init_vars_a();
sub_6BD3A4();
@ -102,7 +103,7 @@ void trackdesigner_load()
RCT2_CALLPROC_EBPSAFE(0x006B9CB0);
reset_park_entrances();
reset_saved_strings();
RCT2_CALLPROC_EBPSAFE(0x0069EB13); // reset_sprites
reset_sprite_list();
ride_init_all();
window_guest_list_init_vars_a();
sub_6BD3A4();
@ -140,7 +141,7 @@ void trackmanager_load()
RCT2_CALLPROC_EBPSAFE(0x006B9CB0);
reset_park_entrances();
reset_saved_strings();
RCT2_CALLPROC_EBPSAFE(0x0069EB13); // reset_sprites
reset_sprite_list();
ride_init_all();
window_guest_list_init_vars_a();
sub_6BD3A4();

View File

@ -32,6 +32,7 @@
#include "sawyercoding.h"
#include "scenario.h"
#include "screenshot.h"
#include "sprite.h"
#include "string_ids.h"
#include "title.h"
#include "tutorial.h"
@ -1581,7 +1582,7 @@ int game_load_save()
// The rest is the same as in scenario load and play
RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
map_update_tile_pointers();
RCT2_CALLPROC_EBPSAFE(0x0069EBE4);
reset_0x69EBE4();// RCT2_CALLPROC_EBPSAFE(0x0069EBE4);
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_PLAYING;
viewport_init_all();
game_create_windows();
@ -1607,7 +1608,7 @@ int game_load_save()
mainWindow->saved_view_y -= mainWindow->viewport->view_height >> 1;
window_invalidate(mainWindow);
RCT2_CALLPROC_EBPSAFE(0x0069E9A7);
sub_0x0069E9A7();
RCT2_CALLPROC_EBPSAFE(0x006DFEE4);
window_new_ride_init_vars();
RCT2_GLOBAL(0x009DEB7C, uint16) = 0;
@ -1619,6 +1620,20 @@ int game_load_save()
return 1;
}
/*
*
* rct2: 0x0069E9A7
*/
void sub_0x0069E9A7(){
//RCT2_CALLPROC_EBPSAFE(0x0069E9A7);
//return;
for (rct_sprite* spr = g_sprite_list; spr < (rct_sprite*)RCT2_ADDRESS_SPRITES_NEXT_INDEX; ++spr){
if (spr->unknown.sprite_identifier != 0xFF){
RCT2_CALLPROC_X(0x0069E9D3, spr->unknown.x, 0, spr->unknown.y, spr->unknown.z, (int)spr, 0, 0);
}
}
}
/**
*
* rct2: 0x0066DBB7

View File

@ -24,6 +24,7 @@
void game_create_windows();
void game_update();
void game_logic_update();
void sub_0x0069E9A7();
int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp);

1113
src/gfx.c

File diff suppressed because it is too large Load Diff

View File

@ -43,7 +43,7 @@ typedef struct {
sint16 x_offset; // 0x08
sint16 y_offset; // 0x0A
uint16 flags; // 0x0C
sint16 unused; // 0x0E
sint16 zoomed_offset; // 0x0E
} rct_g1_element;
enum{
@ -62,6 +62,7 @@ extern int gLastDrawStringX;
extern int gLastDrawStringY;
int gfx_load_g1();
void gfx_load_character_widths();
void gfx_clear(rct_drawpixelinfo *dpi, int colour);
void gfx_draw_pixel(rct_drawpixelinfo *dpi, int x, int y, int colour);
@ -69,6 +70,7 @@ void gfx_draw_line(rct_drawpixelinfo *dpi, int x1, int y1, int x2, int y2, int c
void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bottom, int colour);
void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short right, short bottom, int colour, short _si);
void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y);
void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer);
void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, int y);
void gfx_transpose_palette(int pal, unsigned char product);

View File

@ -44,7 +44,7 @@ int marketing_get_campaign_guest_generation_probability(int campaign)
probability /= 8;
break;
case ADVERTISING_CAMPAIGN_RIDE_FREE:
ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[RCT2_ADDRESS(0x01358116, uint8)[campaign]]);
ride = &g_ride_list[RCT2_ADDRESS(0x01358116, uint8)[campaign]];
if (ride->price < 3)
probability /= 8;
break;

View File

@ -182,7 +182,7 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int *
switch (type) {
case NEWS_ITEM_RIDE:
ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[subject]);
ride = &g_ride_list[subject];
if (ride->overall_view == 0xFFFF) {
*x = SPRITE_LOCATION_NULL;
break;
@ -205,17 +205,17 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int *
}
// Find which ride peep is on
ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[peep->current_ride]);
ride = &g_ride_list[peep->current_ride];
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)) {
*x = SPRITE_LOCATION_NULL;
break;
}
// Find the first car of the train peep is on
vehicle = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[ride->train_car_map[peep->current_train]]).vehicle;
vehicle = &(g_sprite_list[ride->train_car_map[peep->current_train]]).vehicle;
// Find the actual car peep is on
for (i = 0; i < peep->current_car; i++)
vehicle = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[vehicle->next_vehicle_on_train]).vehicle;
vehicle = &(g_sprite_list[vehicle->next_vehicle_on_train]).vehicle;
*x = vehicle->x;
*y = vehicle->y;
*z = vehicle->z;

View File

@ -91,6 +91,7 @@ static void osinterface_create_window()
exit(-1);
}
SDL_VERSION(&wmInfo.version);
// Get the HWND context
if (SDL_GetWindowWMInfo(_window, &wmInfo) != SDL_TRUE) {
RCT2_ERROR("SDL_GetWindowWMInfo failed %s", SDL_GetError());

View File

@ -262,7 +262,7 @@ int calculate_park_rating()
num_litter = 0;
for (sprite_idx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_LITTER, uint16); sprite_idx != SPRITE_INDEX_NULL; sprite_idx = litter->next) {
litter = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_idx].litter);
litter = &(g_sprite_list[sprite_idx].litter);
// Guessing this eliminates recently dropped litter
if (litter->var_24 - RCT2_GLOBAL(0x00F663AC, uint32) >= 7680)
@ -305,7 +305,7 @@ money32 calculate_park_value()
// Sum ride values
result = 0;
for (i = 0; i < 255; i++) {
ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[i]);
ride = &g_ride_list[i];
result += calculate_ride_value(ride);
}

View File

@ -58,7 +58,7 @@ void peep_update_all()
spriteIndex = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16);
i = 0;
while (spriteIndex != SPRITE_INDEX_NULL) {
peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[spriteIndex].peep);
peep = &(g_sprite_list[spriteIndex].peep);
spriteIndex = peep->next;
if ((i & 0x7F) != (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 0x7F)) {
@ -103,7 +103,7 @@ static void peep_update(rct_peep *peep)
peep->thoughts[i].var_2++;
ebp--;
}
} else if (peep->thoughts[i].var_2 >= 0) {
} else if (peep->thoughts[i].var_2 > 1) {
if (++peep->thoughts[i].var_3 > 255) {
if (++peep->thoughts[i].var_3 >= 28) {
peep->var_45 |= 1;
@ -181,7 +181,7 @@ void peep_problem_warnings_update()
hunger_counter++;
break;
}
ride = &RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[peep->var_C5];
ride = &g_ride_list[peep->var_C5];
if (!(RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000))
hunger_counter++;
break;
@ -191,7 +191,7 @@ void peep_problem_warnings_update()
thirst_counter++;
break;
}
ride = &RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[peep->var_C5];
ride = &g_ride_list[peep->var_C5];
if (!(RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x1000000))
thirst_counter++;
break;
@ -201,7 +201,7 @@ void peep_problem_warnings_update()
bathroom_counter++;
break;
}
ride = &RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[peep->var_C5];
ride = &g_ride_list[peep->var_C5];
if (!(RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x2000000))
bathroom_counter++;
break;

View File

@ -200,7 +200,7 @@ enum PEEP_STATE {
PEEP_STATE_SITTING = 8,
PEEP_STATE_PICKED = 9,
PEEP_STATE_PATROLLING = 10, // Not sure
PEEP_STATE_MOPING = 11,
PEEP_STATE_MOWING = 11,
PEEP_STATE_SWEEPING = 12,
PEEP_STATE_ENTERING_PARK = 13,
PEEP_STATE_LEAVING_PARK = 14,
@ -316,10 +316,10 @@ typedef struct {
uint8 pad_01;
uint16 pad_02;
uint16 next; // 0x04
uint16 pad_06;
uint16 previous; // 0x06
uint8 var_08;
uint8 pad_09;
sint16 var_0A;
uint16 sprite_index; // 0x0A
uint16 var_0C;
sint16 x; // 0x0E
sint16 y; // 0x10
@ -420,7 +420,7 @@ typedef struct {
} rct_peep;
/** Helper macro until rides are stored in this module. */
#define GET_PEEP(sprite_index) &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_index].peep)
#define GET_PEEP(sprite_index) &(g_sprite_list[sprite_index].peep)
/**
* Helper macro loop for enumerating through all the non null rides. To avoid needing a end loop counterpart, statements are

View File

@ -33,6 +33,7 @@
#include "climate.h"
#include "config.h"
#include "date.h"
#include "editor.h"
#include "game.h"
#include "gfx.h"
#include "intro.h"
@ -47,6 +48,7 @@
#include "title.h"
#include "track.h"
#include "viewport.h"
#include "sprite.h"
typedef struct tm tm_t;
@ -157,7 +159,9 @@ void rct2_init()
scenario_load_list();
track_load_list(253);
gfx_load_g1();
RCT2_CALLPROC_EBPSAFE(0x006C19AC);
//RCT2_CALLPROC_EBPSAFE(0x006C19AC); //Load character widths
gfx_load_character_widths();
osinterface_init();
RCT2_CALLPROC_EBPSAFE(0x006BA8E0); // init_audio();
viewport_init_all();
@ -165,10 +169,10 @@ void rct2_init()
get_local_time();
reset_park_entrances();
reset_saved_strings();
RCT2_CALLPROC_EBPSAFE(0x0069EB13);
reset_sprite_list();
ride_init_all();
window_guest_list_init_vars_a();
RCT2_CALLPROC_EBPSAFE(0x006BD3A4);
sub_6BD3A4();// RCT2_CALLPROC_EBPSAFE(0x006BD3A4); //Peep?
map_init();
park_init();
RCT2_CALLPROC_EBPSAFE(0x0066B5C0); // 0x0066B5C0 (part of 0x0066B3E8) screen_game_create_windows()
@ -228,9 +232,16 @@ void subsitute_path(char *dest, const char *path, const char *filename)
// rct2: 0x00674B42
void rct2_startup_checks()
{
// check if game is already running
// Check if game is already running
if (check_mutex())
{
RCT2_ERROR("Game is already running");
RCT2_CALLPROC_X(0x006E3838, 0x343, 0xB2B, 0, 0, 0, 0, 0); // exit_with_error
}
RCT2_CALLPROC_EBPSAFE(0x00674C0B);
// Check data files
check_file_paths();
check_files_integrity();
}
void rct2_update()
@ -301,6 +312,99 @@ void check_cmdline_arg()
}
}
// rct2: 0x00407DB0
int check_mutex()
{
const char * const mutex_name = "RollerCoaster Tycoon 2_GSKMUTEX"; // rct2 @ 0x009AAC3D + 0x009A8B50
HANDLE mutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, mutex_name);
if (mutex != NULL)
{
// Already running
CloseHandle(mutex);
return 1;
}
HANDLE status = CreateMutex(NULL, FALSE, mutex_name);
return 0;
}
// rct2: 0x00674C95
void check_file_paths()
{
for (int pathId = 0; pathId < PATH_ID_END; pathId += 1)
{
check_file_path(pathId);
}
}
// rct2: 0x00674CA5
void check_file_path(int pathId)
{
const char * path = get_file_path(pathId);
HANDLE file = CreateFile(path, FILE_GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
switch (pathId)
{
case PATH_ID_GAMECFG:
case PATH_ID_SCORES:
// Do nothing; these will be created later if they do not exist yet
break;
case PATH_ID_CUSTOM1:
if (file != INVALID_HANDLE_VALUE)
RCT2_GLOBAL(0x009AF164, unsigned int) = SetFilePointer(file, 0, 0, FILE_END); // Store file size in music_custom1_size @ 0x009AF164
break;
case PATH_ID_CUSTOM2:
if (file != INVALID_HANDLE_VALUE)
RCT2_GLOBAL(0x009AF16E, unsigned int) = SetFilePointer(file, 0, 0, FILE_END); // Store file size in music_custom2_size @ 0x009AF16E
break;
default:
if (file == INVALID_HANDLE_VALUE) {
// A data file is missing from the installation directory. The original implementation
// asks for a CD-ROM path at this point and stores it in cdrom_path @ 0x9AA318.
// The file_on_cdrom[pathId] @ 0x009AA0B flag is set to 1 as well.
// For PATH_ID_SIXFLAGS_MAGICMOUNTAIN and PATH_ID_SIXFLAGS_BUILDYOUROWN,
// the original implementation always assumes they are stored on CD-ROM.
// This has been removed for now for the sake of simplicity and could be added
// later in a more convenient way using the INI file.
RCT2_ERROR("Could not find file %s", path);
RCT2_CALLPROC_X(0x006E3838, 0x343, 0x337, 0, 0, 0, 0, 0); // exit_with_error
}
break;
}
if (file != INVALID_HANDLE_VALUE)
CloseHandle(file);
}
// rct2: 0x00674C0B
void check_files_integrity()
{
int i = 0;
while (files_to_check[i].pathId != PATH_ID_END)
{
WIN32_FIND_DATA find_data;
const char * path = get_file_path(files_to_check[i].pathId);
HANDLE file = FindFirstFile(path, &find_data);
if (file == INVALID_HANDLE_VALUE || find_data.nFileSizeLow != files_to_check[i].fileSize)
{
if (file != INVALID_HANDLE_VALUE)
FindClose(file);
RCT2_ERROR("Integrity check failed for %s", path);
RCT2_CALLPROC_X(0x006E3838, 0x343, 0x337, 0, 0, 0, 0, 0); // exit_with_error
}
FindClose(file);
i += 1;
}
}
void rct2_update_2()
{
int tick, tick2;
@ -342,13 +446,39 @@ void rct2_endupdate()
*
* rct2: 0x00674E6C
*/
char *get_file_path(int pathId)
const char *get_file_path(int pathId)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
static char path[MAX_PATH]; // get_file_path_buffer @ 0x009E3605
ebx = pathId;
RCT2_CALLFUNC_X(0x00674E6C, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
return (char*)ebx;
// The original implementation checks if the file is on CD-ROM here (file_on_cdrom[pathId] @ 0x009AA0B1).
// If so, the CD-ROM path (cdrom_path @ 0x9AA318) is used instead. This has been removed for now for
// the sake of simplicity.
strcpy(path, gGeneral_config.game_path);
// Make sure base path is terminated with a slash
if (strlen(path) == 0 || path[strlen(path) - 1] != '\\')
{
if (strlen(path) >= MAX_PATH - 1)
{
RCT2_ERROR("Path for %s too long", file_paths[pathId]);
path[0] = '\0';
return path;
}
strcat(path, "\\");
}
// Concatenate file path
if (strlen(path) + strlen(file_paths[pathId]) > MAX_PATH)
{
RCT2_ERROR("Path for %s too long", file_paths[pathId]);
path[0] = '\0';
return path;
}
strcat(path, file_paths[pathId]);
return path;
}
/**

View File

@ -157,13 +157,116 @@ enum {
PATH_ID_CSS43,
PATH_ID_CSS44,
PATH_ID_CSS45,
PATH_ID_CSS46
PATH_ID_CSS46,
PATH_ID_END
};
// rct2 @ 0x0097F67C
static const char * const file_paths[] =
{
"Data\\G1.DAT",
"Data\\PLUGIN.DAT",
"Data\\CSS1.DAT",
"Data\\CSS2.DAT",
"Data\\CSS4.DAT",
"Data\\CSS5.DAT",
"Data\\CSS6.DAT",
"Data\\CSS7.DAT",
"Data\\CSS8.DAT",
"Data\\CSS9.DAT",
"Data\\CSS10.DAT",
"Data\\CSS11.DAT",
"Data\\CSS12.DAT",
"Data\\CSS13.DAT",
"Data\\CSS14.DAT",
"Data\\CSS15.DAT",
"Data\\CSS16.DAT",
"Data\\CSS3.DAT",
"Data\\GAME.CFG",
"Data\\TUT640A.DAT",
"Data\\TUT640B.DAT",
"Data\\TUT640C.DAT",
"Data\\TUT800A.DAT",
"Data\\TUT800B.DAT",
"Data\\TUT800C.DAT",
"Data\\KANJI.DAT",
"Data\\CSS17.DAT",
"Data\\CSS18.DAT",
"Data\\CSS19.DAT",
"Data\\CSS20.DAT",
"Data\\CSS21.DAT",
"Data\\CSS22.DAT",
"Saved Games\\scores.DAT",
"Data\\CSS23.DAT",
"Data\\CSS24.DAT",
"Data\\CSS25.DAT",
"Data\\CSS26.DAT",
"Data\\CSS27.DAT",
"Data\\CSS28.DAT",
"Data\\CSS29.DAT",
"Data\\CSS30.DAT",
"Data\\CSS31.DAT",
"Data\\CSS32.DAT",
"Data\\CSS33.DAT",
"Data\\CSS34.DAT",
"Data\\CSS35.DAT",
"Data\\CSS36.DAT",
"Data\\CSS37.DAT",
"Data\\CSS38.DAT",
"Data\\CUSTOM1.WAV",
"Data\\CUSTOM2.WAV",
"Data\\CSS39.DAT",
"Data\\CSS40.DAT",
"Tracks\\Tracks.IDX",
"Data\\CSS41.DAT",
"Scenarios\\Six Flags Magic Mountain.SC6",
"Scenarios\\Build your own Six Flags Park.SC6",
"Data\\CSS42.DAT",
"Data\\CSS43.DAT",
"Data\\CSS44.DAT",
"Data\\CSS45.DAT",
"Data\\CSS46.DAT"
};
// Files to check (rct2 @ 0x0097FB5A)
static const struct file_to_check
{
int pathId; // ID of file
unsigned int fileSize; // Expected size in bytes
} files_to_check[] = {
{ PATH_ID_CSS18, 8429568 },
{ PATH_ID_CSS19, 10143784 },
{ PATH_ID_CSS20, 12271656 },
{ PATH_ID_CSS21, 9680968 },
{ PATH_ID_CSS22, 10062056 },
{ PATH_ID_CSS23, 11067432 },
{ PATH_ID_CSS24, 12427456 },
{ PATH_ID_CSS25, 15181512 },
{ PATH_ID_CSS26, 10694816 },
{ PATH_ID_CSS27, 10421232 },
{ PATH_ID_CSS28, 13118376 },
{ PATH_ID_CSS29, 15310892 },
{ PATH_ID_CSS30, 10215464 },
{ PATH_ID_CSS31, 11510316 },
{ PATH_ID_CSS32, 11771944 },
{ PATH_ID_CSS33, 10759724 },
{ PATH_ID_CSS34, 14030716 },
{ PATH_ID_CSS35, 11642576 },
{ PATH_ID_CSS36, 8953764 },
{ PATH_ID_CSS37, 13303852 },
{ PATH_ID_CSS38, 10093888 },
{ PATH_ID_CSS39, 7531564 },
{ PATH_ID_CSS40, 5291306 },
{ PATH_ID_END, 0 }
};
void rct2_endupdate();
void subsitute_path(char *dest, const char *path, const char *filename);
char *get_file_path(int pathId);
int check_mutex();
void check_file_paths();
void check_file_path(int pathId);
void check_files_integrity();
const char *get_file_path(int pathId);
void get_system_info();
void get_system_time();
void get_local_time();

View File

@ -99,6 +99,8 @@ const uint8 gRideClassifications[255] = {
#pragma endregion
rct_ride* g_ride_list = RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride);
int ride_get_count()
{
rct_ride *ride;
@ -139,7 +141,7 @@ void ride_init_all()
rct_ride_measurement *ride_measurement;
for (i = 0; i < MAX_RIDES; i++) {
ride = GET_RIDE(i);
ride = &g_ride_list[i];
ride->type = RIDE_TYPE_NULL;
}
@ -183,7 +185,7 @@ void ride_update_favourited_stat()
if (peep->var_08 != 4)
return;
if (peep->favourite_ride != 0xff) {
ride = GET_RIDE(peep->favourite_ride);
ride = &g_ride_list[peep->favourite_ride];
ride->guests_favourite++;
ride->var_14D |= 1;
@ -280,7 +282,7 @@ void ride_shop_connected(rct_ride* ride, int ride_idx)
}
uint8 track_type = tile->properties.track.type;
ride = GET_RIDE(tile->properties.track.ride_index);
ride = &g_ride_list[tile->properties.track.ride_index];
if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) {
entrance_directions = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16];
} else {

View File

@ -326,8 +326,11 @@ enum {
#define MAX_RIDE_MEASUREMENTS 8
#define RIDE_RELIABILITY_UNDEFINED 0xFFFF
// rct2: 0x013628F8
extern rct_ride* g_ride_list;
/** Helper macros until rides are stored in this module. */
#define GET_RIDE(x) (&(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[x]))
#define GET_RIDE(x) (&g_ride_list[x])
#define GET_RIDE_MEASUREMENT(x) (&(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_MEASUREMENTS, rct_ride_measurement)[x]))
/**
@ -335,7 +338,7 @@ enum {
*/
#define FOR_ALL_RIDES(i, ride) \
for (i = 0; i < MAX_RIDES; i++) \
if ((ride = GET_RIDE(i))->type != RIDE_TYPE_NULL)
if ((ride = &g_ride_list[i])->type != RIDE_TYPE_NULL)
extern const uint8 gRideClassifications[255];

View File

@ -154,7 +154,7 @@ void scenario_load(const char *path)
RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
map_update_tile_pointers();
RCT2_CALLPROC_EBPSAFE(0x0069EBE4);
reset_0x69EBE4();// RCT2_CALLPROC_EBPSAFE(0x0069EBE4);
return;
}
@ -214,7 +214,7 @@ void scenario_load_and_play(const rct_scenario_basic *scenario)
mainWindow->saved_view_y -= mainWindow->viewport->view_height >> 1;
window_invalidate(mainWindow);
RCT2_CALLPROC_EBPSAFE(0x0069E9A7);
sub_0x0069E9A7();// RCT2_CALLPROC_EBPSAFE(0x0069E9A7);
window_new_ride_init_vars();
// Set the scenario pseduo-random seeds
@ -501,7 +501,7 @@ void scenario_objectives_check()
rct_ride* ride;
int rcs = 0;
for (int i = 0; i < MAX_RIDES; i++) {
ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[i]);
ride = &g_ride_list[i];
if (ride->status && ride->excitement > objective_currency)
rcs++;
}

View File

@ -19,8 +19,11 @@
*****************************************************************************/
#include "addresses.h"
#include <string.h>
#include "sprite.h"
rct_sprite* g_sprite_list = RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite);
/**
*
* rct2: 0x006736C7
@ -28,4 +31,77 @@
void create_balloon(int x, int y, int z, int colour)
{
RCT2_CALLPROC_X(0x006736C7, x, colour << 8, y, z, 0, 0, 0);
}
/*
*
* rct2: 0x0069EB13
*/
void reset_sprite_list(){
RCT2_GLOBAL(0x1388698, uint16) = 0;
memset(g_sprite_list, 0, sizeof(rct_sprite)* 0x2710);
for (int i = 0; i < 6; ++i){
RCT2_ADDRESS(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16)[i] = -1;
RCT2_ADDRESS(0x13573C8, uint16)[i] = 0;
}
rct_sprite* previous_spr = (rct_sprite*)SPRITE_INDEX_NULL;
rct_sprite* spr = g_sprite_list;
for (int i = 0; i < 0x2710; ++i){
spr->unknown.sprite_identifier = 0xFF;
spr->unknown.sprite_index = i;
spr->unknown.next = SPRITE_INDEX_NULL;
spr->unknown.var_08 = 0;
if (previous_spr != (rct_sprite*)SPRITE_INDEX_NULL){
spr->unknown.previous = previous_spr->unknown.sprite_index;
previous_spr->unknown.next = i;
}
else{
spr->unknown.previous = SPRITE_INDEX_NULL;
RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16) = i;
}
previous_spr = spr;
spr++;
}
RCT2_GLOBAL(0x13573C8, uint16) = 0x2710;
//RCT2_CALLPROC_EBPSAFE(0x0069EBE4);
reset_0x69EBE4();
}
/*
*
* rct: 0x0069EBE4
* This function looks as though it sets some sort of order for sprites.
* Sprites can share thier position if this is the case.
*/
void reset_0x69EBE4(){
//RCT2_CALLPROC_EBPSAFE(0x0069EBE4);
//return;
memset((uint16*)0xF1EF60, -1, 0x10001*2);
rct_sprite* spr = g_sprite_list;
for (; spr < (rct_sprite*)RCT2_ADDRESS_SPRITES_NEXT_INDEX; spr++){
if (spr->unknown.sprite_identifier != 0xFF){
uint32 edi = spr->unknown.x;
if ((uint16)(spr->unknown.x) == SPRITE_LOCATION_NULL){
edi = 0x10000;
}
else{
int ecx = spr->unknown.y;
ecx >>= 5;
edi &= 0x1FE0;
edi <<= 3;
edi |= ecx;
}
uint16 ax = RCT2_ADDRESS(0xF1EF60,uint16)[edi];
RCT2_ADDRESS(0xF1EF60,uint16)[edi] = spr->unknown.sprite_index;
spr->unknown.var_02 = ax;
}
}
}

View File

@ -32,9 +32,13 @@
typedef struct {
uint8 sprite_identifier; // 0x00
uint8 pad_01;
uint16 pad_02;
uint16 var_02;
uint16 next; // 0x04
uint8 pad_06[0x08];
uint16 previous; // 0x06
uint8 var_08;
uint8 pad_09;
uint16 sprite_index; // 0x0A
uint8 pad_0C[2];
sint16 x; // 0x0E
sint16 y; // 0x10
sint16 z; // 0x12
@ -43,7 +47,11 @@ typedef struct {
typedef struct {
uint32 pad_00;
uint16 next; // 0x04
uint8 pad_06[0x1E];
uint16 previous; // 0x06
uint8 var_08;
uint8 pad_09;
uint16 sprite_index; // 0x0A
uint8 pad_0B[0x19];
uint32 var_24;
} rct_litter;
@ -59,6 +67,11 @@ typedef union {
rct_vehicle vehicle;
} rct_sprite;
// rct2: 0x010E63BC
extern rct_sprite* g_sprite_list;
void create_balloon(int x, int y, int z, int colour);
void reset_sprite_list();
void reset_0x69EBE4();
#endif

View File

@ -24,11 +24,24 @@
enum {
SPR_NONE = -1,
SPR_PALETTE_1_START = 3100,
SPR_PALETTE_1_END = 3110,
SPR_COOL_AND_WET = 3290,
SPR_WARM = 3291,
SPR_HOT_AND_DRY = 3292,
SPR_COLD = 3293,
// This is the start of every character there are
// 224 characters per font (first 32 are control codes hence why it doesn't go to 255)
// 4 fonts
// = 896 sprites
SPR_CHAR_START = 3861,
SPR_CHAR_END = 4757,
SPR_PALETTE_2_START = 4915,
SPR_PALETTE_2_END = 5047,
SPR_RESIZE = 5058,
SPR_HEARING_VIEWPORT = 5166,

View File

@ -29,17 +29,41 @@ void reset_saved_strings();
enum {
// Font format codes
FORMAT_TINYFONT = 7,
// The next byte specifies the X coordinate
FORMAT_MOVE_X = 1,
// The next byte specifies the palette
FORMAT_ADJUST_PALETTE,
// Moves to the next line
FORMAT_NEWLINE = 5,
// Moves less than NEWLINE
FORMAT_NEWLINE_SMALLER,
FORMAT_TINYFONT,
FORMAT_BIGFONT,
FORMAT_MEDIUMFONT,
FORMAT_SMALLFONT,
FORMAT_OUTLINE,
FORMAT_OUTLINE_OFF,
// Changes the colour of the text to a predefined window colour.
FORMAT_WINDOW_COLOUR_1,
FORMAT_WINDOW_COLOUR_2,
FORMAT_WINDOW_COLOUR_3,
// The next 2 bytes specify the X and Y coordinates
FORMAT_NEWLINE_X_Y = 17,
// The next 4 bytes specify the sprite
FORMAT_INLINE_SPRITE = 23,
// Non ascii-characters
FORMAT_ENDQUOTES = 34,
// Argument format codes
FORMAT_ARGUMENT_CODE_START = 123,
FORMAT_COMMA32 = 123,
FORMAT_INT32,
FORMAT_COMMA2DP32,
@ -61,6 +85,7 @@ enum {
FORMAT_SPRITE,
// Colour format codes
FORMAT_COLOUR_CODE_START = 142,
FORMAT_BLACK = 142,
FORMAT_GREY,
FORMAT_WHITE,
@ -75,6 +100,7 @@ enum {
FORMAT_LIGHTPINK,
FORMAT_PEARLAQUA,
FORMAT_PALESILVER,
FORMAT_COLOUR_CODE_END = FORMAT_PALESILVER,
// Extra non-ascii characters
FORMAT_AMINUSCULE = 159,
@ -273,9 +299,29 @@ enum {
STR_FOOTPATH_TIP = 1424,
STR_FREE = 1430,
STR_WALKING = 1431,
STR_HEADING_FOR = 1432,
STR_QUEUING_FOR = 1433,
STR_DROWNING = 1434,
STR_ON_RIDE = 1435,
STR_IN_RIDE = 1436,
STR_AT_RIDE = 1437,
STR_SITTING = 1438,
STR_SELECT_LOCATION = 1439,
STR_MOWING_GRASS = 1440,
STR_SWEEPING_FOOTPATH = 1441,
STR_EMPTYING_LITTER_BIN = 1442,
STR_WATERING_GARDENS = 1443,
STR_WATCHING_RIDE = 1444,
STR_WATCHING_CONSTRUCTION_OF = 1445,
STR_LOOKING_AT_SCENERY = 1446,
STR_LEAVING_PARK = 1447,
STR_WATCHING_NEW_RIDE_BEING_CONSTRUCTED = 1448,
STR_GUESTS = 1463,
STR_THOUGHT_START = 1480,
STR_CONSTRUCT_FOOTPATH_ON_LAND_TIP = 1655,
STR_CONSTRUCT_BRIDGE_OR_TUNNEL_FOOTPATH_TIP = 1656,
@ -300,6 +346,11 @@ enum {
STR_OFF = 1775,
STR_ON = 1776,
STR_MUSIC = 1777,
STR_RESPONDING_TO_RIDE_BREAKDOWN_CALL = 1792,
STR_HEADING_TO_RIDE_FOR_INSPECTION = 1793,
STR_FIXING_RIDE = 1794,
STR_ANSWERING_RADIO_CALL = 1795,
STR_ACTIONS = 1814,
STR_THOUGHTS = STR_ACTIONS + 1,
@ -331,7 +382,9 @@ enum {
STR_GUESTS_FAVOURITE_PLURAL_LABEL = 1843,
STR_RIDE_LIST_INFORMATION_TYPE_TIP = 1844,
STR_NUM_GUESTS = 1846,
STR_INSPECTING_RIDE = 1886,
STR_BUILD_RIDE_TIP = 1895,
STR_START_NEW_GAME_TIP = 1921,
@ -348,6 +401,11 @@ enum {
STR_MARKETING = 1953,
STR_RESEARCH_FUNDING = 1954,
STR_ITEM_START = 1988,
STR_ITEM_SINGULAR_START = 2044,
STR_ITEM2_START = 2090,
STR_ITEM2_SINGULAR_START = 2134,
STR_CELSIUS_VALUE = 2216,
STR_FAHRENHEIT_VALUE = 2217,

View File

@ -23,6 +23,7 @@
#include <time.h>
#include "addresses.h"
#include "config.h"
#include "climate.h"
#include "date.h"
#include "game.h"
#include "gfx.h"
@ -33,6 +34,7 @@
#include "rct2.h"
#include "ride.h"
#include "scenario.h"
#include "sprite.h"
#include "string_ids.h"
#include "viewport.h"
#include "editor.h"
@ -95,20 +97,20 @@ void title_load()
reset_park_entrances();
reset_saved_strings();
RCT2_CALLPROC_EBPSAFE(0x0069EB13);
reset_sprite_list();
ride_init_all();
window_guest_list_init_vars_a();
RCT2_CALLPROC_EBPSAFE(0x006BD3A4);
sub_6BD3A4(); // RCT2_CALLPROC_EBPSAFE(0x006BD3A4);
map_init();
park_init();
date_reset();
RCT2_CALLPROC_X(0x006C45ED, 0, 0, 0, 0, 0, 0, 0);
climate_reset(CLIMATE_COOL_AND_WET);
RCT2_CALLPROC_EBPSAFE(0x006DFEE4);
window_new_ride_init_vars();
window_guest_list_init_vars_b();
window_staff_init_vars();
RCT2_CALLPROC_EBPSAFE(0x0068AFFD);
RCT2_CALLPROC_EBPSAFE(0x0069EBE4);
map_update_tile_pointers(); //RCT2_CALLPROC_EBPSAFE(0x0068AFFD);
reset_0x69EBE4();// RCT2_CALLPROC_EBPSAFE(0x0069EBE4);
viewport_init_all();
news_item_init_queue();
title_create_windows();
@ -191,7 +193,7 @@ static void title_update_showcase()
}
window_invalidate(w);
RCT2_CALLPROC_EBPSAFE(0x0069E9A7);
sub_0x0069E9A7();// RCT2_CALLPROC_EBPSAFE(0x0069E9A7);
window_new_ride_init_vars();
RCT2_CALLPROC_EBPSAFE(0x00684AC3);
RCT2_CALLPROC_EBPSAFE(0x006DFEE4);
@ -244,14 +246,10 @@ static void DrawOpenRCT2(int x, int y)
gfx_fill_rect_inset(dpi, x, y, x + 128, y + 20, 0x80 | 12, 0x8);
// Format text (name and version)
sprintf(buffer, "%c%c%s, v%s", FORMAT_MEDIUMFONT, FORMAT_BLACK, OPENRCT2_NAME, OPENRCT2_VERSION);
sprintf(buffer, "%c%c%c%s, v%s", FORMAT_MEDIUMFONT, FORMAT_OUTLINE, FORMAT_WHITE, OPENRCT2_NAME, OPENRCT2_VERSION);
// Draw shadow
// Draw Text
gfx_draw_string(dpi, buffer, 0, x + 5, y + 5);
// Draw text
buffer[1] = FORMAT_WHITE;
gfx_draw_string(dpi, buffer, 0, x + 4, y + 4);
}

View File

@ -42,7 +42,7 @@ void vehicle_update_all()
sprite_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_VEHICLE, uint16);
while (sprite_index != SPRITE_INDEX_NULL) {
vehicle = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_index].vehicle);
vehicle = &(g_sprite_list[sprite_index].vehicle);
sprite_index = vehicle->next;
vehicle_update(vehicle);

View File

@ -27,7 +27,11 @@ typedef struct {
uint8 sprite_identifier; // 0x00
uint8 pad_01[0x03];
uint16 next; // 0x04
uint8 pad_06[0x08];
uint16 previous; // 0x06
uint8 var_08;
uint8 pad_09;
uint16 sprite_index; // 0x0A
uint8 pad_0C[2];
sint16 x; // 0x0E
sint16 y; // 0x10
sint16 z; // 0x12

View File

@ -22,6 +22,7 @@
#include <memory.h>
#include <stdlib.h>
#include "addresses.h"
#include "gfx.h"
#include "sprites.h"
#include "widget.h"
#include "window.h"
@ -914,21 +915,23 @@ static void widget_draw_image(rct_drawpixelinfo *dpi, rct_window *w, int widgetI
// Draw greyed out (light border bottom right shadow)
colour = w->colours[widget->colour];
colour = RCT2_ADDRESS(0x00141FC4A, uint8)[(colour & 0x7F) * 8] & 0xFF;
RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009DED74;
memset((void*)0x009DED74, colour, 256);
RCT2_GLOBAL(0x009DED74, uint8) = 0;
uint8 palette[256];
memset(palette, colour, 256);
palette[0] = 0;
RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000;
image &= 0x7FFFF;
RCT2_CALLPROC_X(0x0067A46E, 0, image, l + 1, t + 1, 0, (int)dpi, 0);
gfx_draw_sprite_palette_set(dpi, image | 0x20000000, l + 1, t + 1, palette, NULL);
// Draw greyed out (dark)
colour = w->colours[widget->colour];
colour = RCT2_ADDRESS(0x00141FC48, uint8)[(colour & 0x7F) * 8] & 0xFF;
RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009DED74;
memset((void*)0x009DED74, colour, 256);
RCT2_GLOBAL(0x009DED74, uint8) = 0;
memset(palette, colour, 256);
palette[0] = 0;
RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000;
RCT2_CALLPROC_X(0x0067A46E, 0, image, l, t, 0, (int)dpi, 0);
gfx_draw_sprite_palette_set(dpi, image | 0x20000000, l, t, palette, NULL);
} else {
if (image & 0x80000000) {
// ?

View File

@ -336,9 +336,8 @@ static void window_all_wheel_input()
rct_window *window_create(int x, int y, int width, int height, uint32 *event_handlers, rct_windowclass cls, uint16 flags)
{
rct_window *w;
// Check if there are any window slots left
if (RCT2_NEW_WINDOW == &(RCT2_FIRST_WINDOW[12])) {
if (RCT2_NEW_WINDOW >= &(RCT2_FIRST_WINDOW[11])) {
// Close least recently used window
for (w = RCT2_FIRST_WINDOW; w < RCT2_NEW_WINDOW; w++)
if (!(w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT | WF_9)))
@ -999,10 +998,10 @@ void window_draw(rct_window *w, int left, int top, int right, int bottom)
RCT2_GLOBAL(0x01420070, sint32) = v->x;
// Text colouring
RCT2_GLOBAL(0x0141F740, uint8) = v->colours[0] & 0x7F;
RCT2_GLOBAL(0x0141F741, uint8) = v->colours[1] & 0x7F;
RCT2_GLOBAL(0x0141F742, uint8) = v->colours[2] & 0x7F;
RCT2_GLOBAL(0x0141F743, uint8) = v->colours[3] & 0x7F;
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_1, uint8) = v->colours[0] & 0x7F;
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_2, uint8) = v->colours[1] & 0x7F;
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_3, uint8) = v->colours[2] & 0x7F;
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_4, uint8) = v->colours[3] & 0x7F;
// Invalidate the window
RCT2_CALLPROC_X(v->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)v, 0, 0);

View File

@ -23,6 +23,7 @@
#include "gfx.h"
#include "park.h"
#include "peep.h"
#include "rct2.h"
struct rct_window;
@ -354,6 +355,7 @@ void window_water_open();
void window_guest_list_open();
void window_map_open();
void window_options_open();
void window_peep_open(rct_peep* peep);
void window_park_awards_open();
void window_park_entrance_open();
void window_park_guests_open();

View File

@ -48,6 +48,7 @@ enum WINDOW_CHEATS_WIDGET_IDX {
WIDX_TAB_1,
WIDX_TAB_2,
WIDX_HIGH_MONEY,
WIDX_PARK_ENTRANCE_FEE,
WIDX_HAPPY_GUESTS = 6 //Same as HIGH_MONEY as it is also the 6th widget but on a different page
};
@ -58,7 +59,8 @@ static rct_widget window_cheats_money_widgets[] = {
{ WWT_IMGBTN, 1, 0, WW - 1, 43, WH - 1, 0x0FFFFFFFF, 65535}, // tab content panel
{ WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 2462}, // tab 1
{ WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 2462}, // tab 2
{ WWT_CLOSEBOX, 1, 4, 74, 47, 63, STR_VERY_HIGH, STR_VERY_HIGH}, // high money
{ WWT_CLOSEBOX, 1, 4, 74, 67, 83, STR_VERY_HIGH, STR_VERY_HIGH}, // high money
{ WWT_CLOSEBOX, 1, 4, 74, 107, 123, STR_FREE, STR_FREE}, //Park Entrance Fee Toggle
{ WIDGETS_END },
};
@ -69,7 +71,7 @@ static rct_widget window_cheats_guests_widgets[] = {
{ WWT_IMGBTN, 1, 0, WW - 1, 43, WH - 1, 0x0FFFFFFFF, 65535 }, // tab content panel
{ WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 2462 }, // tab 1
{ WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 2462 }, // tab 2
{ WWT_CLOSEBOX, 1, 4, 74, 47, 63, STR_EXTREME, STR_EXTREME}, // happy guests
{ WWT_CLOSEBOX, 1, 4, 74, 77, 93, STR_EXTREME, STR_EXTREME}, // happy guests
{ WIDGETS_END },
};
@ -154,7 +156,7 @@ static void* window_cheats_page_events[] = {
};
static uint32 window_cheats_page_enabled_widgets[] = {
(1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_HIGH_MONEY),
(1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_HIGH_MONEY) | (1 << WIDX_PARK_ENTRANCE_FEE),
(1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_HAPPY_GUESTS)
};
@ -218,6 +220,12 @@ static void window_cheats_money_mouseup()
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32) = ENCRYPT_MONEY(i);
window_invalidate_by_id(0x40 | WC_BOTTOM_TOOLBAR, 0);
break;
case WIDX_PARK_ENTRANCE_FEE:
RCT2_GLOBAL(0x13573E5, uint32) ^= 0x020;
if (!(RCT2_GLOBAL(0x13573E5, uint32) & 0x020) ) w->widgets[widgetIndex].image = 2010;
else w->widgets[widgetIndex].image = STR_FREE;
window_invalidate_by_id(0x40 | WC_PARK_INFORMATION, 0);
break;
}
}
@ -317,6 +325,26 @@ static void window_cheats_paint()
window_draw_widgets(w, dpi);
window_cheats_draw_tab_images(dpi, w);
if (w->page == WINDOW_CHEATS_PAGE_MONEY){
char buffer[256];
// Format text
sprintf(buffer, "%c%c%s", FORMAT_MEDIUMFONT, FORMAT_BLACK, "Increases your money by 1,000.");
// Draw shadow
gfx_draw_string(dpi, buffer, 0, w->x + 4, w->y + 50);
sprintf(buffer, "%c%c%s", FORMAT_MEDIUMFONT, FORMAT_BLACK, "Toggle between Free and Paid Entry");
// Draw shadow
gfx_draw_string(dpi, buffer, 0, w->x + 4, w->y + 90);
}
else if (w->page == WINDOW_CHEATS_PAGE_GUESTS){
char buffer[256];
// Format text
sprintf(buffer, "%c%c%s%c%s", FORMAT_MEDIUMFONT, FORMAT_BLACK, "Increases every peeps happiness ", FORMAT_NEWLINE, "to max.");
// Draw shadow
gfx_draw_string(dpi, buffer, 0, w->x + 4, w->y + 50);
}
}
static void window_cheats_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w)
@ -328,7 +356,7 @@ static void window_cheats_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w)
sprite_idx = 5261;
if (w->page == WINDOW_CHEATS_PAGE_MONEY)
sprite_idx += (w->var_48E / 2) % 8;
gfx_draw_sprite(dpi, sprite_idx, w->x + w->widgets[WIDX_TAB_1].left, w->y + w->widgets[WIDX_TAB_1].top);
gfx_draw_sprite(dpi, sprite_idx, w->x + w->widgets[WIDX_TAB_1].left, w->y + w->widgets[WIDX_TAB_1].top);
}
// Guests tab

View File

@ -53,6 +53,7 @@ int _dropdown_highlighted_index;
uint16 gDropdownItemsFormat[64];
sint64 gDropdownItemsArgs[64];
// Replaces 0x009DED38
uint32 gDropdownItemsChecked;
static void window_dropdown_emptysub() { }

View File

@ -215,13 +215,13 @@ static void window_game_bottom_toolbar_mouseup()
static void window_game_bottom_toolbar_tooltip()
{
int month, day;
short widgetIndex;
short tool_tip_index;
rct_window *w;
#ifdef _MSC_VER
__asm mov widgetIndex, dx
__asm mov tool_tip_index, ax
#else
__asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) );
__asm__ ( "mov %[tool_tip_index], ax " : [tool_tip_index] "+m" (tool_tip_index) );
#endif
#ifdef _MSC_VER
@ -231,32 +231,25 @@ static void window_game_bottom_toolbar_tooltip()
#endif
switch (widgetIndex) {
switch (tool_tip_index) {
case WIDX_MONEY:
RCT2_GLOBAL(0x013CE952, int) = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PROFIT, sint32);
RCT2_GLOBAL(0x013CE956, int) = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PARK_VALUE, sint32);
widgetIndex = 0;
tool_tip_index = 0;
break;
case WIDX_PARK_RATING:
RCT2_GLOBAL(0x013CE952, short) = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PARK_RATING, sint16);
widgetIndex = 0;
tool_tip_index = 0;
break;
case WIDX_DATE:
month = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, sint16) & 7;
day = ((RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_TICKS, sint16) * days_in_month[month]) >> 16) & 0xFF;
day = ((RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_TICKS, uint16) * days_in_month[month]) >> 16) & 0xFF;
RCT2_GLOBAL(0x013CE952, short) = STR_DATE_DAY_1 + day;
RCT2_GLOBAL(0x013CE954, short) = STR_MONTH_MARCH + month;
widgetIndex = 0;
tool_tip_index = 0;
break;
}
#ifdef _MSC_VER
__asm mov dx, widgetIndex
#else
__asm__ ( "mov dx, %[widgetIndex] " : [widgetIndex] "+m" (widgetIndex) );
#endif
}
/**

View File

@ -19,12 +19,14 @@
*****************************************************************************/
#include <string.h>
#include <assert.h>
#include "addresses.h"
#include "game.h"
#include "peep.h"
#include "string_ids.h"
#include "sprite.h"
#include "sprites.h"
#include "ride.h"
#include "widget.h"
#include "window.h"
#include "window_dropdown.h"
@ -132,7 +134,9 @@ static int window_guest_list_is_peep_in_filter(rct_peep* peep);
static void window_guest_list_find_groups();
static int get_guest_face_sprite_small(rct_peep *peep);
static int get_guest_face_sprite_large(rct_peep *peep);
static void get_arguments_from_peep(rct_peep *peep, uint32 *argument_1, uint32* argument_2);
void get_arguments_from_thought(rct_peep_thought thought, uint32* argument_1, uint32* argument_2);
void get_arguments_from_action(rct_peep* peep, uint32* argument_1, uint32* argument_2);
/**
*
* rct2: 0x006992E3
@ -277,11 +281,16 @@ static void window_guest_list_mousedown(int widgetIndex, rct_window*w, rct_widge
gDropdownItemsFormat[i] = 1142;
gDropdownItemsArgs[i] = STR_PAGE_1 + i;
}
RCT2_GLOBAL(0x009DED38, uint32) |= (1 << _window_guest_list_selected_view);
gDropdownItemsChecked = (1 << _window_guest_list_selected_view);
break;
case WIDX_INFO_TYPE_DROPDOWN_BUTTON:
widget = &w->widgets[widgetIndex - 1];
for (i = 0; i < 2; i++) {
gDropdownItemsFormat[i] = 1142;
gDropdownItemsArgs[i] = STR_ACTIONS + i;
}
window_dropdown_show_text_custom_width(
w->x + widget->left,
w->y + widget->top,
@ -292,11 +301,7 @@ static void window_guest_list_mousedown(int widgetIndex, rct_window*w, rct_widge
widget->right - widget->left - 3
);
for (i = 0; i < 2; i++) {
gDropdownItemsFormat[i] = 1142;
gDropdownItemsArgs[i] = STR_ACTIONS + i;
}
RCT2_GLOBAL(0x009DED38, uint32) |= (1 << _window_guest_list_selected_view);
gDropdownItemsChecked = (1 << _window_guest_list_selected_view);
break;
}
}
@ -472,7 +477,8 @@ static void window_guest_list_scrollmousedown()
if (i == 0) {
// Open guest window
RCT2_CALLPROC_X(0x006989E9, 0, 0, 0, (int)peep, 0, 0, 0);
window_peep_open(peep);
break;
} else {
i--;
@ -653,6 +659,7 @@ static void window_guest_list_scrollpaint()
rct_drawpixelinfo *dpi;
rct_peep *peep;
rct_peep_thought *thought;
uint32 argument_1, argument_2;
#ifdef _MSC_VER
__asm mov w, esi
@ -715,14 +722,11 @@ static void window_guest_list_scrollpaint()
gfx_draw_sprite(dpi, 5129, 112, y);
// Action
eax = peep->var_0A;
RCT2_CALLFUNC_X(0x00698B0D, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
ebx &= 0xFFFF;
ecx &= 0xFFFF;
RCT2_GLOBAL(0x013CE952, uint16) = ebx;
RCT2_GLOBAL(0x013CE952 + 2, uint16) = ecx;
RCT2_GLOBAL(0x013CE952 + 4, uint32) = edx;
get_arguments_from_action(peep, &argument_1, &argument_2);
RCT2_GLOBAL(0x013CE952, uint32) = argument_1;
RCT2_GLOBAL(0x013CE952 + 4, uint32) = argument_2;
gfx_draw_string_left_clipped(dpi, format, (void*)0x013CE952, 0, 133, y - 1, 314);
break;
case VIEW_THOUGHTS:
@ -735,15 +739,11 @@ static void window_guest_list_scrollpaint()
continue;
if (thought->var_2 > 5)
break;
get_arguments_from_thought(peep->thoughts[j], &argument_1, &argument_2);
ebx = thought->type;
eax = thought->item;
RCT2_CALLFUNC_X(0x00698342, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
ebx &= 0xFFFF;
RCT2_GLOBAL(0x013CE952, uint16) = ebx;
RCT2_GLOBAL(0x013CE952 + 2, uint32) = *((uint32*)esi);
RCT2_GLOBAL(0x013CE952 + 6, uint16) = *((uint16*)(esi + 4));
RCT2_GLOBAL(0x013CE952, uint32) = argument_1;
RCT2_GLOBAL(0x013CE952 + 4, uint32) = argument_2;
gfx_draw_string_left_clipped(dpi, format, (void*)0x013CE952, 0, 118, y - 1, 329);
break;
}
@ -777,11 +777,10 @@ static void window_guest_list_scrollpaint()
// Draw guest faces
numGuests = _window_guest_list_groups_num_guests[i];
for (j = 0; j < 56 && j < numGuests; j++)
gfx_draw_sprite(dpi, _window_guest_list_groups_guest_faces[numGuests * 56 + j] + 5486, j * 8, y + 9);
gfx_draw_sprite(dpi, _window_guest_list_groups_guest_faces[i * 56 + j] + 5486, j * 8, y + 9);
// Draw action
RCT2_GLOBAL(0x013CE952, uint16) = _window_guest_list_groups_argument_1[i] & 0xFFFF;
RCT2_GLOBAL(0x013CE952 + 2, uint16) = _window_guest_list_groups_argument_1[i] >> 16;
RCT2_GLOBAL(0x013CE952, uint32) = _window_guest_list_groups_argument_1[i];
RCT2_GLOBAL(0x013CE952 + 4, uint32) = _window_guest_list_groups_argument_2[i];
RCT2_GLOBAL(0x013CE952 + 10, uint32) = numGuests;
gfx_draw_string_left_clipped(dpi, format, (void*)0x013CE952, 0, 0, y - 1, 414);
@ -796,68 +795,226 @@ static void window_guest_list_scrollpaint()
}
}
/**
*
* returns 0 for in filter and 1 for not in filter
* rct2: 0x0069B865
*/
static int window_guest_list_is_peep_in_filter(rct_peep* peep)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
char temp;
temp = _window_guest_list_selected_view;
_window_guest_list_selected_view = _window_guest_list_selected_filter;
esi = (int)peep;
RCT2_CALLFUNC_X(0x0069B7EA, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
ebx &= 0xFFFF;
int argument1, argument2;
get_arguments_from_peep(peep, &argument1, &argument2);
_window_guest_list_selected_view = temp;
eax = (RCT2_GLOBAL(0x013CE952, uint16) << 16) | ebx;
if (((RCT2_GLOBAL(0x00F1EDF6, uint32) >> 16) & 0xFFFF) == 0xFFFF && _window_guest_list_selected_filter == 1)
eax |= 0xFFFF;
argument1 |= 0xFFFF;
if (eax == RCT2_GLOBAL(0x00F1EDF6, uint32) && RCT2_GLOBAL(0x013CE954, uint32) == RCT2_GLOBAL(0x00F1EDFA, uint32))
if (argument1 == RCT2_GLOBAL(0x00F1EDF6, uint32) && argument2 == RCT2_GLOBAL(0x00F1EDFA, uint32))
return 0;
return 1;
}
static int sub_69B7EA(rct_peep *peep, int *outEAX)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
/**
* rct2: 0x00698342
* thought.item (eax)
* thought.type (ebx)
* argument_1 (esi & ebx)
* argument_2 (esi+2)
*/
void get_arguments_from_thought(rct_peep_thought thought, uint32* argument_1, uint32* argument_2){
int esi = 0x9AC86C;
if ((RCT2_ADDRESS(0x981DB1, uint16)[thought.type] & 0xFF) & 1){
rct_ride* ride = &g_ride_list[thought.item];
esi = &(ride->var_04A);
}
else if ((RCT2_ADDRESS(0x981DB1, uint16)[thought.type] & 0xFF) & 2){
if (thought.item < 0x20){
RCT2_GLOBAL(0x9AC86C, uint16) = thought.item + STR_ITEM_START;
}
else{
RCT2_GLOBAL(0x9AC86C, uint16) = thought.item + STR_ITEM2_START;
}
}
else if ((RCT2_ADDRESS(0x981DB1, uint16)[thought.type] & 0xFF) & 4){
if (thought.item < 0x20){
RCT2_GLOBAL(0x9AC86C, uint16) = thought.item + STR_ITEM_SINGULAR_START;
}
else
{
RCT2_GLOBAL(0x9AC86C, uint16) = thought.item + STR_ITEM2_SINGULAR_START;
}
}
else{
esi = 0x9AC864; //No thought?
}
*argument_1 = ((thought.type + STR_THOUGHT_START) & 0xFFFF) | (*((uint16*)esi) << 16);
*argument_2 = *((uint32*)(esi+2)); //Always 0 apart from on rides?
}
/**
* rct2: 0x00698B0D
* peep.sprite_index (eax)
* thought.type (ebx)
* argument_1 (ecx & ebx)
* argument_2 (edx)
*/
void get_arguments_from_action(rct_peep* peep, uint32 *argument_1, uint32* argument_2){
rct_ride ride;
switch (peep->state){
case 0:
*argument_1 = peep->var_71 == 0xB ? STR_DROWNING : STR_WALKING;
*argument_2 = 0;
break;
case 1:
*argument_1 = STR_WALKING;
*argument_2 = 0;
break;
case PEEP_STATE_ON_RIDE:
case PEEP_STATE_LEAVING_RIDE:
case PEEP_STATE_ENTERING_RIDE:
*argument_1 = STR_ON_RIDE;
ride = g_ride_list[peep->current_ride];
if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride.type*8, uint32)& 0x400000){
*argument_1 = STR_IN_RIDE;
}
*argument_1 |= (ride.var_04A << 16);
*argument_2 = ride.var_04C;
break;
case PEEP_STATE_BUYING:
ride = g_ride_list[peep->current_ride];
*argument_1 = STR_AT_RIDE | (ride.var_04A << 16);
*argument_2 = ride.var_04C;
break;
case PEEP_STATE_WALKING:
case 0x14:
if (peep->var_C5 != 0xFF){
ride = g_ride_list[peep->var_C5];
*argument_1 = STR_HEADING_FOR | (ride.var_04A << 16);
*argument_2 = ride.var_04C;
}
else{
*argument_1 = peep->flags & 1 ? STR_LEAVING_PARK : STR_WALKING;
*argument_2 = 0;
}
break;
case PEEP_STATE_QUEUING_FRONT:
case PEEP_STATE_QUEUING:
ride = g_ride_list[peep->current_ride];
*argument_1 = STR_QUEUING_FOR | (ride.var_04A << 16);
*argument_2 = ride.var_04C;
break;
case PEEP_STATE_SITTING:
*argument_1 = STR_SITTING;
*argument_2 = 0;
break;
case PEEP_STATE_WATCHING:
if (peep->current_ride != 0xFF){
ride = g_ride_list[peep->current_ride];
*argument_1 = STR_WATCHING_RIDE | (ride.var_04A << 16);
*argument_2 = ride.var_04C;
if (peep->current_seat & 0x1)
*argument_1 = STR_WATCHING_CONSTRUCTION_OF | (ride.var_04A << 16);
else
*argument_1 = STR_WATCHING_RIDE | (ride.var_04A << 16);
}
else{
*argument_1 = peep->current_seat & 0x1 ? STR_WATCHING_NEW_RIDE_BEING_CONSTRUCTED : STR_LOOKING_AT_SCENERY;
*argument_2 = 0;
}
break;
case PEEP_STATE_PICKED:
*argument_1 = STR_SELECT_LOCATION;
*argument_2 = 0;
break;
case PEEP_STATE_PATROLLING:
case PEEP_STATE_ENTERING_PARK:
case PEEP_STATE_LEAVING_PARK:
*argument_1 = STR_WALKING;
*argument_2 = 0;
break;
case PEEP_STATE_MOWING:
*argument_1 = STR_MOWING_GRASS;
*argument_2 = 0;
break;
case PEEP_STATE_SWEEPING:
*argument_1 = STR_SWEEPING_FOOTPATH;
*argument_2 = 0;
break;
case PEEP_STATE_WATERING:
*argument_1 = STR_WATERING_GARDENS;
*argument_2 = 0;
break;
case PEEP_STATE_EMPTYING_BIN:
*argument_1 = STR_EMPTYING_LITTER_BIN;
*argument_2 = 0;
break;
case PEEP_STATE_ANSWERING:
if (peep->pad_2C == 0){
*argument_1 = STR_WALKING;
*argument_2 = 0;
}
else if (peep->pad_2C == 1){
*argument_1 = STR_ANSWERING_RADIO_CALL;
*argument_2 = 0;
}
else{
ride = g_ride_list[peep->current_ride];
*argument_1 = STR_RESPONDING_TO_RIDE_BREAKDOWN_CALL | (ride.var_04A << 16);
*argument_2 = ride.var_04C;
}
break;
case PEEP_STATE_FIXING:
ride = g_ride_list[peep->current_ride];
*argument_1 = STR_FIXING_RIDE | (ride.var_04A << 16);
*argument_2 = ride.var_04C;
break;
case PEEP_STATE_HEADING_TO_INSPECTION:
ride = g_ride_list[peep->current_ride];
*argument_1 = STR_HEADING_TO_RIDE_FOR_INSPECTION | (ride.var_04A << 16);
*argument_2 = ride.var_04C;
break;
case PEEP_STATE_INSPECTING:
ride = g_ride_list[peep->current_ride];
*argument_1 = STR_INSPECTING_RIDE | (ride.var_04A << 16);
*argument_2 = ride.var_04C;
break;
}
}
/**
* rct2:0x0069B7EA
* Calculates a hash value (arguments) for comparing peep actions/thoughts
* peep (esi)
* argument_1 (0x013CE952)
* argument_2 (0x013CE954)
*/
static void get_arguments_from_peep(rct_peep *peep, uint32 *argument_1, uint32* argument_2)
{
switch (_window_guest_list_selected_view) {
case VIEW_ACTIONS:
eax = peep->var_0A;
RCT2_CALLFUNC_X(0x00698B0D, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
RCT2_GLOBAL(0x013CE952, uint16) = ecx & 0xFFFF;
RCT2_GLOBAL(0x013CE952 + 2, uint32) = edx;
*outEAX = eax;
return ebx & 0xFFFF;
get_arguments_from_action(peep, argument_1, argument_2);
break;
case VIEW_THOUGHTS:
if (peep->thoughts[0].var_2 <= 5) {
eax = peep->thoughts[0].item;
ebx = peep->thoughts[0].type;
if (peep->thoughts[0].type != PEEP_THOUGHT_TYPE_NONE) {
RCT2_CALLFUNC_X(0x00698342, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
RCT2_GLOBAL(0x013CE952, uint16) = *((uint16*)esi);
RCT2_GLOBAL(0x013CE952 + 2, uint32) = *((uint32*)(esi + 2));
*outEAX = eax;
return ebx & 0xFFFF;
get_arguments_from_thought(peep->thoughts[0], argument_1, argument_2);
break;
}
}
RCT2_GLOBAL(0x013CE952, uint16) = 0;
RCT2_GLOBAL(0x013CE952 + 2, uint32) = 0;
*outEAX = 0;
return 0;
default:
*argument_1 = 0;
*argument_2 = 0;
}
return 0;
return;
}
/**
@ -894,16 +1051,15 @@ static void window_guest_list_find_groups()
if (groupIndex >= 240)
break;
int ax = peep->var_0A;
int ax = peep->sprite_index;
_window_guest_list_num_groups++;
_window_guest_list_groups_num_guests[groupIndex] = 1;
peep->var_0C &= ~(1 << 8);
int bx = sub_69B7EA(peep, &eax);
eax = (RCT2_GLOBAL(0x013CE952, uint16) << 16) | bx;
RCT2_GLOBAL(0x00F1EDF6, uint32) = eax;
_window_guest_list_groups_argument_1[groupIndex] = eax;
RCT2_GLOBAL(0x00F1EDFA, uint32) = RCT2_GLOBAL(0x013CE952 + 2, uint32);
_window_guest_list_groups_argument_2[groupIndex] = RCT2_GLOBAL(0x013CE952 + 2, uint32);
get_arguments_from_peep( peep, &_window_guest_list_groups_argument_1[groupIndex], &_window_guest_list_groups_argument_2[groupIndex]);
RCT2_GLOBAL(0x00F1EDF6, uint32) = _window_guest_list_groups_argument_1[groupIndex];
RCT2_GLOBAL(0x00F1EDFA, uint32) = _window_guest_list_groups_argument_2[groupIndex];
RCT2_ADDRESS(0x00F1AF26, uint8)[groupIndex] = groupIndex;
faceIndex = groupIndex * 56;
_window_guest_list_groups_guest_faces[faceIndex++] = get_guest_face_sprite_small(peep) - 5486;
@ -913,10 +1069,10 @@ static void window_guest_list_find_groups()
if (peep2->var_2A != 0 || !(peep2->var_0C & (1 << 8)))
continue;
int argument1, argument2;
// Get and check if in same group
// BUG this doesn't work!
bx = sub_69B7EA(peep2, &eax);
if (bx != RCT2_GLOBAL(0x00F1EDF6, uint32) || (eax & 0xFFFF) != RCT2_GLOBAL(0x013CE952, uint16) || eax != RCT2_GLOBAL(0x013CE952 + 2, uint32))
get_arguments_from_peep(peep2, &argument1, &argument2);
if (argument1 != _window_guest_list_groups_argument_1[groupIndex] || argument2 != _window_guest_list_groups_argument_2[groupIndex] )
continue;
// Assign guest
@ -924,7 +1080,7 @@ static void window_guest_list_find_groups()
peep2->var_0C &= ~(1 << 8);
// Add face sprite, cap at 56 though
if (_window_guest_list_groups_num_guests[groupIndex] < 56)
if (_window_guest_list_groups_num_guests[groupIndex] >= 56)
continue;
_window_guest_list_groups_guest_faces[faceIndex++] = get_guest_face_sprite_small(peep2) - 5486;
}
@ -934,38 +1090,44 @@ static void window_guest_list_find_groups()
continue;
}
ax = _window_guest_list_groups_num_guests[groupIndex];
int edi = 0;
int curr_num_guests = _window_guest_list_groups_num_guests[groupIndex];
int swap_position = 0;
//This section places the groups in size order.
while (1) {
if (edi >= groupIndex)
if (swap_position >= groupIndex)
goto nextPeep;
if (ax > _window_guest_list_groups_num_guests[edi])
if (curr_num_guests > _window_guest_list_groups_num_guests[swap_position])
break;
edi++;
swap_position++;
}
int ecx = _window_guest_list_groups_argument_1[groupIndex];
int edx = _window_guest_list_groups_argument_2[groupIndex];
int argument_1 = _window_guest_list_groups_argument_1[groupIndex];
int argument_2 = _window_guest_list_groups_argument_2[groupIndex];
int bl = RCT2_ADDRESS(0x00F1AF26, uint8)[groupIndex];
int temp;
do {
temp = ax;
ax = _window_guest_list_groups_num_guests[edi];
_window_guest_list_groups_num_guests[edi] = temp;
temp = curr_num_guests;
curr_num_guests = _window_guest_list_groups_num_guests[swap_position];
_window_guest_list_groups_num_guests[swap_position] = temp;
temp = ecx;
ecx = _window_guest_list_groups_argument_1[edi];
_window_guest_list_groups_argument_1[edi] = temp;
temp = argument_1;
argument_1 = _window_guest_list_groups_argument_1[swap_position];
_window_guest_list_groups_argument_1[swap_position] = temp;
temp = edx;
edx = _window_guest_list_groups_argument_2[edi];
_window_guest_list_groups_argument_2[edi] = temp;
temp = argument_2;
argument_2 = _window_guest_list_groups_argument_2[swap_position];
_window_guest_list_groups_argument_2[swap_position] = temp;
RCT2_ADDRESS(0x00F1AF26, uint8)[edi] = bl;
bl = RCT2_ADDRESS(0x00F1AF26, uint8)[edi];
} while (++edi <= groupIndex);
uint8 temp_faces[56];
memcpy(temp_faces, &(_window_guest_list_groups_guest_faces[groupIndex*56]), 56);
memcpy(&(_window_guest_list_groups_guest_faces[groupIndex * 56]), &(_window_guest_list_groups_guest_faces[swap_position * 56]), 56);
memcpy(&(_window_guest_list_groups_guest_faces[swap_position * 56]), temp_faces, 56);
temp = RCT2_ADDRESS(0x00F1AF26, uint8)[swap_position];
RCT2_ADDRESS(0x00F1AF26, uint8)[swap_position] = bl;
bl = temp;
} while (++swap_position <= groupIndex);
nextPeep:
;
@ -980,10 +1142,10 @@ static int get_guest_face_sprite_small(rct_peep *peep)
{
int sprite;
sprite = SPR_PEEP_SMALL_FACE_ANGRY;
if (peep->var_F3) return sprite;
sprite = SPR_PEEP_SMALL_FACE_VERY_VERY_SICK;
if (peep->nausea > 200) return sprite;
sprite--; //VERY_SICK

View File

@ -1188,7 +1188,7 @@ static void window_park_scroll_to_viewport(rct_window *w)
return;
if (*((uint32*)&w->var_486) & 0x80000000) {
rct_sprite *sprite = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[w->var_482]);
rct_sprite *sprite = &(g_sprite_list[w->var_482]);
x = sprite->unknown.x;
y = sprite->unknown.y;
z = sprite->unknown.z;

175
src/window_peep.c Normal file
View File

@ -0,0 +1,175 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John, Duncan Frost
* 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 "addresses.h"
#include "game.h"
#include "peep.h"
#include "string_ids.h"
#include "sprite.h"
#include "sprites.h"
#include "widget.h"
#include "window.h"
#include "window_dropdown.h"
enum WINDOW_PEEP_PAGE {
WINDOW_PEEP_OVERVIEW,
WINDOW_PEEP_STATS,
WINDOW_PEEP_RIDES,
WINDOW_PEEP_FINANCE,
WINDOW_PEEP_THOUGHTS,
WINDOW_PEEP_INVENTORY
};
enum WINDOW_PEEP_WIDGET_IDX {
WIDX_BACKGROUND,
WIDX_TITLE,
WIDX_CLOSE,
WIDX_PAGE_BACKGROUND,
WIDX_TAB_1,
WIDX_TAB_2,
WIDX_TAB_3,
WIDX_TAB_4,
WIDX_TAB_5,
WIDX_TAB_6,
};
void window_peep_emptysub(){};
rct_widget window_peep_overview_widgets[] = {
{ WWT_FRAME, 0, 0, 191, 0, 156, 0x0FFFFFFFF, STR_NONE }, // Panel / Background
{ WWT_CAPTION, 0, 1, 190, 1, 14, 865, STR_WINDOW_TITLE_TIP }, // Title
{ WWT_CLOSEBOX, 0, 179, 189, 2, 13, 824, STR_CLOSE_WINDOW_TIP }, // Close x button
{ WWT_RESIZE, 1, 1, 191, 43, 156, 0x0FFFFFFFF, STR_NONE }, // Resize
{ WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 1938 }, // Tab 1
{ WWT_TAB, 1, 73, 64, 17, 43, 0x2000144E, 1940}, // Tab 2
{ WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, 1941}, // Tab 3
{ WWT_TAB, 1, 96, 126, 17, 43, 0x2000144E, 1942}, // Tab 4
{ WWT_TAB, 1, 127, 157, 17, 43, 0x2000144E, 1943}, // Tab 5
{ WWT_TAB, 1, 158, 188, 17, 43, 0x2000144E, 1944}, // Tab 6
{ WWT_12, 1, 3, 166, 45, 56, 0x0FFFFFFFF, STR_NONE}, // Label Thought marquee
{ WWT_VIEWPORT, 1, 3, 166, 57, 143, 0x0FFFFFFFF, STR_NONE }, // Viewport
{ WWT_12, 1, 3, 166, 144, 154, 0x0FFFFFFFF, STR_NONE}, // Label Action
{ WWT_FLATBTN, 1, 167, 190, 45, 68, SPR_RENAME, 1706}, // Rename Button
{ WWT_FLATBTN, 1, 167, 190, 69, 92, 0x1430, 1055}, // Pickup Button
{ WWT_FLATBTN, 1, 167, 190, 93, 116, SPR_LOCATE, STR_LOCATE_SUBJECT_TIP},// Locate Button
{ WWT_FLATBTN, 1, 167, 190, 117, 140, SPR_TRACK_PEEP, 1930}, // Track Button
{ WIDGETS_END },
};
rct_widget *window_peep_page_widgets[] = {
window_peep_overview_widgets
};
static void* window_peep_overview_events[] = {
0x696A75,
0x696A06,
0x696FBE,
window_peep_emptysub,
window_peep_emptysub,
window_peep_emptysub,
0x696F45,
window_peep_emptysub,
window_peep_emptysub,
0x696A5F,
0x696A54,
window_peep_emptysub,
window_peep_emptysub,
0x696A49,
window_peep_emptysub,
window_peep_emptysub,
window_peep_emptysub,
window_peep_emptysub,
window_peep_emptysub,
0x696A6A,
0x697076,
window_peep_emptysub,
window_peep_emptysub,
window_peep_emptysub,
window_peep_emptysub,
0x696749, //Invalidate
0x696887, //Paint
0x69707C
};
void* window_peep_page_events[] = {
window_peep_overview_events
};
uint32 window_peep_page_enabled_widgets[] = {
(1 << WIDX_CLOSE) |
(1 << WIDX_TAB_1) |
(1 << WIDX_TAB_2) |
(1 << WIDX_TAB_3) |
(1 << WIDX_TAB_4) |
(1 << WIDX_TAB_5) |
(1 << WIDX_TAB_6)
};
/**
* rct2: 0x006989E9
*
*/
void window_peep_open(rct_peep* peep){
if (peep->type == PEEP_TYPE_STAFF){
RCT2_CALLPROC_X(0x006989E9, 0, 0, 0, (int)peep, 0, 0, 0);
}
rct_window* window;
window = window_bring_to_front_by_id(WC_PEEP, peep->sprite_index);
if (window == NULL){
window = window_create_auto_pos(192, 157, (uint32*)window_peep_overview_events, WC_PEEP, 0);
window->widgets = window_peep_overview_widgets;
window->enabled_widgets = window_peep_page_enabled_widgets[0];
window->number = peep->sprite_index;
window->page = 0;
window->var_482 = 0;
window->var_48E = 0;
window->var_490 = 0;
window->var_492 = 0;
window->var_494 = 0;
RCT2_CALLPROC_X(0x006987A6, 0, 0, 0, 0, (int)window, 0, 0);
window->min_width = 192;
window->min_height = 157;
window->max_width = 500;
window->max_height = 450;
window->flags = 8;
window->var_476 = 0;
window->var_47A = -1;
window->colours[0] = 1;
window->colours[1] = 15;
window->colours[2] = 15;
window->var_482 = -1;
}
window->page = 0;
RCT2_CALLPROC_X(0x006EB13A, 0, 0, 0, 0, (int)window, 0, 0);
window->widgets = RCT2_GLOBAL(0x981D0C, uint32);
window->enabled_widgets = RCT2_GLOBAL(0x981D3C,uint32);
window->var_020 = RCT2_GLOBAL(0x981D54,uint32);
window->event_handlers = RCT2_GLOBAL(0x981D24,uint32);
window->pressed_widgets = 0;
RCT2_CALLPROC_X(0x006987A6, 0, 0, 0, 0, (int)window, 0, 0);
window_init_scroll_widgets(window);
RCT2_CALLPROC_X(0x0069883C, 0, 0, 0, 0, (int)window, 0, 0);
}

View File

@ -557,7 +557,7 @@ static void window_ride_list_scrollpaint()
}
// Get ride
ride = &RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[w->var_076[i]];
ride = &g_ride_list[w->var_076[i]];
// Ride name
gfx_draw_string_left_clipped(dpi, format, &ride->var_04A, 0, 0, y - 1, 159);
@ -703,7 +703,7 @@ static void window_ride_list_refresh_list(rct_window *w)
RCT2_GLOBAL(0x013CE952, uint32) = ride->var_04C;
RCT2_CALLPROC_X(0x006C2538, ride->var_04A, 0, 0x013CE952, 0, 0, 0x0141ED68, 0);
while (--k >= 0) {
otherRide = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[w->var_076[k]]);
otherRide = &g_ride_list[w->var_076[k]];
RCT2_GLOBAL(0x013CE952, uint32) = otherRide->var_04C;
RCT2_CALLPROC_X(0x006C2538, otherRide->var_04A, 0, 0x013CE952, 0, 0, 0x0141EF68, 0);
if (strcmp((char*)0x0141ED68, (char*)0x0141EF68) >= 0)
@ -716,7 +716,7 @@ static void window_ride_list_refresh_list(rct_window *w)
break;
case INFORMATION_TYPE_POPULARITY:
while (--k >= 0) {
otherRide = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[w->var_076[k]]);
otherRide = &g_ride_list[w->var_076[k]];
if ((ride->var_158 & 0xFF) * 4 <= (otherRide->var_158 & 0xFF) * 4)
break;
@ -727,7 +727,7 @@ static void window_ride_list_refresh_list(rct_window *w)
break;
case INFORMATION_TYPE_SATISFACTION:
while (--k >= 0) {
otherRide = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[w->var_076[k]]);
otherRide = &g_ride_list[w->var_076[k]];
if ((ride->var_14A & 0xFF) * 5 <= (otherRide->var_14A & 0xFF) * 5)
break;
@ -738,7 +738,7 @@ static void window_ride_list_refresh_list(rct_window *w)
break;
case INFORMATION_TYPE_PROFIT:
while (--k >= 0) {
otherRide = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[w->var_076[k]]);
otherRide = &g_ride_list[w->var_076[k]];
if (ride->profit <= otherRide->profit)
break;
@ -749,7 +749,7 @@ static void window_ride_list_refresh_list(rct_window *w)
break;
case INFORMATION_TYPE_QUEUE_LENGTH:
while (--k >= 0) {
otherRide = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[w->var_076[k]]);
otherRide = &g_ride_list[w->var_076[k]];
if (ride_get_total_queue_length(ride) <= ride_get_total_queue_length(otherRide))
break;
@ -760,7 +760,7 @@ static void window_ride_list_refresh_list(rct_window *w)
break;
case INFORMATION_TYPE_QUEUE_TIME:
while (--k >= 0) {
otherRide = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[w->var_076[k]]);
otherRide = &g_ride_list[w->var_076[k]];
if (ride_get_max_queue_time(ride) <= ride_get_max_queue_time(otherRide))
break;
@ -771,7 +771,7 @@ static void window_ride_list_refresh_list(rct_window *w)
break;
case INFORMATION_TYPE_RELIABILITY:
while (--k >= 0) {
otherRide = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[w->var_076[k]]);
otherRide = &g_ride_list[w->var_076[k]];
if (ride->var_196 >> 8 <= otherRide->var_196 >> 8)
break;
@ -782,7 +782,7 @@ static void window_ride_list_refresh_list(rct_window *w)
break;
case INFORMATION_TYPE_DOWN_TIME:
while (--k >= 0) {
otherRide = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[w->var_076[k]]);
otherRide = &g_ride_list[w->var_076[k]];
if (ride->var_199 <= otherRide->var_199)
break;
@ -793,7 +793,7 @@ static void window_ride_list_refresh_list(rct_window *w)
break;
case INFORMATION_TYPE_GUESTS_FAVOURITE:
while (--k >= 0) {
otherRide = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[w->var_076[k]]);
otherRide = &g_ride_list[w->var_076[k]];
if (ride->guests_favourite <= otherRide->guests_favourite)
break;