1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-24 00:03:11 +01:00

Merge remote-tracking branch 'refs/remotes/upstream/master'

* refs/remotes/upstream/master: (22 commits)
  fix bug with game_do_command
  add game_do_command
  add more info. to scenario_load_and_play
  set default screenshot format to PNG
  reorganise addresses
  fix peep structure
  Identified monthly ride income location.
  Label energy, thirst, hunger with offsets
  allow BMP to still be saved with PNG as default
  label nausea with offset
  Found nausea peep variable
  finish scenario start and add park size calculate
  Changed screenshot format from BMP to PNG (using LodePNG)
  add game flag for development only below tree height
  rename current day to current month ticks
  fix case and add author to source code header
  Fix comments
  Add rct_car sprite and tidy up news locator
  Change peep news item enum names
  Fix finding peep on ride news items
  ...

Conflicts:
	src/peep.h
This commit is contained in:
ZedThree
2014-05-02 14:01:04 +02:00
24 changed files with 8335 additions and 54 deletions

6260
lodepng/lodepng.c Normal file

File diff suppressed because it is too large Load Diff

1716
lodepng/lodepng.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -51,6 +51,7 @@
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\lodepng\lodepng.c" />
<ClCompile Include="..\src\audio.c" />
<ClCompile Include="..\src\climate.c" />
<ClCompile Include="..\src\config.c" />
@@ -129,13 +130,13 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>$(SolutionDir)..\sdl\include;$(IncludePath)</IncludePath>
<IncludePath>$(SolutionDir)..\lodepng;$(SolutionDir)..\sdl\include;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)..\sdl\lib\x86;$(LibraryPath)</LibraryPath>
<OutDir>$(SolutionDir)..\build\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)..\obj\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IncludePath>$(SolutionDir)..\sdl\include;$(IncludePath)</IncludePath>
<IncludePath>$(SolutionDir)..\lodepng;$(SolutionDir)..\sdl\include;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)..\sdl\lib\x86;$(LibraryPath)</LibraryPath>
<OutDir>$(SolutionDir)..\build\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)..\obj\$(Configuration)\</IntDir>

View File

@@ -254,6 +254,9 @@
<ClCompile Include="..\src\window_about.c">
<Filter>Windows</Filter>
</ClCompile>
<ClCompile Include="..\lodepng\lodepng.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\openrct2.exe">

View File

