2009050
[gdash.git] / src / cave.h
blob7ed6e206559a4b3b29be1a94563d82982a6a7492
1 /*
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.
16 #ifndef _GD_CAVE_H
17 #define _GD_CAVE_H
19 #include <glib.h>
21 #include "config.h"
22 #include "colors.h"
25 /******************************************
27 * BIG STRUCT HANDLING
30 /* possible types handled */
31 typedef enum _gd_type {
32 /* not real types, only used by editor to build ui */
33 GD_TAB,
34 GD_LABEL,
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,
44 GD_TYPE_COLOR,
45 GD_TYPE_EFFECT,
46 GD_TYPE_DIRECTION,
47 GD_TYPE_SCHEDULING,
48 } GdType;
50 enum _gd_property_flags {
51 GD_ALWAYS_SAVE=1<<0,
52 GD_DONT_SAVE=1<<1,
53 GD_DONT_SHOW_IN_EDITOR=1<<2,
54 GD_SHOW_LEVEL_LABEL=1<<3,
55 GD_COMPATIBILITY_SETTING=1<<4,
58 typedef struct _gd_struct_descriptor {
59 char *identifier; /* bdcff identifier */
60 GdType type; /* data type */
61 int flags; /* flags for bdcff saving/loading */
62 char *name; /* name in editor */
63 int offset; /* byte offset in a GdCave structure. use the CAVE_OFFSET macro */
64 int count; /* size of array; usually 1, for non-arrays. */
65 char *tooltip; /* tooltip text in editor */
66 int min, max; /* integers have minimum and maximum */
67 } GdStructDescriptor;
69 typedef struct _gd_property_default {
70 int offset; /* data offset (bytes) in a cave structure */
71 int defval; /* default value, converted to int. if type is a float, *1000000 */
73 int property_index; /* index in gd_cave_properties; created at runtime */
74 } GdPropertyDefault;
78 /* these define the number of the cells in the png file */
79 #define NUM_OF_CELLS_X 8
80 #define NUM_OF_CELLS_Y 46
82 /* +74: placeholder for cells which are rendered by the game; for example diamond+arrow = falling diamond */
83 #define NUM_OF_CELLS (NUM_OF_CELLS_X*NUM_OF_CELLS_Y+80)
88 extern const GdColor gd_flash_color;
89 extern const GdColor gd_select_color;
100 /* These are the objects in caves. */
101 typedef enum _element {
102 O_SPACE,
103 O_DIRT,
104 O_DIRT_SLOPED_UP_RIGHT,
105 O_DIRT_SLOPED_UP_LEFT,
106 O_DIRT_SLOPED_DOWN_LEFT,
107 O_DIRT_SLOPED_DOWN_RIGHT,
108 O_DIRT_BALL,
109 O_DIRT_BALL_F,
110 O_DIRT_LOOSE,
111 O_DIRT_LOOSE_F,
112 O_DIRT2,
113 O_BRICK,
114 O_BRICK_SLOPED_UP_RIGHT,
115 O_BRICK_SLOPED_UP_LEFT,
116 O_BRICK_SLOPED_DOWN_LEFT,
117 O_BRICK_SLOPED_DOWN_RIGHT,
118 O_BRICK_NON_SLOPED,
119 O_MAGIC_WALL,
120 O_PRE_OUTBOX,
121 O_OUTBOX,
122 O_PRE_INVIS_OUTBOX,
123 O_INVIS_OUTBOX,
124 O_STEEL,
125 O_STEEL_SLOPED_UP_RIGHT,
126 O_STEEL_SLOPED_UP_LEFT,
127 O_STEEL_SLOPED_DOWN_LEFT,
128 O_STEEL_SLOPED_DOWN_RIGHT,
129 O_STEEL_EXPLODABLE,
130 O_STEEL_EATABLE,
131 O_BRICK_EATABLE,
132 O_STONE,
133 O_STONE_F,
134 O_FLYING_STONE,
135 O_FLYING_STONE_F,
136 O_MEGA_STONE,
137 O_MEGA_STONE_F,
138 O_DIAMOND,
139 O_DIAMOND_F,
140 O_FLYING_DIAMOND,
141 O_FLYING_DIAMOND_F,
142 O_NUT,
143 O_NUT_F,
144 O_BLADDER_SPENDER,
145 O_INBOX,
146 O_H_EXPANDING_WALL,
147 O_V_EXPANDING_WALL,
148 O_EXPANDING_WALL,
149 O_H_EXPANDING_STEEL_WALL,
150 O_V_EXPANDING_STEEL_WALL,
151 O_EXPANDING_STEEL_WALL,
152 O_EXPANDING_WALL_SWITCH,
153 O_CREATURE_SWITCH,
154 O_BITER_SWITCH,
155 O_REPLICATOR_SWITCH,
156 O_CONVEYOR_SWITCH,
157 O_CONVEYOR_DIR_SWITCH,
158 O_ACID,
159 O_FALLING_WALL,
160 O_FALLING_WALL_F,
161 O_BOX,
162 O_TIME_PENALTY,
163 O_GRAVESTONE,
164 O_STONE_GLUED,
165 O_DIAMOND_GLUED,
166 O_DIAMOND_KEY,
167 O_TRAPPED_DIAMOND,
168 O_CLOCK,
169 O_DIRT_GLUED,
170 O_KEY_1,
171 O_KEY_2,
172 O_KEY_3,
173 O_DOOR_1,
174 O_DOOR_2,
175 O_DOOR_3,
177 O_POT,
178 O_GRAVITY_SWITCH,
179 O_PNEUMATIC_HAMMER,
180 O_TELEPORTER,
181 O_SKELETON,
182 O_WATER,
183 O_WATER_1,
184 O_WATER_2,
185 O_WATER_3,
186 O_WATER_4,
187 O_WATER_5,
188 O_WATER_6,
189 O_WATER_7,
190 O_WATER_8,
191 O_WATER_9,
192 O_WATER_10,
193 O_WATER_11,
194 O_WATER_12,
195 O_WATER_13,
196 O_WATER_14,
197 O_WATER_15,
198 O_WATER_16,
199 O_COW_1,
200 O_COW_2,
201 O_COW_3,
202 O_COW_4,
203 O_COW_ENCLOSED_1,
204 O_COW_ENCLOSED_2,
205 O_COW_ENCLOSED_3,
206 O_COW_ENCLOSED_4,
207 O_COW_ENCLOSED_5,
208 O_COW_ENCLOSED_6,
209 O_COW_ENCLOSED_7,
210 O_WALLED_DIAMOND,
211 O_WALLED_KEY_1,
212 O_WALLED_KEY_2,
213 O_WALLED_KEY_3,
215 O_AMOEBA,
216 O_AMOEBA_2,
217 O_REPLICATOR,
218 O_CONVEYOR_LEFT,
219 O_CONVEYOR_RIGHT,
220 O_LAVA,
221 O_SWEET,
222 O_VOODOO,
223 O_SLIME,
224 O_BLADDER,
225 O_BLADDER_1,
226 O_BLADDER_2,
227 O_BLADDER_3,
228 O_BLADDER_4,
229 O_BLADDER_5,
230 O_BLADDER_6,
231 O_BLADDER_7,
232 O_BLADDER_8,
234 O_WAITING_STONE,
235 O_CHASING_STONE,
236 O_GHOST,
237 O_FIREFLY_1,
238 O_FIREFLY_2,
239 O_FIREFLY_3,
240 O_FIREFLY_4,
241 O_ALT_FIREFLY_1,
242 O_ALT_FIREFLY_2,
243 O_ALT_FIREFLY_3,
244 O_ALT_FIREFLY_4,
245 O_BUTTER_1,
246 O_BUTTER_2,
247 O_BUTTER_3,
248 O_BUTTER_4,
249 O_ALT_BUTTER_1,
250 O_ALT_BUTTER_2,
251 O_ALT_BUTTER_3,
252 O_ALT_BUTTER_4,
253 O_STONEFLY_1,
254 O_STONEFLY_2,
255 O_STONEFLY_3,
256 O_STONEFLY_4,
257 O_BITER_1,
258 O_BITER_2,
259 O_BITER_3,
260 O_BITER_4,
261 O_DRAGONFLY_1,
262 O_DRAGONFLY_2,
263 O_DRAGONFLY_3,
264 O_DRAGONFLY_4,
266 O_PRE_PL_1,
267 O_PRE_PL_2,
268 O_PRE_PL_3,
269 O_PLAYER,
270 O_PLAYER_BOMB,
271 O_PLAYER_GLUED,
272 O_PLAYER_STIRRING,
274 O_BOMB,
275 O_BOMB_TICK_1,
276 O_BOMB_TICK_2,
277 O_BOMB_TICK_3,
278 O_BOMB_TICK_4,
279 O_BOMB_TICK_5,
280 O_BOMB_TICK_6,
281 O_BOMB_TICK_7,
283 O_NITRO_PACK,
284 O_NITRO_PACK_F,
285 O_NITRO_PACK_EXPLODE,
287 O_PRE_CLOCK_1,
288 O_PRE_CLOCK_2,
289 O_PRE_CLOCK_3,
290 O_PRE_CLOCK_4,
291 O_PRE_DIA_1,
292 O_PRE_DIA_2,
293 O_PRE_DIA_3,
294 O_PRE_DIA_4,
295 O_PRE_DIA_5,
296 O_EXPLODE_1,
297 O_EXPLODE_2,
298 O_EXPLODE_3,
299 O_EXPLODE_4,
300 O_EXPLODE_5,
301 O_PRE_STONE_1,
302 O_PRE_STONE_2,
303 O_PRE_STONE_3,
304 O_PRE_STONE_4,
305 O_PRE_STEEL_1,
306 O_PRE_STEEL_2,
307 O_PRE_STEEL_3,
308 O_PRE_STEEL_4,
309 O_GHOST_EXPL_1,
310 O_GHOST_EXPL_2,
311 O_GHOST_EXPL_3,
312 O_GHOST_EXPL_4,
313 O_BOMB_EXPL_1,
314 O_BOMB_EXPL_2,
315 O_BOMB_EXPL_3,
316 O_BOMB_EXPL_4,
317 O_NITRO_EXPL_1,
318 O_NITRO_EXPL_2,
319 O_NITRO_EXPL_3,
320 O_NITRO_EXPL_4,
321 O_AMOEBA_2_EXPL_1,
322 O_AMOEBA_2_EXPL_2,
323 O_AMOEBA_2_EXPL_3,
324 O_AMOEBA_2_EXPL_4,
325 O_NUT_EXPL_1,
326 O_NUT_EXPL_2,
327 O_NUT_EXPL_3,
328 O_NUT_EXPL_4,
330 /* these are used internally for the pneumatic hammer, and should not be used in the editor! */
331 /* (not even as an effect destination or something like that) */
332 O_PLAYER_PNEUMATIC_LEFT,
333 O_PLAYER_PNEUMATIC_RIGHT,
334 O_PNEUMATIC_ACTIVE_LEFT,
335 O_PNEUMATIC_ACTIVE_RIGHT,
337 O_UNKNOWN, /* unknown element imported or read from bdcff */
338 O_NONE, /* do not draw this element when creating cave; can be used, for example, to skip drawing a maze's path */
340 O_MAX, /* remembering last index: this should get an integer value which is 1 more than the one above. */
342 /* fake elements to help drawing */
343 O_FAKE_BONUS,
344 O_OUTBOX_CLOSED,
345 O_OUTBOX_OPEN,
346 O_COVERED,
347 O_PLAYER_LEFT,
348 O_PLAYER_RIGHT,
349 O_PLAYER_TAP,
350 O_PLAYER_BLINK,
351 O_PLAYER_TAP_BLINK,
352 O_CREATURE_SWITCH_ON,
353 O_EXPANDING_WALL_SWITCH_HORIZ,
354 O_EXPANDING_WALL_SWITCH_VERT,
355 O_GRAVITY_SWITCH_ACTIVE,
356 O_REPLICATOR_SWITCH_ON,
357 O_REPLICATOR_SWITCH_OFF,
358 O_CONVEYOR_DIR_NORMAL,
359 O_CONVEYOR_DIR_CHANGED,
360 O_CONVEYOR_SWITCH_OFF,
361 O_CONVEYOR_SWITCH_ON,
363 O_QUESTION_MARK,
364 O_EATABLE,
365 O_DOWN_ARROW,
366 O_LEFTRIGHT_ARROW,
367 O_EVERYDIR_ARROW,
368 O_GLUED,
369 O_OUT,
370 O_EXCLAMATION_MARK,
372 SCANNED=0x100,
373 COVERED=0x200,
375 /* binary AND this to elements to get rid of properties above. */
376 O_MASK = ~(SCANNED | COVERED)
377 } GdElement;
381 enum _element_property {
382 E_P_SLOPED_LEFT, /* stones and diamonds roll down to left on this */
383 E_P_SLOPED_RIGHT, /* stones and diamonds roll down to right on this */
384 E_P_SLOPED_UP,
385 E_P_SLOPED_DOWN,
386 E_P_BLADDER_SLOPED, /* element act sloped also for the bladder */
388 E_P_AMOEBA_CONSUMES, /* amoeba can eat this */
389 E_P_DIRT, /* it is dirt, or something similar (dirt2 or sloped dirt) */
390 E_P_BLOWS_UP_FLIES, /* flies blow up, if they touch this */
391 E_P_EXPLODES_BY_HIT, /* explodes if hit by a stone */
393 E_P_EXPLOSION_FIRST_STAGE, /* set for first stage of every explosion. helps slower/faster explosions changing */
395 E_P_NON_EXPLODABLE, /* selfexplaining */
396 E_P_CCW, /* this creature has a default counterclockwise rotation (for example, o_fire_1) */
397 E_P_CAN_BE_HAMMERED, /* can be broken by pneumatic hammer */
398 E_P_VISUAL_EFFECT, /* if the element can use a visual effect. used to check consistency of the code */
399 E_P_PLAYER, /* easier to find out if it is a player element */
400 E_P_MOVED_BY_CONVEYOR_TOP, /* can be moved by conveyor belt */
401 E_P_MOVED_BY_CONVEYOR_BOTTOM, /* can be moved UNDER the conveyor belt */
404 /* properties */
405 #define P_SLOPED_LEFT (1<<E_P_SLOPED_LEFT)
406 #define P_SLOPED_RIGHT (1<<E_P_SLOPED_RIGHT)
407 #define P_SLOPED_UP (1<<E_P_SLOPED_UP)
408 #define P_SLOPED_DOWN (1<<E_P_SLOPED_DOWN)
409 /* flag to say "any direction" */
410 #define P_SLOPED (P_SLOPED_LEFT|P_SLOPED_RIGHT|P_SLOPED_UP|P_SLOPED_DOWN)
411 #define P_BLADDER_SLOPED (1<<E_P_BLADDER_SLOPED)
413 #define P_AMOEBA_CONSUMES (1<<E_P_AMOEBA_CONSUMES)
414 #define P_DIRT (1<<E_P_DIRT)
415 #define P_BLOWS_UP_FLIES (1<<E_P_BLOWS_UP_FLIES)
417 #define P_EXPLODES_BY_HIT (1<<E_P_EXPLODES_BY_HIT)
418 #define P_EXPLOSION_FIRST_STAGE (1<<E_P_EXPLOSION_FIRST_STAGE)
420 #define P_NON_EXPLODABLE (1<<E_P_NON_EXPLODABLE)
421 #define P_CCW (1<<E_P_CCW)
422 #define P_CAN_BE_HAMMERED (1<<E_P_CAN_BE_HAMMERED)
423 #define P_VISUAL_EFFECT (1<<E_P_VISUAL_EFFECT)
424 #define P_PLAYER (1<<E_P_PLAYER)
425 #define P_MOVED_BY_CONVEYOR_TOP (1<<E_P_MOVED_BY_CONVEYOR_TOP)
426 #define P_MOVED_BY_CONVEYOR_BOTTOM (1<<E_P_MOVED_BY_CONVEYOR_BOTTOM)
434 /* These are states of the magic wall. */
435 typedef enum _magic_wall_state {
436 GD_MW_DORMANT, /* Starting with this. */
437 GD_MW_ACTIVE, /* Boulder or diamond dropped into. */
438 GD_MW_EXPIRED /* Turned off after magic_wall_milling_time. */
439 } GdMagicWallState;
441 /* These are states of Player. */
442 typedef enum _player_state {
443 GD_PL_NOT_YET, /* Not yet living. Beginning of cave time. */
444 GD_PL_LIVING, /* Ok. */
445 GD_PL_TIMEOUT, /* Time is up */
446 GD_PL_DIED, /* Died. */
447 GD_PL_EXITED /* Exited the cave, proceed to next one */
448 } GdPlayerState;
450 /* States of amoeba */
451 typedef enum _amoeba_state {
452 GD_AM_SLEEPING, /* sleeping - not yet let out. */
453 GD_AM_AWAKE, /* living, growing */
454 GD_AM_TOO_BIG, /* grown too big, will convert to stones */
455 GD_AM_ENCLOSED, /* enclosed, will convert to diamonds */
456 } GdAmoebaState;
458 typedef enum _direction {
459 /* not moving */
460 MV_STILL=0,
461 MV_THIS=0,
463 /* directions */
464 MV_UP=1,
465 MV_UP_RIGHT=2,
466 MV_RIGHT=3,
467 MV_DOWN_RIGHT=4,
468 MV_DOWN=5,
469 MV_DOWN_LEFT=6,
470 MV_LEFT=7,
471 MV_UP_LEFT=8,
473 /* to be able to type MV_TWICE+MV_DOWN, for example */
474 MV_TWICE=8,
476 /* directions * 2 */
477 MV_UP_2=9,
478 MV_UP_RIGHT_2=10,
479 MV_RIGHT_2=11,
480 MV_DOWN_RIGHT_2=12,
481 MV_DOWN_2=13,
482 MV_DOWN_LEFT_2=14,
483 MV_LEFT_2=15,
484 MV_UP_LEFT_2=16,
486 MV_MAX,
487 } GdDirection;
489 typedef enum _sound {
490 GD_S_NONE,
492 GD_S_STONE,
493 GD_S_NUT,
494 GD_S_NUT_CRACK,
495 GD_S_DIRT_BALL,
496 GD_S_NITRO,
497 GD_S_FALLING_WALL,
498 GD_S_EXPANDING_WALL,
499 GD_S_WALL_REAPPEAR,
500 GD_S_DIAMOND_RANDOM, /* randomly select a diamond sound */
501 GD_S_DIAMOND_1,
502 GD_S_DIAMOND_2,
503 GD_S_DIAMOND_3,
504 GD_S_DIAMOND_4,
505 GD_S_DIAMOND_5,
506 GD_S_DIAMOND_6,
507 GD_S_DIAMOND_7,
508 GD_S_DIAMOND_8,
509 GD_S_DIAMOND_COLLECT,
510 GD_S_SKELETON_COLLECT,
511 GD_S_PNEUMATIC_COLLECT,
512 GD_S_BOMB_COLLECT,
513 GD_S_CLOCK_COLLECT,
514 GD_S_SWEET_COLLECT,
515 GD_S_KEY_COLLECT,
516 GD_S_DIAMOND_KEY_COLLECT,
517 GD_S_SLIME,
518 GD_S_LAVA,
519 GD_S_REPLICATOR,
520 GD_S_ACID_SPREAD,
521 GD_S_BLADDER_MOVE,
522 GD_S_BLADDER_CONVERT,
523 GD_S_BLADDER_SPENDER,
524 GD_S_BITER_EAT,
526 GD_S_DOOR_OPEN,
527 GD_S_WALK_EARTH,
528 GD_S_WALK_EMPTY,
529 GD_S_STIRRING,
530 GD_S_BOX_PUSH,
531 GD_S_TELEPORTER,
532 GD_S_TIMEOUT_1,
533 GD_S_TIMEOUT_2,
534 GD_S_TIMEOUT_3,
535 GD_S_TIMEOUT_4,
536 GD_S_TIMEOUT_5,
537 GD_S_TIMEOUT_6,
538 GD_S_TIMEOUT_7,
539 GD_S_TIMEOUT_8,
540 GD_S_TIMEOUT_9,
541 GD_S_TIMEOUT,
542 GD_S_EXPLOSION,
543 GD_S_BOMB_EXPLOSION,
544 GD_S_GHOST_EXPLOSION,
545 GD_S_VOODOO_EXPLOSION,
546 GD_S_NITRO_EXPLOSION,
547 GD_S_BOMB_PLACE,
548 GD_S_FINISHED,
549 GD_S_SWITCH_BITER,
550 GD_S_SWITCH_CREATURES,
551 GD_S_SWITCH_GRAVITY,
552 GD_S_SWITCH_EXPANDING,
553 GD_S_SWITCH_CONVEYOR,
554 GD_S_SWITCH_REPLICATOR,
556 GD_S_AMOEBA, /* loop */
557 GD_S_AMOEBA_MAGIC, /* loop */
558 GD_S_MAGIC_WALL, /* loop */
559 GD_S_COVER, /* loop */
560 GD_S_PNEUMATIC_HAMMER, /* loop */
561 GD_S_WATER, /* loop */
562 GD_S_CRACK,
563 GD_S_GRAVITY_CHANGE,
564 GD_S_BONUS_LIFE,
566 GD_S_MAX,
567 } GdSound;
570 /* ELEMENTS DESCRIPTION */
571 typedef struct _elements {
572 GdElement element; /* element number. for example O_DIRT */
573 char *name; /* name in editor, for example "Dirt". some have different names than their real engine meaning! */
574 unsigned int properties;/* engine properties, like P_SLOPED or P_EXPLODES */
575 char *filename; /* name in bdcff file, like "DIRT" */
576 char character; /* character representation in bdcff file, like '.' */
577 int image; /* image in editor (index in cells.png) */
578 int image_simple; /* image for simple view in editor, and for combo box (index in cells.png) */
579 int image_game; /* image for game. negative if animated */
580 int ckdelay; /* ckdelay ratio - how much time required for a c64 to process this element - in microseconds. */
582 char *lowercase_name; /* lowercase of translated name. for editor; generated inside the game. */
583 char character_new; /* character given automatically for elements which don't have one defined in original bdcff description */
584 } GdElements;
586 typedef char GdString[128];
588 typedef struct _highscore {
589 GdString name;
590 int score;
591 } GdHighScore;
593 /* maximum seed value for the cave random generator. should be smaller than a signed int. */
594 #define GD_CAVE_SEED_MAX (1<<30)
596 typedef struct _gd_cave_replay {
597 int level; /* replay for level n */
598 guint32 seed; /* seed the cave is to be rendered with */
599 gboolean saved; /* also store it in the saved bdcff */
600 GdString recorded_with; /* recorded with - application name and version */
602 GdString player_name; /* who played this */
603 GdString date; /* when played */
604 GdString comment; /* some comments from the player */
606 int score; /* score collected */
607 int duration; /* number of seconds played */
608 gboolean success; /* successful playing of cave? */
609 guint32 checksum; /* checksum of the rendered cave. */
611 gboolean wrong_checksum;
612 GByteArray *movements;
613 int current_playing_pos;
614 } GdReplay;
616 typedef enum _gd_scheduling {
617 GD_SCHEDULING_MILLISECONDS,
618 GD_SCHEDULING_BD1,
619 GD_SCHEDULING_BD2,
620 GD_SCHEDULING_PLCK,
621 GD_SCHEDULING_CRDR,
622 GD_SCHEDULING_BD1_ATARI,
623 GD_SCHEDULING_BD2_PLCK_ATARI,
624 GD_SCHEDULING_MAX
625 } GdScheduling;
628 typedef struct _gd_c64_random_generator {
629 int rand_seed_1, rand_seed_2;
630 } GdC64RandomGenerator;
633 Structure holding all data belonging to a cave.
635 #define GD_HIGHSCORE_NUM 20
636 typedef struct _gd_cave {
637 /* Defined by the editor. public data :) */
638 GdString name; /* Name of cave */
639 GdString description; /* Some words about the cave */
640 GdString author; /* Author */
641 GdString difficulty; /* difficulty of the game, for info purposes */
642 GdString www; /* link to author's webpage */
643 GdString date; /* date of creation */
644 GString *story; /* story for the cave - will be shown when the cave is played. */
645 GString *remark; /* some note */
649 GdString charset; /* these are not used by gdash */
650 GdString fontset;
652 /* and this one the highscores */
653 GdHighScore highscore[GD_HIGHSCORE_NUM];
655 GHashTable *tags; /* stores read-but-not-understood strings from bdcff, so we can save them later. */
657 GdElement **map; /* pointer to data for map, non-null if has a map */
658 GList *objects;
659 GList *replays;
661 gboolean intermission; /* is this cave an intermission? */
662 gboolean intermission_instantlife; /* one life extra, if the intermission is reached */
663 gboolean intermission_rewardlife; /* one life extra, if the intermission is successfully finished */
664 gboolean selectable; /* is this selectable as an initial cave for a game? */
665 gboolean diagonal_movements; /* are diagonal movements allowed? */
666 GdElement snap_element; /* snapping (press fire+move) usually leaves space behind, but can be other */
667 gboolean short_explosions; /* in >=1stb, diamond and creature explosions were of 5 stages */
669 GdScheduling scheduling; /* scheduling type; see above */
670 gboolean pal_timing; /* use faster seconds */
672 gboolean active_is_first_found; /* active player is the uppermost. */
673 gboolean lineshift; /* true is line shifting emulation, false is perfect borders emulation */
674 gboolean border_scan_first_and_last; /* if true, scans the first and last line of the border. false for plck */
675 gboolean wraparound_objects; /* if this is true, object drawing (cave rendering) will wraparound as well. */
677 GdElement initial_fill;
678 GdElement initial_border;
679 GdElement random_fill[4]; /* Random fill elements. */
680 int random_fill_probability[4]; /* Random fill, probability of each element. */
682 int level_rand[5]; /* Random seed. */
683 int level_diamonds[5]; /* Must collect diamonds, on level x */
684 int level_speed[5]; /* Time between game cycles in ms */
685 int level_ckdelay[5]; /* Timing in original game units */
686 int level_time[5]; /* Available time, per level */
687 int level_timevalue[5]; /* points for each second remaining, when exiting level */
689 int max_time; /* the maximum time in seconds. if above, it overflows */
691 int w, h; /* Sizes of cave, width and height. */
692 int x1,y1,x2,y2; /* Visible part of the cave */
693 GdColor colorb; /* border color */
694 GdColor color0, color1, color2, color3, color4, color5; /* c64-style colors; 4 and 5 are amoeba and slime. */
696 int diamond_value; /* Score for a diamond. */
697 int extra_diamond_value; /* Score for a diamond, when gate is open. */
699 gboolean stone_sound;
700 gboolean nut_sound;
701 gboolean diamond_sound;
702 gboolean nitro_sound;
703 gboolean falling_wall_sound;
704 gboolean expanding_wall_sound;
705 gboolean bladder_spender_sound;
706 gboolean bladder_convert_sound;
708 int level_magic_wall_time[5]; /* magic wall 'on' state for each level (seconds) */
709 gboolean magic_wall_stops_amoeba; /* Turning on magic wall changes amoeba to diamonds. Original BD: yes, constkit: no */
710 gboolean magic_timer_wait_for_hatching; /* magic wall timer does not start before player's birth */
711 gboolean magic_wall_sound; /* magic wall has sound */
713 int level_amoeba_time[5]; /* amoeba time for each level */
714 double amoeba_growth_prob; /* Amoeba slow growth probability */
715 double amoeba_fast_growth_prob; /* Amoeba fast growth probability */
716 int level_amoeba_threshold[5]; /* amoeba turns to stones; if count is bigger than this (number of cells) */
717 GdElement amoeba_enclosed_effect; /* an enclosed amoeba converts to this element */
718 GdElement amoeba_too_big_effect; /* an amoeba grown too big converts to this element */
720 int level_amoeba_2_time[5]; /* amoeba time for each level */
721 double amoeba_2_growth_prob; /* Amoeba slow growth probability */
722 double amoeba_2_fast_growth_prob; /* Amoeba fast growth probability */
723 int level_amoeba_2_threshold[5]; /* amoeba turns to stones; if count is bigger than this (number of cells) */
724 GdElement amoeba_2_enclosed_effect; /* an enclosed amoeba converts to this element */
725 GdElement amoeba_2_too_big_effect; /* an amoeba grown too big converts to this element */
726 gboolean amoeba_2_explodes_by_amoeba; /* amoeba 2 will explode if touched by amoeba1 */
727 GdElement amoeba_2_explosion_effect; /* amoeba 2 explosion ends in ... */
728 GdElement amoeba_2_looks_like; /* an amoeba 2 looks like this element */
730 gboolean amoeba_timer_started_immediately; /* FALSE: amoeba will start life at the first possibility of growing. */
731 gboolean amoeba_timer_wait_for_hatching; /* amoeba timer does not start before player's birth */
732 gboolean amoeba_sound; /* if the living amoeba has sound. */
734 GdElement acid_eats_this; /* acid eats this element */
735 double acid_spread_ratio; /* Probability of acid blowing up, each frame */
736 gboolean acid_spread_sound; /* acid has sound */
737 GdElement acid_turns_to; /* whether acid converts to explosion on spreading or other */
739 double level_slime_permeability[5]; /* true random slime */
740 int level_slime_permeability_c64[5]; /* Appearing in bd 2 */
741 int level_slime_seed_c64[5]; /* predictable slime random seed */
742 gboolean slime_predictable; /* predictable random start for slime. yes for plck. */
743 GdElement slime_eats_1, slime_converts_1; /* slime eats element x and converts to element x; for example diamond -> falling diamond */
744 GdElement slime_eats_2, slime_converts_2;
745 gboolean slime_sound; /* slime has sound */
747 gboolean lava_sound; /* elements sinking in lava have sound */
749 int level_hatching_delay_frame[5]; /* Scan frames before Player's birth. */
750 int level_hatching_delay_time[5]; /* Scan frames before Player's birth. */
752 int level_bonus_time[5]; /* bonus time for clock collected. */
753 int level_penalty_time[5]; /* Time penalty when voodoo destroyed. */
754 gboolean voodoo_collects_diamonds; /* Voodoo can collect diamonds */
755 gboolean voodoo_dies_by_stone; /* Voodoo can be killed by a falling stone */
756 gboolean voodoo_disappear_in_explosion; /* Voodoo can be destroyed by and explosion */
757 gboolean voodoo_any_hurt_kills_player; /* If any of the voodoos are hurt in any way, the player is killed. */
759 gboolean water_does_not_flow_down; /* if true, water will not grow downwards, only in other directions. */
760 gboolean water_sound; /* water has sound */
762 gboolean bladder_sound; /* bladder moving and pushing has sound */
763 GdElement bladder_converts_by; /* bladder converts to clock by touching this element */
765 int biter_delay_frame; /* frame count biters do move */
766 GdElement biter_eat; /* biters eat this */
767 gboolean biter_sound; /* biters have sound */
769 gboolean expanding_wall_changed; /* expanding wall direction is changed */
771 int replicator_delay_frame; /* replicator delay in frames (number of frames to wait between creating a new element) */
772 gboolean replicators_active; /* replicators are active. */
773 gboolean replicator_sound; /* when replicating an element, play sound or not. */
775 gboolean conveyor_belts_active;
776 gboolean conveyor_belts_direction_changed;
778 /* effects */
779 GdElement explosion_effect; /* explosion converts to this element after its last stage. diego effect. */
780 GdElement diamond_birth_effect; /* a diamond birth converts to this element after its last stage. diego effect. */
781 GdElement bomb_explosion_effect; /* bombs explode to this element. diego effect (almost). */
782 GdElement nitro_explosion_effect; /* nitros explode to this */
784 GdElement firefly_explode_to; /* fireflies explode to this when hit by a stone */
785 GdElement alt_firefly_explode_to; /* alternative fireflies explode to this when hit by a stone */
786 GdElement butterfly_explode_to; /* butterflies explode to this when hit by a stone */
787 GdElement alt_butterfly_explode_to; /* alternative butterflies explode to this when hit by a stone */
788 GdElement stonefly_explode_to; /* stoneflies explode to this when hit by a stone */
789 GdElement dragonfly_explode_to; /* dragonflies explode to this when hit by a stone */
791 GdElement stone_falling_effect; /* a falling stone converts to this element. diego effect. */
792 GdElement diamond_falling_effect; /* a falling diamond converts to this element. diego effect. */
793 GdElement stone_bouncing_effect; /* a bouncing stone converts to this element. diego effect. */
794 GdElement diamond_bouncing_effect; /* a bouncing diamond converts to this element. diego effect. */
796 GdElement expanding_wall_looks_like; /* an expanding wall looks like this element. diego effect. */
797 GdElement dirt_looks_like; /* dirt looks like this element. diego effect. */
799 GdElement magic_stone_to; /* magic wall converts falling stone to */
800 GdElement magic_diamond_to; /* magic wall converts falling diamond to */
801 GdElement magic_mega_stone_to; /* magic wall converts a falling mega stone to */
802 GdElement magic_nitro_pack_to; /* magic wall converts a falling nitro pack to */
803 GdElement magic_flying_stone_to; /* flying stones are converted to */
804 GdElement magic_flying_diamond_to; /* flying diamonds are converted to */
806 double pushing_stone_prob; /* probability of pushing stone */
807 double pushing_stone_prob_sweet; /* probability of pushing, after eating sweet */
808 gboolean mega_stones_pushable_with_sweet; /* mega stones may be pushed with sweet */
810 gboolean creatures_backwards; /* creatures changed direction */
811 gboolean creatures_direction_auto_change_on_start; /* the change occurs also at the start signal */
812 int creatures_direction_auto_change_time; /* creatures automatically change direction every x seconds */
813 gboolean creature_direction_auto_change_sound; /* automatically changing creature direction may have the sound of the creature dir switch */
815 int skeletons_needed_for_pot; /* how many skeletons to be collected, to use a pot */
816 int skeletons_worth_diamonds; /* for crazy dream 7 compatibility: collecting skeletons might open the cave door. */
818 GdDirection gravity;
819 int gravity_change_time;
820 gboolean gravity_change_sound;
821 gboolean gravity_affects_all; /* if true, gravity also affects falling wall, bladder and waiting stones */
822 gboolean gravity_switch_active; /* true if gravity switch is activated, and can be used. */
824 gboolean hammered_walls_reappear;
825 int pneumatic_hammer_frame;
826 int hammered_wall_reappear_frame;
827 gboolean pneumatic_hammer_sound;
831 /* internal variables, used during the game. private data :) */
832 GdElement* (*getp) (const struct _gd_cave*, int x, int y); /* returns a pointer to the element at x, y. this points to a perfect border or a line shifting get function. */
834 gboolean hatched; /* hatching has happened. (timers may run, ...) */
835 gboolean gate_open; /* self-explaining */
836 guint32 render_seed; /* the seed value, which was used to render the cave, is saved here. will be used by record&playback */
837 GRand *random; /* random number generator of rendered cave */
838 int rendered; /* if not zero, rendered at level x */
839 int timing_factor; /* number of "milliseconds" in each second :) 1000 for ntsc, 1200 for pal. */
840 gpointer **objects_order; /* two-dimensional map of cave; each cell is a pointer to the drawing object, which created this element. NULL if map or random. */
841 int **hammered_reappear; /* integer map of cave; if non-zero, a brick wall will appear there */
843 int speed; /* Time between game cycles in ms */
844 int c64_timing; /* a ckdelay value for the level this cave is rendered for */
845 int ckdelay; /* ckdelay value for the current iteration */
846 int ckdelay_extra_for_animation; /* bd1 and similar engines had animation bits in cave data, to set which elements to animate (firefly, butterfly, amoeba).
847 animating an element also caused some delay each frame; according to my measurements, around 2.6 ms/element. */
849 int hatching_delay_frame;
850 int hatching_delay_time;
851 int time_bonus; /* bonus time for clock collected. */
852 int time_penalty; /* Time penalty when voodoo destroyed. */
853 int time; /* milliseconds remaining to finish cave */
854 int timevalue; /* points for remaining seconds - for current level */
855 int diamonds_needed; /* diamonds needed to open outbox */
856 int diamonds_collected; /* diamonds collected */
857 int skeletons_collected; /* number of skeletons collected */
858 int gate_open_flash; /* flashing of screen when gate opens */
859 int score; /* Score got this frame. */
860 int amoeba_time; /* Amoeba growing slow (low probability, default 3%) for milliseconds. After that, fast growth default (25%) */
861 int amoeba_2_time; /* Amoeba growing slow (low probability, default 3%) for milliseconds. After that, fast growth default (25%) */
862 int amoeba_max_count; /* selected amoeba 1 threshold for this level */
863 int amoeba_2_max_count; /* selected amoeba 2 threshold for this level */
864 GdAmoebaState amoeba_state; /* state of amoeba 1 */
865 GdAmoebaState amoeba_2_state; /* state of amoeba 2 */
866 int magic_wall_time; /* magic wall 'on' state for seconds */
867 double slime_permeability; /* true random slime */
868 int slime_permeability_c64; /* Appearing in bd 2 */
869 GdMagicWallState magic_wall_state; /* State of magic wall */
870 GdPlayerState player_state; /* Player state. not yet living, living, exited... */
871 int player_seen_ago; /* player was seen this number of scans ago */
872 gboolean voodoo_touched; /* as its name says */
873 gboolean kill_player; /* Voodoo died, or used pressed escape to restart level. */
874 gboolean sweet_eaten; /* player ate sweet, he's strong. prob_sweet applies, and also able to push chasing stones */
875 int player_x, player_y; /* Coordinates of player (for scrolling) */
876 int px[16], py[16]; /* coordinates of player, for chasing stone */
877 int key1, key2, key3; /* The player is holding this number of keys of each color */
878 gboolean diamond_key_collected; /* Key collected, so trapped diamonds convert to diamonds */
879 gboolean inbox_flash_toggle; /* negated every scan. helps drawing inboxes, and making players be born at different times. */
880 GdDirection last_direction; /* last direction player moved. used by draw routines */
881 GdDirection last_horizontal_direction;
882 int biters_wait_frame; /* number of frames to wait until biters will move again */
883 int replicators_wait_frame; /* number of frames to wait until replicators are activated again */
884 int creatures_direction_will_change; /* creatures automatically change direction every x seconds */
885 GdC64RandomGenerator c64_rand; /* used for predictable random generator during the game. */
887 int gravity_will_change; /* gravity will change in this number of milliseconds */
888 gboolean gravity_disabled; /* when the player is stirring the pot, there is no gravity. */
889 GdDirection gravity_next_direction; /* next direction when the gravity changes. will be set by the player "getting" a gravity switch */
890 gboolean got_pneumatic_hammer; /* true if the player has a pneumatic hammer */
891 int pneumatic_hammer_active_delay; /* number of frames to wait, till pneumatic hammer will destroy the wall */
892 GdSound sound1, sound2, sound3; /* sound set for 3 channels after each iteration */
893 } GdCave;
896 #define CAVE_OFFSET(property) (G_STRUCT_OFFSET(GdCave, property))
907 /* arrays for movements */
908 /* also no1 and bd2 cave data import helpers; line direction coordinates */
909 extern const int gd_dx[], gd_dy[];
911 extern GdElement gd_char_to_element[];
913 void gd_create_char_to_element_table();
914 GdElement gd_get_element_from_character(guint8 character);
915 GdElement gd_get_element_from_string(const char *string);
919 void gd_struct_set_defaults_from_array(gpointer str, const GdStructDescriptor *properties, GdPropertyDefault *defaults);
920 char *gd_struct_explain_defaults_in_string(const GdStructDescriptor *properties, GdPropertyDefault *defaults);
924 /* init cave engine */
925 void gd_cave_init();
927 /* for cave tags hash table */
928 gboolean gd_str_case_equal(gconstpointer s1, gconstpointer s2);
929 guint gd_str_case_hash(gconstpointer v);
931 /* cave highscore functions */
932 int gd_highscore_compare(gconstpointer a, gconstpointer b);
933 gboolean gd_is_highscore(GdHighScore *scores, int score);
934 int gd_add_highscore(GdHighScore *highscores, const char *name, int score);
935 void gd_clear_highscore(GdHighScore *hs);
936 gboolean gd_has_highscore(GdHighScore *hs);
938 /* cave creator and destructor functions */
939 GdCave *gd_cave_new();
940 GdCave *gd_cave_new_from_cave(const GdCave *orig);
941 void gd_cave_copy(GdCave *dest, const GdCave *src);
942 void gd_cave_free(GdCave *cave);
944 /* cave manipulation */
945 void gd_cave_set_gdash_defaults(GdCave *cave);
946 void gd_cave_set_defaults_from_array(GdCave* cave, GdPropertyDefault *defaults);
947 void gd_cave_correct_visible_size(GdCave *cave);
948 void gd_cave_auto_shrink(GdCave *cave);
950 void gd_cave_set_random_c64_colors(GdCave *cave);
951 void gd_cave_set_random_c64dtv_colors(GdCave *cave);
952 void gd_cave_set_random_atari_colors(GdCave *cave);
953 void gd_cave_set_random_colors(GdCave *cave, GdColorType type);
955 void gd_cave_setup_for_game(GdCave *cave);
956 void gd_cave_count_diamonds(GdCave *cave);
958 /* c64 random generator support for cave fill */
959 unsigned int gd_c64_random(GdC64RandomGenerator *rand);
960 unsigned int gd_cave_c64_random(GdCave *);
961 void gd_c64_random_set_seed(GdC64RandomGenerator *rand, int seed1, int seed2);
962 void gd_cave_c64_random_set_seed(GdCave *cave, int seed1, int seed2);
964 /* support */
965 gpointer gd_cave_map_new_for_cave(const GdCave *cave, const int cell_size);
966 gpointer gd_cave_map_dup_size(const GdCave * cave, const gpointer map, const int cell_size);
967 #define gd_cave_map_new(CAVE, TYPE) ((TYPE **)gd_cave_map_new_for_cave((CAVE), sizeof(TYPE)))
968 #define gd_cave_map_dup(CAVE, MAP) ((gpointer)gd_cave_map_dup_size((CAVE), (gpointer *)(CAVE)->MAP, sizeof((CAVE)->MAP[0][0])))
969 void gd_cave_map_free(gpointer map);
971 void gd_cave_store_rc(GdCave * cave, int x, int y, const GdElement element, const void* order);
972 GdElement gd_cave_get_rc (const GdCave *cave, int x, int y);
974 /* direction */
975 const char *gd_direction_get_visible_name(GdDirection dir);
976 const char *gd_direction_get_filename(GdDirection dir);
977 GdDirection gd_direction_from_string(const char *str);
979 /* scheduling */
980 const char *gd_scheduling_get_visible_name(GdScheduling sched);
981 const char *gd_scheduling_get_filename(GdScheduling sched);
982 GdScheduling gd_scheduling_from_string(const char *str);
984 /* game playing helpers */
985 #define GD_REDRAW (1<<10)
986 void gd_drawcave_game(const GdCave *cave, int **gfx_buffer, gboolean bonus_life_flash, gboolean yellowish_color, int animcycle, gboolean hate_invisible_outbox);
988 /* function to copy a GdString */
989 static inline int
990 gd_strcpy(GdString dest, const GdString src)
992 return g_strlcpy(dest, src, sizeof(GdString));
995 int gd_cave_time_show(const GdCave *cave, int internal_time);
997 GdReplay *gd_replay_new();
998 GdReplay *gd_replay_new_from_replay(GdReplay *orig);
999 void gd_replay_free(GdReplay *replay);
1000 void gd_replay_store_movement(GdReplay *replay, GdDirection player_move, gboolean player_fire, gboolean suicide);
1001 gboolean gd_replay_get_next_movement(GdReplay *replay, GdDirection *player_move, gboolean *player_fire, gboolean *suicide);
1002 void gd_replay_rewind(GdReplay *replay);
1004 char *gd_replay_movements_to_bdcff(GdReplay *replay);
1006 guint32 gd_cave_adler_checksum(GdCave *cave);
1007 void gd_cave_adler_checksum_more(GdCave *cave, guint32 *a, guint32 *b);
1009 #endif /* _CAVE_H */