mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-22 22:34:33 +01:00
Merge remote-tracking branch 'upstream/master' into hire-staff-command
This commit is contained in:
@@ -215,6 +215,7 @@
|
||||
#define RCT2_ADDRESS_CURRENT_PARK_RATING 0x01357CB0
|
||||
#define RCT2_ADDRESS_PARK_RATING_HISTORY 0x01357CB2
|
||||
#define RCT2_ADDRESS_GUESTS_IN_PARK_HISTORY 0x01357CD2
|
||||
#define RCT2_ADDRESS_LAST_RESEARCHED_ITEM_SUBJECT 0x01357CF4
|
||||
#define RCT2_ADDRESS_OBJECTIVE_TYPE 0x013580F8
|
||||
#define RCT2_ADDRESS_OBJECTIVE_YEAR 0x013580F9
|
||||
#define RCT2_ADDRESS_OBJECTIVE_CURRENCY 0x013580FC
|
||||
@@ -250,6 +251,8 @@
|
||||
#define RCT2_ADDRESS_SECURITY_COLOUR 0x01357BCF
|
||||
|
||||
#define RCT2_ADDRESS_ACTIVE_RESEARCH_TYPES 0x01357CF2
|
||||
#define RCT2_ADDRESS_NEXT_RESEARCH_EXPECTED_DAY 0x013580E7
|
||||
#define RCT2_ADDRESS_NEXT_RESEARCH_EXPECTED_MONTH 0x013580E8
|
||||
|
||||
#define RCT2_ADDRESS_MAP_SIZE 0x01358834
|
||||
#define RCT2_ADDRESS_PARK_SIZE 0x013580EA
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <ctype.h>
|
||||
#include "addresses.h"
|
||||
#include "config.h"
|
||||
#include "language.h"
|
||||
#include "rct2.h"
|
||||
|
||||
|
||||
@@ -90,6 +91,7 @@ general_configuration_t gGeneral_config_default = {
|
||||
0, // show_height_as_units
|
||||
1, // save_plugin_data
|
||||
0, // fullscreen mode (default: windowed)
|
||||
LANGUAGE_ENGLISH_UK
|
||||
};
|
||||
sound_configuration_t gSound_config;
|
||||
|
||||
@@ -381,6 +383,8 @@ void config_write_ini_general(FILE *fp)
|
||||
fprintf(fp, "fullscreen_mode = fullscreen\n");
|
||||
else
|
||||
fprintf(fp, "fullscreen_mode = borderless_fullscreen\n");
|
||||
|
||||
fprintf(fp, "language = %d\n", gGeneral_config.language);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -621,6 +625,9 @@ static void config_general(char *setting, char *value){
|
||||
else
|
||||
gGeneral_config.fullscreen_mode = 2;
|
||||
}
|
||||
else if (strcmp(setting, "language") == 0) {
|
||||
gGeneral_config.language = atoi(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -130,6 +130,7 @@ typedef struct general_configuration {
|
||||
|
||||
//new
|
||||
uint8 fullscreen_mode;
|
||||
uint16 language;
|
||||
} general_configuration_t;
|
||||
|
||||
static const struct { char *key; int value; } _currencyLookupTable[] = {
|
||||
|
||||
@@ -130,7 +130,7 @@ void finance_pay_ride_upkeep()
|
||||
if (ride->status != RIDE_STATUS_CLOSED && !(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & 0x800)) {
|
||||
sint16 upkeep = ride->upkeep_cost;
|
||||
if (upkeep != -1) {
|
||||
ride->var_158 -= upkeep;
|
||||
ride->var_154 -= upkeep;
|
||||
ride->var_14D |= 2;
|
||||
finance_payment(upkeep, RCT2_EXPENDITURE_TYPE_RIDE_UPKEEP);
|
||||
}
|
||||
|
||||
75
src/game.c
75
src/game.c
@@ -824,7 +824,7 @@ static void game_handle_input_mouse(int x, int y, int state)
|
||||
switch (ebx & 0xFF) {
|
||||
case 2:
|
||||
if (*((uint8*)edx) == 0)
|
||||
RCT2_CALLPROC_X(0x006B4857, eax, 0, ecx, 0, 0, 0, 0);
|
||||
RCT2_CALLPROC_X(0x006B4857, eax, 0, ecx, edx, 0, 0, 0);
|
||||
break;
|
||||
case 3:
|
||||
RCT2_CALLPROC_X(0x006CC056, eax, 0, ecx, edx, 0, 0, 0);
|
||||
@@ -867,7 +867,78 @@ static void game_handle_input_mouse(int x, int y, int state)
|
||||
RCT2_CALLPROC_X(0x006E8DA7, x, y, state, widgetIndex, (int)w, (int)widget, 0);
|
||||
break;
|
||||
case INPUT_STATE_VIEWPORT_LEFT:
|
||||
RCT2_CALLPROC_X(0x006E87B4, x, y, state, widgetIndex, (int)w, (int)widget, 0);
|
||||
//RCT2_CALLPROC_X(0x006E87B4, x, y, state, widgetIndex, (int)w, (int)widget, 0);
|
||||
w = window_find_by_id(RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWCLASS, rct_windowclass), RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER, rct_windownumber));
|
||||
if (!w){
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (state == 0){
|
||||
if (!w->viewport){
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (w->classification != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWCLASS, rct_windowclass) ||
|
||||
w->number != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER, rct_windownumber) ||
|
||||
!(RCT2_GLOBAL(0x9DE518, uint32)&(1 << 3)))break;
|
||||
|
||||
w = window_find_by_id(RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass), RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber));
|
||||
|
||||
if (!w)break;
|
||||
|
||||
RCT2_CALLPROC_X(w->event_handlers[WE_TOOL_DRAG], x, y, 0, (int)RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16), (int)w, 0, 0);
|
||||
}
|
||||
else if (state == 2){
|
||||
|
||||
RCT2_GLOBAL(0x9DE51D, uint8) = 0;
|
||||
if (RCT2_GLOBAL(0x9DE52E, rct_windownumber) != w->number)break;
|
||||
if ((RCT2_GLOBAL(0x9DE518, uint32)&(1 << 3))){
|
||||
w = window_find_by_id(RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass), RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber));
|
||||
if (!w)break;
|
||||
RCT2_CALLPROC_X(w->event_handlers[WE_TOOL_UP], x, y, 0, (int)RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16), (int)w, 0, 0);
|
||||
}
|
||||
else{
|
||||
if ((RCT2_GLOBAL(0x9DE518, uint32)&(1 << 4)))break;
|
||||
rct_sprite* spr;
|
||||
int eax = x, ebx = y, ecx = state, esi = (int)w, edi = (int)widget, ebp = 0;
|
||||
RCT2_CALLFUNC_X(0X6ED9D0, &eax, &ebx, &ecx, (int*)&spr, &esi, &edi, &ebp);
|
||||
if ((ebx & 0xFF) == 2){
|
||||
|
||||
if (spr->unknown.sprite_identifier == SPRITE_IDENTIFIER_VEHICLE){
|
||||
//Open ride window
|
||||
RCT2_CALLPROC_X(0x6ACAC2, eax, ebx, ecx, (int)spr, esi, edi, ebp);
|
||||
}
|
||||
else if (spr->unknown.sprite_identifier == SPRITE_IDENTIFIER_PEEP){
|
||||
window_peep_open(&spr->peep);
|
||||
}
|
||||
else if (spr->unknown.sprite_identifier == SPRITE_IDENTIFIER_FLOATING_TEXT){
|
||||
//Unknown for now
|
||||
RCT2_CALLPROC_X(0x6E88D7, eax, ebx, ecx, (int)spr, esi, edi, ebp);
|
||||
}
|
||||
}
|
||||
else if ((ebx & 0xFF) == 3){
|
||||
//Don't think it is a map element.
|
||||
rct_map_element_properties* map_element = (rct_map_element_properties*)spr;
|
||||
uint32 edx = (uint32)spr;
|
||||
|
||||
if (!((map_element->track.type & 0x3C) == 16)){
|
||||
eax = RCT2_ADDRESS(0x0099BA64, uint8)[16 * (*(uint8*)(edx + 4))];
|
||||
if (!(eax & 0x10)){
|
||||
eax = *((uint8*)(edx + 7));
|
||||
RCT2_CALLPROC_X(0x6ACC28, eax, ebx, ecx, edx, esi, edi, ebp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//Open ride window
|
||||
RCT2_CALLPROC_X(0x6ACCCE, *(uint8*)(edx + 7), ((*(uint8*)(edx + 5)) & 0x70) >> 4, ecx, edx, esi, edi, ebp);
|
||||
}
|
||||
else if ((ebx & 0xFF) == 8){
|
||||
window_park_entrance_open();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case INPUT_STATE_SCROLL_LEFT://0x006E8676
|
||||
//RCT2_CALLPROC_X(0x006E8676, x, y, state, widgetIndex, (int)w, (int)widget, 0);
|
||||
|
||||
113
src/gfx.c
113
src/gfx.c
@@ -690,6 +690,7 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri
|
||||
*/
|
||||
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){
|
||||
|
||||
@@ -697,12 +698,12 @@ void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_pointer, ui
|
||||
if (unknown_pointer!= NULL){ //Not tested. I can't actually work out when this code runs.
|
||||
unknown_pointer += source_pointer - source_image->offset;// RCT2_GLOBAL(0x9E3CE0, uint32);
|
||||
|
||||
for (; height > 0; height -= (1<<zoom_level)){
|
||||
uint8* next_source_pointer = source_pointer + (uint32)(source_image->width << zoom_level);
|
||||
uint8* next_unknown_pointer = unknown_pointer + (uint32)(source_image->width << zoom_level);
|
||||
uint8* next_dest_pointer = dest_pointer + (dest_dpi->width >> zoom_level) + dest_dpi->pitch;
|
||||
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 -= (1<<zoom_level), source_pointer+=(1<<zoom_level), unknown_pointer+=(1<<zoom_level), dest_pointer++){
|
||||
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;
|
||||
@@ -718,10 +719,10 @@ void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_pointer, ui
|
||||
}
|
||||
|
||||
//image colour adjusted?
|
||||
for (; height > 0; height -= (1<<zoom_level)){
|
||||
uint8* next_source_pointer = source_pointer + (uint32)(source_image->width<<zoom_level);
|
||||
uint8* next_dest_pointer = dest_pointer + (dest_dpi->width >> zoom_level) + dest_dpi->pitch;
|
||||
for (int no_pixels = width; no_pixels > 0; no_pixels -= (1<<zoom_level), source_pointer+= (1<<zoom_level), dest_pointer++){
|
||||
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){
|
||||
@@ -738,11 +739,11 @@ void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_pointer, ui
|
||||
//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 -= (1<<zoom_level)){
|
||||
uint8* next_source_pointer = source_pointer + (uint32)(source_image->width << zoom_level);
|
||||
uint8* next_dest_pointer = dest_pointer + (dest_dpi->width >> zoom_level) + dest_dpi->pitch;
|
||||
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 -= (1<<zoom_level), source_pointer += (1<<zoom_level), dest_pointer++){
|
||||
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;
|
||||
@@ -759,11 +760,11 @@ void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_pointer, ui
|
||||
|
||||
//Basic bitmap no fancy stuff
|
||||
if (!(source_image->flags & G1_FLAG_BMP)){//Not tested
|
||||
for (; height > 0; height-=(1<<zoom_level)){
|
||||
uint8* next_source_pointer = source_pointer + (uint32)(source_image->width << zoom_level);
|
||||
uint8* next_dest_pointer = dest_pointer + (dest_dpi->width >> zoom_level) + dest_dpi->pitch;
|
||||
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 -= (1<<zoom_level), dest_pointer++, source_pointer += (1<<zoom_level)){
|
||||
for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_amount, dest_pointer++, source_pointer += zoom_amount){
|
||||
*dest_pointer = *source_pointer;
|
||||
}
|
||||
|
||||
@@ -776,12 +777,12 @@ void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_pointer, ui
|
||||
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 -= (1<<zoom_level)){
|
||||
uint8* next_source_pointer = source_pointer + (uint32)(source_image->width << zoom_level);
|
||||
uint8* next_unknown_pointer = unknown_pointer + (uint32)(source_image->width << zoom_level);
|
||||
uint8* next_dest_pointer = dest_pointer + (dest_dpi->width >> zoom_level) + dest_dpi->pitch;
|
||||
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 -= (1<<zoom_level), dest_pointer++, source_pointer += (1<<zoom_level), unknown_pointer += (1<<zoom_level)){
|
||||
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){
|
||||
@@ -795,11 +796,11 @@ void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_pointer, ui
|
||||
}
|
||||
|
||||
//Basic bitmap with no draw pixels
|
||||
for (; height > 0; height -= (1<<zoom_level)){
|
||||
uint8* next_source_pointer = source_pointer + (uint32)(source_image->width << zoom_level);
|
||||
uint8* next_dest_pointer = dest_pointer + (dest_dpi->width >> zoom_level) + dest_dpi->pitch;
|
||||
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 -= (1<<zoom_level), dest_pointer++, source_pointer += (1<<zoom_level)){
|
||||
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;
|
||||
@@ -818,11 +819,12 @@ void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_pointer, ui
|
||||
*/
|
||||
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 += (1<<zoom_level)){
|
||||
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.
|
||||
@@ -852,7 +854,7 @@ void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_point
|
||||
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_level;
|
||||
dest_pointer += x_start / zoom_amount;
|
||||
}
|
||||
else{
|
||||
//If the start is negative we require to remove part of the image.
|
||||
@@ -879,7 +881,7 @@ void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_point
|
||||
//Finally after all those checks, copy the image onto the drawing surface
|
||||
//If the image type is not a basic one we require to mix the pixels
|
||||
if (image_type & IMAGE_TYPE_USE_PALETTE){//In the .exe these are all unraveled loops
|
||||
for (; no_pixels > 0; no_pixels -= (1<<zoom_level), source_pointer += (1<<zoom_level), dest_pointer++){
|
||||
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)
|
||||
@@ -893,7 +895,7 @@ void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_point
|
||||
//Doesnt use source pointer ??? mix with background only?
|
||||
//Not Tested
|
||||
|
||||
for (; no_pixels > 0; no_pixels -= (1<<zoom_level), dest_pointer++){
|
||||
for (; no_pixels > 0; no_pixels -= zoom_amount, dest_pointer++){
|
||||
uint8 pixel = *dest_pointer;
|
||||
pixel = palette_pointer[pixel];
|
||||
*dest_pointer = pixel;
|
||||
@@ -901,14 +903,14 @@ void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_point
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; no_pixels > 0; no_pixels -= (1<<zoom_level), source_pointer += (1<<zoom_level), dest_pointer++){
|
||||
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 += (int)(dpi->width >> zoom_level) + (int)dpi->pitch;
|
||||
next_dest_pointer += dpi->width / zoom_amount + dpi->pitch;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -946,7 +948,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32
|
||||
|
||||
if (image_type && !(image_type & IMAGE_TYPE_UNKNOWN)) {
|
||||
uint8 palette_ref = (image_id >> 19) & 0xFF;
|
||||
if (!(image_type & IMAGE_TYPE_MIX_BACKGROUND)){
|
||||
if (image_type & IMAGE_TYPE_MIX_BACKGROUND){
|
||||
unknown_pointer = NULL;
|
||||
RCT2_GLOBAL(0x009E3CDC, uint32) = 0;
|
||||
}
|
||||
@@ -1022,7 +1024,7 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in
|
||||
|
||||
rct_g1_element* g1_source = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[image_element]);
|
||||
|
||||
//Zooming code has been integrated into main code but is not working.
|
||||
//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){
|
||||
@@ -1053,17 +1055,19 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in
|
||||
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;
|
||||
uint16 zoom_mask = 0xFFFF << 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 >> zoom_level;
|
||||
int height = g1_source->height;
|
||||
//This is the start y coordinate on the destination
|
||||
sint16 dest_start_y = ((sint16)y + g1_source->y_offset - dpi->y) >> zoom_level;
|
||||
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
|
||||
@@ -1073,29 +1077,31 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in
|
||||
return;
|
||||
}
|
||||
//The source image will start a further up the image
|
||||
source_start_y -= dest_start_y<<zoom_level;
|
||||
source_start_y -= dest_start_y;
|
||||
//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 >> zoom_level)){
|
||||
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 >> zoom_level);
|
||||
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 >> zoom_level;
|
||||
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 = ((sint16)x + g1_source->x_offset - dpi->x) >> zoom_level;
|
||||
|
||||
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
|
||||
@@ -1105,29 +1111,28 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in
|
||||
return;
|
||||
}
|
||||
//The source start will also need to cut off the side
|
||||
source_start_x -= dest_start_x<<zoom_level;
|
||||
source_start_x -= dest_start_x;
|
||||
//Reset the destination to 0
|
||||
dest_start_x = 0;
|
||||
}
|
||||
|
||||
int dest_end_x = dest_start_x + width;
|
||||
|
||||
if (dest_end_x > (dpi->width>>zoom_level)){
|
||||
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 >> zoom_level);
|
||||
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_level) + dpi->pitch)*dest_start_y + dest_start_x;
|
||||
|
||||
height <<= zoom_level;
|
||||
width <<= zoom_level;
|
||||
|
||||
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
|
||||
|
||||
@@ -54,7 +54,7 @@ static void graph_draw_line_a_uint8(rct_drawpixelinfo *dpi, uint8 *history, int
|
||||
x = baseX;
|
||||
for (i = count - 1; i >= 0; i--) {
|
||||
if (history[i] != 0 && history[i] != 255) {
|
||||
y = baseY + (history[i] * 100) / 256;
|
||||
y = baseY + ((255 - history[i]) * 100) / 256;
|
||||
|
||||
if (lastX != -1) {
|
||||
gfx_draw_line(dpi, lastX + 1, lastY + 1, x + 1, y + 1, 10);
|
||||
@@ -78,7 +78,7 @@ static void graph_draw_line_b_uint8(rct_drawpixelinfo *dpi, uint8 *history, int
|
||||
x = baseX;
|
||||
for (i = count - 1; i >= 0; i--) {
|
||||
if (history[i] != 0 && history[i] != 255) {
|
||||
y = baseY + (history[i] * 100) / 256;
|
||||
y = baseY + ((255 - history[i]) * 100) / 256;
|
||||
|
||||
if (lastX != -1)
|
||||
gfx_draw_line(dpi, lastX, lastY, x, y, 21);
|
||||
|
||||
209
src/language.c
Normal file
209
src/language.c
Normal file
@@ -0,0 +1,209 @@
|
||||
/*****************************************************************************
|
||||
* Copyright (c) 2014 Ted John
|
||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
||||
*
|
||||
* This file is part of OpenRCT2.
|
||||
*
|
||||
* OpenRCT2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "addresses.h"
|
||||
#include "language.h"
|
||||
#include "string_ids.h"
|
||||
|
||||
const char *language_names[LANGUAGE_COUNT] = {
|
||||
"", // LANGUAGE_UNDEFINED
|
||||
"English (UK)", // LANGUAGE_ENGLISH_UK
|
||||
"English (US)", // LANGUAGE_ENGLISH_US
|
||||
"Nederlands", // LANGUAGE_DUTCH
|
||||
"Fran\u00e7ais" // LANGUAGE_FRENCH
|
||||
};
|
||||
|
||||
const char *language_filenames[LANGUAGE_COUNT] = {
|
||||
"", // LANGUAGE_UNDEFINED
|
||||
"english_uk", // LANGUAGE_ENGLISH_UK
|
||||
"english_us", // LANGUAGE_ENGLISH_US
|
||||
"dutch", // LANGUAGE_DUTCH
|
||||
"french" // LANGUAGE_FRENCH
|
||||
};
|
||||
|
||||
int gCurrentLanguage = LANGUAGE_UNDEFINED;
|
||||
|
||||
// Buffer storing all the string data
|
||||
long language_buffer_size = 0;
|
||||
char *language_buffer = NULL;
|
||||
|
||||
// List of string pointers into the string data
|
||||
int language_num_strings = 0;
|
||||
char **language_strings = NULL;
|
||||
|
||||
static int language_open_file(const char *filename);
|
||||
|
||||
static int utf8_get_next(char *char_ptr, char **nextchar_ptr)
|
||||
{
|
||||
int result;
|
||||
int numBytes;
|
||||
|
||||
if (!(char_ptr[0] & 0x80)) {
|
||||
result = char_ptr[0];
|
||||
numBytes = 1;
|
||||
} else if (!(char_ptr[0] & 0x20)) {
|
||||
result = ((char_ptr[0] & 0x1F) << 6) | (char_ptr[1] & 0x3F);
|
||||
numBytes = 2;
|
||||
}
|
||||
|
||||
if (nextchar_ptr != NULL)
|
||||
*nextchar_ptr = char_ptr + numBytes;
|
||||
return result;
|
||||
}
|
||||
|
||||
const char *language_get_string(rct_string_id id)
|
||||
{
|
||||
const char *rct = RCT2_ADDRESS(0x009BF2D4, const char*)[id];
|
||||
const char *openrct = language_strings == NULL ? NULL : language_strings[id];
|
||||
const char *str = (openrct == NULL || strlen(openrct) == 0 ? rct : openrct);
|
||||
return str == NULL ? "" : str;
|
||||
}
|
||||
|
||||
int language_open(int id)
|
||||
{
|
||||
char filename[_MAX_PATH];
|
||||
|
||||
language_close();
|
||||
if (id == LANGUAGE_UNDEFINED)
|
||||
return 1;
|
||||
|
||||
sprintf(filename, "data/language/%s.txt", language_filenames[id]);
|
||||
if (language_open_file(filename)) {
|
||||
gCurrentLanguage = id;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Partial support to open a uncompiled language file which parses tokens and converts them to the corresponding character
|
||||
* code. Due to resource strings (strings in scenarios and objects) being written to the original game's string table,
|
||||
* get_string will use those if the same entry in the loaded language is empty.
|
||||
*
|
||||
* Unsure at how the original game decides which entries to write resource strings to, but this could affect adding new
|
||||
* strings for the time being. Further investigation is required.
|
||||
*
|
||||
* Also note that all strings are currently still ASCII. It probably can't be converted to UTF-8 until all game functions that
|
||||
* read / write strings in some way is decompiled. The original game used a DIY extended 8-bit extended ASCII set for special
|
||||
* characters, format codes and accents.
|
||||
*
|
||||
* In terms of reading the language files, the STR_XXXX part is read and XXXX becomes the string id number. Everything after the
|
||||
* colon and before the new line will be saved as the string. Tokens are written with inside curly braces {TOKEN}.
|
||||
* Use # at the beginning of a line to leave a comment.
|
||||
*/
|
||||
static int language_open_file(const char *filename)
|
||||
{
|
||||
FILE *f = fopen(filename, "rb");
|
||||
if (f == NULL)
|
||||
return 0;
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
language_buffer_size = ftell(f);
|
||||
language_buffer = calloc(1, language_buffer_size);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
fread(language_buffer, language_buffer_size, 1, f);
|
||||
fclose(f);
|
||||
|
||||
language_strings = calloc(STR_COUNT, sizeof(char*));
|
||||
|
||||
char *dst, *token;
|
||||
char tokenBuffer[64];
|
||||
int i, stringIndex = 0, mode = 0, string_no;
|
||||
for (i = 0; i < language_buffer_size; i++) {
|
||||
char *src = &language_buffer[i];
|
||||
|
||||
// Handle UTF-8
|
||||
char *srcNext;
|
||||
int utf8Char = utf8_get_next(src, &srcNext);
|
||||
i += srcNext - src - 1;
|
||||
if (utf8Char > 0xFF)
|
||||
utf8Char = '?';
|
||||
else if (utf8Char > 0x7F)
|
||||
utf8Char &= 0xFF;
|
||||
|
||||
switch (mode) {
|
||||
case 0:
|
||||
// Search for a comment
|
||||
if (utf8Char == '#') {
|
||||
mode = 3;
|
||||
} else if (utf8Char == ':' && string_no != -1) {
|
||||
// Search for colon
|
||||
dst = src + 1;
|
||||
language_strings[string_no] = dst;
|
||||
stringIndex++;
|
||||
mode = 1;
|
||||
} else if (!strncmp(src, "STR_", 4)){
|
||||
// Copy in the string number, 4 characters only
|
||||
if (sscanf(src, "STR_%4d", &string_no) != 1) {
|
||||
string_no = -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// Copy string over, stop at line break
|
||||
if (utf8Char == '{') {
|
||||
token = src + 1;
|
||||
mode = 2;
|
||||
} else if (utf8Char == '\n' || *src == '\r') {
|
||||
*dst = 0;
|
||||
mode = 0;
|
||||
} else {
|
||||
*dst++ = utf8Char;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
// Read token, convert to code
|
||||
if (utf8Char == '}') {
|
||||
int tokenLength = min(src - token, sizeof(tokenBuffer) - 1);
|
||||
memcpy(tokenBuffer, token, tokenLength);
|
||||
tokenBuffer[tokenLength] = 0;
|
||||
char code = format_get_code(tokenBuffer);
|
||||
if (code == 0)
|
||||
code = atoi(tokenBuffer);
|
||||
*dst++ = code;
|
||||
mode = 1;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (utf8Char == '\n' || utf8Char == '\r') {
|
||||
mode = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
language_num_strings = stringIndex;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void language_close()
|
||||
{
|
||||
if (language_buffer != NULL)
|
||||
free(language_buffer);
|
||||
language_buffer_size = 0;
|
||||
|
||||
if (language_strings != NULL)
|
||||
free(language_strings);
|
||||
language_num_strings = 0;
|
||||
|
||||
gCurrentLanguage = LANGUAGE_UNDEFINED;
|
||||
}
|
||||
43
src/language.h
Normal file
43
src/language.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*****************************************************************************
|
||||
* Copyright (c) 2014 Ted John
|
||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
||||
*
|
||||
* This file is part of OpenRCT2.
|
||||
*
|
||||
* OpenRCT2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _LANGUAGE_H_
|
||||
#define _LANGUAGE_H_
|
||||
|
||||
#include "rct2.h"
|
||||
#include "string_ids.h"
|
||||
|
||||
enum {
|
||||
LANGUAGE_UNDEFINED,
|
||||
LANGUAGE_ENGLISH_UK,
|
||||
LANGUAGE_ENGLISH_US,
|
||||
LANGUAGE_DUTCH,
|
||||
LANGUAGE_FRENCH,
|
||||
LANGUAGE_COUNT
|
||||
};
|
||||
|
||||
extern const char *language_names[LANGUAGE_COUNT];
|
||||
extern int gCurrentLanguage;
|
||||
|
||||
const char *language_get_string(rct_string_id id);
|
||||
int language_open(int id);
|
||||
void language_close();
|
||||
|
||||
#endif
|
||||
26
src/object.c
26
src/object.c
@@ -94,8 +94,34 @@ static int object_calculate_checksum(rct_object_entry *entry, char *data, int da
|
||||
return checksum;
|
||||
}
|
||||
|
||||
/**
|
||||
* rct2: 0x66B355 part
|
||||
* If al is 0
|
||||
* chunk : esi
|
||||
*/
|
||||
int object_scenario_load_custom_text(char* chunk){
|
||||
int ebp = (int)(&((uint32*)chunk)[2]);
|
||||
int edx = 0;
|
||||
int eax, ebx, ecx, edi;
|
||||
RCT2_CALLFUNC_X(0x6A9E24, &eax, &ebx, &ecx, &edx, (int*)&chunk, &edi, &ebp);
|
||||
*((uint16*)chunk) = eax;
|
||||
edx++;
|
||||
RCT2_CALLFUNC_X(0x6A9E24, &eax, &ebx, &ecx, &edx, (int*)&chunk, &edi, &ebp);
|
||||
*((uint16*)chunk + 1) = eax;
|
||||
edx++;
|
||||
RCT2_CALLFUNC_X(0x6A9E24, &eax, &ebx, &ecx, &edx, (int*)&chunk, &edi, &ebp);
|
||||
*((uint16*)chunk + 2) = eax;
|
||||
|
||||
if (RCT2_GLOBAL(0x9ADAF4, int) == -1)return 0;
|
||||
else *(RCT2_GLOBAL(0x9ADAF4, uint32*)) = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int object_paint(int type, int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp)
|
||||
{
|
||||
if (type == 10){
|
||||
if (eax == 0) return object_scenario_load_custom_text((char*)esi);
|
||||
}
|
||||
RCT2_CALLPROC_X(RCT2_ADDRESS(0x0098D9D4, uint32)[type], eax, ebx, ecx, edx, esi, edi, ebp);
|
||||
#ifdef _MSC_VER
|
||||
__asm jb success
|
||||
|
||||
@@ -71,7 +71,7 @@ void park_init()
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PARK_RATING, uint16) = 0;
|
||||
_guestGenerationProbability = 0;
|
||||
RCT2_GLOBAL(RCT2_TOTAL_RIDE_VALUE, uint16) = 0;
|
||||
RCT2_GLOBAL(0x01357CF4, sint32) = -1;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_LAST_RESEARCHED_ITEM_SUBJECT, sint32) = -1;
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
RCT2_ADDRESS(0x01358102, uint8)[i] = 0;
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "game.h"
|
||||
#include "gfx.h"
|
||||
#include "intro.h"
|
||||
#include "language.h"
|
||||
#include "map.h"
|
||||
#include "news_item.h"
|
||||
#include "object.h"
|
||||
@@ -76,9 +77,6 @@ __declspec(dllexport) int StartOpenRCT(HINSTANCE hInstance, HINSTANCE hPrevInsta
|
||||
{
|
||||
print_launch_information();
|
||||
|
||||
// OpenRCT2 initialisation
|
||||
language_open("data/language/english.txt");
|
||||
|
||||
// Begin RCT2
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_HINSTANCE, HINSTANCE) = hInstance;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CMDLINE, LPSTR) = lpCmdLine;
|
||||
@@ -88,6 +86,7 @@ __declspec(dllexport) int StartOpenRCT(HINSTANCE hInstance, HINSTANCE hPrevInsta
|
||||
audio_get_devices();
|
||||
RCT2_CALLPROC(0x0040502E); // get_dsound_devices()
|
||||
config_init();
|
||||
language_open(gGeneral_config.language);
|
||||
rct2_init();
|
||||
rct2_loop();
|
||||
osinterface_free();
|
||||
|
||||
@@ -42,6 +42,12 @@ typedef unsigned long long uint64;
|
||||
#define ror32(x, shift) (((uint32)(x) >> (shift)) | ((uint32)(x) << (32 - (shift))))
|
||||
#define rol64(x, shift) (((uint64)(x) << (shift)) | ((uint32)(x) >> (64 - (shift))))
|
||||
#define ror64(x, shift) (((uint64)(x) >> (shift)) | ((uint32)(x) << (64 - (shift))))
|
||||
#ifndef min
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef max
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
#define sgn(x) ((x > 0) ? 1 : ((x < 0) ? -1 : 0))
|
||||
#define clamp(l, x, h) (min(h, max(l, x)))
|
||||
|
||||
|
||||
@@ -100,7 +100,8 @@ typedef struct {
|
||||
uint16 var_14A;
|
||||
uint8 pad_14C;
|
||||
uint8 var_14D;
|
||||
uint8 pad_14E[0x0A];
|
||||
uint8 pad_14E[0x06];
|
||||
uint32 var_154;
|
||||
uint16 var_158;
|
||||
uint8 pad_15A[0x26];
|
||||
uint16 build_date;
|
||||
|
||||
109
src/string_ids.c
109
src/string_ids.c
@@ -25,6 +25,7 @@
|
||||
#include "currency.h"
|
||||
#include "game.h"
|
||||
#include "date.h"
|
||||
#include "language.h"
|
||||
#include "rct2.h"
|
||||
#include "string_ids.h"
|
||||
#include "util.h"
|
||||
@@ -1471,7 +1472,7 @@ void format_string_code(unsigned char format_code, char **dest, char **args)
|
||||
value = *((uint16*)*args);
|
||||
*args += 2;
|
||||
|
||||
strcpy(*dest, get_string(STR_MONTH_MARCH + date_get_month(value)));
|
||||
strcpy(*dest, language_get_string(STR_MONTH_MARCH + date_get_month(value)));
|
||||
*dest += strlen(*dest);
|
||||
break;
|
||||
case FORMAT_VELOCITY:
|
||||
@@ -1591,7 +1592,7 @@ void format_string_part(char **dest, rct_string_id format, char **args)
|
||||
{
|
||||
if (format < 0x8000) {
|
||||
// Language string
|
||||
format_string_part_from_raw(dest, get_string(format), args);
|
||||
format_string_part_from_raw(dest, language_get_string(format), args);
|
||||
} else if (format < 0x9000) {
|
||||
// Custom string
|
||||
format -= 0x8000;
|
||||
@@ -1690,108 +1691,4 @@ void reset_saved_strings() {
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
RCT2_ADDRESS(0x135A8F4, uint8)[i * 32] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Buffer storing all the string data
|
||||
long language_buffer_size = 0;
|
||||
char *language_buffer = NULL;
|
||||
|
||||
// List of string pointers into the string data
|
||||
int language_num_strings = 0;
|
||||
char **language_strings = NULL;
|
||||
|
||||
const char *get_string(rct_string_id id)
|
||||
{
|
||||
const char *rct = RCT2_ADDRESS(0x009BF2D4, const char*)[id];
|
||||
const char *openrct = language_strings == NULL ? NULL : language_strings[id];
|
||||
const char *str = (openrct == NULL || strlen(openrct) == 0 ? rct : openrct);
|
||||
return str == NULL ? "" : str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Partial support to open a uncompiled language file which parses tokens and converts them to the corresponding character
|
||||
* code. Due to resource strings (strings in scenarios and objects) being written to the original game's string table,
|
||||
* get_string will use those if the same entry in the loaded language is empty.
|
||||
*
|
||||
* Unsure at how the original game decides which entries to write resource strings to, but this could affect adding new
|
||||
* strings for the time being. Further investigation is required.
|
||||
*
|
||||
* Also note that all strings are currently still ASCII. It probably can't be converted to UTF-8 until all game functions that
|
||||
* read / write strings in some way is decompiled. The original game used a DIY extended 8-bit extended ASCII set for special
|
||||
* characters, format codes and accents.
|
||||
*
|
||||
* In terms of reading the language files, the STR_XXXX part is completely ignored at the moment. It just parses each line from
|
||||
* the colon and thus not allowing gaps in the string indices.
|
||||
*/
|
||||
int language_open(const char *filename)
|
||||
{
|
||||
FILE *f = fopen(filename, "rb");
|
||||
if (f == NULL)
|
||||
return 0;
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
language_buffer_size = ftell(f);
|
||||
language_buffer = calloc(1, language_buffer_size);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
fread(language_buffer, language_buffer_size, 1, f);
|
||||
fclose(f);
|
||||
|
||||
language_strings = calloc(STR_COUNT, sizeof(char*));
|
||||
|
||||
char *dst, *token;
|
||||
char tokenBuffer[64];
|
||||
int i, stringIndex = 0, mode = 0;
|
||||
for (i = 0; i < language_buffer_size; i++) {
|
||||
char *src = &language_buffer[i];
|
||||
|
||||
switch (mode) {
|
||||
case 0:
|
||||
// Search for colon
|
||||
if (*src == ':') {
|
||||
dst = src + 1;
|
||||
language_strings[stringIndex++] = dst;
|
||||
mode = 1;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// Copy string over, stop at line break
|
||||
if (*src == '{') {
|
||||
token = src + 1;
|
||||
mode = 2;
|
||||
} else if (*src == '\n' || *src == '\r') {
|
||||
*dst = 0;
|
||||
mode = 0;
|
||||
} else {
|
||||
*dst++ = *src;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
// Read token, convert to code
|
||||
if (*src == '}') {
|
||||
int tokenLength = min(src - token, sizeof(tokenBuffer) - 1);
|
||||
memcpy(tokenBuffer, token, tokenLength);
|
||||
tokenBuffer[tokenLength] = 0;
|
||||
char code = format_get_code(tokenBuffer);
|
||||
if (code == 0)
|
||||
code = atoi(tokenBuffer);
|
||||
*dst++ = code;
|
||||
mode = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
language_num_strings = stringIndex;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void language_close()
|
||||
{
|
||||
if (language_buffer != NULL)
|
||||
free(language_buffer);
|
||||
language_buffer_size = 0;
|
||||
|
||||
if (language_strings != NULL)
|
||||
free(language_strings);
|
||||
language_num_strings = 0;
|
||||
}
|
||||
@@ -28,9 +28,8 @@ void generate_string_file();
|
||||
void reset_saved_strings();
|
||||
void error_string_quit(int error, rct_string_id format);
|
||||
|
||||
const char *get_string(rct_string_id id);
|
||||
int language_open(const char *filename);
|
||||
void language_close();
|
||||
char format_get_code(const char *token);
|
||||
const char *format_get_token(char code);
|
||||
|
||||
enum {
|
||||
// Font format codes
|
||||
@@ -238,6 +237,7 @@ enum {
|
||||
STR_SHOPS_AND_STALLS = 975,
|
||||
STR_RESTROOMS_AND_INFORMATION_KIOSKS = 976,
|
||||
|
||||
STR_RESEARCH_AND_DEVELOPMENT = 983,
|
||||
STR_RAISE_COST_AMOUNT = 984,
|
||||
STR_LOWER_COST_AMOUNT = 985,
|
||||
STR_COST_AMOUNT = 986,
|
||||
@@ -515,7 +515,29 @@ enum {
|
||||
STR_RESEARCH_COST_PER_MONTH = 2265,
|
||||
STR_RESEARCH_PRIORITIES = 2266,
|
||||
|
||||
STR_RESEARCH_TYPE_LABEL = 2269,
|
||||
STR_RESEARCH_PROGRESS_LABEL = 2270,
|
||||
STR_RESEARCH_EXPECTED_LABEL = 2271,
|
||||
STR_RESEARCH_RIDE_LABEL = 2272,
|
||||
STR_RESEARCH_SCENERY_LABEL = 2273,
|
||||
|
||||
STR_RESEARCH_SHOW_DETAILS_TIP = 2274,
|
||||
STR_FINANCES_RESEARCH = 2275,
|
||||
STR_RESEARCH_AND_DEVELOPMENT_TIP = 2276,
|
||||
STR_RESEARCH_UNKNOWN = 2277,
|
||||
|
||||
STR_TRANSPORT_RIDE = 2278,
|
||||
STR_GENTLE_RIDE = 2279,
|
||||
STR_ROLLER_COASTER = 2280,
|
||||
STR_THRILL_RIDE = 2281,
|
||||
STR_WATER_RIDE = 2282,
|
||||
STR_SHOP_STALL = 2283,
|
||||
STR_SCENERY_THEMEING = 2284,
|
||||
|
||||
STR_INITIAL_RESEARCH = 2285,
|
||||
STR_DESIGNING = 2286,
|
||||
STR_COMPLETING_DESIGN = 2287,
|
||||
STR_UNKNOWN = 2288,
|
||||
|
||||
STR_SELECT_SCENARIO = 2291,
|
||||
|
||||
|
||||
@@ -318,11 +318,11 @@ static void widget_tab_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetInd
|
||||
b = w->y + widget->bottom;
|
||||
|
||||
// Get the colour and image
|
||||
colour = w->colours[widget->colour] << 19;
|
||||
colour = w->colours[widget->colour];
|
||||
image = widget->image + 2;
|
||||
|
||||
// Draw coloured image
|
||||
gfx_draw_sprite(dpi, image | colour, l, t, 0);
|
||||
gfx_draw_sprite(dpi, image | (colour << 19), l, t, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -642,7 +642,7 @@ int window_find_widget_from_point(rct_window *w, int x, int y)
|
||||
|
||||
/**
|
||||
* Invalidates the specified window.
|
||||
* rct2: 0x006EB31A
|
||||
* rct2: 0x006EB13A
|
||||
*
|
||||
* @param window The window to invalidate (esi).
|
||||
*/
|
||||
@@ -924,7 +924,7 @@ void window_zoom_in(rct_window *w)
|
||||
w->saved_view_x += v->view_width >> 1;
|
||||
w->saved_view_y += v->view_height >> 1;
|
||||
|
||||
RCT2_CALLPROC_X(0x006EB13A, 0, 0, 0, 0, (int)w, 0, 0);
|
||||
window_invalidate(w);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -951,7 +951,7 @@ void window_zoom_out(rct_window *w)
|
||||
w->saved_view_x -= width / 2;
|
||||
w->saved_view_y -= height >> 1;
|
||||
|
||||
RCT2_CALLPROC_X(0x006EB13A, 0, 0, 0, 0, (int)w, 0, 0);
|
||||
window_invalidate(w);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -287,6 +287,7 @@ enum {
|
||||
WC_CLEAR_SCENERY = 50,
|
||||
WC_MANAGE_TRACK_DESIGN = 89,
|
||||
WC_CHEATS = 110,
|
||||
WC_RESEARCH = 111
|
||||
} WINDOW_CLASS;
|
||||
|
||||
enum PROMPT_MODE {
|
||||
@@ -374,8 +375,10 @@ void window_park_rating_open();
|
||||
void window_finances_open();
|
||||
void window_new_campaign_open(int campaignType);
|
||||
void window_ride_list_open();
|
||||
void window_new_ride_open();
|
||||
void window_banner_open();
|
||||
void window_cheats_open();
|
||||
void window_research_open();
|
||||
|
||||
void window_guest_list_init_vars_a();
|
||||
void window_guest_list_init_vars_b();
|
||||
|
||||
@@ -89,8 +89,8 @@ static rct_widget window_cheats_money_widgets[] = {
|
||||
{ WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 2462}, // tab 1
|
||||
{ WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 2462}, // tab 2
|
||||
{ WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, 2462}, // tab 3
|
||||
{ WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(1), HPL(1), 2760, STR_VERY_HIGH}, // high money
|
||||
{ WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(3), HPL(3), STR_FREE, STR_FREE}, //Park Entrance Fee Toggle
|
||||
{ WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(1), HPL(1), 2760, STR_NONE}, // high money
|
||||
{ WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(3), HPL(3), 2761, STR_NONE}, //Park Entrance Fee Toggle
|
||||
{ WIDGETS_END },
|
||||
};
|
||||
|
||||
@@ -102,8 +102,8 @@ static rct_widget window_cheats_guests_widgets[] = {
|
||||
{ WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 2462 }, // tab 1
|
||||
{ WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 2462 }, // tab 2
|
||||
{ WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, 2462 }, // tab 3
|
||||
{ WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(1), HPL(1), STR_EXTREME, STR_EXTREME}, // happy guests
|
||||
{ WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(3), HPL(3), STR_NONE, STR_NONE}, // happy guests
|
||||
{ WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(1), HPL(1), 2764, STR_NONE}, // happy guests
|
||||
{ WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(3), HPL(3), 2765, STR_NONE}, // happy guests
|
||||
{ WIDGETS_END },
|
||||
};
|
||||
|
||||
@@ -116,10 +116,10 @@ static rct_widget window_cheats_misc_widgets[] = {
|
||||
{ WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 2462 }, // tab 1
|
||||
{ WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 2462 }, // tab 2
|
||||
{ WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, 2462}, // tab 3
|
||||
{ WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(0), HPL(0), STR_NONE, STR_NONE}, // Freeze climate
|
||||
{ WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(1), HPL(1), STR_NONE, STR_NONE}, // open / close park
|
||||
{ WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(2), HPL(2), STR_NONE, STR_NONE}, // decrease game speed
|
||||
{ WWT_CLOSEBOX, 1, XPL(1), WPL(1), YPL(2), HPL(2), STR_NONE, STR_NONE}, // increase game speed
|
||||
{ WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(0), HPL(0), 2767, STR_NONE}, // Freeze climate
|
||||
{ WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(1), HPL(1), 2769, STR_NONE}, // open / close park
|
||||
{ WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(2), HPL(2), 2771, STR_NONE}, // decrease game speed
|
||||
{ WWT_CLOSEBOX, 1, XPL(1), WPL(1), YPL(2), HPL(2), 2772, STR_NONE}, // increase game speed
|
||||
{ WIDGETS_END },
|
||||
};
|
||||
|
||||
@@ -306,8 +306,8 @@ static void window_cheats_money_mouseup()
|
||||
break;
|
||||
case WIDX_PARK_ENTRANCE_FEE:
|
||||
RCT2_GLOBAL(0x13573E5, uint32) ^= 0x020;
|
||||
if (!(RCT2_GLOBAL(0x13573E5, uint32) & 0x020) ) w->widgets[widgetIndex].image = 2010;
|
||||
else w->widgets[widgetIndex].image = STR_FREE;
|
||||
if (!(RCT2_GLOBAL(0x13573E5, uint32) & 0x020) ) w->widgets[widgetIndex].image = 2762;
|
||||
else w->widgets[widgetIndex].image = 2761;
|
||||
window_invalidate_by_id(0x40 | WC_PARK_INFORMATION, 0);
|
||||
break;
|
||||
}
|
||||
@@ -384,10 +384,12 @@ static void window_cheats_misc_mouseup()
|
||||
break;
|
||||
case WIDX_FREEZE_CLIMATE:
|
||||
toggle_climate_lock();
|
||||
w->widgets[widgetIndex].image = w->widgets[widgetIndex].image == 2767 ? 2768 : 2767;
|
||||
window_invalidate_by_id(0x40 | WC_BOTTOM_TOOLBAR, 0);
|
||||
break;
|
||||
case WIDX_OPEN_CLOSE_PARK:
|
||||
game_do_command(0, 1, 0, park_is_open() ? 0 : 0x101, GAME_COMMAND_SET_PARK_OPEN, 0, 0);
|
||||
w->widgets[widgetIndex].image = w->widgets[widgetIndex].image == 2769 ? 2770 : 2769;
|
||||
window_invalidate_by_id(0x40 | WC_BOTTOM_TOOLBAR, 0);
|
||||
break;
|
||||
case WIDX_DECREASE_GAME_SPEED:
|
||||
@@ -478,23 +480,10 @@ static void window_cheats_paint()
|
||||
// Format text
|
||||
sprintf(buffer, "%c%c%s", FORMAT_MEDIUMFONT, FORMAT_BLACK, "Increases every peeps happiness to max.");
|
||||
// Draw shadow
|
||||
gfx_draw_string(dpi, buffer, 0, w->x + 4, w->y + 50);
|
||||
gfx_draw_string(dpi, buffer, 0, w->x + XPL(0) + TXTO, w->y + YPL(0) + TXTO);
|
||||
|
||||
sprintf(buffer, "%c%c%s", FORMAT_MEDIUMFONT, FORMAT_BLACK, "Large group of peeps arrive");
|
||||
gfx_draw_string(dpi, buffer, 0, w->x + XPL(0) + TXTO, w->y + YPL(2) + TXTO);
|
||||
sprintf(buffer, "%c%c%s", FORMAT_MEDIUMFONT, FORMAT_WINDOW_COLOUR_2, "Large Tram");
|
||||
gfx_draw_string(dpi, buffer, 0, w->x + XPL(0) + TXTO, w->y + YPL(3) + TXTO);
|
||||
}
|
||||
else if (w->page == WINDOW_CHEATS_PAGE_MISC){
|
||||
char buffer[256];
|
||||
sprintf(buffer, "%c%c%s", FORMAT_MEDIUMFONT, FORMAT_WINDOW_COLOUR_2, "Freeze climate");
|
||||
gfx_draw_string(dpi, buffer, 0, w->x + XPL(0) + TXTO, w->y + YPL(0) + TXTO);
|
||||
sprintf(buffer, "%c%c%s", FORMAT_MEDIUMFONT, FORMAT_WINDOW_COLOUR_2, "Open/Close Park");
|
||||
gfx_draw_string(dpi, buffer, 0, w->x + XPL(0) + TXTO, w->y + YPL(1) + TXTO);
|
||||
sprintf(buffer, "%c%c%s", FORMAT_MEDIUMFONT, FORMAT_WINDOW_COLOUR_2, "Slower Gamespeed");
|
||||
gfx_draw_string(dpi, buffer, 0, w->x + XPL(0) + TXTO, w->y + YPL(2) + TXTO);
|
||||
sprintf(buffer, "%c%c%s", FORMAT_MEDIUMFONT, FORMAT_WINDOW_COLOUR_2, "Faster Gamespeed");
|
||||
gfx_draw_string(dpi, buffer, 0, w->x + XPL(1) + TXTO, w->y + YPL(2) + TXTO);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -48,7 +48,8 @@ enum {
|
||||
WIDX_GUESTS,
|
||||
WIDX_CLEAR_SCENERY,
|
||||
|
||||
WIDX_FASTFORWARD
|
||||
WIDX_FASTFORWARD,
|
||||
WIDX_RESEARCH
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@@ -93,8 +94,8 @@ static rct_widget window_game_top_toolbar_widgets[] = {
|
||||
{ WWT_TRNBTN, 3, 0x0230, 0x024D, 0, 27, 0x20000000 | SPR_TOOLBAR_GUESTS, STR_GUESTS_TIP }, // Guests
|
||||
{ WWT_TRNBTN, 2, 0x0230, 0x024D, 0, 27, 0x20000000 | SPR_TOOLBAR_CLEAR_SCENERY, STR_CLEAR_SCENERY_TIP }, // Clear scenery
|
||||
|
||||
{ WWT_TRNBTN, 0, 0x001E, 0x003B, 0, 27, 0x20000000 | 0x15F9, STR_NONE }, // Fast forward
|
||||
|
||||
{ WWT_TRNBTN, 0, 0x001E, 0x003B, 0, 27, 0x20000000 | 0x15F9, STR_NONE }, // Fast forward
|
||||
{ WWT_TRNBTN, 3, 0x001E, 0x003B, 0, 27, 0x20000000 | 0x15F9, 2275 }, // Research
|
||||
{ WIDGETS_END },
|
||||
};
|
||||
|
||||
@@ -152,8 +153,27 @@ void window_game_top_toolbar_open()
|
||||
WF_STICK_TO_FRONT | WF_TRANSPARENT | WF_5
|
||||
);
|
||||
window->widgets = window_game_top_toolbar_widgets;
|
||||
window->enabled_widgets |= (1 | 2 | 4 | 8 | 0x10 | 0x20 | 0x40 | 0x80 | 0x100 | 0x200 | 0x400 | 0x800 |
|
||||
0x1000 | 0x2000 | 0x4000 | 0x8000 | 0x10000 | 0x20000);
|
||||
|
||||
window->enabled_widgets |=
|
||||
(1 << WIDX_PAUSE) |
|
||||
(1 << WIDX_FILE_MENU) |
|
||||
(1 << WIDX_ZOOM_OUT) |
|
||||
(1 << WIDX_ZOOM_IN) |
|
||||
(1 << WIDX_ROTATE) |
|
||||
(1 << WIDX_VIEW_MENU) |
|
||||
(1 << WIDX_MAP) |
|
||||
(1 << WIDX_LAND) |
|
||||
(1 << WIDX_WATER) |
|
||||
(1 << WIDX_SCENERY) |
|
||||
(1 << WIDX_PATH) |
|
||||
(1 << WIDX_CONSTRUCT_RIDE) |
|
||||
(1 << WIDX_RIDES) |
|
||||
(1 << WIDX_PARK) |
|
||||
(1 << WIDX_STAFF) |
|
||||
(1 << WIDX_CLEAR_SCENERY) |
|
||||
(1ULL << WIDX_FASTFORWARD) |
|
||||
(1ULL << WIDX_RESEARCH);
|
||||
|
||||
window_init_scroll_widgets(window);
|
||||
window->colours[0] = 7;
|
||||
window->colours[1] = 12;
|
||||
@@ -170,22 +190,13 @@ static void window_game_top_toolbar_mouseup()
|
||||
short widgetIndex;
|
||||
rct_window *w, *mainWindow;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov widgetIndex, dx
|
||||
#else
|
||||
__asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) );
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov w, esi
|
||||
#else
|
||||
__asm__ ( "mov %[w], esi " : [w] "+m" (w) );
|
||||
#endif
|
||||
|
||||
window_mouse_up_get_registers(w, widgetIndex);
|
||||
|
||||
switch (widgetIndex) {
|
||||
case WIDX_PAUSE:
|
||||
game_do_command(0, 1, 0, 0, GAME_COMMAND_TOGGLE_PAUSE, 0, 0);
|
||||
// Not sure where this was done in the original code
|
||||
w->pressed_widgets ^= (1 << WIDX_PAUSE);
|
||||
break;
|
||||
case WIDX_FASTFORWARD:
|
||||
// This is an excellent place to add in debugging statements and
|
||||
@@ -209,7 +220,6 @@ static void window_game_top_toolbar_mouseup()
|
||||
window_rotate_camera(mainWindow);
|
||||
break;
|
||||
case WIDX_MAP:
|
||||
//RCT2_CALLPROC_EBPSAFE(0x0068C88A);
|
||||
window_map_open();
|
||||
break;
|
||||
case WIDX_CLEAR_SCENERY:
|
||||
@@ -260,7 +270,7 @@ static void window_game_top_toolbar_mouseup()
|
||||
}
|
||||
break;
|
||||
case WIDX_CONSTRUCT_RIDE:
|
||||
RCT2_CALLPROC_EBPSAFE(0x006B3CFF);
|
||||
window_new_ride_open();
|
||||
break;
|
||||
case WIDX_RIDES:
|
||||
window_ride_list_open();
|
||||
@@ -270,11 +280,13 @@ static void window_game_top_toolbar_mouseup()
|
||||
break;
|
||||
case WIDX_STAFF:
|
||||
window_staff_open();
|
||||
//RCT2_CALLPROC_EBPSAFE(0x006BD3CC);
|
||||
break;
|
||||
case WIDX_GUESTS:
|
||||
window_guest_list_open();
|
||||
break;
|
||||
case WIDX_RESEARCH:
|
||||
window_research_open();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,7 +459,7 @@ static void window_game_top_toolbar_dropdown()
|
||||
default:
|
||||
return;
|
||||
}
|
||||
RCT2_CALLPROC_X(0x6EB13A, 0, 0, 0, 0, (int)w, 0, 0);
|
||||
window_invalidate(w);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -488,6 +500,10 @@ static void window_game_top_toolbar_invalidate()
|
||||
window_game_top_toolbar_widgets[WIDX_RIDES].right = x;
|
||||
x -= 29;
|
||||
window_game_top_toolbar_widgets[WIDX_RIDES].left = x;
|
||||
x -= 1;
|
||||
window_game_top_toolbar_widgets[WIDX_RESEARCH].right = x;
|
||||
x -= 29;
|
||||
window_game_top_toolbar_widgets[WIDX_RESEARCH].left = x;
|
||||
x -= 11;
|
||||
window_game_top_toolbar_widgets[WIDX_CONSTRUCT_RIDE].right = x;
|
||||
x -= 29;
|
||||
@@ -524,6 +540,18 @@ static void window_game_top_toolbar_invalidate()
|
||||
w->pressed_widgets |= (1 << WIDX_FASTFORWARD);
|
||||
else
|
||||
w->pressed_widgets &= ~(1 << WIDX_FASTFORWARD);
|
||||
|
||||
// Zoomed out/in disable. Not sure where this code is in the original.
|
||||
if (window_get_main()->viewport->zoom == 0){
|
||||
w->disabled_widgets |= (1 << WIDX_ZOOM_IN);
|
||||
}
|
||||
else if (window_get_main()->viewport->zoom == 3){
|
||||
w->disabled_widgets |= (1 << WIDX_ZOOM_OUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
w->disabled_widgets &= ~((1 << WIDX_ZOOM_IN) | (1 << WIDX_ZOOM_OUT));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -559,4 +587,10 @@ static void window_game_top_toolbar_paint()
|
||||
imgId++;
|
||||
imgId |= (RCT2_GLOBAL(RCT2_ADDRESS_HANDYMAN_COLOUR, uint8) << 19) | 0xA0000000 | (RCT2_GLOBAL(RCT2_ADDRESS_MECHANIC_COLOUR, uint8) << 24);
|
||||
gfx_draw_sprite(dpi, imgId, x, y, 0);
|
||||
|
||||
// Draw research button
|
||||
x = w->x + window_game_top_toolbar_widgets[WIDX_RESEARCH].left - 1;
|
||||
y = w->y + window_game_top_toolbar_widgets[WIDX_RESEARCH].top - 1;
|
||||
imgId = SPR_TAB_FINANCES_RESEARCH_0;
|
||||
gfx_draw_sprite(dpi, imgId, x, y, 0);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,24 @@ enum {
|
||||
WINDOW_NEW_RIDE_TAB_RESEARCH
|
||||
} WINDOW_RIDE_CONSTRUCTION_TAB;
|
||||
|
||||
enum {
|
||||
WIDX_BACKGROUND,
|
||||
WIDX_TITLE,
|
||||
WIDX_CLOSE,
|
||||
WIDX_PAGE_BACKGROUND,
|
||||
WIDX_TAB_1,
|
||||
WIDX_TAB_2,
|
||||
WIDX_TAB_3,
|
||||
WIDX_TAB_4,
|
||||
WIDX_TAB_5,
|
||||
WIDX_TAB_6,
|
||||
WIDX_TAB_7,
|
||||
|
||||
WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP,
|
||||
WIDX_LAST_DEVELOPMENT_GROUP,
|
||||
WIDX_LAST_DEVELOPMENT_BUTTON
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006ACA58
|
||||
@@ -55,4 +73,54 @@ void window_new_ride_init_vars() {
|
||||
}
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_RIDE_LIST_INFORMATION_TYPE, uint8) = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B3CFF
|
||||
*/
|
||||
void window_new_ride_open()
|
||||
{
|
||||
rct_window *w;
|
||||
|
||||
w = window_bring_to_front_by_id(WC_CONSTRUCT_RIDE, 0);
|
||||
if (w != NULL)
|
||||
return;
|
||||
|
||||
// Not sure what these windows are
|
||||
window_close_by_id(161, 0);
|
||||
window_close_by_id(162, 0);
|
||||
|
||||
w = window_create_auto_pos(601, 370, (uint32*)0x0098E354, WC_CONSTRUCT_RIDE, 0x400);
|
||||
w->widgets = (rct_widget*)0x009AEBF4;
|
||||
w->enabled_widgets =
|
||||
(1 << WIDX_CLOSE) |
|
||||
(1 << WIDX_TAB_1) |
|
||||
(1 << WIDX_TAB_2) |
|
||||
(1 << WIDX_TAB_3) |
|
||||
(1 << WIDX_TAB_4) |
|
||||
(1 << WIDX_TAB_5) |
|
||||
(1 << WIDX_TAB_6) |
|
||||
(1 << WIDX_TAB_7) |
|
||||
(1 << 14) |
|
||||
(1 << 15);
|
||||
window_init_scroll_widgets(w);
|
||||
|
||||
w->frame_no = 0;
|
||||
w->colours[0] = 24;
|
||||
w->colours[1] = 26;
|
||||
w->colours[2] = 26;
|
||||
w->var_480 = -1;
|
||||
w->var_482 = -1;
|
||||
RCT2_GLOBAL(0x00F43866, sint16) = -1;
|
||||
|
||||
RCT2_CALLPROC_EBPSAFE(0x006B6F3E);
|
||||
|
||||
w->var_482 = RCT2_ADDRESS(0x00F43825, sint16)[RCT2_GLOBAL(0x00F43824, uint8)];
|
||||
if (w->var_482 == -1)
|
||||
w->var_482 = RCT2_GLOBAL(0x00F43523, sint16);
|
||||
|
||||
w->width = 1;
|
||||
RCT2_CALLPROC_EBPSAFE(0x006B3DF1); // initialise window size and widgets
|
||||
RCT2_CALLPROC_EBPSAFE(0x006B7220);
|
||||
}
|
||||
@@ -129,18 +129,7 @@ static void window_news_mouseup()
|
||||
short widgetIndex;
|
||||
rct_window *w;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov widgetIndex, dx
|
||||
#else
|
||||
__asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) );
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov w, esi
|
||||
#else
|
||||
__asm__ ( "mov %[w], esi " : [w] "+m" (w) );
|
||||
#endif
|
||||
|
||||
window_mouse_up_get_registers(w, widgetIndex);
|
||||
|
||||
if (widgetIndex == WIDX_CLOSE)
|
||||
window_close(w);
|
||||
@@ -304,18 +293,7 @@ static void window_news_paint()
|
||||
rct_window *w;
|
||||
rct_drawpixelinfo *dpi;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov w, esi
|
||||
#else
|
||||
__asm__ ( "mov %[w], esi " : [w] "+m" (w) );
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov dpi, edi
|
||||
#else
|
||||
__asm__ ( "mov %[dpi], edi " : [dpi] "+m" (dpi) );
|
||||
#endif
|
||||
|
||||
window_paint_get_registers(w, dpi);
|
||||
|
||||
window_draw_widgets(w, dpi);
|
||||
}
|
||||
@@ -331,18 +309,7 @@ static void window_news_scrollpaint()
|
||||
rct_drawpixelinfo *dpi;
|
||||
rct_news_item *newsItems, *newsItem, *newsItem2;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov w, esi
|
||||
#else
|
||||
__asm__ ( "mov %[w], esi " : [w] "+m" (w) );
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov dpi, edi
|
||||
#else
|
||||
__asm__ ( "mov %[dpi], edi " : [dpi] "+m" (dpi) );
|
||||
#endif
|
||||
|
||||
window_paint_get_registers(w, dpi);
|
||||
|
||||
y = 0;
|
||||
newsItems = RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item);
|
||||
@@ -366,9 +333,9 @@ static void window_news_scrollpaint()
|
||||
gfx_draw_string_left(dpi, 2235, (void*)0x013CE952, 2, 4, y);
|
||||
|
||||
// Item text
|
||||
RCT2_GLOBAL(0x009B5F2C, uint8) = newsItem->colour;
|
||||
strcpy((char*)0x009B5F2D, newsItem->text);
|
||||
gfx_draw_string_left_wrapped(dpi, 0, 2, y + 10, 325, 1926, 14);
|
||||
char *sz = (char*)0x013CE952;
|
||||
sprintf(sz, "%c%c%s", newsItem->colour, FORMAT_SMALLFONT, newsItem->text);
|
||||
gfx_draw_string_left_wrapped(dpi, &sz, 2, y + 10, 325, 1170, 14);
|
||||
|
||||
// Subject button
|
||||
if ((RCT2_ADDRESS(0x0097BE7C, uint8)[newsItem->type] & 2) && !(newsItem->flags & 1)) {
|
||||
|
||||
@@ -18,42 +18,49 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* To better group the options together and allow the window to be scalable with additional OpenRCT2 options, the window has
|
||||
* been changed to a tab interface similar to the options window seen in Locomotion.
|
||||
*
|
||||
* TODO Some parts, particularly the string handling and order of widgets needs reorganising.
|
||||
* Padding between the widgets and the window needs reducing, an artifact from originally being inside group boxes.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "addresses.h"
|
||||
#include "audio.h"
|
||||
#include "config.h"
|
||||
#include "gfx.h"
|
||||
#include "language.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 <stdint.h>
|
||||
enum {
|
||||
WINDOW_OPTIONS_PAGE_DISPLAY,
|
||||
WINDOW_OPTIONS_PAGE_CULTURE,
|
||||
WINDOW_OPTIONS_PAGE_AUDIO,
|
||||
WINDOW_OPTIONS_PAGE_INPUT,
|
||||
WINDOW_OPTIONS_PAGE_MISC,
|
||||
WINDOW_OPTIONS_PAGE_COUNT
|
||||
};
|
||||
|
||||
enum WINDOW_OPTIONS_WIDGET_IDX {
|
||||
WIDX_BACKGROUND,
|
||||
WIDX_TITLE,
|
||||
WIDX_CLOSE,
|
||||
WIDX_SOUND_GROUP,
|
||||
WIDX_SOUND,
|
||||
WIDX_SOUND_DROPDOWN,
|
||||
WIDX_MUSIC,
|
||||
WIDX_MUSIC_DROPDOWN,
|
||||
WIDX_SOUND_QUALITY,
|
||||
WIDX_SOUND_QUALITY_DROPDOWN,
|
||||
WIDX_SOUND_SW_BUFFER_CHECKBOX,
|
||||
WIDX_SOUND_PAUSED_CHECKBOX,
|
||||
WIDX_UNITS_GROUP,
|
||||
WIDX_CURRENCY,
|
||||
WIDX_CURRENCY_DROPDOWN,
|
||||
WIDX_DISTANCE,
|
||||
WIDX_DISTANCE_DROPDOWN,
|
||||
WIDX_TEMPERATURE,
|
||||
WIDX_TEMPERATURE_DROPDOWN,
|
||||
WIDX_HEIGHT_LABELS,
|
||||
WIDX_HEIGHT_LABELS_DROPDOWN,
|
||||
WIDX_DISPLAY_GROUP,
|
||||
WIDX_PAGE_BACKGROUND,
|
||||
WIDX_TAB_1,
|
||||
WIDX_TAB_2,
|
||||
WIDX_TAB_3,
|
||||
WIDX_TAB_4,
|
||||
WIDX_TAB_5,
|
||||
|
||||
WIDX_RESOLUTION,
|
||||
WIDX_RESOLUTION_DROPDOWN,
|
||||
WIDX_FULLSCREEN,
|
||||
@@ -62,64 +69,106 @@ enum WINDOW_OPTIONS_WIDGET_IDX {
|
||||
WIDX_GRIDLINES_CHECKBOX,
|
||||
WIDX_CONSTRUCTION_MARKER,
|
||||
WIDX_CONSTRUCTION_MARKER_DROPDOWN,
|
||||
WIDX_CONTROLS_GROUP,
|
||||
|
||||
WIDX_LANGUAGE,
|
||||
WIDX_LANGUAGE_DROPDOWN,
|
||||
WIDX_CURRENCY,
|
||||
WIDX_CURRENCY_DROPDOWN,
|
||||
WIDX_DISTANCE,
|
||||
WIDX_DISTANCE_DROPDOWN,
|
||||
WIDX_TEMPERATURE,
|
||||
WIDX_TEMPERATURE_DROPDOWN,
|
||||
WIDX_HEIGHT_LABELS,
|
||||
WIDX_HEIGHT_LABELS_DROPDOWN,
|
||||
|
||||
WIDX_SOUND,
|
||||
WIDX_SOUND_DROPDOWN,
|
||||
WIDX_MUSIC,
|
||||
WIDX_MUSIC_DROPDOWN,
|
||||
WIDX_SOUND_QUALITY,
|
||||
WIDX_SOUND_QUALITY_DROPDOWN,
|
||||
WIDX_SOUND_SW_BUFFER_CHECKBOX,
|
||||
WIDX_SOUND_PAUSED_CHECKBOX,
|
||||
|
||||
WIDX_SCREEN_EDGE_SCROLLING,
|
||||
WIDX_HOTKEY_DROPDOWN,
|
||||
WIDX_GENERAL_GROUP,
|
||||
|
||||
WIDX_REAL_NAME_CHECKBOX,
|
||||
WIDX_SAVE_PLUGIN_DATA_CHECKBOX
|
||||
WIDX_SAVE_PLUGIN_DATA_CHECKBOX,
|
||||
};
|
||||
|
||||
#define WW 310
|
||||
#define WH 399
|
||||
#define WH 135
|
||||
|
||||
static rct_widget window_options_widgets[] = {
|
||||
{ WWT_FRAME, 0, 0, WW - 1, 0, WH - 1, STR_NONE, STR_NONE },
|
||||
{ WWT_CAPTION, 0, 1, WW - 2, 1, 14, STR_OPTIONS, STR_WINDOW_TITLE_TIP },
|
||||
{ WWT_CLOSEBOX, 0, WW-13, WW - 3, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP },
|
||||
{ WWT_GROUPBOX, 0, 3, 306, 17, 105, STR_SOUND, STR_NONE },
|
||||
{ WWT_DROPDOWN, 0, 10, 299, 31, 42, 0x361, STR_NONE }, // sound
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 32, 41, 0x36C, STR_NONE },
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 46, 57, 0x365, STR_NONE }, // music
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 47, 56, 0x36C, STR_NONE },
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 61, 72, 0x366, STR_NONE }, // sound quality
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 62, 71, 0x36C, STR_NONE },
|
||||
{ WWT_CHECKBOX, 0, 10, 299, 76, 87, STR_SOUND_FORCED_SOFTWARE_BUFFER_MIXING, STR_SOUND_FORCED_SOFTWARE_BUFFER_MIXING_TIP },
|
||||
{ WWT_CHECKBOX, 0, 10, 229, 88, 99, STR_SOUND, STR_NONE }, // enable/disable sound
|
||||
{ WWT_GROUPBOX, 0, 3, 306, 112, 188, STR_UNITS, STR_NONE },
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 126, 137, 0x367, STR_NONE }, // currency
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 127, 136, 0x36C, STR_NONE },//
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 141, 152, 0x368, STR_NONE }, // distance
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 142, 151, 0x36C, STR_NONE },
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 156, 168, 0x36B, STR_NONE }, // temperature
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 157, 166, 0x36C, STR_NONE }, //jjj
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 171, 182, 0x364, STR_NONE }, // height labels
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 172, 181, 0x36C, STR_NONE },
|
||||
{ WWT_GROUPBOX, 0, 3, 306, 194, 285, STR_DISPLAY, STR_NONE },//
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 208, 219, 0x348, STR_NONE }, // resolution
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 209, 218, 0x36C, STR_NONE },
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 223, 234, 0x348, STR_NONE }, // fullscreen
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 224, 233, 0x36C, STR_NONE },
|
||||
{ WWT_CHECKBOX, 0, 10, 299, 239, 250, STR_TILE_SMOOTHING, STR_TILE_SMOOTHING_TIP },
|
||||
{ WWT_CHECKBOX, 0, 10, 299, 254, 265, STR_GRIDLINES, STR_GRIDLINES_TIP },
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 268, 279, STR_NONE, STR_NONE }, // construction marker
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 269, 278, 0x36C, STR_NONE },
|
||||
{ WWT_GROUPBOX, 0, 3, 306, 291, 337, STR_CONTROLS, STR_NONE },
|
||||
{ WWT_CHECKBOX, 2, 10, 299, 306, 317, STR_SCREEN_EDGE_SCROLLING, STR_SCREEN_EDGE_SCROLLING_TIP },
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 26, 185, 321, 331, STR_HOTKEY, STR_HOTKEY_TIP },
|
||||
{ WWT_GROUPBOX, 0, 3, 306, 344, 392, STR_GENERAL, STR_NONE },
|
||||
{ WWT_CHECKBOX, 2, 10, 299, 358, 369, STR_REAL_NAME, STR_REAL_NAME_TIP },
|
||||
{ WWT_CHECKBOX, 2, 10, 299, 372, 384, STR_SAVE_PLUGIN_DATA, STR_SAVE_PLUGIN_DATA_TIP },
|
||||
{ WWT_RESIZE, 1, 0, WW - 1, 43, WH - 1, 0xFFFFFFFF, STR_NONE },
|
||||
{ WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, STR_NONE },
|
||||
{ WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, STR_NONE },
|
||||
{ WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, STR_NONE },
|
||||
{ WWT_TAB, 1, 96, 126, 17, 43, 0x2000144E, STR_NONE },
|
||||
{ WWT_TAB, 1, 127, 157, 17, 43, 0x2000144E, STR_NONE },
|
||||
|
||||
// Display tab
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 53, 64, 840, STR_NONE }, // resolution
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 54, 63, 876, STR_NONE },
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 68, 79, 871, STR_NONE }, // fullscreen
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 69, 78, 876, STR_NONE },
|
||||
{ WWT_CHECKBOX, 0, 10, 299, 84, 95, STR_TILE_SMOOTHING, STR_TILE_SMOOTHING_TIP },
|
||||
{ WWT_CHECKBOX, 0, 10, 299, 99, 110, STR_GRIDLINES, STR_GRIDLINES_TIP },
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 113, 124, STR_NONE, STR_NONE }, // construction marker
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 114, 123, 876, STR_NONE },
|
||||
|
||||
// Culture / units tab
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 53, 64, STR_NONE, STR_NONE }, // language
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 54, 63, 876, STR_NONE },
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 68, 79, 871, STR_NONE }, // currency
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 69, 78, 876, STR_NONE }, //
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 83, 94, 872, STR_NONE }, // distance
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 84, 93, 876, STR_NONE },
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 98, 110, 875, STR_NONE }, // temperature
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 99, 108, 876, STR_NONE }, //jjj
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 113, 124, 868, STR_NONE }, // height labels
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 114, 123, 876, STR_NONE },
|
||||
|
||||
// Audio tab
|
||||
{ WWT_DROPDOWN, 0, 10, 299, 53, 64, 865, STR_NONE }, // sound
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 54, 63, 876, STR_NONE },
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 68, 79, 869, STR_NONE }, // music
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 69, 78, 876, STR_NONE },
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 83, 94, 870, STR_NONE }, // sound quality
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 84, 93, 876, STR_NONE },
|
||||
{ WWT_CHECKBOX, 0, 10, 299, 99, 110, STR_SOUND_FORCED_SOFTWARE_BUFFER_MIXING, STR_SOUND_FORCED_SOFTWARE_BUFFER_MIXING_TIP },
|
||||
{ WWT_CHECKBOX, 0, 10, 229, 114, 125, STR_SOUND, STR_NONE }, // enable/disable sound
|
||||
|
||||
// Controls tab
|
||||
{ WWT_CHECKBOX, 2, 10, 299, 53, 64, STR_SCREEN_EDGE_SCROLLING, STR_SCREEN_EDGE_SCROLLING_TIP },
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 26, 185, 68, 78, STR_HOTKEY, STR_HOTKEY_TIP },
|
||||
|
||||
// Misc
|
||||
{ WWT_CHECKBOX, 2, 10, 299, 53, 64, STR_REAL_NAME, STR_REAL_NAME_TIP },
|
||||
{ WWT_CHECKBOX, 2, 10, 299, 68, 79, STR_SAVE_PLUGIN_DATA, STR_SAVE_PLUGIN_DATA_TIP },
|
||||
{ WIDGETS_END },
|
||||
};
|
||||
|
||||
const int window_options_tab_animation_divisor[] = { 4, 8, 2, 2, 2 };
|
||||
const int window_options_tab_animation_frames[] = { 16, 8, 16, 4, 16 };
|
||||
|
||||
static void window_options_set_page(rct_window *w, int page);
|
||||
static void window_options_set_pressed_tab(rct_window *w);
|
||||
static void window_options_draw_tab_image(rct_drawpixelinfo *dpi, rct_window *w, int page, int spriteIndex);
|
||||
static void window_options_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w);
|
||||
|
||||
static void window_options_emptysub() { }
|
||||
static void window_options_mouseup();
|
||||
static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget* widget);
|
||||
static void window_options_dropdown();
|
||||
static void window_options_update(rct_window *w);
|
||||
static void window_options_invalidate();
|
||||
static void window_options_paint();
|
||||
static void window_options_draw_dropdown_box(rct_window *w, rct_widget *widget, int num_items);
|
||||
static void window_options_show_dropdown(rct_window *w, rct_widget *widget, int num_items);
|
||||
static void window_options_update_height_markers();
|
||||
|
||||
static void* window_options_events[] = {
|
||||
@@ -129,7 +178,7 @@ static void* window_options_events[] = {
|
||||
window_options_mousedown,
|
||||
window_options_dropdown,
|
||||
window_options_emptysub,
|
||||
window_options_emptysub,
|
||||
window_options_update,
|
||||
window_options_emptysub,
|
||||
window_options_emptysub,
|
||||
window_options_emptysub,
|
||||
@@ -169,36 +218,42 @@ void window_options_open()
|
||||
w = window_create_auto_pos(WW, WH, (uint32*)window_options_events, WC_OPTIONS, 0);
|
||||
w->widgets = window_options_widgets;
|
||||
w->enabled_widgets =
|
||||
(1 << WIDX_CLOSE) |
|
||||
(1 << WIDX_SOUND) |
|
||||
(1 << WIDX_SOUND_DROPDOWN) |
|
||||
(1 << WIDX_MUSIC) |
|
||||
(1 << WIDX_MUSIC_DROPDOWN) |
|
||||
(1 << WIDX_SOUND_QUALITY) |
|
||||
(1 << WIDX_SOUND_QUALITY_DROPDOWN) |
|
||||
(1 << WIDX_CURRENCY) |
|
||||
(1 << WIDX_CURRENCY_DROPDOWN) |
|
||||
(1 << WIDX_DISTANCE) |
|
||||
(1 << WIDX_DISTANCE_DROPDOWN) |
|
||||
(1 << WIDX_RESOLUTION) |
|
||||
(1 << WIDX_RESOLUTION_DROPDOWN) |
|
||||
(1 << WIDX_FULLSCREEN) |
|
||||
(1 << WIDX_FULLSCREEN_DROPDOWN) |
|
||||
(1 << WIDX_TEMPERATURE) |
|
||||
(1 << WIDX_TEMPERATURE_DROPDOWN) |
|
||||
(1ULL << WIDX_CLOSE) |
|
||||
(1ULL << WIDX_TAB_1) |
|
||||
(1ULL << WIDX_TAB_2) |
|
||||
(1ULL << WIDX_TAB_3) |
|
||||
(1ULL << WIDX_TAB_4) |
|
||||
(1ULL << WIDX_TAB_5) |
|
||||
(1ULL << WIDX_SOUND) |
|
||||
(1ULL << WIDX_SOUND_DROPDOWN) |
|
||||
(1ULL << WIDX_MUSIC) |
|
||||
(1ULL << WIDX_MUSIC_DROPDOWN) |
|
||||
(1ULL << WIDX_SOUND_QUALITY) |
|
||||
(1ULL << WIDX_SOUND_QUALITY_DROPDOWN) |
|
||||
(1ULL << WIDX_CURRENCY) |
|
||||
(1ULL << WIDX_CURRENCY_DROPDOWN) |
|
||||
(1ULL << WIDX_DISTANCE) |
|
||||
(1ULL << WIDX_DISTANCE_DROPDOWN) |
|
||||
(1ULL << WIDX_RESOLUTION) |
|
||||
(1ULL << WIDX_RESOLUTION_DROPDOWN) |
|
||||
(1ULL << WIDX_FULLSCREEN) |
|
||||
(1ULL << WIDX_FULLSCREEN_DROPDOWN) |
|
||||
(1ULL << WIDX_TEMPERATURE) |
|
||||
(1ULL << WIDX_TEMPERATURE_DROPDOWN) |
|
||||
(1ULL << WIDX_HOTKEY_DROPDOWN) |
|
||||
(1ULL << WIDX_SCREEN_EDGE_SCROLLING) |
|
||||
(1ULL << WIDX_REAL_NAME_CHECKBOX) |
|
||||
(1 << WIDX_CONSTRUCTION_MARKER) |
|
||||
(1 << WIDX_CONSTRUCTION_MARKER_DROPDOWN) |
|
||||
(1 << WIDX_HEIGHT_LABELS) |
|
||||
(1 << WIDX_HEIGHT_LABELS_DROPDOWN) |
|
||||
(1 << WIDX_TILE_SMOOTHING_CHECKBOX) |
|
||||
(1 << WIDX_GRIDLINES_CHECKBOX) |
|
||||
(1 << WIDX_SOUND_SW_BUFFER_CHECKBOX) |
|
||||
(1 << WIDX_SOUND_PAUSED_CHECKBOX) |
|
||||
(1ULL << WIDX_CONSTRUCTION_MARKER) |
|
||||
(1ULL << WIDX_CONSTRUCTION_MARKER_DROPDOWN) |
|
||||
(1ULL << WIDX_HEIGHT_LABELS) |
|
||||
(1ULL << WIDX_HEIGHT_LABELS_DROPDOWN) |
|
||||
(1ULL << WIDX_TILE_SMOOTHING_CHECKBOX) |
|
||||
(1ULL << WIDX_GRIDLINES_CHECKBOX) |
|
||||
(1ULL << WIDX_SOUND_SW_BUFFER_CHECKBOX) |
|
||||
(1ULL << WIDX_SOUND_PAUSED_CHECKBOX) |
|
||||
(1ULL << WIDX_SAVE_PLUGIN_DATA_CHECKBOX); // doesn't seem to work?
|
||||
|
||||
w->page = WINDOW_OPTIONS_PAGE_DISPLAY;
|
||||
window_init_scroll_widgets(w);
|
||||
w->colours[0] = 7;
|
||||
w->colours[1] = 7;
|
||||
@@ -214,23 +269,19 @@ static void window_options_mouseup()
|
||||
short widgetIndex;
|
||||
rct_window *w;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov widgetIndex, dx
|
||||
#else
|
||||
__asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) );
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov w, esi
|
||||
#else
|
||||
__asm__ ( "mov %[w], esi " : [w] "+m" (w) );
|
||||
#endif
|
||||
|
||||
window_mouse_up_get_registers(w, widgetIndex);
|
||||
|
||||
switch (widgetIndex) {
|
||||
case WIDX_CLOSE:
|
||||
window_close(w);
|
||||
break;
|
||||
case WIDX_TAB_1:
|
||||
case WIDX_TAB_2:
|
||||
case WIDX_TAB_3:
|
||||
case WIDX_TAB_4:
|
||||
case WIDX_TAB_5:
|
||||
window_options_set_page(w, widgetIndex - WIDX_TAB_1);
|
||||
break;
|
||||
case WIDX_HOTKEY_DROPDOWN:
|
||||
RCT2_CALLPROC_EBPSAFE(0x006E3884);
|
||||
break;
|
||||
@@ -326,7 +377,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
|
||||
gDropdownItemsArgs[i] = 1170 | ((uint64)(intptr_t)gAudioDevices[i].name << 16);
|
||||
}
|
||||
|
||||
window_options_draw_dropdown_box(w, widget, gAudioDeviceCount);
|
||||
window_options_show_dropdown(w, widget, gAudioDeviceCount);
|
||||
|
||||
gDropdownItemsChecked |= (1 << RCT2_GLOBAL(0x9AF280, uint32));
|
||||
break;
|
||||
@@ -336,7 +387,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
|
||||
gDropdownItemsArgs[0] = STR_UNITS;
|
||||
gDropdownItemsArgs[1] = STR_REAL_VALUES;
|
||||
|
||||
window_options_draw_dropdown_box(w, widget, 2);
|
||||
window_options_show_dropdown(w, widget, 2);
|
||||
|
||||
gDropdownItemsChecked =
|
||||
(RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) &
|
||||
@@ -348,7 +399,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
|
||||
gDropdownItemsArgs[0] = STR_OFF;
|
||||
gDropdownItemsArgs[1] = STR_ON;
|
||||
|
||||
window_options_draw_dropdown_box(w, widget, 2);
|
||||
window_options_show_dropdown(w, widget, 2);
|
||||
|
||||
gDropdownItemsChecked = 1 << RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_MUSIC, uint8);
|
||||
break;
|
||||
@@ -360,7 +411,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
|
||||
gDropdownItemsArgs[i] = STR_SOUND_LOW + i; // low, medium, high
|
||||
}
|
||||
|
||||
window_options_draw_dropdown_box(w, widget, num_items);
|
||||
window_options_show_dropdown(w, widget, num_items);
|
||||
|
||||
gDropdownItemsChecked = 1 << RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_QUALITY, uint8);
|
||||
break;
|
||||
@@ -372,7 +423,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
|
||||
gDropdownItemsArgs[i] = STR_POUNDS + i; // all different currencies
|
||||
}
|
||||
|
||||
window_options_draw_dropdown_box(w, widget, num_items);
|
||||
window_options_show_dropdown(w, widget, num_items);
|
||||
|
||||
gDropdownItemsChecked = 1 << (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_CURRENCY, uint8) & 0x3F);
|
||||
break;
|
||||
@@ -382,7 +433,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
|
||||
gDropdownItemsArgs[0] = STR_IMPERIAL;
|
||||
gDropdownItemsArgs[1] = STR_METRIC;
|
||||
|
||||
window_options_draw_dropdown_box(w, widget, 2);
|
||||
window_options_show_dropdown(w, widget, 2);
|
||||
|
||||
gDropdownItemsChecked = 1 << RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_METRIC, uint8);
|
||||
break;
|
||||
@@ -393,11 +444,11 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
|
||||
gDropdownItemsFormat[0] = 1142;
|
||||
gDropdownItemsFormat[1] = 1142;
|
||||
gDropdownItemsFormat[2] = 1142;
|
||||
gDropdownItemsArgs[0] = STR_CELSIUS;
|
||||
gDropdownItemsArgs[1] = STR_FAHRENHEIT;
|
||||
gDropdownItemsArgs[2] = STR_METRIC;
|
||||
gDropdownItemsArgs[0] = 2773;
|
||||
gDropdownItemsArgs[1] = 2774;
|
||||
gDropdownItemsArgs[2] = 2775;
|
||||
|
||||
window_options_draw_dropdown_box(w, widget, 3);
|
||||
window_options_show_dropdown(w, widget, 3);
|
||||
|
||||
gDropdownItemsChecked = 1 << gGeneral_config.fullscreen_mode;
|
||||
break;
|
||||
@@ -407,7 +458,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
|
||||
gDropdownItemsArgs[0] = STR_CELSIUS;
|
||||
gDropdownItemsArgs[1] = STR_FAHRENHEIT;
|
||||
|
||||
window_options_draw_dropdown_box(w, widget, 2);
|
||||
window_options_show_dropdown(w, widget, 2);
|
||||
|
||||
gDropdownItemsChecked = 1 << RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_TEMPERATURE, uint8);
|
||||
break;
|
||||
@@ -417,10 +468,18 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
|
||||
gDropdownItemsArgs[0] = STR_WHITE;
|
||||
gDropdownItemsArgs[1] = STR_TRANSLUCENT;
|
||||
|
||||
window_options_draw_dropdown_box(w, widget, 2);
|
||||
window_options_show_dropdown(w, widget, 2);
|
||||
|
||||
gDropdownItemsChecked = 1 << RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_CONSTRUCTION_MARKER, uint8);
|
||||
break;
|
||||
case WIDX_LANGUAGE_DROPDOWN:
|
||||
for (i = 1; i < LANGUAGE_COUNT; i++) {
|
||||
gDropdownItemsFormat[i - 1] = 2777;
|
||||
gDropdownItemsArgs[i - 1] = (sint64)language_names[i];
|
||||
}
|
||||
window_options_show_dropdown(w, widget, LANGUAGE_COUNT - 1);
|
||||
gDropdownItemsChecked = 1 << (gCurrentLanguage - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,24 +493,7 @@ static void window_options_dropdown()
|
||||
short widgetIndex;
|
||||
rct_window *w;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov dropdownIndex, ax
|
||||
#else
|
||||
__asm__ ( "mov %[dropdownIndex], ax " : [dropdownIndex] "+m" (dropdownIndex) );
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov widgetIndex, dx
|
||||
#else
|
||||
__asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) );
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov w, esi
|
||||
#else
|
||||
__asm__ ( "mov %[w], esi " : [w] "+m" (w) );
|
||||
#endif
|
||||
|
||||
window_dropdown_get_registers(w, widgetIndex, dropdownIndex);
|
||||
|
||||
if (dropdownIndex == -1)
|
||||
return;
|
||||
@@ -521,8 +563,7 @@ static void window_options_dropdown()
|
||||
if (dropdownIndex == 2){
|
||||
w->disabled_widgets |= (1 << WIDX_RESOLUTION_DROPDOWN);
|
||||
w->disabled_widgets |= (1 << WIDX_RESOLUTION);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
w->disabled_widgets &= ~(1 << WIDX_RESOLUTION_DROPDOWN);
|
||||
w->disabled_widgets &= ~(1 << WIDX_RESOLUTION);
|
||||
}
|
||||
@@ -544,6 +585,14 @@ static void window_options_dropdown()
|
||||
gfx_invalidate_screen();
|
||||
}
|
||||
break;
|
||||
case WIDX_LANGUAGE_DROPDOWN:
|
||||
if (dropdownIndex != gCurrentLanguage - 1) {
|
||||
language_open(dropdownIndex + 1);
|
||||
gGeneral_config.language = dropdownIndex + 1;
|
||||
config_save();
|
||||
gfx_invalidate_screen();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,107 +603,154 @@ static void window_options_dropdown()
|
||||
static void window_options_invalidate()
|
||||
{
|
||||
rct_window *w;
|
||||
#ifdef _MSC_VER
|
||||
__asm mov w, esi
|
||||
#else
|
||||
__asm__ ( "mov %[w], esi " : [w] "+m" (w) );
|
||||
#endif
|
||||
int i;
|
||||
sint32 currentSoundDevice;
|
||||
|
||||
sint32 currentSoundDevice = RCT2_GLOBAL(0x009AF280, sint32);
|
||||
window_get_register(w);
|
||||
|
||||
// sound devices
|
||||
if (currentSoundDevice == -1 || gAudioDeviceCount == 0) {
|
||||
RCT2_GLOBAL(0x013CE952, uint16) = STR_SOUND_NONE;
|
||||
} else {
|
||||
RCT2_GLOBAL(0x013CE952, uint16) = 1170;
|
||||
RCT2_GLOBAL(0x013CE952 + 2, uint32) = (uint32)gAudioDevices[currentSoundDevice].name;
|
||||
window_options_set_pressed_tab(w);
|
||||
for (i = WIDX_RESOLUTION; i <= WIDX_SAVE_PLUGIN_DATA_CHECKBOX; i++) {
|
||||
window_options_widgets[i].type = WWT_EMPTY;
|
||||
}
|
||||
|
||||
// height: units/real values
|
||||
RCT2_GLOBAL(0x013CE952 + 6, uint16) = ((RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS)) ?
|
||||
STR_UNITS : STR_REAL_VALUES;
|
||||
|
||||
// music: on/off
|
||||
RCT2_GLOBAL(0x013CE952 + 8, uint16) = STR_OFF +
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_MUSIC, uint8);
|
||||
|
||||
// sound quality: low/medium/high
|
||||
RCT2_GLOBAL(0x013CE952 + 10, uint16) = STR_SOUND_LOW +
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_QUALITY, uint8);
|
||||
|
||||
// currency: pounds, dollars, etc. (10 total)
|
||||
RCT2_GLOBAL(0x013CE952 + 12, uint16) = STR_POUNDS +
|
||||
(RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_CURRENCY, uint8) & 0x3F);
|
||||
switch (w->page) {
|
||||
case WINDOW_OPTIONS_PAGE_DISPLAY:
|
||||
// resolution
|
||||
RCT2_GLOBAL(0x013CE952 + 16, uint16) = RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_RESOLUTION_WIDTH, uint16);
|
||||
RCT2_GLOBAL(0x013CE952 + 18, uint16) = RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_RESOLUTION_HEIGHT, uint16);
|
||||
RCT2_GLOBAL(0x013CE952 + 12, uint16) = 2773 + gGeneral_config.fullscreen_mode;
|
||||
|
||||
// distance: metric/imperial
|
||||
RCT2_GLOBAL(0x013CE952 + 14, uint16) = STR_IMPERIAL +
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_METRIC, uint8);
|
||||
// landscape tile smoothing checkbox
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & CONFIG_FLAG_DISABLE_SMOOTH_LANDSCAPE))
|
||||
w->pressed_widgets &= ~(1ULL << WIDX_TILE_SMOOTHING_CHECKBOX);
|
||||
else
|
||||
w->pressed_widgets |= (1ULL << WIDX_TILE_SMOOTHING_CHECKBOX);
|
||||
|
||||
// resolution
|
||||
RCT2_GLOBAL(0x013CE952 + 16, uint16) =
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_RESOLUTION_WIDTH, uint16);
|
||||
RCT2_GLOBAL(0x013CE952 + 18, uint16) =
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_RESOLUTION_HEIGHT, uint16);
|
||||
// show gridlines checkbox
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES))
|
||||
w->pressed_widgets |= (1ULL << WIDX_GRIDLINES_CHECKBOX);
|
||||
else
|
||||
w->pressed_widgets &= ~(1ULL << WIDX_GRIDLINES_CHECKBOX);
|
||||
|
||||
// temperature: celsius/fahrenheit
|
||||
RCT2_GLOBAL(0x013CE952 + 20, uint16) = STR_CELSIUS +
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_TEMPERATURE, uint8);
|
||||
// construction marker: celsius/fahrenheit
|
||||
window_options_widgets[WIDX_CONSTRUCTION_MARKER].image = STR_WHITE + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_CONSTRUCTION_MARKER, uint8);
|
||||
|
||||
// construction marker: celsius/fahrenheit
|
||||
window_options_widgets[WIDX_CONSTRUCTION_MARKER].image = STR_WHITE +
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_CONSTRUCTION_MARKER, uint8);
|
||||
|
||||
//Sound pause checkbox
|
||||
if (!g_sounds_disabled)
|
||||
w->pressed_widgets |= (1 << WIDX_SOUND_PAUSED_CHECKBOX);
|
||||
else
|
||||
w->pressed_widgets &= ~(1 << WIDX_SOUND_PAUSED_CHECKBOX);
|
||||
window_options_widgets[WIDX_RESOLUTION].type = WWT_DROPDOWN;
|
||||
window_options_widgets[WIDX_RESOLUTION_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
|
||||
window_options_widgets[WIDX_FULLSCREEN].type = WWT_DROPDOWN;
|
||||
window_options_widgets[WIDX_FULLSCREEN_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
|
||||
window_options_widgets[WIDX_TILE_SMOOTHING_CHECKBOX].type = WWT_CHECKBOX;
|
||||
window_options_widgets[WIDX_GRIDLINES_CHECKBOX].type = WWT_CHECKBOX;
|
||||
window_options_widgets[WIDX_CONSTRUCTION_MARKER].type = WWT_DROPDOWN;
|
||||
window_options_widgets[WIDX_CONSTRUCTION_MARKER_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
|
||||
break;
|
||||
case WINDOW_OPTIONS_PAGE_CULTURE:
|
||||
// currency: pounds, dollars, etc. (10 total)
|
||||
RCT2_GLOBAL(0x013CE952 + 12, uint16) = STR_POUNDS + (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_CURRENCY, uint8) & 0x3F);
|
||||
|
||||
// distance: metric/imperial
|
||||
RCT2_GLOBAL(0x013CE952 + 14, uint16) = STR_IMPERIAL + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_METRIC, uint8);
|
||||
|
||||
// temperature: celsius/fahrenheit
|
||||
RCT2_GLOBAL(0x013CE952 + 20, uint16) = STR_CELSIUS + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_TEMPERATURE, uint8);
|
||||
|
||||
// height: units/real values
|
||||
RCT2_GLOBAL(0x013CE952 + 6, uint16) =
|
||||
((RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS)) ? STR_UNITS : STR_REAL_VALUES;
|
||||
|
||||
window_options_widgets[WIDX_LANGUAGE].type = WWT_DROPDOWN;
|
||||
window_options_widgets[WIDX_LANGUAGE_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
|
||||
window_options_widgets[WIDX_CURRENCY].type = WWT_DROPDOWN;
|
||||
window_options_widgets[WIDX_CURRENCY_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
|
||||
window_options_widgets[WIDX_DISTANCE].type = WWT_DROPDOWN;
|
||||
window_options_widgets[WIDX_DISTANCE_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
|
||||
window_options_widgets[WIDX_TEMPERATURE].type = WWT_DROPDOWN;
|
||||
window_options_widgets[WIDX_TEMPERATURE_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
|
||||
window_options_widgets[WIDX_HEIGHT_LABELS].type = WWT_DROPDOWN;
|
||||
window_options_widgets[WIDX_HEIGHT_LABELS_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
|
||||
break;
|
||||
case WINDOW_OPTIONS_PAGE_AUDIO:
|
||||
currentSoundDevice = RCT2_GLOBAL(0x009AF280, sint32);
|
||||
|
||||
// sound devices
|
||||
if (currentSoundDevice == -1 || gAudioDeviceCount == 0) {
|
||||
RCT2_GLOBAL(0x013CE952, uint16) = STR_SOUND_NONE;
|
||||
} else {
|
||||
RCT2_GLOBAL(0x013CE952, uint16) = 1170;
|
||||
RCT2_GLOBAL(0x013CE952 + 2, uint32) = (uint32)gAudioDevices[currentSoundDevice].name;
|
||||
}
|
||||
|
||||
// music: on/off
|
||||
RCT2_GLOBAL(0x013CE952 + 8, uint16) = STR_OFF + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_MUSIC, uint8);
|
||||
|
||||
// sound quality: low/medium/high
|
||||
RCT2_GLOBAL(0x013CE952 + 10, uint16) = STR_SOUND_LOW + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_QUALITY, uint8);
|
||||
|
||||
//Sound pause checkbox
|
||||
if (!g_sounds_disabled)
|
||||
w->pressed_widgets |= (1ULL << WIDX_SOUND_PAUSED_CHECKBOX);
|
||||
else
|
||||
w->pressed_widgets &= ~(1ULL << WIDX_SOUND_PAUSED_CHECKBOX);
|
||||
|
||||
// sound software mixing buffer checkbox
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, uint8))
|
||||
w->pressed_widgets |= (1 << WIDX_SOUND_SW_BUFFER_CHECKBOX);
|
||||
else
|
||||
w->pressed_widgets &= ~(1 << WIDX_SOUND_SW_BUFFER_CHECKBOX);
|
||||
// sound software mixing buffer checkbox
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, uint8))
|
||||
w->pressed_widgets |= (1ULL << WIDX_SOUND_SW_BUFFER_CHECKBOX);
|
||||
else
|
||||
w->pressed_widgets &= ~(1ULL << WIDX_SOUND_SW_BUFFER_CHECKBOX);
|
||||
|
||||
// screen edge scrolling checkbox
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_EDGE_SCROLLING, uint8))
|
||||
w->pressed_widgets |= (1ULL << WIDX_SCREEN_EDGE_SCROLLING);
|
||||
else
|
||||
w->pressed_widgets &= ~(1ULL << WIDX_SCREEN_EDGE_SCROLLING);
|
||||
window_options_widgets[WIDX_SOUND].type = WWT_DROPDOWN;
|
||||
window_options_widgets[WIDX_SOUND_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
|
||||
window_options_widgets[WIDX_MUSIC].type = WWT_DROPDOWN;
|
||||
window_options_widgets[WIDX_MUSIC_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
|
||||
window_options_widgets[WIDX_SOUND_QUALITY].type = WWT_DROPDOWN;
|
||||
window_options_widgets[WIDX_SOUND_QUALITY_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
|
||||
window_options_widgets[WIDX_SOUND_SW_BUFFER_CHECKBOX].type = WWT_CHECKBOX;
|
||||
window_options_widgets[WIDX_SOUND_PAUSED_CHECKBOX].type = WWT_CHECKBOX;
|
||||
break;
|
||||
case WINDOW_OPTIONS_PAGE_INPUT:
|
||||
// screen edge scrolling checkbox
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_EDGE_SCROLLING, uint8))
|
||||
w->pressed_widgets |= (1ULL << WIDX_SCREEN_EDGE_SCROLLING);
|
||||
else
|
||||
w->pressed_widgets &= ~(1ULL << WIDX_SCREEN_EDGE_SCROLLING);
|
||||
|
||||
// real name checkbox
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_SHOW_REAL_GUEST_NAMES)
|
||||
w->pressed_widgets |= (1ULL << WIDX_REAL_NAME_CHECKBOX);
|
||||
else
|
||||
w->pressed_widgets &= ~(1ULL << WIDX_REAL_NAME_CHECKBOX);
|
||||
|
||||
// landscape tile smoothing checkbox
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & CONFIG_FLAG_DISABLE_SMOOTH_LANDSCAPE))
|
||||
w->pressed_widgets &= ~(1 << WIDX_TILE_SMOOTHING_CHECKBOX);
|
||||
else
|
||||
w->pressed_widgets |= (1 << WIDX_TILE_SMOOTHING_CHECKBOX);
|
||||
window_options_widgets[WIDX_SCREEN_EDGE_SCROLLING].type = WWT_CHECKBOX;
|
||||
window_options_widgets[WIDX_HOTKEY_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
|
||||
break;
|
||||
case WINDOW_OPTIONS_PAGE_MISC:
|
||||
// real name checkbox
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_SHOW_REAL_GUEST_NAMES)
|
||||
w->pressed_widgets |= (1ULL << WIDX_REAL_NAME_CHECKBOX);
|
||||
else
|
||||
w->pressed_widgets &= ~(1ULL << WIDX_REAL_NAME_CHECKBOX);
|
||||
|
||||
// show gridlines checkbox
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES))
|
||||
w->pressed_widgets |= (1 << WIDX_GRIDLINES_CHECKBOX);
|
||||
else
|
||||
w->pressed_widgets &= ~(1 << WIDX_GRIDLINES_CHECKBOX);
|
||||
// save plugin data checkbox
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & CONFIG_FLAG_SAVE_PLUGIN_DATA))
|
||||
w->pressed_widgets |= (1ULL << WIDX_SAVE_PLUGIN_DATA_CHECKBOX);
|
||||
else
|
||||
w->pressed_widgets &= ~(1ULL << WIDX_SAVE_PLUGIN_DATA_CHECKBOX);
|
||||
|
||||
// save plugin data checkbox
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & CONFIG_FLAG_SAVE_PLUGIN_DATA))
|
||||
w->pressed_widgets |= (1ULL << WIDX_SAVE_PLUGIN_DATA_CHECKBOX);
|
||||
else
|
||||
w->pressed_widgets &= ~(1ULL << WIDX_SAVE_PLUGIN_DATA_CHECKBOX);
|
||||
// unknown park flag can disable real name checkbox
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & 0x8000)
|
||||
w->disabled_widgets |= (1ULL << WIDX_REAL_NAME_CHECKBOX);
|
||||
|
||||
// unknown park flag can disable real name checkbox
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & 0x8000)
|
||||
w->disabled_widgets |= (1ULL << WIDX_REAL_NAME_CHECKBOX);
|
||||
// save plugin data checkbox: visible or not
|
||||
if (RCT2_GLOBAL(0x00F42BDA, uint8) == 1)
|
||||
window_options_widgets[WIDX_SAVE_PLUGIN_DATA_CHECKBOX].type = WWT_EMPTY;
|
||||
else
|
||||
window_options_widgets[WIDX_SAVE_PLUGIN_DATA_CHECKBOX].type = WWT_CHECKBOX;
|
||||
|
||||
// save plugin data checkbox: visible or not
|
||||
if (RCT2_GLOBAL(0x00F42BDA, uint8) == 1)
|
||||
window_options_widgets[WIDX_SAVE_PLUGIN_DATA_CHECKBOX].type = WWT_EMPTY;
|
||||
else
|
||||
window_options_widgets[WIDX_REAL_NAME_CHECKBOX].type = WWT_CHECKBOX;
|
||||
window_options_widgets[WIDX_SAVE_PLUGIN_DATA_CHECKBOX].type = WWT_CHECKBOX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void window_options_update(rct_window *w)
|
||||
{
|
||||
// Tab animation
|
||||
w->frame_no++;
|
||||
widget_invalidate(w->classification, w->number, WIDX_TAB_1 + w->page);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -665,53 +761,46 @@ static void window_options_paint()
|
||||
{
|
||||
rct_window *w;
|
||||
rct_drawpixelinfo *dpi;
|
||||
char buffer[256];
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov w, esi
|
||||
#else
|
||||
__asm__ ( "mov %[w], esi " : [w] "+m" (w) );
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov dpi, edi
|
||||
#else
|
||||
__asm__ ( "mov %[dpi], edi " : [dpi] "+m" (dpi) );
|
||||
#endif
|
||||
|
||||
window_paint_get_registers(w, dpi);
|
||||
|
||||
window_draw_widgets(w, dpi);
|
||||
window_options_draw_tab_images(dpi, w);
|
||||
|
||||
// units
|
||||
gfx_draw_string_left(dpi, STR_CURRENCY, w, 0, w->x + 10,
|
||||
w->y + window_options_widgets[WIDX_CURRENCY].top + 1);
|
||||
gfx_draw_string_left(dpi, STR_DISTANCE_AND_SPEED, w, 0, w->x + 10,
|
||||
w->y + window_options_widgets[WIDX_DISTANCE].top + 1);
|
||||
gfx_draw_string_left(dpi, STR_TEMPERATURE, w, 0, w->x + 10,
|
||||
w->y + window_options_widgets[WIDX_TEMPERATURE].top + 1);
|
||||
gfx_draw_string_left(dpi, STR_HEIGHT_LABELS, w, 0, w->x + 10,
|
||||
w->y + window_options_widgets[WIDX_HEIGHT_LABELS].top + 1);
|
||||
switch (w->page) {
|
||||
case WINDOW_OPTIONS_PAGE_DISPLAY:
|
||||
gfx_draw_string_left(dpi, STR_DISPLAY_RESOLUTION, w, 0, w->x + 10, w->y + window_options_widgets[WIDX_RESOLUTION].top + 1);
|
||||
|
||||
// display
|
||||
gfx_draw_string_left(dpi, STR_DISPLAY_RESOLUTION, w, 0, w->x + 10,
|
||||
w->y + window_options_widgets[WIDX_RESOLUTION].top + 1);
|
||||
sprintf(buffer, "%c%c%s", FORMAT_MEDIUMFONT, FORMAT_WINDOW_COLOUR_2, "Fullscreen mode:");
|
||||
gfx_draw_string(dpi, buffer, 0, w->x + 10, w->y + window_options_widgets[WIDX_FULLSCREEN].top + 1);
|
||||
|
||||
char buffer[256];
|
||||
sprintf(buffer, "%c%c%s", FORMAT_MEDIUMFONT, FORMAT_WINDOW_COLOUR_2, "Fullscreen mode:");
|
||||
gfx_draw_string(dpi, buffer, 0, w->x + 10,
|
||||
w->y + window_options_widgets[WIDX_FULLSCREEN].top + 1);
|
||||
gfx_draw_string_left(dpi, STR_CONSTRUCTION_MARKER, w, 0, w->x + 10, w->y + window_options_widgets[WIDX_CONSTRUCTION_MARKER].top + 1);
|
||||
break;
|
||||
case WINDOW_OPTIONS_PAGE_CULTURE:
|
||||
gfx_draw_string_left(dpi, 2776, w, 12, w->x + 10, w->y + window_options_widgets[WIDX_LANGUAGE].top + 1);
|
||||
gfx_draw_string(
|
||||
dpi,
|
||||
(char*)language_names[gCurrentLanguage],
|
||||
12,
|
||||
w->x + window_options_widgets[WIDX_LANGUAGE].left + 1,
|
||||
w->y + window_options_widgets[WIDX_LANGUAGE].top
|
||||
);
|
||||
|
||||
gfx_draw_string_left(dpi, STR_CONSTRUCTION_MARKER, w, 0, w->x + 10,
|
||||
w->y + window_options_widgets[WIDX_CONSTRUCTION_MARKER].top + 1);
|
||||
|
||||
// sound
|
||||
gfx_draw_string_left(dpi, STR_MUSIC, w, 0, w->x + 10,
|
||||
w->y + window_options_widgets[WIDX_MUSIC].top + 1);
|
||||
gfx_draw_string_left(dpi, STR_SOUND_QUALITY, w, 0, w->x + 10,
|
||||
w->y + window_options_widgets[WIDX_SOUND_QUALITY].top + 1);
|
||||
gfx_draw_string_left(dpi, STR_CURRENCY, w, 0, w->x + 10, w->y + window_options_widgets[WIDX_CURRENCY].top + 1);
|
||||
gfx_draw_string_left(dpi, STR_DISTANCE_AND_SPEED, w, 0, w->x + 10, w->y + window_options_widgets[WIDX_DISTANCE].top + 1);
|
||||
gfx_draw_string_left(dpi, STR_TEMPERATURE, w, 0, w->x + 10, w->y + window_options_widgets[WIDX_TEMPERATURE].top + 1);
|
||||
gfx_draw_string_left(dpi, STR_HEIGHT_LABELS, w, 0, w->x + 10, w->y + window_options_widgets[WIDX_HEIGHT_LABELS].top + 1);
|
||||
break;
|
||||
case WINDOW_OPTIONS_PAGE_AUDIO:
|
||||
gfx_draw_string_left(dpi, STR_MUSIC, w, 0, w->x + 10, w->y + window_options_widgets[WIDX_MUSIC].top + 1);
|
||||
gfx_draw_string_left(dpi, STR_SOUND_QUALITY, w, 0, w->x + 10, w->y + window_options_widgets[WIDX_SOUND_QUALITY].top + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// helper function, all dropdown boxes have similar properties
|
||||
static void window_options_draw_dropdown_box(rct_window *w, rct_widget *widget, int num_items)
|
||||
static void window_options_show_dropdown(rct_window *w, rct_widget *widget, int num_items)
|
||||
{
|
||||
window_dropdown_show_text_custom_width(
|
||||
w->x + widget->left,
|
||||
@@ -721,7 +810,7 @@ static void window_options_draw_dropdown_box(rct_window *w, rct_widget *widget,
|
||||
0x80,
|
||||
num_items,
|
||||
widget->right - widget->left - 3
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
static void window_options_update_height_markers()
|
||||
@@ -736,3 +825,52 @@ static void window_options_update_height_markers()
|
||||
config_save();
|
||||
gfx_invalidate_screen();
|
||||
}
|
||||
|
||||
#pragma region Common
|
||||
|
||||
static void window_options_set_page(rct_window *w, int page)
|
||||
{
|
||||
w->page = page;
|
||||
w->frame_no = 0;
|
||||
|
||||
window_invalidate(w);
|
||||
|
||||
RCT2_CALLPROC_X(w->event_handlers[WE_RESIZE], 0, 0, 0, 0, (int)w, 0, 0);
|
||||
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
|
||||
|
||||
window_init_scroll_widgets(w);
|
||||
window_invalidate(w);
|
||||
}
|
||||
|
||||
static void window_options_set_pressed_tab(rct_window *w)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < WINDOW_OPTIONS_PAGE_COUNT; i++)
|
||||
w->pressed_widgets &= ~(1 << (WIDX_TAB_1 + i));
|
||||
w->pressed_widgets |= 1LL << (WIDX_TAB_1 + w->page);
|
||||
}
|
||||
|
||||
static void window_options_draw_tab_image(rct_drawpixelinfo *dpi, rct_window *w, int page, int spriteIndex)
|
||||
{
|
||||
int widgetIndex = WIDX_TAB_1 + page;
|
||||
|
||||
if (!(w->disabled_widgets & (1LL << widgetIndex))) {
|
||||
if (w->page == page) {
|
||||
int frame = w->frame_no / window_options_tab_animation_divisor[w->page];
|
||||
spriteIndex += (frame % window_options_tab_animation_frames[w->page]);
|
||||
}
|
||||
|
||||
gfx_draw_sprite(dpi, spriteIndex, w->x + w->widgets[widgetIndex].left, w->y + w->widgets[widgetIndex].top, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void window_options_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w)
|
||||
{
|
||||
window_options_draw_tab_image(dpi, w, WINDOW_OPTIONS_PAGE_DISPLAY, 5442);
|
||||
window_options_draw_tab_image(dpi, w, WINDOW_OPTIONS_PAGE_CULTURE, 5229);
|
||||
window_options_draw_tab_image(dpi, w, WINDOW_OPTIONS_PAGE_AUDIO, 5335);
|
||||
window_options_draw_tab_image(dpi, w, WINDOW_OPTIONS_PAGE_INPUT, 5201);
|
||||
window_options_draw_tab_image(dpi, w, WINDOW_OPTIONS_PAGE_MISC, 5205);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
@@ -129,7 +129,8 @@ uint32 window_peep_page_enabled_widgets[] = {
|
||||
void window_peep_open(rct_peep* peep){
|
||||
|
||||
if (peep->type == PEEP_TYPE_STAFF){
|
||||
RCT2_CALLPROC_X(0x006989E9, 0, 0, 0, (int)peep, 0, 0, 0);
|
||||
window_staff_peep_open(peep);
|
||||
return;
|
||||
}
|
||||
|
||||
rct_window* window;
|
||||
@@ -151,7 +152,7 @@ void window_peep_open(rct_peep* peep){
|
||||
window->min_height = 157;
|
||||
window->max_width = 500;
|
||||
window->max_height = 450;
|
||||
window->flags = 8;
|
||||
window->flags = 1 << 8;
|
||||
window->no_list_items = 0;
|
||||
window->selected_list_item = -1;
|
||||
window->colours[0] = 1;
|
||||
@@ -161,7 +162,7 @@ void window_peep_open(rct_peep* peep){
|
||||
}
|
||||
|
||||
window->page = 0;
|
||||
RCT2_CALLPROC_X(0x006EB13A, 0, 0, 0, 0, (int)window, 0, 0);
|
||||
window_invalidate(window);
|
||||
|
||||
window->widgets = RCT2_GLOBAL(0x981D0C, rct_widget*);
|
||||
window->enabled_widgets = RCT2_GLOBAL(0x981D3C,uint32);
|
||||
@@ -173,35 +174,3 @@ void window_peep_open(rct_peep* peep){
|
||||
window_init_scroll_widgets(window);
|
||||
RCT2_CALLPROC_X(0x0069883C, 0, 0, 0, 0, (int)window, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006BEE98
|
||||
*/
|
||||
void window_staff_peep_open(rct_peep* peep)
|
||||
{
|
||||
rct_window* w = window_bring_to_front_by_id(WC_PEEP, peep->sprite_index);
|
||||
if (!w) {
|
||||
int eax, ebx, ecx, edx, esi, edi;
|
||||
|
||||
eax = peep->sprite_index;
|
||||
ecx = WC_PEEP;
|
||||
edx = peep->sprite_index;
|
||||
|
||||
RCT2_CALLFUNC_X(0x006BEF1B, &eax, &ebx, &ecx, &edx, &esi, &edi, (int*)peep);
|
||||
w = (rct_window*)esi;
|
||||
}
|
||||
|
||||
int PEEP_BACKGROUND_IDX = 0;
|
||||
w->widgets = RCT2_GLOBAL(0x992998, rct_widget*);
|
||||
w->enabled_widgets = RCT2_GLOBAL(0x9929B0, uint32);
|
||||
w->var_020 = RCT2_GLOBAL(0x9929BC, uint32);
|
||||
w->event_handlers = (uint32*)RCT2_GLOBAL(0x9929A4, uint32);
|
||||
w->pressed_widgets = 0;
|
||||
RCT2_CALLPROC_X(0x006BED21, 0, 0, 0, 0, (int)w, 0, 0);
|
||||
window_init_scroll_widgets(w);
|
||||
RCT2_CALLPROC_X(0x006BEDA3, 0, 0, 0, 0, (int)w, 0, 0);
|
||||
if (g_sprite_list[w->number].peep.state == PEEP_STATE_PICKED) {
|
||||
RCT2_CALLPROC_X(w->event_handlers[1], 0, 0, 0, 10, (int)w, 0, 0);
|
||||
}
|
||||
}
|
||||
641
src/window_research.c
Normal file
641
src/window_research.c
Normal file
@@ -0,0 +1,641 @@
|
||||
/*****************************************************************************
|
||||
* Copyright (c) 2014 Ted John
|
||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
||||
*
|
||||
* This file is part of OpenRCT2.
|
||||
*
|
||||
* OpenRCT2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "addresses.h"
|
||||
#include "finance.h"
|
||||
#include "game.h"
|
||||
#include "news_item.h"
|
||||
#include "string_ids.h"
|
||||
#include "sprites.h"
|
||||
#include "widget.h"
|
||||
#include "window.h"
|
||||
#include "window_dropdown.h"
|
||||
|
||||
enum {
|
||||
WINDOW_RESEARCH_PAGE_DEVELOPMENT,
|
||||
WINDOW_RESEARCH_PAGE_FUNDING,
|
||||
WINDOW_RESEARCH_PAGE_COUNT
|
||||
};
|
||||
|
||||
enum {
|
||||
WIDX_BACKGROUND,
|
||||
WIDX_TITLE,
|
||||
WIDX_CLOSE,
|
||||
WIDX_PAGE_BACKGROUND,
|
||||
WIDX_TAB_1,
|
||||
WIDX_TAB_2,
|
||||
|
||||
WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP,
|
||||
WIDX_LAST_DEVELOPMENT_GROUP,
|
||||
WIDX_LAST_DEVELOPMENT_BUTTON,
|
||||
|
||||
WIDX_FUNDING_GROUP = 6,
|
||||
WIDX_RESEARCH_FUNDING,
|
||||
WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON,
|
||||
WIDX_PRIORITIES_GROUP,
|
||||
WIDX_TRANSPORT_RIDES,
|
||||
WIDX_GENTLE_RIDES,
|
||||
WIDX_ROLLER_COASTERS,
|
||||
WIDX_THRILL_RIDES,
|
||||
WIDX_WATER_RIDES,
|
||||
WIDX_SHOPS_AND_STALLS,
|
||||
WIDX_SCENERY_AND_THEMING,
|
||||
};
|
||||
|
||||
#pragma region Widgets
|
||||
|
||||
static rct_widget window_research_development_widgets[] = {
|
||||
{ WWT_FRAME, 0, 0, 299, 0, 195, 0xFFFFFFFF, STR_NONE },
|
||||
{ WWT_CAPTION, 0, 1, 298, 1, 14, STR_RESEARCH_AND_DEVELOPMENT, STR_WINDOW_TITLE_TIP },
|
||||
{ WWT_CLOSEBOX, 0, 287, 297, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP },
|
||||
{ WWT_RESIZE, 1, 0, 299, 43, 195, 0xFFFFFFFF, STR_NONE },
|
||||
{ WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, STR_RESEARCH_AND_DEVELOPMENT_TIP },
|
||||
{ WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, STR_FINANCES_RESEARCH },
|
||||
{ WWT_GROUPBOX, 2, 3, 292, 47, 116, 2267, STR_NONE },
|
||||
{ WWT_GROUPBOX, 2, 3, 292, 124, 188, 2268, STR_NONE },
|
||||
{ WWT_FLATBTN, 2, 265, 288, 161, 184, 0xFFFFFFFF, STR_RESEARCH_SHOW_DETAILS_TIP },
|
||||
{ WIDGETS_END },
|
||||
};
|
||||
|
||||
static rct_widget window_research_funding_widgets[] = {
|
||||
{ WWT_FRAME, 0, 0, 319, 0, 206, 0xFFFFFFFF, STR_NONE },
|
||||
{ WWT_CAPTION, 0, 1, 318, 1, 14, STR_RESEARCH_FUNDING, STR_WINDOW_TITLE_TIP },
|
||||
{ WWT_CLOSEBOX, 0, 307, 317, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP },
|
||||
{ WWT_RESIZE, 1, 0, 319, 43, 206, 0xFFFFFFFF, STR_NONE },
|
||||
{ WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, STR_RESEARCH_AND_DEVELOPMENT_TIP },
|
||||
{ WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, STR_FINANCES_RESEARCH },
|
||||
{ WWT_GROUPBOX, 2, 3, 316, 47, 91, STR_RESEARCH_FUNDING_, STR_NONE },
|
||||
{ WWT_DROPDOWN, 2, 8, 167, 59, 70, 0xFFFFFFFF, STR_SELECT_LEVEL_OF_RESEARCH_AND_DEVELOPMENT },
|
||||
{ WWT_DROPDOWN_BUTTON, 2, 156, 166, 60, 69, 876, STR_SELECT_LEVEL_OF_RESEARCH_AND_DEVELOPMENT },
|
||||
{ WWT_GROUPBOX, 2, 3, 316, 96, 202, STR_RESEARCH_PRIORITIES, STR_NONE },
|
||||
{ WWT_CHECKBOX, 2, 8, 311, 108, 119, STR_RESEARCH_TRANSPORT_RIDES, STR_RESEARCH_NEW_TRANSPORT_RIDES },
|
||||
{ WWT_CHECKBOX, 2, 8, 311, 121, 132, STR_RESEARCH_GENTLE_RIDES, STR_RESEARCH_NEW_GENTLE_RIDES },
|
||||
{ WWT_CHECKBOX, 2, 8, 311, 134, 145, STR_RESEARCH_ROLLER_COASTERS, STR_RESEARCH_NEW_ROLLER_COASTERS },
|
||||
{ WWT_CHECKBOX, 2, 8, 311, 147, 158, STR_RESEARCH_THRILL_RIDES, STR_RESEARCH_NEW_THRILL_RIDES },
|
||||
{ WWT_CHECKBOX, 2, 8, 311, 160, 171, STR_RESEARCH_WATER_RIDES, STR_RESEARCH_NEW_WATER_RIDES },
|
||||
{ WWT_CHECKBOX, 2, 8, 311, 173, 184, STR_RESEARCH_SHOPS_AND_STALLS, STR_RESEARCH_NEW_SHOPS_AND_STALLS },
|
||||
{ WWT_CHECKBOX, 2, 8, 311, 186, 197, STR_RESEARCH_SCENERY_AND_THEMING, STR_RESEARCH_NEW_SCENERY_AND_THEMING },
|
||||
{ WIDGETS_END },
|
||||
};
|
||||
|
||||
static rct_widget *window_research_page_widgets[] = {
|
||||
window_research_development_widgets,
|
||||
window_research_funding_widgets
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Events
|
||||
|
||||
static void window_research_emptysub() { }
|
||||
|
||||
static void window_research_development_mouseup();
|
||||
static void window_research_development_update(rct_window *w);
|
||||
static void window_research_development_invalidate();
|
||||
static void window_research_development_paint();
|
||||
|
||||
static void window_research_funding_mouseup();
|
||||
static void window_research_funding_mousedown(int widgetIndex, rct_window*w, rct_widget* widget);
|
||||
static void window_research_funding_dropdown();
|
||||
static void window_research_funding_update(rct_window *w);
|
||||
static void window_research_funding_invalidate();
|
||||
static void window_research_funding_paint();
|
||||
|
||||
//
|
||||
static void* window_research_development_events[] = {
|
||||
window_research_emptysub,
|
||||
window_research_development_mouseup,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_development_update,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_development_invalidate,
|
||||
window_research_development_paint,
|
||||
window_research_emptysub
|
||||
};
|
||||
|
||||
// 0x009890E8
|
||||
static void* window_research_funding_events[] = {
|
||||
window_research_emptysub,
|
||||
window_research_funding_mouseup,
|
||||
window_research_emptysub,
|
||||
window_research_funding_mousedown,
|
||||
window_research_funding_dropdown,
|
||||
window_research_emptysub,
|
||||
window_research_funding_update,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_emptysub,
|
||||
window_research_funding_invalidate,
|
||||
window_research_funding_paint,
|
||||
window_research_emptysub
|
||||
};
|
||||
|
||||
static void* window_research_page_events[] = {
|
||||
window_research_development_events,
|
||||
window_research_funding_events
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Enabled widgets
|
||||
|
||||
static uint32 window_research_page_enabled_widgets[] = {
|
||||
(1 << WIDX_CLOSE) |
|
||||
(1 << WIDX_TAB_1) |
|
||||
(1 << WIDX_TAB_2),
|
||||
|
||||
(1 << WIDX_CLOSE) |
|
||||
(1 << WIDX_TAB_1) |
|
||||
(1 << WIDX_TAB_2) |
|
||||
(1 << WIDX_RESEARCH_FUNDING) |
|
||||
(1 << WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON) |
|
||||
(1 << WIDX_TRANSPORT_RIDES) |
|
||||
(1 << WIDX_GENTLE_RIDES) |
|
||||
(1 << WIDX_ROLLER_COASTERS) |
|
||||
(1 << WIDX_THRILL_RIDES) |
|
||||
(1 << WIDX_WATER_RIDES) |
|
||||
(1 << WIDX_SHOPS_AND_STALLS) |
|
||||
(1 << WIDX_SCENERY_AND_THEMING)
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
const int window_research_tab_animation_loops[] = { 16, 16 };
|
||||
|
||||
static void window_research_set_page(rct_window *w, int page);
|
||||
static void window_research_set_pressed_tab(rct_window *w);
|
||||
static void window_research_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w);
|
||||
|
||||
void window_research_open()
|
||||
{
|
||||
rct_window *w;
|
||||
|
||||
w = window_bring_to_front_by_id(WC_RESEARCH, 0);
|
||||
if (w == NULL) {
|
||||
w = window_create_auto_pos(530, 257, window_research_page_events[0], WC_RESEARCH, WF_10);
|
||||
w->widgets = window_research_page_widgets[0];
|
||||
w->enabled_widgets = window_research_page_enabled_widgets[0];
|
||||
w->number = 0;
|
||||
w->page = 0;
|
||||
w->frame_no = 0;
|
||||
w->disabled_widgets = 0;
|
||||
w->colours[0] = 1;
|
||||
w->colours[1] = 19;
|
||||
w->colours[2] = 19;
|
||||
RCT2_CALLPROC_EBPSAFE(0x00684BAE);
|
||||
}
|
||||
|
||||
w->page = 0;
|
||||
window_invalidate(w);
|
||||
w->width = 300;
|
||||
w->height = 196;
|
||||
window_invalidate(w);
|
||||
|
||||
w->widgets = window_research_page_widgets[0];
|
||||
w->enabled_widgets = window_research_page_enabled_widgets[0];
|
||||
w->var_020 = RCT2_GLOBAL(0x00988E3C, uint32);
|
||||
w->event_handlers = window_research_page_events[0];
|
||||
w->pressed_widgets = 0;
|
||||
w->disabled_widgets = 0;
|
||||
window_init_scroll_widgets(w);
|
||||
}
|
||||
|
||||
#pragma region Development page
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B6B38
|
||||
*/
|
||||
static void window_research_development_mouseup()
|
||||
{
|
||||
short widgetIndex;
|
||||
rct_window *w;
|
||||
|
||||
window_mouse_up_get_registers(w, widgetIndex);
|
||||
|
||||
switch (widgetIndex) {
|
||||
case WIDX_CLOSE:
|
||||
window_close(w);
|
||||
break;
|
||||
case WIDX_TAB_1:
|
||||
case WIDX_TAB_2:
|
||||
window_research_set_page(w, widgetIndex - WIDX_TAB_1);
|
||||
break;
|
||||
case WIDX_LAST_DEVELOPMENT_BUTTON:
|
||||
news_item_open_subject(NEWS_ITEM_RESEARCH, RCT2_GLOBAL(RCT2_ADDRESS_LAST_RESEARCHED_ITEM_SUBJECT, sint32));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0069CBA6
|
||||
*/
|
||||
static void window_research_development_update(rct_window *w)
|
||||
{
|
||||
// Tab animation
|
||||
if (++w->frame_no >= window_research_tab_animation_loops[w->page])
|
||||
w->frame_no = 0;
|
||||
widget_invalidate(w->classification, w->number, WIDX_TAB_1);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B6819
|
||||
*/
|
||||
static void window_research_development_invalidate()
|
||||
{
|
||||
rct_window *w;
|
||||
|
||||
window_get_register(w);
|
||||
|
||||
if (w->widgets != window_research_page_widgets[WINDOW_RESEARCH_PAGE_DEVELOPMENT]) {
|
||||
w->widgets = window_research_page_widgets[WINDOW_RESEARCH_PAGE_DEVELOPMENT];
|
||||
window_init_scroll_widgets(w);
|
||||
}
|
||||
|
||||
window_research_set_pressed_tab(w);
|
||||
|
||||
window_research_development_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WWT_EMPTY;
|
||||
uint32 typeId = RCT2_GLOBAL(0x01357CF4, uint32);
|
||||
if (typeId != 0xFFFFFFFF) {
|
||||
window_research_development_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WWT_FLATBTN;
|
||||
window_research_development_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].image = typeId >= 0x10000 ? 5189 : 5191;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B689B
|
||||
*/
|
||||
static void window_research_development_paint()
|
||||
{
|
||||
rct_window *w;
|
||||
rct_drawpixelinfo *dpi;
|
||||
int x, y;
|
||||
rct_string_id stringId;
|
||||
|
||||
window_paint_get_registers(w, dpi);
|
||||
|
||||
window_draw_widgets(w, dpi);
|
||||
window_research_draw_tab_images(dpi, w);
|
||||
|
||||
x = w->x + 10;
|
||||
y = w->y + window_research_development_widgets[WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP].top + 12;
|
||||
|
||||
// Research type
|
||||
stringId = STR_RESEARCH_UNKNOWN;
|
||||
if (RCT2_GLOBAL(0x01357CF3, uint8) != 0) {
|
||||
stringId = STR_TRANSPORT_RIDE + RCT2_GLOBAL(0x013580E6, uint8);
|
||||
if (RCT2_GLOBAL(0x01357CF3, uint8) != 1) {
|
||||
uint32 typeId = RCT2_GLOBAL(0x013580E0, uint32);
|
||||
if (typeId >= 0x10000) {
|
||||
uint8 *rideEntry = RCT2_GLOBAL(0x009ACFA4 + (typeId & 0xFF) * 4, uint8*);
|
||||
if (RCT2_GLOBAL(rideEntry + 8, uint32) & 0x1000)
|
||||
stringId = RCT2_GLOBAL(rideEntry, uint16);
|
||||
else
|
||||
stringId = (typeId & 0xFF00) + 2;
|
||||
} else {
|
||||
uint8 *sceneryEntry = RCT2_GLOBAL(0x009ADA90 + (typeId & 0xFFFF) * 4, uint8*);
|
||||
stringId = RCT2_GLOBAL(sceneryEntry, uint16);
|
||||
}
|
||||
}
|
||||
}
|
||||
gfx_draw_string_left_wrapped(dpi, &stringId, x, y, 296, STR_RESEARCH_TYPE_LABEL, 0);
|
||||
y += 25;
|
||||
|
||||
// Progress
|
||||
stringId = 2285 + RCT2_GLOBAL(0x01357CF3, uint8);
|
||||
gfx_draw_string_left_wrapped(dpi, &stringId, x, y, 296, STR_RESEARCH_PROGRESS_LABEL, 0);
|
||||
y += 15;
|
||||
|
||||
// Expected
|
||||
RCT2_GLOBAL(0x013CE952, uint16) = STR_UNKNOWN;
|
||||
if (RCT2_GLOBAL(0x01357CF3, uint8) != 0) {
|
||||
uint16 expectedDay = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RESEARCH_EXPECTED_DAY, uint8);
|
||||
if (expectedDay != 255) {
|
||||
RCT2_GLOBAL(0x013CE952 + 2, uint16) = STR_DATE_DAY_1 + expectedDay;
|
||||
RCT2_GLOBAL(0x013CE952 + 4, uint16) = STR_MONTH_MARCH + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RESEARCH_EXPECTED_MONTH, uint8);
|
||||
RCT2_GLOBAL(0x013CE952, uint16) = 2289;
|
||||
}
|
||||
}
|
||||
gfx_draw_string_left(dpi, STR_RESEARCH_EXPECTED_LABEL, (void*)0x013CE952, 0, x, y);
|
||||
|
||||
// Last development
|
||||
x = w->x + 10;
|
||||
y = w->y + window_research_development_widgets[WIDX_LAST_DEVELOPMENT_GROUP].top + 12;
|
||||
|
||||
uint32 typeId = RCT2_GLOBAL(0x01357CF4, uint32);
|
||||
if (typeId != 0xFFFFFFFF) {
|
||||
if (typeId >= 0x10000) {
|
||||
uint8 *rideEntry = RCT2_GLOBAL(0x009ACFA4 + (typeId & 0xFF) * 4, uint8*);
|
||||
if (RCT2_GLOBAL(rideEntry + 8, uint32) & 0x1000)
|
||||
stringId = RCT2_GLOBAL(rideEntry, uint16);
|
||||
else
|
||||
stringId = (typeId & 0xFF00) + 2;
|
||||
} else {
|
||||
uint8 *sceneryEntry = RCT2_GLOBAL(0x009ADA90 + (typeId & 0xFFFF) * 4, uint8*);
|
||||
stringId = RCT2_GLOBAL(sceneryEntry, uint16);
|
||||
}
|
||||
gfx_draw_string_left_wrapped(dpi, &stringId, x, y, 266, STR_RESEARCH_RIDE_LABEL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Funding page
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0069DB3F
|
||||
*/
|
||||
static void window_research_funding_mouseup()
|
||||
{
|
||||
rct_window * w;
|
||||
short widgetIndex;
|
||||
int activeResearchTypes;
|
||||
|
||||
window_mouse_up_get_registers(w, widgetIndex);
|
||||
|
||||
switch (widgetIndex) {
|
||||
case WIDX_CLOSE:
|
||||
window_close(w);
|
||||
break;
|
||||
case WIDX_TAB_1:
|
||||
case WIDX_TAB_2:
|
||||
window_research_set_page(w, widgetIndex - WIDX_TAB_1);
|
||||
break;
|
||||
case WIDX_TRANSPORT_RIDES:
|
||||
case WIDX_GENTLE_RIDES:
|
||||
case WIDX_ROLLER_COASTERS:
|
||||
case WIDX_THRILL_RIDES:
|
||||
case WIDX_WATER_RIDES:
|
||||
case WIDX_SHOPS_AND_STALLS:
|
||||
case WIDX_SCENERY_AND_THEMING:
|
||||
activeResearchTypes = RCT2_GLOBAL(RCT2_ADDRESS_ACTIVE_RESEARCH_TYPES, uint16);
|
||||
activeResearchTypes ^= 1 << (widgetIndex - WIDX_TRANSPORT_RIDES);
|
||||
game_do_command(0, (1 << 8) | 1, 0, activeResearchTypes, GAME_COMMAND_SET_RESEARCH_FUNDING, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0069DB66
|
||||
*/
|
||||
static void window_research_funding_mousedown(int widgetIndex, rct_window *w, rct_widget* widget)
|
||||
{
|
||||
rct_widget *dropdownWidget;
|
||||
int i;
|
||||
|
||||
if (widgetIndex != WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON)
|
||||
return;
|
||||
|
||||
dropdownWidget = widget - 1;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
gDropdownItemsFormat[i] = 1142;
|
||||
gDropdownItemsArgs[i] = STR_NO_FUNDING + i;
|
||||
}
|
||||
window_dropdown_show_text_custom_width(
|
||||
w->x + dropdownWidget->left,
|
||||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0x80,
|
||||
4,
|
||||
dropdownWidget->right - dropdownWidget->left - 3
|
||||
);
|
||||
|
||||
int currentResearchLevel = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_RESEARCH_LEVEL, uint8);
|
||||
gDropdownItemsChecked = (1 << currentResearchLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0069DB6D
|
||||
*/
|
||||
static void window_research_funding_dropdown()
|
||||
{
|
||||
rct_window *w;
|
||||
short widgetIndex;
|
||||
short dropdownIndex;
|
||||
|
||||
window_dropdown_get_registers(w, widgetIndex, dropdownIndex);
|
||||
|
||||
if (widgetIndex != WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON || dropdownIndex == -1)
|
||||
return;
|
||||
|
||||
game_do_command(0, 1, 0, dropdownIndex, GAME_COMMAND_SET_RESEARCH_FUNDING, 0, 0);
|
||||
window_invalidate(w);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0069DC23
|
||||
*/
|
||||
static void window_research_funding_update(rct_window *w)
|
||||
{
|
||||
// Tab animation
|
||||
if (++w->frame_no >= window_research_tab_animation_loops[w->page])
|
||||
w->frame_no = 0;
|
||||
widget_invalidate(w->classification, w->number, WIDX_TAB_2);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0069DA64
|
||||
*/
|
||||
static void window_research_funding_invalidate()
|
||||
{
|
||||
rct_window *w;
|
||||
|
||||
window_get_register(w);
|
||||
|
||||
if (w->widgets != window_research_page_widgets[WINDOW_RESEARCH_PAGE_FUNDING]) {
|
||||
w->widgets = window_research_page_widgets[WINDOW_RESEARCH_PAGE_FUNDING];
|
||||
window_init_scroll_widgets(w);
|
||||
}
|
||||
|
||||
window_research_set_pressed_tab(w);
|
||||
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY)) {
|
||||
window_research_funding_widgets[WIDX_FUNDING_GROUP].type = WWT_EMPTY;
|
||||
window_research_funding_widgets[WIDX_RESEARCH_FUNDING].type = WWT_EMPTY;
|
||||
window_research_funding_widgets[WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON].type = WWT_EMPTY;
|
||||
} else {
|
||||
window_research_funding_widgets[WIDX_FUNDING_GROUP].type = WWT_GROUPBOX;
|
||||
window_research_funding_widgets[WIDX_RESEARCH_FUNDING].type = WWT_DROPDOWN;
|
||||
window_research_funding_widgets[WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON].type = WWT_DROPDOWN_BUTTON;
|
||||
|
||||
// Current funding
|
||||
int currentResearchLevel = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_RESEARCH_LEVEL, uint8);
|
||||
window_research_funding_widgets[WIDX_RESEARCH_FUNDING].image = STR_NO_FUNDING + currentResearchLevel;
|
||||
}
|
||||
|
||||
// Checkboxes
|
||||
int activeResearchTypes = RCT2_GLOBAL(RCT2_ADDRESS_ACTIVE_RESEARCH_TYPES, uint16);
|
||||
int uncompletedResearchTypes = RCT2_GLOBAL(RCT2_ADDRESS_UNCOMPLETED_RESEARCH_TYPES, uint16);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
int mask = 1 << i;
|
||||
int widgetMask = 1 << (i + WIDX_TRANSPORT_RIDES);
|
||||
|
||||
// Set checkbox disabled if research type is complete
|
||||
if (uncompletedResearchTypes & mask) {
|
||||
w->disabled_widgets &= ~widgetMask;
|
||||
|
||||
// Set checkbox ticked if research type is active
|
||||
if (activeResearchTypes & mask)
|
||||
w->pressed_widgets |= widgetMask;
|
||||
else
|
||||
w->pressed_widgets &= ~widgetMask;
|
||||
} else {
|
||||
w->disabled_widgets |= widgetMask;
|
||||
w->pressed_widgets &= ~widgetMask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0069DAF0
|
||||
*/
|
||||
static void window_research_funding_paint()
|
||||
{
|
||||
rct_window *w;
|
||||
rct_drawpixelinfo *dpi;
|
||||
|
||||
window_paint_get_registers(w, dpi);
|
||||
|
||||
window_draw_widgets(w, dpi);
|
||||
window_research_draw_tab_images(dpi, w);
|
||||
|
||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY)) {
|
||||
int currentResearchLevel = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_RESEARCH_LEVEL, uint8);
|
||||
money32 currentResearchCostPerWeek = research_cost_table[currentResearchLevel];
|
||||
gfx_draw_string_left(dpi, STR_RESEARCH_COST_PER_MONTH, ¤tResearchCostPerWeek, 0, w->x + 10, w->y + 77);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Common
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0069CAC5
|
||||
*/
|
||||
static void window_research_set_page(rct_window *w, int page)
|
||||
{
|
||||
w->page = page;
|
||||
w->frame_no = 0;
|
||||
if (w->viewport != NULL) {
|
||||
w->viewport->width = 0;
|
||||
w->viewport = NULL;
|
||||
}
|
||||
|
||||
w->enabled_widgets = window_research_page_enabled_widgets[page];
|
||||
w->var_020 = RCT2_ADDRESS(0x00988E3C, uint32)[page];
|
||||
w->event_handlers = window_research_page_events[page];
|
||||
w->widgets = window_research_page_widgets[page];
|
||||
w->disabled_widgets = 0;
|
||||
w->pressed_widgets = 0;
|
||||
|
||||
window_invalidate(w);
|
||||
if (w->page == WINDOW_RESEARCH_PAGE_DEVELOPMENT) {
|
||||
w->width = 300;
|
||||
w->height = 196;
|
||||
} else {
|
||||
w->width = 320;
|
||||
w->height = 207;
|
||||
}
|
||||
RCT2_CALLPROC_X(w->event_handlers[WE_RESIZE], 0, 0, 0, 0, (int)w, 0, 0);
|
||||
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
|
||||
|
||||
window_init_scroll_widgets(w);
|
||||
window_invalidate(w);
|
||||
}
|
||||
|
||||
static void window_research_set_pressed_tab(rct_window *w)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < WINDOW_RESEARCH_PAGE_COUNT; i++)
|
||||
w->pressed_widgets &= ~(1 << (WIDX_TAB_1 + i));
|
||||
w->pressed_widgets |= 1LL << (WIDX_TAB_1 + w->page);
|
||||
}
|
||||
|
||||
static void window_research_draw_tab_image(rct_drawpixelinfo *dpi, rct_window *w, int page, int spriteIndex)
|
||||
{
|
||||
int widgetIndex = WIDX_TAB_1 + page;
|
||||
|
||||
if (!(w->disabled_widgets & (1LL << widgetIndex))) {
|
||||
if (w->page == page) {
|
||||
int frame = w->frame_no / 2;
|
||||
if (page == WINDOW_RESEARCH_PAGE_DEVELOPMENT)
|
||||
frame %= 8;
|
||||
spriteIndex += frame;
|
||||
}
|
||||
|
||||
gfx_draw_sprite(dpi, spriteIndex, w->x + w->widgets[widgetIndex].left, w->y + w->widgets[widgetIndex].top, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void window_research_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w)
|
||||
{
|
||||
window_research_draw_tab_image(dpi, w, WINDOW_RESEARCH_PAGE_DEVELOPMENT, SPR_TAB_FINANCES_RESEARCH_0);
|
||||
window_research_draw_tab_image(dpi, w, WINDOW_RESEARCH_PAGE_FUNDING, SPR_TAB_FINANCES_SUMMARY_0);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
244
src/window_staff_peep.c
Normal file
244
src/window_staff_peep.c
Normal file
@@ -0,0 +1,244 @@
|
||||
/*****************************************************************************
|
||||
* Copyright (c) 2014 Ted John, Duncan Frost
|
||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
||||
*
|
||||
* This file is part of OpenRCT2.
|
||||
*
|
||||
* OpenRCT2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "addresses.h"
|
||||
#include "game.h"
|
||||
#include "peep.h"
|
||||
#include "string_ids.h"
|
||||
#include "sprite.h"
|
||||
#include "sprites.h"
|
||||
#include "widget.h"
|
||||
#include "window.h"
|
||||
#include "window_dropdown.h"
|
||||
|
||||
enum WINDOW_STAFF_PEEP_PAGE {
|
||||
WINDOW_STAFF_PEEP_OVERVIEW,
|
||||
WINDOW_STAFF_PEEP_OPTIONS,
|
||||
WINDOW_STAFF_PEEP_STATISTICS,
|
||||
};
|
||||
|
||||
enum WINDOW_STAFF_PEEP_WIDGET_IDX {
|
||||
WIDX_BACKGROUND,
|
||||
WIDX_TITLE,
|
||||
WIDX_CLOSE,
|
||||
WIDX_RESIZE,
|
||||
WIDX_TAB_1,
|
||||
WIDX_TAB_2,
|
||||
WIDX_TAB_3,
|
||||
WIDX_TAB_4,
|
||||
WIDX_VIEWPORT,
|
||||
WIDX_BTM_LABEL,
|
||||
WIDX_PATROL,
|
||||
WIDX_RENAME,
|
||||
WIDX_LOCATE,
|
||||
WIDX_FIRE
|
||||
};
|
||||
|
||||
void window_staff_peep_emptysub(){};
|
||||
|
||||
rct_widget window_staff_peep_overview_widgets[] = {
|
||||
{ WWT_FRAME, 0, 0, 189, 0, 179, 0x0FFFFFFFF, STR_NONE }, // Panel / Background
|
||||
{ WWT_CAPTION, 0, 1, 188, 1, 14, 0x361, STR_WINDOW_TITLE_TIP }, // Title
|
||||
{ WWT_CLOSEBOX, 0, 177, 187, 2, 13, 0x338, STR_CLOSE_WINDOW_TIP }, // Close x button
|
||||
{ WWT_RESIZE, 1, 0, 189, 43, 179, 0x0FFFFFFFF, STR_NONE }, // Resize
|
||||
{ WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 1939 }, // Tab 1
|
||||
{ WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 1945}, // Tab 2
|
||||
{ WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, 2348}, // Tab 3
|
||||
{ WWT_TAB, 1, 96, 126, 17, 43, 0x2000144E, STR_NONE}, // Tab 4
|
||||
{ WWT_VIEWPORT, 1, 3, 164, 47, 166, 0x0FFFFFFFF, STR_NONE}, // Viewport
|
||||
{ WWT_12, 1, 3, 164, 167, 177, 0x0FFFFFFFF, STR_NONE }, // Label at bottom of viewport
|
||||
{ WWT_FLATBTN, 1, 165, 188, 45, 68, 0x1436, 1706}, // Pickup Button
|
||||
{ WWT_FLATBTN, 1, 165, 188, 69, 92, 0x1437, 1708}, // Patrol Button
|
||||
{ WWT_FLATBTN, 1, 165, 188, 93, 116, 0x1430, 1056}, // Rename Button
|
||||
{ WWT_FLATBTN, 1, 165, 188, 117, 140, 0x142F, 1027}, // Locate Button
|
||||
{ WWT_FLATBTN, 1, 165, 188, 141, 164, 0x142D, 1705}, // Fire Button
|
||||
{ WIDGETS_END },
|
||||
};
|
||||
|
||||
rct_widget *window_staff_peep_page_widgets[] = {
|
||||
window_staff_peep_overview_widgets
|
||||
};
|
||||
|
||||
// 0x992AEC
|
||||
static void* window_staff_peep_overview_events[] = {
|
||||
(void*)0x6BDFF8,
|
||||
(void*)0x6BDF55,
|
||||
(void*)0x6BE558,
|
||||
(void*)0x6BDF98,
|
||||
(void*)0x6BDFA3,
|
||||
window_staff_peep_emptysub,
|
||||
(void*)0x6BE602,
|
||||
window_staff_peep_emptysub,
|
||||
window_staff_peep_emptysub,
|
||||
(void*)0x6BDFD8,
|
||||
(void*)0x6BDFC3,
|
||||
window_staff_peep_emptysub,
|
||||
window_staff_peep_emptysub,
|
||||
(void*)0x6BDFAE,
|
||||
window_staff_peep_emptysub,
|
||||
window_staff_peep_emptysub,
|
||||
window_staff_peep_emptysub,
|
||||
window_staff_peep_emptysub,
|
||||
window_staff_peep_emptysub,
|
||||
(void*)0x6BDFED,
|
||||
(void*)0x6BE5FC,
|
||||
window_staff_peep_emptysub,
|
||||
window_staff_peep_emptysub,
|
||||
window_staff_peep_emptysub,
|
||||
window_staff_peep_emptysub,
|
||||
(void*)0x6BDD91, //Invalidate
|
||||
(void*)0x6BDEAF, //Paint
|
||||
(void*)0x6BE62A
|
||||
};
|
||||
|
||||
void* window_staff_peep_page_events[] = {
|
||||
window_staff_peep_overview_events
|
||||
};
|
||||
|
||||
uint32 window_staff_peep_page_enabled_widgets[] = {
|
||||
(1 << WIDX_CLOSE) |
|
||||
(1 << WIDX_TAB_1) |
|
||||
(1 << WIDX_TAB_2) |
|
||||
(1 << WIDX_TAB_3) |
|
||||
(1 << WIDX_PATROL) |
|
||||
(1 << WIDX_RENAME) |
|
||||
(1 << WIDX_LOCATE) |
|
||||
(1 << WIDX_FIRE) |
|
||||
(1 << 14)
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* rct2: 0x006BED21
|
||||
*
|
||||
*/
|
||||
void sub_6BED21(rct_window* w, rct_peep* peep)
|
||||
{
|
||||
int eax = 0 | 0x80;
|
||||
|
||||
if (peep->staff_type == 2) {
|
||||
eax |= 0x20;
|
||||
}
|
||||
|
||||
//RCT2_CALLFUNC_X(0x698827, 0, 0, 0, 0, 0, 0, 0);
|
||||
// sub_698827
|
||||
// This is here due to needing the Carry Flag.
|
||||
|
||||
int CF = 0;
|
||||
int res = RCT2_GLOBAL(0x982004 + peep->state, uint8) & 1;
|
||||
|
||||
if (res == 0) {
|
||||
CF = 1;
|
||||
}
|
||||
else {
|
||||
eax = eax & eax;
|
||||
}
|
||||
|
||||
// end sub_698827
|
||||
|
||||
int a = 0;
|
||||
|
||||
// pop esi
|
||||
if (CF == 1 && w->page == 0) {
|
||||
eax |= 0x400; //or eax, 400h
|
||||
|
||||
a = w->disabled_widgets & (1 << 0xA); //bt dword ptr[esi + 10h], 0Ah
|
||||
|
||||
}
|
||||
|
||||
if (a == 0) {
|
||||
CF = w->disabled_widgets & (1 << 0xA); //bt dword ptr [esi+10h], 0Ah
|
||||
if (CF == 1) {
|
||||
window_invalidate(w);
|
||||
}
|
||||
}
|
||||
|
||||
w->disabled_widgets = eax;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the window for a specific peep.
|
||||
*
|
||||
* rct2: 0x006BEF1B
|
||||
*/
|
||||
rct_window* sub_6BEF1B(rct_peep* peep)
|
||||
{
|
||||
rct_window* w = window_create_auto_pos(190, 180, (uint32*)window_staff_peep_overview_events, WC_PEEP, (uint16)0x400);
|
||||
|
||||
w->widgets = RCT2_GLOBAL(0x9AF81C, rct_widget*);
|
||||
w->enabled_widgets = RCT2_GLOBAL(0x9929B0, uint32);
|
||||
w->number = peep->sprite_index;
|
||||
w->page = 0;
|
||||
w->var_482 = 0;
|
||||
w->frame_no = 0;
|
||||
|
||||
RCT2_GLOBAL((int*)w + 0x496, uint16) = 0; // missing, var_494 should perhaps be uint16?
|
||||
|
||||
sub_6BED21(w, peep);
|
||||
|
||||
w->min_width = 190;
|
||||
w->min_height = 180;
|
||||
w->max_width = 500;
|
||||
w->max_height = 450;
|
||||
|
||||
w->flags = 1 << 8;
|
||||
|
||||
w->colours[0] = 1;
|
||||
w->colours[1] = 4;
|
||||
w->colours[2] = 4;
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006BEE98
|
||||
*/
|
||||
void window_staff_peep_open(rct_peep* peep)
|
||||
{
|
||||
rct_window* w = window_bring_to_front_by_id(WC_PEEP, peep->sprite_index);
|
||||
if (!w) {
|
||||
//int eax, ebx, ecx, edx, esi, edi;
|
||||
|
||||
//eax = peep->sprite_index;
|
||||
//ecx = WC_PEEP;
|
||||
//edx = peep->sprite_index;
|
||||
|
||||
//RCT2_CALLFUNC_X(0x006BEF1B, &eax, &ebx, &ecx, &edx, &esi, &edi, (int*)peep);
|
||||
//w = (rct_window*)esi;
|
||||
|
||||
w = sub_6BEF1B(peep);
|
||||
}
|
||||
w->page = 0;
|
||||
window_invalidate(w);
|
||||
|
||||
w->widgets = window_staff_peep_overview_widgets;
|
||||
w->enabled_widgets = window_staff_peep_page_enabled_widgets[0];
|
||||
w->var_020 = RCT2_GLOBAL(0x9929BC, uint32);
|
||||
w->event_handlers = window_staff_peep_page_events[0];
|
||||
w->pressed_widgets = 0;
|
||||
//RCT2_CALLPROC_X(0x006BED21, 0, 0, 0, 0, (int)w, 0, 0);
|
||||
sub_6BED21(w, peep);
|
||||
window_init_scroll_widgets(w);
|
||||
RCT2_CALLPROC_X(0x006BEDA3, 0, 0, 0, 0, (int)w, 0, 0);
|
||||
if (g_sprite_list[w->number].peep.state == PEEP_STATE_PICKED) {
|
||||
RCT2_CALLPROC_X(w->event_handlers[WE_MOUSE_UP], 0, 0, 0, 10, (int)w, 0, 0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user