@@ -40,7 +40,7 @@
#define RCT2_CALLPROC_4(address, a1, a2, a3, a4, v1, v2, v3, v4) RCT2_CALLFUNC_4(address, void, a1, a2, a3, a4, v1, v2, v3, v4)
#define RCT2_CALLPROC_5(address, a1, a2, a3, a4, a5, v1, v2, v3, v4, v5) RCT2_CALLFUNC_5(address, void, a1, a2, a3, a4, a5, v1, v2, v3, v4, v5)
#define RCT2_ADDRESS_RIDE_PROPERTIES 0x00997c9d
#define RCT2_ADDRESS_RIDE_PROPERTIES 0x00997C9D
#define RCT2_ADDRESS_LAND_TOOL_SIZE 0x009A9800
#define RCT2_ADDRESS_SCENARIO_LIST 0x009A9FF4
@@ -54,6 +54,8 @@
#define RCT2_ADDRESS_CONFIG_KEYBOARD_SHORTCUTS 0x009AAC7A
#define RCT2_ADDRESS_CONFIG_EDGE_SCROLLING 0x009AACBA
#define RCT2_ADDRESS_EXPANSION_NAMES 0x009AACC0
#define RCT2_ADDRESS_EXPANSION_FLAGS 0x009AB4C0
#define RCT2_ADDRESS_CONFIG_RESOLUTION_WIDTH 0x009AB4C2
#define RCT2_ADDRESS_CONFIG_RESOLUTION_HEIGHT 0x009AB4C4
@@ -68,8 +70,6 @@
#define RCT2_ADDRESS_SCREEN_DPI 0x009ABDC8
#define RCT2_ADDRESS_SCREEN_WIDTH 0x009ABDD8
#define RCT2_ADDRESS_SCREEN_HEIGHT 0x009ABDDA
#define RCT2_ADDRESS_SCREEN_CAP_BPP 0x01423C10
#define RCT2_ADDRESS_SCREEN_CAP_RASTER_STRETCH 0x01423C14
#define RCT2_ADDRESS_DIRTY_BLOCK_WIDTH 0x009ABDE4
#define RCT2_ADDRESS_DIRTY_BLOCK_HEIGHT 0x009ABDE6
@@ -121,7 +121,7 @@
#define RCT2_ADDRESS_G1_ELEMENTS 0x009EBD28
#define RCT2_ADDRESS_CURRENT_MONTH_YEAR 0x00F663A8
#define RCT2_ADDRESS_CURRENT_DAY 0x00F663AA
#define RCT2_ADDRESS_CURRENT_MONTH_TICKS 0x00F663AA
#define RCT2_ADDRESS_MAP_ELEMENTS 0x00F663B8
@@ -136,6 +136,7 @@
#define RCT2_ADDRESS_GAME_FLAGS 0x013573E4
#define RCT2_ADDRESS_PARK_ENTRANCE_FEE 0x013573E8
#define RCT2_ADDRESS_GUESTS_IN_PARK 0x01357844
#define RCT2_ADDRESS_MONTHLY_RIDE_INCOME 0x01357894
#define RCT2_ADDRESS_CURRENT_PARK_RATING 0x01357CB0
#define RCT2_ADDRESS_PARK_RATING_HISTORY 0x01357CB2
#define RCT2_ADDRESS_GUESTS_IN_PARK_HISTORY 0x01357CD2
@@ -162,6 +163,8 @@
#define RCT2_ADDRESS_CURRENT_TICKS 0x013628F4
#define RCT2_ADDRESS_RIDE_LIST 0x013628F8
#define RCT2_ADDRESS_SAVED_VIEW_X 0x0138869A
#define RCT2_ADDRESS_SAVED_VIEW_Y 0x0138869C
#define RCT2_ADDRESS_RIDE_MEASUREMENTS 0x0138B60C
#define RCT2_ADDRESS_CLIMATE 0x013CA746
@@ -182,6 +185,8 @@
#define RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE 0x013CE950
#define RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS 0x013CE9A4
#define RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT 0x0141E9AC
#define RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE 0x0141E9AE
#define RCT2_ADDRESS_CURRENT_ROTATION 0x0141E9E0
@@ -214,8 +219,8 @@
#define RCT2_ADDRESS_MEM_TOTAL_PAGEFILE 0x01423B60
#define RCT2_ADDRESS_MEM_TOTAL_VIRTUAL 0x01423B64
#define RCT2_ADDRESS_EXPANSION_FLAGS 0x009AB4C0
#define RCT2_ADDRESS_EXPANSION_NAMES 0x009AACC0
#define RCT2_ADDRESS_SCREEN_CAP_BPP 0x01423C10
#define RCT2_ADDRESS_SCREEN_CAP_RASTER_STRETCH 0x01423C14
static void RCT2_CALLPROC_EBPSAFE(int address)
{

View File

@@ -22,6 +22,10 @@
#include "date.h"
#include "rct2.h"
// rct2: 0x00993988
const sint16 days_in_month[MONTH_COUNT] = { 31, 30, 31, 30, 31, 31, 30, 31 };
int date_get_month(int months)
{
return months % MONTH_COUNT;
@@ -44,6 +48,6 @@ int date_get_total_months(int month, int year)
void date_reset()
{
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, sint16) = MONTH_MARCH;
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_DAY, sint16) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_TICKS, sint16) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, sint32) = 0;
}

View File

@@ -21,6 +21,8 @@
#ifndef _DATE_H_
#define _DATE_H_
#include "rct2.h"
enum {
MONTH_MARCH,
MONTH_APRIL,
@@ -34,6 +36,8 @@ enum {
MONTH_COUNT
};
extern const sint16 days_in_month[MONTH_COUNT];
int date_get_month(int months);
int date_get_total_months(int month, int year);
void date_reset();

View File

@@ -21,6 +21,7 @@
#include "addresses.h"
#include "date.h"
#include "editor.h"
#include "game.h"
#include "gfx.h"
#include "map.h"
#include "news_item.h"
@@ -165,5 +166,5 @@ static void set_all_land_owned()
{
int mapSize = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, sint16);
RCT2_CALLPROC_X(0x006677F2, 64, 1, 64, 2, 56, (mapSize - 2) * 32, (mapSize - 2) * 32);
game_do_command(64, 1, 64, 2, 56, (mapSize - 2) * 32, (mapSize - 2) * 32);
}

