1
0
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:
qcz
2014-08-19 09:46:25 +02:00
35 changed files with 12365 additions and 596 deletions

View File

@@ -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

View File

@@ -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);
}
}
/**

View File

@@ -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[] = {

View File

@@ -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);
}

View File

@@ -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
View File

@@ -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

View File

@@ -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
View 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
View 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

View File

@@ -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

View File

@@ -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;

View File

@@ -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();

View File

@@ -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)))

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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);
}
/**

View File

@@ -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);
}
/**

View File

@@ -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();

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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)) {

View File

@@ -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

View File

@@ -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
View 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, &currentResearchCostPerWeek, 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
View 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);
}
}