OpenTTD

newgrf_animation_base.h
Go to the documentation of this file.
1 /* $Id: newgrf_animation_base.h 24846 2012-12-23 21:09:09Z frosch $ */
2
3 /*
4 * This file is part of OpenTTD.
5 * OpenTTD 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, version 2.
6 * OpenTTD 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.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8 */
9
12 /* No inclusion guards as this file must only be included from .cpp files. */
13
14 #include "animated_tile_func.h"
15 #include "core/random_func.hpp"
16 #include "date_func.h"
17 #include "viewport_func.h"
18 #include "newgrf_animation_type.h"
19 #include "newgrf_callbacks.h"
20 #include "tile_map.h"
21
30 template <typename Tbase, typename Tspec, typename Tobj, typename Textra, uint16 (*GetCallback)(CallbackID callback, uint32 param1, uint32 param2, const Tspec *statspec, Tobj *st, TileIndex tile, Textra extra_data)>
31 struct AnimationBase {
41 static void AnimateTile(const Tspec *spec, Tobj *obj, TileIndex tile, bool random_animation, Textra extra_data = 0)
42 {
43 assert(spec != NULL);
44
45 /* Acquire the animation speed from the NewGRF. */
46 uint8 animation_speed = spec->animation.speed;
47 if (HasBit(spec->callback_mask, Tbase::cbm_animation_speed)) {
48 uint16 callback = GetCallback(Tbase::cb_animation_speed, 0, 0, spec, obj, tile, extra_data);
49 if (callback != CALLBACK_FAILED) {
50 if (callback >= 0x100 && spec->grf_prop.grffile->grf_version >= 8) ErrorUnknownCallbackResult(spec->grf_prop.grffile->grfid, Tbase::cb_animation_speed, callback);
51 animation_speed = Clamp(callback & 0xFF, 0, 16);
52 }
53 }
54
55 /* An animation speed of 2 means the animation frame changes 4 ticks, and
56 * increasing this value by one doubles the wait. 0 is the minimum value
57 * allowed for animation_speed, which corresponds to 30ms, and 16 is the
58 * maximum, corresponding to around 33 minutes. */
59 if (_tick_counter % (1 << animation_speed) != 0) return;
60
61 uint8 frame = GetAnimationFrame(tile);
62 uint8 num_frames = spec->animation.frames;
63
64 bool frame_set_by_callback = false;
65
66 if (HasBit(spec->callback_mask, Tbase::cbm_animation_next_frame)) {
67 uint16 callback = GetCallback(Tbase::cb_animation_next_frame, random_animation ? Random() : 0, 0, spec, obj, tile, extra_data);
68
69 if (callback != CALLBACK_FAILED) {
70 frame_set_by_callback = true;
71
72 switch (callback & 0xFF) {
73 case 0xFF:
74 DeleteAnimatedTile(tile);
75 break;
76
77 case 0xFE:
78 frame_set_by_callback = false;
79 break;
80
81 default:
82 frame = callback & 0xFF;
83 break;
84 }
85
86 /* If the lower 7 bits of the upper byte of the callback
87 * result are not empty, it is a sound effect. */
88 if (GB(callback, 8, 7) != 0 && _settings_client.sound.ambient) PlayTileSound(spec->grf_prop.grffile, GB(callback, 8, 7), tile);
89 }
90 }
91
92 if (!frame_set_by_callback) {
93 if (frame < num_frames) {
94 frame++;
95 } else if (frame == num_frames && spec->animation.status == ANIM_STATUS_LOOPING) {
96 /* This animation loops, so start again from the beginning */
97 frame = 0;
98 } else {
99 /* This animation doesn't loop, so stay here */
100 DeleteAnimatedTile(tile);
101 }
102 }
103
104 SetAnimationFrame(tile, frame);
105 MarkTileDirtyByTile(tile);
106 }
107
120 static void ChangeAnimationFrame(CallbackID cb, const Tspec *spec, Tobj *obj, TileIndex tile, uint32 random_bits, uint32 trigger, Textra extra_data = 0)
121 {
122 uint16 callback = GetCallback(cb, random_bits, trigger, spec, obj, tile, extra_data);
123 if (callback == CALLBACK_FAILED) return;
124
125 switch (callback & 0xFF) {
126 case 0xFD: /* Do nothing. */ break;
127 case 0xFE: AddAnimatedTile(tile); break;
128 case 0xFF: DeleteAnimatedTile(tile); break;
129 default:
130 SetAnimationFrame(tile, callback);
131 AddAnimatedTile(tile);
132 break;
133 }
134
135 /* If the lower 7 bits of the upper byte of the callback
136 * result are not empty, it is a sound effect. */
137 if (GB(callback, 8, 7) != 0 && _settings_client.sound.ambient) PlayTileSound(spec->grf_prop.grffile, GB(callback, 8, 7), tile);
138 }
139 };
CALLBACK_FAILED
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
Definition: newgrf_callbacks.h:406
SetAnimationFrame
static void SetAnimationFrame(TileIndex t, byte frame)
Set a new animation frame.
Definition: tile_map.h:255
AddAnimatedTile
void AddAnimatedTile(TileIndex tile)
Add the given tile to the animated tile table (if it does not exist on that table yet)...
Definition: animated_tile.cpp:51
date_func.h
Functions related to dates.
GetAnimationFrame
static byte GetAnimationFrame(TileIndex t)
Get the current animation frame.
Definition: tile_map.h:243
newgrf_animation_type.h
Definitions related to NewGRF animation.
SoundSettings::ambient
bool ambient
Play ambient, industry and town sounds.
Definition: settings_type.h:181
AnimationBase::ChangeAnimationFrame
static void ChangeAnimationFrame(CallbackID cb, const Tspec *spec, Tobj *obj, TileIndex tile, uint32 random_bits, uint32 trigger, Textra extra_data=0)
Check a callback to determine what the next animation step is and execute that step.
Definition: newgrf_animation_base.h:120
newgrf_callbacks.h
Callbacks that NewGRFs could implement.
AnimationBase::AnimateTile
static void AnimateTile(const Tspec *spec, Tobj *obj, TileIndex tile, bool random_animation, Textra extra_data=0)
Animate a single tile.
Definition: newgrf_animation_base.h:41
viewport_func.h
Functions related to (drawing on) viewports.
random_func.hpp
Pseudo random number generator.
animated_tile_func.h
Tile animation!
ClientSettings::sound
SoundSettings sound
sound effect settings
Definition: settings_type.h:564
PlayTileSound
void PlayTileSound(const GRFFile *file, SoundID sound_id, TileIndex tile)
Play a NewGRF sound effect at the location of a specific tile.
Definition: newgrf_sound.cpp:220
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:76
DeleteAnimatedTile
void DeleteAnimatedTile(TileIndex tile)
Removes the given tile from the animated tile table.
Definition: animated_tile.cpp:30
Clamp
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:139
MarkTileDirtyByTile
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset)
Mark a tile given by its index dirty for repaint.
Definition: viewport.cpp:1904
_tick_counter
uint16 _tick_counter
Ever incrementing (and sometimes wrapping) tick counter for setting off various events.
Definition: date.cpp:30
ErrorUnknownCallbackResult
void ErrorUnknownCallbackResult(uint32 grfid, uint16 cbid, uint16 cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
Definition: newgrf_commons.cpp:518
TileIndex
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:80
AnimationBase
Helper class for a unified approach to NewGRF animation.
Definition: newgrf_animation_base.h:31
GB
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
Definition: bitmath_func.hpp:34
CallbackID
CallbackID
List of implemented NewGRF callbacks.
Definition: newgrf_callbacks.h:22
HasBit
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
Definition: bitmath_func.hpp:105
tile_map.h
Map writing/reading functions for tiles.
ANIM_STATUS_LOOPING
static const uint8 ANIM_STATUS_LOOPING
Animation is looping.
Definition: newgrf_animation_type.h:16