changeset 18278:11ed8abd8930 draft

(svn r23114) -Feature: [NewGRF] Ambient sound effect callback.
author michi_cc <michi_cc@openttd.org>
date Fri, 04 Nov 2011 21:05:08 +0000
parents 6bf27441026a
children 574646cd34a7
files src/clear_cmd.cpp src/newgrf.h src/newgrf_callbacks.h src/newgrf_generic.cpp src/newgrf_generic.h src/tree_cmd.cpp src/water_cmd.cpp
diffstat 7 files changed, 55 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/clear_cmd.cpp
+++ b/src/clear_cmd.cpp
@@ -20,6 +20,7 @@
 #include "viewport_func.h"
 #include "water.h"
 #include "core/random_func.hpp"
+#include "newgrf_generic.h"
 
 #include "table/strings.h"
 #include "table/sprites.h"
@@ -239,6 +240,7 @@
 		}
 	}
 	TileLoopClearHelper(tile);
+	AmbientSoundEffectCallback(tile);
 
 	switch (_settings_game.game_creation.landscape) {
 		case LT_TROPIC: TileLoopClearDesert(tile); break;
--- a/src/newgrf.h
+++ b/src/newgrf.h
@@ -56,7 +56,7 @@
 	GMB_DESERT_PAVED_ROADS     = 1,
 	GMB_FIELD_BOUNDING_BOX     = 2, // Unsupported.
 	GMB_TRAIN_WIDTH_32_PIXELS  = 3, ///< Use 32 pixels per train vehicle in depot gui and vehicle details. Never set in the global variable; @see GRFFile::traininfo_vehicle_width
-	GMB_AMBIENT_SOUND_CALLBACK = 4, // Unsupported.
+	GMB_AMBIENT_SOUND_CALLBACK = 4,
 	GMB_CATENARY_ON_3RD_TRACK  = 5, // Unsupported.
 };
 
--- a/src/newgrf_callbacks.h
+++ b/src/newgrf_callbacks.h
@@ -196,7 +196,7 @@
 	CBID_HOUSE_DENY_DESTRUCTION          = 0x143, // 15 bit callback
 
 	/** Select an ambient sound to play for a given type of tile. */
-	CBID_SOUNDS_AMBIENT_EFFECT           = 0x144, // 15 bit callback, not implemented
+	CBID_SOUNDS_AMBIENT_EFFECT           = 0x144, // 15 bit callback
 
 	/** Called to calculate part of a station rating. */
 	CBID_CARGO_STATION_RATING_CALC       = 0x145, // 15 bit callback
--- a/src/newgrf_generic.cpp
+++ b/src/newgrf_generic.cpp
@@ -15,6 +15,9 @@
 #include "newgrf_spritegroup.h"
 #include "industrytype.h"
 #include "core/bitmath_func.hpp"
+#include "core/random_func.hpp"
+#include "tile_map.h"
+#include "newgrf_sound.h"
 #include <list>
 
 
