Merge remote-tracking branch 'upstream/master' into scenery-window

Resolve conflict in projects/openrct2.vcxproj.filters
This commit is contained in:
qcz 2014-08-27 18:21:11 +02:00
commit 2eef202628
43 changed files with 4108 additions and 2471 deletions

View File

@ -55,6 +55,6 @@ set_target_properties(${PROJECT} PROPERTIES PREFIX "")
TARGET_LINK_LIBRARIES(${PROJECT} ${SDL2_LIBRARIES})
if (WIN32)
target_link_libraries(${PROJECT} winmm.lib -limm32 -lversion)
target_link_libraries(${PROJECT} winmm.lib -limm32 -lversion -ldsound)
endif (WIN32)

View File

@ -1,20 +1,11 @@
SET(CMAKE_SYSTEM_NAME Windows)
if (APPLE)
SET(COMPILER_PREFIX i586-mingw32)
SET(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
SET(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-c++)
SET(CMAKE_RC_COMPILER ${COMPILER_PREFIX}-windres)
SET(CMAKE_PKGCONFIG_EXECUTABLE i686-w64-mingw32-pkg-config)
SET(PKG_CONFIG_EXECUTABLE i686-w64-mingw32-pkg-config)
else()
SET(COMPILER_PREFIX i686-w64-mingw32)
SET(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
SET(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-c++)
SET(CMAKE_RC_COMPILER ${COMPILER_PREFIX}-windres)
SET(CMAKE_PKGCONFIG_EXECUTABLE ${COMPILER_PREFIX}-pkg-config)
SET(PKG_CONFIG_EXECUTABLE ${COMPILER_PREFIX}-pkg-config)
endif (APPLE)
SET(COMPILER_PREFIX i686-w64-mingw32)
SET(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
SET(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-c++)
SET(CMAKE_RC_COMPILER ${COMPILER_PREFIX}-windres)
SET(CMAKE_PKGCONFIG_EXECUTABLE ${COMPILER_PREFIX}-pkg-config)
SET(PKG_CONFIG_EXECUTABLE ${COMPILER_PREFIX}-pkg-config)
# potential flags to make code more similar to MSVC:
# -fshort-wchar -fshort-enums -mms-bitfields
@ -22,15 +13,19 @@ endif (APPLE)
set(CMAKE_C_FLAGS "-masm=intel -std=gnu99 -fpack-struct=2" CACHE STRING "" FORCE)
set(CMAKE_SHARED_LINKER_FLAGS "-static-libgcc" CACHE STRING "" FORCE)
include_directories("/usr/include/wine/windows/")
# find and include SDL2
INCLUDE(FindPkgConfig)
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS})
if(APPLE)
SET(TARGET_ENVIRONMENT /usr/local/mingw-w32-bin_i686-darwin/i686-w64-mingw32)
else()
SET(TARGET_ENVIRONMENT /usr/i686-w64-mingw32)
endif(APPLE)
# here is the target environment located
#SET(CMAKE_FIND_ROOT_PATH /usr/${COMPILER_PREFIX})
SET(CMAKE_FIND_ROOT_PATH ${TARGET_ENVIRONMENT})
# adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search

File diff suppressed because it is too large Load Diff

View File

@ -49,18 +49,29 @@ if [[ `uname` == "Darwin" ]]; then
sudo ln -s $wine_path /usr/include
fi
mingw_dmg=gcc-4.8.0-qt-4.8.4-for-mingw32.dmg
mingw_path=/usr/local/gcc-4.8.0-qt-4.8.4-for-mingw32/win32-gcc/bin
if [[ ! -f $cachedir/$mingw_dmg ]]; then
wget http://crossgcc.rts-software.org/download/gcc-4.8.0-qt-4.8.4-win32/$mingw_dmg --output-document $cachedir/$mingw_dmg
mingw_name=mingw-w32-bin_i686-darwin
mingw_tar=$mingw_name"_20130531".tar.bz2
mingw_path=/usr/local/$mingw_name
if [[ ! -f $cachedir/$mingw_tar ]]; then
wget "https://downloads.sourceforge.net/project/mingw-w64/Toolchains targetting Win32/Automated Builds/$mingw_tar" --output-document $cachedir/$mingw_tar
fi
if [[ ! -d $ming_path ]]; then
if [[ ! -d $mingw_path ]]; then
echo "Open the DMG file and install its contents"
open $cachedir/$mingw_dmg
pushd /usr/local/
sudo mkdir $mingw_name
popd
echo "Extracting contents of $mingw_tar to $mingw_path"
echo "Don't forget to add $mingw_path to your PATH variable!"
sudo tar -xyf $cachedir/$mingw_tar -C $mingw_path
pushd /usr/local
sudo chmod 755 $mingw_name
pushd $mingw_name
sudo find . -type d -exec chmod 755 {} \;
popd
popd
fi
echo "You will need to add $mingw_path to your \$PATH"
elif [[ `uname` == "Linux" ]]; then
sudo apt-get install -y --force-yes binutils-mingw-w64-i686 gcc-mingw-w64-i686 g++-mingw-w64-i686
fi

View File

@ -28,6 +28,7 @@
<ClInclude Include="..\src\game.h" />
<ClInclude Include="..\src\gfx.h" />
<ClInclude Include="..\src\graph.h" />
<ClInclude Include="..\src\input.h" />
<ClInclude Include="..\src\intro.h" />
<ClInclude Include="..\src\language.h" />
<ClInclude Include="..\src\map.h" />
@ -74,6 +75,7 @@
<ClCompile Include="..\src\game.c" />
<ClCompile Include="..\src\gfx.c" />
<ClCompile Include="..\src\graph.c" />
<ClCompile Include="..\src\input.c" />
<ClCompile Include="..\src\intro.c" />
<ClCompile Include="..\src\language.c" />
<ClCompile Include="..\src\map.c" />
@ -121,6 +123,7 @@
<ClCompile Include="..\src\window_options.c" />
<ClCompile Include="..\src\window_peep.c" />
<ClCompile Include="..\src\window_research.c" />
<ClCompile Include="..\src\window_ride.c" />
<ClCompile Include="..\src\window_ride_list.c" />
<ClCompile Include="..\src\window_save_prompt.c" />
<ClCompile Include="..\src\window_staff.c" />
@ -199,7 +202,7 @@
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>winmm.lib;sdl2.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winmm.lib;sdl2.lib;Dsound.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -222,7 +225,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>winmm.lib;sdl2.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winmm.lib;sdl2.lib;Dsound.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /Y "$(ProjectDir)\..\Data\Language\*.*" "$(TargetDir)\Data\Language\"</Command>

View File

@ -159,6 +159,9 @@
<ClInclude Include="..\src\staff.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\input.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\game.c">
@ -380,6 +383,12 @@
<ClCompile Include="..\src\window_scenery.c">
<Filter>Windows</Filter>
</ClCompile>
<ClCompile Include="..\src\input.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\window_ride.c">
<Filter>Windows</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\openrct2.exe">

View File

@ -33,6 +33,7 @@
#define RCT2_CALLFUNC_3(address, returnType, a1, a2, a3, v1, v2, v3) (((returnType(*)(a1, a2, a3))(address))(v1, v2, v3))
#define RCT2_CALLFUNC_4(address, returnType, a1, a2, a3, a4, v1, v2, v3, v4) (((returnType(*)(a1, a2, a3, a4))(address))(v1, v2, v3, v4))
#define RCT2_CALLFUNC_5(address, returnType, a1, a2, a3, a4, a5, v1, v2, v3, v4, v5) (((returnType(*)(a1, a2, a3, a4, a5))(address))(v1, v2, v3, v4, v5))
#define RCT2_CALLFUNC_6(address, returnType, a1, a2, a3, a4, a5, a6, v1, v2, v3, v4, v5, v6) (((returnType(*)(a1, a2, a3, a4, a5, a6))(address))(v1, v2, v3, v4, v5, v6))
#define RCT2_CALLPROC_1(address, a1, v1) RCT2_CALLFUNC_1(address, void, a1, v1)
#define RCT2_CALLPROC_2(address, a1, a2, v1, v2) RCT2_CALLFUNC_2(address, void, a1, a2, v1, v2)
@ -106,6 +107,10 @@
#define RCT2_ADDRESS_INSTALLED_OBJECT_LIST 0x009ADAE8
#define RCT2_ADDRESS_CURRENT_SOUND_DEVICE 0x009AF280
#define RCT2_ADDRESS_VEHICLE_SOUND_LIST 0x009AF288
#define RCT2_ADDRESS_CURENT_CURSOR 0x009DE51C
#define RCT2_ADDRESS_INPUT_STATE 0x009DE51D
#define RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS 0x009DE51F
@ -154,8 +159,14 @@
#define RCT2_ADDRESS_WINDOW_DPI 0x009DEA74
#define RCT2_ADDRESS_DSOUND_BUFFERS 0x009E1AB0
#define RCT2_ADDRESS_NUM_DSOUND_DEVICES 0x009E2B88
#define RCT2_ADDRESS_DSOUND_DEVICES 0x009E2B8C
#define RCT2_ADDRESS_SOUND_INFO_LIST_MAPPING 0x009E2B94
#define RCT2_ADDRESS_SOUNDLIST_BEGIN 0x009E2B98
#define RCT2_ADDRESS_SOUNDLIST_END 0x009E2B9C
#define RCT2_ADDRESS_DIRECTSOUND 0x009E2BA0
#define RCT2_ADDRESS_DSOUND_DEVICES_COUNTER 0x009E2BAC
#define RCT2_ADDRESS_CMDLINE 0x009E2D98
@ -193,6 +204,7 @@
#define RCT2_ADDRESS_CURRENT_MONTH_YEAR 0x00F663A8
#define RCT2_ADDRESS_CURRENT_MONTH_TICKS 0x00F663AA
#define RCT2_ADDRESS_SCENARIO_TICKS 0x00F663AC
#define RCT2_ADDRESS_SCENARIO_SRAND_0 0x00F663B0
#define RCT2_ADDRESS_SCENARIO_SRAND_1 0x00F663B4
@ -254,6 +266,7 @@
#define RCT2_ADDRESS_NEXT_RESEARCH_EXPECTED_DAY 0x013580E7
#define RCT2_ADDRESS_NEXT_RESEARCH_EXPECTED_MONTH 0x013580E8
#define RCT2_ADDRESS_MAP_MAXIMUM_X_Y 0x01358832
#define RCT2_ADDRESS_MAP_SIZE 0x01358834
#define RCT2_ADDRESS_PARK_SIZE 0x013580EA
@ -305,7 +318,9 @@
#define RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER 0x0141ED68
#define RCT2_ADDRESS_AUDIO_INFO 0x01425B40
#define RCT2_ADDRESS_SOUND_CHANNEL_LIST 0x014262E0
#define RCT2_ADDRESS_WATER_RAISE_COST 0x0141F738
#define RCT2_ADDRESS_WATER_LOWER_COST 0x0141F73C

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,8 @@
#ifndef _AUDIO_H_
#define _AUDIO_H_
#include "rct2.h"
typedef struct {
char name[256];
} audio_device;
@ -31,7 +33,7 @@ extern audio_device *gAudioDevices;
void audio_init();
void audio_quit();
void audio_get_devices();
void audio_init2(int device);
#include <dsound.h>
@ -47,20 +49,83 @@ typedef struct {
/**
* Represents a prepared sound.
*/
typedef struct {
typedef struct rct_sound {
LPDIRECTSOUNDBUFFER dsbuffer;
int id;
int has_caps;
int var_0C;
int var_10;
struct rct_sound* next;
} rct_sound;
void get_dsound_devices();
int sound_prepare(int sound_id, rct_sound *sound, int var_8, int var_c);
void sound_play_panned(int sound_id, int x);
typedef struct {
uint16 var_0;
uint16 channels;
uint32 samples;
uint32 var_8;
uint16 bytes;
uint16 bits;
uint16 var_E;
} rct_audio_info;
typedef struct {
uint32 var_0;
uint8 pad_4[0x118];
HMMIO hmmio;
HGLOBAL hmem;
uint8 pad_124[0x3C];
uint32 var_160;
uint32 var_164;
uint32 var_168;
} rct_sound_channel;
typedef struct {
uint32 size;
WAVEFORMATEX format;
char* data;
} rct_sound_info;
typedef struct {
uint16 id;
uint16 var_2;
rct_sound sound1; // 0x04
uint16 var_18;
uint8 pad_1A[0x06];
rct_sound sound2; // 0x20
uint16 var_34;
uint8 pad_36[0x06];
} rct_vehicle_sound;
typedef struct {
uint16 id;
rct_sound sound;
} rct_other_sound;
int get_dsound_devices();
int sound_prepare(int sound_id, rct_sound *sound, int channels, int software);
int sound_play_panned(int sound_id, int x);
int sound_play(rct_sound* sound, int looping, int volume, int pan, int frequency);
void sound_stop(rct_sound *sound);
int sound_is_playing(rct_sound* sound);
int sound_set_frequency(rct_sound* sound, int frequency);
int sound_set_pan(rct_sound* sound, int pan);
int sound_set_volume(rct_sound* sound, int volume);
int sound_channel_play(int channel, int a2, int volume, int pan, int frequency);
int sound_channel_set_frequency(int channel, int frequency);
int sound_channel_set_pan(int channel, int pan);
int sound_channel_set_volume(int channel, int volume);
int sound_stop(rct_sound *sound);
int sound_stop_all();
int unmap_file(LPCVOID base);
int sound_channel_stop(int channel);
rct_sound* sound_add(rct_sound* sound);
rct_sound* sound_remove(rct_sound* sound);
rct_sound* sound_begin();
rct_sound* sound_next(rct_sound* sound);
void pause_sounds();
void stop_other_sounds();
void stop_vehicle_sounds();
void stop_ride_music();
void stop_peep_sounds();
void stop_title_music();
void unpause_sounds();
// 0x009AF59C probably does the same job

View File

@ -131,12 +131,12 @@ static int award_is_deserved_best_rollercoasters(int awardType, int activeAwardT
{
int i, rollerCoasters;
rct_ride *ride;
char *object;
rct_ride_type *rideType;
rollerCoasters = 0;
FOR_ALL_RIDES(i, ride) {
object = RCT2_ADDRESS(0x009ACFA4, char*)[ride->subtype];
if (RCT2_GLOBAL(object + 0x1BE, uint8) != RIDE_GROUP_ROLLERCOASTER && RCT2_GLOBAL(object + 0x1BF, uint8) != RIDE_GROUP_ROLLERCOASTER)
rideType = gRideTypeList[ride->subtype];
if (rideType->category[0] != RIDE_GROUP_ROLLERCOASTER && rideType->category[1] != RIDE_GROUP_ROLLERCOASTER)
continue;
if (ride->status != RIDE_STATUS_OPEN || (ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED))
@ -274,7 +274,7 @@ static int award_is_deserved_best_food(int awardType, int activeAwardTypes)
int i, hungryPeeps, shops, uniqueShops;
uint64 shopTypes;
rct_ride *ride;
char *object;
rct_ride_type *rideType;
uint16 spriteIndex;
rct_peep *peep;
@ -291,9 +291,9 @@ static int award_is_deserved_best_food(int awardType, int activeAwardTypes)
continue;
shops++;
object = RCT2_ADDRESS(0x009ACFA4, char*)[ride->subtype];
if (!(shopTypes & (1ULL << RCT2_GLOBAL(object + 0x1C0, uint8)))) {
shopTypes |= (1ULL << RCT2_GLOBAL(object + 0x1C0, uint8));
rideType = gRideTypeList[ride->subtype];
if (!(shopTypes & (1ULL << rideType->shop_item))) {
shopTypes |= (1ULL << rideType->shop_item);
uniqueShops++;
}
}
@ -320,7 +320,7 @@ static int award_is_deserved_worst_food(int awardType, int activeAwardTypes)
int i, hungryPeeps, shops, uniqueShops;
uint64 shopTypes;
rct_ride *ride;
char *object;
rct_ride_type *rideType;
uint16 spriteIndex;
rct_peep *peep;
@ -337,9 +337,9 @@ static int award_is_deserved_worst_food(int awardType, int activeAwardTypes)
continue;
shops++;
object = RCT2_ADDRESS(0x009ACFA4, char*)[ride->subtype];
if (!(shopTypes & (1ULL << RCT2_GLOBAL(object + 0x1C0, uint8)))) {
shopTypes |= (1ULL << RCT2_GLOBAL(object + 0x1C0, uint8));
rideType = gRideTypeList[ride->subtype];
if (!(shopTypes & (1ULL << rideType->shop_item))) {
shopTypes |= (1ULL << rideType->shop_item);
uniqueShops++;
}
}
@ -430,12 +430,12 @@ static int award_is_deserved_best_water_rides(int awardType, int activeAwardType
{
int i, waterRides;
rct_ride *ride;
char *object;
rct_ride_type *rideType;
waterRides = 0;
FOR_ALL_RIDES(i, ride) {
object = RCT2_ADDRESS(0x009ACFA4, char*)[ride->subtype];
if (RCT2_GLOBAL(object + 0x1BE, uint8) != RIDE_GROUP_WATER && RCT2_GLOBAL(object + 0x1BF, uint8) != RIDE_GROUP_WATER)
rideType = gRideTypeList[ride->subtype];
if (rideType->category[0] != RIDE_GROUP_WATER && rideType->category[1] != RIDE_GROUP_WATER)
continue;
if (ride->status != RIDE_STATUS_OPEN || (ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED))
@ -522,12 +522,12 @@ static int award_is_deserved_best_gentle_rides(int awardType, int activeAwardTyp
{
int i, gentleRides;
rct_ride *ride;
char *object;
rct_ride_type *rideType;
gentleRides = 0;
FOR_ALL_RIDES(i, ride) {
object = RCT2_ADDRESS(0x009ACFA4, char*)[ride->subtype];
if (RCT2_GLOBAL(object + 0x1BE, uint8) != RIDE_GROUP_GENTLE && RCT2_GLOBAL(object + 0x1BF, uint8) != RIDE_GROUP_GENTLE)
rideType = gRideTypeList[ride->subtype];
if (rideType->category[0] != RIDE_GROUP_GENTLE && rideType->category[1] != RIDE_GROUP_GENTLE)
continue;
if (ride->status != RIDE_STATUS_OPEN || (ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED))

View File

@ -186,7 +186,7 @@ static void climate_determine_future_weather()
*/
void climate_update_sound()
{
if (RCT2_GLOBAL(0x009AF280, uint32) == 0xFFFFFFFF)
if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) == 0xFFFFFFFF)
return;
if (RCT2_GLOBAL(0x009AF59C, uint8) != 0)
return;
@ -210,13 +210,13 @@ static void climate_update_rain_sound()
} else {
// Increase rain sound
_rainVolume = min(-1400, _rainVolume + 80);
RCT2_CALLPROC_2(0x00404F0D, rct_sound*, int, &_rainSoundInstance, _rainVolume);
sound_set_volume(&_rainSoundInstance, _rainVolume);
}
} else if (_rainVolume != 1) {
// Decrease rain sound
_rainVolume -= 80;
if (_rainVolume > -4000) {
RCT2_CALLPROC_2(0x00404F0D, rct_sound*, int, &_rainSoundInstance, _rainVolume);
sound_set_volume(&_rainSoundInstance, _rainVolume);
} else {
sound_stop(&_rainSoundInstance);
_rainVolume = 1;
@ -248,7 +248,7 @@ static void climate_update_thunder_sound()
if (_thunderStatus[i] == THUNDER_STATUS_NULL)
continue;
if (!RCT2_CALLFUNC_1(0x00404E53, int, rct_sound*, &_thunderSoundInstance[i])) {
if (!sound_is_playing(&_thunderSoundInstance[i])) {
sound_stop(&_thunderSoundInstance[i]);
_thunderStatus[i] = THUNDER_STATUS_NULL;
}

View File

@ -73,7 +73,7 @@ void editor_load()
RCT2_CALLPROC_EBPSAFE(0x0066EF38); // window_main_editor_create
mainWindow = window_get_main();
window_scroll_to_location(mainWindow, 2400, 2400, 112);
mainWindow->flags &= ~WF_3;
mainWindow->flags &= ~WF_SCROLLING_TO_LOCATION;
RCT2_CALLPROC_EBPSAFE(0x006837E3);
gfx_invalidate_screen();
RCT2_GLOBAL(0x009DEA66, sint16) = 0;
@ -120,7 +120,7 @@ void trackdesigner_load()
RCT2_CALLPROC_EBPSAFE(0x0066EF38); // window_main_editor_create
mainWindow = window_get_main();
window_scroll_to_location(mainWindow, 2400, 2400, 112);
mainWindow->flags &= ~WF_3;
mainWindow->flags &= ~WF_SCROLLING_TO_LOCATION;
RCT2_CALLPROC_EBPSAFE(0x006837E3);
gfx_invalidate_screen();
RCT2_GLOBAL(0x009DEA66, sint16) = 0;
@ -158,7 +158,7 @@ void trackmanager_load()
RCT2_CALLPROC_EBPSAFE(0x0066EF38); // window_main_editor_create
mainWindow = window_get_main();
window_scroll_to_location(mainWindow, 2400, 2400, 112);
mainWindow->flags &= ~WF_3;
mainWindow->flags &= ~WF_SCROLLING_TO_LOCATION;
RCT2_CALLPROC_EBPSAFE(0x006837E3);
gfx_invalidate_screen();
RCT2_GLOBAL(0x009DEA66, sint16) = 0;

1849
src/game.c

File diff suppressed because it is too large Load Diff

View File

@ -84,6 +84,8 @@ enum GAME_COMMAND {
typedef void (GAME_COMMAND_POINTER)(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
extern int gGameSpeed;
void game_create_windows();
void game_update();
void game_logic_update();

View File

@ -2317,7 +2317,7 @@ rct_drawpixelinfo* clip_drawpixelinfo(rct_drawpixelinfo* dpi, int left, int widt
* x_start: edi
* y_start: esi
*/
void gfx_draw_rain(int left, int top, int width, int height, uint32 x_start, uint32 y_start){
void gfx_draw_rain(int left, int top, int width, int height, sint32 x_start, sint32 y_start){
uint8* pattern = RCT2_GLOBAL(RCT2_ADDRESS_RAIN_PATTERN, uint8*);
uint8 pattern_x_space = *pattern++;
uint8 pattern_y_space = *pattern++;

View File

@ -92,7 +92,7 @@ void gfx_draw_all_dirty_blocks();
void gfx_redraw_screen_rect(short left, short top, short right, short bottom);
void gfx_invalidate_screen();
void gfx_draw_rain(int left, int top, int width, int height, uint32 x_start, uint32 y_start);
void gfx_draw_rain(int left, int top, int width, int height, sint32 x_start, sint32 y_start);
rct_drawpixelinfo* clip_drawpixelinfo(rct_drawpixelinfo* dpi, int left, int width, int top, int height);

1765
src/input.c Normal file

File diff suppressed because it is too large Load Diff

27
src/input.h Normal file
View File

@ -0,0 +1,27 @@
/*****************************************************************************
* 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 _INPUT_H_
#define _INPUT_H_
void game_handle_input();
void game_handle_keyboard_input();
#endif

View File

@ -80,7 +80,7 @@ void intro_update()
// Chain lift sound
_sound_playing_flag = 0;
if (RCT2_GLOBAL(0x009AF280, sint32) != -1) {
if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, sint32) != -1) {
// Prepare and play the sound
if (sound_prepare(SOUND_LIFT_7, &_prepared_sound, 0, 1))
if (sound_play(&_prepared_sound, 1, 0, 0, 0))
@ -157,7 +157,7 @@ void intro_update()
}
// Play the track friction sound
if (RCT2_GLOBAL(0x009AF280, sint32) != -1) {
if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, sint32) != -1) {
// Prepare and play the sound
if (sound_prepare(SOUND_TRACK_FRICTION_3, &_prepared_sound, 1, 1))
if (sound_play(&_prepared_sound, 1, -800, 0, 0x3A98))
@ -188,7 +188,7 @@ void intro_update()
}
// Play long peep scream sound
if (RCT2_GLOBAL(0x009AF280, sint32) != -1)
if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, sint32) != -1)
if (sound_prepare(SOUND_SCREAM_1, &_prepared_sound, 0, 1))
if (sound_play(&_prepared_sound, 0, 0, 0, 0))
_sound_playing_flag = 1;

View File

@ -102,7 +102,7 @@ void map_init()
RCT2_GLOBAL(0x013CE774, sint16) = 0;
RCT2_GLOBAL(0x013CE776, sint16) = 0;
RCT2_GLOBAL(0x01358830, sint16) = 4768;
RCT2_GLOBAL(0x01358832, sint16) = 5054;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16) = 5054;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, sint16) = 150;
RCT2_GLOBAL(0x01358836, sint16) = 4767;
RCT2_GLOBAL(0x01359208, sint16) = 7;
@ -141,7 +141,7 @@ void map_update_tile_pointers()
/**
* Return the absolute height of an element, given its (x,y) coordinates
*
*
* rct2: 0x00662783
*/
int map_element_height(int x, int y)
@ -168,7 +168,7 @@ int map_element_height(int x, int y)
// Remove the extra height bit
slope &= 0xF;
uint8 quad, quad_extra; // which quadrant the element is in?
sint8 quad, quad_extra; // which quadrant the element is in?
// quad_extra is for extra height tiles
uint8 xl, yl; // coordinates across this tile
@ -198,7 +198,7 @@ int map_element_height(int x, int y)
quad = TILE_SIZE - yl - xl;
break;
case 8: // NW corner up
quad = xl - yl;
quad = yl - xl;
break;
}
// If the element is in the quadrant with the slope, raise its height
@ -210,7 +210,7 @@ int map_element_height(int x, int y)
// One side up
switch (slope) {
case 3: // E side up
height += xl / 2;
height += xl / 2 + 1;
break;
case 6: // S side up
height += (TILE_SIZE - yl) / 2;
@ -233,15 +233,15 @@ int map_element_height(int x, int y)
break;
case 11: // SW corner down
quad_extra = xl + yl;
quad = xl + yl - TILE_SIZE;
quad = xl + yl - TILE_SIZE - 1;
break;
case 13: // SE corner down
quad_extra = TILE_SIZE - xl + yl;
quad = xl - yl;
quad = yl - xl;
break;
case 14: // NE corner down
quad_extra = (TILE_SIZE - xl) + (TILE_SIZE - yl);
quad = TILE_SIZE - yl - xl;
quad = TILE_SIZE - yl - xl - 1;
break;
}
@ -255,7 +255,6 @@ int map_element_height(int x, int y)
// so we move *down* the slope
if (quad < 0) {
height += quad / 2;
height += 0xFF00;
}
}

View File

@ -24,8 +24,8 @@
#include "rct2.h"
typedef struct {
uint8 slope;
uint8 terrain;
uint8 slope; //4
uint8 terrain; //5
uint8 grass_length;
uint8 ownership;
} rct_map_element_surface_properties;
@ -92,10 +92,10 @@ typedef union {
* size: 0x08
*/
typedef struct {
uint8 type;
uint8 flags;
uint8 base_height;
uint8 clearance_height;
uint8 type; //0
uint8 flags; //1
uint8 base_height; //2
uint8 clearance_height; //3
rct_map_element_properties properties;
} rct_map_element;
@ -177,6 +177,8 @@ enum {
#define MAP_ELEMENT_WATER_HEIGHT_MASK 0x1F
#define MAP_ELEMENT_SURFACE_TERRAIN_MASK 0xE0
#define MAP_MINIMUM_X_Y -256
#define MAX_MAP_ELEMENTS 196608
#define MAX_TILE_MAP_ELEMENT_POINTERS (256 * 256)

View File

@ -264,7 +264,7 @@ void news_item_add_to_queue(uint8 type, rct_string_id string_id, uint32 assoc)
newsItem->assoc = assoc;
newsItem->ticks = 0;
newsItem->month_year = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, uint16);
newsItem->day = (days_in_month[(newsItem->month_year & 7)] * RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_TICKS, uint16)) >> 16;
newsItem->day = ((days_in_month[(newsItem->month_year & 7)] * RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_TICKS, uint16)) >> 16) + 1;
format_string((char*)0x0141EF68, string_id, (void*)0x013CE952); // overflows possible?
newsItem->colour = ((char*)0x0141EF68)[0];

View File

@ -44,7 +44,7 @@ unsigned int gLastKeyPressed;
static void osinterface_create_window();
static void osinterface_close_window();
static void osinterface_resize(int width, int height);
static void sub_406C96(int actionType);
static SDL_Window *_window;
static SDL_Surface *_surface;
@ -350,7 +350,7 @@ void osinterface_process_messages()
RCT2_GLOBAL(0x0142431C, int) = e.button.y;
switch (e.button.button) {
case SDL_BUTTON_LEFT:
RCT2_CALLPROC_1(0x00406C96, int, 1);
sub_406C96(1); //RCT2_CALLPROC_1(0x00406C96, int, 1);
gCursorState.left = CURSOR_PRESSED;
gCursorState.old = 1;
break;
@ -358,7 +358,7 @@ void osinterface_process_messages()
gCursorState.middle = CURSOR_PRESSED;
break;
case SDL_BUTTON_RIGHT:
RCT2_CALLPROC_1(0x00406C96, int, 3);
sub_406C96(3); //RCT2_CALLPROC_1(0x00406C96, int, 3);
gCursorState.right = CURSOR_PRESSED;
gCursorState.old = 2;
break;
@ -369,7 +369,7 @@ void osinterface_process_messages()
RCT2_GLOBAL(0x0142431C, int) = e.button.y;
switch (e.button.button) {
case SDL_BUTTON_LEFT:
RCT2_CALLPROC_1(0x00406C96, int, 2);
sub_406C96(2); //RCT2_CALLPROC_1(0x00406C96, int, 2);
gCursorState.left = CURSOR_RELEASED;
gCursorState.old = 3;
break;
@ -377,7 +377,7 @@ void osinterface_process_messages()
gCursorState.middle = CURSOR_RELEASED;
break;
case SDL_BUTTON_RIGHT:
RCT2_CALLPROC_1(0x00406C96, int, 4);
sub_406C96(4); //RCT2_CALLPROC_1(0x00406C96, int, 4);
gCursorState.right = CURSOR_RELEASED;
gCursorState.old = 4;
break;
@ -452,6 +452,7 @@ int osinterface_open_common_file_dialog(int type, char *title, char *filename, c
OPENFILENAME openFileName;
BOOL result;
int tmp;
DWORD commonFlags;
// Get directory path from given filename
strcpy(initialDirectory, filename);
@ -488,11 +489,12 @@ int osinterface_open_common_file_dialog(int type, char *title, char *filename, c
RCT2_GLOBAL(0x009E2C74, uint32) = 1;
// Open dialog
commonFlags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
if (type == 0) {
openFileName.Flags = OFN_EXPLORER | OFN_CREATEPROMPT | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
openFileName.Flags = commonFlags | OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT;
result = GetSaveFileName(&openFileName);
} else if (type == 1) {
openFileName.Flags = OFN_EXPLORER | OFN_NONETWORKBUTTON | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
openFileName.Flags = commonFlags | OFN_NONETWORKBUTTON | OFN_FILEMUSTEXIST;
result = GetOpenFileName(&openFileName);
}
@ -596,3 +598,23 @@ char osinterface_get_path_separator()
{
return '\\';
}
void sub_406C96(int actionType)
{
int eax = RCT2_GLOBAL(0x009E2DE4, uint32);
int ecx = eax + 1;
ecx &= 0x3F; //Array of 64 point structs, loop around buffer?
if (ecx != RCT2_GLOBAL(0x009E2DE8, uint32)) {
int edx = RCT2_GLOBAL(0x01424318, uint32); // X
//eax is a struct index here. Mutliplied by then and then 4 for the struct with 3 4 byte fields
//Struct is {int x, int y, int actionType}
eax = eax + eax*2;
eax = 0x01424340 + eax * 4; //get base of struct, address is base of array
*((uint32*)eax) = edx;
edx = RCT2_GLOBAL(0x0142431C, uint32); // Y
*((uint32*)eax + 1) = edx;
edx = actionType;
*((uint32*)eax + 2) = edx;
RCT2_GLOBAL(0x009E2DE4, uint32) = ecx;
}
}

View File

@ -265,7 +265,7 @@ int calculate_park_rating()
litter = &(g_sprite_list[sprite_idx].litter);
// Guessing this eliminates recently dropped litter
if (litter->var_24 - RCT2_GLOBAL(0x00F663AC, uint32) >= 7680)
if (litter->var_24 - RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, uint32) >= 7680)
num_litter++;
}
result -= 600 - (4 * (150 - min(150, num_litter)));

View File

@ -84,7 +84,7 @@ __declspec(dllexport) int StartOpenRCT(HINSTANCE hInstance, HINSTANCE hPrevInsta
audio_init();
audio_get_devices();
RCT2_CALLPROC(0x0040502E); // get_dsound_devices()
get_dsound_devices();
config_init();
language_open(gGeneral_config.language);
rct2_init();
@ -146,7 +146,7 @@ void rct2_quit() {
void rct2_init()
{
RCT2_GLOBAL(0x00F663AC, int) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) = 0;
RCT2_GLOBAL(0x009AC310, char*) = RCT2_GLOBAL(RCT2_ADDRESS_CMDLINE, char*);
get_system_time();
RCT2_GLOBAL(0x009DEA69, short) = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_DAY, short);

View File

@ -99,6 +99,7 @@ const uint8 gRideClassifications[255] = {
#pragma endregion
rct_ride_type **gRideTypeList = RCT2_ADDRESS(0x009ACFA4, rct_ride_type*);
rct_ride* g_ride_list = RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride);
int ride_get_count()

View File

@ -22,6 +22,7 @@
#define _RIDE_H_
#include "rct2.h"
#include "string_ids.h"
typedef fixed16_2dp ride_rating;
@ -36,6 +37,26 @@ typedef struct {
ride_rating nausea;
} rating_tuple;
/**
* Ride type structure.
* size: unknown
*/
typedef struct {
rct_string_id name; // 0x000
rct_string_id description; // 0x002
uint32 var_004;
uint32 var_008;
uint8 var_00C;
uint8 var_00D;
uint8 pad_00E[0x1A4];
sint8 excitement_multipler; // 0x1B2
sint8 intensity_multipler; // 0x1B3
sint8 nausea_multipler; // 0x1B4
uint8 pad_1B5[0x09];
uint8 category[2]; // 0x1BE
uint8 shop_item; // 0x1C0
} rct_ride_type;
/**
* Ride structure.
* size: 0x0260
@ -109,7 +130,9 @@ typedef struct {
uint16 build_date;
sint16 upkeep_cost; // 0x182
uint16 race_winner; // 0x184
uint8 pad_186[0x10];
uint8 pad_186[0x06];
uint8 var_18C;
uint8 pad_18D[0x09];
uint16 var_196;
// used in computing excitement, nausea, etc
uint8 var_198;
@ -332,6 +355,9 @@ enum {
#define MAX_RIDE_MEASUREMENTS 8
#define RIDE_RELIABILITY_UNDEFINED 0xFFFF
// rct2: 0x009ACFA4
rct_ride_type **gRideTypeList;
// rct2: 0x013628F8
extern rct_ride* g_ride_list;

View File

@ -172,17 +172,12 @@ rating_tuple per_ride_rating_adjustments(rct_ride *ride, ride_rating excitement,
{
// NB: The table here is allocated dynamically. Reading the exe will tell
// you nothing
uint32 subtype_p = RCT2_GLOBAL(0x009ACFA4 + ride->subtype * 4, uint32);
rct_ride_type *rideType = gRideTypeList[ride->subtype];
// example value here: 12 (?)
sint16 ctr = RCT2_GLOBAL(subtype_p + 0x1b2, sint16);
excitement = excitement + ((excitement * ctr) >> 7);
ctr = RCT2_GLOBAL(subtype_p + 0x1b3, sint16);
intensity = intensity + ((intensity * ctr) >> 7);
ctr = RCT2_GLOBAL(subtype_p + 0x1b4, sint16);
nausea = nausea + ((nausea * ctr) >> 7);
excitement = excitement + ((excitement * rideType->excitement_multipler) >> 7);
intensity = intensity + ((intensity * rideType->intensity_multipler) >> 7);
nausea = nausea + ((nausea * rideType->nausea_multipler) >> 7);
// As far as I can tell, this flag detects whether the ride is a roller
// coaster, or a log flume or rapids. Everything else it's not set.
@ -190,7 +185,7 @@ rating_tuple per_ride_rating_adjustments(rct_ride *ride, ride_rating excitement,
uint16 ridetype_var = RCT2_GLOBAL(0x0097D4F2 + ride->type * 8, uint16);
if (ridetype_var & 0x80) {
uint16 ax = ride->var_1F4;
if (RCT2_GLOBAL(subtype_p + 8, uint32) & 0x800) {
if (rideType->var_008 & 0x800) {
// 65e86e
ax = ax - 96;
if (ax >= 0) {

View File

@ -116,7 +116,10 @@ void scenario_load(const char *path)
object_read_and_load_entries(file);
// Read flags (16 bytes)
// Read flags (16 bytes). Loads:
// RCT2_ADDRESS_CURRENT_MONTH_YEAR
// RCT2_ADDRESS_CURRENT_MONTH_TICKS
// RCT2_ADDRESS_SCENARIO_TICKS
sawyercoding_read_chunk(file, (uint8*)RCT2_ADDRESS_CURRENT_MONTH_YEAR);
// Read map elements
@ -381,12 +384,11 @@ void scenario_objective5_check()
FOR_ALL_RIDES(i, ride) {
uint8 subtype_id = ride->subtype;
uint32 subtype_p = RCT2_GLOBAL(0x009ACFA4 + subtype_id * 4, uint32);
rct_ride_type *rideType = gRideTypeList[subtype_id];
if ((RCT2_GLOBAL(subtype_p + 0x1BE, sint8) == 2 ||
RCT2_GLOBAL(subtype_p + 0x1BF, sint8) == 2) &&
if ((rideType->category[0] == RIDE_GROUP_ROLLERCOASTER || rideType->category[1] == RIDE_GROUP_ROLLERCOASTER) &&
ride->status == RIDE_STATUS_OPEN &&
ride->excitement >= 600 && type_already_counted[subtype_id] == 0){
ride->excitement >= RIDE_RATING(6,00) && type_already_counted[subtype_id] == 0){
type_already_counted[subtype_id]++;
rcs++;
}
@ -412,12 +414,10 @@ void scenario_objective8_check()
FOR_ALL_RIDES(i, ride) {
uint8 subtype_id = ride->subtype;
uint32 subtype_p = RCT2_GLOBAL(0x009ACFA4 + subtype_id * 4, uint32);
if ((RCT2_GLOBAL(subtype_p + 0x1BE, sint8) == 2 ||
RCT2_GLOBAL(subtype_p + 0x1BF, sint8) == 2) &&
rct_ride_type *rideType = gRideTypeList[subtype_id];
if ((rideType->category[0] == RIDE_GROUP_ROLLERCOASTER || rideType->category[1] == RIDE_GROUP_ROLLERCOASTER) &&
ride->status == RIDE_STATUS_OPEN &&
ride->excitement >= 600 && type_already_counted[subtype_id] == 0){
ride->excitement >= RIDE_RATING(7,00) && type_already_counted[subtype_id] == 0){
// this calculates the length, no idea why it's done so complicated though.
uint8 limit = ride->pad_088[63];

View File

@ -22,6 +22,7 @@
#include <string.h>
#include <time.h>
#include "addresses.h"
#include "audio.h"
#include "config.h"
#include "climate.h"
#include "date.h"
@ -309,7 +310,7 @@ static void title_play_music()
if (!(RCT2_GLOBAL(0x009AF284, uint32) & 1) || !(RCT2_GLOBAL(0x009AF59D, uint8) & 1)) {
if (RCT2_GLOBAL(0x009AF600, uint8) != 0)
RCT2_CALLPROC_EBPSAFE(0x006BD0BD); // stop music
stop_title_music();
return;
}

View File

@ -35,8 +35,27 @@ typedef struct {
sint16 x; // 0x0E
sint16 y; // 0x10
sint16 z; // 0x12
uint8 pad_14[0x2A];
uint8 pad_14[0x0B];
uint8 var_1F;
uint8 pad_20[0x08];
uint32 var_28;
uint8 pad_2C[0x04];
uint8 ride; // 0x30
uint8 var_31;
uint8 pad_32[0x0C];
uint16 next_vehicle_on_train; // 0x3E
uint8 pad_40[0x08];
uint16 var_48;
uint8 pad_4A[0x06];
uint8 var_50;
uint8 var_51;
uint8 pad_52[0x69];
uint16 var_BB;
uint16 var_BD;
uint8 pad_BF[0x0D];
uint8 var_CC;
uint8 pad_CD[0x09];
uint8 var_D6;
} rct_vehicle;
void vehicle_update_all();

View File

@ -18,9 +18,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include <assert.h>
#include "addresses.h"
#include "config.h"
#include "gfx.h"
#include "map.h"
#include "string_ids.h"
#include "sprite.h"
#include "sprites.h"
@ -219,13 +221,166 @@ void viewport_update_pointers()
*vp = NULL;
}
void sub_689174(sint16* x, sint16* y, uint8 curr_rotation){
//RCT2_CALLFUNC_X(0x00689174, (int*)&x, (int*)&y, &ecx, &curr_rotation, (int*)&window, (int*)&viewport, &ebp);
sint16 start_x = *x;
sint16 start_y = *y;
sint16 height = 0;
switch (curr_rotation){
case 0:
for (int i = 0; i < 6; ++i){
*x = start_y - start_x / 2 + height;
*y = start_y + start_x / 2 + height;
height = map_element_height((0xFFFF) & *x, (0xFFFF) & *y);
}
break;
case 1:
for (int i = 0; i < 6; ++i){
*x = -start_y - start_x / 2 - height;
*y = start_y - start_x / 2 + height;
height = map_element_height((0xFFFF) & *x, (0xFFFF) & *y);
}
break;
case 2:
for (int i = 0; i < 6; ++i){
*x = -start_y + start_x / 2 - height;
*y = -start_y - start_x / 2 - height;
height = map_element_height((0xFFFF) & *x, (0xFFFF) & *y);
}
break;
case 3:
for (int i = 0; i < 6; ++i){
*x = start_x / 2 + start_y + height;
*y = start_x / 2 - start_y - height;
height = map_element_height((0xFFFF) & *x, (0xFFFF) & *y);
}
break;
}
}
/**
*
* rct2: 0x006E7A3A
*/
void viewport_update_position(rct_window *window)
{
RCT2_CALLPROC_X(0x006E7A3A, 0, 0, 0, 0, (int)window, 0, 0);
//RCT2_CALLPROC_X(0x006E7A3A, 0, 0, 0, 0, (int)window, 0, 0);
RCT2_CALLPROC_X(window->event_handlers[WE_RESIZE], 0, 0, 0, 0, (int)window, 0, 0);
rct_viewport* viewport = window->viewport;
if (!viewport)return;
if (window->viewport_target_sprite != -1){
rct_sprite* sprite = &g_sprite_list[window->viewport_target_sprite];
int height = map_element_height(sprite->unknown.x, sprite->unknown.y) - 16;
int underground = sprite->unknown.z < height;
RCT2_CALLPROC_X(0x6E7A15, sprite->unknown.x, sprite->unknown.y, sprite->unknown.z, underground, (int)window, (int)viewport, 0);
int center_x, center_y;
center_2d_coordinates(sprite->unknown.x, sprite->unknown.y, sprite->unknown.z, &center_x, &center_y, window->viewport);
RCT2_CALLPROC_X(0x6E7DE1, center_x, center_y, 0, 0, (int)window, (int)viewport, 0);
window_invalidate(window);//Added to force a redraw.
return;
}
sint16 x = viewport->view_width / 2 + window->saved_view_x;
sint16 y = viewport->view_height / 2 + window->saved_view_y;
int curr_rotation = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32);
sub_689174(&x, &y, curr_rotation);
RCT2_CALLPROC_X(0x006E7A15, x, y, 0, 0, (int)window, (int)viewport, 0);
//Clamp to the map minimum value
int at_map_edge = 0;
if (x < MAP_MINIMUM_X_Y){
x = MAP_MINIMUM_X_Y;
at_map_edge = 1;
}
if (y < MAP_MINIMUM_X_Y){
y = MAP_MINIMUM_X_Y;
at_map_edge = 1;
}
//Clamp to the map maximum value (scenario specific)
if (x > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16)){
x = RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16);
at_map_edge = 1;
}
if (y > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16)){
y = RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16);
at_map_edge = 1;
}
if (at_map_edge) {
// The &0xFFFF is to prevent the sign extension messing the
// function up.
int z = map_element_height(x & 0xFFFF, y & 0xFFFF);
int _2d_x, _2d_y;
center_2d_coordinates(x, y, z, &_2d_x, &_2d_y, viewport);
if (window->saved_view_x > 0){
_2d_x = min(_2d_x, window->saved_view_x);
}
else{
_2d_x = max(_2d_x, window->saved_view_x);
}
if (window->saved_view_y > 0){
_2d_y = min(_2d_y, window->saved_view_y);
}
else{
_2d_y = max(_2d_y, window->saved_view_y);
}
window->saved_view_x = _2d_x;
window->saved_view_y = _2d_y;
}
x = window->saved_view_x;
y = window->saved_view_y;
if (window->flags & WF_SCROLLING_TO_LOCATION){
// Moves the viewport if focusing in on an item
uint8 flags = 0;
x -= viewport->view_x;
if (x < 0){
x = -x;
flags |= 1;
}
y -= viewport->view_y;
if (y < 0){
y = -y;
flags |= 2;
}
x = (x + 7)/8;
y = (y + 7)/8;
//If we are at the final zoom position
if (!x && !y){
window->flags &= ~WF_SCROLLING_TO_LOCATION;
}
if (flags & 1){
x = -x;
}
if (flags & 2){
y = -y;
}
x += viewport->view_x;
y += viewport->view_y;
}
RCT2_CALLPROC_X(0x6E7DE1, x, y, 0, 0, (int)window, (int)viewport, 0);
}
void viewport_paint(rct_viewport* viewport, rct_drawpixelinfo* dpi, int left, int top, int right, int bottom);

View File

@ -1465,3 +1465,34 @@ void window_resize_gui_scenario_editor(int width, int height)
}
}
void RCT2_CALLPROC_WE_MOUSE_DOWN(int address, int widgetIndex, rct_window*w, rct_widget* widget )
{
#ifdef _MSC_VER
__asm {
push address
push widget
push w
push widgetIndex
mov edi, widget
mov edx, widgetIndex
mov esi, w
call[esp + 12]
add esp, 16
}
#else
__asm__("\
push %[address]\n\
mov edi, %[widget] \n\
mov eax, %[w] \n\
mov edx, %[widgetIndex] \n\
push edi \n\
push eax \n\
push edx \n\
mov esi, %[w] \n\
call [esp+12] \n\
add esp, 16 \n\
" :[address] "+m" (address), [w] "+m" (w), [widget] "+m" (widget), [widgetIndex] "+m" (widgetIndex): : "eax", "esi", "edx", "edi"
);
#endif
}

View File

@ -155,7 +155,13 @@ typedef struct{
uint16 var_484;
uint16 var_486;
uint16 var_488;
}map_variables;
} map_variables;
typedef struct {
sint16 var_480;
sint32 var_482;
} ride_variables;
/**
* Window structure
* size: 0x4C0
@ -185,13 +191,14 @@ typedef struct rct_window {
sint16 selected_list_item; // 0x47A -1 for none selected
sint16 pad_47C;
sint16 pad_47E;
union{
union {
coordinate_focus viewport_focus_coordinates;
sprite_focus viewport_focus_sprite;
campaign_variables campaign;
new_ride_variables new_ride;
news_variables news;
map_variables map;
ride_variables ride;
};
sint16 page; // 0x48A
sint16 var_48C;
@ -260,7 +267,7 @@ typedef enum {
WF_STICK_TO_BACK = (1 << 0),
WF_STICK_TO_FRONT = (1 << 1),
WF_2 = (1 << 2),
WF_3 = (1 << 3),
WF_SCROLLING_TO_LOCATION = (1 << 3),
WF_TRANSPARENT = (1 << 4),
WF_5 = (1 << 5),
WF_RESIZABLE = (1 << 8),
@ -442,6 +449,7 @@ void window_park_rating_open();
void window_finances_open();
void window_finances_research_open();
void window_new_campaign_open(sint16 campaignType);
void window_ride_main_open(int rideIndex);
void window_ride_list_open();
void window_new_ride_open();
void window_banner_open();
@ -458,6 +466,7 @@ void window_new_ride_init_vars();
void window_staff_init_vars();
void window_event_helper(rct_window* w, short widgetIndex, WINDOW_EVENTS event);
void RCT2_CALLPROC_WE_MOUSE_DOWN(int address, int widgetIndex, rct_window*w, rct_widget* widget);
#ifdef _MSC_VER
#define window_get_register(w) \

View File

@ -804,7 +804,7 @@ static void window_guest_list_find_groups()
int spriteIndex, spriteIndex2, groupIndex, faceIndex;
rct_peep *peep, *peep2;
int eax = RCT2_GLOBAL(0x00F663AC, uint32) & 0xFFFFFF00;
int eax = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, uint32) & 0xFFFFFF00;
if (_window_guest_list_selected_view == RCT2_GLOBAL(0x00F1EE02, uint32))
if (RCT2_GLOBAL(0x00F1AF20, uint16) != 0 || eax == RCT2_GLOBAL(0x00F1AF1C, uint32))
return;

View File

@ -28,7 +28,7 @@
#include "window.h"
#include "window_dropdown.h"
#define SELECTED_RIDE_UNDEFINED ((sint16)0xFFFF)
#define SELECTED_RIDE_UNDEFINED ((uint16)0xFFFF)
enum WINDOW_NEW_CAMPAIGN_WIDGET_IDX {
WIDX_BACKGROUND,
@ -200,8 +200,8 @@ static void window_new_campaign_get_shop_items()
uint64 items = 0;
FOR_ALL_RIDES(i, ride) {
uint8 *rideTypeInfo = RCT2_ADDRESS(0x009ACFA4, void*)[ride->subtype];
uint8 itemType = RCT2_GLOBAL(rideTypeInfo + 0x1C0, uint8);
rct_ride_type *rideType = gRideTypeList[ride->subtype];
uint8 itemType = rideType->shop_item;
if (itemType != 255)
items |= 1LL << itemType;
}

View File

@ -301,7 +301,7 @@ static void window_new_ride_populate_list()
uint8 currentCategory = _window_new_ride_current_tab;
ride_list_item *nextListItem = (ride_list_item*)0x00F43523;
uint8 **rideEntries = (uint8**)0x009ACFA4;
rct_ride_type **rideEntries = (rct_ride_type**)0x009ACFA4;
// For each ride type in the view order list
for (i = 0; i < countof(RideTypeViewOrder); i++) {
@ -325,15 +325,13 @@ static void window_new_ride_populate_list()
continue;
// Ride entries
uint8 *rideEntry = rideEntries[rideEntryIndex];
uint8 categoryA = rideEntry[0x1BE];
uint8 categoryB = rideEntry[0x1BF];
rct_ride_type *rideEntry = rideEntries[rideEntryIndex];
// Check if ride is in this category
if (currentCategory != categoryA && currentCategory != categoryB)
if (currentCategory != rideEntry->category[0] && currentCategory != rideEntry->category[1])
continue;
if (RCT2_GLOBAL(rideEntry + 8, uint32) & 0x2000) {
if (rideEntry->var_008 & 0x2000) {
dh &= ~4;
nextListItem->type = rideType;
nextListItem->entry_index = rideEntryIndex;
@ -344,7 +342,7 @@ static void window_new_ride_populate_list()
nextListItem->entry_index = rideEntryIndex;
nextListItem++;
} else if (dh & 4) {
if (rideType == rideEntry[0x0C]) {
if (rideType == rideEntry->var_00C) {
nextListItem--;
nextListItem->type = rideType;
nextListItem->entry_index = rideEntryIndex;
@ -431,7 +429,7 @@ void window_new_ride_open()
w->colours[0] = 24;
w->colours[1] = 26;
w->colours[2] = 26;
w->new_ride.selected_ride_countdown = -1;
w->new_ride.selected_ride_id = -1;
w->new_ride.highlighted_ride_id = -1;
_lastTrackDesignCountRideType.type = 255;
_lastTrackDesignCountRideType.entry_index = 255;
@ -603,7 +601,7 @@ static void window_new_ride_update(rct_window *w)
widget_invalidate(w->classification, w->number, WIDX_TAB_1 + _window_new_ride_current_tab);
if (w->new_ride.selected_ride_countdown != -1 && w->new_ride.selected_ride_countdown-- == 0)
if (w->new_ride.selected_ride_id != -1 && w->new_ride.selected_ride_countdown-- == 0)
window_new_ride_select(w);
}
@ -657,7 +655,7 @@ static void window_new_ride_scrollmousedown()
return;
RCT2_ADDRESS(0x00F43825, ride_list_item)[_window_new_ride_current_tab] = item;
w->new_ride.selected_ride_countdown = *((sint16*)&item);
w->new_ride.selected_ride_id = *((sint16*)&item);
sound_play_panned(SOUND_CLICK_1, w->x + (w->width / 2));
w->new_ride.selected_ride_countdown = 8;
@ -676,10 +674,11 @@ static void window_new_ride_scrollmouseover()
window_scrollmouse_get_registers(w, x, y);
if (w->new_ride.selected_ride_countdown != -1)
if (w->new_ride.selected_ride_id != -1)
return;
item = window_new_ride_scroll_get_ride_list_item_at(w, x, y);
if (w->new_ride.highlighted_ride_id == *((sint16*)&item))
return;
@ -757,11 +756,10 @@ static void window_new_ride_paint()
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;
rct_ride_type *rideEntry = RCT2_GLOBAL(0x009ACFA4 + (typeId & 0xFF) * 4, rct_ride_type*);
stringId = rideEntry->var_008 & 0x1000 ?
rideEntry->name :
(typeId & 0xFF00) + 2;
} else {
uint8 *sceneryEntry = RCT2_GLOBAL(0x009ADA90 + (typeId & 0xFFFF) * 4, uint8*);
stringId = RCT2_GLOBAL(sceneryEntry, uint16);
@ -795,11 +793,10 @@ static void window_new_ride_paint()
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;
rct_ride_type *rideEntry = RCT2_GLOBAL(0x009ACFA4 + (typeId & 0xFF) * 4, rct_ride_type*);
stringId = rideEntry->var_008 & 0x1000 ?
rideEntry->name :
(typeId & 0xFF00) + 2;
} else {
uint8 *sceneryEntry = RCT2_GLOBAL(0x009ADA90 + (typeId & 0xFFFF) * 4, uint8*);
stringId = RCT2_GLOBAL(sceneryEntry, uint16);
@ -816,7 +813,7 @@ static void window_new_ride_scrollpaint()
{
rct_window *w;
rct_drawpixelinfo *dpi;
uint8 **rideEntries = (uint8**)0x009ACFA4;
rct_ride_type **rideEntries = (rct_ride_type**)0x009ACFA4;
window_paint_get_registers(w, dpi);
@ -829,20 +826,20 @@ static void window_new_ride_scrollpaint()
int y = 1;
ride_list_item *listItem = (ride_list_item*)0x00F43523;
while (listItem->type != 255 || listItem->entry_index != 255) {
uint8 *rideEntry;
rct_ride_type *rideEntry;
// Draw flat button rectangle
int flags = 0;
if (w->new_ride.selected_ride_countdown == *((sint16*)listItem))
if (w->new_ride.selected_ride_id == *((sint16*)listItem))
flags |= 0x20;
if (w->new_ride.highlighted_ride_id == *((sint16*)listItem) || flags != 0)
gfx_fill_rect_inset(dpi, x, y, x + 115, y + 115, w->colours[1], 0x80 | flags);
// Draw ride image
rideEntry = rideEntries[listItem->entry_index];
int unk = RCT2_GLOBAL(rideEntry + 4, uint32);
if (listItem->type != RCT2_GLOBAL(rideEntry + 12, uint8)) {
int unk = rideEntry->var_004;
if (listItem->type != rideEntry->var_00C) {
unk++;
if (listItem->type != RCT2_GLOBAL(rideEntry + 13, uint8))
if (listItem->type != rideEntry->var_00D)
unk++;
}
RCT2_CALLPROC_X(0x00681DE2, 0, 29013, x + 2, y + 2, 0xA0, (int)dpi, unk);
@ -908,13 +905,13 @@ static int get_num_track_designs(ride_list_item item)
*/
static void window_new_ride_paint_ride_information(rct_window *w, rct_drawpixelinfo *dpi, ride_list_item item, int x, int y, int width)
{
uint8 **rideEntries = (uint8**)0x009ACFA4;
uint8 *rideEntry = rideEntries[item.entry_index];
rct_ride_type **rideEntries = (rct_ride_type**)0x009ACFA4;
rct_ride_type *rideEntry = rideEntries[item.entry_index];
// Ride name and description
rct_string_id rideName = RCT2_GLOBAL(rideEntry + 0, uint16);
rct_string_id rideDescription = RCT2_GLOBAL(rideEntry + 2, uint16);
if (!(RCT2_GLOBAL(rideEntry + 8, uint32) & 0x1000)) {
rct_string_id rideName = rideEntry->name;
rct_string_id rideDescription = rideEntry->description;
if (!(rideEntry->var_008 & 0x1000)) {
rideName = item.type + 2;
rideDescription = item.type + 512;
}
@ -973,7 +970,7 @@ static void window_new_ride_paint_ride_information(rct_window *w, rct_drawpixeli
*/
static void window_new_ride_select(rct_window *w)
{
ride_list_item item = *((ride_list_item*)&w->new_ride.selected_ride_countdown);
ride_list_item item = *((ride_list_item*)&w->new_ride.selected_ride_id);
if (item.type == 255)
return;

View File

@ -379,7 +379,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
window_options_show_dropdown(w, widget, gAudioDeviceCount);
gDropdownItemsChecked |= (1 << RCT2_GLOBAL(0x9AF280, uint32));
gDropdownItemsChecked |= (1 << RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32));
break;
case WIDX_HEIGHT_LABELS_DROPDOWN:
gDropdownItemsFormat[0] = 1142;
@ -500,13 +500,15 @@ static void window_options_dropdown()
switch (widgetIndex) {
case WIDX_SOUND_DROPDOWN:
#ifdef _MSC_VER
audio_init2(dropdownIndex);
/*#ifdef _MSC_VER
__asm movzx ax, dropdownIndex
#else
__asm__ ( "movzx ax, %[dropdownIndex] " : : [dropdownIndex] "g" ((char)dropdownIndex) );
#endif
// the switch replaces ax value
RCT2_CALLPROC_EBPSAFE(0x006BA9B5); // part of init audio
RCT2_CALLPROC_EBPSAFE(0x006BA9B5); // part of init audio*/
window_invalidate(w);
break;
case WIDX_HEIGHT_LABELS_DROPDOWN:
@ -670,7 +672,7 @@ static void window_options_invalidate()
window_options_widgets[WIDX_HEIGHT_LABELS_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
break;
case WINDOW_OPTIONS_PAGE_AUDIO:
currentSoundDevice = RCT2_GLOBAL(0x009AF280, sint32);
currentSoundDevice = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, sint32);
// sound devices
if (currentSoundDevice == -1 || gAudioDeviceCount == 0) {

View File

@ -325,6 +325,7 @@ void window_peep_overview_mouse_up(){
short widgetIndex;
rct_window* w;
window_widget_get_registers(w, widgetIndex);
rct_peep* peep = GET_PEEP(w->number);
switch(widgetIndex){
case WIDX_CLOSE:
@ -340,9 +341,27 @@ void window_peep_overview_mouse_up(){
break;
case WIDX_PICKUP:
//696ba6
if (!peep_can_be_picked_up(peep)) {
return;
}
if (tool_set(w, widgetIndex, 7)) {
return;
}
w->var_48C = peep->sprite_identifier;
RCT2_CALLPROC_X(0x0069A512, 0, 0, 0, 0, (int)peep, 0, 0);
RCT2_CALLPROC_X(0x006EC473, 0, 0, 0, 0, (int)peep, 0, 0);
RCT2_CALLPROC_X(0x0069E9D3, 0x8000, 0, peep->y, peep->z, (int)peep, 0, 0);
RCT2_CALLPROC_X(0x0069A409, 0, 0, 0, 0, (int)peep, 0, 0);
peep->state = 9;
peep->pad_2C = 0;
RCT2_CALLPROC_X(0x0069A42F, 0, 0, 0, 0, (int)peep, 0, 0);
break;
case WIDX_RENAME:
//696e4d
window_show_textinput(w, (int)widgetIndex, 0x5AC, 0x5AD, peep->name_string_idx);
break;
case WIDX_LOCATE:
window_scroll_to_viewport(w);
@ -502,10 +521,10 @@ void window_peep_viewport_init(rct_window* w){
void window_peep_overview_paint(){
rct_window *w;
rct_drawpixelinfo *dpi;
rct_widget *labelWidget;
//rct_widget *labelWidget;
window_paint_get_registers(w, dpi);
RCT2_CALLPROC_X(0x696887, 0, 0, 0, 0, w, dpi, 0);
RCT2_CALLPROC_X(0x696887, 0, 0, 0, 0, (int)w, (int)dpi, 0);
return;
window_draw_widgets(w, dpi);

View File

@ -22,6 +22,7 @@
#include "finance.h"
#include "game.h"
#include "news_item.h"
#include "ride.h"
#include "string_ids.h"
#include "sprites.h"
#include "widget.h"
@ -342,11 +343,10 @@ static void window_research_development_paint()
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 >> 8) & 0xFF) + 2;
rct_ride_type *rideEntry = RCT2_GLOBAL(0x009ACFA4 + (typeId & 0xFF) * 4, rct_ride_type*);
stringId = rideEntry->var_008 & 0x1000 ?
rideEntry->name :
((typeId >> 8) & 0xFF) + 2;
} else {
uint8 *sceneryEntry = RCT2_GLOBAL(0x009ADA90 + (typeId & 0xFFFF) * 4, uint8*);
stringId = RCT2_GLOBAL(sceneryEntry, uint16);
@ -381,11 +381,10 @@ static void window_research_development_paint()
int lastDevelopmentFormat;
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 >> 8) & 0xFF) + 2;
rct_ride_type *rideEntry = RCT2_GLOBAL(0x009ACFA4 + (typeId & 0xFF) * 4, rct_ride_type*);
stringId = rideEntry->var_008 & 0x1000 ?
rideEntry->name :
((typeId >> 8) & 0xFF) + 2;
lastDevelopmentFormat = STR_RESEARCH_RIDE_LABEL;
} else {

154
src/window_ride.c Normal file
View File

@ -0,0 +1,154 @@
/*****************************************************************************
* 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 <string.h>
#include "addresses.h"
#include "game.h"
#include "ride.h"
#include "string_ids.h"
#include "sprite.h"
#include "sprites.h"
#include "widget.h"
#include "window.h"
#include "window_dropdown.h"
#pragma region Widgets
static rct_widget *window_ride_page_widgets[] = {
(rct_widget*)0x009ADC34,
(rct_widget*)0x009ADDA8,
(rct_widget*)0x009ADEFC,
(rct_widget*)0x009AE190,
(rct_widget*)0x009AE2A4,
(rct_widget*)0x009AE4C8,
(rct_widget*)0x009AE5DC,
(rct_widget*)0x009AE710,
(rct_widget*)0x009AE844,
(rct_widget*)0x009AE9C8
};
#pragma endregion
#pragma region Events
static uint32* window_ride_page_events[] = {
(uint32*)0x0098DFD4,
(uint32*)0x0098E204,
(uint32*)0x0098E0B4,
(uint32*)0x0098E124,
(uint32*)0x0098E044,
(uint32*)0x0098E194,
(uint32*)0x0098DE14,
(uint32*)0x0098DF64,
(uint32*)0x0098DEF4,
(uint32*)0x0098DE84
};
#pragma endregion
/**
*
* rct2: 0x006AEAB4
*/
rct_window *window_ride_open(int rideIndex)
{
rct_window *w;
w = window_create_auto_pos(316, 180, window_ride_page_events[0], WC_RIDE, 0x400);
w->widgets = window_ride_page_widgets[0];
w->enabled_widgets = 0x007DBFF4;
w->number = rideIndex;
w->page = 0;
w->var_48C = 0;
w->frame_no = 0;
w->list_information_type = 0;
w->var_492 = 0;
w->var_494 = 0;
RCT2_CALLPROC_X(0x006AEB9F, 0, 0, 0, 0, (int)w, 0, 0);
w->min_width = 316;
w->min_height = 180;
w->max_width = 500;
w->max_height = 450;
w->flags |= WF_RESIZABLE;
w->colours[0] = 1;
w->colours[1] = 26;
w->colours[2] = 11;
rct_ride *ride = &g_ride_list[rideIndex];
uint8 *edx = (uint8*)0x009E32F8;
if (ride->type != RIDE_TYPE_NULL) {
int rideType = ride->type;
do {
edx++;
if (*(edx - 1) != 0xFF)
continue;
} while (rideType-- != 0);
}
int eax, ebx = 0, ecx;
while (*edx != 0xFF) {
eax = *edx++;
ecx = eax >> 5;
eax &= 0x1F;
if (!(RCT2_ADDRESS(0x001357424, uint32)[ecx] & (1 << eax)))
continue;
ebx++;
}
RCT2_GLOBAL((int)w + 496, uint16) = ebx;
return w;
}
/**
*
* rct2: 0x006ACC28
*/
void window_ride_main_open(int rideIndex)
{
rct_window *w;
w = window_bring_to_front_by_id(WC_RIDE, rideIndex);
if (w == NULL) {
w = window_ride_open(rideIndex);
w->ride.var_482 = -1;
}
if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) {
if (w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) &&
w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber)
) {
tool_cancel();
}
}
w->page = 0;
w->width = 316;
w->height = 180;
window_invalidate(w);
w->widgets = window_ride_page_widgets[0];
w->enabled_widgets = 0x007DBFF4;
w->var_020 = 0;
w->event_handlers = window_ride_page_events[0];
w->pressed_widgets = 0;
RCT2_CALLPROC_X(0x006AEB9F, 0, 0, 0, 0, (int)w, 0, 0);
window_init_scroll_widgets(w);
w->ride.var_480 = 0;
RCT2_CALLPROC_X(0x006AF994, 0, 0, 0, 0, (int)w, 0, 0);
}

View File

@ -352,7 +352,7 @@ static void window_ride_list_scrollmousedown()
return;
// Open ride window
RCT2_CALLPROC_X(0x006ACC28, w->list_item_positions[index], 0, 0, 0, 0, 0, 0);
window_ride_main_open(w->list_item_positions[index]);
}
/**

View File

@ -24,6 +24,7 @@
#include "string_ids.h"
#include "sprite.h"
#include "sprites.h"
#include "viewport.h"
#include "widget.h"
#include "window.h"
#include "window_dropdown.h"
@ -45,6 +46,7 @@ enum WINDOW_STAFF_PEEP_WIDGET_IDX {
WIDX_TAB_4,
WIDX_VIEWPORT,
WIDX_BTM_LABEL,
WIDX_PICKUP,
WIDX_PATROL,
WIDX_RENAME,
WIDX_LOCATE,
@ -73,13 +75,21 @@ rct_widget window_staff_peep_overview_widgets[] = {
};
rct_widget *window_staff_peep_page_widgets[] = {
window_staff_peep_overview_widgets
window_staff_peep_overview_widgets,
(rct_widget *)0x9AF910,
(rct_widget *)0x9AF9F4
};
void window_staff_peep_set_page(rct_window* w, int page);
void window_staff_peep_disable_widgets(rct_window* w);
void window_staff_peep_close();
void window_staff_peep_mouse_up();
// 0x992AEC
static void* window_staff_peep_overview_events[] = {
(void*)0x6BDFF8,
(void*)0x6BDF55,
window_staff_peep_close,
window_staff_peep_mouse_up,
(void*)0x6BE558,
(void*)0x6BDF98,
(void*)0x6BDFA3,
@ -109,7 +119,9 @@ static void* window_staff_peep_overview_events[] = {
};
void* window_staff_peep_page_events[] = {
window_staff_peep_overview_events
window_staff_peep_overview_events,
(void*)0x992B5C,
(void*)0x992BCC
};
uint32 window_staff_peep_page_enabled_widgets[] = {
@ -117,20 +129,79 @@ uint32 window_staff_peep_page_enabled_widgets[] = {
(1 << WIDX_TAB_1) |
(1 << WIDX_TAB_2) |
(1 << WIDX_TAB_3) |
(1 << WIDX_PICKUP) |
(1 << WIDX_PATROL) |
(1 << WIDX_RENAME) |
(1 << WIDX_LOCATE) |
(1 << WIDX_FIRE) |
(1 << 14)
(1 << WIDX_FIRE),
(1 << WIDX_CLOSE) |
(1 << WIDX_TAB_1) |
(1 << WIDX_TAB_2) |
(1 << WIDX_TAB_3),
(1 << WIDX_CLOSE) |
(1 << WIDX_TAB_1) |
(1 << WIDX_TAB_2) |
(1 << WIDX_TAB_3)
};
/**
*
* 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 == NULL) {
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->viewport_focus_coordinates.y = 0;
w->frame_no = 0;
RCT2_GLOBAL((int*)w + 0x496, uint16) = 0; // missing, var_494 should perhaps be uint16?
window_staff_peep_disable_widgets(w);
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;
}
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;
window_staff_peep_disable_widgets(w);
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);
}
}
/**
* rct2: 0x006BED21
*
* Disable the staff pickup if not in pickup state.
*/
void sub_6BED21(rct_window* w, rct_peep* peep)
void window_staff_peep_disable_widgets(rct_window* w)
{
rct_peep* peep = &g_sprite_list[w->number].peep;
int eax = 0 | 0x80;
if (peep->staff_type == 2) {
@ -174,71 +245,119 @@ void sub_6BED21(rct_window* w, rct_peep* peep)
}
/**
* Create the window for a specific peep.
*
* rct2: 0x006BEF1B
*/
rct_window* sub_6BEF1B(rct_peep* peep)
* Same as window_peep_close.
* rct2: 0x006BDFF8
*/
void window_staff_peep_close()
{
rct_window* w = window_create_auto_pos(190, 180, (uint32*)window_staff_peep_overview_events, WC_PEEP, (uint16)0x400);
rct_window* w;
w->widgets = RCT2_GLOBAL(0x9AF81C, rct_widget*);
w->enabled_widgets = RCT2_GLOBAL(0x9929B0, uint32);
w->number = peep->sprite_index;
w->page = 0;
w->viewport_focus_coordinates.y = 0;
w->frame_no = 0;
window_get_register(w);
RCT2_GLOBAL((int*)w + 0x496, uint16) = 0; // missing, var_494 should perhaps be uint16?
if (RCT2_GLOBAL(0x9DE518, uint32) & (1 << 3)){
if (w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) &&
w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber))
tool_cancel();
}
}
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: 0x6C0A77 */
void window_staff_peep_fire(rct_window* w)
{
RCT2_CALLPROC_X(0x6C0A77, 0, 0, 0, 0, (int)w, 0, 0);
}
/**
*
* rct2: 0x006BEE98
*/
void window_staff_peep_open(rct_peep* peep)
* Mostly similar to window_peep_set_page.
* rct2: 0x006BE023
*/
void window_staff_peep_set_page(rct_window* w, int page)
{
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);
if (RCT2_GLOBAL(0x9DE518,uint32) & (1 << 3))
{
if(w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber) &&
w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass))
tool_cancel();
}
w->page = 0;
int listen = 0;
if (page == WINDOW_STAFF_PEEP_OVERVIEW && w->page == WINDOW_STAFF_PEEP_OVERVIEW && w->viewport){
if (!(w->viewport->flags & VIEWPORT_FLAG_SOUND_ON))
listen = 1;
}
w->page = page;
w->frame_no = 0;
rct_viewport* viewport = w->viewport;
w->viewport = 0;
if (viewport){
viewport->width = 0;
}
w->enabled_widgets = window_staff_peep_page_enabled_widgets[page];
w->var_020 = RCT2_ADDRESS(0x9929BC, uint32)[page];
w->event_handlers = window_staff_peep_page_events[page];
w->pressed_widgets = 0;
w->widgets = window_staff_peep_page_widgets[page];
window_staff_peep_disable_widgets(w);
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);
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);
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);
window_invalidate(w);
if (listen && w->viewport) w->viewport->flags |= VIEWPORT_FLAG_SOUND_ON;
}
/** rct2: 0x006BDF55 */
void window_staff_peep_mouse_up()
{
short widgetIndex;
rct_window* w;
window_widget_get_registers(w, widgetIndex);
rct_peep* peep = GET_PEEP(w->number);
switch (widgetIndex) {
case WIDX_CLOSE:
window_close(w);
break;
case WIDX_TAB_1:
case WIDX_TAB_2:
case WIDX_TAB_3:
window_staff_peep_set_page(w, widgetIndex - WIDX_TAB_1);
break;
case WIDX_LOCATE: // 0xD
window_scroll_to_viewport(w);
break;
case WIDX_PICKUP: // 0xA
// 0x6BE236
if (tool_set(w, widgetIndex, 7)) {
return;
}
w->var_48C = peep->sprite_identifier;
RCT2_CALLPROC_X(0x0069A512, 0, 0, 0, 0, (int)peep, 0, 0);
RCT2_CALLPROC_X(0x006EC473, 0, 0, 0, 0, (int)peep, 0, 0);
RCT2_CALLPROC_X(0x0069E9D3, 0x8000, 0, peep->y, peep->z, (int)peep, 0, 0);
RCT2_CALLPROC_X(0x0069A409, 0, 0, 0, 0, (int)peep, 0, 0);
peep->state = 9;
RCT2_CALLPROC_X(0x0069A42F, 0, 0, 0, 0, (int)peep, 0, 0);
break;
case WIDX_FIRE: // 0xE
window_staff_peep_fire(w);
break;
case WIDX_RENAME: // 0xC
// 6BE4BC
window_show_textinput(w, (int)widgetIndex, 0xBA1, 0xBA2, peep->name_string_idx);
break;
}
}