diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj
index d8737d4cf0..db01c91c99 100644
--- a/projects/openrct2.vcxproj
+++ b/projects/openrct2.vcxproj
@@ -28,10 +28,16 @@
+
+
-
+
+
+
+
+
@@ -45,14 +51,19 @@
-
+
+
+
+
+
+
@@ -111,12 +122,20 @@
+
+
+
+
+
+
+
+
-
+
@@ -128,8 +147,10 @@
-
+
+
+
@@ -137,6 +158,7 @@
+
@@ -197,8 +219,8 @@
$(SolutionDir)..\obj\$(Configuration)\
- $(SolutionDir)..\lodepng;$(SolutionDir)..\sdl\include;$(SolutionDir)..\libspeex;$(IncludePath)
- $(SolutionDir)..\sdl\lib\x86;$(LibraryPath)
+ $(SolutionDir)..\lib;$(SolutionDir)..\lib\libspeex;$(SolutionDir)..\lib\sdl\include;$(IncludePath)
+ $(SolutionDir)..\lib\sdl\lib\x86;$(LibraryPath)
$(SolutionDir)..\build\$(Configuration)\
$(SolutionDir)..\obj\$(Configuration)\
@@ -230,6 +252,7 @@
false
_CRT_SECURE_NO_WARNINGS;HAVE_CONFIG_H;_USE_MATH_DEFINES;%(PreprocessorDefinitions)
+ $(IntDir)fake\%(RelativeDir)
true
diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters
index ef32e47779..128d9c6948 100644
--- a/projects/openrct2.vcxproj.filters
+++ b/projects/openrct2.vcxproj.filters
@@ -53,6 +53,9 @@
{81716f5d-b396-4a82-a450-76fee56d982b}
+
+ {209155b8-2f61-4e25-ab86-c8aa36357abd}
+
@@ -104,9 +107,6 @@
Source\Audio
-
- Source\Drawing
-
Source\Interface
@@ -260,9 +260,6 @@
Source\Localisation
-
- Source\Localisation
-
Source\Platform
@@ -329,6 +326,45 @@
Source\Localisation
+
+ Source\Drawing
+
+
+ Source\Drawing
+
+
+ Source\Drawing
+
+
+ Source\Drawing
+
+
+ Source\Drawing
+
+
+ Source\Localisation
+
+
+ Source\Platform
+
+
+ Source\Platform
+
+
+ Source\Platform
+
+
+ Source\Platform
+
+
+ Source\Localisation
+
+
+ Libraries\lodepng
+
+
+ Libraries\libspeex
+
@@ -349,9 +385,6 @@
Source\Audio
-
- Source\Drawing
-
Source\Interface
@@ -478,5 +511,41 @@
Source\Localisation
+
+ Source\Drawing
+
+
+ Source
+
+
+ Source\Localisation
+
+
+ Source\Platform
+
+
+ Source\Localisation
+
+
+ Libraries\lodepng
+
+
+ Libraries\libspeex
+
+
+ Libraries\libspeex
+
+
+ Libraries\libspeex
+
+
+ Libraries\libspeex
+
+
+ Libraries\libspeex\speex
+
+
+ Libraries\libspeex\speex
+
\ No newline at end of file
diff --git a/src/audio/audio.c b/src/audio/audio.c
index 98c7f1a21c..ea045449ee 100644
--- a/src/audio/audio.c
+++ b/src/audio/audio.c
@@ -19,15 +19,14 @@
*****************************************************************************/
#include
+#include "../addresses.h"
+#include "../config.h"
+#include "../interface/viewport.h"
+#include "../interface/window.h"
+#include "../platform/osinterface.h"
+#include "../world/map.h"
+#include "../world/sprite.h"
#include "audio.h"
-#include "addresses.h"
-#include "config.h"
-#include "map.h"
-#include "osinterface.h"
-#include "rct2.h"
-#include "sprite.h"
-#include "viewport.h"
-#include "window.h"
int gAudioDeviceCount;
audio_device *gAudioDevices = NULL;
diff --git a/src/audio/audio.h b/src/audio/audio.h
index 6dbdfbadd2..6f4b70e294 100644
--- a/src/audio/audio.h
+++ b/src/audio/audio.h
@@ -21,8 +21,8 @@
#ifndef _AUDIO_H_
#define _AUDIO_H_
-#include "rct2.h"
-#include "sprite.h"
+#include "../common.h"
+#include "../world/sprite.h"
typedef struct {
char name[256];
diff --git a/src/audio/mixer.cpp b/src/audio/mixer.cpp
index baabda9f85..10f836645b 100644
--- a/src/audio/mixer.cpp
+++ b/src/audio/mixer.cpp
@@ -23,8 +23,8 @@
#include
extern "C" {
+#include "../config.h"
#include "audio.h"
-#include "config.h"
}
#include "mixer.h"
diff --git a/src/audio/mixer.h b/src/audio/mixer.h
index b2b453034b..b866f36ccf 100644
--- a/src/audio/mixer.h
+++ b/src/audio/mixer.h
@@ -21,7 +21,7 @@
#ifndef _MIXER_H_
#define _MIXER_H_
-#include "rct2.h"
+#include "../common.h"
#define MIXER_LOOP_NONE 0
#define MIXER_LOOP_INFINITE -1
diff --git a/src/common.h b/src/common.h
new file mode 100644
index 0000000000..e2bdc76314
--- /dev/null
+++ b/src/common.h
@@ -0,0 +1,26 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Ted John
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of OpenRCT2.
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#include "rct2.h"
+
+#endif
\ No newline at end of file
diff --git a/src/config.c b/src/config.c
index 4dbd9117a0..d12a86bc26 100644
--- a/src/config.c
+++ b/src/config.c
@@ -23,11 +23,8 @@
#include
#include "addresses.h"
#include "config.h"
-#include "language.h"
-#include "rct2.h"
-
-
-#include "osinterface.h"
+#include "localisation/localisation.h"
+#include "platform/osinterface.h"
// Current keyboard shortcuts
uint16 gShortcutKeys[SHORTCUT_COUNT];
diff --git a/src/config.h b/src/config.h
index 1c200ec09c..8efcdd6e68 100644
--- a/src/config.h
+++ b/src/config.h
@@ -21,9 +21,9 @@
#ifndef _CONFIG_H_
#define _CONFIG_H_
-#include "currency.h"
-#include "rct2.h"
#include // for MAX_PATH
+#include "common.h"
+#include "localisation/currency.h"
enum {
CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES = (1 << 0),
diff --git a/src/drawing/drawing.c b/src/drawing/drawing.c
new file mode 100644
index 0000000000..f64bc1a312
--- /dev/null
+++ b/src/drawing/drawing.c
@@ -0,0 +1,624 @@
+/*****************************************************************************
+ * 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.
+ *
+ * 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
+#include
+#include
+#include
+#include
+#include
+#include "../addresses.h"
+#include "../common.h"
+#include "../localisation/localisation.h"
+#include "../interface/window.h"
+#include "../platform/osinterface.h"
+#include "drawing.h"
+
+// HACK These were originally passed back through registers
+int gLastDrawStringX;
+int gLastDrawStringY;
+
+uint8 _screenDirtyBlocks[5120];
+
+//Originally 0x9ABE0C, 12 elements from 0xF3 are the peep top colour, 12 elements from 0xCA are peep trouser colour
+const uint8 peep_palette[0x100] = {
+ 0x00, 0xF3, 0xF4, 0xF5, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
+ 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+ 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+ 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+ 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
+ 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
+};
+
+//Originally 0x9ABE04
+uint8 text_palette[0x8] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+// Previously 0x97FCBC use it to get the correct palette from g1_elements
+const 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);
+
+/**
+ * Clears the screen with the specified colour.
+ * rct2: 0x00678A9F
+ */
+void gfx_clear(rct_drawpixelinfo *dpi, int colour)
+{
+ int y, w, h;
+ char* ptr;
+
+ w = dpi->width >> dpi->zoom_level;
+ h = dpi->height >> dpi->zoom_level;
+
+ ptr = dpi->bits;
+ for (y = 0; y < h; y++) {
+ memset(ptr, colour, w);
+ ptr += w + dpi->pitch;
+ }
+}
+
+void gfx_draw_pixel(rct_drawpixelinfo *dpi, int x, int y, int colour)
+{
+ gfx_fill_rect(dpi, x, y, x, y, colour);
+}
+
+#define RCT2_Y_RELATED_GLOBAL_1 0x9E3D12 //uint16
+#define RCT2_Y_END_POINT_GLOBAL 0x9ABDAC //sint16
+#define RCT2_Y_START_POINT_GLOBAL 0xEDF808 //sint16
+#define RCT2_X_RELATED_GLOBAL_1 0x9E3D10 //uint16
+#define RCT2_X_END_POINT_GLOBAL 0x9ABDA8 //sint16
+#define RCT2_X_START_POINT_GLOBAL 0xEDF80C //sint16
+#define RCT2_DPI_LINE_LENGTH_GLOBAL 0x9ABDB0 //uint16 width+pitch
+
+/*
+* 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(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;
+ //}
+ 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->pitch,
+ .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;
+ }
+
+ if ( dpi->zoom_level && (g1_source->flags & (1<<5)) ){
+ return;
+ }
+
+ //Its used super often so we will define it to a seperate variable.
+ int zoom_level = dpi->zoom_level;
+ int zoom_amount = 1 << zoom_level;
+ int zoom_mask = 0xFFFFFFFF << zoom_level;
+
+ //This will be the height of the drawn image
+ int height = g1_source->height;
+ //This is the start y coordinate on the destination
+ sint16 dest_start_y = ((y + g1_source->y_offset)&zoom_mask) - dpi->y;
+ //This is the start y coordinate on the source
+ int source_start_y = 0;
+
+ if (dest_start_y < 0){
+ //If the destination y is negative reduce the height of the
+ //image as we will cut off the bottom
+ height += dest_start_y;
+ //If the image is no longer visible nothing to draw
+ if (height <= 0){
+ return;
+ }
+ //The source image will start a further up the image
+ source_start_y -= dest_start_y;
+ //The destination start is now reset to 0
+ dest_start_y = 0;
+ }
+
+ int dest_end_y = dest_start_y + height;
+
+ if (dest_end_y > dpi->height){
+ //If the destination y is outside of the drawing
+ //image reduce the height of the image
+ height -= dest_end_y - dpi->height;
+ }
+ //If the image no longer has anything to draw
+ if (height <= 0)return;
+
+ dest_start_y /= zoom_amount;
+ dest_end_y /= zoom_amount;
+
+ //This will be the width of the drawn image
+ int width = g1_source->width;
+ //This is the source start x coordinate
+ int source_start_x = 0;
+ //This is the destination start x coordinate
+ sint16 dest_start_x = ((x + g1_source->x_offset) & zoom_mask) - dpi->x;
+
+ if (dest_start_x < 0){
+ //If the destination is negative reduce the width
+ //image will cut off the side
+ width += dest_start_x;
+ //If there is no image to draw
+ if (width <= 0){
+ return;
+ }
+ //The source start will also need to cut off the side
+ source_start_x -= dest_start_x;
+ //Reset the destination to 0
+ dest_start_x = 0;
+ }
+
+ int dest_end_x = dest_start_x + width;
+
+ if (dest_end_x > dpi->width){
+ //If the destination x is outside of the drawing area
+ //reduce the image width.
+ width -= dest_end_x - dpi->width;
+ //If there is no image to draw.
+ if (width <= 0)return;
+ }
+
+ dest_start_x /= zoom_amount;
+ dest_end_x /= zoom_amount;
+
+ uint8* dest_pointer = (uint8*)dpi->bits;
+ //Move the pointer to the start point of the destination
+ dest_pointer += ((dpi->width / zoom_amount) + dpi->pitch)*dest_start_y + dest_start_x;
+
+ if (g1_source->flags & G1_FLAG_RLE_COMPRESSION){
+ //We have to use a different method to move the source pointer for
+ //rle encoded sprites so that will be handled within this function
+ gfx_rle_sprite_to_buffer(g1_source->offset, dest_pointer, palette_pointer, dpi, image_type, source_start_y, height, source_start_x, width);
+ return;
+ }
+ uint8* source_pointer = g1_source->offset;
+ //Move the pointer to the start point of the source
+ source_pointer += g1_source->width*source_start_y + source_start_x;
+
+ if (!(g1_source->flags & 0x02)){
+ gfx_bmp_sprite_to_buffer(palette_pointer, unknown_pointer, source_pointer, dest_pointer, g1_source, dpi, height, width, image_type);
+ return;
+ }
+ //0x67A60A Not tested
+ int total_no_pixels = g1_source->width*g1_source->height;
+ source_pointer = g1_source->offset;
+ uint8* new_source_pointer_start = malloc(total_no_pixels);
+ uint8* new_source_pointer = new_source_pointer_start;// 0x9E3D28;
+ int ebx, ecx;
+ while (total_no_pixels>0){
+ sint8 no_pixels = *source_pointer;
+ if (no_pixels >= 0){
+ source_pointer++;
+ total_no_pixels -= no_pixels;
+ memcpy((char*)new_source_pointer, (char*)source_pointer, no_pixels);
+ new_source_pointer += no_pixels;
+ source_pointer += no_pixels;
+ continue;
+ }
+ ecx = no_pixels;
+ no_pixels &= 0x7;
+ ecx >>= 3;//SAR
+ int eax = ((int)no_pixels)<<8;
+ ecx = -ecx;//Odd
+ eax = eax & 0xFF00 + *(source_pointer+1);
+ total_no_pixels -= ecx;
+ source_pointer += 2;
+ ebx = (uint32)new_source_pointer - eax;
+ eax = (uint32)source_pointer;
+ source_pointer = (uint8*)ebx;
+ ebx = eax;
+ eax = 0;
+ memcpy((char*)new_source_pointer, (char*)source_pointer, ecx);
+ new_source_pointer += ecx;
+ source_pointer += ecx;
+ source_pointer = (uint8*)ebx;
+ }
+ source_pointer = new_source_pointer_start + g1_source->width*source_start_y + source_start_x;
+ gfx_bmp_sprite_to_buffer(palette_pointer, unknown_pointer, source_pointer, dest_pointer, g1_source, dpi, height, width, image_type);
+ free(new_source_pointer_start);
+ return;
+}
+
+/**
+ *
+ * rct2: 0x00683854
+ * a1 (ebx)
+ * product (cl)
+ */
+void gfx_transpose_palette(int pal, unsigned char product)
+{
+ 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;
+
+ 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);//Odd would have expected dest_pointer
+}
+/**
+ * Draws i formatted text string centred at i specified position.
+ * rct2: 0x006C1D6C
+ * dpi (edi)
+ * format (bx)
+ * x (cx)
+ * y (dx)
+ * colour (al)
+ * args (esi)
+ */
+void gfx_draw_string_centred(rct_drawpixelinfo *dpi, int format, int x, int y, int colour, void *args)
+{
+ char* buffer;
+ short text_width;
+
+ buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char);
+ format_string(buffer, format, args);
+
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0;
+
+ // Measure text width
+ text_width = gfx_get_string_width(buffer);
+
+ // Draw the text centred
+ if (text_width <= 0xFFFF) {
+ x -= text_width / 2;
+ gfx_draw_string(dpi, buffer, colour, x, y);
+ }
+}
+
+/**
+ *
+ * rct2: 0x006ED7E5
+ */
+void gfx_invalidate_screen()
+{
+ int width = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16);
+ int height = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16);
+ gfx_set_dirty_blocks(0, 0, width, height);
+}
+
+/**
+ *
+ * rct2: 0x006E732D
+ * left (ax)
+ * top (bx)
+ * right (dx)
+ * bottom (bp)
+ */
+void gfx_set_dirty_blocks(int left, int top, int right, int bottom)
+{
+ int x, y;
+ uint8 *screenDirtyBlocks = RCT2_ADDRESS(0x00EDE408, uint8);
+
+ left = max(left, 0);
+ top = max(top, 0);
+ right = min(right, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16));
+ bottom = min(bottom, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16));
+
+ if (left >= right)
+ return;
+ if (top >= bottom)
+ return;
+
+ right--;
+ bottom--;
+
+ left >>= RCT2_GLOBAL(0x009ABDF0, sint8);
+ right >>= RCT2_GLOBAL(0x009ABDF0, sint8);
+ top >>= RCT2_GLOBAL(0x009ABDF1, sint8);
+ bottom >>= RCT2_GLOBAL(0x009ABDF1, sint8);
+
+ for (y = top; y <= bottom; y++)
+ for (x = left; x <= right; x++)
+ screenDirtyBlocks[y * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32) + x] = 0xFF;
+}
+
+/**
+ *
+ * rct2: 0x006E73BE
+ */
+void gfx_draw_all_dirty_blocks()
+{
+ int x, y, xx, yy, columns, rows;
+ uint8 *screenDirtyBlocks = RCT2_ADDRESS(0x00EDE408, uint8);
+
+ for (x = 0; x < RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32); x++) {
+ for (y = 0; y < RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_ROWS, sint32); y++) {
+ if (screenDirtyBlocks[y * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32) + x] == 0)
+ continue;
+
+ // Determine columns
+ for (xx = x; xx < RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32); xx++)
+ if (screenDirtyBlocks[y * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32) + xx] == 0)
+ break;
+ columns = xx - x;
+
+ // Check rows
+ for (yy = y; yy < RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_ROWS, sint32); yy++)
+ for (xx = x; xx < x + columns; xx++)
+ if (screenDirtyBlocks[yy * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32) + xx] == 0)
+ goto endRowCheck;
+
+ endRowCheck:
+ rows = yy - y;
+ gfx_draw_dirty_blocks(x, y, columns, rows);
+ }
+ }
+}
+
+static void gfx_draw_dirty_blocks(int x, int y, int columns, int rows)
+{
+ int left, top, right, bottom;
+ uint8 *screenDirtyBlocks = RCT2_ADDRESS(0x00EDE408, uint8);
+
+ // Unset dirty blocks
+ for (top = y; top < y + rows; top++)
+ for (left = x; left < x + columns; left++)
+ screenDirtyBlocks[top * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32) + left] = 0;
+
+ // Determine region in pixels
+ left = max(0, x * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_WIDTH, sint16));
+ top = max(0, y * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_HEIGHT, sint16));
+ right = min(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16), left + (columns * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_WIDTH, sint16)));
+ bottom = min(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16), top + (rows * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_HEIGHT, sint16)));
+ if (right <= left || bottom <= top)
+ return;
+
+ // Draw region
+ gfx_redraw_screen_rect(left, top, right, bottom);
+}
+
+/**
+ *
+ * rct2: 0x006E7499
+ * left (ax)
+ * top (bx)
+ * right (dx)
+ * bottom (bp)
+ */
+void gfx_redraw_screen_rect(short left, short top, short right, short bottom)
+{
+ rct_window* w;
+ rct_drawpixelinfo *screenDPI = RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo);
+ rct_drawpixelinfo *windowDPI = RCT2_ADDRESS(RCT2_ADDRESS_WINDOW_DPI, rct_drawpixelinfo);
+
+ // Unsure what this does
+ RCT2_CALLPROC_X(0x00683326, left, top, right - 1, bottom - 1, 0, 0, 0);
+
+ windowDPI->bits = screenDPI->bits + left + ((screenDPI->width + screenDPI->pitch) * top);
+ windowDPI->x = left;
+ windowDPI->y = top;
+ windowDPI->width = right - left;
+ windowDPI->height = bottom - top;
+ windowDPI->pitch = screenDPI->width + screenDPI->pitch + left - right;
+
+ for (w = g_window_list; w < RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*); w++) {
+ if (w->flags & WF_TRANSPARENT)
+ continue;
+ if (right <= w->x || bottom <= w->y)
+ continue;
+ if (left >= w->x + w->width || top >= w->y + w->height)
+ continue;
+ window_draw(w, left, top, right, bottom);
+ }
+}
+
+/*
+*
+* rct2: 0x006EE53B
+* left (ax)
+* width (bx)
+* top (cx)
+* height (dx)
+* drawpixelinfo (edi)
+*/
+rct_drawpixelinfo* clip_drawpixelinfo(rct_drawpixelinfo* dpi, int left, int width, int top, int height)
+{
+ rct_drawpixelinfo* newDrawPixelInfo = rct2_malloc(sizeof(rct_drawpixelinfo));
+
+ int right = left + width;
+ int bottom = top + height;
+
+ newDrawPixelInfo->bits = dpi->bits;
+ newDrawPixelInfo->x = dpi->x;
+ newDrawPixelInfo->y = dpi->y;
+ newDrawPixelInfo->width = dpi->width;
+ newDrawPixelInfo->height = dpi->height;
+ newDrawPixelInfo->pitch = dpi->pitch;
+ newDrawPixelInfo->zoom_level = 0;
+
+ if (left > newDrawPixelInfo->x) {
+ uint16 clippedFromLeft = left - newDrawPixelInfo->x;
+ newDrawPixelInfo->width -= clippedFromLeft;
+ newDrawPixelInfo->x = left;
+ newDrawPixelInfo->pitch += clippedFromLeft;
+ newDrawPixelInfo->bits += clippedFromLeft;
+ }
+
+ int stickOutWidth = newDrawPixelInfo->x + newDrawPixelInfo->width - right;
+ if (stickOutWidth > 0) {
+ newDrawPixelInfo->width -= stickOutWidth;
+ newDrawPixelInfo->pitch += stickOutWidth;
+ }
+
+ if (top > newDrawPixelInfo->y) {
+ uint16 clippedFromTop = top - newDrawPixelInfo->y;
+ newDrawPixelInfo->height -= clippedFromTop;
+ newDrawPixelInfo->y = top;
+ uint32 bitsPlus = (newDrawPixelInfo->pitch + newDrawPixelInfo->width) * clippedFromTop;
+ newDrawPixelInfo->bits += bitsPlus;
+ }
+
+ int bp = newDrawPixelInfo->y + newDrawPixelInfo->height - bottom;
+ if (bp > 0) {
+ newDrawPixelInfo->height -= bp;
+ }
+
+ if (newDrawPixelInfo->width > 0 && newDrawPixelInfo->height > 0) {
+ newDrawPixelInfo->x -= left;
+ newDrawPixelInfo->y -= top;
+
+ return newDrawPixelInfo;
+ }
+
+ rct2_free(newDrawPixelInfo);
+ return NULL;
+}
+
+/***
+*
+* rct2: 0x00684027
+*
+* ebp used to be a parameter but it is always zero
+* left : eax
+* top : ebx
+* width : ecx
+* height : edx
+* x_start: edi
+* y_start: esi
+*/
+void gfx_draw_rain(int left, int top, int width, int height, sint32 x_start, sint32 y_start){
+ uint8* pattern = RCT2_GLOBAL(RCT2_ADDRESS_RAIN_PATTERN, uint8*);
+ uint8 pattern_x_space = *pattern++;
+ uint8 pattern_y_space = *pattern++;
+
+ uint8 pattern_start_x_offset = x_start % pattern_x_space;
+ uint8 pattern_start_y_offset = y_start % pattern_y_space;;
+
+ rct_drawpixelinfo* dpi = RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo);
+ uint32 pixel_offset = (dpi->pitch + dpi->width)*top + left;
+ uint8 pattern_y_pos = pattern_start_y_offset;
+
+ //Stores the colours of changed pixels
+ uint32* pixel_store = RCT2_ADDRESS(RCT2_ADDRESS_RAIN_PIXEL_STORE, uint32);
+ pixel_store += RCT2_GLOBAL(RCT2_ADDRESS_NO_RAIN_PIXELS, uint32);
+
+ for (; height != 0; height--){
+ uint8 pattern_x = pattern[pattern_y_pos * 2];
+ if (pattern_x != 0xFF){
+ if (RCT2_GLOBAL(0x9AC00C, uint32) <= 0x1F38){
+
+ int final_pixel_offset = width + pixel_offset;
+
+ int x_pixel_offset = pixel_offset;
+ x_pixel_offset += ((uint8)(pattern_x - pattern_start_x_offset)) % pattern_x_space;
+
+ uint8 pattern_pixel = pattern[pattern_y_pos * 2 + 1];
+ for (; x_pixel_offset < final_pixel_offset; x_pixel_offset += pattern_x_space){
+ uint8 current_pixel = dpi->bits[x_pixel_offset];
+ dpi->bits[x_pixel_offset] = pattern_pixel;
+ RCT2_GLOBAL(RCT2_ADDRESS_NO_RAIN_PIXELS, uint32)++;
+
+ //Store colour and position
+ *pixel_store++ = (x_pixel_offset << 8) | current_pixel;
+ }
+ }
+ }
+
+ pixel_offset += dpi->pitch + dpi->width;
+
+ pattern_y_pos++;
+ pattern_y_pos %= pattern_y_space;
+ }
+}
\ No newline at end of file
diff --git a/src/drawing/gfx.h b/src/drawing/drawing.h
similarity index 86%
rename from src/drawing/gfx.h
rename to src/drawing/drawing.h
index df9984dd26..a240d5429f 100644
--- a/src/drawing/gfx.h
+++ b/src/drawing/drawing.h
@@ -18,10 +18,10 @@
* along with this program. If not, see .
*****************************************************************************/
-#ifndef _GFX_H_
-#define _GFX_H_
+#ifndef _DRAWING_H_
+#define _DRAWING_H_
-#include "rct2.h"
+#include "../common.h"
// Size: 0x10
typedef struct {
@@ -58,47 +58,58 @@ enum{
IMAGE_TYPE_UNKNOWN = (1<<3)
};
+extern const uint16 palette_to_g1_offset[];
+extern const uint8 peep_palette[];
+extern uint8 text_palette[];
+
extern int gLastDrawStringX;
extern int gLastDrawStringY;
-int gfx_load_g1();
-void gfx_load_character_widths();
-
-int gfx_wrap_string(char* buffer, int width, int* num_lines, int* font_height);
-void gfx_clear(rct_drawpixelinfo *dpi, int colour);
-void gfx_draw_pixel(rct_drawpixelinfo *dpi, int x, int y, int colour);
-void gfx_draw_line(rct_drawpixelinfo *dpi, int x1, int y1, int x2, int y2, int colour);
-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, uint32 tertiary_colour);
-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 *buffer, int colour, int x, int y);
-void gfx_transpose_palette(int pal, unsigned char product);
-
-void gfx_draw_string_left(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y);
-void gfx_draw_string_left_clipped(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y, int width);
-void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y, int width);
-void gfx_draw_string_right(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y);
-void gfx_draw_string_centred(rct_drawpixelinfo *dpi, int format, int x, int y, int colour, void *args);
-int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour);
-int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour);
-
-int gfx_get_string_width(char *buffer);
-int clip_text(char *buffer, int width);
-void gfx_fill_rect_inset(rct_drawpixelinfo *dpi, short left, short top, short right, short bottom, int colour, short _si);
-
+//
+rct_drawpixelinfo* clip_drawpixelinfo(rct_drawpixelinfo* dpi, int left, int width, int top, int height);
void gfx_set_dirty_blocks(int left, int top, int right, int bottom);
void gfx_draw_all_dirty_blocks();
void gfx_redraw_screen_rect(short left, short top, short right, short bottom);
void gfx_invalidate_screen();
+// palette
+void gfx_transpose_palette(int pal, unsigned char product);
+
+// other
void gfx_draw_rain(int left, int top, int width, int height, sint32 x_start, sint32 y_start);
+void gfx_clear(rct_drawpixelinfo *dpi, int colour);
+void gfx_draw_pixel(rct_drawpixelinfo *dpi, int x, int y, int colour);
-rct_drawpixelinfo* clip_drawpixelinfo(rct_drawpixelinfo* dpi, int left, int width, int top, int height);
+// line
+void gfx_draw_line(rct_drawpixelinfo *dpi, int x1, int y1, int x2, int y2, int colour);
+// rect
+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);
+
+// sprite
+int gfx_load_g1();
+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);
+void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_pointer, uint8* palette_pointer, rct_drawpixelinfo *dpi, int image_type, int source_y_start, int height, int source_x_start, int width);
+void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32 tertiary_colour);
+void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer);
+
+// string
+void gfx_load_character_widths();
+int clip_text(char *buffer, int width);
+int gfx_wrap_string(char* buffer, int width, int* num_lines, int* font_height);
+int gfx_get_string_width(char *buffer);
+void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, int y);
+void gfx_draw_string_left(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y);
+void gfx_draw_string_left_clipped(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y, int width);
+int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour);
void draw_string_left_underline(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y);
-void draw_string_right_underline(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y);
+void gfx_draw_string_centred(rct_drawpixelinfo *dpi, int format, int x, int y, int colour, void *args);
+void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y, int width);
void draw_string_centred_underline(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y);
+int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour);
void draw_string_centred_raw(rct_drawpixelinfo *dpi, int x, int y, int numLines, char *text);
+void gfx_draw_string_right(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y);
+void draw_string_right_underline(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y);
#endif
diff --git a/src/drawing/gfx.c b/src/drawing/gfx.c
deleted file mode 100644
index 93c3f44748..0000000000
--- a/src/drawing/gfx.c
+++ /dev/null
@@ -1,2421 +0,0 @@
-/*****************************************************************************
- * 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.
- *
- * 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
-#include
-#include
-#include
-#include
-#include
-#include "addresses.h"
-#include "gfx.h"
-#include "rct2.h"
-#include "string_ids.h"
-#include "sprites.h"
-#include "window.h"
-#include "osinterface.h"
-
-typedef struct {
- uint32 num_entries;
- uint32 total_size;
-} rct_g1_header;
-
-void *_g1Buffer = NULL;
-
-// HACK These were originally passed back through registers
-int gLastDrawStringX;
-int gLastDrawStringY;
-
-uint8 _screenDirtyBlocks[5120];
-
-//Originally 0x9ABE0C, 12 elements from 0xF3 are the peep top colour, 12 elements from 0xCA are peep trouser colour
-uint8 peep_palette[0x100] = {
- 0x00, 0xF3, 0xF4, 0xF5, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
- 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
- 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
- 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
- 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
- 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
- 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
- 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
- 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
-};
-
-//Originally 0x9ABE04
-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);
-
-/**
- *
- * rct2: 0x00678998
- */
-int gfx_load_g1()
-{
- FILE *file;
- rct_g1_header header;
- unsigned int i;
-
- rct_g1_element *g1Elements = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element);
-
- file = fopen(get_file_path(PATH_ID_G1), "rb");
- if (file != NULL) {
- if (fread(&header, 8, 1, file) == 1) {
- // number of elements is stored in g1.dat, but because the entry headers are static, this can't be variable until
- // made into a dynamic array
- header.num_entries = 29294;
-
- // Read element headers
- fread(g1Elements, header.num_entries * sizeof(rct_g1_element), 1, file);
-
- // Read element data
- _g1Buffer = rct2_malloc(header.total_size);
- fread(_g1Buffer, header.total_size, 1, file);
-
- fclose(file);
-
- // Fix entry data offsets
- for (i = 0; i < header.num_entries; i++)
- g1Elements[i].offset += (int)_g1Buffer;
-
- // Successful
- return 1;
- }
- fclose(file);
- }
-
- // Unsuccessful
- RCT2_ERROR("Unable to load g1.dat");
- 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, 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
- */
-void gfx_clear(rct_drawpixelinfo *dpi, int colour)
-{
- int y, w, h;
- char* ptr;
-
- w = dpi->width >> dpi->zoom_level;
- h = dpi->height >> dpi->zoom_level;
-
- ptr = dpi->bits;
- for (y = 0; y < h; y++) {
- memset(ptr, colour, w);
- ptr += w + dpi->pitch;
- }
-}
-
-void gfx_draw_pixel(rct_drawpixelinfo *dpi, int x, int y, int colour)
-{
- gfx_fill_rect(dpi, x, y, x, y, colour);
-}
-
-/*
-* Draws a horizontal line of specified colour to a buffer.
-* rct2: 0x68474C
-*/
-void gfx_draw_line_on_buffer(rct_drawpixelinfo *dpi, char colour, int y, int x, int no_pixels)
-{
- y -= dpi->y;
-
- //Check to make sure point is in the y range
- if (y < 0)return;
- if (y >= dpi->height)return;
- //Check to make sure we are drawing at least a pixel
- if (!no_pixels) no_pixels++;
-
- x -= dpi->x;
-
- //If x coord outside range leave
- if (x < 0){
- //Unless the number of pixels is enough to be in range
- no_pixels += x;
- if (no_pixels <= 0)return;
- //Resets starting point to 0 as we don't draw outside the range
- x = 0;
- }
-
- //Ensure that the end point of the line is within range
- if (x + no_pixels - dpi->width > 0){
- //If the end point has any pixels outside range
- //cut them off. If there are now no pixels return.
- no_pixels -= x + no_pixels - dpi->width;
- if (no_pixels <= 0)return;
- }
-
- char* bits_pointer;
- //Get the buffer we are drawing to and move to the first coordinate.
- bits_pointer = dpi->bits + y*(dpi->pitch + dpi->width) + x;
-
- //Draw the line to the specified colour
- for (; no_pixels > 0; --no_pixels, ++bits_pointer){
- *((uint8*)bits_pointer) = colour;
- }
-}
-
-
-/**
- * Draws a line on dpi if within dpi boundaries
- * rct2: 0x00684466
- * dpi (edi)
- * x1 (ax)
- * y1 (bx)
- * x2 (cx)
- * y2 (dx)
- * colour (ebp)
- */
-void gfx_draw_line(rct_drawpixelinfo *dpi, int x1, int y1, int x2, int y2, int colour)
-{
- // Check to make sure the line is within the drawing area
- if ((x1 < dpi->x) && (x2 < dpi->x)){
- return;
- }
-
- if ((y1 < dpi->y) && (y2 < dpi->y)){
- return;
- }
-
- if ((x1 >(dpi->x + dpi->width)) && (x2 >(dpi->x + dpi->width))){
- return;
- }
-
- if ((y1 > (dpi->y + dpi->height)) && (y2 > (dpi->y + dpi->height))){
- return;
- }
-
- //Bresenhams algorithm
-
- //If vertical plot points upwards
- int steep = abs(y2 - y1) > abs(x2 - x1);
- if (steep){
- int temp_y2 = y2;
- int temp_x2 = x2;
- y2 = x1;
- x2 = y1;
- y1 = temp_x2;
- x1 = temp_y2;
- }
-
- //If line is right to left swap direction
- if (x1 > x2){
- int temp_y2 = y2;
- int temp_x2 = x2;
- y2 = y1;
- x2 = x1;
- y1 = temp_y2;
- x1 = temp_x2;
- }
-
- int delta_x = x2 - x1;
- int delta_y = abs(y2 - y1);
- int error = delta_x / 2;
- int y_step;
- int y = y1;
-
- //Direction of step
- if (y1 < y2)y_step = 1;
- else y_step = -1;
-
- for (int x = x1, x_start = x1, no_pixels = 1; x < x2; ++x,++no_pixels){
- //Vertical lines are drawn 1 pixel at a time
- if (steep)gfx_draw_line_on_buffer(dpi, colour, x, y, 1);
-
- error -= delta_y;
- if (error < 0){
- //Non vertical lines are drawn with as many pixels in a horizontal line as possible
- if (!steep)gfx_draw_line_on_buffer(dpi, colour, y, x_start, no_pixels);
-
- //Reset non vertical line vars
- x_start = x + 1;
- no_pixels = 1;
- y += y_step;
- error += delta_x;
- }
-
- //Catch the case of the last line
- if (x + 1 == x2 && !steep){
- gfx_draw_line_on_buffer(dpi, colour, y, x_start, no_pixels);
- }
- }
- return;
-}
-
-/**
- *
- * rct2: 0x00678AD4
- * dpi (edi)
- * left (ax)
- * top (cx)
- * right (bx)
- * bottom (dx)
- * colour (ebp)
- */
-void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bottom, int colour)
-{
- int left_, right_, top_, bottom_;
- rct_drawpixelinfo* dpi_;
- left_ = left;
- right_ = right;
- top_ = top;
- bottom_ = bottom;
- dpi_ = dpi;
-
- if ((left > right) || (top > bottom) || (dpi->x > right) || (left >= (dpi->x + dpi->width)) ||
- (bottom < dpi->y) || (top >= (dpi->y + dpi->height)))
- return;
-
- colour |= RCT2_GLOBAL(0x009ABD9C, uint32);
-
- uint16 cross_pattern = 0;
-
- int start_x = left - dpi->x;
- if (start_x < 0){
- start_x = 0;
- cross_pattern ^= start_x;
- }
-
- 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;
-
- uint32 ecx;
- 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) | width;
- // Fill every other pixel with the colour
- for (; (ecx & 0xFFFF) > 0; ecx--) {
- ecx = ecx ^ 0x80000000;
- if ((int)ecx < 0) {
- *dest_pointer = colour & 0xFF;
- }
- dest_pointer++;
- }
- 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);
-}
-
-/**
- * Draw a rectangle, with optional border or fill
- *
- * rct2: 0x006E6F81
- * dpi (edi)
- * left (ax)
- * top (cx)
- * right (bx)
- * bottom (dx)
- * colour (ebp)
- * flags (si)
- */
-void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short right, short bottom, int colour, short flags)
-{
- uint8 shadow, fill, hilight;
-
- // Flags
- int no_border, no_fill, pressed;
-
- no_border = 8;
- no_fill = 0x10;
- pressed = 0x20;
-
- if (colour & 0x180) {
- if (colour & 0x100) {
- colour = colour & 0x7F;
- } else {
- colour = RCT2_ADDRESS(0x009DEDF4,uint8)[colour];
- }
-
- colour = colour | 0x2000000; //Transparent
-
- if (flags & no_border) {
- gfx_fill_rect(dpi, left, top, bottom, right, colour);
- } else if (flags & pressed) {
- // Draw outline of box
- gfx_fill_rect(dpi, left, top, left, bottom, colour + 1);
- gfx_fill_rect(dpi, left, top, right, top, colour + 1);
- gfx_fill_rect(dpi, right, top, right, bottom, colour + 2);
- gfx_fill_rect(dpi, left, bottom, right, bottom, colour + 2);
-
- if (!(flags & no_fill)) {
- gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, colour);
- }
- } else {
- // Draw outline of box
- gfx_fill_rect(dpi, left, top, left, bottom, colour + 2);
- gfx_fill_rect(dpi, left, top, right, top, colour + 2);
- gfx_fill_rect(dpi, right, top, right, bottom, colour + 1);
- gfx_fill_rect(dpi, left, bottom, right, bottom, colour + 1);
-
- if (!(flags & no_fill)) {
- gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, colour);
- }
- }
- } else {
- if (flags & 0x80) {
- shadow = RCT2_ADDRESS(0x0141FC46, uint8)[colour * 8];
- fill = RCT2_ADDRESS(0x0141FC48, uint8)[colour * 8];
- hilight = RCT2_ADDRESS(0x0141FC4A, uint8)[colour * 8];
- } else {
- shadow = RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8];
- fill = RCT2_ADDRESS(0x0141FC49, uint8)[colour * 8];
- hilight = RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8];
- }
-
- if (flags & no_border) {
- gfx_fill_rect(dpi, left, top, right, bottom, fill);
- } else if (flags & pressed) {
- // Draw outline of box
- gfx_fill_rect(dpi, left, top, left, bottom, shadow);
- gfx_fill_rect(dpi, left + 1, top, right, top, shadow);
- gfx_fill_rect(dpi, right, top + 1, right, bottom - 1, hilight);
- gfx_fill_rect(dpi, left + 1, bottom, right, bottom, hilight);
-
- if (!(flags & no_fill)) {
- if (!(flags & 0x40)) {
- if (flags & 0x04) {
- fill = RCT2_ADDRESS(0x0141FC49, uint8)[0];
- } else {
- fill = RCT2_ADDRESS(0x0141FC4A, uint8)[colour * 8];
- }
- }
- gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, fill);
- }
- } else {
- // Draw outline of box
- gfx_fill_rect(dpi, left, top, left, bottom - 1, hilight);
- gfx_fill_rect(dpi, left + 1, top, right - 1, top, hilight);
- gfx_fill_rect(dpi, right, top, right, bottom - 1, shadow);
- gfx_fill_rect(dpi, left, bottom, right, bottom, shadow);
-
- if (!(flags & no_fill)) {
- if (flags & 0x04) {
- fill = RCT2_ADDRESS(0x0141FC49, uint8)[0];
- }
- gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, fill);
- }
- }
- }
-}
-
-#define RCT2_Y_RELATED_GLOBAL_1 0x9E3D12 //uint16
-#define RCT2_Y_END_POINT_GLOBAL 0x9ABDAC //sint16
-#define RCT2_Y_START_POINT_GLOBAL 0xEDF808 //sint16
-#define RCT2_X_RELATED_GLOBAL_1 0x9E3D10 //uint16
-#define RCT2_X_END_POINT_GLOBAL 0x9ABDA8 //sint16
-#define RCT2_X_START_POINT_GLOBAL 0xEDF80C //sint16
-#define RCT2_DPI_LINE_LENGTH_GLOBAL 0x9ABDB0 //uint16 width+pitch
-
-/*
-* rct2: 0x67A690
-* copies a sprite onto the buffer. There is no compression used on the sprite
-* 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;
- uint8 zoom_amount = 1 << zoom_level;
- //Requires use of palette?
- if (image_type & IMAGE_TYPE_USE_PALETTE){
-
- //Mix with another image?? and colour adjusted
- 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_amount){
- uint8* next_source_pointer = source_pointer + (uint32)(source_image->width * zoom_amount);
- uint8* next_unknown_pointer = unknown_pointer + (uint32)(source_image->width * zoom_amount);
- uint8* next_dest_pointer = dest_pointer + (dest_dpi->width / zoom_amount) + dest_dpi->pitch;
-
- for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_amount, source_pointer += zoom_amount, unknown_pointer += zoom_amount, dest_pointer++){
- uint8 pixel = *source_pointer;
- pixel = palette_pointer[pixel];
- pixel &= *unknown_pointer;
- if (pixel){
- *dest_pointer = pixel;
- }
- }
- source_pointer = next_source_pointer;
- dest_pointer = next_dest_pointer;
- unknown_pointer = next_unknown_pointer;
- }
- return;
- }
-
- //image colour adjusted?
- for (; height > 0; height -= zoom_amount){
- uint8* next_source_pointer = source_pointer + (uint32)(source_image->width * zoom_amount);
- uint8* next_dest_pointer = dest_pointer + (dest_dpi->width / zoom_amount) + dest_dpi->pitch;
- for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_amount, source_pointer += zoom_amount, dest_pointer++){
- uint8 pixel = *source_pointer;
- pixel = palette_pointer[pixel];
- if (pixel){
- *dest_pointer = pixel;
- }
- }
-
- source_pointer = next_source_pointer;
- dest_pointer = next_dest_pointer;
- }
- return;
- }
-
- //Mix with background. It only uses source pointer for
- //telling if it needs to be drawn not for colour.
- if (image_type & IMAGE_TYPE_MIX_BACKGROUND){//Not tested
- for (; height > 0; height -= zoom_amount){
- uint8* next_source_pointer = source_pointer + (uint32)(source_image->width * zoom_amount);
- uint8* next_dest_pointer = dest_pointer + (dest_dpi->width / zoom_amount) + dest_dpi->pitch;
-
- for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_amount, source_pointer += zoom_amount, dest_pointer++){
- uint8 pixel = *source_pointer;
- if (pixel){
- pixel = *dest_pointer;
- pixel = palette_pointer[pixel];
- *dest_pointer = pixel;
- }
- }
-
- source_pointer = next_source_pointer;
- dest_pointer = next_dest_pointer;
- }
- return;
- }
-
- //Basic bitmap no fancy stuff
- if (!(source_image->flags & G1_FLAG_BMP)){//Not tested
- for (; height > 0; height -= zoom_amount){
- uint8* next_source_pointer = source_pointer + (uint32)(source_image->width * zoom_amount);
- uint8* next_dest_pointer = dest_pointer + (dest_dpi->width / zoom_amount) + dest_dpi->pitch;
-
- for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_amount, dest_pointer++, source_pointer += zoom_amount){
- *dest_pointer = *source_pointer;
- }
-
- dest_pointer = next_dest_pointer;
- source_pointer = next_source_pointer;
- }
- return;
- }
-
- if (RCT2_GLOBAL(0x9E3CDC, uint32) != 0){//Not tested. I can't actually work out when this code runs.
- unknown_pointer += source_pointer - source_image->offset;
-
- for (; height > 0; height -= zoom_amount){
- uint8* next_source_pointer = source_pointer + (uint32)(source_image->width * zoom_amount);
- uint8* next_unknown_pointer = unknown_pointer + (uint32)(source_image->width * zoom_amount);
- uint8* next_dest_pointer = dest_pointer + (dest_dpi->width / zoom_amount) + dest_dpi->pitch;
-
- for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_amount, dest_pointer++, source_pointer += zoom_amount, unknown_pointer += zoom_amount){
- uint8 pixel = *source_pointer;
- pixel &= *unknown_pointer;
- if (pixel){
- *dest_pointer = pixel;
- }
- }
- dest_pointer = next_dest_pointer;
- source_pointer = next_source_pointer;
- unknown_pointer = next_unknown_pointer;
- }
- }
-
- //Basic bitmap with no draw pixels
- for (; height > 0; height -= zoom_amount){
- uint8* next_source_pointer = source_pointer + (uint32)(source_image->width * zoom_amount);
- uint8* next_dest_pointer = dest_pointer + (dest_dpi->width / zoom_amount) + dest_dpi->pitch;
-
- for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_amount, dest_pointer++, source_pointer += zoom_amount){
- uint8 pixel = *source_pointer;
- if (pixel){
- *dest_pointer = pixel;
- }
- }
- dest_pointer = next_dest_pointer;
- source_pointer = next_source_pointer;
- }
- return;
-}
-
-
-/*
-* rct2: 0x67AA18 transfers readied images onto buffers
-* This function copies the sprite data onto the screen
-*/
-void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_pointer, uint8* palette_pointer, rct_drawpixelinfo *dpi, int image_type, int source_y_start, int height, int source_x_start, int width){
- int zoom_level = dpi->zoom_level;
- int zoom_amount = 1 << 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_amount){
-
- //The first part of the source pointer is a list of offsets to different lines
- //This will move the pointer to the correct source line.
- next_source_pointer = source_bits_pointer + ((uint16*)source_bits_pointer)[y];
-
- uint8 last_data_line = 0;
-
- //For every data section in the line
- while (!last_data_line){
- uint8* source_pointer = next_source_pointer;
- uint8* dest_pointer = next_dest_pointer;
-
- int no_pixels = *source_pointer++;
- //gap_size is the number of non drawn pixels you require to
- //jump over on your destination
- uint8 gap_size = *source_pointer++;
- //The last bit in no_pixels tells you if you have reached the end of a line
- last_data_line = no_pixels & 0x80;
- //Clear the last data line bit so we have just the no_pixels
- no_pixels &= 0x7f;
- //Have our next source pointer point to the next data section
- next_source_pointer = source_pointer + no_pixels;
-
- //Calculates the start point of the image
- int x_start = gap_size - source_x_start;
-
- if (x_start > 0){
- //Since the start is positive
- //We need to move the drawing surface to the correct position
- dest_pointer += x_start / zoom_amount;
- }
- else{
- //If the start is negative we require to remove part of the image.
- //This is done by moving the image pointer to the correct position.
- source_pointer -= x_start;
- //The no_pixels will be reduced in this operation
- no_pixels += x_start;
- //If there are no pixels there is nothing to draw this data section
- if (no_pixels <= 0) continue;
- //Reset the start position to zero as we have taken into account all moves
- x_start = 0;
- }
-
- int x_end = x_start + no_pixels;
- //If the end position is further out than the whole image
- //end position then we need to shorten the line again
- if (x_end > width){
- //Shorten the line
- no_pixels -= x_end - width;
- //If there are no pixels there is nothing to draw.
- if (no_pixels <= 0) continue;
- }
-
- //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_amount, source_pointer += zoom_amount, dest_pointer++){
- uint8 al = *source_pointer;
- uint8 ah = *dest_pointer;
- if (image_type & IMAGE_TYPE_MIX_BACKGROUND)
- al = palette_pointer[(((uint16)al << 8) | ah) - 0x100];
- else
- al = palette_pointer[al];
- *dest_pointer = al;
- }
- }
- else if (image_type & IMAGE_TYPE_MIX_BACKGROUND){//In the .exe these are all unraveled loops
- //Doesnt use source pointer ??? mix with background only?
- //Not Tested
-
- for (; no_pixels > 0; no_pixels -= zoom_amount, dest_pointer++){
- uint8 pixel = *dest_pointer;
- pixel = palette_pointer[pixel];
- *dest_pointer = pixel;
- }
- }
- else
- {
- for (; no_pixels > 0; no_pixels -= zoom_amount, source_pointer += zoom_amount, dest_pointer++){
- *dest_pointer = *source_pointer;
- }
- }
- }
-
- //Add a line to the drawing surface pointer
- next_dest_pointer += dpi->width / zoom_amount + dpi->pitch;
- }
-}
-
-/**
- *
- * rct2: 0x0067A28E
- * image_id (ebx)
- * image_id as below
- * 0b_111X_XXXX_XXXX_XXXX_XXXX_XXXX_XXXX_XXXX image_type
- * 0b_XXX1_11XX_XXXX_XXXX_XXXX_XXXX_XXXX_XXXX image_sub_type (unknown pointer)
- * 0b_XXX1_1111_XXXX_XXXX_XXXX_XXXX_XXXX_XXXX secondary_colour
- * 0b_XXXX_XXXX_1111_1XXX_XXXX_XXXX_XXXX_XXXX primary_colour
- * 0b_XXXX_X111_1111_1XXX_XXXX_XXXX_XXXX_XXXX palette_ref
- * 0b_XXXX_XXXX_XXXX_X111_1111_1111_1111_1111 image_id (offset to g1)
- * x (cx)
- * y (dx)
- * dpi (esi)
- * tertiary_colour (ebp)
- */
-void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32 tertiary_colour)
-{
- //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, (int)dpi, tertiary_colour);
- //return;
-
- int image_type = (image_id & 0xE0000000) >> 28;
- int image_sub_type = (image_id & 0x1C000000) >> 26;
-
- uint8* palette_pointer = NULL;
- uint8 palette[0x100];
-
- RCT2_GLOBAL(0x00EDF81C, uint32) = image_id & 0xE0000000;
-
- uint8* unknown_pointer = (uint8*)(RCT2_ADDRESS(0x9E3CE4, uint32*)[image_sub_type]);
- RCT2_GLOBAL(0x009E3CDC, uint32) = (uint32)unknown_pointer;
-
- if (image_type && !(image_type & IMAGE_TYPE_UNKNOWN)) {
- uint8 palette_ref = (image_id >> 19) & 0xFF;
- if (image_type & IMAGE_TYPE_MIX_BACKGROUND){
- unknown_pointer = NULL;
- RCT2_GLOBAL(0x009E3CDC, uint32) = 0;
- }
- else{
- palette_ref &= 0x7F;
- }
-
- uint16 palette_offset = palette_to_g1_offset[palette_ref];
- palette_pointer = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[palette_offset].offset;
- RCT2_GLOBAL(0x9ABDA4, uint32) = (uint32)palette_pointer;
- }
- else if (image_type && !(image_type & IMAGE_TYPE_USE_PALETTE)){
- RCT2_GLOBAL(0x9E3CDC, uint32) = 0;
- unknown_pointer = NULL;
-
- uint32 primary_offset = palette_to_g1_offset[(image_id >> 19) & 0x1F];
- uint32 secondary_offset = palette_to_g1_offset[(image_id >> 24) & 0x1F];
- uint32 tertiary_offset = palette_to_g1_offset[tertiary_colour];
-
- rct_g1_element* primary_colour = &RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[primary_offset];
- rct_g1_element* secondary_colour = &RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[secondary_offset];
- rct_g1_element* tertiary_colour = &RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[tertiary_offset];
-
- memcpy((uint8*)0x9ABFFF, &primary_colour->offset[0xF3], 12);
- memcpy((uint8*)0x9ABFD6, &secondary_colour->offset[0xF3], 12);
- memcpy((uint8*)0x9ABF3A, &tertiary_colour->offset[0xF3], 12);
-
- //image_id
- RCT2_GLOBAL(0xEDF81C, uint32) |= 0x20000000;
- image_id |= IMAGE_TYPE_USE_PALETTE << 28;
-
- RCT2_GLOBAL(0x9ABDA4, uint32) = 0x9ABF0C;
- palette_pointer = (uint8*)0x9ABF0C;
- }
- else if (image_type){
- RCT2_GLOBAL(0x9E3CDC, uint32) = 0;
- unknown_pointer = NULL;
- //Copy the peep palette into a new palette.
- //Not really required but its nice to make a copy
- memcpy(palette, peep_palette, 0x100);
-
- //Top
- int top_type = (image_id >> 19) & 0x1f;
- 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 = 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);
-
- //For backwards compatibility until the zooming function is done
- RCT2_GLOBAL(0x9ABDA4, uint8*) = palette;
- palette_pointer = palette;
- }
- gfx_draw_sprite_palette_set(dpi, image_id, x, y, palette_pointer, unknown_pointer);
-}
-
-/*
-* 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(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;
- //}
- 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->pitch,
- .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;
- }
-
- if ( dpi->zoom_level && (g1_source->flags & (1<<5)) ){
- return;
- }
-
- //Its used super often so we will define it to a seperate variable.
- int zoom_level = dpi->zoom_level;
- int zoom_amount = 1 << zoom_level;
- int zoom_mask = 0xFFFFFFFF << zoom_level;
-
- //This will be the height of the drawn image
- int height = g1_source->height;
- //This is the start y coordinate on the destination
- sint16 dest_start_y = ((y + g1_source->y_offset)&zoom_mask) - dpi->y;
- //This is the start y coordinate on the source
- int source_start_y = 0;
-
- if (dest_start_y < 0){
- //If the destination y is negative reduce the height of the
- //image as we will cut off the bottom
- height += dest_start_y;
- //If the image is no longer visible nothing to draw
- if (height <= 0){
- return;
- }
- //The source image will start a further up the image
- source_start_y -= dest_start_y;
- //The destination start is now reset to 0
- dest_start_y = 0;
- }
-
- int dest_end_y = dest_start_y + height;
-
- if (dest_end_y > dpi->height){
- //If the destination y is outside of the drawing
- //image reduce the height of the image
- height -= dest_end_y - dpi->height;
- }
- //If the image no longer has anything to draw
- if (height <= 0)return;
-
- dest_start_y /= zoom_amount;
- dest_end_y /= zoom_amount;
-
- //This will be the width of the drawn image
- int width = g1_source->width;
- //This is the source start x coordinate
- int source_start_x = 0;
- //This is the destination start x coordinate
- sint16 dest_start_x = ((x + g1_source->x_offset) & zoom_mask) - dpi->x;
-
- if (dest_start_x < 0){
- //If the destination is negative reduce the width
- //image will cut off the side
- width += dest_start_x;
- //If there is no image to draw
- if (width <= 0){
- return;
- }
- //The source start will also need to cut off the side
- source_start_x -= dest_start_x;
- //Reset the destination to 0
- dest_start_x = 0;
- }
-
- int dest_end_x = dest_start_x + width;
-
- if (dest_end_x > dpi->width){
- //If the destination x is outside of the drawing area
- //reduce the image width.
- width -= dest_end_x - dpi->width;
- //If there is no image to draw.
- if (width <= 0)return;
- }
-
- dest_start_x /= zoom_amount;
- dest_end_x /= zoom_amount;
-
- uint8* dest_pointer = (uint8*)dpi->bits;
- //Move the pointer to the start point of the destination
- dest_pointer += ((dpi->width / zoom_amount) + dpi->pitch)*dest_start_y + dest_start_x;
-
- if (g1_source->flags & G1_FLAG_RLE_COMPRESSION){
- //We have to use a different method to move the source pointer for
- //rle encoded sprites so that will be handled within this function
- gfx_rle_sprite_to_buffer(g1_source->offset, dest_pointer, palette_pointer, dpi, image_type, source_start_y, height, source_start_x, width);
- return;
- }
- uint8* source_pointer = g1_source->offset;
- //Move the pointer to the start point of the source
- source_pointer += g1_source->width*source_start_y + source_start_x;
-
- if (!(g1_source->flags & 0x02)){
- gfx_bmp_sprite_to_buffer(palette_pointer, unknown_pointer, source_pointer, dest_pointer, g1_source, dpi, height, width, image_type);
- return;
- }
- //0x67A60A Not tested
- int total_no_pixels = g1_source->width*g1_source->height;
- source_pointer = g1_source->offset;
- uint8* new_source_pointer_start = malloc(total_no_pixels);
- uint8* new_source_pointer = new_source_pointer_start;// 0x9E3D28;
- int ebx, ecx;
- while (total_no_pixels>0){
- sint8 no_pixels = *source_pointer;
- if (no_pixels >= 0){
- source_pointer++;
- total_no_pixels -= no_pixels;
- memcpy((char*)new_source_pointer, (char*)source_pointer, no_pixels);
- new_source_pointer += no_pixels;
- source_pointer += no_pixels;
- continue;
- }
- ecx = no_pixels;
- no_pixels &= 0x7;
- ecx >>= 3;//SAR
- int eax = ((int)no_pixels)<<8;
- ecx = -ecx;//Odd
- eax = eax & 0xFF00 + *(source_pointer+1);
- total_no_pixels -= ecx;
- source_pointer += 2;
- ebx = (uint32)new_source_pointer - eax;
- eax = (uint32)source_pointer;
- source_pointer = (uint8*)ebx;
- ebx = eax;
- eax = 0;
- memcpy((char*)new_source_pointer, (char*)source_pointer, ecx);
- new_source_pointer += ecx;
- source_pointer += ecx;
- source_pointer = (uint8*)ebx;
- }
- source_pointer = new_source_pointer_start + g1_source->width*source_start_y + source_start_x;
- gfx_bmp_sprite_to_buffer(palette_pointer, unknown_pointer, source_pointer, dest_pointer, g1_source, dpi, height, width, image_type);
- free(new_source_pointer_start);
- return;
-}
-
-/**
- *
- * rct2: 0x00683854
- * a1 (ebx)
- * product (cl)
- */
-void gfx_transpose_palette(int pal, unsigned char product)
-{
- 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;
-
- 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);//Odd would have expected dest_pointer
-}
-/**
- * Draws i formatted text string centred at i specified position.
- * rct2: 0x006C1D6C
- * dpi (edi)
- * format (bx)
- * x (cx)
- * y (dx)
- * colour (al)
- * args (esi)
- */
-void gfx_draw_string_centred(rct_drawpixelinfo *dpi, int format, int x, int y, int colour, void *args)
-{
- char* buffer;
- short text_width;
-
- buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char);
- format_string(buffer, format, args);
-
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0;
-
- // Measure text width
- text_width = gfx_get_string_width(buffer);
-
- // Draw the text centred
- if (text_width <= 0xFFFF) {
- x -= text_width / 2;
- gfx_draw_string(dpi, buffer, colour, x, y);
- }
-}
-
-/**
- *
- * rct2: 0x006ED7E5
- */
-void gfx_invalidate_screen()
-{
- int width = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16);
- int height = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16);
- gfx_set_dirty_blocks(0, 0, width, height);
-}
-
-/**
- *
- * rct2: 0x006E732D
- * left (ax)
- * top (bx)
- * right (dx)
- * bottom (bp)
- */
-void gfx_set_dirty_blocks(int left, int top, int right, int bottom)
-{
- int x, y;
- uint8 *screenDirtyBlocks = RCT2_ADDRESS(0x00EDE408, uint8);
-
- left = max(left, 0);
- top = max(top, 0);
- right = min(right, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16));
- bottom = min(bottom, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16));
-
- if (left >= right)
- return;
- if (top >= bottom)
- return;
-
- right--;
- bottom--;
-
- left >>= RCT2_GLOBAL(0x009ABDF0, sint8);
- right >>= RCT2_GLOBAL(0x009ABDF0, sint8);
- top >>= RCT2_GLOBAL(0x009ABDF1, sint8);
- bottom >>= RCT2_GLOBAL(0x009ABDF1, sint8);
-
- for (y = top; y <= bottom; y++)
- for (x = left; x <= right; x++)
- screenDirtyBlocks[y * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32) + x] = 0xFF;
-}
-
-/**
- *
- * rct2: 0x006E73BE
- */
-void gfx_draw_all_dirty_blocks()
-{
- int x, y, xx, yy, columns, rows;
- uint8 *screenDirtyBlocks = RCT2_ADDRESS(0x00EDE408, uint8);
-
- for (x = 0; x < RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32); x++) {
- for (y = 0; y < RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_ROWS, sint32); y++) {
- if (screenDirtyBlocks[y * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32) + x] == 0)
- continue;
-
- // Determine columns
- for (xx = x; xx < RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32); xx++)
- if (screenDirtyBlocks[y * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32) + xx] == 0)
- break;
- columns = xx - x;
-
- // Check rows
- for (yy = y; yy < RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_ROWS, sint32); yy++)
- for (xx = x; xx < x + columns; xx++)
- if (screenDirtyBlocks[yy * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32) + xx] == 0)
- goto endRowCheck;
-
- endRowCheck:
- rows = yy - y;
- gfx_draw_dirty_blocks(x, y, columns, rows);
- }
- }
-}
-
-static void gfx_draw_dirty_blocks(int x, int y, int columns, int rows)
-{
- int left, top, right, bottom;
- uint8 *screenDirtyBlocks = RCT2_ADDRESS(0x00EDE408, uint8);
-
- // Unset dirty blocks
- for (top = y; top < y + rows; top++)
- for (left = x; left < x + columns; left++)
- screenDirtyBlocks[top * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32) + left] = 0;
-
- // Determine region in pixels
- left = max(0, x * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_WIDTH, sint16));
- top = max(0, y * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_HEIGHT, sint16));
- right = min(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16), left + (columns * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_WIDTH, sint16)));
- bottom = min(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16), top + (rows * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_HEIGHT, sint16)));
- if (right <= left || bottom <= top)
- return;
-
- // Draw region
- gfx_redraw_screen_rect(left, top, right, bottom);
-}
-
-/**
- *
- * rct2: 0x006E7499
- * left (ax)
- * top (bx)
- * right (dx)
- * bottom (bp)
- */
-void gfx_redraw_screen_rect(short left, short top, short right, short bottom)
-{
- rct_window* w;
- rct_drawpixelinfo *screenDPI = RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo);
- rct_drawpixelinfo *windowDPI = RCT2_ADDRESS(RCT2_ADDRESS_WINDOW_DPI, rct_drawpixelinfo);
-
- // Unsure what this does
- RCT2_CALLPROC_X(0x00683326, left, top, right - 1, bottom - 1, 0, 0, 0);
-
- windowDPI->bits = screenDPI->bits + left + ((screenDPI->width + screenDPI->pitch) * top);
- windowDPI->x = left;
- windowDPI->y = top;
- windowDPI->width = right - left;
- windowDPI->height = bottom - top;
- windowDPI->pitch = screenDPI->width + screenDPI->pitch + left - right;
-
- for (w = g_window_list; w < RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*); w++) {
- if (w->flags & WF_TRANSPARENT)
- continue;
- if (right <= w->x || bottom <= w->y)
- continue;
- if (left >= w->x + w->width || top >= w->y + w->height)
- continue;
- window_draw(w, left, top, right, bottom);
- }
-}
-
-/**
- * Return the width of the string in buffer
- *
- * rct2: 0x006C2321
- * buffer (esi)
- */
-int gfx_get_string_width(char* buffer)
-{
- // Current font sprites
- uint16* current_font_sprite_base;
- // Width of string
- int width;
- rct_g1_element g1_element;
-
- current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16);
- width = 0;
-
- for (uint8* curr_char = (uint8*)buffer; *curr_char != (uint8)0; curr_char++) {
-
- if (*curr_char >= 0x20) {
- width += RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8)[*current_font_sprite_base + (*curr_char - 0x20)];
- continue;
- }
- switch(*curr_char) {
- case FORMAT_MOVE_X:
- curr_char++;
- width = *curr_char;
- break;
- case FORMAT_ADJUST_PALETTE:
- case 3:
- case 4:
- curr_char++;
- break;
- case FORMAT_NEWLINE:
- case FORMAT_NEWLINE_SMALLER:
- continue;
- 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 = 0x0E0;
- break;
- case FORMAT_SMALLFONT:
- *current_font_sprite_base = 0;
- break;
- 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 <= 0x16) { //case 0x11? FORMAT_NEW_LINE_X_Y
- curr_char += 2;
- continue;
- }
- curr_char += 4;//never happens?
- break;
- }
- }
- return width;
-}
-
-/**
- * Clip the text in buffer to width, add ellipsis and return the new width of the clipped string
- *
- * rct2: 0x006C2460
- * buffer (esi)
- * width (edi)
- */
-int gfx_clip_string(char* buffer, int width)
-{
- // Location of font sprites
- uint16 current_font_sprite_base;
- // Width the string has to fit into
- unsigned int max_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;
- }
-
- current_font_sprite_base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16);
- max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[current_font_sprite_base]);
-
- clipped_width = 0;
- last_char = buffer;
-
- for (unsigned char* curr_char = buffer; *curr_char != (uint8)0; curr_char++) {
- if (*curr_char < 0x20) {
- switch (*curr_char) {
- case FORMAT_MOVE_X:
- curr_char++;
- clipped_width = *curr_char;
- continue;
- case FORMAT_ADJUST_PALETTE:
- case 3:
- case 4:
- curr_char++;
- continue;
- case FORMAT_NEWLINE:
- case FORMAT_NEWLINE_SMALLER:
- continue;
- 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 = 0x0E0;
- break;
- case FORMAT_SMALLFONT:
- current_font_sprite_base = 0;
- break;
- 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 <= 0x16) { //case 0x11? FORMAT_NEW_LINE_X_Y
- curr_char += 2;
- continue;
- }
- curr_char += 4;//never happens?
- continue;
- }
- max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[current_font_sprite_base]);
- }
-
- clipped_width += RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8)[current_font_sprite_base + (*curr_char - 0x20)];
-
- if ((int)clipped_width > width) {
-// *((uint32*)last_char) = '...';
- strcpy(last_char-3, "...");
- clipped_width = width;
- return clipped_width;
- }
- if (clipped_width <= max_width) {
- last_char = curr_char+1;
- }
- }
- return clipped_width;
-}
-
-
-/**
- * Wrap the text in buffer to width, returns width of longest line.
- *
- * Inserts NULL where line should break (as \n is used for something else),
- * so the number of lines is returned in num_lines. font_height seems to be
- * a control character for line height.
- *
- * rct2: 0x006C21E2
- * buffer (esi)
- * width (edi) - in
- * num_lines (edi) - out
- * font_height (ebx) - out
- */
-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;
-
- *num_lines = 0;
- *font_height = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16);
-
- // Pointer to the start of the current word
- unsigned char* curr_word = NULL;
- // Width of line up to current word
- unsigned int curr_width;
-
- for (unsigned char* curr_char = buffer; *curr_char != (uint8)0; curr_char++) {
-
- // Remember start of current word and line width up to this word
- if (*curr_char == ' ') {
- curr_word = curr_char;
- curr_width = line_width;
- }
-
- // 5 is RCT2 new line?
- if (*curr_char != 5) {
- if (*curr_char < ' ') {
- switch(*curr_char) {
- case FORMAT_MOVE_X:
- case FORMAT_ADJUST_PALETTE:
- case 3:
- case 4:
- curr_char++;
- continue;
- case FORMAT_NEWLINE:
- case FORMAT_NEWLINE_SMALLER:
- continue;
- case FORMAT_TINYFONT:
- *font_height = 0x1C0;
- continue;
- case FORMAT_BIGFONT:
- *font_height = 0x2A0;
- continue;
- case FORMAT_MEDIUMFONT:
- *font_height = 0xE0;
- continue;
- case FORMAT_SMALLFONT:
- *font_height = 0;
- continue;
- 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 <= 0x16) {
- curr_char += 2;
- continue;
- }
- curr_char += 4;
- continue;
- }
- }
-
- line_width += RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8)[*font_height + (*curr_char - 0x20)];
-
- if ((int)line_width <= width) {
- continue;
- }
- if (curr_word == 0) {
- curr_char--;
- unsigned char* old_char = curr_char;
- unsigned char swap_char = 0;
- unsigned char temp;
- // Insert NULL at current character
- // Aboslutely no guarantee that this won't overrun!
- do {
- temp = swap_char;
- swap_char = *curr_char;
- *curr_char = temp;
- curr_char++;
- } while(swap_char != 0);
-
- *curr_char = swap_char;
- curr_char = old_char;
- curr_char++;
- *num_lines += 1;
-
- if (line_width > max_width) {
- max_width = line_width;
- }
- line_width = 0;
- curr_word = 0;
- continue;
- }
- curr_char = curr_word;
- line_width = curr_width;
- }
-
- *num_lines += 1;
- *curr_char = 0;
-
- if (line_width > max_width) {
- max_width = line_width;
- }
- line_width = 0;
- curr_word = 0;
- }
- if (max_width == 0)return line_width;
- return max_width;
-}
-
-
-/**
- * Draws i formatted text string left aligned at i specified position but clips
- * the text with an elipsis if the text width exceeds the specified width.
- * rct2: 0x006C1B83
- * dpi (edi)
- * format (bx)
- * args (esi)
- * colour (al)
- * x (cx)
- * y (dx)
- * width (bp)
- */
-void gfx_draw_string_left_clipped(rct_drawpixelinfo* dpi, int format, void* args, int colour, int x, int y, int width)
-{
- char* buffer;
-
- buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char);
- format_string(buffer, format, args);
-
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0;
-
- // Clip text - return value is not needed
- gfx_clip_string(buffer, width);
-
- gfx_draw_string(dpi, buffer, colour, x, y);
-}
-
-/**
- * Draws i formatted text string centred at i specified position but clips the
- * text with an elipsis if the text width exceeds the specified width.
- * rct2: 0x006C1BBA
- * dpi (edi)
- * format (bx)
- * args (esi)
- * colour (al)
- * x (cx)
- * y (dx)
- * width (bp)
- */
-void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y, int width)
-{
- char* buffer;
- short text_width;
-
- buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char);
- format_string(buffer, format, args);
-
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0;
-
- // Clip text
- text_width = gfx_clip_string(buffer, width);
-
- // Draw the text centred
- if (text_width <= 0xFFFF) {
- x -= (text_width - 1) / 2;
- gfx_draw_string(dpi, buffer, colour, x, y);
- }
-}
-
-/**
- * Draws i formatted text string right aligned.
- * rct2: 0x006C1BFC
- * dpi (edi)
- * format (bx)
- * args (esi)
- * colour (al)
- * x (cx)
- * y (dx)
- */
-void gfx_draw_string_right(rct_drawpixelinfo* dpi, int format, void* args, int colour, int x, int y)
-{
- char* buffer;
- short text_width;
-
- buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char);
- format_string(buffer, format, args);
-
- // Measure text width
- text_width = gfx_get_string_width(buffer);
-
- // Draw the text right aligned
- x -= text_width;
- gfx_draw_string(dpi, buffer, colour, x, y);
-}
-
-/**
- *
- * rct2: 0x006C1E53
- * dpi (edi)
- * args (esi)
- * x (cx)
- * y (dx)
- * width (bp)
- * colour (al)
- * format (ebx)
- */
-int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour)
-{
- int font_height, line_height, line_width, line_y, num_lines;
- // Location of font sprites
- uint16* current_font_sprite_base;
-
- char* buffer = RCT2_ADDRESS(0x009C383D, char);
-
- current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16);
- *current_font_sprite_base = 0xE0;
-
- gfx_draw_string(dpi, buffer, colour, dpi->x, dpi->y);
-
- buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char);
-
- format_string(buffer, format, args);
-
- *current_font_sprite_base = 0xE0;
-
- // line_width unused here
- line_width = gfx_wrap_string(buffer, width, &num_lines, &font_height);
-
- line_height = 0x0A;
-
- if (font_height > 0xE0) {
- line_height = 6;
- if (font_height != 0x1C0) {
- line_height = 0x12;
- }
- }
-
- if (*buffer == 0x0B) {
- line_height = line_height + 1;
- }
-
- font_height = (line_height / 2) * num_lines;
- line_y = y - font_height;
-
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16) = 0;
-
- for (int line = 0; line <= num_lines; ++line) {
- int half_width = gfx_get_string_width(buffer) / 2;
- gfx_draw_string(dpi, buffer, 0xFE, x - half_width, line_y);
-
- buffer += get_string_length(buffer) + 1;
- line_y += line_height;
- }
-
- return line_y - y;
-}
-
-/**
- *
- * rct2: 0x006C2105
- * dpi (edi)
- * args (esi)
- * x (cx)
- * y (dx)
- * width (bp)
- * format (bx)
- * colour (al)
- */
-int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour)
-{
- // font height might actually be something else
- int font_height, line_height, line_width, line_y, num_lines;
-
- // Location of font sprites
- uint16* current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16);
- *current_font_sprite_base = 0xE0;
-
- char* buffer = RCT2_ADDRESS(0x009C383D, char);
-
- gfx_draw_string(dpi, buffer, colour, dpi->x, dpi->y);
-
- buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char);
-
- format_string(buffer, format, args);
-
- *current_font_sprite_base = 0xE0;
-
- // Line width unused here
- line_width = gfx_wrap_string(buffer, width, &num_lines, &font_height);
-
- line_height = 0x0A;
-
- if (font_height > 0xE0) {
- line_height = 6;
- if (font_height != 0x1C0) {
- line_height = 0x12;
- }
- }
-
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16) = 0;
-
- line_y = y;
-
- for (int line = 0; line <= num_lines; ++line) {
- gfx_draw_string(dpi, buffer, 0xFE, x, line_y);
- buffer += get_string_length(buffer) + 1;
- line_y += line_height;
- }
-
- return line_y - y;
-}
-
-/**
- * Draws i formatted text string.
- * rct2: 0x006C1B2F
- * dpi (edi)
- * format (bx)
- * args (esi)
- * colour (al)
- * x (cx)
- * y (dx)
- */
-void gfx_draw_string_left(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y)
-{
- char* buffer;
-
- buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char);
- format_string(buffer, format, args);
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0;
- gfx_draw_string(dpi, buffer, colour, x, y);
-}
-
-/* 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)[colour & 0xFF];
-
- if (!(*current_font_flags & 2)) {
- eax = eax & 0x0FF0000FF;
- }
- // Adjust text palette. Store current colour?
- 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;
-}
-
-/* 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;
-
- eax = RCT2_ADDRESS(0x0141FD45, uint8)[colour * 8];
- if (*current_font_flags & 2) {
- eax |= 0x0A0A00;
- }
- //Adjust text palette. Store current colour?
- 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;
-}
-
-
-/**
- *
- * rct2: 0x00682702
- * dpi (edi)
- * buffer (esi)
- * colour (al)
- * x (cx)
- * y (dx)
- */
-void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, int y)
-{
-
- int eax, ebx, ebp;
- rct_g1_element* g1_element;
-
- // Maximum length/height of string
- int max_x = x;
- int max_y = 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;
-
- if (colour != 0xFE) {
-
- if (x >= dpi->x + dpi->width)
- return;
-
- if (x + 0x280 <= dpi->x)
- return;
-
- if (y >= dpi->y + dpi->height)
- return;
-
- if (y + 0x5A <= dpi->y) {
- return;
- }
-
- if (colour != 0xFF) {
-
- // switch_colour:
- *current_font_flags = 0;
- if (*current_font_sprite_base < 0) {
- *current_font_flags |= 4;
- if (*current_font_sprite_base != 0xFFFF) {
- *current_font_flags |= 8;
- }
- *current_font_sprite_base = 0xE0;
- }
- if (colour & (1 << 5)) {
- *current_font_flags |= 2;
- }
- colour &= ~(1 << 5);
-
- if (!(colour & 0x40)) {
- ebp = colour;
- if (*current_font_flags & 1) {
- if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) {
- skip_char = 1;
- } else {
- skip_char = 0;
- }
- } else {
- colour_char_window(ebp, current_font_flags, palette_pointer);
- }
- } else {
- *current_font_flags |= 1;
- colour &= 0x1F;
-
- if (*current_font_flags & 4) {
- if (*current_font_flags & 8) {
- eax = RCT2_ADDRESS(0x0141FC48, uint8)[colour * 8];
- eax = eax << 16;
- eax = eax | RCT2_ADDRESS(0x0141FC46, uint8)[colour * 8];
- } else {
- eax = RCT2_ADDRESS(0x0141FC49, uint8)[colour * 8];
- eax = eax << 16;
- eax = eax | RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8];
- }
- } else {
- eax = RCT2_ADDRESS(0x0141FC4A, uint8)[colour * 8];
- eax = eax << 16;
- eax = eax | RCT2_ADDRESS(0x0141FC48, uint8)[colour * 8];
- }
- // Adjust text palette. Store current colour? ;
- 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;
- }
- }
- }
-
- if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) {
- skip_char = 1;
- }
-
- for (uint8 al = *buffer; al > 0; ++buffer, al = *buffer) {
-
- // Skip to the next printing character
- if (skip_char) {
- if (al < 0x20) {
- // Control codes
- skip_char = 0;
- } else if (al >= FORMAT_COLOUR_CODE_START && al <= FORMAT_COLOUR_CODE_END) {
- // Colour codes
- if (*current_font_flags == 1) {
- if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) {
- skip_char = 1;
- } else {
- skip_char = 0;
- }
- continue;
- }
- colour_char(al - FORMAT_COLOUR_CODE_START, current_font_flags, palette_pointer);
- continue;
- } else {
- continue;
- }
- }
-
- // Control codes
- switch (al) {
- case FORMAT_MOVE_X://Start New Line at start+buffer x, same y. (Overwrite?)
- max_x = x + (uint8)*++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;
- break;
- }
- }
-
- 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;
- }
-
- 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;
-
-
- 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;
- }
- 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 = *((uint16*)(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, 0);
-
- 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;
- }
- 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;
- }
- }
-
- gLastDrawStringX = max_x;
- gLastDrawStringY = max_y;
-}
-
-/*
-*
-* rct2: 0x006EE53B
-* left (ax)
-* width (bx)
-* top (cx)
-* height (dx)
-* drawpixelinfo (edi)
-*/
-rct_drawpixelinfo* clip_drawpixelinfo(rct_drawpixelinfo* dpi, int left, int width, int top, int height)
-{
- rct_drawpixelinfo* newDrawPixelInfo = rct2_malloc(sizeof(rct_drawpixelinfo));
-
- int right = left + width;
- int bottom = top + height;
-
- newDrawPixelInfo->bits = dpi->bits;
- newDrawPixelInfo->x = dpi->x;
- newDrawPixelInfo->y = dpi->y;
- newDrawPixelInfo->width = dpi->width;
- newDrawPixelInfo->height = dpi->height;
- newDrawPixelInfo->pitch = dpi->pitch;
- newDrawPixelInfo->zoom_level = 0;
-
- if (left > newDrawPixelInfo->x) {
- uint16 clippedFromLeft = left - newDrawPixelInfo->x;
- newDrawPixelInfo->width -= clippedFromLeft;
- newDrawPixelInfo->x = left;
- newDrawPixelInfo->pitch += clippedFromLeft;
- newDrawPixelInfo->bits += clippedFromLeft;
- }
-
- int stickOutWidth = newDrawPixelInfo->x + newDrawPixelInfo->width - right;
- if (stickOutWidth > 0) {
- newDrawPixelInfo->width -= stickOutWidth;
- newDrawPixelInfo->pitch += stickOutWidth;
- }
-
- if (top > newDrawPixelInfo->y) {
- uint16 clippedFromTop = top - newDrawPixelInfo->y;
- newDrawPixelInfo->height -= clippedFromTop;
- newDrawPixelInfo->y = top;
- uint32 bitsPlus = (newDrawPixelInfo->pitch + newDrawPixelInfo->width) * clippedFromTop;
- newDrawPixelInfo->bits += bitsPlus;
- }
-
- int bp = newDrawPixelInfo->y + newDrawPixelInfo->height - bottom;
- if (bp > 0) {
- newDrawPixelInfo->height -= bp;
- }
-
- if (newDrawPixelInfo->width > 0 && newDrawPixelInfo->height > 0) {
- newDrawPixelInfo->x -= left;
- newDrawPixelInfo->y -= top;
-
- return newDrawPixelInfo;
- }
-
- rct2_free(newDrawPixelInfo);
- return NULL;
-}
-
-/***
-*
-* rct2: 0x00684027
-*
-* ebp used to be a parameter but it is always zero
-* left : eax
-* top : ebx
-* width : ecx
-* height : edx
-* x_start: edi
-* y_start: esi
-*/
-void gfx_draw_rain(int left, int top, int width, int height, sint32 x_start, sint32 y_start){
- uint8* pattern = RCT2_GLOBAL(RCT2_ADDRESS_RAIN_PATTERN, uint8*);
- uint8 pattern_x_space = *pattern++;
- uint8 pattern_y_space = *pattern++;
-
- uint8 pattern_start_x_offset = x_start % pattern_x_space;
- uint8 pattern_start_y_offset = y_start % pattern_y_space;;
-
- rct_drawpixelinfo* dpi = RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo);
- uint32 pixel_offset = (dpi->pitch + dpi->width)*top + left;
- uint8 pattern_y_pos = pattern_start_y_offset;
-
- //Stores the colours of changed pixels
- uint32* pixel_store = RCT2_ADDRESS(RCT2_ADDRESS_RAIN_PIXEL_STORE, uint32);
- pixel_store += RCT2_GLOBAL(RCT2_ADDRESS_NO_RAIN_PIXELS, uint32);
-
- for (; height != 0; height--){
- uint8 pattern_x = pattern[pattern_y_pos * 2];
- if (pattern_x != 0xFF){
- if (RCT2_GLOBAL(0x9AC00C, uint32) <= 0x1F38){
-
- int final_pixel_offset = width + pixel_offset;
-
- int x_pixel_offset = pixel_offset;
- x_pixel_offset += ((uint8)(pattern_x - pattern_start_x_offset)) % pattern_x_space;
-
- uint8 pattern_pixel = pattern[pattern_y_pos * 2 + 1];
- for (; x_pixel_offset < final_pixel_offset; x_pixel_offset += pattern_x_space){
- uint8 current_pixel = dpi->bits[x_pixel_offset];
- dpi->bits[x_pixel_offset] = pattern_pixel;
- RCT2_GLOBAL(RCT2_ADDRESS_NO_RAIN_PIXELS, uint32)++;
-
- //Store colour and position
- *pixel_store++ = (x_pixel_offset << 8) | current_pixel;
- }
- }
- }
-
- pixel_offset += dpi->pitch + dpi->width;
-
- pattern_y_pos++;
- pattern_y_pos %= pattern_y_space;
- }
-}
-
-void draw_string_left_underline(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y)
-{
- char buffer[128];
- int width;
-
- format_string(buffer, format, args);
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 224;
- width = gfx_get_string_width(buffer);
- gfx_draw_string(dpi, buffer, colour, x, y);
- gfx_fill_rect(dpi, x, y + 11, x + width, y + 11, text_palette[1]);
- if (text_palette[2] != 0)
- gfx_fill_rect(dpi, x + 1, y + 12, x + width + 1, y + 12, text_palette[2]);
-}
-
-void draw_string_right_underline(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y)
-{
- char buffer[128];
- int width;
-
- format_string(buffer, format, args);
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 224;
- width = gfx_get_string_width(buffer);
- x -= width;
- gfx_draw_string(dpi, buffer, colour, x, y);
- gfx_fill_rect(dpi, x, y + 11, x + width, y + 11, text_palette[1]);
- if (text_palette[2] != 0)
- gfx_fill_rect(dpi, x + 1, y + 12, x + width + 1, y + 12, text_palette[2]);
-}
-
-void draw_string_centred_underline(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y)
-{
- char buffer[128];
- int width;
-
- format_string(buffer, format, args);
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 224;
- width = gfx_get_string_width(buffer);
- x -= width / 2;
- gfx_draw_string(dpi, buffer, colour, x, y);
- gfx_fill_rect(dpi, x, y + 11, x + width, y + 11, text_palette[1]);
- if (text_palette[2] != 0)
- gfx_fill_rect(dpi, x + 1, y + 12, x + width + 1, y + 12, text_palette[2]);
-}
-
-/**
- *
- * rct2: 0x006C1DB7
- *
- * left : cx
- * top : dx
- * numLines : bp
- * text : esi
- * dpi : edi
- */
-void draw_string_centred_raw(rct_drawpixelinfo *dpi, int x, int y, int numLines, char *text)
-{
- RCT2_CALLPROC_X(0x006C1DB7, 0, 0, x, y, (int)text, (int)dpi, numLines);
-}
\ No newline at end of file
diff --git a/src/drawing/line.c b/src/drawing/line.c
new file mode 100644
index 0000000000..28bfbe7db6
--- /dev/null
+++ b/src/drawing/line.c
@@ -0,0 +1,150 @@
+/*****************************************************************************
+ * 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.
+ *
+ * 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 "drawing.h"
+
+/*
+ * Draws a horizontal line of specified colour to a buffer.
+ * rct2: 0x0068474C
+ */
+void gfx_draw_line_on_buffer(rct_drawpixelinfo *dpi, char colour, int y, int x, int no_pixels)
+{
+ y -= dpi->y;
+
+ //Check to make sure point is in the y range
+ if (y < 0)return;
+ if (y >= dpi->height)return;
+ //Check to make sure we are drawing at least a pixel
+ if (!no_pixels) no_pixels++;
+
+ x -= dpi->x;
+
+ //If x coord outside range leave
+ if (x < 0){
+ //Unless the number of pixels is enough to be in range
+ no_pixels += x;
+ if (no_pixels <= 0)return;
+ //Resets starting point to 0 as we don't draw outside the range
+ x = 0;
+ }
+
+ //Ensure that the end point of the line is within range
+ if (x + no_pixels - dpi->width > 0){
+ //If the end point has any pixels outside range
+ //cut them off. If there are now no pixels return.
+ no_pixels -= x + no_pixels - dpi->width;
+ if (no_pixels <= 0)return;
+ }
+
+ char* bits_pointer;
+ //Get the buffer we are drawing to and move to the first coordinate.
+ bits_pointer = dpi->bits + y*(dpi->pitch + dpi->width) + x;
+
+ //Draw the line to the specified colour
+ for (; no_pixels > 0; --no_pixels, ++bits_pointer){
+ *((uint8*)bits_pointer) = colour;
+ }
+}
+
+/**
+ * Draws a line on dpi if within dpi boundaries
+ * rct2: 0x00684466
+ * dpi (edi)
+ * x1 (ax)
+ * y1 (bx)
+ * x2 (cx)
+ * y2 (dx)
+ * colour (ebp)
+ */
+void gfx_draw_line(rct_drawpixelinfo *dpi, int x1, int y1, int x2, int y2, int colour)
+{
+ // Check to make sure the line is within the drawing area
+ if ((x1 < dpi->x) && (x2 < dpi->x)){
+ return;
+ }
+
+ if ((y1 < dpi->y) && (y2 < dpi->y)){
+ return;
+ }
+
+ if ((x1 >(dpi->x + dpi->width)) && (x2 >(dpi->x + dpi->width))){
+ return;
+ }
+
+ if ((y1 > (dpi->y + dpi->height)) && (y2 > (dpi->y + dpi->height))){
+ return;
+ }
+
+ //Bresenhams algorithm
+
+ //If vertical plot points upwards
+ int steep = abs(y2 - y1) > abs(x2 - x1);
+ if (steep){
+ int temp_y2 = y2;
+ int temp_x2 = x2;
+ y2 = x1;
+ x2 = y1;
+ y1 = temp_x2;
+ x1 = temp_y2;
+ }
+
+ //If line is right to left swap direction
+ if (x1 > x2){
+ int temp_y2 = y2;
+ int temp_x2 = x2;
+ y2 = y1;
+ x2 = x1;
+ y1 = temp_y2;
+ x1 = temp_x2;
+ }
+
+ int delta_x = x2 - x1;
+ int delta_y = abs(y2 - y1);
+ int error = delta_x / 2;
+ int y_step;
+ int y = y1;
+
+ //Direction of step
+ if (y1 < y2)y_step = 1;
+ else y_step = -1;
+
+ for (int x = x1, x_start = x1, no_pixels = 1; x < x2; ++x,++no_pixels){
+ //Vertical lines are drawn 1 pixel at a time
+ if (steep)gfx_draw_line_on_buffer(dpi, colour, x, y, 1);
+
+ error -= delta_y;
+ if (error < 0){
+ //Non vertical lines are drawn with as many pixels in a horizontal line as possible
+ if (!steep)gfx_draw_line_on_buffer(dpi, colour, y, x_start, no_pixels);
+
+ //Reset non vertical line vars
+ x_start = x + 1;
+ no_pixels = 1;
+ y += y_step;
+ error += delta_x;
+ }
+
+ //Catch the case of the last line
+ if (x + 1 == x2 && !steep){
+ gfx_draw_line_on_buffer(dpi, colour, y, x_start, no_pixels);
+ }
+ }
+ return;
+}
\ No newline at end of file
diff --git a/src/drawing/rect.c b/src/drawing/rect.c
new file mode 100644
index 0000000000..c23f881b56
--- /dev/null
+++ b/src/drawing/rect.c
@@ -0,0 +1,329 @@
+/*****************************************************************************
+ * 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.
+ *
+ * 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 "../common.h"
+#include "drawing.h"
+
+/**
+ *
+ * rct2: 0x00678AD4
+ * dpi (edi)
+ * left (ax)
+ * top (cx)
+ * right (bx)
+ * bottom (dx)
+ * colour (ebp)
+ */
+void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bottom, int colour)
+{
+ int left_, right_, top_, bottom_;
+ rct_drawpixelinfo* dpi_;
+ left_ = left;
+ right_ = right;
+ top_ = top;
+ bottom_ = bottom;
+ dpi_ = dpi;
+
+ if ((left > right) || (top > bottom) || (dpi->x > right) || (left >= (dpi->x + dpi->width)) ||
+ (bottom < dpi->y) || (top >= (dpi->y + dpi->height)))
+ return;
+
+ colour |= RCT2_GLOBAL(0x009ABD9C, uint32);
+
+ uint16 cross_pattern = 0;
+
+ int start_x = left - dpi->x;
+ if (start_x < 0){
+ start_x = 0;
+ cross_pattern ^= start_x;
+ }
+
+ 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;
+
+ uint32 ecx;
+ 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) | width;
+ // Fill every other pixel with the colour
+ for (; (ecx & 0xFFFF) > 0; ecx--) {
+ ecx = ecx ^ 0x80000000;
+ if ((int)ecx < 0) {
+ *dest_pointer = colour & 0xFF;
+ }
+ dest_pointer++;
+ }
+ 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);
+}
+
+/**
+ * Draw a rectangle, with optional border or fill
+ *
+ * rct2: 0x006E6F81
+ * dpi (edi)
+ * left (ax)
+ * top (cx)
+ * right (bx)
+ * bottom (dx)
+ * colour (ebp)
+ * flags (si)
+ */
+void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short right, short bottom, int colour, short flags)
+{
+ uint8 shadow, fill, hilight;
+
+ // Flags
+ int no_border, no_fill, pressed;
+
+ no_border = 8;
+ no_fill = 0x10;
+ pressed = 0x20;
+
+ if (colour & 0x180) {
+ if (colour & 0x100) {
+ colour = colour & 0x7F;
+ } else {
+ colour = RCT2_ADDRESS(0x009DEDF4,uint8)[colour];
+ }
+
+ colour = colour | 0x2000000; //Transparent
+
+ if (flags & no_border) {
+ gfx_fill_rect(dpi, left, top, bottom, right, colour);
+ } else if (flags & pressed) {
+ // Draw outline of box
+ gfx_fill_rect(dpi, left, top, left, bottom, colour + 1);
+ gfx_fill_rect(dpi, left, top, right, top, colour + 1);
+ gfx_fill_rect(dpi, right, top, right, bottom, colour + 2);
+ gfx_fill_rect(dpi, left, bottom, right, bottom, colour + 2);
+
+ if (!(flags & no_fill)) {
+ gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, colour);
+ }
+ } else {
+ // Draw outline of box
+ gfx_fill_rect(dpi, left, top, left, bottom, colour + 2);
+ gfx_fill_rect(dpi, left, top, right, top, colour + 2);
+ gfx_fill_rect(dpi, right, top, right, bottom, colour + 1);
+ gfx_fill_rect(dpi, left, bottom, right, bottom, colour + 1);
+
+ if (!(flags & no_fill)) {
+ gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, colour);
+ }
+ }
+ } else {
+ if (flags & 0x80) {
+ shadow = RCT2_ADDRESS(0x0141FC46, uint8)[colour * 8];
+ fill = RCT2_ADDRESS(0x0141FC48, uint8)[colour * 8];
+ hilight = RCT2_ADDRESS(0x0141FC4A, uint8)[colour * 8];
+ } else {
+ shadow = RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8];
+ fill = RCT2_ADDRESS(0x0141FC49, uint8)[colour * 8];
+ hilight = RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8];
+ }
+
+ if (flags & no_border) {
+ gfx_fill_rect(dpi, left, top, right, bottom, fill);
+ } else if (flags & pressed) {
+ // Draw outline of box
+ gfx_fill_rect(dpi, left, top, left, bottom, shadow);
+ gfx_fill_rect(dpi, left + 1, top, right, top, shadow);
+ gfx_fill_rect(dpi, right, top + 1, right, bottom - 1, hilight);
+ gfx_fill_rect(dpi, left + 1, bottom, right, bottom, hilight);
+
+ if (!(flags & no_fill)) {
+ if (!(flags & 0x40)) {
+ if (flags & 0x04) {
+ fill = RCT2_ADDRESS(0x0141FC49, uint8)[0];
+ } else {
+ fill = RCT2_ADDRESS(0x0141FC4A, uint8)[colour * 8];
+ }
+ }
+ gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, fill);
+ }
+ } else {
+ // Draw outline of box
+ gfx_fill_rect(dpi, left, top, left, bottom - 1, hilight);
+ gfx_fill_rect(dpi, left + 1, top, right - 1, top, hilight);
+ gfx_fill_rect(dpi, right, top, right, bottom - 1, shadow);
+ gfx_fill_rect(dpi, left, bottom, right, bottom, shadow);
+
+ if (!(flags & no_fill)) {
+ if (flags & 0x04) {
+ fill = RCT2_ADDRESS(0x0141FC49, uint8)[0];
+ }
+ gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, fill);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/drawing/sprite.c b/src/drawing/sprite.c
new file mode 100644
index 0000000000..eb39e79f61
--- /dev/null
+++ b/src/drawing/sprite.c
@@ -0,0 +1,399 @@
+/*****************************************************************************
+ * 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.
+ *
+ * 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 "../common.h"
+#include "drawing.h"
+
+typedef struct {
+ uint32 num_entries;
+ uint32 total_size;
+} rct_g1_header;
+
+void *_g1Buffer = NULL;
+
+/**
+ *
+ * rct2: 0x00678998
+ */
+int gfx_load_g1()
+{
+ FILE *file;
+ rct_g1_header header;
+ unsigned int i;
+
+ rct_g1_element *g1Elements = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element);
+
+ file = fopen(get_file_path(PATH_ID_G1), "rb");
+ if (file != NULL) {
+ if (fread(&header, 8, 1, file) == 1) {
+ // number of elements is stored in g1.dat, but because the entry headers are static, this can't be variable until
+ // made into a dynamic array
+ header.num_entries = 29294;
+
+ // Read element headers
+ fread(g1Elements, header.num_entries * sizeof(rct_g1_element), 1, file);
+
+ // Read element data
+ _g1Buffer = rct2_malloc(header.total_size);
+ fread(_g1Buffer, header.total_size, 1, file);
+
+ fclose(file);
+
+ // Fix entry data offsets
+ for (i = 0; i < header.num_entries; i++)
+ g1Elements[i].offset += (int)_g1Buffer;
+
+ // Successful
+ return 1;
+ }
+ fclose(file);
+ }
+
+ // Unsuccessful
+ RCT2_ERROR("Unable to load g1.dat");
+ return 0;
+}
+
+/**
+ * Copies a sprite onto the buffer. There is no compression used on the sprite
+ * image.
+ * rct2: 0x0067A690
+ */
+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;
+ uint8 zoom_amount = 1 << zoom_level;
+ //Requires use of palette?
+ if (image_type & IMAGE_TYPE_USE_PALETTE){
+
+ //Mix with another image?? and colour adjusted
+ 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_amount){
+ uint8* next_source_pointer = source_pointer + (uint32)(source_image->width * zoom_amount);
+ uint8* next_unknown_pointer = unknown_pointer + (uint32)(source_image->width * zoom_amount);
+ uint8* next_dest_pointer = dest_pointer + (dest_dpi->width / zoom_amount) + dest_dpi->pitch;
+
+ for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_amount, source_pointer += zoom_amount, unknown_pointer += zoom_amount, dest_pointer++){
+ uint8 pixel = *source_pointer;
+ pixel = palette_pointer[pixel];
+ pixel &= *unknown_pointer;
+ if (pixel){
+ *dest_pointer = pixel;
+ }
+ }
+ source_pointer = next_source_pointer;
+ dest_pointer = next_dest_pointer;
+ unknown_pointer = next_unknown_pointer;
+ }
+ return;
+ }
+
+ //image colour adjusted?
+ for (; height > 0; height -= zoom_amount){
+ uint8* next_source_pointer = source_pointer + (uint32)(source_image->width * zoom_amount);
+ uint8* next_dest_pointer = dest_pointer + (dest_dpi->width / zoom_amount) + dest_dpi->pitch;
+ for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_amount, source_pointer += zoom_amount, dest_pointer++){
+ uint8 pixel = *source_pointer;
+ pixel = palette_pointer[pixel];
+ if (pixel){
+ *dest_pointer = pixel;
+ }
+ }
+
+ source_pointer = next_source_pointer;
+ dest_pointer = next_dest_pointer;
+ }
+ return;
+ }
+
+ //Mix with background. It only uses source pointer for
+ //telling if it needs to be drawn not for colour.
+ if (image_type & IMAGE_TYPE_MIX_BACKGROUND){//Not tested
+ for (; height > 0; height -= zoom_amount){
+ uint8* next_source_pointer = source_pointer + (uint32)(source_image->width * zoom_amount);
+ uint8* next_dest_pointer = dest_pointer + (dest_dpi->width / zoom_amount) + dest_dpi->pitch;
+
+ for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_amount, source_pointer += zoom_amount, dest_pointer++){
+ uint8 pixel = *source_pointer;
+ if (pixel){
+ pixel = *dest_pointer;
+ pixel = palette_pointer[pixel];
+ *dest_pointer = pixel;
+ }
+ }
+
+ source_pointer = next_source_pointer;
+ dest_pointer = next_dest_pointer;
+ }
+ return;
+ }
+
+ //Basic bitmap no fancy stuff
+ if (!(source_image->flags & G1_FLAG_BMP)){//Not tested
+ for (; height > 0; height -= zoom_amount){
+ uint8* next_source_pointer = source_pointer + (uint32)(source_image->width * zoom_amount);
+ uint8* next_dest_pointer = dest_pointer + (dest_dpi->width / zoom_amount) + dest_dpi->pitch;
+
+ for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_amount, dest_pointer++, source_pointer += zoom_amount){
+ *dest_pointer = *source_pointer;
+ }
+
+ dest_pointer = next_dest_pointer;
+ source_pointer = next_source_pointer;
+ }
+ return;
+ }
+
+ if (RCT2_GLOBAL(0x9E3CDC, uint32) != 0){//Not tested. I can't actually work out when this code runs.
+ unknown_pointer += source_pointer - source_image->offset;
+
+ for (; height > 0; height -= zoom_amount){
+ uint8* next_source_pointer = source_pointer + (uint32)(source_image->width * zoom_amount);
+ uint8* next_unknown_pointer = unknown_pointer + (uint32)(source_image->width * zoom_amount);
+ uint8* next_dest_pointer = dest_pointer + (dest_dpi->width / zoom_amount) + dest_dpi->pitch;
+
+ for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_amount, dest_pointer++, source_pointer += zoom_amount, unknown_pointer += zoom_amount){
+ uint8 pixel = *source_pointer;
+ pixel &= *unknown_pointer;
+ if (pixel){
+ *dest_pointer = pixel;
+ }
+ }
+ dest_pointer = next_dest_pointer;
+ source_pointer = next_source_pointer;
+ unknown_pointer = next_unknown_pointer;
+ }
+ }
+
+ //Basic bitmap with no draw pixels
+ for (; height > 0; height -= zoom_amount){
+ uint8* next_source_pointer = source_pointer + (uint32)(source_image->width * zoom_amount);
+ uint8* next_dest_pointer = dest_pointer + (dest_dpi->width / zoom_amount) + dest_dpi->pitch;
+
+ for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_amount, dest_pointer++, source_pointer += zoom_amount){
+ uint8 pixel = *source_pointer;
+ if (pixel){
+ *dest_pointer = pixel;
+ }
+ }
+ dest_pointer = next_dest_pointer;
+ source_pointer = next_source_pointer;
+ }
+ return;
+}
+
+/**
+ * Transfers readied images onto buffers
+ * This function copies the sprite data onto the screen
+ * rct2: 0x0067AA18
+ */
+void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_pointer, uint8* palette_pointer, rct_drawpixelinfo *dpi, int image_type, int source_y_start, int height, int source_x_start, int width){
+ int zoom_level = dpi->zoom_level;
+ int zoom_amount = 1 << 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_amount){
+
+ //The first part of the source pointer is a list of offsets to different lines
+ //This will move the pointer to the correct source line.
+ next_source_pointer = source_bits_pointer + ((uint16*)source_bits_pointer)[y];
+
+ uint8 last_data_line = 0;
+
+ //For every data section in the line
+ while (!last_data_line){
+ uint8* source_pointer = next_source_pointer;
+ uint8* dest_pointer = next_dest_pointer;
+
+ int no_pixels = *source_pointer++;
+ //gap_size is the number of non drawn pixels you require to
+ //jump over on your destination
+ uint8 gap_size = *source_pointer++;
+ //The last bit in no_pixels tells you if you have reached the end of a line
+ last_data_line = no_pixels & 0x80;
+ //Clear the last data line bit so we have just the no_pixels
+ no_pixels &= 0x7f;
+ //Have our next source pointer point to the next data section
+ next_source_pointer = source_pointer + no_pixels;
+
+ //Calculates the start point of the image
+ int x_start = gap_size - source_x_start;
+
+ if (x_start > 0){
+ //Since the start is positive
+ //We need to move the drawing surface to the correct position
+ dest_pointer += x_start / zoom_amount;
+ }
+ else{
+ //If the start is negative we require to remove part of the image.
+ //This is done by moving the image pointer to the correct position.
+ source_pointer -= x_start;
+ //The no_pixels will be reduced in this operation
+ no_pixels += x_start;
+ //If there are no pixels there is nothing to draw this data section
+ if (no_pixels <= 0) continue;
+ //Reset the start position to zero as we have taken into account all moves
+ x_start = 0;
+ }
+
+ int x_end = x_start + no_pixels;
+ //If the end position is further out than the whole image
+ //end position then we need to shorten the line again
+ if (x_end > width){
+ //Shorten the line
+ no_pixels -= x_end - width;
+ //If there are no pixels there is nothing to draw.
+ if (no_pixels <= 0) continue;
+ }
+
+ //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_amount, source_pointer += zoom_amount, dest_pointer++){
+ uint8 al = *source_pointer;
+ uint8 ah = *dest_pointer;
+ if (image_type & IMAGE_TYPE_MIX_BACKGROUND)
+ al = palette_pointer[(((uint16)al << 8) | ah) - 0x100];
+ else
+ al = palette_pointer[al];
+ *dest_pointer = al;
+ }
+ }
+ else if (image_type & IMAGE_TYPE_MIX_BACKGROUND){//In the .exe these are all unraveled loops
+ //Doesnt use source pointer ??? mix with background only?
+ //Not Tested
+
+ for (; no_pixels > 0; no_pixels -= zoom_amount, dest_pointer++){
+ uint8 pixel = *dest_pointer;
+ pixel = palette_pointer[pixel];
+ *dest_pointer = pixel;
+ }
+ }
+ else
+ {
+ for (; no_pixels > 0; no_pixels -= zoom_amount, source_pointer += zoom_amount, dest_pointer++){
+ *dest_pointer = *source_pointer;
+ }
+ }
+ }
+
+ //Add a line to the drawing surface pointer
+ next_dest_pointer += dpi->width / zoom_amount + dpi->pitch;
+ }
+}
+
+/**
+ *
+ * rct2: 0x0067A28E
+ * image_id (ebx)
+ * image_id as below
+ * 0b_111X_XXXX_XXXX_XXXX_XXXX_XXXX_XXXX_XXXX image_type
+ * 0b_XXX1_11XX_XXXX_XXXX_XXXX_XXXX_XXXX_XXXX image_sub_type (unknown pointer)
+ * 0b_XXX1_1111_XXXX_XXXX_XXXX_XXXX_XXXX_XXXX secondary_colour
+ * 0b_XXXX_XXXX_1111_1XXX_XXXX_XXXX_XXXX_XXXX primary_colour
+ * 0b_XXXX_X111_1111_1XXX_XXXX_XXXX_XXXX_XXXX palette_ref
+ * 0b_XXXX_XXXX_XXXX_X111_1111_1111_1111_1111 image_id (offset to g1)
+ * x (cx)
+ * y (dx)
+ * dpi (esi)
+ * tertiary_colour (ebp)
+ */
+void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32 tertiary_colour)
+{
+ //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, (int)dpi, tertiary_colour);
+ //return;
+
+ int image_type = (image_id & 0xE0000000) >> 28;
+ int image_sub_type = (image_id & 0x1C000000) >> 26;
+
+ uint8* palette_pointer = NULL;
+ uint8 palette[0x100];
+
+ RCT2_GLOBAL(0x00EDF81C, uint32) = image_id & 0xE0000000;
+
+ uint8* unknown_pointer = (uint8*)(RCT2_ADDRESS(0x9E3CE4, uint32*)[image_sub_type]);
+ RCT2_GLOBAL(0x009E3CDC, uint32) = (uint32)unknown_pointer;
+
+ if (image_type && !(image_type & IMAGE_TYPE_UNKNOWN)) {
+ uint8 palette_ref = (image_id >> 19) & 0xFF;
+ if (image_type & IMAGE_TYPE_MIX_BACKGROUND){
+ unknown_pointer = NULL;
+ RCT2_GLOBAL(0x009E3CDC, uint32) = 0;
+ }
+ else{
+ palette_ref &= 0x7F;
+ }
+
+ uint16 palette_offset = palette_to_g1_offset[palette_ref];
+ palette_pointer = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[palette_offset].offset;
+ RCT2_GLOBAL(0x9ABDA4, uint32) = (uint32)palette_pointer;
+ }
+ else if (image_type && !(image_type & IMAGE_TYPE_USE_PALETTE)){
+ RCT2_GLOBAL(0x9E3CDC, uint32) = 0;
+ unknown_pointer = NULL;
+
+ uint32 primary_offset = palette_to_g1_offset[(image_id >> 19) & 0x1F];
+ uint32 secondary_offset = palette_to_g1_offset[(image_id >> 24) & 0x1F];
+ uint32 tertiary_offset = palette_to_g1_offset[tertiary_colour];
+
+ rct_g1_element* primary_colour = &RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[primary_offset];
+ rct_g1_element* secondary_colour = &RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[secondary_offset];
+ rct_g1_element* tertiary_colour = &RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[tertiary_offset];
+
+ memcpy((uint8*)0x9ABFFF, &primary_colour->offset[0xF3], 12);
+ memcpy((uint8*)0x9ABFD6, &secondary_colour->offset[0xF3], 12);
+ memcpy((uint8*)0x9ABF3A, &tertiary_colour->offset[0xF3], 12);
+
+ //image_id
+ RCT2_GLOBAL(0xEDF81C, uint32) |= 0x20000000;
+ image_id |= IMAGE_TYPE_USE_PALETTE << 28;
+
+ RCT2_GLOBAL(0x9ABDA4, uint32) = 0x9ABF0C;
+ palette_pointer = (uint8*)0x9ABF0C;
+ }
+ else if (image_type){
+ RCT2_GLOBAL(0x9E3CDC, uint32) = 0;
+ unknown_pointer = NULL;
+ //Copy the peep palette into a new palette.
+ //Not really required but its nice to make a copy
+ memcpy(palette, peep_palette, 0x100);
+
+ //Top
+ int top_type = (image_id >> 19) & 0x1f;
+ 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 = 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);
+
+ //For backwards compatibility until the zooming function is done
+ RCT2_GLOBAL(0x9ABDA4, uint8*) = palette;
+ palette_pointer = palette;
+ }
+ gfx_draw_sprite_palette_set(dpi, image_id, x, y, palette_pointer, unknown_pointer);
+}
\ No newline at end of file
diff --git a/src/drawing/string.c b/src/drawing/string.c
new file mode 100644
index 0000000000..faeec42f64
--- /dev/null
+++ b/src/drawing/string.c
@@ -0,0 +1,1011 @@
+/*****************************************************************************
+ * 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.
+ *
+ * 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 "../localisation/localisation.h"
+#include "../sprites.h"
+#include "drawing.h"
+
+/**
+ *
+ * rct2: 0x006C19AC
+ */
+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, 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;
+ }
+}
+
+/**
+ * Return the width of the string in buffer
+ *
+ * rct2: 0x006C2321
+ * buffer (esi)
+ */
+int gfx_get_string_width(char* buffer)
+{
+ // Current font sprites
+ uint16* current_font_sprite_base;
+ // Width of string
+ int width;
+ rct_g1_element g1_element;
+
+ current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16);
+ width = 0;
+
+ for (uint8* curr_char = (uint8*)buffer; *curr_char != (uint8)0; curr_char++) {
+
+ if (*curr_char >= 0x20) {
+ width += RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8)[*current_font_sprite_base + (*curr_char - 0x20)];
+ continue;
+ }
+ switch(*curr_char) {
+ case FORMAT_MOVE_X:
+ curr_char++;
+ width = *curr_char;
+ break;
+ case FORMAT_ADJUST_PALETTE:
+ case 3:
+ case 4:
+ curr_char++;
+ break;
+ case FORMAT_NEWLINE:
+ case FORMAT_NEWLINE_SMALLER:
+ continue;
+ 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 = 0x0E0;
+ break;
+ case FORMAT_SMALLFONT:
+ *current_font_sprite_base = 0;
+ break;
+ 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 <= 0x16) { //case 0x11? FORMAT_NEW_LINE_X_Y
+ curr_char += 2;
+ continue;
+ }
+ curr_char += 4;//never happens?
+ break;
+ }
+ }
+ return width;
+}
+
+/**
+ * Clip the text in buffer to width, add ellipsis and return the new width of the clipped string
+ *
+ * rct2: 0x006C2460
+ * buffer (esi)
+ * width (edi)
+ */
+int gfx_clip_string(char* buffer, int width)
+{
+ // Location of font sprites
+ uint16 current_font_sprite_base;
+ // Width the string has to fit into
+ unsigned int max_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;
+ }
+
+ current_font_sprite_base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16);
+ max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[current_font_sprite_base]);
+
+ clipped_width = 0;
+ last_char = buffer;
+
+ for (unsigned char* curr_char = buffer; *curr_char != (uint8)0; curr_char++) {
+ if (*curr_char < 0x20) {
+ switch (*curr_char) {
+ case FORMAT_MOVE_X:
+ curr_char++;
+ clipped_width = *curr_char;
+ continue;
+ case FORMAT_ADJUST_PALETTE:
+ case 3:
+ case 4:
+ curr_char++;
+ continue;
+ case FORMAT_NEWLINE:
+ case FORMAT_NEWLINE_SMALLER:
+ continue;
+ 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 = 0x0E0;
+ break;
+ case FORMAT_SMALLFONT:
+ current_font_sprite_base = 0;
+ break;
+ 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 <= 0x16) { //case 0x11? FORMAT_NEW_LINE_X_Y
+ curr_char += 2;
+ continue;
+ }
+ curr_char += 4;//never happens?
+ continue;
+ }
+ max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[current_font_sprite_base]);
+ }
+
+ clipped_width += RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8)[current_font_sprite_base + (*curr_char - 0x20)];
+
+ if ((int)clipped_width > width) {
+// *((uint32*)last_char) = '...';
+ strcpy(last_char-3, "...");
+ clipped_width = width;
+ return clipped_width;
+ }
+ if (clipped_width <= max_width) {
+ last_char = curr_char+1;
+ }
+ }
+ return clipped_width;
+}
+
+
+/**
+ * Wrap the text in buffer to width, returns width of longest line.
+ *
+ * Inserts NULL where line should break (as \n is used for something else),
+ * so the number of lines is returned in num_lines. font_height seems to be
+ * a control character for line height.
+ *
+ * rct2: 0x006C21E2
+ * buffer (esi)
+ * width (edi) - in
+ * num_lines (edi) - out
+ * font_height (ebx) - out
+ */
+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;
+
+ *num_lines = 0;
+ *font_height = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16);
+
+ // Pointer to the start of the current word
+ unsigned char* curr_word = NULL;
+ // Width of line up to current word
+ unsigned int curr_width;
+
+ for (unsigned char* curr_char = buffer; *curr_char != (uint8)0; curr_char++) {
+
+ // Remember start of current word and line width up to this word
+ if (*curr_char == ' ') {
+ curr_word = curr_char;
+ curr_width = line_width;
+ }
+
+ // 5 is RCT2 new line?
+ if (*curr_char != 5) {
+ if (*curr_char < ' ') {
+ switch(*curr_char) {
+ case FORMAT_MOVE_X:
+ case FORMAT_ADJUST_PALETTE:
+ case 3:
+ case 4:
+ curr_char++;
+ continue;
+ case FORMAT_NEWLINE:
+ case FORMAT_NEWLINE_SMALLER:
+ continue;
+ case FORMAT_TINYFONT:
+ *font_height = 0x1C0;
+ continue;
+ case FORMAT_BIGFONT:
+ *font_height = 0x2A0;
+ continue;
+ case FORMAT_MEDIUMFONT:
+ *font_height = 0xE0;
+ continue;
+ case FORMAT_SMALLFONT:
+ *font_height = 0;
+ continue;
+ 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 <= 0x16) {
+ curr_char += 2;
+ continue;
+ }
+ curr_char += 4;
+ continue;
+ }
+ }
+
+ line_width += RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8)[*font_height + (*curr_char - 0x20)];
+
+ if ((int)line_width <= width) {
+ continue;
+ }
+ if (curr_word == 0) {
+ curr_char--;
+ unsigned char* old_char = curr_char;
+ unsigned char swap_char = 0;
+ unsigned char temp;
+ // Insert NULL at current character
+ // Aboslutely no guarantee that this won't overrun!
+ do {
+ temp = swap_char;
+ swap_char = *curr_char;
+ *curr_char = temp;
+ curr_char++;
+ } while(swap_char != 0);
+
+ *curr_char = swap_char;
+ curr_char = old_char;
+ curr_char++;
+ *num_lines += 1;
+
+ if (line_width > max_width) {
+ max_width = line_width;
+ }
+ line_width = 0;
+ curr_word = 0;
+ continue;
+ }
+ curr_char = curr_word;
+ line_width = curr_width;
+ }
+
+ *num_lines += 1;
+ *curr_char = 0;
+
+ if (line_width > max_width) {
+ max_width = line_width;
+ }
+ line_width = 0;
+ curr_word = 0;
+ }
+ if (max_width == 0)return line_width;
+ return max_width;
+}
+
+
+/**
+ * Draws i formatted text string left aligned at i specified position but clips
+ * the text with an elipsis if the text width exceeds the specified width.
+ * rct2: 0x006C1B83
+ * dpi (edi)
+ * format (bx)
+ * args (esi)
+ * colour (al)
+ * x (cx)
+ * y (dx)
+ * width (bp)
+ */
+void gfx_draw_string_left_clipped(rct_drawpixelinfo* dpi, int format, void* args, int colour, int x, int y, int width)
+{
+ char* buffer;
+
+ buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char);
+ format_string(buffer, format, args);
+
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0;
+
+ // Clip text - return value is not needed
+ gfx_clip_string(buffer, width);
+
+ gfx_draw_string(dpi, buffer, colour, x, y);
+}
+
+/**
+ * Draws i formatted text string centred at i specified position but clips the
+ * text with an elipsis if the text width exceeds the specified width.
+ * rct2: 0x006C1BBA
+ * dpi (edi)
+ * format (bx)
+ * args (esi)
+ * colour (al)
+ * x (cx)
+ * y (dx)
+ * width (bp)
+ */
+void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y, int width)
+{
+ char* buffer;
+ short text_width;
+
+ buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char);
+ format_string(buffer, format, args);
+
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0;
+
+ // Clip text
+ text_width = gfx_clip_string(buffer, width);
+
+ // Draw the text centred
+ if (text_width <= 0xFFFF) {
+ x -= (text_width - 1) / 2;
+ gfx_draw_string(dpi, buffer, colour, x, y);
+ }
+}
+
+/**
+ * Draws i formatted text string right aligned.
+ * rct2: 0x006C1BFC
+ * dpi (edi)
+ * format (bx)
+ * args (esi)
+ * colour (al)
+ * x (cx)
+ * y (dx)
+ */
+void gfx_draw_string_right(rct_drawpixelinfo* dpi, int format, void* args, int colour, int x, int y)
+{
+ char* buffer;
+ short text_width;
+
+ buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char);
+ format_string(buffer, format, args);
+
+ // Measure text width
+ text_width = gfx_get_string_width(buffer);
+
+ // Draw the text right aligned
+ x -= text_width;
+ gfx_draw_string(dpi, buffer, colour, x, y);
+}
+
+/**
+ *
+ * rct2: 0x006C1E53
+ * dpi (edi)
+ * args (esi)
+ * x (cx)
+ * y (dx)
+ * width (bp)
+ * colour (al)
+ * format (ebx)
+ */
+int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour)
+{
+ int font_height, line_height, line_width, line_y, num_lines;
+ // Location of font sprites
+ uint16* current_font_sprite_base;
+
+ char* buffer = RCT2_ADDRESS(0x009C383D, char);
+
+ current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16);
+ *current_font_sprite_base = 0xE0;
+
+ gfx_draw_string(dpi, buffer, colour, dpi->x, dpi->y);
+
+ buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char);
+
+ format_string(buffer, format, args);
+
+ *current_font_sprite_base = 0xE0;
+
+ // line_width unused here
+ line_width = gfx_wrap_string(buffer, width, &num_lines, &font_height);
+
+ line_height = 0x0A;
+
+ if (font_height > 0xE0) {
+ line_height = 6;
+ if (font_height != 0x1C0) {
+ line_height = 0x12;
+ }
+ }
+
+ if (*buffer == 0x0B) {
+ line_height = line_height + 1;
+ }
+
+ font_height = (line_height / 2) * num_lines;
+ line_y = y - font_height;
+
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16) = 0;
+
+ for (int line = 0; line <= num_lines; ++line) {
+ int half_width = gfx_get_string_width(buffer) / 2;
+ gfx_draw_string(dpi, buffer, 0xFE, x - half_width, line_y);
+
+ buffer += get_string_length(buffer) + 1;
+ line_y += line_height;
+ }
+
+ return line_y - y;
+}
+
+/**
+ *
+ * rct2: 0x006C2105
+ * dpi (edi)
+ * args (esi)
+ * x (cx)
+ * y (dx)
+ * width (bp)
+ * format (bx)
+ * colour (al)
+ */
+int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour)
+{
+ // font height might actually be something else
+ int font_height, line_height, line_width, line_y, num_lines;
+
+ // Location of font sprites
+ uint16* current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16);
+ *current_font_sprite_base = 0xE0;
+
+ char* buffer = RCT2_ADDRESS(0x009C383D, char);
+
+ gfx_draw_string(dpi, buffer, colour, dpi->x, dpi->y);
+
+ buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char);
+
+ format_string(buffer, format, args);
+
+ *current_font_sprite_base = 0xE0;
+
+ // Line width unused here
+ line_width = gfx_wrap_string(buffer, width, &num_lines, &font_height);
+
+ line_height = 0x0A;
+
+ if (font_height > 0xE0) {
+ line_height = 6;
+ if (font_height != 0x1C0) {
+ line_height = 0x12;
+ }
+ }
+
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16) = 0;
+
+ line_y = y;
+
+ for (int line = 0; line <= num_lines; ++line) {
+ gfx_draw_string(dpi, buffer, 0xFE, x, line_y);
+ buffer += get_string_length(buffer) + 1;
+ line_y += line_height;
+ }
+
+ return line_y - y;
+}
+
+/**
+ * Draws i formatted text string.
+ * rct2: 0x006C1B2F
+ * dpi (edi)
+ * format (bx)
+ * args (esi)
+ * colour (al)
+ * x (cx)
+ * y (dx)
+ */
+void gfx_draw_string_left(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y)
+{
+ char* buffer;
+
+ buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char);
+ format_string(buffer, format, args);
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0;
+ gfx_draw_string(dpi, buffer, colour, x, y);
+}
+
+/**
+ * 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)[colour & 0xFF];
+
+ if (!(*current_font_flags & 2)) {
+ eax = eax & 0x0FF0000FF;
+ }
+ // Adjust text palette. Store current colour?
+ 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;
+}
+
+/**
+ * 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;
+
+ eax = RCT2_ADDRESS(0x0141FD45, uint8)[colour * 8];
+ if (*current_font_flags & 2) {
+ eax |= 0x0A0A00;
+ }
+ //Adjust text palette. Store current colour?
+ 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;
+}
+
+
+/**
+ *
+ * rct2: 0x00682702
+ * dpi (edi)
+ * buffer (esi)
+ * colour (al)
+ * x (cx)
+ * y (dx)
+ */
+void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, int y)
+{
+
+ int eax, ebx, ebp;
+ rct_g1_element* g1_element;
+
+ // Maximum length/height of string
+ int max_x = x;
+ int max_y = 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;
+
+ if (colour != 0xFE) {
+
+ if (x >= dpi->x + dpi->width)
+ return;
+
+ if (x + 0x280 <= dpi->x)
+ return;
+
+ if (y >= dpi->y + dpi->height)
+ return;
+
+ if (y + 0x5A <= dpi->y) {
+ return;
+ }
+
+ if (colour != 0xFF) {
+
+ // switch_colour:
+ *current_font_flags = 0;
+ if (*current_font_sprite_base < 0) {
+ *current_font_flags |= 4;
+ if (*current_font_sprite_base != 0xFFFF) {
+ *current_font_flags |= 8;
+ }
+ *current_font_sprite_base = 0xE0;
+ }
+ if (colour & (1 << 5)) {
+ *current_font_flags |= 2;
+ }
+ colour &= ~(1 << 5);
+
+ if (!(colour & 0x40)) {
+ ebp = colour;
+ if (*current_font_flags & 1) {
+ if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) {
+ skip_char = 1;
+ } else {
+ skip_char = 0;
+ }
+ } else {
+ colour_char_window(ebp, current_font_flags, palette_pointer);
+ }
+ } else {
+ *current_font_flags |= 1;
+ colour &= 0x1F;
+
+ if (*current_font_flags & 4) {
+ if (*current_font_flags & 8) {
+ eax = RCT2_ADDRESS(0x0141FC48, uint8)[colour * 8];
+ eax = eax << 16;
+ eax = eax | RCT2_ADDRESS(0x0141FC46, uint8)[colour * 8];
+ } else {
+ eax = RCT2_ADDRESS(0x0141FC49, uint8)[colour * 8];
+ eax = eax << 16;
+ eax = eax | RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8];
+ }
+ } else {
+ eax = RCT2_ADDRESS(0x0141FC4A, uint8)[colour * 8];
+ eax = eax << 16;
+ eax = eax | RCT2_ADDRESS(0x0141FC48, uint8)[colour * 8];
+ }
+ // Adjust text palette. Store current colour? ;
+ 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;
+ }
+ }
+ }
+
+ if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) {
+ skip_char = 1;
+ }
+
+ for (uint8 al = *buffer; al > 0; ++buffer, al = *buffer) {
+
+ // Skip to the next printing character
+ if (skip_char) {
+ if (al < 0x20) {
+ // Control codes
+ skip_char = 0;
+ } else if (al >= FORMAT_COLOUR_CODE_START && al <= FORMAT_COLOUR_CODE_END) {
+ // Colour codes
+ if (*current_font_flags == 1) {
+ if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) {
+ skip_char = 1;
+ } else {
+ skip_char = 0;
+ }
+ continue;
+ }
+ colour_char(al - FORMAT_COLOUR_CODE_START, current_font_flags, palette_pointer);
+ continue;
+ } else {
+ continue;
+ }
+ }
+
+ // Control codes
+ switch (al) {
+ case FORMAT_MOVE_X://Start New Line at start+buffer x, same y. (Overwrite?)
+ max_x = x + (uint8)*++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;
+ break;
+ }
+ }
+
+ 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;
+ }
+
+ 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;
+
+
+ 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;
+ }
+ 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 = *((uint16*)(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, 0);
+
+ 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;
+ }
+ 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;
+ }
+ }
+
+ gLastDrawStringX = max_x;
+ gLastDrawStringY = max_y;
+}
+
+void draw_string_left_underline(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y)
+{
+ char buffer[128];
+ int width;
+
+ format_string(buffer, format, args);
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 224;
+ width = gfx_get_string_width(buffer);
+ gfx_draw_string(dpi, buffer, colour, x, y);
+ gfx_fill_rect(dpi, x, y + 11, x + width, y + 11, text_palette[1]);
+ if (text_palette[2] != 0)
+ gfx_fill_rect(dpi, x + 1, y + 12, x + width + 1, y + 12, text_palette[2]);
+}
+
+void draw_string_right_underline(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y)
+{
+ char buffer[128];
+ int width;
+
+ format_string(buffer, format, args);
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 224;
+ width = gfx_get_string_width(buffer);
+ x -= width;
+ gfx_draw_string(dpi, buffer, colour, x, y);
+ gfx_fill_rect(dpi, x, y + 11, x + width, y + 11, text_palette[1]);
+ if (text_palette[2] != 0)
+ gfx_fill_rect(dpi, x + 1, y + 12, x + width + 1, y + 12, text_palette[2]);
+}
+
+void draw_string_centred_underline(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y)
+{
+ char buffer[128];
+ int width;
+
+ format_string(buffer, format, args);
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 224;
+ width = gfx_get_string_width(buffer);
+ x -= width / 2;
+ gfx_draw_string(dpi, buffer, colour, x, y);
+ gfx_fill_rect(dpi, x, y + 11, x + width, y + 11, text_palette[1]);
+ if (text_palette[2] != 0)
+ gfx_fill_rect(dpi, x + 1, y + 12, x + width + 1, y + 12, text_palette[2]);
+}
+
+/**
+ *
+ * rct2: 0x006C1DB7
+ *
+ * left : cx
+ * top : dx
+ * numLines : bp
+ * text : esi
+ * dpi : edi
+ */
+void draw_string_centred_raw(rct_drawpixelinfo *dpi, int x, int y, int numLines, char *text)
+{
+ RCT2_CALLPROC_X(0x006C1DB7, 0, 0, x, y, (int)text, (int)dpi, numLines);
+}
\ No newline at end of file
diff --git a/src/editor.c b/src/editor.c
index 138eeb1162..1d57704561 100644
--- a/src/editor.c
+++ b/src/editor.c
@@ -19,22 +19,22 @@
*****************************************************************************/
#include "addresses.h"
-#include "date.h"
+#include "audio/audio.h"
+#include "drawing/drawing.h"
#include "editor.h"
#include "game.h"
-#include "gfx.h"
-#include "map.h"
-#include "news_item.h"
+#include "interface/window.h"
+#include "interface/viewport.h"
+#include "localisation/date.h"
+#include "localisation/localisation.h"
+#include "management/finance.h"
+#include "management/news_item.h"
#include "object.h"
-#include "park.h"
-#include "ride.h"
-#include "window.h"
-#include "viewport.h"
-#include "finance.h"
-#include "audio.h"
-#include "sprite.h"
-#include "string_ids.h"
-#include "staff.h"
+#include "ride/ride.h"
+#include "world/map.h"
+#include "world/park.h"
+#include "world/sprite.h"
+#include "world/staff.h"
static void set_all_land_owned();
diff --git a/src/game.c b/src/game.c
index 8348b053cd..3453f23ec3 100644
--- a/src/game.c
+++ b/src/game.c
@@ -19,34 +19,32 @@
*****************************************************************************/
#include "addresses.h"
-#include "audio.h"
-#include "climate.h"
+#include "audio/audio.h"
#include "config.h"
-#include "finance.h"
#include "game.h"
#include "input.h"
-#include "news_item.h"
+#include "localisation/localisation.h"
+#include "interface/screenshot.h"
+#include "interface/viewport.h"
+#include "interface/widget.h"
+#include "interface/window.h"
+#include "management/finance.h"
+#include "management/news_item.h"
#include "object.h"
-#include "osinterface.h"
-#include "park.h"
-#include "peep.h"
-#include "rct2.h"
-#include "ride.h"
-#include "sawyercoding.h"
+#include "platform/osinterface.h"
+#include "ride/ride.h"
+#include "ride/vehicle.h"
#include "scenario.h"
-#include "screenshot.h"
-#include "sprite.h"
-#include "string_ids.h"
#include "title.h"
#include "tutorial.h"
-#include "vehicle.h"
-#include "viewport.h"
-#include "widget.h"
-#include "window.h"
-#include "staff.h"
-#include "window_error.h"
-#include "window_tooltip.h"
-
+#include "util/sawyercoding.h"
+#include "windows/error.h"
+#include "windows/tooltip.h"
+#include "world/climate.h"
+#include "world/park.h"
+#include "world/peep.h"
+#include "world/sprite.h"
+#include "world/staff.h"
int gGameSpeed = 1;
diff --git a/src/input.c b/src/input.c
index a2e1f2bd1c..5cc12fd69f 100644
--- a/src/input.c
+++ b/src/input.c
@@ -21,19 +21,19 @@
#include
#include
#include "addresses.h"
-#include "audio.h"
+#include "audio/audio.h"
#include "config.h"
#include "game.h"
#include "input.h"
-#include "map.h"
-#include "osinterface.h"
-#include "sprite.h"
+#include "interface/viewport.h"
+#include "interface/widget.h"
+#include "interface/window.h"
+#include "platform/osinterface.h"
#include "tutorial.h"
-#include "viewport.h"
-#include "widget.h"
-#include "window.h"
-#include "window_tooltip.h"
-#include "window_dropdown.h"
+#include "windows/tooltip.h"
+#include "windows/dropdown.h"
+#include "world/map.h"
+#include "world/sprite.h"
POINT _dragPosition;
diff --git a/src/interface/graph.c b/src/interface/graph.c
index 9cb39f564c..96917c88af 100644
--- a/src/interface/graph.c
+++ b/src/interface/graph.c
@@ -18,10 +18,10 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
-#include "date.h"
+#include "../addresses.h"
+#include "../localisation/date.h"
+#include "../localisation/localisation.h"
#include "graph.h"
-#include "string_ids.h"
static void graph_draw_months_uint8(rct_drawpixelinfo *dpi, uint8 *history, int count, int baseX, int baseY)
{
diff --git a/src/interface/graph.h b/src/interface/graph.h
index 03622b7a2c..82a0f7fa6c 100644
--- a/src/interface/graph.h
+++ b/src/interface/graph.h
@@ -21,8 +21,8 @@
#ifndef _GRAPH_H_
#define _GRAPH_H_
-#include "gfx.h"
-#include "rct2.h"
+#include "../common.h"
+#include "../drawing/drawing.h"
void graph_draw_uint8(rct_drawpixelinfo *dpi, uint8 *history, int count, int baseX, int baseY);
void graph_draw_money32(rct_drawpixelinfo *dpi, money32 *history, int count, int baseX, int baseY, int modifier, int offset);
diff --git a/src/interface/screenshot.c b/src/interface/screenshot.c
index 240745c906..5f871f609b 100644
--- a/src/interface/screenshot.c
+++ b/src/interface/screenshot.c
@@ -19,19 +19,18 @@
*****************************************************************************/
#pragma pack(1)
-#include
-#include
-#include "osinterface.h"
-#include "addresses.h"
-#include "config.h"
-#include "gfx.h"
-#include "game.h"
-#include "rct2.h"
-#include "screenshot.h"
-#include "string_ids.h"
-#include "window_error.h"
-
#include // For MAX_PATH
+#include
+#include
+#include "../platform/osinterface.h"
+#include "../addresses.h"
+#include "../config.h"
+#include "../drawing/drawing.h"
+#include "../game.h"
+#include "../localisation/localisation.h"
+#include "../windows/error.h"
+#include "screenshot.h"
+
static int screenshot_dump_bmp();
diff --git a/src/interface/viewport.c b/src/interface/viewport.c
index 25b4fe062b..9bf6493372 100644
--- a/src/interface/viewport.c
+++ b/src/interface/viewport.c
@@ -19,13 +19,13 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "config.h"
-#include "gfx.h"
-#include "map.h"
-#include "string_ids.h"
-#include "sprite.h"
-#include "sprites.h"
+#include "../addresses.h"
+#include "../config.h"
+#include "../drawing/drawing.h"
+#include "../localisation/localisation.h"
+#include "../sprites.h"
+#include "../world/map.h"
+#include "../world/sprite.h"
#include "viewport.h"
#include "window.h"
diff --git a/src/interface/widget.c b/src/interface/widget.c
index 7a460654d2..08a7a7b554 100644
--- a/src/interface/widget.c
+++ b/src/interface/widget.c
@@ -21,9 +21,9 @@
#include
#include
#include
-#include "addresses.h"
-#include "gfx.h"
-#include "sprites.h"
+#include "../addresses.h"
+#include "../drawing/drawing.h"
+#include "../sprites.h"
#include "widget.h"
#include "window.h"
diff --git a/src/interface/window.c b/src/interface/window.c
index e61abcb944..44abfc78f9 100644
--- a/src/interface/window.c
+++ b/src/interface/window.c
@@ -19,17 +19,16 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "audio.h"
-#include "game.h"
-#include "gfx.h"
-#include "map.h"
-#include "osinterface.h"
-#include "rct2.h"
+#include "../addresses.h"
+#include "../audio/audio.h"
+#include "../game.h"
+#include "../drawing/drawing.h"
+#include "../platform/osinterface.h"
+#include "../world/map.h"
+#include "../world/sprite.h"
#include "widget.h"
#include "window.h"
#include "viewport.h"
-#include "sprite.h"
#define RCT2_FIRST_WINDOW (RCT2_ADDRESS(RCT2_ADDRESS_WINDOW_LIST, rct_window))
#define RCT2_LAST_WINDOW (RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*) - 1)
diff --git a/src/interface/window.h b/src/interface/window.h
index f7c27d7b1d..c5fc9a328a 100644
--- a/src/interface/window.h
+++ b/src/interface/window.h
@@ -21,11 +21,11 @@
#ifndef _WINDOW_H_
#define _WINDOW_H_
-#include "gfx.h"
-#include "park.h"
-#include "peep.h"
-#include "rct2.h"
-#include "ride.h"
+#include "../common.h"
+#include "../drawing/drawing.h"
+#include "../ride/ride.h"
+#include "../world/park.h"
+#include "../world/peep.h"
struct rct_window;
union rct_window_event;
diff --git a/src/intro.c b/src/intro.c
index 8b2ee2fdba..17f22c2ce0 100644
--- a/src/intro.c
+++ b/src/intro.c
@@ -19,13 +19,12 @@
*****************************************************************************/
#include "addresses.h"
-#include "audio.h"
-#include "gfx.h"
+#include "audio/audio.h"
+#include "drawing/drawing.h"
#include "intro.h"
-#include "rct2.h"
-#include "osinterface.h"
+#include "localisation/localisation.h"
+#include "platform/osinterface.h"
#include "sprites.h"
-#include "string_ids.h"
static void screen_intro_process_mouse_input();
static void screen_intro_process_keyboard_input();
diff --git a/src/localisation/date.c b/src/localisation/date.c
index 1db9d0f224..8312f5d798 100644
--- a/src/localisation/date.c
+++ b/src/localisation/date.c
@@ -18,9 +18,8 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
+#include "../addresses.h"
#include "date.h"
-#include "rct2.h"
// rct2: 0x00993988
const sint16 days_in_month[MONTH_COUNT] = { 31, 30, 31, 30, 31, 31, 30, 31 };
diff --git a/src/localisation/date.h b/src/localisation/date.h
index 0fef3dde69..94d0f3af4c 100644
--- a/src/localisation/date.h
+++ b/src/localisation/date.h
@@ -21,7 +21,7 @@
#ifndef _DATE_H_
#define _DATE_H_
-#include "rct2.h"
+#include "../common.h"
enum {
MONTH_MARCH,
diff --git a/src/localisation/format_codes.h b/src/localisation/format_codes.h
new file mode 100644
index 0000000000..c0931c0b4b
--- /dev/null
+++ b/src/localisation/format_codes.h
@@ -0,0 +1,127 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Ted John
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of OpenRCT2.
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
+#ifndef _FORMAT_CODES_H_
+#define _FORMAT_CODES_H_
+
+char format_get_code(const char *token);
+const char *format_get_token(char code);
+
+enum {
+ // Font format codes
+
+ // 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,
+ FORMAT_COMMA16,
+ FORMAT_UINT16,
+ FORMAT_CURRENCY2DP,
+ FORMAT_CURRENCY,
+ FORMAT_STRINGID,
+ FORMAT_STRINGID2,
+ FORMAT_STRING,
+ FORMAT_MONTHYEAR,
+ FORMAT_MONTH,
+ FORMAT_VELOCITY,
+ FORMAT_POP16,
+ FORMAT_PUSH16,
+ FORMAT_DURATION,
+ FORMAT_REALTIME,
+ FORMAT_LENGTH,
+ FORMAT_SPRITE,
+
+ // Colour format codes
+ FORMAT_COLOUR_CODE_START = 142,
+ FORMAT_BLACK = 142,
+ FORMAT_GREY,
+ FORMAT_WHITE,
+ FORMAT_RED,
+ FORMAT_GREEN,
+ FORMAT_YELLOW,
+ FORMAT_TOPAZ,
+ FORMAT_CELADON,
+ FORMAT_BABYBLUE,
+ FORMAT_PALELAVENDER,
+ FORMAT_PALEGOLD,
+ FORMAT_LIGHTPINK,
+ FORMAT_PEARLAQUA,
+ FORMAT_PALESILVER,
+ FORMAT_COLOUR_CODE_END = FORMAT_PALESILVER,
+
+ // Extra non-ascii characters
+ FORMAT_AMINUSCULE = 159,
+ FORMAT_UP,
+ FORMAT_POUND = 163,
+ FORMAT_YEN = 165,
+ FORMAT_COPYRIGHT = 169,
+ FORMAT_DOWN,
+ FORMAT_LEFTGUILLEMET,
+ FORMAT_TICK,
+ FORMAT_CROSS,
+ FORMAT_RIGHT = 175,
+ FORMAT_DEGREE,
+ FORMAT_SQUARED = 178,
+ FORMAT_OPENQUOTES = 180,
+ FORMAT_EURO = 181,
+ FORMAT_APPROX = 184,
+ FORMAT_POWERNEGATIVEONE,
+ FORMAT_BULLET,
+ FORMAT_RIGHTGUILLEMET,
+ FORMAT_SMALLUP,
+ FORMAT_SMALLDOWN,
+ FORMAT_LEFT,
+ FORMAT_INVERTEDQUESTION
+};
+
+#endif
\ No newline at end of file
diff --git a/src/localisation/language.c b/src/localisation/language.c
index e6e9fb099a..c0951caf74 100644
--- a/src/localisation/language.c
+++ b/src/localisation/language.c
@@ -20,9 +20,8 @@
#include
#include
-#include "addresses.h"
-#include "language.h"
-#include "string_ids.h"
+#include "../addresses.h"
+#include "localisation.h"
const char *language_names[LANGUAGE_COUNT] = {
"", // LANGUAGE_UNDEFINED
diff --git a/src/localisation/language.h b/src/localisation/language.h
index 86c3b6afef..88fa6e5a9c 100644
--- a/src/localisation/language.h
+++ b/src/localisation/language.h
@@ -21,8 +21,7 @@
#ifndef _LANGUAGE_H_
#define _LANGUAGE_H_
-#include "rct2.h"
-#include "string_ids.h"
+#include "../common.h"
enum {
LANGUAGE_UNDEFINED,
diff --git a/src/localisation/string_ids.c b/src/localisation/localisation.c
similarity index 58%
rename from src/localisation/string_ids.c
rename to src/localisation/localisation.c
index aa9d50f568..c2462bbd1a 100644
--- a/src/localisation/string_ids.c
+++ b/src/localisation/localisation.c
@@ -18,1053 +18,12 @@
* along with this program. If not, see .
*****************************************************************************/
-#include
-#include
-#include "addresses.h"
-#include "config.h"
-#include "currency.h"
-#include "game.h"
+#include "../addresses.h"
+#include "../config.h"
+#include "../game.h"
+#include "../util/util.h"
#include "date.h"
-#include "language.h"
-#include "rct2.h"
-#include "string_ids.h"
-#include "util.h"
-
-// TODO Store real names in a data file.
-#pragma region Real names
-
-const char *real_names[] = {
- "Aaron",
- "Abdul",
- "Abraham",
- "Abu",
- "Adam",
- "Adrian",
- "Adriane",
- "Aileen",
- "Aisha",
- "Akiko",
- "Akira",
- "Al",
- "Ali",
- "Alan",
- "Alana",
- "Albert",
- "Alberta",
- "Alec",
- "Alesia",
- "Alex",
- "Alexa",
- "Alexander",
- "Alexandra",
- "Alexis",
- "Alf",
- "Alfonso",
- "Alfred",
- "Alice",
- "Alicia",
- "Alison",
- "Alistair",
- "Allan",
- "Allen",
- "Allison",
- "Allister",
- "Alma",
- "Alvin",
- "Alyson",
- "Amanda",
- "Amber",
- "Amilio",
- "Amos",
- "Amy",
- "Ana",
- "Anabel",
- "Anastasia",
- "Andie",
- "Andrea",
- "Andres",
- "Andrew",
- "Andy",
- "Angel",
- "Angela",
- "Angelica",
- "Angie",
- "Angus",
- "Anika",
- "Ann",
- "Anna",
- "Anne",
- "Annette",
- "Annie",
- "Annika",
- "Anthony",
- "Anton",
- "Antonio",
- "April",
- "Archer",
- "Archie",
- "Arlene",
- "Arnie",
- "Arnold",
- "Art",
- "Arthur",
- "Asaf",
- "Ashley",
- "Astrid",
- "Aubrey",
- "Austin",
- "Austine",
- "Avon",
- "Avril",
- "Axel",
- "Aziz",
- "Bailey",
- "Barbara",
- "Barney",
- "Barry",
- "Bart",
- "Barton",
- "Baxter",
- "Beck",
- "Becket",
- "Becky",
- "Belinda",
- "Bella",
- "Belle",
- "Ben",
- "Benjamin",
- "Benny",
- "Bernadette",
- "Bernard",
- "Bernice",
- "Bess",
- "Beth",
- "Bethany",
- "Bette",
- "Betty",
- "Bernard",
- "Bernardette",
- "Bernice",
- "Berty",
- "Bev",
- "Beverly",
- "Beverley",
- "Bianca",
- "Bill",
- "Billie",
- "Billy",
- "Bjorn",
- "Blaire",
- "Blake",
- "Blanche",
- "Bo",
- "Bob",
- "Bobbie",
- "Bobby",
- "Bonnie",
- "Boris",
- "Brad",
- "Bradley",
- "Brady",
- "Brandi",
- "Brandon",
- "Brandy",
- "Brenda",
- "Brendan",
- "Brendon",
- "Brent",
- "Brett",
- "Brian",
- "Bridgit",
- "Brigitte",
- "Britney",
- "Bruce",
- "Bruno",
- "Brutus",
- "Bryan",
- "Buck",
- "Bucky",
- "Bug",
- "Burton",
- "Byron",
- "Cailin",
- "Caitlyn",
- "Cal",
- "Caley",
- "Callum",
- "Calvin",
- "Cameron",
- "Camille",
- "Campbell",
- "Candy",
- "Carl",
- "Carla",
- "Carlene",
- "Carlos",
- "Carmela",
- "Carmen",
- "Carol",
- "Carole",
- "Caroline",
- "Carolyn",
- "Carrie",
- "Casey",
- "Cassandra",
- "Cassey",
- "Cassie",
- "Catherina",
- "Catherine",
- "Cathy",
- "Caz",
- "Cecelia",
- "Cecil",
- "Cecille",
- "Ceilidh",
- "Celeste",
- "Chad",
- "Charlene",
- "Charles",
- "Charlie",
- "Charlotte",
- "Chelsea",
- "Cher",
- "Cheri",
- "Cheryll",
- "Chip",
- "Chloe",
- "Chris",
- "Christel",
- "Christian",
- "Christie",
- "Christina",
- "Christine",
- "Christopher",
- "Chuck",
- "Cindy",
- "Clark",
- "Clair",
- "Claire",
- "Clara",
- "Clarabell",
- "Claude",
- "Claudette",
- "Claudia",
- "Clayton",
- "Cliff",
- "Clifford",
- "Clint",
- "Clive",
- "Clyde",
- "Codey",
- "Cody",
- "Colin",
- "Colleen",
- "Connie",
- "Coral",
- "Corina",
- "Craig",
- "Curtis",
- "Cynthia",
- "Cyril",
- "Darby",
- "Daisy",
- "Dale",
- "Damien",
- "Damon",
- "Dan",
- "Dana",
- "Daniel",
- "Danielle",
- "Danni",
- "Danny",
- "Daphne",
- "Darla",
- "Darlene",
- "Darrell",
- "Darren",
- "Darryl",
- "Dave",
- "David",
- "Davie",
- "Davis",
- "Dawn",
- "Dean",
- "Debbie",
- "Debby",
- "Deborah",
- "Debra",
- "Debs",
- "Deidre",
- "Delores",
- "Denise",
- "Dennis",
- "Denzel",
- "Derek",
- "Desmond",
- "Diana",
- "Diane",
- "Dianna",
- "Dick",
- "Dillon",
- "Dina",
- "Dominic",
- "Dominik",
- "Don",
- "Donald",
- "Donna",
- "Donovan",
- "Doreen",
- "Doris",
- "Dorothy",
- "Doug",
- "Dougal",
- "Douglas",
- "Doyle",
- "Drew",
- "Duane",
- "Dudley",
- "Duncan",
- "Dwight",
- "Dylan",
- "Earl",
- "Ed",
- "Eddie",
- "Edgar",
- "Edith",
- "Edmond",
- "Edward",
- "Edwin",
- "Edwina",
- "Eileen",
- "Elaine",
- "Elina",
- "Elisa",
- "Elisabeth",
- "Eliza",
- "Elizabeth",
- "Ella",
- "Ellen",
- "Elmer",
- "Elsie",
- "Emile",
- "Emilio",
- "Emily",
- "Emma",
- "Emmett",
- "Enrique",
- "Eric",
- "Erica",
- "Ericka",
- "Erik",
- "Erika",
- "Erin",
- "Erinn",
- "Ernest",
- "Esmeralda",
- "Esta",
- "Estella",
- "Esther",
- "Ethan",
- "Eugene",
- "Eva",
- "Evan",
- "Eve",
- "Evelyn",
- "Everett",
- "Felix",
- "Fabio",
- "Falicia",
- "Farah",
- "Felicity",
- "Fernando",
- "Fergus",
- "Fidelia",
- "Finlay",
- "Fiona",
- "Fletcher",
- "Flora",
- "Florence",
- "Floyd",
- "Fly",
- "Frances",
- "Francesca",
- "Francis",
- "Francisco",
- "Frank",
- "Franklin",
- "Franky",
- "Fraser",
- "Fred",
- "Freda",
- "Freddy",
- "Fuzz",
- "Gabriel",
- "Gabriela",
- "Gail",
- "Garrett",
- "Garth",
- "Gary",
- "Gavin",
- "Gayle",
- "Gene",
- "Genevieve",
- "Geoff",
- "Geoffrey",
- "George",
- "Gerald",
- "Geraldine",
- "Gerard",
- "Geri",
- "Gerry",
- "Gilbert",
- "Gillian",
- "Gina",
- "Ginger",
- "Giuseppe",
- "Gladys",
- "Glen",
- "Glenda",
- "Glenn",
- "Gloria",
- "Glyne",
- "Goldie",
- "Gordon",
- "Grace",
- "Graeme",
- "Graham",
- "Grant",
- "Grayson",
- "Greg",
- "Gregor",
- "Gregory",
- "Gretchen",
- "Gus",
- "Guy",
- "Gwen",
- "Gwendoline",
- "Hadrian",
- "Hamish",
- "Hank",
- "Hannah",
- "Hans",
- "Harley",
- "Harold",
- "Harry",
- "Harvey",
- "Haseem",
- "Hayley",
- "Hazel",
- "Heather",
- "Hector",
- "Heidi",
- "Helen",
- "Helena",
- "Henri",
- "Henry",
- "Herbert",
- "Herbie",
- "Hermann",
- "Hilda",
- "Hollie",
- "Holly",
- "Homer",
- "Horace",
- "Howard",
- "Hugh",
- "Hugo",
- "Iain",
- "Ian",
- "Imani",
- "Imelda",
- "Imran",
- "Ingrid",
- "Irene",
- "Irma",
- "Irving",
- "Isaac",
- "Isabella",
- "Isabelle",
- "Ishan",
- "Isla",
- "Ivan",
- "Ivanna",
- "Ivy",
- "Izola",
- "Jack",
- "Jacque",
- "Jacqueline",
- "Jacqui",
- "Jake",
- "Jakob",
- "James",
- "Jacob",
- "Jan",
- "Janet",
- "Jane",
- "Janice",
- "Jason",
- "Jasper",
- "Jay",
- "Jayne",
- "Jean",
- "Jeanette",
- "Jeff",
- "Jeffrey",
- "Jennifer",
- "Jenny",
- "Jeremy",
- "Jerry",
- "Jesse",
- "Jessica",
- "Jessie",
- "Jessy",
- "Jill",
- "Jillian",
- "Jim",
- "Jimbo",
- "Jimmy",
- "Jo",
- "Joan",
- "Joann",
- "Joanne",
- "Jock",
- "Jodi",
- "Joe",
- "Joel",
- "Joelyn",
- "Joey",
- "Johan",
- "John",
- "Johnathan",
- "Johnnie",
- "Johnny",
- "Jolynn",
- "Jon",
- "Jonah",
- "Jonas",
- "Jonathan",
- "Joni",
- "Jonny",
- "Jordan",
- "Jorge",
- "Jose",
- "Joseph",
- "Josephine",
- "Josh",
- "Joshua",
- "Joyce",
- "Juan",
- "Juana",
- "Juanita",
- "Judge",
- "Judie",
- "Judith",
- "Judy",
- "Julia",
- "Julian",
- "Julie",
- "Juliette",
- "Julio",
- "Julius",
- "June",
- "Justin",
- "Kaley",
- "Kaitlyn",
- "Kandice",
- "Kara",
- "Kareen",
- "Karen",
- "Karl",
- "Karolyne",
- "Karri",
- "Kate",
- "Katelyn",
- "Katey",
- "Kathy",
- "Katherine",
- "Kathie",
- "Kathleen",
- "Kathryn",
- "Katie",
- "Katrina",
- "Katy",
- "Katya",
- "Kay",
- "Keiko",
- "Keith",
- "Kelly",
- "Kelsey",
- "Ken",
- "Kenneth",
- "Kenny",
- "Kerry",
- "Kev",
- "Kevin",
- "Kieran",
- "Kim",
- "Kimberly",
- "Kiriaki",
- "Kirk",
- "Klaus",
- "Kris",
- "Krista",
- "Kristian",
- "Kristy",
- "Kurt",
- "Kurtis",
- "Kyle",
- "Kylie",
- "Laila",
- "Lana",
- "Lance",
- "Larry",
- "Lasse",
- "Latisha",
- "Laura",
- "Lauren",
- "Lauryn",
- "Laurie",
- "Lawrence",
- "Leah",
- "Lee",
- "Leigh",
- "Len",
- "Lena",
- "Lenore",
- "Leo",
- "Leon",
- "Leonard",
- "Leonardo",
- "Leone",
- "Leroy",
- "Les",
- "Leslie",
- "Lesley",
- "Lester",
- "Lewis",
- "Liam",
- "Lillian",
- "Lilly",
- "Lily",
- "Linda",
- "Lindsay",
- "Lindsey",
- "Lisa",
- "Lita",
- "Logan",
- "Lone",
- "Loren",
- "Loretta",
- "Lori",
- "Lorraine",
- "Lottie",
- "Louis",
- "Louise",
- "Lowell",
- "Lucas",
- "Lucy",
- "Luis",
- "Luke",
- "Luther",
- "Lydia",
- "Lynn",
- "Lynne",
- "Lyssa",
- "Mabel",
- "Madeline",
- "Maggie",
- "Magnus",
- "Mahamed",
- "Malcolm",
- "Mandy",
- "Manuel",
- "Marc",
- "Marcela",
- "Marci",
- "Marcia",
- "Marco",
- "Marcus",
- "Marcy",
- "Margaret",
- "Margarita",
- "Maria",
- "Mariah",
- "Marian",
- "Marianna",
- "Marie",
- "Marilyn",
- "Marina",
- "Marion",
- "Marisa",
- "Marissa",
- "Marjorie",
- "Mark",
- "Markus",
- "Marlene",
- "Marlin",
- "Marlon",
- "Marshall",
- "Martha",
- "Martin",
- "Martyn",
- "Marvin",
- "Mary",
- "Mathew",
- "Matt",
- "Matthew",
- "Maude",
- "Maureen",
- "Maurice",
- "Mauricio",
- "Mavis",
- "Max",
- "Maxine",
- "May",
- "Megan",
- "Meghan",
- "Mel",
- "Melanie",
- "Melany",
- "Melinda",
- "Melissa",
- "Melody",
- "Melvin",
- "Mervin",
- "Mhairi",
- "Mia",
- "Michael",
- "Michelle",
- "Mick",
- "Mickey",
- "Miguel",
- "Mikael",
- "Mike",
- "Mikey",
- "Miki",
- "Mikko",
- "Mildred",
- "Millie",
- "Milly",
- "Milton",
- "Miranda",
- "Miriam",
- "Mirriam",
- "Mitchell",
- "Mo",
- "Molly",
- "Monica",
- "Monique",
- "Monty",
- "Morgan",
- "Morten",
- "Moses",
- "Morris",
- "Muriel",
- "Murphy",
- "Murray",
- "Mustafa",
- "Myles",
- "Myrissa",
- "Myrtle",
- "Nadine",
- "Nancy",
- "Nanette",
- "Naomi",
- "Natalia",
- "Natalie",
- "Natasha",
- "Nathan",
- "Nathaniel",
- "Neil",
- "Nellie",
- "Nelly",
- "Nelson",
- "Neville",
- "Nicholas",
- "Nichole",
- "Nick",
- "Nico",
- "Nicola",
- "Nicolas",
- "Nicole",
- "Nigel",
- "Nikia",
- "Nikki",
- "Nina",
- "Noah",
- "Noel",
- "Norma",
- "Norman",
- "Norris",
- "Norvall",
- "Olga",
- "Olive",
- "Oliver",
- "Ollie",
- "Omar",
- "Oona",
- "Orve",
- "Orville",
- "Oscar",
- "Otto",
- "Owen",
- "Paisley",
- "Pam",
- "Pamela",
- "Pandora",
- "Pat",
- "Patricia",
- "Patrick",
- "Patty",
- "Paul",
- "Paula",
- "Pauline",
- "Pedro",
- "Peggy",
- "Penelope",
- "Penny",
- "Perry",
- "Pete",
- "Peter",
- "Phil",
- "Philip",
- "Phillip",
- "Phyllis",
- "Polly",
- "Preston",
- "Qasim",
- "Quentin",
- "Quinn",
- "Rachel",
- "Rae",
- "Rafael",
- "Raj",
- "Raja",
- "Ralph",
- "Ramon",
- "Randal",
- "Rashid",
- "Raquel",
- "Raul",
- "Ray",
- "Raymond",
- "Raymondo",
- "Rebecca",
- "Reg",
- "Regina",
- "Reginald",
- "Reinhold",
- "Rene",
- "Reuben",
- "Rex",
- "Rhonda",
- "Richard",
- "Rick",
- "Ricky",
- "Rita",
- "Robb",
- "Robert",
- "Roberta",
- "Robin",
- "Robina",
- "Robyn",
- "Robynne",
- "Rock",
- "Rockie",
- "Rod",
- "Rodney",
- "Rodrigo",
- "Roland",
- "Rolf",
- "Romeo",
- "Ronald",
- "Ronan",
- "Ronnie",
- "Roger",
- "Rosalind",
- "Rosanna",
- "Rosanned",
- "Rose",
- "Rosemary",
- "Rosetta",
- "Rosie",
- "Ross",
- "Roxanne",
- "Roy",
- "Russell",
- "Rosty",
- "Ruben",
- "Ruby",
- "Ruth",
- "Ryan",
- "Sabrina",
- "Sadie",
- "Sally",
- "Sam",
- "Samantha",
- "Sammy",
- "Samuel",
- "Sandra",
- "Sandy",
- "Sara",
- "Sarah",
- "Sasha",
- "Saul",
- "Scot",
- "Scott",
- "Sean",
- "Sebastian",
- "Sergio",
- "Shakira",
- "Shannon",
- "Shari",
- "Sharnell",
- "Sharon",
- "Sharyn",
- "Shawn",
- "Shelby",
- "Shelley",
- "Sherene",
- "Sheri",
- "Sherman",
- "Sherry",
- "Shirley",
- "Sheryl",
- "Shivani",
- "Shona",
- "Sian",
- "Sid",
- "Sidney",
- "Simon",
- "Sindy",
- "Sinead",
- "Sofia",
- "Sonny",
- "Sonja",
- "Sonya",
- "Sophia",
- "Sophie",
- "Spencer",
- "Stacey",
- "Stan",
- "Stanley",
- "Stefan",
- "Stephen",
- "Stephanie",
- "Steve",
- "Steven",
- "Stewart",
- "Stuart",
- "Sue",
- "Suki",
- "Susan",
- "Susana",
- "Susanne",
- "Susie",
- "Suzanne",
- "Sven",
- "Sylvester",
- "Sylvia",
- "Tabatha",
- "Tamara",
- "Tammie",
- "Tamsin",
- "Tania",
- "Tanya",
- "Tara",
- "Taylor",
- "Ted",
- "Teresa",
- "Terrance",
- "Terry",
- "Tess",
- "Tessa",
- "Tex",
- "Thelma",
- "Theodore",
- "Theresa",
- "Thomas",
- "Tiffany",
- "Tiger",
- "Tiko",
- "Tillie",
- "Tim",
- "Timmy",
- "Timothy",
- "Tina",
- "Toby",
- "Todd",
- "Tom",
- "Tomaki",
- "Tommy",
- "Tonia",
- "Tonie",
- "Tony",
- "Tracy",
- "Travis",
- "Trevor",
- "Tricia",
- "Trixie",
- "Troy",
- "Tucker",
- "Tyler",
- "Tyson",
- "Ulysses",
- "Uri",
- "Val",
- "Valerie",
- "Vanessa",
- "Vani",
- "Vaughn",
- "Velma",
- "Vernon",
- "Veronica",
- "Vicki",
- "Vicky",
- "Victor",
- "Victoria",
- "Vijay",
- "Vince",
- "Vincent",
- "Vinnie",
- "Virginia",
- "Viv",
- "Vivian",
- "Viviene",
- "Wally",
- "Walt",
- "Walter",
- "Walton",
- "Wanda",
- "Warren",
- "Wayne",
- "Wendell",
- "Wendy",
- "Wes",
- "Wesley",
- "Whitney",
- "Will",
- "William",
- "Willie",
- "Willis",
- "Wilson",
- "Winston",
- "Wyatt",
- "Xavier",
- "Yasmin",
- "Yogi",
- "Ysabel",
- "Yvonne",
- "Zachary",
- "Zachery",
- "Zola"
-};
-
-#pragma endregion
-
-char real_name_initials[] = {
- 'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'W'
-};
+#include "localisation.h"
#pragma region Format codes
diff --git a/src/localisation/localisation.h b/src/localisation/localisation.h
new file mode 100644
index 0000000000..af25310d7b
--- /dev/null
+++ b/src/localisation/localisation.h
@@ -0,0 +1,39 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Ted John
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of OpenRCT2.
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
+#ifndef LOCALISATION_H
+#define LOCALISATION_H
+
+#include "currency.h"
+#include "format_codes.h"
+#include "language.h"
+#include "string_ids.h"
+
+void format_string(char *dest, rct_string_id format, void *args);
+void generate_string_file();
+void reset_saved_strings();
+void error_string_quit(int error, rct_string_id format);
+int get_string_length(char* buffer);
+
+// Real name data
+extern const char real_name_initials[];
+extern const char *real_names[];
+
+#endif
diff --git a/src/localisation/real_names.c b/src/localisation/real_names.c
new file mode 100644
index 0000000000..0c1c8c1eef
--- /dev/null
+++ b/src/localisation/real_names.c
@@ -0,0 +1,1052 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Ted John
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of OpenRCT2.
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
+#include "localisation.h"
+
+const char real_name_initials[] = {
+ 'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'W'
+};
+
+const char *real_names[] = {
+ "Aaron",
+ "Abdul",
+ "Abraham",
+ "Abu",
+ "Adam",
+ "Adrian",
+ "Adriane",
+ "Aileen",
+ "Aisha",
+ "Akiko",
+ "Akira",
+ "Al",
+ "Ali",
+ "Alan",
+ "Alana",
+ "Albert",
+ "Alberta",
+ "Alec",
+ "Alesia",
+ "Alex",
+ "Alexa",
+ "Alexander",
+ "Alexandra",
+ "Alexis",
+ "Alf",
+ "Alfonso",
+ "Alfred",
+ "Alice",
+ "Alicia",
+ "Alison",
+ "Alistair",
+ "Allan",
+ "Allen",
+ "Allison",
+ "Allister",
+ "Alma",
+ "Alvin",
+ "Alyson",
+ "Amanda",
+ "Amber",
+ "Amilio",
+ "Amos",
+ "Amy",
+ "Ana",
+ "Anabel",
+ "Anastasia",
+ "Andie",
+ "Andrea",
+ "Andres",
+ "Andrew",
+ "Andy",
+ "Angel",
+ "Angela",
+ "Angelica",
+ "Angie",
+ "Angus",
+ "Anika",
+ "Ann",
+ "Anna",
+ "Anne",
+ "Annette",
+ "Annie",
+ "Annika",
+ "Anthony",
+ "Anton",
+ "Antonio",
+ "April",
+ "Archer",
+ "Archie",
+ "Arlene",
+ "Arnie",
+ "Arnold",
+ "Art",
+ "Arthur",
+ "Asaf",
+ "Ashley",
+ "Astrid",
+ "Aubrey",
+ "Austin",
+ "Austine",
+ "Avon",
+ "Avril",
+ "Axel",
+ "Aziz",
+ "Bailey",
+ "Barbara",
+ "Barney",
+ "Barry",
+ "Bart",
+ "Barton",
+ "Baxter",
+ "Beck",
+ "Becket",
+ "Becky",
+ "Belinda",
+ "Bella",
+ "Belle",
+ "Ben",
+ "Benjamin",
+ "Benny",
+ "Bernadette",
+ "Bernard",
+ "Bernice",
+ "Bess",
+ "Beth",
+ "Bethany",
+ "Bette",
+ "Betty",
+ "Bernard",
+ "Bernardette",
+ "Bernice",
+ "Berty",
+ "Bev",
+ "Beverly",
+ "Beverley",
+ "Bianca",
+ "Bill",
+ "Billie",
+ "Billy",
+ "Bjorn",
+ "Blaire",
+ "Blake",
+ "Blanche",
+ "Bo",
+ "Bob",
+ "Bobbie",
+ "Bobby",
+ "Bonnie",
+ "Boris",
+ "Brad",
+ "Bradley",
+ "Brady",
+ "Brandi",
+ "Brandon",
+ "Brandy",
+ "Brenda",
+ "Brendan",
+ "Brendon",
+ "Brent",
+ "Brett",
+ "Brian",
+ "Bridgit",
+ "Brigitte",
+ "Britney",
+ "Bruce",
+ "Bruno",
+ "Brutus",
+ "Bryan",
+ "Buck",
+ "Bucky",
+ "Bug",
+ "Burton",
+ "Byron",
+ "Cailin",
+ "Caitlyn",
+ "Cal",
+ "Caley",
+ "Callum",
+ "Calvin",
+ "Cameron",
+ "Camille",
+ "Campbell",
+ "Candy",
+ "Carl",
+ "Carla",
+ "Carlene",
+ "Carlos",
+ "Carmela",
+ "Carmen",
+ "Carol",
+ "Carole",
+ "Caroline",
+ "Carolyn",
+ "Carrie",
+ "Casey",
+ "Cassandra",
+ "Cassey",
+ "Cassie",
+ "Catherina",
+ "Catherine",
+ "Cathy",
+ "Caz",
+ "Cecelia",
+ "Cecil",
+ "Cecille",
+ "Ceilidh",
+ "Celeste",
+ "Chad",
+ "Charlene",
+ "Charles",
+ "Charlie",
+ "Charlotte",
+ "Chelsea",
+ "Cher",
+ "Cheri",
+ "Cheryll",
+ "Chip",
+ "Chloe",
+ "Chris",
+ "Christel",
+ "Christian",
+ "Christie",
+ "Christina",
+ "Christine",
+ "Christopher",
+ "Chuck",
+ "Cindy",
+ "Clark",
+ "Clair",
+ "Claire",
+ "Clara",
+ "Clarabell",
+ "Claude",
+ "Claudette",
+ "Claudia",
+ "Clayton",
+ "Cliff",
+ "Clifford",
+ "Clint",
+ "Clive",
+ "Clyde",
+ "Codey",
+ "Cody",
+ "Colin",
+ "Colleen",
+ "Connie",
+ "Coral",
+ "Corina",
+ "Craig",
+ "Curtis",
+ "Cynthia",
+ "Cyril",
+ "Darby",
+ "Daisy",
+ "Dale",
+ "Damien",
+ "Damon",
+ "Dan",
+ "Dana",
+ "Daniel",
+ "Danielle",
+ "Danni",
+ "Danny",
+ "Daphne",
+ "Darla",
+ "Darlene",
+ "Darrell",
+ "Darren",
+ "Darryl",
+ "Dave",
+ "David",
+ "Davie",
+ "Davis",
+ "Dawn",
+ "Dean",
+ "Debbie",
+ "Debby",
+ "Deborah",
+ "Debra",
+ "Debs",
+ "Deidre",
+ "Delores",
+ "Denise",
+ "Dennis",
+ "Denzel",
+ "Derek",
+ "Desmond",
+ "Diana",
+ "Diane",
+ "Dianna",
+ "Dick",
+ "Dillon",
+ "Dina",
+ "Dominic",
+ "Dominik",
+ "Don",
+ "Donald",
+ "Donna",
+ "Donovan",
+ "Doreen",
+ "Doris",
+ "Dorothy",
+ "Doug",
+ "Dougal",
+ "Douglas",
+ "Doyle",
+ "Drew",
+ "Duane",
+ "Dudley",
+ "Duncan",
+ "Dwight",
+ "Dylan",
+ "Earl",
+ "Ed",
+ "Eddie",
+ "Edgar",
+ "Edith",
+ "Edmond",
+ "Edward",
+ "Edwin",
+ "Edwina",
+ "Eileen",
+ "Elaine",
+ "Elina",
+ "Elisa",
+ "Elisabeth",
+ "Eliza",
+ "Elizabeth",
+ "Ella",
+ "Ellen",
+ "Elmer",
+ "Elsie",
+ "Emile",
+ "Emilio",
+ "Emily",
+ "Emma",
+ "Emmett",
+ "Enrique",
+ "Eric",
+ "Erica",
+ "Ericka",
+ "Erik",
+ "Erika",
+ "Erin",
+ "Erinn",
+ "Ernest",
+ "Esmeralda",
+ "Esta",
+ "Estella",
+ "Esther",
+ "Ethan",
+ "Eugene",
+ "Eva",
+ "Evan",
+ "Eve",
+ "Evelyn",
+ "Everett",
+ "Felix",
+ "Fabio",
+ "Falicia",
+ "Farah",
+ "Felicity",
+ "Fernando",
+ "Fergus",
+ "Fidelia",
+ "Finlay",
+ "Fiona",
+ "Fletcher",
+ "Flora",
+ "Florence",
+ "Floyd",
+ "Fly",
+ "Frances",
+ "Francesca",
+ "Francis",
+ "Francisco",
+ "Frank",
+ "Franklin",
+ "Franky",
+ "Fraser",
+ "Fred",
+ "Freda",
+ "Freddy",
+ "Fuzz",
+ "Gabriel",
+ "Gabriela",
+ "Gail",
+ "Garrett",
+ "Garth",
+ "Gary",
+ "Gavin",
+ "Gayle",
+ "Gene",
+ "Genevieve",
+ "Geoff",
+ "Geoffrey",
+ "George",
+ "Gerald",
+ "Geraldine",
+ "Gerard",
+ "Geri",
+ "Gerry",
+ "Gilbert",
+ "Gillian",
+ "Gina",
+ "Ginger",
+ "Giuseppe",
+ "Gladys",
+ "Glen",
+ "Glenda",
+ "Glenn",
+ "Gloria",
+ "Glyne",
+ "Goldie",
+ "Gordon",
+ "Grace",
+ "Graeme",
+ "Graham",
+ "Grant",
+ "Grayson",
+ "Greg",
+ "Gregor",
+ "Gregory",
+ "Gretchen",
+ "Gus",
+ "Guy",
+ "Gwen",
+ "Gwendoline",
+ "Hadrian",
+ "Hamish",
+ "Hank",
+ "Hannah",
+ "Hans",
+ "Harley",
+ "Harold",
+ "Harry",
+ "Harvey",
+ "Haseem",
+ "Hayley",
+ "Hazel",
+ "Heather",
+ "Hector",
+ "Heidi",
+ "Helen",
+ "Helena",
+ "Henri",
+ "Henry",
+ "Herbert",
+ "Herbie",
+ "Hermann",
+ "Hilda",
+ "Hollie",
+ "Holly",
+ "Homer",
+ "Horace",
+ "Howard",
+ "Hugh",
+ "Hugo",
+ "Iain",
+ "Ian",
+ "Imani",
+ "Imelda",
+ "Imran",
+ "Ingrid",
+ "Irene",
+ "Irma",
+ "Irving",
+ "Isaac",
+ "Isabella",
+ "Isabelle",
+ "Ishan",
+ "Isla",
+ "Ivan",
+ "Ivanna",
+ "Ivy",
+ "Izola",
+ "Jack",
+ "Jacque",
+ "Jacqueline",
+ "Jacqui",
+ "Jake",
+ "Jakob",
+ "James",
+ "Jacob",
+ "Jan",
+ "Janet",
+ "Jane",
+ "Janice",
+ "Jason",
+ "Jasper",
+ "Jay",
+ "Jayne",
+ "Jean",
+ "Jeanette",
+ "Jeff",
+ "Jeffrey",
+ "Jennifer",
+ "Jenny",
+ "Jeremy",
+ "Jerry",
+ "Jesse",
+ "Jessica",
+ "Jessie",
+ "Jessy",
+ "Jill",
+ "Jillian",
+ "Jim",
+ "Jimbo",
+ "Jimmy",
+ "Jo",
+ "Joan",
+ "Joann",
+ "Joanne",
+ "Jock",
+ "Jodi",
+ "Joe",
+ "Joel",
+ "Joelyn",
+ "Joey",
+ "Johan",
+ "John",
+ "Johnathan",
+ "Johnnie",
+ "Johnny",
+ "Jolynn",
+ "Jon",
+ "Jonah",
+ "Jonas",
+ "Jonathan",
+ "Joni",
+ "Jonny",
+ "Jordan",
+ "Jorge",
+ "Jose",
+ "Joseph",
+ "Josephine",
+ "Josh",
+ "Joshua",
+ "Joyce",
+ "Juan",
+ "Juana",
+ "Juanita",
+ "Judge",
+ "Judie",
+ "Judith",
+ "Judy",
+ "Julia",
+ "Julian",
+ "Julie",
+ "Juliette",
+ "Julio",
+ "Julius",
+ "June",
+ "Justin",
+ "Kaley",
+ "Kaitlyn",
+ "Kandice",
+ "Kara",
+ "Kareen",
+ "Karen",
+ "Karl",
+ "Karolyne",
+ "Karri",
+ "Kate",
+ "Katelyn",
+ "Katey",
+ "Kathy",
+ "Katherine",
+ "Kathie",
+ "Kathleen",
+ "Kathryn",
+ "Katie",
+ "Katrina",
+ "Katy",
+ "Katya",
+ "Kay",
+ "Keiko",
+ "Keith",
+ "Kelly",
+ "Kelsey",
+ "Ken",
+ "Kenneth",
+ "Kenny",
+ "Kerry",
+ "Kev",
+ "Kevin",
+ "Kieran",
+ "Kim",
+ "Kimberly",
+ "Kiriaki",
+ "Kirk",
+ "Klaus",
+ "Kris",
+ "Krista",
+ "Kristian",
+ "Kristy",
+ "Kurt",
+ "Kurtis",
+ "Kyle",
+ "Kylie",
+ "Laila",
+ "Lana",
+ "Lance",
+ "Larry",
+ "Lasse",
+ "Latisha",
+ "Laura",
+ "Lauren",
+ "Lauryn",
+ "Laurie",
+ "Lawrence",
+ "Leah",
+ "Lee",
+ "Leigh",
+ "Len",
+ "Lena",
+ "Lenore",
+ "Leo",
+ "Leon",
+ "Leonard",
+ "Leonardo",
+ "Leone",
+ "Leroy",
+ "Les",
+ "Leslie",
+ "Lesley",
+ "Lester",
+ "Lewis",
+ "Liam",
+ "Lillian",
+ "Lilly",
+ "Lily",
+ "Linda",
+ "Lindsay",
+ "Lindsey",
+ "Lisa",
+ "Lita",
+ "Logan",
+ "Lone",
+ "Loren",
+ "Loretta",
+ "Lori",
+ "Lorraine",
+ "Lottie",
+ "Louis",
+ "Louise",
+ "Lowell",
+ "Lucas",
+ "Lucy",
+ "Luis",
+ "Luke",
+ "Luther",
+ "Lydia",
+ "Lynn",
+ "Lynne",
+ "Lyssa",
+ "Mabel",
+ "Madeline",
+ "Maggie",
+ "Magnus",
+ "Mahamed",
+ "Malcolm",
+ "Mandy",
+ "Manuel",
+ "Marc",
+ "Marcela",
+ "Marci",
+ "Marcia",
+ "Marco",
+ "Marcus",
+ "Marcy",
+ "Margaret",
+ "Margarita",
+ "Maria",
+ "Mariah",
+ "Marian",
+ "Marianna",
+ "Marie",
+ "Marilyn",
+ "Marina",
+ "Marion",
+ "Marisa",
+ "Marissa",
+ "Marjorie",
+ "Mark",
+ "Markus",
+ "Marlene",
+ "Marlin",
+ "Marlon",
+ "Marshall",
+ "Martha",
+ "Martin",
+ "Martyn",
+ "Marvin",
+ "Mary",
+ "Mathew",
+ "Matt",
+ "Matthew",
+ "Maude",
+ "Maureen",
+ "Maurice",
+ "Mauricio",
+ "Mavis",
+ "Max",
+ "Maxine",
+ "May",
+ "Megan",
+ "Meghan",
+ "Mel",
+ "Melanie",
+ "Melany",
+ "Melinda",
+ "Melissa",
+ "Melody",
+ "Melvin",
+ "Mervin",
+ "Mhairi",
+ "Mia",
+ "Michael",
+ "Michelle",
+ "Mick",
+ "Mickey",
+ "Miguel",
+ "Mikael",
+ "Mike",
+ "Mikey",
+ "Miki",
+ "Mikko",
+ "Mildred",
+ "Millie",
+ "Milly",
+ "Milton",
+ "Miranda",
+ "Miriam",
+ "Mirriam",
+ "Mitchell",
+ "Mo",
+ "Molly",
+ "Monica",
+ "Monique",
+ "Monty",
+ "Morgan",
+ "Morten",
+ "Moses",
+ "Morris",
+ "Muriel",
+ "Murphy",
+ "Murray",
+ "Mustafa",
+ "Myles",
+ "Myrissa",
+ "Myrtle",
+ "Nadine",
+ "Nancy",
+ "Nanette",
+ "Naomi",
+ "Natalia",
+ "Natalie",
+ "Natasha",
+ "Nathan",
+ "Nathaniel",
+ "Neil",
+ "Nellie",
+ "Nelly",
+ "Nelson",
+ "Neville",
+ "Nicholas",
+ "Nichole",
+ "Nick",
+ "Nico",
+ "Nicola",
+ "Nicolas",
+ "Nicole",
+ "Nigel",
+ "Nikia",
+ "Nikki",
+ "Nina",
+ "Noah",
+ "Noel",
+ "Norma",
+ "Norman",
+ "Norris",
+ "Norvall",
+ "Olga",
+ "Olive",
+ "Oliver",
+ "Ollie",
+ "Omar",
+ "Oona",
+ "Orve",
+ "Orville",
+ "Oscar",
+ "Otto",
+ "Owen",
+ "Paisley",
+ "Pam",
+ "Pamela",
+ "Pandora",
+ "Pat",
+ "Patricia",
+ "Patrick",
+ "Patty",
+ "Paul",
+ "Paula",
+ "Pauline",
+ "Pedro",
+ "Peggy",
+ "Penelope",
+ "Penny",
+ "Perry",
+ "Pete",
+ "Peter",
+ "Phil",
+ "Philip",
+ "Phillip",
+ "Phyllis",
+ "Polly",
+ "Preston",
+ "Qasim",
+ "Quentin",
+ "Quinn",
+ "Rachel",
+ "Rae",
+ "Rafael",
+ "Raj",
+ "Raja",
+ "Ralph",
+ "Ramon",
+ "Randal",
+ "Rashid",
+ "Raquel",
+ "Raul",
+ "Ray",
+ "Raymond",
+ "Raymondo",
+ "Rebecca",
+ "Reg",
+ "Regina",
+ "Reginald",
+ "Reinhold",
+ "Rene",
+ "Reuben",
+ "Rex",
+ "Rhonda",
+ "Richard",
+ "Rick",
+ "Ricky",
+ "Rita",
+ "Robb",
+ "Robert",
+ "Roberta",
+ "Robin",
+ "Robina",
+ "Robyn",
+ "Robynne",
+ "Rock",
+ "Rockie",
+ "Rod",
+ "Rodney",
+ "Rodrigo",
+ "Roland",
+ "Rolf",
+ "Romeo",
+ "Ronald",
+ "Ronan",
+ "Ronnie",
+ "Roger",
+ "Rosalind",
+ "Rosanna",
+ "Rosanned",
+ "Rose",
+ "Rosemary",
+ "Rosetta",
+ "Rosie",
+ "Ross",
+ "Roxanne",
+ "Roy",
+ "Russell",
+ "Rosty",
+ "Ruben",
+ "Ruby",
+ "Ruth",
+ "Ryan",
+ "Sabrina",
+ "Sadie",
+ "Sally",
+ "Sam",
+ "Samantha",
+ "Sammy",
+ "Samuel",
+ "Sandra",
+ "Sandy",
+ "Sara",
+ "Sarah",
+ "Sasha",
+ "Saul",
+ "Scot",
+ "Scott",
+ "Sean",
+ "Sebastian",
+ "Sergio",
+ "Shakira",
+ "Shannon",
+ "Shari",
+ "Sharnell",
+ "Sharon",
+ "Sharyn",
+ "Shawn",
+ "Shelby",
+ "Shelley",
+ "Sherene",
+ "Sheri",
+ "Sherman",
+ "Sherry",
+ "Shirley",
+ "Sheryl",
+ "Shivani",
+ "Shona",
+ "Sian",
+ "Sid",
+ "Sidney",
+ "Simon",
+ "Sindy",
+ "Sinead",
+ "Sofia",
+ "Sonny",
+ "Sonja",
+ "Sonya",
+ "Sophia",
+ "Sophie",
+ "Spencer",
+ "Stacey",
+ "Stan",
+ "Stanley",
+ "Stefan",
+ "Stephen",
+ "Stephanie",
+ "Steve",
+ "Steven",
+ "Stewart",
+ "Stuart",
+ "Sue",
+ "Suki",
+ "Susan",
+ "Susana",
+ "Susanne",
+ "Susie",
+ "Suzanne",
+ "Sven",
+ "Sylvester",
+ "Sylvia",
+ "Tabatha",
+ "Tamara",
+ "Tammie",
+ "Tamsin",
+ "Tania",
+ "Tanya",
+ "Tara",
+ "Taylor",
+ "Ted",
+ "Teresa",
+ "Terrance",
+ "Terry",
+ "Tess",
+ "Tessa",
+ "Tex",
+ "Thelma",
+ "Theodore",
+ "Theresa",
+ "Thomas",
+ "Tiffany",
+ "Tiger",
+ "Tiko",
+ "Tillie",
+ "Tim",
+ "Timmy",
+ "Timothy",
+ "Tina",
+ "Toby",
+ "Todd",
+ "Tom",
+ "Tomaki",
+ "Tommy",
+ "Tonia",
+ "Tonie",
+ "Tony",
+ "Tracy",
+ "Travis",
+ "Trevor",
+ "Tricia",
+ "Trixie",
+ "Troy",
+ "Tucker",
+ "Tyler",
+ "Tyson",
+ "Ulysses",
+ "Uri",
+ "Val",
+ "Valerie",
+ "Vanessa",
+ "Vani",
+ "Vaughn",
+ "Velma",
+ "Vernon",
+ "Veronica",
+ "Vicki",
+ "Vicky",
+ "Victor",
+ "Victoria",
+ "Vijay",
+ "Vince",
+ "Vincent",
+ "Vinnie",
+ "Virginia",
+ "Viv",
+ "Vivian",
+ "Viviene",
+ "Wally",
+ "Walt",
+ "Walter",
+ "Walton",
+ "Wanda",
+ "Warren",
+ "Wayne",
+ "Wendell",
+ "Wendy",
+ "Wes",
+ "Wesley",
+ "Whitney",
+ "Will",
+ "William",
+ "Willie",
+ "Willis",
+ "Wilson",
+ "Winston",
+ "Wyatt",
+ "Xavier",
+ "Yasmin",
+ "Yogi",
+ "Ysabel",
+ "Yvonne",
+ "Zachary",
+ "Zachery",
+ "Zola"
+};
\ No newline at end of file
diff --git a/src/localisation/string_ids.h b/src/localisation/string_ids.h
index f4bd4f45bc..755918699f 100644
--- a/src/localisation/string_ids.h
+++ b/src/localisation/string_ids.h
@@ -21,117 +21,6 @@
#ifndef _STRING_IDS_H_
#define _STRING_IDS_H_
-typedef unsigned short rct_string_id;
-
-void format_string(char *dest, rct_string_id format, void *args);
-void generate_string_file();
-void reset_saved_strings();
-void error_string_quit(int error, rct_string_id format);
-
-char format_get_code(const char *token);
-const char *format_get_token(char code);
-int get_string_length(char* buffer);
-
-enum {
- // Font format codes
-
- // 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,
- FORMAT_COMMA16,
- FORMAT_UINT16,
- FORMAT_CURRENCY2DP,
- FORMAT_CURRENCY,
- FORMAT_STRINGID,
- FORMAT_STRINGID2,
- FORMAT_STRING,
- FORMAT_MONTHYEAR,
- FORMAT_MONTH,
- FORMAT_VELOCITY,
- FORMAT_POP16,
- FORMAT_PUSH16,
- FORMAT_DURATION,
- FORMAT_REALTIME,
- FORMAT_LENGTH,
- FORMAT_SPRITE,
-
- // Colour format codes
- FORMAT_COLOUR_CODE_START = 142,
- FORMAT_BLACK = 142,
- FORMAT_GREY,
- FORMAT_WHITE,
- FORMAT_RED,
- FORMAT_GREEN,
- FORMAT_YELLOW,
- FORMAT_TOPAZ,
- FORMAT_CELADON,
- FORMAT_BABYBLUE,
- FORMAT_PALELAVENDER,
- FORMAT_PALEGOLD,
- FORMAT_LIGHTPINK,
- FORMAT_PEARLAQUA,
- FORMAT_PALESILVER,
- FORMAT_COLOUR_CODE_END = FORMAT_PALESILVER,
-
- // Extra non-ascii characters
- FORMAT_AMINUSCULE = 159,
- FORMAT_UP,
- FORMAT_POUND = 163,
- FORMAT_YEN = 165,
- FORMAT_COPYRIGHT = 169,
- FORMAT_DOWN,
- FORMAT_LEFTGUILLEMET,
- FORMAT_TICK,
- FORMAT_CROSS,
- FORMAT_RIGHT = 175,
- FORMAT_DEGREE,
- FORMAT_SQUARED = 178,
- FORMAT_OPENQUOTES = 180,
- FORMAT_EURO = 181,
- FORMAT_APPROX = 184,
- FORMAT_POWERNEGATIVEONE,
- FORMAT_BULLET,
- FORMAT_RIGHTGUILLEMET,
- FORMAT_SMALLUP,
- FORMAT_SMALLDOWN,
- FORMAT_LEFT,
- FORMAT_INVERTEDQUESTION
-};
-
enum {
STR_NONE = -1,
diff --git a/src/management/award.c b/src/management/award.c
index 041efa7263..f7fb2466fc 100644
--- a/src/management/award.c
+++ b/src/management/award.c
@@ -18,14 +18,15 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
+#include "../addresses.h"
+#include "../interface/window.h"
+#include "../localisation/localisation.h"
+#include "../ride/ride.h"
+#include "../scenario.h"
+#include "../world/peep.h"
+#include "../world/sprite.h"
#include "award.h"
#include "news_item.h"
-#include "peep.h"
-#include "ride.h"
-#include "scenario.h"
-#include "sprite.h"
-#include "window.h"
#define NEGATIVE 0
#define POSITIVE 1
diff --git a/src/management/award.h b/src/management/award.h
index aba8cb9456..8e7c965f50 100644
--- a/src/management/award.h
+++ b/src/management/award.h
@@ -21,7 +21,7 @@
#ifndef _AWARD_H_
#define _AWARD_H_
-#include "rct2.h"
+#include "../common.h"
typedef struct {
uint16 time;
diff --git a/src/management/finance.c b/src/management/finance.c
index 447f4fb71b..fc95483950 100644
--- a/src/management/finance.c
+++ b/src/management/finance.c
@@ -18,13 +18,13 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
+#include "../addresses.h"
+#include "../interface/window.h"
+#include "../ride/ride.h"
+#include "../world/park.h"
+#include "../world/peep.h"
+#include "../world/sprite.h"
#include "finance.h"
-#include "sprite.h"
-#include "park.h"
-#include "peep.h"
-#include "ride.h"
-#include "window.h"
// Monthly staff wages
const money32 wage_table[4] = {
diff --git a/src/management/finance.h b/src/management/finance.h
index e839dd3914..f87998ab15 100644
--- a/src/management/finance.h
+++ b/src/management/finance.h
@@ -21,7 +21,7 @@
#ifndef _FINANCE_H_
#define _FINANCE_H_
-#include "rct2.h"
+#include "../common.h"
typedef int rct_expenditure_type;
diff --git a/src/management/marketing.c b/src/management/marketing.c
index c8a1f6e991..0a86b9ed95 100644
--- a/src/management/marketing.c
+++ b/src/management/marketing.c
@@ -18,13 +18,12 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
+#include "../addresses.h"
+#include "../interface/window.h"
+#include "../localisation/localisation.h"
+#include "../ride/ride.h"
#include "marketing.h"
#include "news_item.h"
-#include "rct2.h"
-#include "ride.h"
-#include "string_ids.h"
-#include "window.h"
const money16 AdvertisingCampaignPricePerWeek[] = {
MONEY(50,00), // PARK_ENTRY_FREE,
diff --git a/src/management/marketing.h b/src/management/marketing.h
index f94f27664d..6dc42a7b64 100644
--- a/src/management/marketing.h
+++ b/src/management/marketing.h
@@ -21,7 +21,8 @@
#ifndef _MARKETING_H_
#define _MARKETING_H_
-#include "peep.h"
+#include "../common.h"
+#include "../world/peep.h"
enum {
ADVERTISING_CAMPAIGN_PARK_ENTRY_FREE,
diff --git a/src/management/news_item.c b/src/management/news_item.c
index eccd51623d..fb20be1fd1 100644
--- a/src/management/news_item.c
+++ b/src/management/news_item.c
@@ -19,15 +19,14 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "audio.h"
-#include "date.h"
+#include "../addresses.h"
+#include "../audio/audio.h"
+#include "../interface/window.h"
+#include "../localisation/date.h"
+#include "../localisation/localisation.h"
+#include "../ride/ride.h"
+#include "../world/sprite.h"
#include "news_item.h"
-#include "rct2.h"
-#include "ride.h"
-#include "string_ids.h"
-#include "sprite.h"
-#include "window.h"
void window_game_bottom_toolbar_invalidate_news_item();
static int news_item_get_new_history_slot();
diff --git a/src/management/news_item.h b/src/management/news_item.h
index a089496741..8b48e61b6b 100644
--- a/src/management/news_item.h
+++ b/src/management/news_item.h
@@ -21,10 +21,7 @@
#ifndef _NEWS_ITEM_H_
#define _NEWS_ITEM_H_
-#include "rct2.h"
-#include "map.h"
-#include "string_ids.h"
-
+#include "../common.h"
enum {
NEWS_ITEM_NULL,
diff --git a/src/object.c b/src/object.c
index dae1f19074..a4644602f7 100644
--- a/src/object.c
+++ b/src/object.c
@@ -23,10 +23,10 @@
#include
#include
#include "addresses.h"
-#include "string_ids.h"
+#include "localisation/localisation.h"
#include "object.h"
-#include "osinterface.h"
-#include "sawyercoding.h"
+#include "platform/osinterface.h"
+#include "util/sawyercoding.h"
int object_entry_compare(rct_object_entry *a, rct_object_entry *b);
int object_calculate_checksum(rct_object_entry *entry, char *data, int dataLength);
diff --git a/src/object_list.c b/src/object_list.c
index 39f8a996cd..4ddcf45712 100644
--- a/src/object_list.c
+++ b/src/object_list.c
@@ -21,7 +21,7 @@
#include
#include "addresses.h"
#include "object.h"
-#include "sawyercoding.h"
+#include "util/sawyercoding.h"
#define OBJECT_ENTRY_GROUP_COUNT 11
#define OBJECT_ENTRY_COUNT 721
diff --git a/src/platform/osinterface.c b/src/platform/osinterface.c
index 59b5a887c0..2e2c53a927 100644
--- a/src/platform/osinterface.c
+++ b/src/platform/osinterface.c
@@ -25,15 +25,14 @@
#include
#include
-#include "addresses.h"
-#include "config.h"
-#include "gfx.h"
-#include "input.h"
+#include "../addresses.h"
+#include "../config.h"
+#include "../cursors.h"
+#include "../drawing/drawing.h"
+#include "../input.h"
+#include "../interface/screenshot.h"
+#include "../interface/window.h"
#include "osinterface.h"
-#include "screenshot.h"
-#include "window.h"
-#include "rct2.h"
-#include "cursors.h"
typedef void(*update_palette_func)(char*, int, int);
diff --git a/src/platform/osinterface.h b/src/platform/osinterface.h
index 7c08580483..be984b64d8 100644
--- a/src/platform/osinterface.h
+++ b/src/platform/osinterface.h
@@ -22,7 +22,7 @@
#define _SDL_INTERFACE_H_
#include
-#include "rct2.h"
+#include "../common.h"
enum {
CURSOR_UP = 0,
diff --git a/src/platform/osx.c b/src/platform/osx.c
new file mode 100644
index 0000000000..d16040f99d
--- /dev/null
+++ b/src/platform/osx.c
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Ted John
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of OpenRCT2.
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
+#ifdef __APPLE__
+
+/**
+ * OSX entry point to OpenRCT2.
+ */
+// int main(char *argv[], int argc)
+// {
+// return 0;
+// }
+
+char platform_get_path_separator()
+{
+ return '/';
+}
+
+#endif
\ No newline at end of file
diff --git a/src/platform/platform.h b/src/platform/platform.h
new file mode 100644
index 0000000000..88678c3ec8
--- /dev/null
+++ b/src/platform/platform.h
@@ -0,0 +1,30 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Ted John
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of OpenRCT2.
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
+#ifndef _PLATFORM_H_
+#define _PLATFORM_H_
+
+
+// Platform specific definitions
+char platform_get_path_separator();
+int platform_directory_exists(const char *path);
+int platform_ensure_directory_exists(const char *path);
+
+#endif
\ No newline at end of file
diff --git a/src/platform/shared.c b/src/platform/shared.c
new file mode 100644
index 0000000000..20a00a3bd2
--- /dev/null
+++ b/src/platform/shared.c
@@ -0,0 +1,20 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Ted John
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of OpenRCT2.
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
diff --git a/src/platform/unix.c b/src/platform/unix.c
new file mode 100644
index 0000000000..47aecde2d2
--- /dev/null
+++ b/src/platform/unix.c
@@ -0,0 +1,38 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Ted John
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of OpenRCT2.
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
+#ifndef _WIN32
+#ifndef __APPLE__
+
+/**
+ * Unix, linux and fallback entry point to OpenRCT2.
+ */
+// int main(char *argv[], int argc)
+// {
+// return 0;
+// }
+
+char platform_get_path_separator()
+{
+ return '/';
+}
+
+#endif
+#endif
\ No newline at end of file
diff --git a/src/platform/windows.c b/src/platform/windows.c
new file mode 100644
index 0000000000..1d683f9e8b
--- /dev/null
+++ b/src/platform/windows.c
@@ -0,0 +1,76 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Ted John
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of OpenRCT2.
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
+#ifdef _WIN32
+
+#include
+
+/**
+ * Windows entry point to OpenRCT2 without a console window.
+ */
+// int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
+// {
+// return 0;
+// }
+
+/**
+ * Windows entry point to OpenRCT2 with a console window using a traditional C main function.
+ */
+// int main(char *argv[], int argc)
+// {
+// return 0;
+// }
+
+/**
+ * Entry point for when the DLL is loaded. This will be removed when OpenRCT2 can be built as a stand alone application.
+ */
+BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
+{
+ return TRUE;
+}
+
+/**
+ * The function that is called directly from the host application (rct2.exe)'s WinMain. This will be removed when OpenRCT2 can
+ * be built as a stand alone application.
+ */
+// __declspec(dllexport) int StartOpenRCT(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
+// {
+// }
+
+char platform_get_path_separator()
+{
+ return '\\';
+}
+
+int platform_directory_exists(const char *path)
+{
+ DWORD dwAttrib = GetFileAttributes(path);
+ return dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
+}
+
+int platform_ensure_directory_exists(const char *path)
+{
+ if (platform_directory_exists(path))
+ return 1;
+
+ return CreateDirectory(path, NULL);
+}
+
+#endif
\ No newline at end of file
diff --git a/src/rct2.c b/src/rct2.c
index 5d9c7ff135..4b1896ca00 100644
--- a/src/rct2.c
+++ b/src/rct2.c
@@ -29,29 +29,27 @@
#include
#include
#include "addresses.h"
-#include "audio.h"
-#include "climate.h"
+#include "audio/audio.h"
+#include "audio/mixer.h"
#include "config.h"
-#include "date.h"
+#include "drawing/drawing.h"
#include "editor.h"
#include "game.h"
-#include "gfx.h"
+#include "interface/viewport.h"
#include "intro.h"
-#include "language.h"
-#include "map.h"
-#include "mixer.h"
-#include "news_item.h"
+#include "localisation/date.h"
+#include "localisation/localisation.h"
+#include "management/news_item.h"
#include "object.h"
-#include "osinterface.h"
-#include "park.h"
-#include "rct2.h"
-#include "ride.h"
+#include "platform/osinterface.h"
+#include "ride/ride.h"
+#include "ride/track.h"
#include "scenario.h"
#include "title.h"
-#include "track.h"
-#include "viewport.h"
-#include "sprite.h"
-#include "string_ids.h"
+#include "world/map.h"
+#include "world/park.h"
+#include "world/climate.h"
+#include "world/sprite.h"
typedef struct tm tm_t;
@@ -69,11 +67,6 @@ static void rct2_update_2();
static int _finished;
static jmp_buf _end_update_jump;
-BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
-{
- return TRUE;
-}
-
__declspec(dllexport) int StartOpenRCT(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
print_launch_information();
diff --git a/src/rct2.h b/src/rct2.h
index 6589990001..51f982c4ed 100644
--- a/src/rct2.h
+++ b/src/rct2.h
@@ -91,6 +91,8 @@ typedef fixed32_1dp money32;
#define MONEY32_UNDEFINED ((money32)0x80000000)
+typedef unsigned short rct_string_id;
+
void rct2_finish();
enum {
diff --git a/src/ride/ride.c b/src/ride/ride.c
index f6bb8eb460..e3c54396d7 100644
--- a/src/ride/ride.c
+++ b/src/ride/ride.c
@@ -19,18 +19,18 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "game.h"
-#include "map.h"
-#include "news_item.h"
-#include "staff.h"
-#include "sprite.h"
+#include "../addresses.h"
+#include "../game.h"
+#include "../interface/window.h"
+#include "../localisation/localisation.h"
+#include "../management/news_item.h"
+#include "../scenario.h"
+#include "../world/map.h"
+#include "../world/peep.h"
+#include "../world/sprite.h"
+#include "../world/staff.h"
#include "ride.h"
#include "ride_data.h"
-#include "scenario.h"
-#include "sprite.h"
-#include "peep.h"
-#include "window.h"
#pragma region Ride classification table
diff --git a/src/ride/ride.h b/src/ride/ride.h
index 3d323c6a34..065c108f6a 100644
--- a/src/ride/ride.h
+++ b/src/ride/ride.h
@@ -21,10 +21,9 @@
#ifndef _RIDE_H_
#define _RIDE_H_
-#include "map.h"
-#include "peep.h"
-#include "rct2.h"
-#include "string_ids.h"
+#include "../common.h"
+#include "../world/map.h"
+#include "../world/peep.h"
typedef fixed16_2dp ride_rating;
diff --git a/src/ride/ride_data.c b/src/ride/ride_data.c
index 387156f9a7..b1ae1d8b85 100644
--- a/src/ride/ride_data.c
+++ b/src/ride/ride_data.c
@@ -9,7 +9,6 @@
*/
#include
-#include "rct2.h"
#include "ride.h"
#include "ride_data.h"
diff --git a/src/ride/ride_data.h b/src/ride/ride_data.h
index 0d0bcb658b..d6b1617b04 100644
--- a/src/ride/ride_data.h
+++ b/src/ride/ride_data.h
@@ -22,8 +22,7 @@
#define _RIDE_DATA_H_
#include
-#include "rct2.h"
-#include "string_ids.h"
+#include "../common.h"
typedef struct {
rct_string_id vehicle_name;
diff --git a/src/ride/ride_ratings.c b/src/ride/ride_ratings.c
index 64553970d6..cf27fa487c 100644
--- a/src/ride/ride_ratings.c
+++ b/src/ride/ride_ratings.c
@@ -18,7 +18,7 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
+#include "../addresses.h"
#include "ride.h"
#include "ride_data.h"
#include "ride_ratings.h"
diff --git a/src/ride/ride_ratings.h b/src/ride/ride_ratings.h
index 7b6463c525..14e158f564 100644
--- a/src/ride/ride_ratings.h
+++ b/src/ride/ride_ratings.h
@@ -21,7 +21,7 @@
#ifndef _RIDE_RATINGS_H_
#define _RIDE_RATINGS_H_
-#include "rct2.h"
+#include "../common.h"
#include "ride.h"
void crooked_house_excitement(rct_ride *ride);
diff --git a/src/ride/track.c b/src/ride/track.c
index 341528d545..5cf6801b9a 100644
--- a/src/ride/track.c
+++ b/src/ride/track.c
@@ -20,9 +20,9 @@
#include
#include
-#include "addresses.h"
+#include "../addresses.h"
+#include "../platform/osinterface.h"
#include "ride.h"
-#include "osinterface.h"
#include "track.h"
/**
diff --git a/src/ride/track.h b/src/ride/track.h
index 1bdf348969..e55e598c4f 100644
--- a/src/ride/track.h
+++ b/src/ride/track.h
@@ -21,7 +21,7 @@
#ifndef _TRACK_H_
#define _TRACK_H_
-#include "rct2.h"
+#include "../common.h"
#include "ride.h"
typedef struct {
diff --git a/src/ride/vehicle.c b/src/ride/vehicle.c
index 1f0b81ddfe..0de6cb713c 100644
--- a/src/ride/vehicle.c
+++ b/src/ride/vehicle.c
@@ -18,12 +18,12 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
-#include "audio.h"
+#include "../addresses.h"
+#include "../audio/audio.h"
+#include "../interface/viewport.h"
+#include "../world/sprite.h"
#include "ride.h"
-#include "sprite.h"
#include "vehicle.h"
-#include "viewport.h"
static void vehicle_update(rct_vehicle *vehicle);
diff --git a/src/ride/vehicle.h b/src/ride/vehicle.h
index d781ba8202..71edc25a94 100644
--- a/src/ride/vehicle.h
+++ b/src/ride/vehicle.h
@@ -21,7 +21,7 @@
#ifndef _VEHICLE_H_
#define _VEHICLE_H_
-#include "rct2.h"
+#include "../common.h"
typedef union {
struct {
diff --git a/src/scenario.c b/src/scenario.c
index b27fd4f830..1e9bbbbafd 100644
--- a/src/scenario.c
+++ b/src/scenario.c
@@ -21,22 +21,21 @@
#include
#include
#include "addresses.h"
-#include "award.h"
-#include "date.h"
-#include "finance.h"
#include "game.h"
-#include "map.h"
-#include "marketing.h"
-#include "news_item.h"
+#include "interface/viewport.h"
+#include "localisation/date.h"
+#include "localisation/localisation.h"
+#include "management/award.h"
+#include "management/finance.h"
+#include "management/marketing.h"
+#include "management/news_item.h"
#include "object.h"
-#include "park.h"
-#include "rct2.h"
-#include "ride.h"
-#include "sawyercoding.h"
+#include "ride/ride.h"
#include "scenario.h"
-#include "string_ids.h"
-#include "sprite.h"
-#include "viewport.h"
+#include "util/sawyercoding.h"
+#include "world/map.h"
+#include "world/park.h"
+#include "world/sprite.h"
/**
* Loads only the basic information from a scenario.
diff --git a/src/title.c b/src/title.c
index 04898fd40c..697163d1f2 100644
--- a/src/title.c
+++ b/src/title.c
@@ -22,23 +22,22 @@
#include
#include
#include "addresses.h"
-#include "audio.h"
+#include "audio/audio.h"
#include "config.h"
-#include "climate.h"
-#include "date.h"
-#include "game.h"
-#include "gfx.h"
-#include "intro.h"
-#include "map.h"
-#include "news_item.h"
-#include "park.h"
-#include "rct2.h"
-#include "ride.h"
-#include "scenario.h"
-#include "sprite.h"
-#include "string_ids.h"
-#include "viewport.h"
+#include "drawing/drawing.h"
#include "editor.h"
+#include "localisation/date.h"
+#include "localisation/localisation.h"
+#include "game.h"
+#include "interface/viewport.h"
+#include "intro.h"
+#include "management/news_item.h"
+#include "ride/ride.h"
+#include "scenario.h"
+#include "world/climate.h"
+#include "world/map.h"
+#include "world/park.h"
+#include "world/sprite.h"
static const int gOldMusic = 0;
static const int gRandomShowcase = 0;
diff --git a/src/tutorial.c b/src/tutorial.c
index b990cc51b0..fe42977286 100644
--- a/src/tutorial.c
+++ b/src/tutorial.c
@@ -20,8 +20,9 @@
#include
#include "addresses.h"
+#include "localisation/localisation.h"
#include "tutorial.h"
-#include "window_error.h"
+#include "windows/error.h"
/**
*
diff --git a/src/util/sawyercoding.c b/src/util/sawyercoding.c
index c62722f8b7..5443b2c4b9 100644
--- a/src/util/sawyercoding.c
+++ b/src/util/sawyercoding.c
@@ -20,8 +20,7 @@
#include
#include
-#include "addresses.h"
-#include "rct2.h"
+#include "../addresses.h"
#include "sawyercoding.h"
static int decode_chunk_rle(uint8* src_buffer, uint8* dst_buffer, int length);
diff --git a/src/util/sawyercoding.h b/src/util/sawyercoding.h
index c965d2da94..7f990c589e 100644
--- a/src/util/sawyercoding.h
+++ b/src/util/sawyercoding.h
@@ -22,7 +22,7 @@
#define _SAWYERCODING_H_
#include
-#include "rct2.h"
+#include "../common.h"
typedef struct {
uint8 encoding;
diff --git a/src/windows/about.c b/src/windows/about.c
index dcb678a2cd..22f8f1a7c0 100644
--- a/src/windows/about.c
+++ b/src/windows/about.c
@@ -20,11 +20,11 @@
#include
#include
-#include "addresses.h"
-#include "string_ids.h"
-#include "sprites.h"
-#include "widget.h"
-#include "window.h"
+#include "../addresses.h"
+#include "../localisation/localisation.h"
+#include "../sprites.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
enum WINDOW_ABOUT_WIDGET_IDX {
WIDX_BACKGROUND,
diff --git a/src/windows/banner.c b/src/windows/banner.c
index 82c92d41e9..e95340b1f4 100644
--- a/src/windows/banner.c
+++ b/src/windows/banner.c
@@ -19,12 +19,12 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "config.h"
-#include "string_ids.h"
-#include "viewport.h"
-#include "widget.h"
-#include "window.h"
+#include "../addresses.h"
+#include "../config.h"
+#include "../localisation/localisation.h"
+#include "../interface/viewport.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
enum WINDOW_BANNER_WIDGET_IDX {
WIDX_BACKGROUND,
diff --git a/src/windows/cheats.c b/src/windows/cheats.c
index e0975ef90d..354e63bc2f 100644
--- a/src/windows/cheats.c
+++ b/src/windows/cheats.c
@@ -21,18 +21,18 @@
#include
#include
#include
-#include "addresses.h"
-#include "park.h"
-#include "peep.h"
-#include "string_ids.h"
-#include "sprite.h"
-#include "sprites.h"
-#include "widget.h"
-#include "window.h"
-#include "climate.h"
-#include "ride.h"
-#include "scenario.h"
-#include "game.h"
+#include "../addresses.h"
+#include "../game.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "../localisation/localisation.h"
+#include "../ride/ride.h"
+#include "../scenario.h"
+#include "../sprites.h"
+#include "../world/climate.h"
+#include "../world/park.h"
+#include "../world/peep.h"
+#include "../world/sprite.h"
//#define WW 200
//#define WH 128
diff --git a/src/windows/clear_scenery.c b/src/windows/clear_scenery.c
index df945f65d1..a507f3a313 100644
--- a/src/windows/clear_scenery.c
+++ b/src/windows/clear_scenery.c
@@ -18,12 +18,12 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
-#include "map.h"
-#include "string_ids.h"
-#include "sprites.h"
-#include "widget.h"
-#include "window.h"
+#include "../addresses.h"
+#include "../world/map.h"
+#include "../localisation/localisation.h"
+#include "../sprites.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
enum WINDOW_CLEAR_SCENERY_WIDGET_IDX {
WIDX_BACKGROUND,
diff --git a/src/windows/dropdown.c b/src/windows/dropdown.c
index b075a58aea..3408abd056 100644
--- a/src/windows/dropdown.c
+++ b/src/windows/dropdown.c
@@ -20,13 +20,13 @@
#include
#include
-#include "addresses.h"
-#include "scenario.h"
-#include "string_ids.h"
-#include "sprites.h"
-#include "widget.h"
-#include "window.h"
-#include "window_dropdown.h"
+#include "../addresses.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "../localisation/localisation.h"
+#include "../scenario.h"
+#include "../sprites.h"
+#include "dropdown.h"
int gAppropriateImageDropdownItemsPerRow[] = {
1, 1, 1, 1, 2, 2, 3, 3, 4,
diff --git a/src/windows/dropdown.h b/src/windows/dropdown.h
index 234b956bdc..76370cd212 100644
--- a/src/windows/dropdown.h
+++ b/src/windows/dropdown.h
@@ -21,7 +21,7 @@
#ifndef _WINDOW_DROPDOWN_H_
#define _WINDOW_DROPDOWN_H_
-#include "rct2.h"
+#include "../common.h"
#define DROPDOWN_SEPARATOR 0
diff --git a/src/windows/error.c b/src/windows/error.c
index d088f344f9..8e4efb7d9e 100644
--- a/src/windows/error.c
+++ b/src/windows/error.c
@@ -18,12 +18,12 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
-#include "audio.h"
-#include "string_ids.h"
-#include "widget.h"
-#include "window.h"
-#include "window_error.h"
+#include "../addresses.h"
+#include "../audio/audio.h"
+#include "../localisation/localisation.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "error.h"
enum {
WIDX_BACKGROUND
diff --git a/src/windows/error.h b/src/windows/error.h
index a4f8f363ce..3ddb36c1c9 100644
--- a/src/windows/error.h
+++ b/src/windows/error.h
@@ -21,7 +21,7 @@
#ifndef _WINDOW_ERROR_H_
#define _WINDOW_ERROR_H_
-#include "string_ids.h"
+#include "../common.h"
void window_error_open(rct_string_id title, rct_string_id message);
diff --git a/src/windows/finances.c b/src/windows/finances.c
index 56f7072898..0fbd089caf 100644
--- a/src/windows/finances.c
+++ b/src/windows/finances.c
@@ -18,19 +18,19 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
-#include "date.h"
-#include "finance.h"
-#include "game.h"
-#include "graph.h"
-#include "marketing.h"
-#include "ride.h"
-#include "scenario.h"
-#include "string_ids.h"
-#include "sprites.h"
-#include "widget.h"
-#include "window.h"
-#include "window_dropdown.h"
+#include "../addresses.h"
+#include "../game.h"
+#include "../interface/graph.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "../localisation/date.h"
+#include "../localisation/localisation.h"
+#include "../management/finance.h"
+#include "../management/marketing.h"
+#include "../ride/ride.h"
+#include "../scenario.h"
+#include "../sprites.h"
+#include "dropdown.h"
enum {
WINDOW_FINANCES_PAGE_SUMMARY,
diff --git a/src/windows/footpath.c b/src/windows/footpath.c
index 62c1e5ada5..b09b37cee6 100644
--- a/src/windows/footpath.c
+++ b/src/windows/footpath.c
@@ -19,16 +19,16 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "audio.h"
-#include "game.h"
-#include "map.h"
-#include "string_ids.h"
-#include "sprites.h"
-#include "viewport.h"
-#include "widget.h"
-#include "window.h"
-#include "window_dropdown.h"
+#include "../addresses.h"
+#include "../audio/audio.h"
+#include "../game.h"
+#include "../world/map.h"
+#include "../localisation/localisation.h"
+#include "../sprites.h"
+#include "../interface/viewport.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "dropdown.h"
enum {
PATH_CONSTRUCTION_MODE_LAND,
diff --git a/src/windows/game_bottom_toolbar.c b/src/windows/game_bottom_toolbar.c
index 46e983865e..26fd02d15b 100644
--- a/src/windows/game_bottom_toolbar.c
+++ b/src/windows/game_bottom_toolbar.c
@@ -20,17 +20,17 @@
#include
#include
-#include "addresses.h"
-#include "climate.h"
-#include "date.h"
-#include "news_item.h"
-#include "park.h"
-#include "peep.h"
-#include "sprite.h"
-#include "sprites.h"
-#include "string_ids.h"
-#include "widget.h"
-#include "window.h"
+#include "../addresses.h"
+#include "../localisation/date.h"
+#include "../localisation/localisation.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "../management/news_item.h"
+#include "../sprites.h"
+#include "../world/climate.h"
+#include "../world/park.h"
+#include "../world/peep.h"
+#include "../world/sprite.h"
enum WINDOW_GAME_BOTTOM_TOOLBAR_WIDGET_IDX {
WIDX_LEFT_OUTSET,
diff --git a/src/windows/game_top_toolbar.c b/src/windows/game_top_toolbar.c
index a81eaf85df..1a5497c380 100644
--- a/src/windows/game_top_toolbar.c
+++ b/src/windows/game_top_toolbar.c
@@ -19,14 +19,14 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "game.h"
-#include "sprites.h"
-#include "string_ids.h"
-#include "widget.h"
-#include "window.h"
-#include "window_dropdown.h"
-#include "viewport.h"
+#include "../addresses.h"
+#include "../game.h"
+#include "../sprites.h"
+#include "../localisation/localisation.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "dropdown.h"
+#include "../interface/viewport.h"
enum {
WIDX_PAUSE,
diff --git a/src/windows/guest_list.c b/src/windows/guest_list.c
index 97223cb97a..b9669c0ad8 100644
--- a/src/windows/guest_list.c
+++ b/src/windows/guest_list.c
@@ -20,16 +20,16 @@
#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"
+#include "../addresses.h"
+#include "../game.h"
+#include "../world/peep.h"
+#include "../localisation/localisation.h"
+#include "../world/sprite.h"
+#include "../sprites.h"
+#include "../ride/ride.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "dropdown.h"
enum {
PAGE_INDIVIDUAL,
diff --git a/src/windows/land.c b/src/windows/land.c
index 81d95020b1..cccbe99d7a 100644
--- a/src/windows/land.c
+++ b/src/windows/land.c
@@ -18,13 +18,13 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
-#include "map.h"
-#include "string_ids.h"
-#include "sprites.h"
-#include "widget.h"
-#include "window.h"
-#include "window_dropdown.h"
+#include "../addresses.h"
+#include "../world/map.h"
+#include "../localisation/localisation.h"
+#include "../sprites.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "dropdown.h"
enum WINDOW_LAND_WIDGET_IDX {
WIDX_BACKGROUND,
diff --git a/src/windows/main.c b/src/windows/main.c
index 7f2e6f3caa..1134af7f65 100644
--- a/src/windows/main.c
+++ b/src/windows/main.c
@@ -18,10 +18,10 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
-#include "viewport.h"
-#include "widget.h"
-#include "window.h"
+#include "../addresses.h"
+#include "../interface/viewport.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
rct_widget window_main_widgets[] = {
{ WWT_VIEWPORT, 0, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0xFFFFFFFE, 0xFFFF },
diff --git a/src/windows/map.c b/src/windows/map.c
index 91284ce9af..2bbf64b06e 100644
--- a/src/windows/map.c
+++ b/src/windows/map.c
@@ -19,13 +19,13 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "sprites.h"
-#include "string_ids.h"
-#include "widget.h"
-#include "window.h"
-#include "window_scenery.h"
-#include "viewport.h"
+#include "../addresses.h"
+#include "../sprites.h"
+#include "../localisation/localisation.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "../windows/scenery.h"
+#include "../interface/viewport.h"
enum WINDOW_MAP_WIDGET_IDX {
WIDX_BACKGROUND,
diff --git a/src/windows/music_credits.c b/src/windows/music_credits.c
index 9c25b28eb0..8910bb577f 100644
--- a/src/windows/music_credits.c
+++ b/src/windows/music_credits.c
@@ -20,11 +20,11 @@
#include
#include
-#include "addresses.h"
-#include "string_ids.h"
-#include "sprites.h"
-#include "widget.h"
-#include "window.h"
+#include "../addresses.h"
+#include "../localisation/localisation.h"
+#include "../sprites.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
enum WINDOW_MUSIC_CREDITS_WIDGET_IDX {
WIDX_BACKGROUND,
diff --git a/src/windows/new_campaign.c b/src/windows/new_campaign.c
index 39ad693d98..d2146ad9e9 100644
--- a/src/windows/new_campaign.c
+++ b/src/windows/new_campaign.c
@@ -19,14 +19,14 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "game.h"
-#include "marketing.h"
-#include "ride.h"
-#include "string_ids.h"
-#include "widget.h"
-#include "window.h"
-#include "window_dropdown.h"
+#include "../addresses.h"
+#include "../game.h"
+#include "../localisation/localisation.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "../management/marketing.h"
+#include "../ride/ride.h"
+#include "dropdown.h"
#define SELECTED_RIDE_UNDEFINED ((uint16)0xFFFF)
diff --git a/src/windows/new_ride.c b/src/windows/new_ride.c
index c920c6e004..d44b5445ec 100644
--- a/src/windows/new_ride.c
+++ b/src/windows/new_ride.c
@@ -19,16 +19,16 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "audio.h"
-#include "game.h"
-#include "news_item.h"
-#include "ride.h"
-#include "string_ids.h"
-#include "scenery.h"
-#include "track.h"
-#include "widget.h"
-#include "window.h"
+#include "../addresses.h"
+#include "../audio/audio.h"
+#include "../game.h"
+#include "../management/news_item.h"
+#include "../ride/ride.h"
+#include "../localisation/localisation.h"
+#include "../world/scenery.h"
+#include "../ride/track.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
#define _window_new_ride_current_tab RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_RIDE_LIST_SELECTED_TAB, uint8)
diff --git a/src/windows/news.c b/src/windows/news.c
index 256ecb0493..1f7a85b27d 100644
--- a/src/windows/news.c
+++ b/src/windows/news.c
@@ -19,14 +19,14 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "audio.h"
-#include "news_item.h"
-#include "string_ids.h"
-#include "sprite.h"
-#include "sprites.h"
-#include "widget.h"
-#include "window.h"
+#include "../addresses.h"
+#include "../audio/audio.h"
+#include "../management/news_item.h"
+#include "../localisation/localisation.h"
+#include "../world/sprite.h"
+#include "../sprites.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
enum WINDOW_NEWS_WIDGET_IDX {
WIDX_BACKGROUND,
diff --git a/src/windows/options.c b/src/windows/options.c
index 4df489aa0f..851f13cb7b 100644
--- a/src/windows/options.c
+++ b/src/windows/options.c
@@ -28,19 +28,18 @@
#include
-#include "addresses.h"
-#include "audio.h"
-#include "config.h"
-#include "gfx.h"
-#include "language.h"
-#include "mixer.h"
-#include "osinterface.h"
-#include "sprites.h"
-#include "string_ids.h"
-#include "viewport.h"
-#include "widget.h"
-#include "window.h"
-#include "window_dropdown.h"
+#include "../addresses.h"
+#include "../audio/audio.h"
+#include "../audio/mixer.h"
+#include "../config.h"
+#include "../drawing/drawing.h"
+#include "../interface/viewport.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "../localisation/localisation.h"
+#include "../sprites.h"
+#include "../platform/osinterface.h"
+#include "dropdown.h"
enum {
WINDOW_OPTIONS_PAGE_DISPLAY,
diff --git a/src/windows/park.c b/src/windows/park.c
index 62abaec285..df7b9931cf 100644
--- a/src/windows/park.c
+++ b/src/windows/park.c
@@ -19,24 +19,24 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "award.h"
-#include "config.h"
-#include "date.h"
-#include "game.h"
-#include "graph.h"
-#include "park.h"
-#include "peep.h"
-#include "ride.h"
-#include "scenario.h"
-#include "string_ids.h"
-#include "sprite.h"
-#include "sprites.h"
-#include "util.h"
-#include "viewport.h"
-#include "widget.h"
-#include "window.h"
-#include "window_dropdown.h"
+#include "../addresses.h"
+#include "../config.h"
+#include "../game.h"
+#include "../localisation/date.h"
+#include "../localisation/localisation.h"
+#include "../interface/graph.h"
+#include "../interface/viewport.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "../management/award.h"
+#include "../ride/ride.h"
+#include "../scenario.h"
+#include "../sprites.h"
+#include "../util/util.h"
+#include "../world/park.h"
+#include "../world/peep.h"
+#include "../world/sprite.h"
+#include "dropdown.h"
enum WINDOW_PARK_PAGE {
WINDOW_PARK_PAGE_ENTRANCE,
diff --git a/src/windows/peep.c b/src/windows/peep.c
index 5dbd0d03d8..eeb1804a10 100644
--- a/src/windows/peep.c
+++ b/src/windows/peep.c
@@ -18,22 +18,22 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
-#include "game.h"
-#include "map.h"
-#include "marketing.h"
-#include "ride.h"
-#include "peep.h"
-#include "scenario.h"
-#include "string_ids.h"
-#include "staff.h"
-#include "sprite.h"
-#include "sprites.h"
-#include "viewport.h"
-#include "widget.h"
-#include "window.h"
-#include "window_dropdown.h"
-#include "window_error.h"
+#include "../addresses.h"
+#include "../game.h"
+#include "../world/map.h"
+#include "../management/marketing.h"
+#include "../ride/ride.h"
+#include "../world/peep.h"
+#include "../scenario.h"
+#include "../localisation/localisation.h"
+#include "../world/staff.h"
+#include "../world/sprite.h"
+#include "../sprites.h"
+#include "../interface/viewport.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "dropdown.h"
+#include "error.h"
enum WINDOW_PEEP_PAGE {
WINDOW_PEEP_OVERVIEW,
diff --git a/src/windows/publisher_credits.c b/src/windows/publisher_credits.c
index ce9e815b1c..c942621723 100644
--- a/src/windows/publisher_credits.c
+++ b/src/windows/publisher_credits.c
@@ -20,11 +20,11 @@
#include
#include
-#include "addresses.h"
-#include "string_ids.h"
-#include "sprites.h"
-#include "widget.h"
-#include "window.h"
+#include "../addresses.h"
+#include "../localisation/localisation.h"
+#include "../sprites.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
enum WINDOW_PUBLISHER_CREDITS_WIDGET_IDX {
WIDX_BACKGROUND,
diff --git a/src/windows/research.c b/src/windows/research.c
index 5685c80da1..b5384f970c 100644
--- a/src/windows/research.c
+++ b/src/windows/research.c
@@ -18,17 +18,17 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
-#include "finance.h"
-#include "game.h"
-#include "news_item.h"
-#include "ride.h"
-#include "scenery.h"
-#include "string_ids.h"
-#include "sprites.h"
-#include "widget.h"
-#include "window.h"
-#include "window_dropdown.h"
+#include "../addresses.h"
+#include "../game.h"
+#include "../localisation/localisation.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "../management/finance.h"
+#include "../management/news_item.h"
+#include "../ride/ride.h"
+#include "../sprites.h"
+#include "../world/scenery.h"
+#include "dropdown.h"
enum {
WINDOW_RESEARCH_PAGE_DEVELOPMENT,
diff --git a/src/windows/ride.c b/src/windows/ride.c
index 008ca07884..7497f71701 100644
--- a/src/windows/ride.c
+++ b/src/windows/ride.c
@@ -19,19 +19,19 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "game.h"
-#include "map.h"
-#include "ride.h"
-#include "ride_data.h"
-#include "staff.h"
-#include "string_ids.h"
-#include "sprite.h"
-#include "sprites.h"
-#include "viewport.h"
-#include "widget.h"
-#include "window.h"
-#include "window_dropdown.h"
+#include "../addresses.h"
+#include "../game.h"
+#include "../world/map.h"
+#include "../ride/ride.h"
+#include "../ride/ride_data.h"
+#include "../world/staff.h"
+#include "../localisation/localisation.h"
+#include "../world/sprite.h"
+#include "../sprites.h"
+#include "../interface/viewport.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "dropdown.h"
#define var_496(w) RCT2_GLOBAL((int)w + 0x496, uint16)
diff --git a/src/windows/ride_list.c b/src/windows/ride_list.c
index 598955a548..69704cfd6a 100644
--- a/src/windows/ride_list.c
+++ b/src/windows/ride_list.c
@@ -19,15 +19,15 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "game.h"
-#include "ride.h"
-#include "string_ids.h"
-#include "sprite.h"
-#include "sprites.h"
-#include "widget.h"
-#include "window.h"
-#include "window_dropdown.h"
+#include "../addresses.h"
+#include "../game.h"
+#include "../ride/ride.h"
+#include "../localisation/localisation.h"
+#include "../world/sprite.h"
+#include "../sprites.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "dropdown.h"
enum {
PAGE_RIDES,
diff --git a/src/windows/save_prompt.c b/src/windows/save_prompt.c
index 185ef5f7b2..1c8dc75980 100644
--- a/src/windows/save_prompt.c
+++ b/src/windows/save_prompt.c
@@ -18,16 +18,15 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
-#include "game.h"
-#include "rct2.h"
-#include "string_ids.h"
-#include "sprites.h"
-#include "tutorial.h"
-#include "widget.h"
-#include "window.h"
-#include "audio.h"
-#include "config.h"
+#include "../addresses.h"
+#include "../audio/audio.h"
+#include "../game.h"
+#include "../localisation/localisation.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "../sprites.h"
+#include "../config.h"
+#include "../tutorial.h"
enum WINDOW_SAVE_PROMPT_WIDGET_IDX {
WIDX_BACKGROUND,
diff --git a/src/windows/scenery.c b/src/windows/scenery.c
index b74c977ffa..45a3620c3b 100644
--- a/src/windows/scenery.c
+++ b/src/windows/scenery.c
@@ -20,20 +20,20 @@
#include
#include
-#include "addresses.h"
-#include "audio.h"
-#include "game.h"
-#include "map.h"
-#include "gfx.h"
-#include "peep.h"
-#include "sprite.h"
+#include "../addresses.h"
+#include "../audio/audio.h"
+#include "../game.h"
+#include "../world/map.h"
+#include "../drawing/drawing.h"
+#include "../world/peep.h"
+#include "../world/sprite.h"
+#include "../world/scenery.h"
+#include "../localisation/localisation.h"
+#include "../interface/viewport.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "dropdown.h"
#include "scenery.h"
-#include "string_ids.h"
-#include "viewport.h"
-#include "widget.h"
-#include "window.h"
-#include "window_dropdown.h"
-#include "window_scenery.h"
enum {
WINDOW_SCENERY_TAB_1,
diff --git a/src/windows/staff.c b/src/windows/staff.c
index d03e0aee99..6d99cdf59a 100644
--- a/src/windows/staff.c
+++ b/src/windows/staff.c
@@ -19,17 +19,17 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "game.h"
-#include "gfx.h"
-#include "peep.h"
-#include "staff.h"
-#include "sprite.h"
-#include "string_ids.h"
-#include "viewport.h"
-#include "widget.h"
-#include "window.h"
-#include "window_dropdown.h"
+#include "../addresses.h"
+#include "../game.h"
+#include "../drawing/drawing.h"
+#include "../world/peep.h"
+#include "../world/staff.h"
+#include "../world/sprite.h"
+#include "../localisation/localisation.h"
+#include "../interface/viewport.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "dropdown.h"
enum {
WINDOW_STAFF_TAB_HANDYMEN,
diff --git a/src/windows/staff_peep.c b/src/windows/staff_peep.c
index 1b899f99b0..5b58fa8223 100644
--- a/src/windows/staff_peep.c
+++ b/src/windows/staff_peep.c
@@ -18,17 +18,17 @@
* 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 "viewport.h"
-#include "widget.h"
-#include "window.h"
-#include "window_dropdown.h"
-#include "staff.h"
+#include "../addresses.h"
+#include "../game.h"
+#include "../world/peep.h"
+#include "../localisation/localisation.h"
+#include "../world/sprite.h"
+#include "../sprites.h"
+#include "../interface/viewport.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "dropdown.h"
+#include "../world/staff.h"
enum WINDOW_STAFF_PEEP_PAGE {
WINDOW_STAFF_PEEP_OVERVIEW,
diff --git a/src/windows/title_exit.c b/src/windows/title_exit.c
index ecb6426aed..2e8478f5fb 100644
--- a/src/windows/title_exit.c
+++ b/src/windows/title_exit.c
@@ -18,13 +18,12 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
-#include "game.h"
-#include "sprites.h"
-#include "string_ids.h"
-#include "widget.h"
-#include "window.h"
-#include "rct2.h"
+#include "../addresses.h"
+#include "../game.h"
+#include "../sprites.h"
+#include "../localisation/localisation.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
static rct_widget window_title_exit_widgets[] = {
{ WWT_IMGBTN, 2, 0, 39, 0, 63, SPR_MENU_EXIT, STR_EXIT },
diff --git a/src/windows/title_logo.c b/src/windows/title_logo.c
index 2fd9d7c0f0..835ab23d67 100644
--- a/src/windows/title_logo.c
+++ b/src/windows/title_logo.c
@@ -18,11 +18,11 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
-#include "string_ids.h"
-#include "sprites.h"
-#include "widget.h"
-#include "window.h"
+#include "../addresses.h"
+#include "../localisation/localisation.h"
+#include "../sprites.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
static rct_widget window_title_logo_widgets[] = {
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE },
diff --git a/src/windows/title_menu.c b/src/windows/title_menu.c
index 54aa0ea04c..88bf10d8f5 100644
--- a/src/windows/title_menu.c
+++ b/src/windows/title_menu.c
@@ -18,15 +18,15 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
-#include "editor.h"
-#include "game.h"
-#include "string_ids.h"
-#include "sprites.h"
-#include "tutorial.h"
-#include "widget.h"
-#include "window.h"
-#include "window_dropdown.h"
+#include "../addresses.h"
+#include "../editor.h"
+#include "../game.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "../localisation/localisation.h"
+#include "../sprites.h"
+#include "../tutorial.h"
+#include "dropdown.h"
enum {
WIDX_START_NEW_GAME,
diff --git a/src/windows/title_scenarioselect.c b/src/windows/title_scenarioselect.c
index c55aeedce9..69efd55a7c 100644
--- a/src/windows/title_scenarioselect.c
+++ b/src/windows/title_scenarioselect.c
@@ -19,14 +19,14 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "audio.h"
-#include "date.h"
-#include "scenario.h"
-#include "string_ids.h"
-#include "sprites.h"
-#include "widget.h"
-#include "window.h"
+#include "../addresses.h"
+#include "../audio/audio.h"
+#include "../localisation/date.h"
+#include "../localisation/localisation.h"
+#include "../scenario.h"
+#include "../sprites.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
enum {
WIDX_BACKGROUND,
diff --git a/src/windows/tooltip.c b/src/windows/tooltip.c
index 746cc81830..85164885cd 100644
--- a/src/windows/tooltip.c
+++ b/src/windows/tooltip.c
@@ -20,11 +20,11 @@
#include
#include
-#include "addresses.h"
-#include "string_ids.h"
-#include "widget.h"
-#include "window.h"
-#include "gfx.h"
+#include "../addresses.h"
+#include "../drawing/drawing.h"
+#include "../localisation/localisation.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
enum {
WIDX_BACKGROUND
diff --git a/src/windows/tooltip.h b/src/windows/tooltip.h
index cf05351929..adff1c3ed6 100644
--- a/src/windows/tooltip.h
+++ b/src/windows/tooltip.h
@@ -21,8 +21,7 @@
#ifndef _WINDOW_TOOLTIP_H_
#define _WINDOW_TOOLTIP_H_
-#include "rct2.h"
-#include "window.h"
+#include "../interface/window.h"
void window_tooltip_reset(int x, int y);
void window_tooltip_open(rct_window *widgetWindow, int widgetIndex, int x, int y);
diff --git a/src/windows/track_list.c b/src/windows/track_list.c
index 784e99427a..34e8b72032 100644
--- a/src/windows/track_list.c
+++ b/src/windows/track_list.c
@@ -19,16 +19,16 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "audio.h"
-#include "editor.h"
-#include "ride.h"
-#include "sprites.h"
-#include "string_ids.h"
-#include "track.h"
-#include "widget.h"
-#include "window.h"
-#include "window_error.h"
+#include "../addresses.h"
+#include "../audio/audio.h"
+#include "../editor.h"
+#include "../localisation/localisation.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
+#include "../ride/ride.h"
+#include "../ride/track.h"
+#include "../sprites.h"
+#include "error.h"
enum {
WIDX_BACKGROUND,
diff --git a/src/windows/track_manage.c b/src/windows/track_manage.c
index 7741bdfe30..ebfe54d6c6 100644
--- a/src/windows/track_manage.c
+++ b/src/windows/track_manage.c
@@ -18,8 +18,8 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
-#include "window.h"
+#include "../addresses.h"
+#include "../interface/window.h"
/**
*
diff --git a/src/windows/track_place.c b/src/windows/track_place.c
index be3b367c0e..1042f6d0dd 100644
--- a/src/windows/track_place.c
+++ b/src/windows/track_place.c
@@ -19,15 +19,15 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "audio.h"
-#include "game.h"
-#include "sprites.h"
-#include "string_ids.h"
-#include "track.h"
-#include "viewport.h"
-#include "widget.h"
-#include "window.h"
+#include "../addresses.h"
+#include "../audio/audio.h"
+#include "../game.h"
+#include "../sprites.h"
+#include "../localisation/localisation.h"
+#include "../ride/track.h"
+#include "../interface/viewport.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
#define TRACK_MINI_PREVIEW_WIDTH 168
#define TRACK_MINI_PREVIEW_HEIGHT 78
diff --git a/src/windows/water.c b/src/windows/water.c
index 0147842f5e..c844df0672 100644
--- a/src/windows/water.c
+++ b/src/windows/water.c
@@ -18,12 +18,12 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
-#include "map.h"
-#include "string_ids.h"
-#include "sprites.h"
-#include "widget.h"
-#include "window.h"
+#include "../addresses.h"
+#include "../world/map.h"
+#include "../localisation/localisation.h"
+#include "../sprites.h"
+#include "../interface/widget.h"
+#include "../interface/window.h"
enum WINDOW_WATER_WIDGET_IDX {
WIDX_BACKGROUND,
diff --git a/src/world/climate.c b/src/world/climate.c
index af633917fa..387d5c01e2 100644
--- a/src/world/climate.c
+++ b/src/world/climate.c
@@ -18,13 +18,12 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
-#include "audio.h"
+#include "../addresses.h"
+#include "../audio/audio.h"
+#include "../drawing/drawing.h"
+#include "../localisation/date.h"
+#include "../scenario.h"
#include "climate.h"
-#include "date.h"
-#include "gfx.h"
-#include "rct2.h"
-#include "scenario.h"
enum {
THUNDER_STATUS_NULL = 0,
diff --git a/src/world/climate.h b/src/world/climate.h
index 9aba03f523..fb52082cf6 100644
--- a/src/world/climate.h
+++ b/src/world/climate.h
@@ -21,7 +21,7 @@
#ifndef _CLIMATE_H_
#define _CLIMATE_H_
-#include "rct2.h"
+#include "../common.h"
enum {
CLIMATE_COOL_AND_WET,
diff --git a/src/world/map.c b/src/world/map.c
index cc749f604a..01eb46806b 100644
--- a/src/world/map.c
+++ b/src/world/map.c
@@ -18,9 +18,9 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
+#include "../addresses.h"
+#include "../localisation/date.h"
#include "climate.h"
-#include "date.h"
#include "map.h"
static void tiles_init();
diff --git a/src/world/map.h b/src/world/map.h
index 8b0073eaa0..5ce24b4d84 100644
--- a/src/world/map.h
+++ b/src/world/map.h
@@ -21,7 +21,7 @@
#ifndef _MAP_H_
#define _MAP_H_
-#include "rct2.h"
+#include "../common.h"
typedef struct {
uint8 slope; //4
diff --git a/src/world/park.c b/src/world/park.c
index f4ad3dc9b8..2b516bec82 100644
--- a/src/world/park.c
+++ b/src/world/park.c
@@ -19,19 +19,19 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "award.h"
-#include "finance.h"
-#include "map.h"
-#include "marketing.h"
-#include "news_item.h"
+#include "../addresses.h"
+#include "../interface/window.h"
+#include "../localisation/localisation.h"
+#include "../management/award.h"
+#include "../management/finance.h"
+#include "../management/marketing.h"
+#include "../management/news_item.h"
+#include "../ride/ride.h"
+#include "../scenario.h"
+#include "../world/map.h"
#include "park.h"
#include "peep.h"
-#include "ride.h"
-#include "scenario.h"
#include "sprite.h"
-#include "string_ids.h"
-#include "window.h"
/**
* In a difficult guest generation scenario, no guests will be generated if over this value.
diff --git a/src/world/park.h b/src/world/park.h
index 8a27dfdc8d..9bd41691a1 100644
--- a/src/world/park.h
+++ b/src/world/park.h
@@ -21,7 +21,7 @@
#ifndef _PARK_H_
#define _PARK_H_
-#include "rct2.h"
+#include "../common.h"
#define DECRYPT_MONEY(money) rol32((money) ^ 0xF4EC9621, 13)
#define ENCRYPT_MONEY(money) (ror32((money), 13) ^ 0xF4EC9621)
diff --git a/src/world/peep.c b/src/world/peep.c
index 623fff5273..67ee0f3479 100644
--- a/src/world/peep.c
+++ b/src/world/peep.c
@@ -19,16 +19,16 @@
*****************************************************************************/
#include
-#include "addresses.h"
-#include "audio.h"
-#include "news_item.h"
+#include "../addresses.h"
+#include "../audio/audio.h"
+#include "../interface/window.h"
+#include "../localisation/localisation.h"
+#include "../management/news_item.h"
+#include "../ride/ride.h"
+#include "../sprites.h"
#include "peep.h"
-#include "rct2.h"
-#include "ride.h"
#include "sprite.h"
-#include "sprites.h"
#include "staff.h"
-#include "window.h"
static void peep_update(rct_peep *peep);
diff --git a/src/world/peep.h b/src/world/peep.h
index 858047cdfb..8642a154ff 100644
--- a/src/world/peep.h
+++ b/src/world/peep.h
@@ -21,7 +21,7 @@
#ifndef _PEEP_H_
#define _PEEP_H_
-#include "rct2.h"
+#include "../common.h"
#define PEEP_MAX_THOUGHTS 5
diff --git a/src/world/scenery.h b/src/world/scenery.h
index 59704d94c0..cadf20f77b 100644
--- a/src/world/scenery.h
+++ b/src/world/scenery.h
@@ -21,8 +21,7 @@
#ifndef _SCENERY_H_
#define _SCENERY_H_
-#include "rct2.h"
-#include "string_ids.h"
+#include "../common.h"
typedef struct {
uint32 flags; // 0x06
diff --git a/src/world/sprite.c b/src/world/sprite.c
index e6d589f5b1..6c6bf44b2d 100644
--- a/src/world/sprite.c
+++ b/src/world/sprite.c
@@ -18,8 +18,8 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "addresses.h"
#include
+#include "../addresses.h"
#include "sprite.h"
rct_sprite* g_sprite_list = RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite);
diff --git a/src/world/sprite.h b/src/world/sprite.h
index 567c64af44..4941c38874 100644
--- a/src/world/sprite.h
+++ b/src/world/sprite.h
@@ -21,13 +21,13 @@
#ifndef _SPRITE_H_
#define _SPRITE_H_
-#include "rct2.h"
+#include "../common.h"
+#include "../ride/vehicle.h"
+#include "peep.h"
#define SPRITE_INDEX_NULL 0xFFFF
#define SPRITE_LOCATION_NULL 0x8000
-#include "peep.h"
-#include "vehicle.h"
enum SPRITE_IDENTIFIER{
SPRITE_IDENTIFIER_VEHICLE = 0,
diff --git a/src/world/staff.c b/src/world/staff.c
index d0bc47c04e..aa688c8895 100644
--- a/src/world/staff.c
+++ b/src/world/staff.c
@@ -18,15 +18,14 @@
* along with this program. If not, see .
*****************************************************************************/
-#include "staff.h"
-#include "addresses.h"
-#include "rct2.h"
-#include "game.h"
-#include "finance.h"
+#include "../addresses.h"
+#include "../game.h"
+#include "../interface/viewport.h"
+#include "../localisation/string_ids.h"
+#include "../management/finance.h"
#include "peep.h"
#include "sprite.h"
-#include "string_ids.h"
-#include "viewport.h"
+#include "staff.h"
/**
*
diff --git a/src/world/staff.h b/src/world/staff.h
index b8ef29af0c..72e9f0c965 100644
--- a/src/world/staff.h
+++ b/src/world/staff.h
@@ -21,7 +21,7 @@
#ifndef _STAFF_H_
#define _STAFF_H_
-#include "rct2.h"
+#include "../common.h"
#define STAFF_MAX_COUNT 0xC8
#define STAFF_TYPE_COUNT 0x04