cleanup of unnecessarily convoluted function call
[rocksndiamonds.git] / src / game_bd / bd_cave.h
1 /*
2  * Copyright (c) 2007, 2008, 2009, Czirkos Zoltan <cirix@fw.hu>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #ifndef BD_CAVE_H
18 #define BD_CAVE_H
19
20 #include "bd_elements.h"
21 #include "bd_colors.h"
22 #include "bd_random.h"
23
24
25 // ============================================================================
26 // BIG STRUCT HANDLING
27 // ============================================================================
28
29 // possible types handled
30 typedef enum _gd_type
31 {
32   // not real types, only used by editor to build ui
33   GD_TAB,
34   GD_LABEL,
35
36   // gd types
37   GD_TYPE_STRING,               // static string, fixed array of characters
38   GD_TYPE_LONGSTRING,           // long string which has its own notebook page in the editor
39   GD_TYPE_INT,
40   GD_TYPE_RATIO,
41   GD_TYPE_ELEMENT,
42   GD_TYPE_BOOLEAN,
43   GD_TYPE_PROBABILITY,          // probabilities are stored in parts per million,
44                                 // ie. *1E6, converted to int.
45   GD_TYPE_COLOR,
46   GD_TYPE_EFFECT,
47   GD_TYPE_DIRECTION,
48   GD_TYPE_SCHEDULING,
49 } GdType;
50
51 enum _gd_property_flags
52 {
53   GD_ALWAYS_SAVE           = 1 << 0,
54   GD_DONT_SAVE             = 1 << 1,
55   GD_DONT_SHOW_IN_EDITOR   = 1 << 2,
56   GD_SHOW_LEVEL_LABEL      = 1 << 3,
57   GD_COMPATIBILITY_SETTING = 1 << 4,
58 };
59
60 typedef struct _gd_struct_descriptor
61 {
62   char *identifier;             // bdcff identifier
63   GdType type;                  // data type
64   int flags;                    // flags for bdcff saving/loading
65   char *name;                   // name in editor
66   int offset;                   // byte offset in a GdCave structure. use the CAVE_OFFSET macro
67   int count;                    // size of array; usually 1, for non-arrays.
68   char *tooltip;                // tooltip text in editor
69   int min, max;                 // integers have minimum and maximum
70 } GdStructDescriptor;
71
72 typedef struct _gd_property_default
73 {
74   int offset;                   // data offset (bytes) in a cave structure
75   int defval;                   // default value, converted to int. if type is a float, *1000000
76
77   int property_index;           // index in gd_cave_properties; created at runtime
78 } GdPropertyDefault;
79
80
81 void gd_struct_set_defaults_from_array(void *str, const GdStructDescriptor *properties, GdPropertyDefault *defaults);
82
83 // these define the number of the cells in the png file
84 #define GD_NUM_OF_CELLS_X       8
85 #define GD_NUM_OF_CELLS_Y       51
86
87 // +80: placeholder for cells which are rendered by the game;
88 // for example diamond + arrow = falling diamond
89 #define GD_NUM_OF_CELLS         (GD_NUM_OF_CELLS_X * GD_NUM_OF_CELLS_Y + 80)
90
91 // maximum replay size (maximum seconds x game cycles per second)
92 #define MAX_REPLAY_LEN          (10000 * FRAMES_PER_SECOND / 8)
93
94 extern const GdColor gd_flash_color;
95 extern const GdColor gd_select_color;
96
97 enum _element_property
98 {
99   E_P_SLOPED_LEFT,              // stones and diamonds roll down to left on this
100   E_P_SLOPED_RIGHT,             // stones and diamonds roll down to right on this
101   E_P_SLOPED_UP,
102   E_P_SLOPED_DOWN,
103   E_P_BLADDER_SLOPED,           // element act sloped also for the bladder
104
105   E_P_AMOEBA_CONSUMES,          // amoeba can eat this
106   E_P_DIRT,                     // it is dirt, or something similar (dirt2 or sloped dirt)
107   E_P_BLOWS_UP_FLIES,           // flies blow up, if they touch this
108   E_P_EXPLODES_BY_HIT,          // explodes if hit by a stone
109
110   E_P_EXPLOSION,                // set for every stage of every explosion.
111   E_P_EXPLOSION_FIRST_STAGE,    // set for first stage of every explosion.
112                                 // helps slower/faster explosions changing
113
114   E_P_NON_EXPLODABLE,           // selfexplaining
115   E_P_CCW,                      // this creature has a default counterclockwise
116                                 // rotation (for example, o_fire_1)
117   E_P_CAN_BE_HAMMERED,          // can be broken by pneumatic hammer
118   E_P_VISUAL_EFFECT,            // if the element can use a visual effect.
119                                 // used to check consistency of the code
120   E_P_PLAYER,                   // easier to find out if it is a player element
121   E_P_MOVED_BY_CONVEYOR_TOP,    // can be moved by conveyor belt
122   E_P_MOVED_BY_CONVEYOR_BOTTOM, // can be moved UNDER the conveyor belt
123
124   E_P_WALKABLE,                 // can be walked
125   E_P_DIGGABLE,                 // can be digged
126   E_P_COLLECTIBLE,              // can be collected
127   E_P_PUSHABLE,                 // can be pushed
128   E_P_CAN_MOVE,                 // can move
129   E_P_CAN_FALL,                 // can fall
130   E_P_FALLING,                  // falling
131   E_P_GROWING,                  // growing (element birth)
132 };
133
134 // properties
135 #define P_SLOPED_LEFT                   (1 << E_P_SLOPED_LEFT)
136 #define P_SLOPED_RIGHT                  (1 << E_P_SLOPED_RIGHT)
137 #define P_SLOPED_UP                     (1 << E_P_SLOPED_UP)
138 #define P_SLOPED_DOWN                   (1 << E_P_SLOPED_DOWN)
139
140 // flag to say "any direction"
141 #define P_SLOPED                        (P_SLOPED_LEFT  |               \
142                                          P_SLOPED_RIGHT |               \
143                                          P_SLOPED_UP    |               \
144                                          P_SLOPED_DOWN)
145
146 #define P_BLADDER_SLOPED                (1 << E_P_BLADDER_SLOPED)
147
148 #define P_AMOEBA_CONSUMES               (1 << E_P_AMOEBA_CONSUMES)
149 #define P_DIRT                          (1 << E_P_DIRT)
150 #define P_BLOWS_UP_FLIES                (1 << E_P_BLOWS_UP_FLIES)
151
152 #define P_EXPLODES_BY_HIT               (1 << E_P_EXPLODES_BY_HIT)
153 #define P_EXPLOSION                     (1 << E_P_EXPLOSION)
154 #define P_EXPLOSION_FIRST_STAGE         (1 << E_P_EXPLOSION_FIRST_STAGE)
155
156 #define P_NON_EXPLODABLE                (1 << E_P_NON_EXPLODABLE)
157 #define P_CCW                           (1 << E_P_CCW)
158 #define P_CAN_BE_HAMMERED               (1 << E_P_CAN_BE_HAMMERED)
159 #define P_VISUAL_EFFECT                 (1 << E_P_VISUAL_EFFECT)
160 #define P_PLAYER                        (1 << E_P_PLAYER)
161 #define P_MOVED_BY_CONVEYOR_TOP         (1 << E_P_MOVED_BY_CONVEYOR_TOP)
162 #define P_MOVED_BY_CONVEYOR_BOTTOM      (1 << E_P_MOVED_BY_CONVEYOR_BOTTOM)
163
164 #define P_WALKABLE                      (1 << E_P_WALKABLE)
165 #define P_DIGGABLE                      (1 << E_P_DIGGABLE)
166 #define P_COLLECTIBLE                   (1 << E_P_COLLECTIBLE)
167 #define P_PUSHABLE                      (1 << E_P_PUSHABLE)
168 #define P_CAN_MOVE                      (1 << E_P_CAN_MOVE)
169 #define P_CAN_FALL                      (1 << E_P_CAN_FALL)
170 #define P_FALLING                       (1 << E_P_FALLING)
171 #define P_GROWING                       (1 << E_P_GROWING)
172
173 // These are states of the magic wall.
174 typedef enum _magic_wall_state
175 {
176   GD_MW_DORMANT,                // Starting with this.
177   GD_MW_ACTIVE,                 // Boulder or diamond dropped into.
178   GD_MW_EXPIRED                 // Turned off after magic_wall_milling_time.
179 } GdMagicWallState;
180
181 // These are states of Player.
182 typedef enum _player_state
183 {
184   GD_PL_NOT_YET,                // Not yet living. Beginning of cave time.
185   GD_PL_LIVING,                 // Ok.
186   GD_PL_TIMEOUT,                // Time is up
187   GD_PL_DIED,                   // Died.
188   GD_PL_EXITED                  // Exited the cave, proceed to next one
189 } GdPlayerState;
190
191 // States of amoeba
192 typedef enum _amoeba_state
193 {
194   GD_AM_SLEEPING,               // sleeping - not yet let out.
195   GD_AM_AWAKE,                  // living, growing
196   GD_AM_TOO_BIG,                // grown too big, will convert to stones
197   GD_AM_ENCLOSED,               // enclosed, will convert to diamonds
198 } GdAmoebaState;
199
200 typedef enum _direction
201 {
202   // not moving
203   GD_MV_STILL           = 0,
204   GD_MV_THIS            = 0,
205
206   // directions
207   GD_MV_UP              = 1,
208   GD_MV_UP_RIGHT        = 2,
209   GD_MV_RIGHT           = 3,
210   GD_MV_DOWN_RIGHT      = 4,
211   GD_MV_DOWN            = 5,
212   GD_MV_DOWN_LEFT       = 6,
213   GD_MV_LEFT            = 7,
214   GD_MV_UP_LEFT         = 8,
215
216   // to be able to type GD_MV_TWICE + GD_MV_DOWN, for example
217   GD_MV_TWICE           = 8,
218
219   // directions * 2
220   GD_MV_UP_2            = 9,
221   GD_MV_UP_RIGHT_2      = 10,
222   GD_MV_RIGHT_2         = 11,
223   GD_MV_DOWN_RIGHT_2    = 12,
224   GD_MV_DOWN_2          = 13,
225   GD_MV_DOWN_LEFT_2     = 14,
226   GD_MV_LEFT_2          = 15,
227   GD_MV_UP_LEFT_2       = 16,
228
229   GD_MV_MAX,
230 } GdDirection;
231
232 enum
233 {
234   GD_REPLAY_MOVE_MASK    = 0x0f,
235   GD_REPLAY_FIRE_MASK    = 0x10,
236   GD_REPLAY_SUICIDE_MASK = 0x20,
237 };
238
239
240 // ELEMENTS DESCRIPTION
241 typedef struct _elements
242 {
243   GdElement element;            // element number. for example O_DIRT
244   char *name;                   // name in editor, for example "Dirt". some have
245                                 // different names than their real engine meaning!
246   unsigned int properties;      // engine properties, like P_SLOPED or P_EXPLODES
247   char *filename;               // name in bdcff file, like "DIRT"
248   char character;               // character representation in bdcff file, like '.'
249   int image;                    // image in editor (index in cells.png)
250   int image_simple;             // image in editor (index in cells.png) (simple view / combo box)
251   int image_game;               // image for game. negative if animated
252   int ckdelay;                  // ckdelay ratio - how much time required for a c64 to
253                                 // process this element - in microseconds.
254
255   char *lowercase_name;         // lowercase of translated name. for editor;
256                                 // generated inside the game.
257   char character_new;           // character given automatically for elements which
258                                 // don't have one defined in original bdcff description
259 } GdElements;
260
261
262 typedef char GdString[MAX_LINE_LEN];
263
264 typedef struct _highscore
265 {
266   GdString name;
267   int score;
268 } GdHighScore;
269
270 typedef struct _replay_movements
271 {
272   unsigned char data[MAX_REPLAY_LEN];
273   unsigned int len;
274 } GdReplayMovements;
275
276 // maximum seed value for the cave random generator. should be smaller than a signed int.
277 #define GD_CAVE_SEED_MAX        (1 << 30)
278
279 typedef struct _gd_cave_replay
280 {
281   int level;                    // replay for level n
282   unsigned int seed;            // seed the cave is to be rendered with
283   boolean saved;                // also store it in the saved bdcff
284   GdString recorded_with;       // recorded with - application name and version
285
286   GdString player_name;         // who played this
287   GdString date;                // when played
288   char *comment;                // some comments from the player
289
290   int score;                    // score collected
291   int duration;                 // number of seconds played
292   boolean success;              // successful playing of cave?
293   unsigned int checksum;        // checksum of the rendered cave.
294
295   boolean wrong_checksum;
296   GdReplayMovements *movements;
297   int current_playing_pos;
298 } GdReplay;
299
300 typedef enum _gd_scheduling
301 {
302   GD_SCHEDULING_MILLISECONDS,
303   GD_SCHEDULING_BD1,
304   GD_SCHEDULING_BD2,
305   GD_SCHEDULING_PLCK,
306   GD_SCHEDULING_CRDR,
307   GD_SCHEDULING_BD1_ATARI,
308   GD_SCHEDULING_BD2_PLCK_ATARI,
309   GD_SCHEDULING_MAX
310 } GdScheduling;
311
312 typedef struct _gd_c64_random_generator
313 {
314   int rand_seed_1, rand_seed_2;
315 } GdC64RandomGenerator;
316
317 // ----------------------------------------------------------------------------
318 // Structure holding all data belonging to a cave.
319 // ----------------------------------------------------------------------------
320
321 #define GD_HIGHSCORE_NUM 20
322
323 typedef struct _gd_cave
324 {
325   // Defined by the editor. public data :)
326   GdString name;                        // name of cave
327   GdString description;                 // some words about the cave
328   GdString author;                      // author
329   GdString difficulty;                  // difficulty of the game, for info purposes
330   GdString www;                         // link to author's webpage
331   GdString date;                        // date of creation
332   char *story;                          // story for the cave - will be shown when cave is played.
333   char *remark;                         // some note
334
335   GdString charset;                     // these are not used by gdash
336   GdString fontset;
337
338   // and this one the highscores
339   GdHighScore highscore[GD_HIGHSCORE_NUM];
340
341   HashTable *tags;                      // stores read-but-not-understood strings from bdcff,
342                                         // so we can save them later.
343
344   GdElement **map;                      // pointer to data for map, non-null if has a map
345   List *objects;
346   List *replays;
347
348   boolean intermission;                 // is this cave an intermission?
349   boolean intermission_instantlife;     // one life extra, if the intermission is reached
350   boolean intermission_rewardlife;      // one life extra, if the intermission is finished
351   boolean selectable;                   // is this selectable as an initial cave for a game?
352   boolean diagonal_movements;           // are diagonal movements allowed?
353   GdElement snap_element;               // snapping (press fire+move) usually leaves space behind,
354                                         // but can be other
355   boolean short_explosions;             // in >= 1stb, diamond/creature explosions were of 5 stages
356
357   GdScheduling scheduling;              // scheduling type; see above
358   boolean pal_timing;                   // use faster seconds
359
360   boolean active_is_first_found;        // active player is the uppermost.
361   boolean lineshift;                    // true is line shifting emulation,
362                                         // false is perfect borders emulation
363   boolean border_scan_first_and_last;   // if true, scans the first and last line of the border.
364                                         // false for plck
365   boolean wraparound_objects;           // if this is true, object drawing (cave rendering)
366                                         // will wraparound as well.
367
368   GdElement initial_fill;
369   GdElement initial_border;
370   GdElement random_fill[4];             // Random fill elements.
371   int random_fill_probability[4];       // Random fill, probability of each element.
372
373   int level_rand[5];                    // Random seed.
374   int level_diamonds[5];                // Must collect diamonds, on level x
375   int level_speed[5];                   // Time between game cycles in ms
376   int level_ckdelay[5];                 // Timing in original game units
377   int level_time[5];                    // Available time, per level
378   int level_timevalue[5];               // points for each second remaining, when exiting level
379
380   int max_time;                         // the maximum time in seconds. if above, it overflows
381
382   int w, h;                             // Sizes of cave, width and height.
383   int x1,y1,x2,y2;                      // Visible part of the cave
384   GdColor colorb;                       // border color
385   GdColor color0, color1, color2, color3, color4, color5;    // c64-style colors;
386                                                              // color 4 and 5 are amoeba and slime.
387
388   int diamond_value;                    // Score for a diamond.
389   int extra_diamond_value;              // Score for a diamond, when gate is open.
390
391   boolean stone_sound;
392   boolean nut_sound;
393   boolean diamond_sound;
394   boolean nitro_sound;
395   boolean falling_wall_sound;
396   boolean expanding_wall_sound;
397   boolean bladder_spender_sound;
398   boolean bladder_convert_sound;
399
400   int level_magic_wall_time[5];         // magic wall 'on' state for each level (seconds)
401   boolean magic_wall_stops_amoeba;      // Turning on magic wall changes amoeba to diamonds.
402                                         // Original BD: yes, constkit: no
403   boolean magic_wall_breakscan;         // Currently this setting enabled will turn the amoeba to
404                                         // an enclosed state. To implement buggy BD1 behaviour.
405   boolean magic_timer_zero_is_infinite; // magic wall timer 0 is interpreted as infinite
406   boolean magic_timer_wait_for_hatching;// magic wall timer does not start before player's birth
407   boolean magic_wall_sound;             // magic wall has sound
408
409   int level_amoeba_time[5];             // amoeba time for each level
410   int amoeba_growth_prob;               // Amoeba slow growth probability
411   int amoeba_fast_growth_prob;          // Amoeba fast growth probability
412   int level_amoeba_threshold[5];        // amoeba turns to stones; if count is bigger than this
413                                         // (number of cells)
414   GdElement amoeba_enclosed_effect;     // an enclosed amoeba converts to this element
415   GdElement amoeba_too_big_effect;      // an amoeba grown too big converts to this element
416
417   int level_amoeba_2_time[5];           // amoeba time for each level
418   int amoeba_2_growth_prob;             // Amoeba slow growth probability
419   int amoeba_2_fast_growth_prob;        // Amoeba fast growth probability
420   int level_amoeba_2_threshold[5];      // amoeba turns to stones; if count is bigger than this
421                                         // (number of cells)
422   GdElement amoeba_2_enclosed_effect;   // an enclosed amoeba converts to this element
423   GdElement amoeba_2_too_big_effect;    // an amoeba grown too big converts to this element
424   boolean amoeba_2_explodes_by_amoeba;  // amoeba 2 will explode if touched by amoeba1
425   GdElement amoeba_2_explosion_effect;  // amoeba 2 explosion ends in ...
426   GdElement amoeba_2_looks_like;        // an amoeba 2 looks like this element
427
428   boolean amoeba_timer_started_immediately; // FALSE: amoeba will start life at the first
429                                             //        possibility of growing.
430   boolean amoeba_timer_wait_for_hatching;   // amoeba timer does not start before player's birth
431   boolean amoeba_sound;                 // if the living amoeba has sound.
432
433   GdElement acid_eats_this;             // acid eats this element
434   int acid_spread_ratio;                // Probability of acid blowing up, each frame
435   boolean acid_spread_sound;            // acid has sound
436   GdElement acid_turns_to;              // whether acid converts to explosion on spreading or other
437
438   GdElement nut_turns_to_when_crushed;  // when nut is hit by stone, it converts to this element
439
440   int level_slime_permeability[5];      // true random slime
441   int level_slime_permeability_c64[5];  // Appearing in bd 2
442   int level_slime_seed_c64[5];          // predictable slime random seed
443   boolean slime_predictable;            // predictable random start for slime. yes for plck.
444   boolean slime_correct_random;         // correct random number generator for rendered caves
445   GdElement slime_eats_1, slime_converts_1; // slime eats element x and converts to element x;
446                                             // for example diamond -> falling diamond
447   GdElement slime_eats_2, slime_converts_2; // this is usually stone -> stone_f
448   GdElement slime_eats_3, slime_converts_3; // this is usually nut -> nut_f
449   boolean slime_sound;                  // slime has sound
450
451   boolean lava_sound;                   // elements sinking in lava have sound
452
453   int level_hatching_delay_frame[5];    // Scan frames before Player's birth.
454   int level_hatching_delay_time[5];     // Scan frames before Player's birth.
455
456   int level_bonus_time[5];              // bonus time for clock collected.
457   int level_penalty_time[5];            // Time penalty when voodoo destroyed.
458   boolean voodoo_collects_diamonds;     // Voodoo can collect diamonds
459   boolean voodoo_dies_by_stone;         // Voodoo can be killed by a falling stone
460   boolean voodoo_disappear_in_explosion;// Voodoo can be destroyed by and explosion
461   boolean voodoo_any_hurt_kills_player; // If any voodoo hurt in any way, player is killed.
462
463   boolean water_does_not_flow_down;     // if true, water will not grow downwards,
464                                         // only in other directions.
465   boolean water_sound;                  // water has sound
466
467   boolean bladder_sound;                // bladder moving and pushing has sound
468   GdElement bladder_converts_by;        // bladder converts to clock by touching this element
469
470   int biter_delay_frame;                // frame count biters do move
471   GdElement biter_eat;                  // biters eat this
472   boolean biter_sound;                  // biters have sound
473
474   boolean expanding_wall_changed;       // expanding wall direction is changed
475
476   int    replicator_delay_frame;        // replicator delay in frames (number of frames
477                                         // to wait between creating a new element)
478   boolean replicators_active;           // replicators are active.
479   boolean replicator_sound;             // when replicating an element, play sound or not.
480
481   boolean conveyor_belts_active;
482   boolean conveyor_belts_direction_changed;
483
484   // effects
485   GdElement explosion_effect;           // explosion converts to this element after its last stage.
486                                         // diego effect.
487   GdElement diamond_birth_effect;       // a diamond birth converts to this element after its last
488                                         // stage. diego effect.
489   GdElement bomb_explosion_effect;      // bombs explode to this element. diego effect (almost).
490   GdElement nitro_explosion_effect;     // nitros explode to this
491
492   GdElement firefly_explode_to;         // fireflies explode to this when hit by stone
493   GdElement alt_firefly_explode_to;     // alternative fireflies explode to this when hit by stone
494   GdElement butterfly_explode_to;       // butterflies explode to this when hit by stone
495   GdElement alt_butterfly_explode_to;   // alternative butterflies explode to this when hit by stone
496   GdElement stonefly_explode_to;        // stoneflies explode to this when hit by stone
497   GdElement dragonfly_explode_to;       // dragonflies explode to this when hit by stone
498
499   GdElement stone_falling_effect;       // falling stone converts to this element. diego effect.
500   GdElement diamond_falling_effect;     // falling diamond converts to this element. diego effect.
501   GdElement stone_bouncing_effect;      // bouncing stone converts to this element. diego effect.
502   GdElement diamond_bouncing_effect;    // bouncing diamond converts to this element. diego effect.
503
504   GdElement expanding_wall_looks_like;  // an expanding wall looks like this element. diego effect.
505   GdElement dirt_looks_like;            // dirt looks like this element. diego effect.
506
507   GdElement magic_stone_to;             // magic wall converts falling stone to
508   GdElement magic_diamond_to;           // magic wall converts falling diamond to
509   GdElement magic_mega_stone_to;        // magic wall converts a falling mega stone to
510   GdElement magic_nitro_pack_to;        // magic wall converts a falling nitro pack to
511   GdElement magic_nut_to;               // magic wall converts a falling nut to
512   GdElement magic_flying_stone_to;      // flying stones are converted to
513   GdElement magic_flying_diamond_to;    // flying diamonds are converted to
514
515   int pushing_stone_prob;               // probability of pushing stone
516   int pushing_stone_prob_sweet;         // probability of pushing, after eating sweet
517   boolean mega_stones_pushable_with_sweet; // mega stones may be pushed with sweet
518
519   boolean creatures_backwards;          // creatures changed direction
520   boolean creatures_direction_auto_change_on_start; // the change occurs also at the start signal
521   int creatures_direction_auto_change_time; // creatures automatically change direction every x
522                                             // seconds
523   boolean creature_direction_auto_change_sound; // automatically changing creature direction may
524                                                 // have the sound of the creature dir switch
525
526   int skeletons_needed_for_pot;         // how many skeletons to be collected, to use a pot
527   int skeletons_worth_diamonds;         // for crazy dream 7 compatibility: collecting skeletons
528                                         // might open the cave door.
529
530   GdDirection gravity;
531   int gravity_change_time;
532   boolean gravity_change_sound;
533   boolean gravity_affects_all;          // if true, gravity also affects falling wall, bladder
534                                         // and waiting stones
535   boolean gravity_switch_active;        // true if gravity switch is activated, and can be used.
536
537   boolean hammered_walls_reappear;
538   int pneumatic_hammer_frame;
539   int hammered_wall_reappear_frame;
540   boolean pneumatic_hammer_sound;
541
542   boolean infinite_rockets;             // if true, the player which got a rocket launcher will be
543                                         // able to launch an infinite number of rockets
544
545   // internal variables, used during the game. private data :)
546
547   // returns range corrected x/y position (points to perfect or line shifting get function)
548   int (*getx) (const struct _gd_cave*, int x, int y);
549   int (*gety) (const struct _gd_cave*, int x, int y);
550
551   // returns pointer to element at x, y (points to perfect border or a line shifting get function)
552   GdElement* (*getp) (const struct _gd_cave*, int x, int y);
553
554   boolean hatched;                      // hatching has happened. (timers may run, ...)
555   boolean gate_open;                    // self-explaining
556   unsigned int render_seed;             // the seed value, which was used to render the cave,
557                                         // is saved here. will be used by record&playback
558   GdRand *random;                       // random number generator of rendered cave
559   int rendered;                         // if not zero, rendered at level x
560   int timing_factor;                    // number of "milliseconds" in each second :)
561                                         // 1000 for ntsc, 1200 for pal.
562   void ***objects_order;                // two-dimensional map of cave; each cell is a pointer
563                                         // to the drawing object, which created this element.
564                                         // NULL if map or random.
565   int **hammered_reappear;              // integer map of cave; if non-zero, a brick wall will
566                                         // appear there
567
568   int speed;                            // Time between game cycles in ms
569   int c64_timing;                       // a ckdelay value for the level this cave is rendered for
570   int ckdelay;                          // ckdelay value for the current iteration
571   int ckdelay_extra_for_animation;      // bd1 and similar engines had animation bits in cave data,
572                                         // to set which elements to animate (firefly, butterfly,
573                                         // amoeba).
574                                         // animating an element also caused some delay each frame;
575                                         //  according to my measurements, around 2.6 ms/element.
576
577   int frame;  // XXX
578
579   int hatching_delay_frame;
580   int hatching_delay_time;
581   int time_bonus;                       // bonus time for clock collected.
582   int time_penalty;                     // Time penalty when voodoo destroyed.
583   int time;                             // milliseconds remaining to finish cave
584   int timevalue;                        // points for remaining seconds - for current level
585   int diamonds_needed;                  // diamonds needed to open outbox
586   int diamonds_collected;               // diamonds collected
587   int skeletons_collected;              // number of skeletons collected
588   int gate_open_flash;                  // flashing of screen when gate opens
589   int score;                            // Score got this frame.
590   int amoeba_time;                      // Amoeba growing slow (low probability, default 3%) for
591                                         // milliseconds. After that, fast growth default (25%)
592   int amoeba_2_time;                    // Amoeba growing slow (low probability, default 3%) for
593                                         // milliseconds. After that, fast growth default (25%)
594   int amoeba_max_count;                 // selected amoeba 1 threshold for this level
595   int amoeba_2_max_count;               // selected amoeba 2 threshold for this level
596   GdAmoebaState amoeba_state;           // state of amoeba 1
597   GdAmoebaState amoeba_2_state;         // state of amoeba 2
598   boolean convert_amoeba_this_frame;    // To implement BD1 buggy amoeba+magic wall behaviour.
599   int magic_wall_time;                  // magic wall 'on' state for seconds
600   int slime_permeability;               // true random slime
601   int slime_permeability_c64;           // Appearing in bd 2
602   GdMagicWallState magic_wall_state;    // State of magic wall
603   GdPlayerState player_state;           // Player state. not yet living, living, exited...
604   int player_seen_ago;                  // player was seen this number of scans ago
605   boolean voodoo_touched;               // as its name says
606   boolean kill_player;                  // Voodoo died, or used pressed escape to restart level.
607   boolean sweet_eaten;                  // player ate sweet, he's strong. prob_sweet applies,
608                                         // and also able to push chasing stones
609   int player_x, player_y;               // Coordinates of player (for scrolling)
610   int px[16], py[16];                   // coordinates of player, for chasing stone
611   int key1, key2, key3;                 // The player is holding this number of keys of each color
612   boolean diamond_key_collected;        // Key collected, so trapped diamonds convert to diamonds
613   boolean inbox_flash_toggle;           // negated every scan. helps drawing inboxes, and making
614                                         // players be born at different times.
615   GdDirection last_direction;           // last direction player moved. used by draw routines
616   GdDirection last_horizontal_direction;
617   int biters_wait_frame;                // number of frames to wait until biters will move again
618   int replicators_wait_frame;           // number of frames to wait until replicators are
619                                         // activated again
620   int creatures_direction_will_change;  // creatures automatically change direction every x seconds
621   GdC64RandomGenerator c64_rand;        // used for predictable random generator during the game.
622
623   int gravity_will_change;              // gravity will change in this number of milliseconds
624   boolean gravity_disabled;             // when player is stirring the pot, there is no gravity.
625   GdDirection gravity_next_direction;   // next direction when the gravity changes.
626                                         // will be set by the player "getting" a gravity switch
627   boolean got_pneumatic_hammer;         // true if the player has a pneumatic hammer
628   int pneumatic_hammer_active_delay;    // number of frames to wait, till pneumatic hammer will
629                                         // destroy the wall
630   GdSound sound1, sound2, sound3;       // sound set for 3 channels after each iteration
631 } GdCave;
632
633
634 #define CAVE_OFFSET(property) (STRUCT_OFFSET(GdCave, property))
635
636 // arrays for movements
637 // also no1 and bd2 cave data import helpers; line direction coordinates
638 extern const int gd_dx[], gd_dy[];
639
640 extern GdElement gd_char_to_element[];
641
642 void gd_create_char_to_element_table(void);
643 GdElement gd_get_element_from_character(unsigned char character);
644 GdElement gd_get_element_from_string(const char *string);
645
646 // init cave engine
647 void gd_cave_init(void);
648
649 // for cave tags hash table
650 int gd_str_case_equal(void *s1, void *s2);
651 unsigned int gd_str_case_hash(void *v);
652
653 // cave highscore functions
654 int gd_highscore_compare(const void *a, const void *b);
655 boolean gd_is_highscore(GdHighScore *scores, int score);
656 int gd_add_highscore(GdHighScore *highscores, const char *name, int score);
657 void gd_clear_highscore(GdHighScore *hs);
658 boolean gd_has_highscore(GdHighScore *hs);
659
660 // cave creator and destructor functions
661 GdCave *gd_cave_new(void);
662 GdCave *gd_cave_new_from_cave(const GdCave *orig);
663 void gd_cave_copy(GdCave *dest, const GdCave *src);
664 void gd_cave_free(GdCave *cave);
665
666 // cave manipulation
667 void gd_cave_set_gdash_defaults(GdCave *cave);
668 void gd_cave_set_defaults_from_array(GdCave* cave, GdPropertyDefault *defaults);
669 void gd_cave_correct_visible_size(GdCave *cave);
670 void gd_cave_set_random_colors(GdCave *cave, GdColorType type);
671 void gd_cave_auto_shrink(GdCave *cave);
672
673 void gd_cave_setup_for_game(GdCave *cave);
674 void gd_cave_count_diamonds(GdCave *cave);
675
676 // c64 random generator support for cave fill
677 unsigned int gd_c64_random(GdC64RandomGenerator *rand);
678 unsigned int gd_cave_c64_random(GdCave *);
679 void gd_c64_random_set_seed(GdC64RandomGenerator *rand, int seed1, int seed2);
680 void gd_cave_c64_random_set_seed(GdCave *cave, int seed1, int seed2);
681 void gd_cave_set_random_c64_colors(GdCave *cave);
682
683 // support
684 void *gd_cave_map_new_for_cave(const GdCave *cave, const int cell_size);
685 void *gd_cave_map_dup_size(const GdCave * cave, const void *map, const int cell_size);
686 #define gd_cave_map_new(CAVE, TYPE) ((TYPE **)gd_cave_map_new_for_cave((CAVE), sizeof(TYPE)))
687 #define gd_cave_map_dup(CAVE, MAP) ((void *)gd_cave_map_dup_size((CAVE), (void **)(CAVE)->MAP, sizeof((CAVE)->MAP[0][0])))
688 void gd_cave_map_free(void *map);
689
690 void gd_cave_store_rc(GdCave * cave, int x, int y, const GdElement element, const void* order);
691 GdElement gd_cave_get_rc (const GdCave *cave, int x, int y);
692
693 // direction
694 const char *gd_direction_get_visible_name(GdDirection dir);
695 const char *gd_direction_get_filename(GdDirection dir);
696 GdDirection gd_direction_from_string(const char *str);
697
698 // scheduling
699 const char *gd_scheduling_get_visible_name(GdScheduling sched);
700 const char *gd_scheduling_get_filename(GdScheduling sched);
701 GdScheduling gd_scheduling_from_string(const char *str);
702
703 // game playing helpers
704 #define GD_REDRAW (1 << 10)
705
706 void gd_drawcave_game(const GdCave *cave,
707                       int **element_buffer, int **last_element_buffer, int **gfx_buffer,
708                       boolean bonus_life_flash, int animcycle, boolean hate_invisible_outbox);
709
710 // function to copy a GdString
711 static inline char *gd_strcpy(GdString dest, const GdString src)
712 {
713     return strncpy(dest, src, sizeof(GdString));
714 }
715
716 int gd_cave_time_show(const GdCave *cave, int internal_time);
717
718 GdReplay *gd_replay_new(void);
719 GdReplay *gd_replay_new_from_replay(GdReplay *orig);
720 void gd_replay_free(GdReplay *replay);
721 void gd_replay_store_movement(GdReplay *replay, GdDirection player_move, boolean player_fire, boolean suicide);
722
723 unsigned int gd_cave_adler_checksum(GdCave *cave);
724 void gd_cave_adler_checksum_more(GdCave *cave, unsigned int *a, unsigned int *b);
725
726 boolean gd_cave_has_levels(GdCave *cave);
727 boolean gd_caveset_has_levels(void);
728
729 #endif  // BD_CAVE_H