View File

@@ -970,4 +970,109 @@ void game_handle_keyboard_input()
// Write tutorial input
RCT2_CALLPROC_X(0x0066EEE1, RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8), 0, 0, 0, 0, 0, 0);
}
}
/**
*
* rct2: 0x006677F2
*
* @param cost (ebp)
*/
static int game_check_affordability(int cost)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
ebp = cost;
RCT2_CALLFUNC_X(0x0069C62C, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
return ebp;
}
/**
*
* rct2: 0x006677F2
*
* @param flags (ebx)
* @param command (esi)
*/
int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp)
{
int cost, flags, insufficientFunds;
int original_ebx, original_edx, original_esi, original_edi, original_ebp;
original_ebx = ebx;
original_edx = edx;
original_esi = esi;
original_edi = edi;
original_ebp = ebp;
RCT2_CALLFUNC_X(0x006677F2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
return ebx;
flags = ebx;
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 0xFFFF;
// Increment nest count
RCT2_GLOBAL(0x009A8C28, uint8)++;
ebx &= ~1;
// Primary command
RCT2_CALLFUNC_X(RCT2_ADDRESS(0x0097B9A4, uint32)[esi], &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
cost = ebx;
if (cost != 0x80000000) {
// Check funds
insufficientFunds = 0;
if (RCT2_GLOBAL(0x009A8C28, uint8) == 1 && !(flags & 4) && !(flags & 0x20) && cost != 0)
insufficientFunds = game_check_affordability(cost);
if (insufficientFunds != 0x80000000) {
ebx = original_ebx;
edx = original_edx;
esi = original_esi;
edi = original_edi;
ebp = original_ebp;
if (!(flags & 1)) {
// Decrement nest count
RCT2_GLOBAL(0x009A8C28, uint8)--;
return cost;
}
// Secondary command
RCT2_CALLFUNC_X(RCT2_ADDRESS(0x0097B9A4, uint32)[esi], &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
edx = ebx;
if (edx != 0x80000000 && edx < cost)
cost = edx;
// Decrement nest count
RCT2_GLOBAL(0x009A8C28, uint8)--;
if (RCT2_GLOBAL(0x009A8C28, uint8) != 0)
return cost;
//
if (!(flags & 0x20)) {
// Update money balance
RCT2_CALLPROC_X(0x0069C674, 0, cost, 0, 0, 0, 0, 0);
if (RCT2_GLOBAL(0x0141F568, uint8) == RCT2_GLOBAL(0x013CA740, uint8)) {
// Create a +/- money text effect
if (cost != 0)
RCT2_CALLPROC_X(0x0069C5D0, 0, cost, 0, 0, 0, 0, 0);
}
}
return cost;
}
}
// Error occured
// Decrement nest count
RCT2_GLOBAL(0x009A8C28, uint8)--;
// Show error window
if (RCT2_GLOBAL(0x009A8C28, uint8) == 0 && (flags & 1) && RCT2_GLOBAL(0x0141F568, uint8) == RCT2_GLOBAL(0x013CA740, uint8) && !(flags & 8))
window_error_open(RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16), RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16));
return 0x80000000;
}

View File

@@ -25,4 +25,6 @@ void game_create_windows();
void game_update();
void game_logic_update();
int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp);
#endif

View File