@@ -84,6 +87,14 @@
 
 static uint32 GenericCallbackGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
 {
+	DEBUG(grf, 1, "Unhandled generic feature variable 0x%02X", variable);
+
+	*available = false;
+	return UINT_MAX;
+}
+
+static uint32 GenericAiCallbackGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
+{
 	switch (variable) {
 		case 0x40: return object->grffile->cargo_map[object->u.generic.cargo_type];
 
@@ -115,12 +126,12 @@
 }
 
 
-static inline void NewGenericResolver(ResolverObject *res)
+static inline void NewGenericResolver(ResolverObject *res, bool ai_callback)
 {
 	res->GetRandomBits = &GenericCallbackGetRandomBits;
 	res->GetTriggers   = &GenericCallbackGetTriggers;
 	res->SetTriggers   = &GenericCallbackSetTriggers;
-	res->GetVariable   = &GenericCallbackGetVariable;
+	res->GetVariable   = ai_callback ? &GenericAiCallbackGetVariable : &GenericCallbackGetVariable;
 	res->ResolveReal   = &GenericCallbackResolveReal;
 
 	res->callback        = CBID_NO_CALLBACK;
@@ -181,7 +192,7 @@
 {
 	ResolverObject object;
 
-	NewGenericResolver(&object);
+	NewGenericResolver(&object, true);
 
 	if (src_industry != IT_AI_UNKNOWN && src_industry != IT_AI_TOWN) {
 		const IndustrySpec *is = GetIndustrySpec(src_industry);
@@ -209,3 +220,32 @@
 	if (callback != CALLBACK_FAILED) callback = GB(callback, 0, 8);
 	return callback;
 }
+
+
+/**
+ * 'Execute' the ambient sound effect callback.
+ * @param tile Tile the sound effect should be generated for.
+ */
+void AmbientSoundEffectCallback(TileIndex tile)
+{
+	assert(IsTileType(tile, MP_CLEAR) || IsTileType(tile, MP_TREES) || IsTileType(tile, MP_WATER));
+
+	/* Only run callback if enabled. */
+	if (!HasGrfMiscBit(GMB_AMBIENT_SOUND_CALLBACK)) return;
+	/* Only run every 1/200-th time. */
+	uint32 r; // Save for later
+	if (!Chance16R(1, 200, r)) return;
+
+	ResolverObject object;
+
+	/* Prepare resolver object. */
+	NewGenericResolver(&object, false);
+	object.callback = CBID_SOUNDS_AMBIENT_EFFECT;
+	object.callback_param1 = GetTileType(tile) << 28 | TileHeight(tile) << 24 | GB(r, 16, 8) << 16 | GetTerrainType(tile);
+
+	/* Run callback. */
+	const GRFFile *grf_file;
+	uint16 callback = GetGenericCallbackResult(GSF_SOUNDFX, &object, &grf_file);
+
+	if (callback != CALLBACK_FAILED) PlayTileSound(grf_file, callback, tile);
+}
--- a/src/newgrf_generic.h
+++ b/src/newgrf_generic.h
@@ -15,6 +15,7 @@
 #include "cargo_type.h"
 #include "industry_type.h"
 #include "newgrf.h"
+#include "tile_type.h"
 
 struct SpriteGroup;
 
@@ -50,5 +51,6 @@
 void AddGenericCallback(uint8 feature, const GRFFile *file, const SpriteGroup *group);
 
 uint16 GetAiPurchaseCallbackResult(uint8 feature, CargoID cargo_type, uint8 default_selection, IndustryType src_industry, IndustryType dst_industry, uint8 distance, AIConstructionEvent event, uint8 count, uint8 station_size, const GRFFile **file);
+void AmbientSoundEffectCallback(TileIndex tile);
 
 #endif /* NEWGRF_GENERIC_H */
--- a/src/tree_cmd.cpp
+++ b/src/tree_cmd.cpp
@@ -27,6 +27,7 @@
 #include "landscape_type.h"
 #include "company_base.h"
 #include "core/random_func.hpp"
+#include "newgrf_generic.h"
 
 #include "table/strings.h"
 #include "table/sprites.h"
@@ -620,12 +621,14 @@
 static void TileLoop_Trees(TileIndex tile)
 {
 	if (GetTreeGround(tile) == TREE_GROUND_SHORE) {
-		TileLoop_Water(tile);
+		TileLoop_Water(tile); // Calls AmbientSoundEffectCallback
 	} else {
 		switch (_settings_game.game_creation.landscape) {
 			case LT_TROPIC: TileLoopTreesDesert(tile); break;
 			case LT_ARCTIC: TileLoopTreesAlps(tile);   break;
 		}
+
+		AmbientSoundEffectCallback(tile);
 	}
 
 	TileLoopClearHelper(tile);
--- a/src/water_cmd.cpp
+++ b/src/water_cmd.cpp
@@ -1071,6 +1071,8 @@
  */
 void TileLoop_Water(TileIndex tile)
 {
+	AmbientSoundEffectCallback(tile);
+
 	switch (GetFloodingBehaviour(tile)) {
 		case FLOOD_ACTIVE:
 			for (Direction dir = DIR_BEGIN; dir < DIR_END; dir++) {