1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-23 15:52:55 +01:00

Merge branch 'master' into swedish-translation

This commit is contained in:
vahiki
2014-09-12 07:34:30 +02:00
16 changed files with 768 additions and 460 deletions

1
build.bat Normal file
View File

@@ -0,0 +1 @@
msbuild .\projects\openrct2.vcxproj /p:Configuration=Release /p:Platform=x86

File diff suppressed because it is too large Load Diff

View File

@@ -59,6 +59,7 @@
<ClInclude Include="..\src\window.h" />
<ClInclude Include="..\src\window_dropdown.h" />
<ClInclude Include="..\src\window_error.h" />
<ClInclude Include="..\src\window_scenery.h" />
<ClInclude Include="..\src\window_tooltip.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="..\src\staff.h" />
@@ -139,6 +140,7 @@
<ClCompile Include="..\src\window_water.c" />
<ClCompile Include="..\src\staff.c" />
<ClCompile Include="..\src\window_scenery.c" />
<ClCompile Include="..\src\window_credits.c" />
</ItemGroup>
<ItemGroup>
<None Include="..\openrct2.exe" />

View File

@@ -165,6 +165,9 @@
<ClInclude Include="..\src\scenery.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\window_scenery.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\game.c">
@@ -392,6 +395,9 @@
<ClCompile Include="..\src\window_ride.c">
<Filter>Windows</Filter>
</ClCompile>
<ClCompile Include="..\src\window_credits.c">
<Filter>Windows</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\openrct2.exe">

View File

@@ -65,7 +65,7 @@ void peep_update_all()
peep_update(peep);
} else {
RCT2_CALLPROC_X(0x0068F41A, 0, 0, 0, i, (int)peep, 0, 0);
if (peep->var_08 == 4)
if (peep->linked_list_type_offset == SPRITE_LINKEDLIST_OFFSET_PEEP)
peep_update(peep);
}

View File