@@ -19,10 +19,12 @@
*****************************************************************************/
#include "addresses.h"
#include "map.h"
#include "park.h"
#include "peep.h"
#include "ride.h"
#include "sprite.h"
#include "window.h"
int park_is_open()
{
@@ -38,6 +40,36 @@ void park_init()
RCT2_CALLPROC_EBPSAFE(0x00667132);
}
/**
*
* rct2: 0x0066A348
*/
int park_calculate_size()
{
int tiles, x, y;
rct_map_element *mapElement;
tiles = 0;
for (y = 0; y < 256; y++) {
for (x = 0; x < 256; x++) {
mapElement = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[y * 256 + x];
while (mapElement->type & MAP_ELEMENT_TYPE_MASK) {
mapElement++;
}
if (mapElement->properties.surface.ownership & 0x30)
tiles++;
}
}
if (tiles != RCT2_GLOBAL(0x013580EA, sint16)) {
RCT2_GLOBAL(0x013580EA, sint16) = tiles;
window_invalidate_by_id(WC_PARK_INFORMATION, 0);
}
return tiles;
}
/**
*
* rct2: 0x00669EAA

View File

@@ -53,6 +53,7 @@ enum {
int park_is_open();
void park_init();
int park_calculate_size();
int calculate_park_rating();
int calculate_park_value();

View File

@@ -8,12 +8,12 @@
* 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/>.
*****************************************************************************/
@@ -30,6 +30,13 @@ enum PEEP_TYPE {
PEEP_TYPE_STAFF
};
enum STAFF_TYPE {
STAFF_TYPE_HANDYMAN,
STAFF_TYPE_MECHANIC,
STAFF_TYPE_SECURITY,
STAFF_TYPE_ENTERTAINER
};
enum {
PEEP_FLAGS_TRACKING = 8
};
@@ -68,18 +75,25 @@ typedef struct {
uint8 pad_2C;
uint8 sprite_type; // 0x2D
uint8 type; // 0x2E
uint8 var_2F;
uint8 staff_type; // 0x2F
uint8 var_30;
uint8 var_31;
uint8 pad_32[0x08];
uint8 pad_32[0x06];
uint8 energy; // 0x38
uint8 var_39;
uint8 happiness; // 0x3A
uint8 pad_03B[0x2D];
uint8 var_03B;
uint8 nausea; // 0x3C
uint8 var_03D;
uint8 hunger; // 0x3E
uint8 thirst; // 0x3F
uint8 pad_040[0x28];
uint8 current_ride; // 0x68
uint8 pad_6a; // 0x6A Part of current_ride?
uint8 pad_6A; // 0x6A Part of current_ride?
uint8 current_train; // 0x6B
uint8 current_car; // 0x6C
uint8 current_seat; // 0x6d
uint8 pad_6C[0x2e];
uint8 current_seat; // 0x6D
uint8 pad_6E[0x2E];
uint32 id; // 0x9C
uint8 pad_A0[0x10];
rct_peep_thought thoughts[PEEP_MAX_THOUGHTS]; // 0xB0

View File

@@ -122,9 +122,10 @@ enum {
enum {
GAME_FLAGS_PARK_OPEN = (1 << 0),
GAME_FLAGS_BELOW_TREE_HEIGHT_ONLY = (1 << 5),
GAME_FLAGS_BELOW_TREE_HEIGHT_ONLY = (1 << 5),
GAME_FLAGS_NO_MONEY = (1 << 11),
GAME_FLAGS_PARK_FREE_ENTRY = (1 << 13)
GAME_FLAGS_PARK_FREE_ENTRY = (1 << 13),
GAME_FLAGS_18 = (1 << 18)
};
void rct2_endupdate();

View File

@@ -22,6 +22,7 @@
#include <windows.h>
#include "addresses.h"
#include "date.h"
#include "game.h"
#include "map.h"
#include "news_item.h"
@@ -419,8 +420,8 @@ void scenario_load_and_play(rct_scenario_basic *scenario)
mainWindow = window_get_main();
mainWindow->var_4B0 = -1;
mainWindow->var_4B2 = RCT2_GLOBAL(0x0138869A, sint16);
mainWindow->var_4B4 = RCT2_GLOBAL(0x0138869C, sint16);
mainWindow->var_4B2 = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_X, sint16);
mainWindow->var_4B4 = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_Y, sint16);
uint8 _cl = (RCT2_GLOBAL(0x0138869E, sint16) & 0xFF) - mainWindow->viewport->zoom;
mainWindow->viewport->zoom = RCT2_GLOBAL(0x0138869E, sint16) & 0xFF;
@@ -459,10 +460,68 @@ void scenario_load_and_play(rct_scenario_basic *scenario)
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_COMPANY_VALUE, sint16) = calculate_company_value();
RCT2_GLOBAL(0x013587D0, sint16) = RCT2_GLOBAL(0x013573DC, sint16) - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, sint16);
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint16) = ENCRYPT_MONEY(RCT2_GLOBAL(0x013573DC, sint32));
RCT2_CALLPROC_EBPSAFE(0x0069E869);
RCT2_CALLPROC_EBPSAFE(0x0069E869); // (loan related)
strcpy(0x0135924A, s6Info->details);
strcpy(0x0135920A, s6Info->name);
RCT2_CALLPROC_EBPSAFE(0x00678461);
if (RCT2_GLOBAL(0x009ADAE4, sint32) != -1) {
char *ebp = RCT2_GLOBAL(0x009ADAE4, char*);
//
format_string(0x0141ED68, RCT2_GLOBAL(ebp + 2, uint16), 0);
// Set park name
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16) = STR_CANT_RENAME_PARK;
game_do_command(1, 1, 0, *((int*)(0x0141ED68 + 0)), 33, *((int*)(0x0141ED68 + 8)), *((int*)(0x0141ED68 + 4)));
game_do_command(2, 1, 0, *((int*)(0x0141ED68 + 12)), 33, *((int*)(0x0141ED68 + 20)), *((int*)(0x0141ED68 + 16)));
game_do_command(0, 1, 0, *((int*)(0x0141ED68 + 24)), 33, *((int*)(0x0141ED68 + 32)), *((int*)(0x0141ED68 + 28)));
//
format_string(0x0141ED68, RCT2_GLOBAL(ebp + 0, uint16), 0);
strcpy_s(0x0135920A, 32, 0x0141ED68);
// Set scenario details
format_string(0x0141ED68, RCT2_GLOBAL(ebp + 4, uint16), 0);
strcpy_s(RCT2_ADDRESS_SCENARIO_DETAILS, 256, 0x0141ED68);
}
// Set the last saved game path
strcpy(0x009ABB37, 0x009AB5DA);
format_string(0x009ABB37 + strlen(0x009ABB37), RCT2_GLOBAL(0x0013573D4, uint16), 0x0013573D8);
strcat(0x009ABB37, ".SV6");
memset(0x001357848, 0, 56);
RCT2_GLOBAL(0x0135832C, uint32) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PROFIT, sint32) = 0;
RCT2_GLOBAL(0x01358334, uint32) = 0;
RCT2_GLOBAL(0x01358338, uint16) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_COMPLETED_COMPANY_VALUE, uint32) = 0x80000000;
RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_ADMISSIONS, uint32) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_INCOME_FROM_ADMISSIONS, uint32) = 0;
RCT2_GLOBAL(0x013587D8, uint16) = 63;
RCT2_CALLPROC_EBPSAFE(0x0069E869); // (loan related, called above already)
RCT2_CALLPROC_EBPSAFE(0x0066729F); // reset history / finance / awards
RCT2_CALLPROC_EBPSAFE(0x006B7A38); // reset_all_ride_build_dates
date_reset();
RCT2_CALLPROC_EBPSAFE(0x00674576);
park_calculate_size();
RCT2_CALLPROC_EBPSAFE(0x006C1955);
RCT2_GLOBAL(0x01358840, uint8) = 0;
memset(0x001358102, 0, 20);
RCT2_GLOBAL(0x00135882E, uint16) = 0;
// Open park with free entry when there is no money
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & GAME_FLAGS_NO_MONEY) {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) |= GAME_FLAGS_PARK_OPEN;
RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, uint16) = 0;
}
RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) |= GAME_FLAGS_18;
RCT2_CALLPROC_EBPSAFE(0x006837E3); // (palette related)
gfx_invalidate_screen();
RCT2_GLOBAL(0x009DEA66, uint16) = 0;
RCT2_GLOBAL(0x009DEA5C, uint16) = 62000; // (doesn't appear to ever be read)
}

