2 * Copyright (c) 2007, 2008, 2009, Czirkos Zoltan <cirix@fw.hu>
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.
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.
20 #include "bd_elements.h"
21 #include "bd_colors.h"
22 #include "bd_random.h"
25 // ============================================================================
26 // BIG STRUCT HANDLING
27 // ============================================================================
29 // possible types handled
32 // not real types, only used by editor to build ui
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
43 GD_TYPE_PROBABILITY, // probabilities are stored in parts per million,
44 // ie. *1E6, converted to int.
51 enum _gd_property_flags
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,
60 typedef struct _gd_struct_descriptor
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
72 typedef struct _gd_property_default
74 int offset; // data offset (bytes) in a cave structure
75 int defval; // default value, converted to int. if type is a float, *1000000
77 int property_index; // index in gd_cave_properties; created at runtime
81 void gd_struct_set_defaults_from_array(void *str, const GdStructDescriptor *properties, GdPropertyDefault *defaults);
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
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)
91 // maximum replay size (maximum seconds x game cycles per second)
92 #define MAX_REPLAY_LEN (10000 * FRAMES_PER_SECOND / 8)
94 extern const GdColor gd_flash_color;
95 extern const GdColor gd_select_color;
97 enum _element_property
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
103 E_P_BLADDER_SLOPED, // element act sloped also for the bladder
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
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
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
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)
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)
140 // flag to say "any direction"
141 #define P_SLOPED (P_SLOPED_LEFT | \
146 #define P_BLADDER_SLOPED (1 << E_P_BLADDER_SLOPED)
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)
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)
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)
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)
173 // These are states of the magic wall.
174 typedef enum _magic_wall_state
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.
181 // These are states of Player.
182 typedef enum _player_state
184 GD_PL_NOT_YET, // Not yet living. Beginning of cave time.
186 GD_PL_TIMEOUT, // Time is up
188 GD_PL_EXITED // Exited the cave, proceed to next one
192 typedef enum _amoeba_state
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
200 typedef enum _direction
210 GD_MV_DOWN_RIGHT = 4,
216 // to be able to type GD_MV_TWICE + GD_MV_DOWN, for example
221 GD_MV_UP_RIGHT_2 = 10,
223 GD_MV_DOWN_RIGHT_2 = 12,
225 GD_MV_DOWN_LEFT_2 = 14,
227 GD_MV_UP_LEFT_2 = 16,
234 GD_REPLAY_MOVE_MASK = 0x0f,
235 GD_REPLAY_FIRE_MASK = 0x10,
236 GD_REPLAY_SUICIDE_MASK = 0x20,
240 // ELEMENTS DESCRIPTION
241 typedef struct _elements
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.
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
262 typedef char GdString[MAX_LINE_LEN];
264 typedef struct _highscore
270 typedef struct _replay_movements
272 unsigned char data[MAX_REPLAY_LEN];
276 // maximum seed value for the cave random generator. should be smaller than a signed int.
277 #define GD_CAVE_SEED_MAX (1 << 30)
279 typedef struct _gd_cave_replay
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
286 GdString player_name; // who played this
287 GdString date; // when played
288 char *comment; // some comments from the player
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.
295 boolean wrong_checksum;
296 GdReplayMovements *movements;
297 int current_playing_pos;
300 typedef enum _gd_scheduling
302 GD_SCHEDULING_MILLISECONDS,
307 GD_SCHEDULING_BD1_ATARI,
308 GD_SCHEDULING_BD2_PLCK_ATARI,
312 typedef struct _gd_c64_random_generator
314 int rand_seed_1, rand_seed_2;
315 } GdC64RandomGenerator;
317 // ----------------------------------------------------------------------------
318 // Structure holding all data belonging to a cave.
319 // ----------------------------------------------------------------------------
321 #define GD_HIGHSCORE_NUM 20
323 typedef struct _gd_cave
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
335 GdString charset; // these are not used by gdash
338 // and this one the highscores
339 GdHighScore highscore[GD_HIGHSCORE_NUM];
341 HashTable *tags; // stores read-but-not-understood strings from bdcff,
342 // so we can save them later.
344 GdElement **map; // pointer to data for map, non-null if has a map
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,
355 boolean short_explosions; // in >= 1stb, diamond/creature explosions were of 5 stages
357 GdScheduling scheduling; // scheduling type; see above
358 boolean pal_timing; // use faster seconds
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.
365 boolean wraparound_objects; // if this is true, object drawing (cave rendering)
366 // will wraparound as well.
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.
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
380 int max_time; // the maximum time in seconds. if above, it overflows
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.
388 int diamond_value; // Score for a diamond.
389 int extra_diamond_value; // Score for a diamond, when gate is open.
393 boolean diamond_sound;
395 boolean falling_wall_sound;
396 boolean expanding_wall_sound;
397 boolean bladder_spender_sound;
398 boolean bladder_convert_sound;
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
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
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
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
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
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.
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
438 GdElement nut_turns_to_when_crushed; // when nut is hit by stone, it converts to this element
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
451 boolean lava_sound; // elements sinking in lava have sound
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.
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.
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
467 boolean bladder_sound; // bladder moving and pushing has sound
468 GdElement bladder_converts_by; // bladder converts to clock by touching this element
470 int biter_delay_frame; // frame count biters do move
471 GdElement biter_eat; // biters eat this
472 boolean biter_sound; // biters have sound
474 boolean expanding_wall_changed; // expanding wall direction is changed
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.
481 boolean conveyor_belts_active;
482 boolean conveyor_belts_direction_changed;
485 GdElement explosion_effect; // explosion converts to this element after its last stage.
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
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
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.
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.
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
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
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
523 boolean creature_direction_auto_change_sound; // automatically changing creature direction may
524 // have the sound of the creature dir switch
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.
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.
537 boolean hammered_walls_reappear;
538 int pneumatic_hammer_frame;
539 int hammered_wall_reappear_frame;
540 boolean pneumatic_hammer_sound;
542 boolean infinite_rockets; // if true, the player which got a rocket launcher will be
543 // able to launch an infinite number of rockets
545 // internal variables, used during the game. private data :)
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);
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);
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
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,
574 // animating an element also caused some delay each frame;
575 // according to my measurements, around 2.6 ms/element.
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
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.
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
630 GdSound sound1, sound2, sound3; // sound set for 3 channels after each iteration
634 #define CAVE_OFFSET(property) (STRUCT_OFFSET(GdCave, property))
636 // arrays for movements
637 // also no1 and bd2 cave data import helpers; line direction coordinates
638 extern const int gd_dx[], gd_dy[];
640 extern GdElement gd_char_to_element[];
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);
647 void gd_cave_init(void);
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);
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);
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);
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);
673 void gd_cave_setup_for_game(GdCave *cave);
674 void gd_cave_count_diamonds(GdCave *cave);
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);
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);
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);
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);
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);
703 // game playing helpers
704 #define GD_REDRAW (1 << 10)
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);
710 // function to copy a GdString
711 static inline char *gd_strcpy(GdString dest, const GdString src)
713 return strncpy(dest, src, sizeof(GdString));
716 int gd_cave_time_show(const GdCave *cave, int internal_time);
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);
723 unsigned int gd_cave_adler_checksum(GdCave *cave);
724 void gd_cave_adler_checksum_more(GdCave *cave, unsigned int *a, unsigned int *b);
726 boolean gd_cave_has_levels(GdCave *cave);
727 boolean gd_caveset_has_levels(void);