Translations update
[openttd/fttd.git] / src / newgrf_animation_base.h
blobbf58fa84631efd4e5fedf3c62ab870ceb28ec1af
1 /* $Id$ */
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 */
10 /** @file newgrf_animation_base.h Function implementations related to NewGRF animation. */
12 /* No inclusion guards as this file must only be included from .cpp files. */
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 "map/common.h"
22 /**
23 * Helper class for a unified approach to NewGRF animation.
25 struct AnimationBase {
26 /**
27 * Animate a single tile.
28 * @param cb The callback to actually call.
29 * @param spec Specification related to the tile.
30 * @param obj Object related to the tile.
31 * @param tile Tile to animate changes for.
32 * @param random_animation Whether to pass random bits to the "next frame" callback.
33 * @tparam Tbase Instantiation of this class.
34 * @tparam Tspec NewGRF specification related to the animated tile.
35 * @tparam Tobj Object related to the animated tile.
37 template <typename Tbase, typename Tspec, typename Tobj>
38 static void AnimateTile (const Tspec *spec, Tobj *obj, TileIndex tile, bool random_animation)
40 assert(spec != NULL);
42 /* Acquire the animation speed from the NewGRF. */
43 uint8 animation_speed = spec->animation.speed;
44 if (HasBit(spec->callback_mask, Tbase::cbm_animation_speed)) {
45 uint16 callback = Tbase::get_callback (Tbase::cb_animation_speed, 0, 0, spec, obj, tile);
46 if (callback != CALLBACK_FAILED) {
47 if (callback >= 0x100 && spec->grf_prop.grffile->grf_version >= 8) ErrorUnknownCallbackResult(spec->grf_prop.grffile->grfid, Tbase::cb_animation_speed, callback);
48 animation_speed = Clamp(callback & 0xFF, 0, 16);
52 /* An animation speed of 2 means the animation frame changes 4 ticks, and
53 * increasing this value by one doubles the wait. 0 is the minimum value
54 * allowed for animation_speed, which corresponds to 30ms, and 16 is the
55 * maximum, corresponding to around 33 minutes. */
56 if (_tick_counter % (1 << animation_speed) != 0) return;
58 uint8 frame = GetAnimationFrame(tile);
59 uint8 num_frames = spec->animation.frames;
61 bool frame_set_by_callback = false;
63 if (HasBit(spec->callback_mask, Tbase::cbm_animation_next_frame)) {
64 uint16 callback = Tbase::get_callback (Tbase::cb_animation_next_frame, random_animation ? Random() : 0, 0, spec, obj, tile);
66 if (callback != CALLBACK_FAILED) {
67 frame_set_by_callback = true;
69 switch (callback & 0xFF) {
70 case 0xFF:
71 DeleteAnimatedTile(tile);
72 break;
74 case 0xFE:
75 frame_set_by_callback = false;
76 break;
78 default:
79 frame = callback & 0xFF;
80 break;
83 /* If the lower 7 bits of the upper byte of the callback
84 * result are not empty, it is a sound effect. */
85 if (GB(callback, 8, 7) != 0 && _settings_client.sound.ambient) PlayTileSound(spec->grf_prop.grffile, GB(callback, 8, 7), tile);
89 if (!frame_set_by_callback) {
90 if (frame < num_frames) {
91 frame++;
92 } else if (frame == num_frames && spec->animation.status == ANIM_STATUS_LOOPING) {
93 /* This animation loops, so start again from the beginning */
94 frame = 0;
95 } else {
96 /* This animation doesn't loop, so stay here */
97 DeleteAnimatedTile(tile);
101 SetAnimationFrame(tile, frame);
102 MarkTileDirtyByTile(tile);
106 * Process an animation callback result.
107 * @param spec Specification related to the tile.
108 * @param tile Tile to consider animation changes for.
109 * @param callback The callback result.
111 template <typename Tspec>
112 static void ChangeAnimationFrame (const Tspec *spec, TileIndex tile, uint16 callback)
114 if (callback == CALLBACK_FAILED) return;
116 switch (callback & 0xFF) {
117 case 0xFD: /* Do nothing. */ break;
118 case 0xFE: AddAnimatedTile(tile); break;
119 case 0xFF: DeleteAnimatedTile(tile); break;
120 default:
121 SetAnimationFrame(tile, callback);
122 AddAnimatedTile(tile);
123 break;
126 /* If the lower 7 bits of the upper byte of the callback
127 * result are not empty, it is a sound effect. */
128 if (GB(callback, 8, 7) != 0 && _settings_client.sound.ambient) PlayTileSound(spec->grf_prop.grffile, GB(callback, 8, 7), tile);