@@ -308,7 +308,7 @@ typedef struct {
uint16 var_02; // 0x02
uint16 next; // 0x04
uint16 previous; // 0x06
uint8 var_08;
uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_...
uint8 var_09; // 0x09
uint16 sprite_index; // 0x0A
uint16 var_0C;

View File

@@ -184,7 +184,7 @@ void ride_update_favourited_stat()
ride->guests_favourite = 0;
FOR_ALL_PEEPS(spriteIndex, peep) {
if (peep->var_08 != 4)
if (peep->linked_list_type_offset != SPRITE_LINKEDLIST_OFFSET_PEEP)
return;
if (peep->favourite_ride != 0xff) {
ride = &g_ride_list[peep->favourite_ride];

View File

@@ -53,7 +53,7 @@ void reset_sprite_list(){
spr->unknown.sprite_identifier = 0xFF;
spr->unknown.sprite_index = i;
spr->unknown.next = SPRITE_INDEX_NULL;
spr->unknown.var_08 = 0;
spr->unknown.linked_list_type_offset = 0;
if (previous_spr != (rct_sprite*)SPRITE_INDEX_NULL){
spr->unknown.previous = previous_spr->unknown.sprite_index;
@@ -108,11 +108,11 @@ void reset_0x69EBE4(){
/*
* rct2: 0x0069EC6B
* bl: unclear what this does
* bl: if bl & 2 > 0, the sprite ends up in the FLOATING_TEXT linked list.
*/
rct_sprite *create_sprite(uint8 bl)
{
int ecx = 0xA;
SPRITE_LINKEDLIST_OFFSET linkedListTypeOffset = SPRITE_LINKEDLIST_OFFSET_UNKNOWN; // cl
if ((bl & 2) != 0)
{
@@ -123,7 +123,7 @@ rct_sprite *create_sprite(uint8 bl)
return NULL;
}
ecx = 6;
linkedListTypeOffset = SPRITE_LINKEDLIST_OFFSET_FLOATING_TEXT;
}
else if (RCT2_GLOBAL(0x13573C8, uint16) <= 0)
{
@@ -132,7 +132,7 @@ rct_sprite *create_sprite(uint8 bl)
rct_unk_sprite *sprite = &(g_sprite_list[RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16)]).unknown;
RCT2_CALLPROC_X(0x0069ED0B, 0, 0, ecx, 0, (int)sprite, 0, 0);
move_sprite_to_list((rct_sprite *)sprite, (uint8)linkedListTypeOffset);
sprite->x = SPRITE_LOCATION_NULL;
sprite->y = SPRITE_LOCATION_NULL;
@@ -149,3 +149,55 @@ rct_sprite *create_sprite(uint8 bl)
return (rct_sprite*)sprite;
}
/*
* rct2: 0x0069ED0B
* This function moves a sprite to the specified sprite linked list.
* There are 5/6 of those, and cl specifies a pointer offset
* of the desired linked list in a uint16 array. Known valid values are
* 2, 4, 6, 8 or 10 (SPRITE_LINKEDLIST_OFFSET_...)
*/
void move_sprite_to_list(rct_sprite *sprite, uint8 cl)
{
rct_unk_sprite *unkSprite = &sprite->unknown;
// No need to move if the sprite is already in the desired list
if (unkSprite->linked_list_type_offset == cl)
return;
// If the sprite is currently the head of the list, the
// sprite following this one becomes the new head of the list.
if (unkSprite->previous == SPRITE_INDEX_NULL)
{
RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX + unkSprite->linked_list_type_offset, uint16) = unkSprite->next;
}
else
{
// Hook up sprite->previous->next to sprite->next, removing the sprite from its old list
g_sprite_list[unkSprite->previous].unknown.next = unkSprite->next;
}
// Similarly, hook up sprite->next->previous to sprite->previous
if (unkSprite->next != SPRITE_INDEX_NULL)
{
g_sprite_list[unkSprite->next].unknown.previous = unkSprite->previous;
}
int oldListTypeOffset = unkSprite->linked_list_type_offset;
unkSprite->previous = SPRITE_INDEX_NULL; // We become the new head of the target list, so there's no previous sprite
unkSprite->linked_list_type_offset = cl;
unkSprite->next = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX + cl, uint16); // This sprite's next sprite is the old head, since we're the new head
RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX + cl, uint16) = unkSprite->sprite_index; // Store this sprite's index as head of its new list
if (unkSprite->next != SPRITE_INDEX_NULL)
{
// Fix the chain by settings sprite->next->previous to sprite_index
g_sprite_list[unkSprite->next].unknown.previous = unkSprite->sprite_index;
}
// These globals are probably counters for each sprite list?
// Decrement old list counter, increment new list counter.
--(RCT2_GLOBAL(0x13573C8 + oldListTypeOffset, uint16));
++(RCT2_GLOBAL(0x13573C8 + cl, uint16));
}

View File

@@ -36,13 +36,21 @@ enum SPRITE_IDENTIFIER{
SPRITE_IDENTIFIER_LITTER = 3,
};
typedef enum {
SPRITE_LINKEDLIST_OFFSET_VEHICLE = 2,
SPRITE_LINKEDLIST_OFFSET_PEEP = 4,
SPRITE_LINKEDLIST_OFFSET_FLOATING_TEXT = 6,
SPRITE_LINKEDLIST_OFFSET_FLOATING_LITTER = 8,
SPRITE_LINKEDLIST_OFFSET_UNKNOWN = 10
} SPRITE_LINKEDLIST_OFFSET;
typedef struct {
uint8 sprite_identifier; // 0x00
uint8 pad_01;
uint16 var_02;
uint16 next; // 0x04
uint16 previous; // 0x06
uint8 var_08;
uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_...
uint8 pad_09;
uint16 sprite_index; // 0x0A
uint8 pad_0C[2];
@@ -66,7 +74,7 @@ typedef struct {
uint16 var_02; // 0x02
uint16 next; // 0x04
uint16 previous; // 0x06
uint8 var_08;
uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_...
uint8 pad_09;
uint16 sprite_index; // 0x0A
uint8 pad_0B[0x19];
@@ -92,5 +100,6 @@ void create_balloon(int x, int y, int z, int colour);
rct_sprite *create_sprite(uint8 bl);
void reset_sprite_list();
void reset_0x69EBE4();
void move_sprite_to_list(rct_sprite *sprite, uint8 cl);
#endif

View File

@@ -127,7 +127,7 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx,
RCT2_CALLPROC_X(0x0069EDB6, 0, 0, _ecx, 0, (int)newPeep, 0, 0);
}
else {
RCT2_CALLPROC_X(0x0069ED0B, 0, 0, 4, 0, (int)newPeep, 0, 0);
move_sprite_to_list((rct_sprite *)newPeep, SPRITE_LINKEDLIST_OFFSET_PEEP);
newPeep->sprite_identifier = 1;
newPeep->var_09 = 0x0F;

View File

@@ -36,7 +36,7 @@ typedef struct {
uint8 pad_01[0x03];
uint16 next; // 0x04
uint16 previous; // 0x06
uint8 var_08;
uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_...
uint8 pad_09;
uint16 sprite_index; // 0x0A
uint8 pad_0C[2];

View File

@@ -330,8 +330,8 @@ enum {
WC_TOOLTIP = 5,
WC_DROPDOWN = 6,
WC_ABOUT = 8,
WC_MUSIC_CREDITS = 9,
WC_PUBLISHER_CREDITS = 10,
WC_PUBLISHER_CREDITS = 9,
WC_MUSIC_CREDITS = 10,
WC_ERROR = 11,
WC_RIDE = 12,
WC_RIDE_CONSTRUCTION = 13,
@@ -464,6 +464,7 @@ void window_banner_open();
void window_cheats_open();
void window_research_open();
void window_scenery_open();
void window_music_credits_open();
void window_guest_list_init_vars_a();
void window_guest_list_init_vars_b();

View File

@@ -125,7 +125,7 @@ static void window_about_mouseup()
window_close(w);
break;
case WIDX_MUSIC_CREDITS:
RCT2_CALLPROC_EBPSAFE(0x0066D55B);
window_music_credits_open();
break;
case WIDX_PUBLISHER_CREDITS:
RCT2_CALLPROC_EBPSAFE(0x0066D4EC);

201
src/window_credits.c Normal file
View File

@@ -0,0 +1,201 @@
/*****************************************************************************
* 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 <windows.h>
#include <string.h>
#include "addresses.h"
#include "string_ids.h"
#include "sprites.h"
#include "widget.h"
#include "window.h"
enum WINDOW_MUSIC_CREDITS_WIDGET_IDX {
WIDX_BACKGROUND,
WIDX_TITLE,
WIDX_CLOSE
};
rct_widget window_music_credits_widgets[] = {
{ WWT_FRAME, 0, 0, 509, 0, 313, 0x0FFFFFFFF, STR_NONE }, // panel / background
{ WWT_CAPTION, 0, 1, 508, 1, 14, STR_MUSIC_ACKNOWLEDGEMENTS, STR_WINDOW_TITLE_TIP }, // title bar
{ WWT_CLOSEBOX, 0, 497, 507, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, // close x button
{ WWT_SCROLL, 0, 4, 505, 18, 309, 2, STR_NONE }, // scroll
{ WIDGETS_END },
};
static void window_music_credits_emptysub() { }
static void window_music_credits_mouseup();
static void window_music_credits_scrollgetsize();
static void window_music_credits_paint();
static void window_music_credits_scrollpaint();
static void* window_music_credits_events[] = {
window_music_credits_emptysub,
window_music_credits_mouseup,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_scrollgetsize,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_emptysub,
window_music_credits_paint,
window_music_credits_scrollpaint
};
/**
*
* rct2: 0x0066D55B
*/
void window_music_credits_open()
{
rct_window* window;
// Check if window is already open
window = window_bring_to_front_by_id(WC_MUSIC_CREDITS, 0);
if (window != NULL)
return;
window = window_create(
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16) / 2 - 255,
max(28, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16) / 2 - 157),
510,
314,
(uint32*)window_music_credits_events,
WC_MUSIC_CREDITS,
0
);
window->widgets = window_music_credits_widgets;
window->enabled_widgets = 1 << WIDX_CLOSE;
window_init_scroll_widgets(window);
window->colours[0] = 7;
window->colours[1] = 7;
window->colours[2] = 7;
}
/**
*
* rct2: 0x0066DB2C
*/
static void window_music_credits_mouseup()
{
short widgetIndex;
rct_window *w;
window_widget_get_registers(w, widgetIndex);
switch (widgetIndex) {
case WIDX_CLOSE:
window_close(w);
break;
}
}
/**
*
* rct2: 0x0066DB37
*/
static void window_music_credits_scrollgetsize()
{
int y = 560;
#ifdef _MSC_VER
__asm mov edx, y
#else
__asm__("mov edx, %[y] " : [y] "+m" (y));
#endif
}
/**
*
* rct2: 0x0066D7B9
*/
static void window_music_credits_paint()
{
rct_window *w;
rct_drawpixelinfo *dpi;
window_paint_get_registers(w, dpi);
window_draw_widgets(w, dpi);
}
/**
*
* rct2: 0x0066D7BF
*/
static void window_music_credits_scrollpaint()
{
rct_window *w;
rct_drawpixelinfo *dpi;
window_paint_get_registers(w, dpi);
int x = 245;
int y = 2;
int string = 0xB30;
for (int i = 0; i < 12; i++) {
gfx_draw_string_centred(dpi, string, x, y, 0, 0);
y += 10;
if (i == 10) { // Add 4 more space before "Original recordings ...".
y += 4;
}
string += 1;
}
// Draw the separator
y += 5;
gfx_fill_rect_inset(dpi, 4, y, 484, y+1, w->colours[1], 0x20);
y += 11;
for (int i = 0; i < 31; i++) {
if (i == 21) { // Move special courtesy to below Hypothermia.
gfx_draw_string_centred(dpi, string + 4, x, y, 0, 0);
y += 10;
continue;
} else if (i == 25) { // Remove special courtesy and blank line.
string += 2;
}
gfx_draw_string_centred(dpi, string, x, y, 0, 0);
y += 10;
string += 1;
}
}

View File

@@ -32,12 +32,7 @@
#include "viewport.h"
#include "widget.h"
#include "window.h"
#define WINDOW_SCENERY_WIDTH 0x27A
#define WINDOW_SCENERY_HEIGHT 0x8E
#define SCENERY_BUTTON_WIDTH 66
#define SCENERY_BUTTON_HEIGHT 80
#define SCENERY_ENTRIES_BY_TAB 128
#include "window_scenery.h"
enum {
WINDOW_SCENERY_TAB_1,
@@ -181,6 +176,10 @@ static rct_widget window_scenery_widgets[] = {
static sint16 window_scenery_tab_entries[0x13][SCENERY_ENTRIES_BY_TAB + 1];
/*
* Was part of 0x006DFA00
* The same code repeated five times for every scenery entry type
*/
void init_scenery_entry(rct_scenery_entry *sceneryEntry, int index, uint8 sceneryTabId) {
if (RCT2_ADDRESS(0x01357BD0, sint32)[index >> 5] & (1 << (index & 0x1F))) {
if (sceneryTabId != 0xFF) {
@@ -417,7 +416,7 @@ void window_scenery_open()
window_init_scroll_widgets(window);
RCT2_CALLPROC_X(0x006E1EB4, 0, 0, 0, 0, (int)window, 0, 0);
show_gridlines();
RCT2_GLOBAL(0x00F64F05, uint8) = 3; // scenery rotation
window_scenery_rotation = 3;
RCT2_GLOBAL(0x00F64F12, uint8) = 0;
RCT2_GLOBAL(0x00F64F13, uint8) = 0;
window->scenery.selected_scenery_id = -1;
@@ -426,8 +425,8 @@ void window_scenery_open()
RCT2_GLOBAL(0x00F64F0D, uint8) = 0;
RCT2_GLOBAL(0x00F64EB4, uint32) = 0x80000000;
RCT2_GLOBAL(0x00F64EC0, uint16) = 0;
RCT2_GLOBAL(0x00F64F19, uint8) = 0; // repaint colored scenery tool state
RCT2_GLOBAL(0x00F64F1A, uint8) = 0; // build cluster tool state
window_scenery_is_repaint_scenery_tool_on = 0; // repaint colored scenery tool state
window_scenery_is_build_cluster_tool_on = 0; // build cluster tool state
window->min_width = WINDOW_SCENERY_WIDTH;
window->max_width = WINDOW_SCENERY_WIDTH;
@@ -441,12 +440,12 @@ void window_scenery_open()
/*
* rct2: 0x0066DB3D
*/
bool window_scenery_is_tool_active() {
bool window_scenery_is_scenery_tool_active() {
int toolWindowClassification = RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass);
int toolWidgetIndex = RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, rct_windownumber);
if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3))
if (toolWindowClassification == WC_TOP_TOOLBAR && toolWidgetIndex == 9)
if (toolWindowClassification == WC_TOP_TOOLBAR && toolWidgetIndex == 9) // 9 is WIDX_SCENERY
return true;
return false;
@@ -465,13 +464,13 @@ void window_scenery_close() {
hide_gridlines();
RCT2_CALLPROC_X(0x006CB70A, 0, 0, 0, 0, 0, 0, 0);
if (window_scenery_is_tool_active())
if (window_scenery_is_scenery_tool_active())
tool_cancel();
}
int window_scenery_scrollgetsize_num() {
int items = 0;
while (window_scenery_tab_entries[RCT2_GLOBAL(0x00F64EDC, uint8)][items] != -1)
while (window_scenery_tab_entries[window_scenery_active_tab_index][items] != -1)
items++;
items += 8;
@@ -498,17 +497,17 @@ static void window_scenery_mouseup()
window_close(w);
break;
case WIDX_SCENERY_ROTATE_OBJECTS_BUTTON:
RCT2_GLOBAL(0x00F64F05, uint8)++;
RCT2_GLOBAL(0x00F64F05, uint8) = RCT2_GLOBAL(0x00F64F05, uint8) % 4;
window_scenery_rotation++;
window_scenery_rotation = window_scenery_rotation % 4;
RCT2_CALLPROC_EBPSAFE(0x006E2712);
window_invalidate(w);
break;
case WIDX_SCENERY_REPAINT_SCENERY_BUTTON:
RCT2_GLOBAL(0x00F64F19, uint8) ^= 1;
window_scenery_is_repaint_scenery_tool_on ^= 1;
window_invalidate(w);
break;
case WIDX_SCENERY_BUILD_CLUSTER_BUTTON:
RCT2_GLOBAL(0x00F64F1A, uint8) ^= 1;
window_scenery_is_build_cluster_tool_on ^= 1;
window_invalidate(w);
break;
}
@@ -522,12 +521,12 @@ void window_scenery_update_scroll(rct_window *w) {
int scrollsize = window_scenery_scrollgetsize_num();
w->scrolls[0].v_bottom = scrollsize;
int tabIndex = RCT2_GLOBAL(0x00F64EDC, uint8);
int tabIndex = window_scenery_active_tab_index;
int itemIndex = 0;
sint16 sceneryId;
while ((sceneryId = window_scenery_tab_entries[tabIndex][itemIndex]) != -1) {
if (sceneryId == RCT2_ADDRESS(0x00F64EDD, sint16)[tabIndex])
if (sceneryId == window_scenery_selected_scenery_by_tab[tabIndex])
break;
itemIndex++;
}
@@ -536,7 +535,7 @@ void window_scenery_update_scroll(rct_window *w) {
itemIndex = 0;
sint16 sceneryId = window_scenery_tab_entries[tabIndex][itemIndex];
if (sceneryId != -1)
RCT2_ADDRESS(0x00F64EDD, sint16)[tabIndex] = sceneryId;
window_scenery_selected_scenery_by_tab[tabIndex] = sceneryId;
}
w->scrolls[0].v_top = (itemIndex / 9) * SCENERY_BUTTON_HEIGHT;
@@ -585,21 +584,21 @@ static void window_scenery_mousedown(int widgetIndex, rct_window* w, rct_widget*
switch (widgetIndex) {
case WIDX_SCENERY_PRIMARY_COLOUR_BUTTON:
eax = (RCT2_GLOBAL(0xF64F06, uint8) << 8) + 0x80 + w->colours[1];
eax = (window_scenery_primary_colour << 8) + 0x80 + w->colours[1];
RCT2_CALLPROC_X(0x006ED43D, eax, 0, 0, widgetIndex, (int)w, (int)widget, 0xFFFFFFFF);
break;
case WIDX_SCENERY_SECONDARY_COLOUR_BUTTON:
eax = (RCT2_GLOBAL(0xF64F07, uint8) << 8) + 0x80 + w->colours[1];
eax = (window_scenery_secondary_colour << 8) + 0x80 + w->colours[1];
RCT2_CALLPROC_X(0x006ED43D, eax, 0, 0, widgetIndex, (int)w, (int)widget, 0xFFFFFFFF);
break;
case WIDX_SCENERY_TERTIARY_COLOUR_BUTTON:
eax = (RCT2_GLOBAL(0xF64F08, uint8) << 8) + 0x80 + w->colours[1];
eax = (window_scenery_tertiary_colour << 8) + 0x80 + w->colours[1];
RCT2_CALLPROC_X(0x006ED43D, eax, 0, 0, widgetIndex, (int)w, (int)widget, 0xFFFFFFFF);
break;
}
if (widgetIndex >= WIDX_SCENERY_TAB_1 && widgetIndex <= WIDX_SCENERY_TAB_20) {
RCT2_GLOBAL(0x00F64EDC, uint8) = widgetIndex - WIDX_SCENERY_TAB_1;
window_scenery_active_tab_index = widgetIndex - WIDX_SCENERY_TAB_1;
window_invalidate(w);
RCT2_GLOBAL(0x00F64EB4, uint32) = 0x80000000;
window_scenery_update_scroll(w);
@@ -619,13 +618,13 @@ static void window_scenery_dropdown() {
return;
if (widgetIndex == WIDX_SCENERY_PRIMARY_COLOUR_BUTTON) {
RCT2_GLOBAL(0x00F64F06, uint8) = (uint8)dropdownIndex;
window_scenery_primary_colour = (uint8)dropdownIndex;
}
else if (widgetIndex == WIDX_SCENERY_SECONDARY_COLOUR_BUTTON) {
RCT2_GLOBAL(0x00F64F07, uint8) = (uint8)dropdownIndex;
window_scenery_secondary_colour = (uint8)dropdownIndex;
}
else if (widgetIndex == WIDX_SCENERY_TERTIARY_COLOUR_BUTTON) {
RCT2_GLOBAL(0x00F64F08, uint8) = (uint8)dropdownIndex;
window_scenery_tertiary_colour = (uint8)dropdownIndex;
}
window_invalidate(w);
@@ -697,34 +696,32 @@ static void window_scenery_update(rct_window *w)
gfx_invalidate_screen();
// todo
//if (window_scenery_is_tool_active())
//window_close(w);
if (!window_scenery_is_scenery_tool_active())
window_close(w);
if (RCT2_GLOBAL(0x00F64F19, uint8) != 1) {
if (window_scenery_is_repaint_scenery_tool_on == 1) { // the repaint scenery tool is active
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = 0x17;
return;
}
} else {
uint16 tabIndex = window_scenery_active_tab_index;
sint16 tabSelectedSceneryId = window_scenery_selected_scenery_by_tab[tabIndex];
uint16 tabIndex = RCT2_GLOBAL(0x00F64EDC, uint8);
sint16 tabSelectedSceneryId = RCT2_ADDRESS(0x00F64EDD, sint16)[tabIndex];
if (tabSelectedSceneryId == -1)
return;
if (tabSelectedSceneryId > 0x400) { // banner
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = 0x18;
} else if (tabSelectedSceneryId > 0x300) { // large scenery
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) =
g_largeSceneryEntries[tabSelectedSceneryId - 0x300]->large_scenery.tool_id;
} else if (tabSelectedSceneryId > 0x200) { // wall
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) =
g_wallSceneryEntries[tabSelectedSceneryId - 0x200]->wall.tool_id;
} else if (tabSelectedSceneryId > 0x100) { // path bit
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) =
g_pathBitSceneryEntries[tabSelectedSceneryId - 0x100]->path_bit.tool_id;
} else { // small scenery
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) =
g_smallSceneryEntries[tabSelectedSceneryId]->small_scenery.tool_id;
if (tabSelectedSceneryId != -1) {
if (tabSelectedSceneryId >= 0x400) { // banner
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = 0x18;
} else if (tabSelectedSceneryId >= 0x300) { // large scenery
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) =
g_largeSceneryEntries[tabSelectedSceneryId - 0x300]->large_scenery.tool_id;
} else if (tabSelectedSceneryId >= 0x200) { // wall
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) =
g_wallSceneryEntries[tabSelectedSceneryId - 0x200]->wall.tool_id;
} else if (tabSelectedSceneryId >= 0x100) { // path bit
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) =
g_pathBitSceneryEntries[tabSelectedSceneryId - 0x100]->path_bit.tool_id;
} else { // small scenery
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) =
g_smallSceneryEntries[tabSelectedSceneryId]->small_scenery.tool_id;
}
}
}
}
@@ -744,7 +741,7 @@ void window_scenery_scrollgetsize() {
short get_scenery_id_by_cursor_pos(short x, short y) {
int tabSceneryIndex = x / SCENERY_BUTTON_WIDTH + (y / SCENERY_BUTTON_HEIGHT) * 9;
uint8 tabIndex = RCT2_GLOBAL(0x00F64EDC, uint8);
uint8 tabIndex = window_scenery_active_tab_index;
int itemCounter = 0;
sint16 sceneryId = 0;
@@ -773,10 +770,10 @@ void window_scenery_scrollmousedown() {
if (sceneryId == -1)
return;
uint8 tabIndex = RCT2_GLOBAL(0x00F64EDC, uint8);
RCT2_ADDRESS(0x00F64EDD, sint16)[tabIndex] = sceneryId;
uint8 tabIndex = window_scenery_active_tab_index;
window_scenery_selected_scenery_by_tab[tabIndex] = sceneryId;
RCT2_GLOBAL(0x00F64F19, uint8) &= 0xFE;
window_scenery_is_repaint_scenery_tool_on &= 0xFE;
sound_play_panned(4, (w->width >> 1) + w->x);
w->scenery.hover_counter = -16;
RCT2_GLOBAL(0x00F64EB4, uint32) = 0x80000000;
@@ -831,7 +828,7 @@ void window_scenery_invalidate() {
window_get_register(w);
uint16 tabIndex = RCT2_GLOBAL(0x00F64EDC, uint8);
uint16 tabIndex = window_scenery_active_tab_index;
uint32 titleStringId = 0x715;
if (tabIndex <= 0x13) {
titleStringId = g_scenerySetEntries[tabIndex]->name;
@@ -840,21 +837,21 @@ void window_scenery_invalidate() {
w->pressed_widgets = (((uint32)w->pressed_widgets & 0xFF00000F) | (1 << (tabIndex + 4))) & 0xBBFFFFFF;
if (RCT2_GLOBAL(0x00F64F19, uint8) == 1) { // repaint colored scenery tool is on
w->pressed_widgets |= 0x04000000;
if (window_scenery_is_repaint_scenery_tool_on == 1) {
w->pressed_widgets |= (1 << WIDX_SCENERY_REPAINT_SCENERY_BUTTON);
}
if (RCT2_GLOBAL(0x00F64F1A, uint8) == 1) { // build cluster tool is on
w->pressed_widgets |= 0x040000000;
if (window_scenery_is_build_cluster_tool_on == 1) {
w->pressed_widgets |= (1 << WIDX_SCENERY_BUILD_CLUSTER_BUTTON);
}
window_scenery_widgets[WIDX_SCENERY_ROTATE_OBJECTS_BUTTON].type = WWT_EMPTY;
window_scenery_widgets[WIDX_SCENERY_BUILD_CLUSTER_BUTTON].type = WWT_EMPTY;
sint16 tabSelectedSceneryId = RCT2_ADDRESS(0x00F64EDD, sint16)[tabIndex];
sint16 tabSelectedSceneryId = window_scenery_selected_scenery_by_tab[tabIndex];
if (tabSelectedSceneryId != -1) {
if (tabSelectedSceneryId < 0x100) {
if (!(RCT2_GLOBAL(0x00F64F19, uint8) & 1))
if (!(window_scenery_is_repaint_scenery_tool_on & 1))
window_scenery_widgets[WIDX_SCENERY_BUILD_CLUSTER_BUTTON].type = WWT_FLATBTN;
rct_scenery_entry* sceneryEntry = g_smallSceneryEntries[tabSelectedSceneryId];
@@ -868,17 +865,17 @@ void window_scenery_invalidate() {
}
window_scenery_widgets[WIDX_SCENERY_PRIMARY_COLOUR_BUTTON].image =
(RCT2_GLOBAL(0x00F64F06, uint8) << 19) + 0x600013C3;
(window_scenery_primary_colour << 19) + 0x600013C3;
window_scenery_widgets[WIDX_SCENERY_SECONDARY_COLOUR_BUTTON].image =
(RCT2_GLOBAL(0x00F64F07, uint8) << 19) + 0x600013C3;
(window_scenery_secondary_colour << 19) + 0x600013C3;
window_scenery_widgets[WIDX_SCENERY_TERTIARY_COLOUR_BUTTON].image =
(RCT2_GLOBAL(0x00F64F08, uint8) << 19) + 0x600013C3;
(window_scenery_tertiary_colour << 19) + 0x600013C3;
window_scenery_widgets[WIDX_SCENERY_PRIMARY_COLOUR_BUTTON].type = WWT_EMPTY;
window_scenery_widgets[WIDX_SCENERY_SECONDARY_COLOUR_BUTTON].type = WWT_EMPTY;
window_scenery_widgets[WIDX_SCENERY_TERTIARY_COLOUR_BUTTON].type = WWT_EMPTY;
if (RCT2_GLOBAL(0x00F64F19, uint8) & 1) { // repaint colored scenery tool is on
if (window_scenery_is_repaint_scenery_tool_on & 1) { // repaint colored scenery tool is on
window_scenery_widgets[WIDX_SCENERY_PRIMARY_COLOUR_BUTTON].type = WWT_COLORBTN;
window_scenery_widgets[WIDX_SCENERY_SECONDARY_COLOUR_BUTTON].type = WWT_COLORBTN;
window_scenery_widgets[WIDX_SCENERY_TERTIARY_COLOUR_BUTTON].type = WWT_COLORBTN;
@@ -965,7 +962,7 @@ void window_scenery_paint() {
window_draw_widgets(w, dpi);
uint16 tabIndex = RCT2_GLOBAL(0x00F64EDC, uint8);
uint16 tabIndex = window_scenery_active_tab_index;
uint16 selectedWidgetId = tabIndex + 4;
uint32 imageId = ((w->colours[1] << 19) | window_scenery_widgets[selectedWidgetId].image) + 1ul;
@@ -976,10 +973,10 @@ void window_scenery_paint() {
sint16 selectedSceneryEntryId = w->scenery.selected_scenery_id;
if (selectedSceneryEntryId == -1) {
if (RCT2_GLOBAL(0x00F64F19, uint8) & 1) // repaint colored scenery tool is on
if (window_scenery_is_repaint_scenery_tool_on & 1) // repaint colored scenery tool is on
return;
selectedSceneryEntryId = RCT2_ADDRESS(0x00F64EDD, sint16)[tabIndex];
selectedSceneryEntryId = window_scenery_selected_scenery_by_tab[tabIndex];
if (selectedSceneryEntryId == -1)
return;
@@ -1035,16 +1032,16 @@ void window_scenery_scrollpaint()
gfx_clear(dpi, ((char*)0x0141FC48)[w->colours[1] * 8] * 0x1010101);
uint8 tabIndex = RCT2_GLOBAL(0x00F64EDC, uint8);
uint8 tabIndex = window_scenery_active_tab_index;
int sceneryTabItemIndex = 0;
sint16 currentSceneryGlobalId = -1;
sint16 left = 0, top = 0;
uint8 sceneryRotation = RCT2_GLOBAL(0x00F64F05, uint8);
while ((currentSceneryGlobalId = window_scenery_tab_entries[tabIndex][sceneryTabItemIndex]) != -1) {
uint16 tabSelectedSceneryId = RCT2_ADDRESS(0x00F64EDD, uint16)[tabIndex];
if (RCT2_GLOBAL(0x00F64F19, uint8) == 1)
while ((currentSceneryGlobalId = window_scenery_tab_entries[tabIndex][sceneryTabItemIndex]) != -1) {
uint16 tabSelectedSceneryId = window_scenery_selected_scenery_by_tab[tabIndex];
if (window_scenery_is_repaint_scenery_tool_on == 1)
{
if (w->scenery.selected_scenery_id == currentSceneryGlobalId) {
gfx_fill_rect_inset(dpi, left, top, left + SCENERY_BUTTON_WIDTH - 1,
@@ -1064,17 +1061,17 @@ void window_scenery_scrollpaint()
rct_scenery_entry* sceneryEntry;
if (currentSceneryGlobalId >= 0x400) {
sceneryEntry = g_bannerSceneryEntries[currentSceneryGlobalId - 0x400];
uint32 imageId = sceneryEntry->image + sceneryRotation * 2;
imageId |= (RCT2_GLOBAL(0x00F64F06, uint8) << 19) | 0x20000000;
uint32 imageId = sceneryEntry->image + window_scenery_rotation * 2;
imageId |= (window_scenery_primary_colour << 19) | 0x20000000;
gfx_draw_sprite(dpi, imageId, left + 0x21, top + 0x28, w->colours[1]);
gfx_draw_sprite(dpi, imageId + 1, left + 0x21, top + 0x28, w->colours[1]);
}
else if (currentSceneryGlobalId >= 0x300) {
sceneryEntry = g_largeSceneryEntries[currentSceneryGlobalId - 0x300];
uint32 imageId = sceneryEntry->image + sceneryRotation;
imageId |= (RCT2_GLOBAL(0x00F64F06, uint8) << 19) | 0x20000000;
imageId |= (RCT2_GLOBAL(0x00F64F07, uint8) << 24) | 0x80000000;
uint32 imageId = sceneryEntry->image + window_scenery_rotation;
imageId |= (window_scenery_primary_colour << 19) | 0x20000000;
imageId |= (window_scenery_secondary_colour << 24) | 0x80000000;
gfx_draw_sprite(dpi, imageId, left + 0x21, top, w->colours[1]);
}
@@ -1086,21 +1083,21 @@ void window_scenery_scrollpaint()
uint8 tertiaryColour = w->colours[1];
if (sceneryEntry->wall.flags & WALL_SCENERY_FLAG2) {
imageId |= (RCT2_GLOBAL(0x00F64F06, uint8) << 19) | 0x20000000;
imageId |= (window_scenery_primary_colour << 19) | 0x20000000;
if (sceneryEntry->wall.flags & WALL_SCENERY_HAS_SECONDARY_COLOUR) {
imageId |= (RCT2_GLOBAL(0x00F64F07, uint8) << 24) | 0x80000000;
imageId |= (window_scenery_secondary_colour << 24) | 0x80000000;
}
}
else {
imageId |= (RCT2_GLOBAL(0x00F64F06, uint8) << 19) | 0x20000000;
imageId |= (window_scenery_primary_colour << 19) | 0x20000000;
if (sceneryEntry->wall.flags & WALL_SCENERY_HAS_SECONDARY_COLOUR) {
imageId |= (RCT2_GLOBAL(0x00F64F07, uint8) << 24) | 0x80000000;
imageId |= (window_scenery_secondary_colour << 24) | 0x80000000;
if (sceneryEntry->wall.flags & WALL_SCENERY_HAS_TERNARY_COLOUR) {
imageId &= 0xDFFFFFFF;
tertiaryColour = RCT2_GLOBAL(0x00F64F08, uint8);
tertiaryColour = window_scenery_tertiary_colour;
}
}
@@ -1121,13 +1118,13 @@ void window_scenery_scrollpaint()
rct_drawpixelinfo* clipdpi = clip_drawpixelinfo(dpi, left + 1, SCENERY_BUTTON_WIDTH - 2, top + 1, SCENERY_BUTTON_HEIGHT - 2);
if (clipdpi != NULL) {
uint32 imageId = sceneryEntry->image + sceneryRotation;
uint32 imageId = sceneryEntry->image + window_scenery_rotation;
if (sceneryEntry->small_scenery.flags & SMALL_SCENERY_HAS_PRIMARY_COLOUR) {
imageId |= (RCT2_GLOBAL(0x00F64F06, uint8) << 19) | 0x20000000;
imageId |= (window_scenery_primary_colour << 19) | 0x20000000;
if (sceneryEntry->small_scenery.flags & SMALL_SCENERY_HAS_SECONDARY_COLOUR) {
imageId |= (RCT2_GLOBAL(0x00F64F07, uint8) << 24) | 0x80000000;
imageId |= (window_scenery_secondary_colour << 24) | 0x80000000;
}
}
@@ -1141,14 +1138,14 @@ void window_scenery_scrollpaint()
gfx_draw_sprite(clipdpi, imageId, 0x20, spriteTop, w->colours[1]);
if (sceneryEntry->small_scenery.flags & 0x200) {
imageId = ((sceneryEntry->image + sceneryRotation) + 0x40000004) +
((RCT2_GLOBAL(0x00F64F06, uint8) + 0x70) << 19);
imageId = ((sceneryEntry->image + window_scenery_rotation) + 0x40000004) +
((window_scenery_primary_colour + 0x70) << 19);
gfx_draw_sprite(clipdpi, imageId, 0x20, spriteTop, w->colours[1]);
}
if (sceneryEntry->small_scenery.flags & SMALL_SCENERY_FLAG8) {
imageId = (sceneryEntry->image + sceneryRotation) + 4;
imageId = (sceneryEntry->image + window_scenery_rotation) + 4;
gfx_draw_sprite(clipdpi, imageId, 0x20, spriteTop, w->colours[1]);
}

39
src/window_scenery.h Normal file
View File

@@ -0,0 +1,39 @@
/*****************************************************************************
* Copyright (c) 2014 Dániel Tar
* 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 _WINDOW_SCENERY_H_
#define _WINDOW_SCENERY_H_
#define WINDOW_SCENERY_WIDTH 0x27A
#define WINDOW_SCENERY_HEIGHT 0x8E
#define SCENERY_BUTTON_WIDTH 66
#define SCENERY_BUTTON_HEIGHT 80
#define SCENERY_ENTRIES_BY_TAB 128
#define window_scenery_active_tab_index RCT2_GLOBAL(0x00F64EDC, uint8)
#define window_scenery_selected_scenery_by_tab RCT2_ADDRESS(0x00F64EDD, sint16)
#define window_scenery_is_build_cluster_tool_on RCT2_GLOBAL(0x00F64F1A, uint8)
#define window_scenery_is_repaint_scenery_tool_on RCT2_GLOBAL(0x00F64F19, uint8)
#define window_scenery_rotation RCT2_GLOBAL(0x00F64F05, uint8)
#define window_scenery_primary_colour RCT2_GLOBAL(0x00F64F06, uint8)
#define window_scenery_secondary_colour RCT2_GLOBAL(0x00F64F07, uint8)
#define window_scenery_tertiary_colour RCT2_GLOBAL(0x00F64F08, uint8)
#endif