diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj
index fe636745d1..7528f5ae19 100644
--- a/src/openrct2/libopenrct2.vcxproj
+++ b/src/openrct2/libopenrct2.vcxproj
@@ -335,7 +335,7 @@
-
+
diff --git a/src/openrct2/world/Balloon.cpp b/src/openrct2/world/Balloon.cpp
index f6bfde7315..5698811685 100644
--- a/src/openrct2/world/Balloon.cpp
+++ b/src/openrct2/world/Balloon.cpp
@@ -1,122 +1,144 @@
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
/*****************************************************************************
- * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
- *
- * OpenRCT2 is the work of many authors, a full list can be found in contributors.md
- * For more information, visit https://github.com/OpenRCT2/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.
- *
- * A full copy of the GNU General Public License can be found in licence.txt
- *****************************************************************************/
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
#pragma endregion
-#include "../audio/audio.h"
#include "../network/network.h"
-#include "../scenario/scenario.h"
-#include "../util/util.h"
-#include "sprite.h"
-/**
- *
- * rct2: 0x006736C7
- */
-void create_balloon(sint32 x, sint32 y, sint32 z, sint32 colour, uint8 bl)
+extern "C"
{
- rct_sprite* sprite = create_sprite(2);
- if (sprite != NULL) {
- sprite->balloon.var_14 = 13;
- sprite->balloon.var_09 = 22;
- sprite->balloon.var_15 = 11;
- sprite->balloon.sprite_identifier = SPRITE_IDENTIFIER_MISC;
- sprite_move(x, y, z, sprite);
- sprite->balloon.misc_identifier = SPRITE_MISC_BALLOON;
- sprite->balloon.frame = 0;
- sprite->balloon.colour = colour;
- sprite->balloon.popped = bl;
- }
+ #include "../audio/audio.h"
+ #include "../scenario/scenario.h"
+ #include "../util/util.h"
+ #include "sprite.h"
}
-static void balloon_pop(rct_balloon *balloon)
+static bool sprite_is_balloon(rct_sprite * sprite)
{
- balloon->popped = 1;
- balloon->frame = 0;
- audio_play_sound_at_location(SOUND_BALLOON_POP, balloon->x, balloon->y, balloon->z);
+ return sprite != nullptr &&
+ sprite->balloon.sprite_identifier == SPRITE_IDENTIFIER_MISC &&
+ sprite->balloon.misc_identifier == SPRITE_MISC_BALLOON;
+}
+
+static void balloon_pop(rct_balloon * balloon)
+{
+ balloon->popped = 1;
+ balloon->frame = 0;
+ audio_play_sound_at_location(SOUND_BALLOON_POP, balloon->x, balloon->y, balloon->z);
}
/**
- *
- * rct2: 0x0067342C
- */
-void balloon_update(rct_balloon *balloon)
+*
+* rct2: 0x006E88ED
+*/
+static void balloon_press(rct_balloon * balloon)
{
- invalidate_sprite_2((rct_sprite*)balloon);
- if (balloon->popped == 1) {
- balloon->frame += 256;
- if (balloon->frame >= 1280)
- sprite_remove((rct_sprite*)balloon);
-
- return;
- }
-
- sint32 original_var26a = balloon->var_26a;
- balloon->var_26a += 85;
- if (original_var26a < 255 - 85)
- return;
-
- balloon->var_26b++;
- sprite_move(balloon->x, balloon->y, balloon->z + 1, (rct_sprite*)balloon);
-
- sint32 maxZ = 1967 - ((balloon->x ^ balloon->y) & 31);
- if (balloon->z < maxZ)
- return;
-
- balloon_pop(balloon);
+ if (balloon->popped != 1)
+ {
+ uint32 random = scenario_rand();
+ if ((balloon->sprite_index & 7) || (random & 0xFFFF) < 0x2000)
+ {
+ balloon_pop(balloon);
+ }
+ else
+ {
+ sint16 shift = ((random & 0x80000000) ? -6 : 6);
+ sprite_move(balloon->x + shift,
+ balloon->y,
+ balloon->z,
+ (rct_sprite *)balloon);
+ }
+ }
}
-/**
- *
- * rct2: 0x006E88ED
- */
-static void balloon_press(rct_balloon *balloon)
+static sint32 balloon_press(uint16 spriteIndex, uint8 flags)
{
- if (balloon->popped == 1)
- return;
+ rct_sprite * sprite = try_get_sprite(spriteIndex);
+ if (!sprite_is_balloon(sprite))
+ {
+ log_error("Tried getting invalid sprite for balloon: %u", spriteIndex);
+ return MONEY32_UNDEFINED;
+ }
- uint32 random = scenario_rand();
- if ((balloon->sprite_index & 7) || (random & 0xFFFF) < 0x2000) {
- balloon_pop(balloon);
- return;
- }
-
- sprite_move(
- balloon->x + ((random & 0x80000000) ? -6 : 6),
- balloon->y,
- balloon->z,
- (rct_sprite*)balloon
- );
+ if (flags & GAME_COMMAND_FLAG_APPLY)
+ {
+ if (sprite_is_balloon(sprite))
+ {
+ balloon_press(&sprite->balloon);
+ }
+ }
+ return 0;
}
-void game_command_balloon_press(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp)
+extern "C"
{
- uint32 balloon_num = *eax;
- sint32 flags = *ebx;
- *ebx = 0;
- if (!(flags & GAME_COMMAND_FLAG_APPLY)) {
- return;
- }
+ /**
+ *
+ * rct2: 0x006736C7
+ */
+ void create_balloon(sint32 x, sint32 y, sint32 z, sint32 colour, uint8 bl)
+ {
+ rct_sprite* sprite = create_sprite(2);
+ if (sprite != nullptr)
+ {
+ sprite->balloon.var_14 = 13;
+ sprite->balloon.var_09 = 22;
+ sprite->balloon.var_15 = 11;
+ sprite->balloon.sprite_identifier = SPRITE_IDENTIFIER_MISC;
+ sprite_move(x, y, z, sprite);
+ sprite->balloon.misc_identifier = SPRITE_MISC_BALLOON;
+ sprite->balloon.frame = 0;
+ sprite->balloon.colour = colour;
+ sprite->balloon.popped = bl;
+ }
+ }
- if (balloon_num >= MAX_SPRITES) {
- log_error("Tried getting invalid sprite for balloon: %u", balloon_num);
- *ebx = MONEY32_UNDEFINED;
- return;
- }
+ /**
+ *
+ * rct2: 0x0067342C
+ */
+ void balloon_update(rct_balloon * balloon)
+ {
+ invalidate_sprite_2((rct_sprite *)balloon);
+ if (balloon->popped == 1)
+ {
+ balloon->frame += 256;
+ if (balloon->frame >= 1280)
+ {
+ sprite_remove((rct_sprite *)balloon);
+ }
+ }
+ else
+ {
+ sint32 original_var26a = balloon->var_26a;
+ balloon->var_26a += 85;
+ if (original_var26a >= 255 - 85)
+ {
+ balloon->var_26b++;
+ sprite_move(balloon->x, balloon->y, balloon->z + 1, (rct_sprite*)balloon);
- rct_sprite* sprite = get_sprite(balloon_num);
- if (sprite != NULL && sprite->balloon.sprite_identifier == SPRITE_IDENTIFIER_MISC && sprite->balloon.misc_identifier == SPRITE_MISC_BALLOON) {
- balloon_press(&sprite->balloon);
- }
+ sint32 maxZ = 1967 - ((balloon->x ^ balloon->y) & 31);
+ if (balloon->z >= maxZ)
+ {
+ balloon_pop(balloon);
+ }
+ }
+ }
+ }
+
+ void game_command_balloon_press(sint32 * eax, sint32 * ebx, sint32 * ecx, sint32 * edx, sint32 * esi, sint32 * edi, sint32 * ebp)
+ {
+ *ebx = balloon_press(*eax & 0xFFFF, *ebx);
+ }
}
diff --git a/src/openrct2/world/sprite.c b/src/openrct2/world/sprite.c
index e83ee13566..15569658eb 100644
--- a/src/openrct2/world/sprite.c
+++ b/src/openrct2/world/sprite.c
@@ -45,6 +45,16 @@ static rct_xyz16 _spritelocations2[MAX_SPRITES];
static size_t GetSpatialIndexOffset(sint32 x, sint32 y);
+rct_sprite *try_get_sprite(size_t spriteIndex)
+{
+ rct_sprite * sprite = NULL;
+ if (spriteIndex < MAX_SPRITES)
+ {
+ sprite = &_spriteList[spriteIndex];
+ }
+ return sprite;
+}
+
rct_sprite *get_sprite(size_t sprite_idx)
{
openrct2_assert(sprite_idx < MAX_SPRITES, "Tried getting sprite %u", sprite_idx);
diff --git a/src/openrct2/world/sprite.h b/src/openrct2/world/sprite.h
index fb0077a6c7..a21b07f3c4 100644
--- a/src/openrct2/world/sprite.h
+++ b/src/openrct2/world/sprite.h
@@ -376,6 +376,7 @@ enum {
LITTER_TYPE_EMPTY_BOWL_BLUE,
};
+rct_sprite *try_get_sprite(size_t spriteIndex);
rct_sprite *get_sprite(size_t sprite_idx);
#ifdef NO_RCT2