View File

@@ -18,6 +18,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include <lodepng.h>
#include <stdio.h>
#include <windows.h>
#include "addresses.h"
#include "gfx.h"
@@ -26,6 +28,16 @@
#include "strings.h"
#include "window_error.h"
enum {
SCREENSHOT_FORMAT_BMP,
SCREENSHOT_FORMAT_PNG
};
int gScreenshotFormat = SCREENSHOT_FORMAT_PNG;
static int screenshot_dump_bmp();
static int screenshot_dump_png();
/**
*
* rct2: 0x006E3AEC
@@ -50,17 +62,14 @@ void screenshot_check()
}
}
static int screenshot_get_next_path(char *path)
static int screenshot_get_next_path(char *path, char *extension)
{
char *placeHolder;
strcpy(path, RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH_SLASH, char));
placeHolder = path + strlen(path);
int i;
for (i = 1; i < 1000; i++) {
RCT2_GLOBAL(0x013CE952, uint16) = i;
format_string(placeHolder, STR_SCR_BMP, 0x013CE952);
// Glue together path and filename
sprintf(path, "%sSCR%d%s", RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH_SLASH, char), i, extension);
if (GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND)
return i;
@@ -69,6 +78,18 @@ static int screenshot_get_next_path(char *path)
return -1;
}
int screenshot_dump()
{
switch (gScreenshotFormat) {
case SCREENSHOT_FORMAT_BMP:
return screenshot_dump_bmp();
case SCREENSHOT_FORMAT_PNG:
return screenshot_dump_png();
default:
return -1;
}
}
// Bitmap header structs, for cross platform purposes
typedef struct {
uint16 bfType;
@@ -96,7 +117,7 @@ typedef struct {
*
* rct2: 0x00683D20
*/
int screenshot_dump()
int screenshot_dump_bmp()
{
BitmapFileHeader header;
BitmapInfoHeader info;
@@ -107,7 +128,7 @@ int screenshot_dump()
DWORD bytesWritten;
// Get a free screenshot path
if ((index = screenshot_get_next_path(path)) == -1)
if ((index = screenshot_get_next_path(path, ".bmp")) == -1)
return -1;
// Open file for writing
@@ -188,5 +209,48 @@ int screenshot_dump()
CloseHandle(hFile);
free(buffer);
return index;
}
int screenshot_dump_png()
{
int i, index, width, height, stride;
char path[MAX_PATH] = "";
unsigned char r, g, b, a = 255;
unsigned char* png;
size_t pngSize;
LodePNGState state;
// Get a free screenshot path
if ((index = screenshot_get_next_path(path, ".png")) == -1)
return -1;
lodepng_state_init(&state);
state.info_raw.colortype = LCT_PALETTE;
// Get image size
width = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16);
height = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16);
stride = (width + 3) & 0xFFFFFFFC;
for (i = 0; i < 246; i++) {
b = RCT2_ADDRESS(0x01424680, uint8)[i * 4 + 0];
g = RCT2_ADDRESS(0x01424680, uint8)[i * 4 + 1];
r = RCT2_ADDRESS(0x01424680, uint8)[i * 4 + 2];
lodepng_palette_add(&state.info_raw, r, g, b, a);
}
rct_drawpixelinfo *dpi = RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo);
unsigned int error = lodepng_encode(&png, &pngSize, dpi->bits, stride, dpi->height, &state);
if (!error) lodepng_save_file(png, pngSize, path);
if (error) fprintf(stderr, "error: %u: %s\n", error, lodepng_error_text(error));
free(png);
return index;
}

