diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj
index 00362abcc4..89c9d0d52b 100644
--- a/projects/openrct2.vcxproj
+++ b/projects/openrct2.vcxproj
@@ -110,6 +110,7 @@
+
diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters
index dd606605a9..00b53db492 100644
--- a/projects/openrct2.vcxproj.filters
+++ b/projects/openrct2.vcxproj.filters
@@ -332,6 +332,9 @@
Source Files
+
+ Windows
+
diff --git a/src/addresses.h b/src/addresses.h
index 3dcd895af5..90f044fcbd 100644
--- a/src/addresses.h
+++ b/src/addresses.h
@@ -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
diff --git a/src/climate.c b/src/climate.c
index 37bae75fda..ca0c832038 100644
--- a/src/climate.c
+++ b/src/climate.c
@@ -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);
+ }
}
}
diff --git a/src/config.c b/src/config.c
index 41551d94a5..c82a4cb8b1 100644
--- a/src/config.c
+++ b/src/config.c
@@ -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");
diff --git a/src/editor.c b/src/editor.c
index f9f2a43c70..d70af6bea9 100644
--- a/src/editor.c
+++ b/src/editor.c
@@ -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();
diff --git a/src/game.c b/src/game.c
index a5327e18c8..76bd399391 100644
--- a/src/game.c
+++ b/src/game.c
@@ -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
diff --git a/src/game.h b/src/game.h
index 4b1bd42d4c..47d7f51ceb 100644
--- a/src/game.h
+++ b/src/game.h
@@ -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);
diff --git a/src/gfx.c b/src/gfx.c
index 4304589758..6fd0515136 100644
--- a/src/gfx.c
+++ b/src/gfx.c
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2014 Ted John, Peter Hill
+ * Copyright (c) 2014 Ted John, Peter Hill, Duncan Frost
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* This file is part of OpenRCT2.
@@ -27,6 +27,7 @@
#include "gfx.h"
#include "rct2.h"
#include "string_ids.h"
+#include "sprites.h"
#include "window.h"
#include "osinterface.h"
@@ -68,6 +69,46 @@ uint8 text_palette[0x8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
+// Previously 0x97FCBC use it to get the correct palette from g1_elements
+uint16 palette_to_g1_offset[] = {
+ 0x1333, 0x1334, 0x1335, 0x1336,
+ 0x1337, 0x1338, 0x1339, 0x133A,
+ 0x133B, 0x133C, 0x133D, 0x133E,
+ 0x133F, 0x1340, 0x1341, 0x1342,
+ 0x1343, 0x1344, 0x1345, 0x1346,
+ 0x1347, 0x1348, 0x1349, 0x134A,
+ 0x134B, 0x134C, 0x134D, 0x134E,
+ 0x134F, 0x1350, 0x1351, 0x1352,
+ 0x1353, 0x0C1C, 0x0C1D, 0x0C1E,
+ 0x0C1F, 0x0C20, 0x0C22, 0x0C23,
+ 0x0C24, 0x0C25, 0x0C26, 0x0C21,
+ 0x1354, 0x1355, 0x1356, 0x1357,
+ 0x1358, 0x1359, 0x135A, 0x135B,
+ 0x135C, 0x135D, 0x135E, 0x135F,
+ 0x1360, 0x1361, 0x1362, 0x1363,
+ 0x1364, 0x1365, 0x1366, 0x1367,
+ 0x1368, 0x1369, 0x136A, 0x136B,
+ 0x136C, 0x136D, 0x136E, 0x136F,
+ 0x1370, 0x1371, 0x1372, 0x1373,
+ 0x1374, 0x1375, 0x1376, 0x1377,
+ 0x1378, 0x1379, 0x137A, 0x137B,
+ 0x137C, 0x137D, 0x137E, 0x137F,
+ 0x1380, 0x1381, 0x1382, 0x1383,
+ 0x1384, 0x1385, 0x1386, 0x1387,
+ 0x1388, 0x1389, 0x138A, 0x138B,
+ 0x138C, 0x138D, 0x138E, 0x138F,
+ 0x1390, 0x1391, 0x1392, 0x1393,
+ 0x1394, 0x1395, 0x1396, 0x1397,
+ 0x1398, 0x1399, 0x139A, 0x139B,
+ 0x139C, 0x139D, 0x139E, 0x139F,
+ 0x13A0, 0x13A1, 0x13A2, 0x13A3,
+ 0x13A4, 0x13A5, 0x13A6, 0x13A7,
+ 0x13A8, 0x13A9, 0x13AA, 0x13AB,
+ 0x13AC, 0x13AD, 0x13AE, 0x13AF,
+ 0x13B0, 0x13B1, 0x13B2, 0x13B3,
+ 0x13B4, 0x13B5, 0x13B6, 0x13B7,
+};
+
static void gfx_draw_dirty_blocks(int x, int y, int columns, int rows);
/**
@@ -113,6 +154,67 @@ int gfx_load_g1()
return 0;
}
+/*
+* 0x6C19AC
+*/
+void gfx_load_character_widths(){
+
+ uint8* char_width_pointer = RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8);
+ for (int char_set_offset = 0; char_set_offset < 4*0xE0; char_set_offset+=0xE0){
+ for (uint8 c = 0; c < 0xE0; c++, char_width_pointer++){
+ rct_g1_element g1 = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[c + SPR_CHAR_START + char_set_offset];
+ int width;
+
+ if (char_set_offset == 0xE0*3) width = g1.width + 1;
+ else width = g1.width - 1;
+
+ if (c >= (FORMAT_ARGUMENT_CODE_START - 0x20) && c < (FORMAT_COLOUR_CODE_END - 0x20)){
+ width = 0;
+ }
+ *char_width_pointer = (uint8)width;
+ }
+
+ }
+
+ uint8 drawing_surface[0x40];
+ rct_drawpixelinfo dpi = {
+ .bits = (char*)&drawing_surface,
+ .width = 8,
+ .height = 8,
+ .x = 0,
+ .y = 0,
+ .pitch = 0,
+ .zoom_level = 0};
+
+
+ for (int i = 0; i < 0xE0; ++i){
+ memset(drawing_surface, 0, sizeof(drawing_surface));
+ gfx_draw_sprite(&dpi, i + 0x10D5, -1, 0);
+
+ for (int x = 0; x < 8; ++x){
+ uint8 val = 0;
+ for (int y = 0; y < 8; ++y){
+ val >>= 1;
+ if (dpi.bits[x + y * 8]==1){
+ val |= 0x80;
+ }
+ }
+ RCT2_ADDRESS(0xF4393C, uint8)[i * 8 + x] = val;
+ }
+
+ }
+
+ for (int i = 0; i < 0x20; ++i){
+ rct_g1_element* g1 = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[0x606 + i]);
+ uint8* unknown_pointer = RCT2_ADDRESS(0x9C3852, uint8) + 0xa12 * i;
+ g1->offset = unknown_pointer;
+ g1->width = 0x40;
+ g1->height = 0x28;
+ *((uint16*)unknown_pointer) = 0xFFFF;
+ *((uint32*)(unknown_pointer + 0x0E)) = 0;
+ }
+}
+
/**
* Clears the screen with the specified colour.
* rct2: 0x00678A9F
@@ -122,8 +224,8 @@ void gfx_clear(rct_drawpixelinfo *dpi, int colour)
int y, w, h;
char* ptr;
- w = dpi->width >> dpi->var_0F;
- h = dpi->height >> dpi->var_0F;
+ w = dpi->width >> dpi->zoom_level;
+ h = dpi->height >> dpi->zoom_level;
ptr = dpi->bits;
for (y = 0; y < h; y++) {
@@ -294,178 +396,181 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot
colour |= RCT2_GLOBAL(0x009ABD9C, uint32);
- if (!(colour & 0x1000000)) {
- if (!(colour & 0x8000000)) {
- left_ = left - dpi->x;
- if (left_ < 0)
- left_ = 0;
+ uint16 cross_pattern = 0;
- right_ = right - dpi->x;
- right_++;
- if (right_ > dpi->width)
- right_ = dpi->width;
+ int start_x = left - dpi->x;
+ if (start_x < 0){
+ start_x = 0;
+ cross_pattern ^= start_x;
+ }
- right_ -= left_;
+ int end_x = right - dpi->x;
+ end_x++;
+ if (end_x > dpi->width)
+ end_x = dpi->width;
+
+ int width = end_x - start_x;
+
+ int start_y = top - dpi->y;
+ if (start_y < 0){
+ start_y = 0;
+ cross_pattern ^= start_y;
+ }
+ int end_y = bottom - dpi->y;
+ end_y++;
+
+ if (end_y > dpi->height)
+ end_y = dpi->height;
+
+ int height = end_y - start_y;
+ if (colour&0x1000000){
+ // 00678B2E 00678BE5
+ //Cross hatching
+ uint8* dest_pointer = (start_y * (dpi->width + dpi->pitch)) + start_x + dpi->bits;
- top_ = top - dpi->y;
- if (top_ < 0)
- top_ = 0;
-
- bottom_ = bottom - dpi->y;
- bottom_++;
-
- if (bottom_ > dpi->height)
- bottom_ = dpi->height;
-
- bottom_ -= top_;
-
- if (!(colour & 0x2000000)) {
- if (!(colour & 0x4000000)) {
- uint8* pixel = (top_ * (dpi->width + dpi->pitch)) + left_ + dpi->bits;
-
- int length = dpi->width + dpi->pitch - right_;
-
- for (int i = 0; i < bottom_; ++i) {
- memset(pixel, (colour & 0xFF), right_);
- pixel += length + right_;
- }
- } else {
- // 00678B8A 00678E38
- char* esi;
- esi = (top_ * (dpi->width + dpi->pitch)) + left_ + dpi->bits;;
-
- int eax, ebp;
- eax = colour;
- ebp = dpi->width + dpi->pitch - right_;
-
- RCT2_GLOBAL(0x00EDF810, uint32) = ebp;
- RCT2_GLOBAL(0x009ABDB2, uint16) = bottom_;
- RCT2_GLOBAL(0x00EDF814, uint32) = right_;
-
- top_ = (top + dpi->y) & 0xf;
- right_ = (right + dpi_->x) &0xf;
-
- dpi_ = (rct_drawpixelinfo*)esi;
-
- esi = (char*)(eax >> 0x1C);
- esi = (char*)RCT2_GLOBAL(0x0097FEFC,uint32)[esi]; // or possibly uint8)[esi*4] ?
-
- for (; RCT2_GLOBAL(0x009ABDB2, uint16) > 0; RCT2_GLOBAL(0x009ABDB2, uint16)--) {
- // push ebx
- // push ecx
- ebp = *(esi + top_*2);
-
- // mov bp, [esi+top_*2];
- int ecx;
- ecx = RCT2_GLOBAL(0x00EDF814, uint32);
-
- for (int i = ecx; i >=0; --i) {
- if (!(ebp & (1 << right_)))
- dpi_->bits = (char*)(left_ & 0xFF);
-
- right_++;
- right_ = right_ & 0xF;
- dpi_++;
- }
- // pop ecx
- // pop ebx
- top_++;
- top_ = top_ &0xf;
- dpi_ += RCT2_GLOBAL(0x00EDF810, uint32);
- }
- return;
- }
-
- } else {
- // 00678B7E 00678C83
- if (dpi->zoom_level < 1) {
- // Location in screen buffer?
- uint8* pixel = top_ * (dpi->width + dpi->pitch) + left_ + dpi->bits;
-
- // Find colour in colour table?
- uint32 eax = RCT2_ADDRESS(0x0097FCBC, uint32)[(colour & 0xFF)];
- rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]);
-
- int length = (dpi->width + dpi->pitch) - right_;
-
- // Fill the rectangle with the colours from the colour table
- for (int i = 0; i < bottom_; ++i) {
- for (int j = 0; j < right_; ++j) {
- *pixel = *((uint8*)(&g1_element->offset[*pixel]));
- pixel++;
- }
- pixel += length;
- }
- } else if (dpi->zoom_level > 1) {
- // 00678C8A 00678D57
- right_ = right;
- } else if (dpi->zoom_level == 1) {
- // 00678C88 00678CEE
- right = right;
- }
-
- }
- } else {
- // 00678B3A 00678EC9
- right_ = right;
- }
- } else {
- // 00678B2E 00678BE5
- // Cross hatching
- uint16 pattern = 0;
-
- left_ = left_ - dpi->x;
- if (left_ < 0) {
- pattern = pattern ^ left_;
- left_ = 0;
- }
-
- right_ = right_ - dpi->x;
- right_++;
-
- if (right_ > dpi->width)
- right_ = dpi-> width;
-
- right_ = right_ - left_;
-
- top_ = top - dpi->y;
- if (top_ < 0) {
- pattern = pattern ^ top_;
- top_ = 0;
- }
-
- bottom_ = bottom - dpi->y;
- bottom_++;
-
- if (bottom_ > dpi->height)
- bottom_ = dpi->height;
-
- bottom_ -= top_;
-
- uint8* pixel = (top_ * (dpi->width + dpi->pitch)) + left_ + dpi->bits;
-
- int length = dpi->width + dpi->pitch - right_;
-
uint32 ecx;
- for (int i = 0; i < bottom_; ++i) {
- ecx = pattern;
+ for (int i = 0; i < height; ++i) {
+ uint8* next_dest_pointer = dest_pointer + dpi->width + dpi->pitch;
+ ecx = cross_pattern;
// Rotate right
ecx = (ecx >> 1) | (ecx << (sizeof(ecx) * CHAR_BIT - 1));
- ecx = (ecx & 0xFFFF0000) | right_;
+ ecx = (ecx & 0xFFFF0000) | width;
// Fill every other pixel with the colour
for (; (ecx & 0xFFFF) > 0; ecx--) {
ecx = ecx ^ 0x80000000;
if ((int)ecx < 0) {
- *pixel = colour & 0xFF;
+ *dest_pointer = colour & 0xFF;
}
- pixel++;
+ dest_pointer++;
}
- pattern = pattern ^ 1;
- pixel += length;
+ cross_pattern ^= 1;
+ dest_pointer = next_dest_pointer;
}
+ return;
}
+ if (colour & 0x2000000){
+ //0x2000000
+ // 00678B7E 00678C83
+ // Location in screen buffer?
+ uint8* dest_pointer = dpi->bits + (uint32)((start_y >> (dpi->zoom_level)) * ((dpi->width >> dpi->zoom_level) + dpi->pitch) + (start_x >> dpi->zoom_level));
+ // Find colour in colour table?
+ uint16 eax = palette_to_g1_offset[(colour & 0xFF)];
+ rct_g1_element g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax];
+
+ // Fill the rectangle with the colours from the colour table
+ for (int i = 0; i < height>>dpi->zoom_level; ++i) {
+ uint8* next_dest_pointer = dest_pointer + (dpi->width >> dpi->zoom_level) + dpi->pitch;
+ for (int j = 0; j < width; ++j) {
+ *dest_pointer = g1_element.offset[*dest_pointer];
+ dest_pointer++;
+ }
+ dest_pointer = next_dest_pointer;
+ }
+ return;
+ }
+ if (colour & 0x4000000){
+ //0x4000000
+ // 00678B8A 00678E38
+ char* dest_pointer;
+ dest_pointer = start_y * (dpi->width + dpi->pitch) + start_x + dpi->bits;
+
+ //The pattern loops every 15 lines this is which
+ //part the pattern is on.
+ int pattern_y = (start_y + dpi->y) % 16;
+
+ //The pattern loops every 15 pixels this is which
+ //part the pattern is on.
+ int start_pattern_x = (start_x + dpi_->x) % 16;
+ int pattern_x = start_pattern_x;
+
+ uint16* pattern_pointer;
+ pattern_pointer = RCT2_ADDRESS(0x0097FEFC,uint16*)[colour >> 28]; // or possibly uint8)[esi*4] ?
+
+ for (int no_lines = height; no_lines > 0; no_lines--) {
+ char* next_dest_pointer = dest_pointer + dpi->width + dpi->pitch;
+ uint16 pattern = pattern_pointer[pattern_y];
+
+ for (int no_pixels = width; no_pixels > 0; --no_pixels) {
+ if (pattern & (1 << pattern_x))
+ *dest_pointer = colour & 0xFF;
+
+ pattern_x = (pattern_x + 1) % 16;
+ dest_pointer++;
+ }
+ pattern_x = start_pattern_x;
+ pattern_y = (pattern_y + 1) % 16;
+ dest_pointer = next_dest_pointer;
+ }
+ return;
+ }
+ if (colour & 0x8000000){
+ //0x8000000
+ // 00678B3A 00678EC9 still to be implemented
+ //RCT2_CALLPROC_X(0x00678AD4, left, right, top, bottom, 0, dpi, colour);
+ int esi = left - RCT2_GLOBAL(0x1420070,sint16);
+ RCT2_GLOBAL(0xEDF824,uint32) = esi;
+ esi = top - RCT2_GLOBAL(0x1420072,sint16);
+ RCT2_GLOBAL(0xEDF828,uint32) = esi;
+ left -= dpi->x;//0x4
+ if ( left < 0 ){
+ RCT2_GLOBAL(0xEDF824,sint32) -= left;
+ left = 0;
+ }
+ right -= dpi->x;
+ right++;
+ if ( right > dpi->width ){
+ right = dpi->width;
+ }
+ right -= left;
+ top -= dpi->y;
+ if ( top < 0 ){
+ RCT2_GLOBAL(0xEDF828,sint32) -= top;
+ top = 0;
+ }
+ bottom -= dpi->y;
+ bottom++;
+ if (bottom > dpi->height){
+ bottom = dpi->height;
+ }
+ bottom -= top;
+ RCT2_GLOBAL(0xEDF824,sint32) &= 0x3F;
+ RCT2_GLOBAL(0xEDF828,sint32) &= 0x3F;
+ esi = dpi->width;
+ esi += dpi->pitch;
+ esi *= top;
+ esi += left;
+ esi += (uint32)dpi->bits;
+ RCT2_GLOBAL(0xEDF82C,sint32) = right;
+ RCT2_GLOBAL(0xEDF830,sint32) = bottom;
+ left = dpi->width;
+ left+= dpi->pitch;
+ left-= right;
+ RCT2_GLOBAL(0xEDF834,sint32) = left;
+ colour &= 0xFF;
+ colour--;
+ right = colour;
+ colour <<= 8;
+ right |= colour;
+ RCT2_GLOBAL(0xEDF838,sint32) = right;
+ //right <<= 4;
+ int edi = esi;
+ esi = RCT2_GLOBAL(0xEDF828,sint32);
+ esi *= 0x40;
+ left = 0;
+ esi += (uint32)(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS,rct_g1_element)[right]).offset;//???
+ //Not finished
+ //Start of loop
+ return;
+ }
+ //0x0000000
+ uint8* dest_pointer = start_y * (dpi->width + dpi->pitch) + start_x + dpi->bits;
+
+ for (int i = 0; i < height; ++i) {
+ memset(dest_pointer, (colour & 0xFF), width);
+ dest_pointer += dpi->width + dpi->pitch;
+ }
// RCT2_CALLPROC_X(0x00678AD4, left, right, top, bottom, 0, dpi, colour);
}
@@ -585,7 +690,7 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri
* image.
*/
void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_pointer, uint8* source_pointer, uint8* dest_pointer, rct_g1_element* source_image, rct_drawpixelinfo *dest_dpi, int height, int width, int image_type){
- uint8 zoom_level = dest_dpi->zoom_level + 1;
+ uint8 zoom_level = dest_dpi->zoom_level;
//Requires use of palette?
if (image_type & IMAGE_TYPE_USE_PALETTE){
@@ -593,12 +698,12 @@ void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_pointer, ui
if (unknown_pointer!= NULL){ //Not tested. I can't actually work out when this code runs.
unknown_pointer += source_pointer - source_image->offset;// RCT2_GLOBAL(0x9E3CE0, uint32);
- for (; height > 0; height -= zoom_level){
- uint8* next_source_pointer = source_pointer + source_image->width*zoom_level;
- uint8* next_unknown_pointer = unknown_pointer + source_image->width*zoom_level;
+ for (; height > 0; height -= (1<width << zoom_level);
+ uint8* next_unknown_pointer = unknown_pointer + (uint32)(source_image->width << zoom_level);
uint8* next_dest_pointer = dest_pointer + dest_dpi->width + dest_dpi->pitch;
- for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_level, source_pointer+=zoom_level, unknown_pointer+=zoom_level, dest_pointer++){
+ for (int no_pixels = width; no_pixels > 0; no_pixels -= (1< 0; height -= zoom_level){
- uint8* next_source_pointer = source_pointer + source_image->width*zoom_level;
+ for (; height > 0; height -= (1<width<width + dest_dpi->pitch;
- for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_level, source_pointer+= zoom_level, dest_pointer++){
+ for (int no_pixels = width; no_pixels > 0; no_pixels -= (1< 0; height -= zoom_level){
- uint8* next_source_pointer = source_pointer + source_image->width*zoom_level;
+ for (; height > 0; height -= (1<width << zoom_level);
uint8* next_dest_pointer = dest_pointer + dest_dpi->width + dest_dpi->pitch;
- for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_level, source_pointer += zoom_level, dest_pointer++){
+ for (int no_pixels = width; no_pixels > 0; no_pixels -= (1<flags & G1_FLAG_BMP)){//Not tested
- for (; height > 0; height-=zoom_level){
- uint8* next_source_pointer = source_pointer + source_image->width*zoom_level;
+ for (; height > 0; height-=(1<width << zoom_level);
uint8* next_dest_pointer = dest_pointer + dest_dpi->width + dest_dpi->pitch;
- for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_level, dest_pointer++, source_pointer += zoom_level){
+ for (int no_pixels = width; no_pixels > 0; no_pixels -= (1<offset;
- for (; height > 0; height -= zoom_level){
- uint8* next_source_pointer = source_pointer + source_image->width*zoom_level;
- uint8* next_unknown_pointer = unknown_pointer + source_image->width*zoom_level;
+ for (; height > 0; height -= (1<width << zoom_level);
+ uint8* next_unknown_pointer = unknown_pointer + (uint32)(source_image->width << zoom_level);
uint8* next_dest_pointer = dest_pointer + dest_dpi->width + dest_dpi->pitch;
- for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_level, dest_pointer++, source_pointer += zoom_level, unknown_pointer += zoom_level){
+ for (int no_pixels = width; no_pixels > 0; no_pixels -= (1< 0; height -= zoom_level){
- uint8* next_source_pointer = source_pointer + source_image->width*zoom_level;
+ for (; height > 0; height -= (1<width << zoom_level);
uint8* next_dest_pointer = dest_pointer + dest_dpi->width + dest_dpi->pitch;
- for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_level, dest_pointer++, source_pointer += zoom_level){
+ for (int no_pixels = width; no_pixels > 0; no_pixels -= (1<zoom_level + 1;
+ int zoom_level = dpi->zoom_level;
uint8* next_source_pointer;
uint8* next_dest_pointer = dest_bits_pointer;
//For every line in the image
- for (int y = source_y_start; y < (height + source_y_start); y += zoom_level){
+ for (int y = source_y_start; y < (height + source_y_start); y += (1< 0){
//Since the start is positive
//We need to move the drawing surface to the correct position
- dest_pointer += x_start / zoom_level;
+ dest_pointer += x_start >> zoom_level;
}
else{
//If the start is negative we require to remove part of the image.
@@ -778,7 +881,7 @@ void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_point
//Finally after all those checks, copy the image onto the drawing surface
//If the image type is not a basic one we require to mix the pixels
if (image_type & IMAGE_TYPE_USE_PALETTE){//In the .exe these are all unraveled loops
- for (; no_pixels > 0; no_pixels -= zoom_level, source_pointer += zoom_level, dest_pointer++){
+ for (; no_pixels > 0; no_pixels -= (1< 0; no_pixels -= zoom_level, dest_pointer++){
+ for (; no_pixels > 0; no_pixels -= (1< 0; no_pixels -= zoom_level, source_pointer += zoom_level, dest_pointer++){
+ for (; no_pixels > 0; no_pixels -= (1<>= 19;
eax &= 0x7F;
}
- eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32);
+ eax = palette_to_g1_offset[eax];// RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32);
palette_pointer = ((rct_g1_element*)RCT2_ADDRESS_G1_ELEMENTS)[eax].offset;
RCT2_GLOBAL(0x9ABDA4, uint32) = (uint32)palette_pointer;
@@ -861,8 +964,9 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y)
eax >>= 19;
//push edx/y
eax &= 0x1F;
- ebp = RCT2_GLOBAL(ebp * 4 + 0x97FCBC, uint32);
- eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32);
+ ebp = palette_to_g1_offset[ebp]; //RCT2_GLOBAL(ebp * 4 + 0x97FCBC, uint32); //ebp has not been set to anything before this! ??
+ //Possibly another variable input?!
+ eax = palette_to_g1_offset[eax]; //RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32);
ebp <<= 0x4;
eax <<= 0x4;
ebp = RCT2_GLOBAL(ebp + RCT2_ADDRESS_G1_ELEMENTS, uint32);
@@ -888,7 +992,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y)
RCT2_GLOBAL(0xEDF81C, uint32) |= 0x20000000;
image_id |= IMAGE_TYPE_USE_PALETTE;
- eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32);
+ eax = palette_to_g1_offset[eax]; //RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32);
eax <<= 4;
eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32);
edx = *((uint32*)(eax + 0xF3));
@@ -911,13 +1015,13 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y)
//Top
int top_type = (image_id >> 19) & 0x1f;
- uint32 top_offset = RCT2_ADDRESS(0x97FCBC, uint32)[top_type];
+ uint32 top_offset = palette_to_g1_offset[top_type]; //RCT2_ADDRESS(0x97FCBC, uint32)[top_type];
rct_g1_element top_palette = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[top_offset];
memcpy(palette + 0xF3, top_palette.offset + 0xF3, 12);
//Trousers
int trouser_type = (image_id >> 24) & 0x1f;
- uint32 trouser_offset = RCT2_ADDRESS(0x97FCBC, uint32)[trouser_type];
+ uint32 trouser_offset = palette_to_g1_offset[trouser_type]; //RCT2_ADDRESS(0x97FCBC, uint32)[trouser_type];
rct_g1_element trouser_palette = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[trouser_offset];
memcpy(palette + 0xCA, trouser_palette.offset + 0xF3, 12);
@@ -925,38 +1029,60 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y)
RCT2_GLOBAL(0x9ABDA4, uint8*) = palette;
palette_pointer = palette;
}
-
gfx_draw_sprite_palette_set(dpi, image_id, x, y, palette_pointer, unknown_pointer);
}
/*
-* 0x67A46E
+* rct: 0x0067A46E
+* image_id (ebx) and also (0x00EDF81C)
+* palette_pointer (0x9ABDA4)
+* unknown_pointer (0x9E3CDC)
+* dpi (edi)
+* x (cx)
+* y (dx)
*/
void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer){
int image_element = 0x7FFFF&image_id;
int image_type = (image_id & 0xE0000000) >> 28;
rct_g1_element* g1_source = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[image_element]);
-
- //Zooming code has been integrated into main code.
- /*if (dpi->zoom_level >= 1){ //These have not been tested
- //something to do with zooming
- if (dpi->zoom_level == 1){
- RCT2_CALLPROC_X(0x0067BD81, 0, (int)g1_source, x, y, 0,(int) dpi, 0);
- return;
- }
- if (dpi->zoom_level == 2){
- RCT2_CALLPROC_X(0x0067DADA, 0, (int)g1_source, x, y, 0, (int)dpi, 0);
- return;
- }
- RCT2_CALLPROC_X(0x0067FAAE, 0, (int)g1_source, x, y, 0, (int)dpi, 0);
+
+ if ( dpi->zoom_level && (g1_source->flags & (1<<4)) ){
+ rct_drawpixelinfo zoomed_dpi = {
+ .bits = dpi->bits,
+ .x = dpi->x >> 1,
+ .y = dpi->y >> 1,
+ .height = dpi->height>>1,
+ .width = dpi->width>>1,
+ .pitch = (dpi->width+dpi->pitch)-(dpi->width>>1),//In the actual code this is dpi->pitch but that doesn't seem correct.
+ .zoom_level = dpi->zoom_level - 1
+ };
+ gfx_draw_sprite_palette_set(&zoomed_dpi, (image_type << 28) | (image_element - g1_source->zoomed_offset), x >> 1, y >> 1, palette_pointer, unknown_pointer);
return;
- }*/
+ }
- //We add on one so that divides will create the correct number of pixels
- int zoom_level = dpi->zoom_level + 1;
+ if ( dpi->zoom_level && (g1_source->flags & (1<<5)) ){
+ return;
+ }
+ //Zooming code has been integrated into main code.
+ //if (dpi->zoom_level >= 1){ //These have not been tested
+ // //something to do with zooming
+ // if (dpi->zoom_level == 1){
+ // RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, (int)dpi, 0);
+ // return;
+ // }
+ // if (dpi->zoom_level == 2){
+ // RCT2_CALLPROC_X(0x0067DADA, 0, (int)g1_source, x, y, 0, (int)dpi, 0);
+ // return;
+ // }
+ // RCT2_CALLPROC_X(0x0067FAAE, 0, (int)g1_source, x, y, 0, (int)dpi, 0);
+ // return;
+ //}
+
+ //Its used super often so we will define it to a seperate variable.
+ int zoom_level = dpi->zoom_level;
//This will be the height of the drawn image
- int height = g1_source->height / zoom_level;
+ int height = g1_source->height >> zoom_level;
//This is the start y coordinate on the destination
int dest_start_y = y - dpi->y + g1_source->y_offset;
//This is the start y coordinate on the source
@@ -972,7 +1098,7 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in
return;
}
//The source image will start a further up the image
- source_start_y -= dest_start_y*zoom_level;
+ source_start_y -= dest_start_y<width / zoom_level;
+ int width = g1_source->width >> zoom_level;
//This is the source start x coordinate
int source_start_x = 0;
//This is the destination start x coordinate
@@ -1004,7 +1130,7 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in
return;
}
//The source start will also need to cut off the side
- source_start_x -= dest_start_x*zoom_level;
+ source_start_x -= dest_start_x<width + dpi->pitch)*dest_start_y + dest_start_x;
- height *= zoom_level;
- width *= zoom_level;
+ height <<= zoom_level;
+ width <<= zoom_level;
if (g1_source->flags & G1_FLAG_RLE_COMPRESSION){
//We have to use a different method to move the source pointer for
@@ -1089,25 +1215,21 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in
*/
void gfx_transpose_palette(int pal, unsigned char product)
{
- int eax, ebx, ebp;
- uint8* esi, *edi;
+ rct_g1_element g1 = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[pal];
+ int width = g1.width;
+ int x = g1.x_offset;
+ uint8* dest_pointer = (uint8*)&(RCT2_ADDRESS(0x014124680,uint8)[x]);
+ uint8* source_pointer = g1.offset;
- ebx = pal * 16;
- esi = (uint8*)(*((int*)(RCT2_ADDRESS_G1_ELEMENTS + ebx)));
- ebp = *((short*)(0x009EBD2C + ebx));
- eax = *((short*)(0x009EBD30 + ebx)) * 4;
- edi = (uint8*)0x01424680 + eax;
-
- for (; ebp > 0; ebp--) {
- edi[0] = (esi[0] * product) >> 8;
- edi[1] = (esi[1] * product) >> 8;
- edi[2] = (esi[2] * product) >> 8;
- esi += 3;
- edi += 4;
+ for (; width > 0; width--) {
+ dest_pointer[0] = (source_pointer[0] * product) >> 8;
+ dest_pointer[1] = (source_pointer[1] * product) >> 8;
+ dest_pointer[2] = (source_pointer[2] * product) >> 8;
+ source_pointer += 3;
+ dest_pointer += 4;
}
- osinterface_update_palette((char*)0x01424680, 10, 236);
+ osinterface_update_palette((char*)0x01424680, 10, 236);//Odd would have expected dest_pointer
}
-
/**
* Draws i formatted text string centred at i specified position.
* rct2: 0x006C1D6C
@@ -1287,54 +1409,60 @@ int gfx_get_string_width(char* buffer)
uint16* current_font_sprite_base;
// Width of string
int width;
- rct_g1_element* g1_element;
+ rct_g1_element g1_element;
current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16);
width = 0;
- for (uint8* curr_char = buffer; *curr_char != NULL; curr_char++) {
+ for (uint8* curr_char = (uint8*)buffer; *curr_char != (uint8)NULL; curr_char++) {
if (*curr_char >= 0x20) {
- //Maybe global not address??
- width += RCT2_ADDRESS(0x0141E9E8, uint8)[*current_font_sprite_base + (*curr_char-0x20)];
+ width += RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8)[*current_font_sprite_base + (*curr_char - 0x20)];
continue;
}
switch(*curr_char) {
- case 1:
- width = *curr_char;
+ case FORMAT_MOVE_X:
curr_char++;
+ width = *curr_char;
break;
- case 2:
+ case FORMAT_ADJUST_PALETTE:
case 3:
case 4:
curr_char++;
break;
- case 7:
+ case FORMAT_NEWLINE:
+ case FORMAT_NEWLINE_SMALLER:
+ continue;
+ case FORMAT_TINYFONT:
*current_font_sprite_base = 0x1C0;
break;
- case 8:
+ case FORMAT_BIGFONT:
*current_font_sprite_base = 0x2A0;
break;
- case 9:
+ case FORMAT_MEDIUMFONT:
*current_font_sprite_base = 0x0E0;
break;
- case 0x0A:
+ case FORMAT_SMALLFONT:
*current_font_sprite_base = 0;
break;
- case 0x17:
- g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[*curr_char&0x7FFFF]);
- width += g1_element->width; //RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4];
+ case FORMAT_OUTLINE:
+ case FORMAT_OUTLINE_OFF:
+ case FORMAT_WINDOW_COLOUR_1:
+ case FORMAT_WINDOW_COLOUR_2:
+ case FORMAT_WINDOW_COLOUR_3:
+ case 0x10:
+ continue;
+ case FORMAT_INLINE_SPRITE:
+ g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[*((uint32*)(curr_char+1))&0x7FFFF];
+ width += g1_element.width;
curr_char += 4;
break;
default:
- if (*curr_char <= 0x10) {
+ if (*curr_char <= 0x16) { //case 0x11? FORMAT_NEW_LINE_X_Y
+ curr_char += 2;
continue;
}
- curr_char += 2;
- if (*curr_char <= 0x16) {
- continue;
- }
- curr_char += 2;
+ curr_char += 4;//never happens?
break;
}
}
@@ -1357,8 +1485,11 @@ int gfx_clip_string(char* buffer, int width)
// Character to change to ellipsis
unsigned char* last_char;
// Width of the string, including ellipsis
+
unsigned int clipped_width;
+ rct_g1_element g1_element;
+
if (width < 6) {
*buffer = 0;
return 0;
@@ -1370,52 +1501,59 @@ int gfx_clip_string(char* buffer, int width)
clipped_width = 0;
last_char = buffer;
- for (unsigned char* curr_char = buffer; *curr_char != NULL; curr_char++) {
+ for (unsigned char* curr_char = buffer; *curr_char != (uint8)NULL; curr_char++) {
if (*curr_char < 0x20) {
switch (*curr_char) {
- case 1:
+ case FORMAT_MOVE_X:
curr_char++;
clipped_width = *curr_char;
continue;
- case 2:
+ case FORMAT_ADJUST_PALETTE:
case 3:
case 4:
curr_char++;
continue;
- case 7:
+ case FORMAT_NEWLINE:
+ case FORMAT_NEWLINE_SMALLER:
+ continue;
+ case FORMAT_TINYFONT:
current_font_sprite_base = 0x1C0;
break;
- case 8:
+ case FORMAT_BIGFONT:
current_font_sprite_base = 0x2A0;
break;
- case 9:
+ case FORMAT_MEDIUMFONT:
current_font_sprite_base = 0x0E0;
break;
- case 0x0A:
+ case FORMAT_SMALLFONT:
current_font_sprite_base = 0;
break;
- case 0x17:
- clipped_width += RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*(curr_char+1) & 0x7FFFF) << 4];
+ case FORMAT_OUTLINE:
+ case FORMAT_OUTLINE_OFF:
+ case FORMAT_WINDOW_COLOUR_1:
+ case FORMAT_WINDOW_COLOUR_2:
+ case FORMAT_WINDOW_COLOUR_3:
+ case 0x10:
+ continue;
+ case FORMAT_INLINE_SPRITE:
+ g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[*((uint32*)(curr_char+1))&0x7FFFF];
+ clipped_width += g1_element.width;
curr_char += 4;
continue;
default:
- if (*curr_char <= 0x10) {
- continue;
- }
-
- if (*curr_char <= 0x16) {
+ if (*curr_char <= 0x16) { //case 0x11? FORMAT_NEW_LINE_X_Y
curr_char += 2;
continue;
}
- curr_char += 4;
+ curr_char += 4;//never happens?
continue;
}
max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[current_font_sprite_base]);
}
- clipped_width += RCT2_ADDRESS(0x0141E9E8, uint8)[current_font_sprite_base + (*curr_char - 0x20)];
+ clipped_width += RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8)[current_font_sprite_base + (*curr_char - 0x20)];
- if (clipped_width > width) {
+ if ((int)clipped_width > width) {
*((uint32*)last_char) = '...';
clipped_width = width;
return clipped_width;
@@ -1445,7 +1583,7 @@ int gfx_wrap_string(char* buffer, int width, int* num_lines, int* font_height)
{
unsigned int line_width = 0;
unsigned int max_width = 0;
- rct_g1_element* g1_element;
+ rct_g1_element g1_element;
uint16* current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16);
@@ -1457,7 +1595,7 @@ int gfx_wrap_string(char* buffer, int width, int* num_lines, int* font_height)
// Width of line up to current word
unsigned int curr_width;
- for (unsigned char* curr_char = buffer; *curr_char != NULL; curr_char++) {
+ for (unsigned char* curr_char = buffer; *curr_char != (uint8)NULL; curr_char++) {
// Remember start of current word and line width up to this word
if (*curr_char == ' ') {
@@ -1469,44 +1607,52 @@ int gfx_wrap_string(char* buffer, int width, int* num_lines, int* font_height)
if (*curr_char != 5) {
if (*curr_char < ' ') {
switch(*curr_char) {
- case 1:
- case 2:
+ case FORMAT_MOVE_X:
+ case FORMAT_ADJUST_PALETTE:
case 3:
case 4:
curr_char++;
continue;
- case 7:
+ case FORMAT_NEWLINE:
+ case FORMAT_NEWLINE_SMALLER:
+ continue;
+ case FORMAT_TINYFONT:
*font_height = 0x1C0;
continue;
- case 8:
+ case FORMAT_BIGFONT:
*font_height = 0x2A0;
continue;
- case 9:
+ case FORMAT_MEDIUMFONT:
*font_height = 0xE0;
continue;
- case 0x0A:
+ case FORMAT_SMALLFONT:
*font_height = 0;
continue;
- case 0x17:
- line_width += RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF)];
+ case FORMAT_OUTLINE:
+ case FORMAT_OUTLINE_OFF:
+ case FORMAT_WINDOW_COLOUR_1:
+ case FORMAT_WINDOW_COLOUR_2:
+ case FORMAT_WINDOW_COLOUR_3:
+ case 0x10:
+ continue;
+ case FORMAT_INLINE_SPRITE:
+ g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[*((uint32*)(curr_char + 1)) & 0x7FFFF];
+ line_width += g1_element.width;
curr_char += 4;
break;
default:
- if (*curr_char < 0x10) {
- continue;
- }
- curr_char += 2;
if (*curr_char <= 0x16) {
+ curr_char += 2;
continue;
}
- curr_char += 2;
+ curr_char += 4;
continue;
}
}
- line_width += RCT2_ADDRESS(0x0141E9E8, uint8)[*current_font_sprite_base + (*curr_char-0x20)];
+ line_width += RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8)[*current_font_sprite_base + (*curr_char - 0x20)];
- if (line_width <= width) {
+ if ((int)line_width <= width) {
continue;
}
if (curr_word == 0) {
@@ -1654,8 +1800,6 @@ int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, i
int font_height, line_height, line_width, line_y, num_lines;
// Location of font sprites
uint16* current_font_sprite_base;
- // Location of font flags
- uint16 current_font_flags;
char* buffer = RCT2_ADDRESS(0x009C383D, char);
@@ -1777,38 +1921,43 @@ void gfx_draw_string_left(rct_drawpixelinfo *dpi, int format, void *args, int co
gfx_draw_string(dpi, buffer, colour, x, y);
}
-
-void colour_char(int al, uint16* current_font_flags) {
+/* Changes the palette so that the next character changes colour
+*/
+void colour_char(uint8 colour, uint16* current_font_flags, uint8* palette_pointer) {
int eax;
- rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[0x1332]);
- eax = ((uint32*)g1_element->offset)[al & 0xFF];
+ rct_g1_element g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[0x1332];
+ eax = ((uint32*)g1_element.offset)[colour & 0xFF];
if (!(*current_font_flags & 2)) {
eax = eax & 0x0FF0000FF;
}
// Adjust text palette. Store current colour?
- RCT2_GLOBAL(0x009ABE05, uint32) = eax;
- RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04;
+ palette_pointer[1] = eax & 0xFF;
+ palette_pointer[2] = (eax >> 8) & 0xFF;
+ palette_pointer[3] = (eax >> 16) & 0xFF;
+ palette_pointer[4] = (eax >> 24) & 0xFF;
+ RCT2_GLOBAL(0x009ABDA4, uint32) = (uint32)palette_pointer;
}
-
-void sub_682AC7(int ebp, uint16* current_font_flags) {
+/* Changes the palette so that the next character changes colour
+* This is specific to changing to a predefined window related colour
+*/
+void colour_char_window(uint8 colour, uint16* current_font_flags,uint8* palette_pointer) {
int eax;
- // loc_682AC7
- eax = RCT2_ADDRESS(0x0141FD45, uint8)[ebp * 8];
+ eax = RCT2_ADDRESS(0x0141FD45, uint8)[colour * 8];
if (*current_font_flags & 2) {
eax |= 0x0A0A00;
}
//Adjust text palette. Store current colour?
- RCT2_GLOBAL(0x009ABE05, uint32) = eax;
- RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04;
- eax = 0;
- // jmp loc_682842
-
+ palette_pointer[1] = eax & 0xFF;
+ palette_pointer[2] = (eax >> 8) & 0xFF;
+ palette_pointer[3] = (eax >> 16) & 0xFF;
+ palette_pointer[4] = (eax >> 24) & 0xFF;
+ RCT2_GLOBAL(0x009ABDA4, uint32) = (uint32)palette_pointer;
}
@@ -1824,25 +1973,19 @@ void sub_682AC7(int ebp, uint16* current_font_flags) {
void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, int y)
{
- //gLastDrawStringX = ecx;
- //gLastDrawStringY = edx;
- //return;
- //
- int eax, ebx, ecx, edx, esi, edi, ebp;
+ int eax, ebx, ecx, ebp;
rct_g1_element* g1_element;
// Maximum length/height of string
int max_x = x;
int max_y = y;
- // Store original x, y
- RCT2_GLOBAL(0x00EDF840, uint16) = x;
- RCT2_GLOBAL(0x00EDF842, uint16) = y;
-
//
uint16* current_font_flags = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16);
uint16* current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16);
+ uint8* palette_pointer = text_palette;
+
// Flag for skipping non-printing characters
int skip_char = 0;
@@ -1886,7 +2029,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in
skip_char = 0;
}
} else {
- sub_682AC7(ebp, current_font_flags);
+ colour_char_window(ebp, current_font_flags, palette_pointer);
}
} else {
*current_font_flags |= 1;
@@ -1908,8 +2051,11 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in
eax = eax | RCT2_ADDRESS(0x0141FC48, uint8)[colour * 8];
}
// Adjust text palette. Store current colour? ;
- RCT2_GLOBAL(0x009ABE05, uint32) = eax;
- RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04;
+ palette_pointer[1] = eax & 0xFF;
+ palette_pointer[2] = (eax >> 8) & 0xFF;
+ palette_pointer[3] = (eax >> 16) & 0xFF;
+ palette_pointer[4] = (eax >> 24) & 0xFF;
+ RCT2_GLOBAL(0x009ABDA4, uint32) = (uint32)palette_pointer;
eax = 0;
}
}
@@ -1926,9 +2072,8 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in
if (al < 0x20) {
// Control codes
skip_char = 0;
- } else if (al >= 0x8E && al < 0x9C) {
+ } else if (al >= FORMAT_COLOUR_CODE_START && al <= FORMAT_COLOUR_CODE_END) {
// Colour codes
- al -= 0x8E;
if (*current_font_flags == 1) {
if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) {
skip_char = 1;
@@ -1937,201 +2082,179 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in
}
continue;
}
- colour_char(al, current_font_flags);
+ colour_char(al - FORMAT_COLOUR_CODE_START, current_font_flags, palette_pointer);
continue;
} else {
continue;
}
}
- if ((al >= 0x8E) && (al < 0x9C)){
- // Colour codes
- al -= 0x8E;
- if (*current_font_flags == 1) {
+ // Control codes
+ switch (al) {
+ case FORMAT_MOVE_X://Start New Line at start+buffer x, same y. (Overwrite?)
+ max_x = x + *++buffer;
+ break;
+ case FORMAT_ADJUST_PALETTE:
+ al = *++buffer;
+ if (*current_font_flags & 1) {
if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) {
skip_char = 1;
- } else {
- skip_char = 0;
+ break;
}
- continue;
}
- colour_char(al, current_font_flags);
- continue;
- } else {
- if (al < 0x20) {
- // Control codes
- al -= 0x20;
- switch (al) {
- case 0x0E5://Start New Line at set y lower
- max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16);
- max_y += 0x0A;
- if (*current_font_sprite_base <= 0x0E) {
- break;
- }
- max_y -= 4;
- if (*current_font_sprite_base == 0x1C0) {
- break;
- }
- max_y -= 0xFFF4;
- break;
- case 0x0E6://Start New Line at set y lower
- max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16);
- max_y += 5;
- if (*current_font_sprite_base <= 0x0E) {
- break;
- }
- max_y -= 2;
- if (*current_font_sprite_base == 0x1C0) {
- break;
- }
- max_y -= 0xFFFA;//This does not look correct probably should be an add
- break;
- case 0x0E1://Start New Line at start+buffer x, same y. (Overwrite?)
- al = *(buffer+1);
- buffer++;
- max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16);
- max_x += al;
- break;
- case 0x0F1: //Start new line at specified x,y
- eax = *((uint16*)(buffer+1));
- buffer += 2;
- max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16);
- max_x += (eax & 0xFF);
- max_y = y;//RCT2_GLOBAL(0x0EDF842, uint16);
- max_y += (eax & 0xFF00) >> 8;
- break;
- case 0x0E7:
- *current_font_sprite_base = 0x1C0;
- break;
- case 0x0E8:
- *current_font_sprite_base = 0x2A0;
- break;
- case 0x0E9:
- *current_font_sprite_base = 0xE0;
- break;
- case 0x0EA:
- *current_font_sprite_base = 0;
- break;
- case 0x0EB:
- *current_font_flags |= 2;
- break;
- case 0x0EC:
- *current_font_flags &= 0x0FFFD;
- break;
- case 0x0ED:
- ebp = RCT2_GLOBAL(0x0141F740, uint8);
- if (*current_font_flags & 1) {
- if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) {
- skip_char = 1;
- } else {
- skip_char = 0;
- }
- break;
- }
- sub_682AC7(ebp, current_font_flags);
- break;
- case 0x0EE:
- ebp = RCT2_GLOBAL(0x0141F741, uint8);
- if (*current_font_flags & 1) {
- if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) {
- skip_char = 1;
- } else {
- skip_char = 0;
- }
- break;
- }
- sub_682AC7(ebp, current_font_flags);
- break;
- case 0x0EF:
- ebp = RCT2_GLOBAL(0x0141F742, uint8);
- if (*current_font_flags & 1) {
- if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) {
- skip_char = 1;
- } else {
- skip_char = 0;
- }
- break;
- }
- sub_682AC7(ebp, current_font_flags);
- break;
- case 0x0E2:
- al = *(buffer+1);
- buffer++;
- if (*current_font_flags & 1) {
- if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) {
- skip_char = 1;
- break;
- }
- }
-
- eax = RCT2_ADDRESS(0x097FCBC, uint32)[al*4];
- g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]);
- ebx = g1_element->offset[0xF9] + (1 << 8);
- if (!(*current_font_flags & 2)) {
- ebx = ebx & 0xFF;
- }
- //Adjust the text palette
- RCT2_GLOBAL(0x09ABE05, uint16) = ebx;
- memcpy((uint8*)0x09ABE07,&(g1_element->offset[0xF7]),2);
- //ebx = g1_element->offset[0xF7];
- //RCT2_GLOBAL(0x09ABE07, uint16) = ebx;
- memcpy((uint8*)0x09ABE09,&(g1_element->offset[0xFA]),2);
- //ebx = g1_element->offset[0xFA];
- //RCT2_GLOBAL(0x09ABE09, uint16) = ebx;
- //Set the palette pointer
- RCT2_GLOBAL(0x09ABDA4, uint32) = 0x09ABE04;
- if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) {
- skip_char = 1;
- }
- break;
- case 0x0F7:
- buffer += 5;
- if (max_x >= dpi->x + dpi->width) {
- skip_char = 1;
- break;
- }
- ebx = *(buffer - 3);
- eax = ebx & 0x7FFFF;
- g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]);
-
- gfx_draw_sprite(dpi, ebx, max_x, max_y);
+ eax = palette_to_g1_offset[al]; //RCT2_ADDRESS(0x097FCBC, uint32)[al * 4];
+ g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]);
+ ebx = g1_element->offset[0xF9] + (1 << 8);
+ if (!(*current_font_flags & 2)) {
+ ebx = ebx & 0xFF;
+ }
- max_x = max_x + g1_element->width;
- break;
- }
+ palette_pointer[1] = ebx & 0xff;
+ palette_pointer[2] = (ebx >> 8) & 0xff;
+ //Adjust the text palette
+ memcpy(palette_pointer + 3, &(g1_element->offset[0xF7]), 2);
+ memcpy(palette_pointer + 5, &(g1_element->offset[0xFA]), 2);
+ //Set the palette pointer
+ RCT2_GLOBAL(0x009ABDA4, uint32) = (uint32)palette_pointer;
- } else {
- al -= 0x20;
- if (max_x >= dpi->x + dpi->width) {
+
+ if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) {
+ skip_char = 1;
+ }
+ break;
+ case FORMAT_NEWLINE://Start New Line at set y lower
+ max_x = x;
+ if (*current_font_sprite_base <= 0xE0) {
+ max_y += 10;
+ break;
+ }
+ else if (*current_font_sprite_base == 0x1C0) {
+ max_y += 6;
+ break;
+ }
+ max_y += 18;
+ break;
+ case FORMAT_NEWLINE_SMALLER://Start New Line at set y lower
+ max_x = x;
+ if (*current_font_sprite_base <= 0xE0) {
+ max_y += 5;
+ break;
+ }
+ else if (*current_font_sprite_base == 0x1C0) {
+ max_y += 3;
+ break;
+ }
+ max_y += 9;
+ break;
+ case FORMAT_TINYFONT:
+ *current_font_sprite_base = 0x1C0;
+ break;
+ case FORMAT_BIGFONT:
+ *current_font_sprite_base = 0x2A0;
+ break;
+ case FORMAT_MEDIUMFONT:
+ *current_font_sprite_base = 0xE0;
+ break;
+ case FORMAT_SMALLFONT:
+ *current_font_sprite_base = 0;
+ break;
+ case FORMAT_OUTLINE:
+ *current_font_flags |= 2;
+ break;
+ case FORMAT_OUTLINE_OFF:
+ *current_font_flags &= 0x0FFFD;
+ break;
+ case FORMAT_WINDOW_COLOUR_1:
+ ebp = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_1, uint8);
+ if (*current_font_flags & 1) {
+ if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) {
skip_char = 1;
}
- if (max_x + 0x1A < dpi->x) {
- ebx = al;
- ebx += *current_font_sprite_base;
- max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF);
+ else {
+ skip_char = 0;
+ }
+ break;
+ }
+ colour_char_window(ebp, current_font_flags, palette_pointer);
+ break;
+ case FORMAT_WINDOW_COLOUR_2:
+ ebp = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_2, uint8);
+ if (*current_font_flags & 1) {
+ if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) {
+ skip_char = 1;
+ }
+ else {
+ skip_char = 0;
+ }
+ break;
+ }
+ colour_char_window(ebp, current_font_flags, palette_pointer);
+ break;
+ case FORMAT_WINDOW_COLOUR_3:
+ ebp = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_3, uint8);
+ if (*current_font_flags & 1) {
+ if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) {
+ skip_char = 1;
+ }
+ else {
+ skip_char = 0;
+ }
+ break;
+ }
+ colour_char_window(ebp, current_font_flags, palette_pointer);
+ break;
+ case FORMAT_NEWLINE_X_Y: //Start new line at specified x,y
+ max_x = x + *++buffer;
+ max_y = y + *++buffer;
+ break;
+ case FORMAT_INLINE_SPRITE:
+ buffer += 4;
+ if (max_x >= dpi->x + dpi->width) {
+ skip_char = 1;
+ break;
+ }
+ ebx = *(buffer - 3);
+ eax = ebx & 0x7FFFF;
+ g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]);
+
+ gfx_draw_sprite(dpi, ebx, max_x, max_y);
+
+ max_x = max_x + g1_element->width;
+ break;
+ default:
+ // Colour codes
+ if ((al >= FORMAT_COLOUR_CODE_START) && (al <= FORMAT_COLOUR_CODE_END)){
+
+ if (*current_font_flags == 1) {
+ if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) {
+ skip_char = 1;
+ } else {
+ skip_char = 0;
+ }
continue;
}
- ebx = al + *current_font_sprite_base;
-
- ecx = max_x;
-
- max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF);
-
- eax = (int)al;
- ebx += 0xF15;
-
- edx = max_y;
- esi = (int)buffer;
- edi = (int)dpi;
- ebp = 0;
-
- RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000;
-
- gfx_draw_sprite_palette_set(dpi, 0x20000000 | ebx, ecx, edx, RCT2_GLOBAL(0x9ABDA4, uint8*), NULL);
-
+ colour_char(al - FORMAT_COLOUR_CODE_START, current_font_flags, palette_pointer);
continue;
}
+
+ // Normal Characters
+ if (max_x >= dpi->x + dpi->width) {
+ skip_char = 1;
+ }
+ if (max_x + 0x1A < dpi->x) {
+ ebx = al-0x20;
+ ebx += *current_font_sprite_base;
+ max_x = max_x + (RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8)[ebx] & 0xFF);
+ continue;
+ }
+
+ uint32 char_offset = al - 0x20 + *current_font_sprite_base;
+ RCT2_GLOBAL(0x00EDF81C, uint32) = (IMAGE_TYPE_USE_PALETTE << 28);
+
+ gfx_draw_sprite_palette_set(dpi, (IMAGE_TYPE_USE_PALETTE << 28) | char_offset + SPR_CHAR_START, max_x, max_y, palette_pointer, NULL);
+ max_x += (RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8)[char_offset] & 0xFF);
+ continue;
}
}
diff --git a/src/gfx.h b/src/gfx.h
index a627bffb72..f82ae27d02 100644
--- a/src/gfx.h
+++ b/src/gfx.h
@@ -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);
diff --git a/src/marketing.c b/src/marketing.c
index 15b7192035..57808a3a73 100644
--- a/src/marketing.c
+++ b/src/marketing.c
@@ -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;
diff --git a/src/news_item.c b/src/news_item.c
index f9584cdaa4..e2053594e5 100644
--- a/src/news_item.c
+++ b/src/news_item.c
@@ -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;
diff --git a/src/osinterface.c b/src/osinterface.c
index 3741f6bfd2..20d8778e88 100644
--- a/src/osinterface.c
+++ b/src/osinterface.c
@@ -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());
diff --git a/src/park.c b/src/park.c
index 0d45e8a597..72eb1cd87f 100644
--- a/src/park.c
+++ b/src/park.c
@@ -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);
}
diff --git a/src/peep.c b/src/peep.c
index 7042c04c5d..00dd073ff1 100644
--- a/src/peep.c
+++ b/src/peep.c
@@ -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;
diff --git a/src/peep.h b/src/peep.h
index 74dfd3f6b8..f71907cd36 100644
--- a/src/peep.h
+++ b/src/peep.h
@@ -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
diff --git a/src/rct2.c b/src/rct2.c
index 7ab6254c34..559fced6bf 100644
--- a/src/rct2.c
+++ b/src/rct2.c
@@ -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;
}
/**
diff --git a/src/rct2.h b/src/rct2.h
index f5b765b206..dcdb81bcc0 100644
--- a/src/rct2.h
+++ b/src/rct2.h
@@ -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();
diff --git a/src/ride.c b/src/ride.c
index bbaa1db97f..7dc493efd6 100644
--- a/src/ride.c
+++ b/src/ride.c
@@ -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 {
diff --git a/src/ride.h b/src/ride.h
index bcbc0c86dd..80357bc764 100644
--- a/src/ride.h
+++ b/src/ride.h
@@ -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];
diff --git a/src/scenario.c b/src/scenario.c
index 6dc29fa1bf..38c95bf5fd 100644
--- a/src/scenario.c
+++ b/src/scenario.c
@@ -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++;
}
diff --git a/src/sprite.c b/src/sprite.c
index 37157e98b6..c2c80cb5dd 100644
--- a/src/sprite.c
+++ b/src/sprite.c
@@ -19,8 +19,11 @@
*****************************************************************************/
#include "addresses.h"
+#include
#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;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/sprite.h b/src/sprite.h
index 3edb1d5e6f..f42388dd8e 100644
--- a/src/sprite.h
+++ b/src/sprite.h
@@ -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
diff --git a/src/sprites.h b/src/sprites.h
index 6f356affcb..2ec98fa449 100644
--- a/src/sprites.h
+++ b/src/sprites.h
@@ -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,
diff --git a/src/string_ids.h b/src/string_ids.h
index 5db27533b3..a13bbe7d2d 100644
--- a/src/string_ids.h
+++ b/src/string_ids.h
@@ -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,
diff --git a/src/title.c b/src/title.c
index bdd623692d..06a451667e 100644
--- a/src/title.c
+++ b/src/title.c
@@ -23,6 +23,7 @@
#include
#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);
}
diff --git a/src/vehicle.c b/src/vehicle.c
index a96bb51282..2bf9f92029 100644
--- a/src/vehicle.c
+++ b/src/vehicle.c
@@ -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);
diff --git a/src/vehicle.h b/src/vehicle.h
index 3bddf738fc..9451bdb8c8 100644
--- a/src/vehicle.h
+++ b/src/vehicle.h
@@ -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
diff --git a/src/widget.c b/src/widget.c
index f686f1bd26..d69b239cba 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -22,6 +22,7 @@
#include
#include
#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) {
// ?
diff --git a/src/window.c b/src/window.c
index 0a1e9168e1..541601a529 100644
--- a/src/window.c
+++ b/src/window.c
@@ -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);
diff --git a/src/window.h b/src/window.h
index ec54076f1b..de50344044 100644
--- a/src/window.h
+++ b/src/window.h
@@ -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();
diff --git a/src/window_cheats.c b/src/window_cheats.c
index 84301284fa..f95eb299f2 100644
--- a/src/window_cheats.c
+++ b/src/window_cheats.c
@@ -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
diff --git a/src/window_dropdown.c b/src/window_dropdown.c
index 4b552e7d80..f9b609d453 100644
--- a/src/window_dropdown.c
+++ b/src/window_dropdown.c
@@ -53,6 +53,7 @@ int _dropdown_highlighted_index;
uint16 gDropdownItemsFormat[64];
sint64 gDropdownItemsArgs[64];
+// Replaces 0x009DED38
uint32 gDropdownItemsChecked;
static void window_dropdown_emptysub() { }
diff --git a/src/window_game_bottom_toolbar.c b/src/window_game_bottom_toolbar.c
index 1d4b4ddf51..73ad07b02c 100644
--- a/src/window_game_bottom_toolbar.c
+++ b/src/window_game_bottom_toolbar.c
@@ -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
-
}
/**
diff --git a/src/window_guest_list.c b/src/window_guest_list.c
index 14fe8d13a7..e1a71208ab 100644
--- a/src/window_guest_list.c
+++ b/src/window_guest_list.c
@@ -19,12 +19,14 @@
*****************************************************************************/
#include
+#include
#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
diff --git a/src/window_park.c b/src/window_park.c
index d47358c7fd..2f65603d65 100644
--- a/src/window_park.c
+++ b/src/window_park.c
@@ -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;
diff --git a/src/window_peep.c b/src/window_peep.c
new file mode 100644
index 0000000000..daa92a38a3
--- /dev/null
+++ b/src/window_peep.c
@@ -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 .
+*****************************************************************************/
+
+#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);
+}
diff --git a/src/window_ride_list.c b/src/window_ride_list.c
index 8dff8e2433..a32c142236 100644
--- a/src/window_ride_list.c
+++ b/src/window_ride_list.c
@@ -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;