View File

@@ -21,6 +21,8 @@
#ifndef _SCREENSHOT_H_
#define _SCREENSHOT_H_
extern int gScreenshotFormat;
void screenshot_check();
int screenshot_dump();

View File

@@ -135,8 +135,8 @@ typedef struct rct_window {
sint16 var_4AC;
sint16 var_4AE;
sint16 var_4B0; // viewport target sprite?
sint16 var_4B2;
sint16 var_4B4;
sint16 var_4B2; // viewport target x?
sint16 var_4B4; // viewport target y?
rct_windowclass classification; // 0x4B6
uint8 pad_4B7;
sint8 var_4B8;

View File

@@ -20,6 +20,7 @@
#include "addresses.h"
#include "climate.h"
#include "date.h"
#include "news_item.h"
#include "park.h"
#include "peep.h"
@@ -221,7 +222,8 @@ static void window_game_bottom_toolbar_tooltip()
break;
case WIDX_DATE:
month = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, sint16) & 7;
day = ((RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_DAY, sint16) * ((short*)0x00993988)[month]) >> 16) & 0xFF;
day = ((RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_TICKS, sint16) * days_in_month[month]) >> 16) & 0xFF;
*((short*)0x013CE952) = STR_DATE_DAY_1 + day;
*((short*)0x013CE954) = STR_MONTH_MARCH + month;
widgetIndex = 0;

View File

@@ -19,6 +19,7 @@
*****************************************************************************/
#include "addresses.h"
#include "game.h"
#include "sprites.h"
#include "strings.h"
#include "widget.h"
@@ -151,7 +152,7 @@ static void window_game_top_toolbar_mouseup()
switch (widgetIndex) {
case WIDX_PAUSE:
RCT2_CALLPROC_X(0x006677F2, 0, 1, 0, 0, 2, 0, 0);
game_do_command(0, 1, 0, 0, 2, 0, 0);
break;
case WIDX_FASTFORWARD:
window_cheats_open();
@@ -342,7 +343,7 @@ static void window_game_top_toolbar_dropdown()
if (widgetIndex == WIDX_FILE_MENU) {
switch (dropdownIndex) {
case 0: // load game
RCT2_CALLPROC_X(0x006677F2, 0, 1, 0, 0, 5, 0, 0);
game_do_command(0, 1, 0, 0, 5, 0, 0);
break;
case 1: // save game
RCT2_CALLPROC_EBPSAFE(0x006EE281);
@@ -367,7 +368,7 @@ static void window_game_top_toolbar_dropdown()
RCT2_CALLPROC_X(0x006754F5, eax, 0, 0, 0, 0, 0, 0);
// check success?
RCT2_CALLPROC_X(0x006677F2, 0, 1047, 0, -1, 0, 0, 0);
game_do_command(0, 1047, 0, -1, 0, 0, 0);
gfx_invalidate_screen();
}
break;
@@ -381,7 +382,7 @@ static void window_game_top_toolbar_dropdown()
RCT2_GLOBAL(RCT2_ADDRESS_SCREENSHOT_COUNTDOWN, sint8) = 10;
break;
case 7: // quit game
RCT2_CALLPROC_X(0x006677F2, 0, 1, 0, 0, 5, 1, 0);
game_do_command(0, 1, 0, 0, 5, 1, 0);
break;
}
} else if (widgetIndex == WIDX_VIEW_MENU) {

View File

@@ -21,6 +21,7 @@
#include "addresses.h"
#include "config.h"
#include "date.h"
#include "game.h"
#include "park.h"
#include "peep.h"
#include "ride.h"
@@ -759,12 +760,12 @@ static void window_park_entrance_dropdown()
if (dropdownIndex != 0) {
dropdownIndex &= 0x00FF;
dropdownIndex |= 0x0100;
RCT2_GLOBAL(0x0141E9AE, uint16) = 1724;
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16) = 1724;
} else {
dropdownIndex &= 0x00FF;
RCT2_GLOBAL(0x0141E9AE, uint16) = 1723;
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16) = 1723;
}
RCT2_CALLPROC_X(0x006677F2, 0, 1, 0, dropdownIndex, 34, 0, 0);
game_do_command(0, 1, 0, dropdownIndex, 34, 0, 0);
}
}
@@ -886,10 +887,10 @@ static void window_park_entrance_textinput()
if (widgetIndex == WIDX_RENAME) {
if (result) {
RCT2_GLOBAL(0x0141E9AE, uint16) = STR_CANT_RENAME_PARK;
RCT2_CALLPROC_X(0x006677F2, 1, 1, 0, *((int*)(text + 0)), '!', *((int*)(text + 8)), *((int*)(text + 4)));
RCT2_CALLPROC_X(0x006677F2, 2, 1, 0, *((int*)(text + 12)), '!', *((int*)(text + 20)), *((int*)(text + 16)));
RCT2_CALLPROC_X(0x006677F2, 0, 1, 0, *((int*)(text + 24)), '!', *((int*)(text + 32)), *((int*)(text + 28)));
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16) = STR_CANT_RENAME_PARK;
game_do_command(1, 1, 0, *((int*)(text + 0)), 33, *((int*)(text + 8)), *((int*)(text + 4)));
game_do_command(2, 1, 0, *((int*)(text + 12)), 33, *((int*)(text + 20)), *((int*)(text + 16)));
game_do_command(0, 1, 0, *((int*)(text + 24)), 33, *((int*)(text + 32)), *((int*)(text + 28)));
}
}
}
@@ -1370,11 +1371,11 @@ static void window_park_price_mousedown()
break;
case WIDX_INCREASE_PRICE:
newFee = min(1000, RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, uint16) + 10);
RCT2_CALLPROC_X(0x006677F2, 0, 1, 0, 0, 39, newFee, 0);
game_do_command(0, 1, 0, 0, 39, newFee, 0);
break;
case WIDX_DECREASE_PRICE:
newFee = max(0, RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, uint16) - 10);
RCT2_CALLPROC_X(0x006677F2, 0, 1, 0, 0, 39, newFee, 0);
game_do_command(0, 1, 0, 0, 39, newFee, 0);
break;
}
}
@@ -2029,7 +2030,7 @@ static void window_park_graph_draw_months(rct_drawpixelinfo *dpi, uint8 *history
int i, x, y, yearOver32, currentMonth, currentDay;
currentMonth = date_get_month(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, uint16));
currentDay = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_DAY, uint16);
currentDay = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_TICKS, uint16);
yearOver32 = (currentMonth * 4) + (currentDay >> 14) - 31;
x = baseX;
y = baseY;

View File

@@ -20,6 +20,7 @@
#include <string.h>
#include "addresses.h"
#include "game.h"
#include "ride.h"
#include "strings.h"
#include "sprites.h"
@@ -756,7 +757,7 @@ static void window_ride_list_close_all(rct_window *w)
RCT2_GLOBAL(0x013CE952 + 6, uint16) = w->scrolls[0].v_top;
RCT2_GLOBAL(0x013CE952 + 8, uint32) = w->scrolls[0].v_bottom;
RCT2_CALLPROC_X(0x006677F2, 0, 1, 0, i, 8, 0, 0);
game_do_command(0, 1, 0, i, 8, 0, 0);
}
}
@@ -776,6 +777,6 @@ static void window_ride_list_open_all(rct_window *w)
RCT2_GLOBAL(0x013CE952 + 6, uint16) = w->scrolls[0].v_top;
RCT2_GLOBAL(0x013CE952 + 8, uint32) = w->scrolls[0].v_bottom;
RCT2_CALLPROC_X(0x006677F2, 0, 1, 0, (1 << 8) | i, 8, 0, 0);
game_do_command(0, 1, 0, (1 << 8) | i, 8, 0, 0);
}
}

View File

@@ -19,6 +19,7 @@
*****************************************************************************/
#include "addresses.h"
#include "game.h"
#include "sprites.h"
#include "strings.h"
#include "widget.h"
@@ -104,7 +105,7 @@ static void window_title_exit_mouseup()
return;
if (widgetIndex == 0)
RCT2_CALLPROC_X(0x006677F2, 0, 1, 0, 0, 5, 2, 0);
game_do_command(0, 1, 0, 0, 5, 2, 0);
}
/**

View File

@@ -20,6 +20,7 @@
#include "addresses.h"
#include "editor.h"
#include "game.h"
#include "strings.h"
#include "sprites.h"
#include "tutorial.h"
@@ -112,7 +113,7 @@ static void window_title_menu_mouseup()
if (widgetIndex == WIDX_START_NEW_GAME) {
window_scenarioselect_open();
} else if (widgetIndex == WIDX_CONTINUE_SAVED_GAME) {
RCT2_CALLPROC_X(0x006677F2, 0, 1, 0, 0, 5, 0, 0);
game_do_command(0, 1, 0, 0, 5, 0, 0);
}
}