From 8fc42ddec026c091f0279199168b43e099ea3322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Sat, 21 Nov 2020 09:11:53 +0100 Subject: [PATCH] Remove folder --- main_gbmeta/My_settings.h | 6 - main_gbmeta/constants.h | 582 -- main_gbmeta/demo.h | 587 -- main_gbmeta/game.h | 4862 ----------------- main_gbmeta/images.h | 1397 ----- main_gbmeta/levels.h | 1809 ------ main_gbmeta/main_gbmeta.ino | 173 - .../main_gbmeta.ino.gamebuino_meta.bin | Bin 214568 -> 0 bytes main_gbmeta/mbed_config.h | 25 - main_gbmeta/palette.h | 98 - main_gbmeta/raycastlib.h | 2058 ------- main_gbmeta/settings.h | 447 -- main_gbmeta/smallinput.h | 404 -- main_gbmeta/sounds.h | 488 -- main_gbmeta/texts.h | 60 - 15 files changed, 12996 deletions(-) delete mode 100644 main_gbmeta/My_settings.h delete mode 100644 main_gbmeta/constants.h delete mode 100644 main_gbmeta/demo.h delete mode 100755 main_gbmeta/game.h delete mode 100644 main_gbmeta/images.h delete mode 100644 main_gbmeta/levels.h delete mode 100644 main_gbmeta/main_gbmeta.ino delete mode 100755 main_gbmeta/main_gbmeta.ino.gamebuino_meta.bin delete mode 100644 main_gbmeta/mbed_config.h delete mode 100644 main_gbmeta/palette.h delete mode 100644 main_gbmeta/raycastlib.h delete mode 100644 main_gbmeta/settings.h delete mode 100644 main_gbmeta/smallinput.h delete mode 100644 main_gbmeta/sounds.h delete mode 100644 main_gbmeta/texts.h diff --git a/main_gbmeta/My_settings.h b/main_gbmeta/My_settings.h deleted file mode 100644 index cf7eba5..0000000 --- a/main_gbmeta/My_settings.h +++ /dev/null @@ -1,6 +0,0 @@ -// Pokitto config required by PokittoLib - -//#define PROJ_SHOW_FPS_COUNTER -#define PROJ_SCREENMODE 13 -#define PROJ_MODE13 1 -#define PROJ_ENABLE_SOUND 1 diff --git a/main_gbmeta/constants.h b/main_gbmeta/constants.h deleted file mode 100644 index 08ae02b..0000000 --- a/main_gbmeta/constants.h +++ /dev/null @@ -1,582 +0,0 @@ -/** - @file constants.h - - This file contains definitions of game constants that are not considered - part of game settings and whose change can ffect the game balance and - playability, e.g. physics constants. - - by Miloslav Ciz (drummyfish), 2019 - - Released under CC0 1.0 (https://creativecommons.org/publicdomain/zero/1.0/) - plus a waiver of all other intellectual property. The goal of this work is - be and remain completely in the public domain forever, available for any use - whatsoever. -*/ - -#ifndef _SFG_CONSTANTS_H -#define _SFG_CONSTANTS_H - -/** - How quickly player moves, in squares per second. -*/ -#define SFG_PLAYER_MOVE_SPEED 7 - -/** - Gravity acceleration in squares / (second^2). -*/ -#define SFG_GRAVITY_ACCELERATION 30 - -/** - Initial upwards speed of player's jump, in squares per second. -*/ -#define SFG_PLAYER_JUMP_SPEED 5 - -/** - Melee and close-up attack range, in RCL_Units. -*/ -#define SFG_MELEE_RANGE 1600 - -/** - When a projectile is shot, it'll be offset by this distance (in RCL_Units) - from the shooter. -*/ - -#define SFG_PROJECTILE_SPAWN_OFFSET 256 - -/** - Player's melee hit range, in RCL_Units (RCL_UNITS_PER_SQUARE means full angle, - 180 degrees to both sides). -*/ -#define SFG_PLAYER_MELEE_ANGLE 512 - -/** - How quickly elevators and squeezers move, in RCL_Unit per second. -*/ -#define SFG_MOVING_WALL_SPEED 1024 - -/** - How quickly doors open and close, in RCL_Unit per second. -*/ -#define SFG_DOOR_OPEN_SPEED 2048 - -/** - Helper special state value. -*/ -#define SFG_CANT_SAVE 255 - -/** - Says the distance in RCL_Units at which level elements (items, monsters etc.) - are active. -*/ -#define SFG_LEVEL_ELEMENT_ACTIVE_DISTANCE (12 * 1024) - -/** - Rate at which AI will be updated, which also affects how fast enemies will - appear. -*/ -#define SFG_AI_FPS 4 - -/** - Says a probability (0 - 255) of the AI changing its state during one update - step. -*/ -#define SFG_AI_RANDOM_CHANGE_PROBABILITY 40 - -/** - Distance at which level elements (sprites) collide, in RCL_Unit (1024 per - square). -*/ -#define SFG_ELEMENT_COLLISION_RADIUS 1800 - -/** - Height, in RCL_Units, at which collisions happen with level elements - (sprites). -*/ -#define SFG_ELEMENT_COLLISION_HEIGHT 1024 - -/** - Distance at which explosion does damage and throws away the player, in - RCL_Units. Should be higher than SFG_ELEMENT_COLLISION_RADIUS so that - exploded rockets also hurt the target. -*/ -#define SFG_EXPLOSION_RADIUS 2000 - -/** - Distance in RCL_Units which the player is pushed away by an explosion. Watch - out, a slightly higher value can make player go through walls. Rather keep - this under RCL_UNITS_PER_SQUARE; -*/ -#define SFG_EXPLOSION_PUSH_AWAY_DISTANCE 1023 - -/** - How much damage triggers a barrel explosion. -*/ - -#define SFG_BARREL_EXPLOSION_DAMAGE_THRESHOLD 3 - -/** - Maximum player health. -*/ -#define SFG_PLAYER_MAX_HEALTH 125 - -/** - Start health of player. -*/ -#define SFG_PLAYER_START_HEALTH 100 - -/** - At which value health indicator shows a warning (red color). -*/ -#define SFG_PLAYER_HEALTH_WARNING_LEVEL 20 - -/** - Amount of health that is increased by taking a health kit. -*/ -#define SFG_HEALTH_KIT_VALUE 20 - -/** - How much randomness (positive and negative) will be added to damage - (e.g. by weapons, explosions, ...). This constant is is 0 to 255, 255 meaning - 100% of the base value. -*/ -#define SFG_DAMAGE_RANDOMNESS 64 - -/** - Height of monster collision BBox in RCL_Units. -*/ -#define SFG_MONSTER_COLLISION_HEIGHT 1024 - -/** - Specifies key repeat delay, in ms. -*/ -#define SFG_KEY_REPEAT_DELAY 500 - -/** - Specifies key repeat period, in ms. -*/ -#define SFG_KEY_REPEAT_PERIOD 150 - -/** - Angle in which multiple projectiles are spread, RCL_Units. -*/ -#define SFG_PROJECTILE_SPREAD_ANGLE 100 - -#define SFG_MAX_MONSTERS 64 - -#define SFG_MAX_PROJECTILES 12 - -#define SFG_MAX_DOORS 32 - -#define SFG_AMMO_BULLETS 0 -#define SFG_AMMO_ROCKETS 1 -#define SFG_AMMO_PLASMA 2 - -#define SFG_AMMO_TOTAL 3 - -#define SFG_AMMO_NONE SFG_AMMO_TOTAL - -#define SFG_AMMO_INCREASE_BULLETS 10 -#define SFG_AMMO_INCREASE_ROCKETS 5 -#define SFG_AMMO_INCREASE_PLASMA 8 - -#define SFG_AMMO_MAX_BULLETS 200 -#define SFG_AMMO_MAX_ROCKETS 100 -#define SFG_AMMO_MAX_PLASMA 150 - -/** - Duration of story text (intro/outro) in ms. -*/ -#define SFG_STORYTEXT_DURATION 15000 - -/** - Time in ms of the player death animation. -*/ -#define SFG_LOSE_ANIMATION_DURATION 2000 - -/** - Time in ms of the level win animation. -*/ -#define SFG_WIN_ANIMATION_DURATION 2500 - -/** - Time in ms of the level start stage. -*/ -#define SFG_LEVEL_START_DURATION 1500 - -/** - Vertical sprite size, in RCL_Units. -*/ -#define SFG_BASE_SPRITE_SIZE RCL_UNITS_PER_SQUARE - -// ---------------------------- -// derived constants - -#define SFG_GAME_RESOLUTION_X \ - (SFG_SCREEN_RESOLUTION_X / SFG_RESOLUTION_SCALEDOWN) - -#define SFG_GAME_RESOLUTION_Y \ - (SFG_SCREEN_RESOLUTION_Y / SFG_RESOLUTION_SCALEDOWN) - -#define SFG_MS_PER_FRAME (1000 / SFG_FPS) // ms per frame with target FPS - -#if SFG_MS_PER_FRAME == 0 - #undef SFG_MS_PER_FRAME - #define SFG_MS_PER_FRAME 1 -#endif - -#define SFG_KEY_REPEAT_DELAY_FRAMES \ - (SFG_KEY_REPEAT_DELAY / SFG_MS_PER_FRAME) - -#if SFG_KEY_REPEAT_DELAY_FRAMES == 0 - #undef SFG_KEY_REPEAT_DELAY_FRAMES - #define SFG_KEY_REPEAT_DELAY_FRAMES 1 -#endif - -#define SFG_KEY_REPEAT_PERIOD_FRAMES \ - (SFG_KEY_REPEAT_PERIOD / SFG_MS_PER_FRAME) - -#if SFG_KEY_REPEAT_PERIOD_FRAMES == 0 - #undef SFG_KEY_REPEAT_PERIOD_FRAMES - #define SFG_KEY_REPEAT_PERIOD_FRAMES 1 -#endif - -#define SFG_WEAPON_IMAGE_SCALE \ - (SFG_GAME_RESOLUTION_X / (SFG_TEXTURE_SIZE * 5)) - -#if SFG_WEAPON_IMAGE_SCALE == 0 - #undef SFG_WEAPON_IMAGE_SCALE - #define SFG_WEAPON_IMAGE_SCALE 1 -#endif - -#define SFG_WEAPONBOB_OFFSET_PIXELS \ - (SFG_WEAPONBOB_OFFSET * SFG_WEAPON_IMAGE_SCALE) - -#define SFG_WEAPON_IMAGE_POSITION_X \ - (SFG_GAME_RESOLUTION_X / 2 - (SFG_WEAPON_IMAGE_SCALE * SFG_TEXTURE_SIZE) / 2) - -#if SFG_GAME_RESOLUTION_Y > 70 - #define SFG_WEAPON_IMAGE_POSITION_Y \ - (SFG_GAME_RESOLUTION_Y - (SFG_WEAPON_IMAGE_SCALE * SFG_TEXTURE_SIZE)) -#elif SFG_GAME_RESOLUTION_Y > 50 - #define SFG_WEAPON_IMAGE_POSITION_Y (SFG_GAME_RESOLUTION_Y \ - - ((SFG_WEAPON_IMAGE_SCALE * 3 * SFG_TEXTURE_SIZE) / 4)) -#else - #define SFG_WEAPON_IMAGE_POSITION_Y \ - (SFG_GAME_RESOLUTION_Y - SFG_TEXTURE_SIZE / 2) -#endif - -#define SFG_PLAYER_TURN_UNITS_PER_FRAME \ - ((SFG_PLAYER_TURN_SPEED * RCL_UNITS_PER_SQUARE) / (360 * SFG_FPS)) - -#if SFG_PLAYER_TURN_UNITS_PER_FRAME == 0 - #undef SFG_PLAYER_TURN_UNITS_PER_FRAME - #define SFG_PLAYER_TURN_UNITS_PER_FRAME 1 -#endif - -#define SFG_PLAYER_MOVE_UNITS_PER_FRAME \ - ((SFG_PLAYER_MOVE_SPEED * RCL_UNITS_PER_SQUARE) / SFG_FPS) - -#if SFG_PLAYER_MOVE_UNITS_PER_FRAME == 0 - #undef SFG_PLAYER_MOVE_UNITS_PER_FRAME - #define SFG_PLAYER_MOVE_UNITS_PER_FRAME 1 -#endif - -#define SFG_GRAVITY_SPEED_INCREASE_PER_FRAME \ - ((SFG_GRAVITY_ACCELERATION * RCL_UNITS_PER_SQUARE) / (SFG_FPS * SFG_FPS)) - -#if SFG_GRAVITY_SPEED_INCREASE_PER_FRAME == 0 - #undef SFG_GRAVITY_SPEED_INCREASE_PER_FRAME - #define SFG_GRAVITY_SPEED_INCREASE_PER_FRAME 1 -#endif - -#define SFG_PLAYER_JUMP_OFFSET_PER_FRAME \ - (((SFG_PLAYER_JUMP_SPEED * RCL_UNITS_PER_SQUARE) / SFG_FPS) \ - - SFG_GRAVITY_SPEED_INCREASE_PER_FRAME / 2) - /* ^ This substraction corrects the initial veloc. so that the numeric curve - copies the analytical (smooth) curve. Without it the numeric curve goes - ABOVE and makes player jump higher with lower FPS. To make sense of this - try to solve the differential equation and plot it. */ - -#if SFG_PLAYER_JUMP_OFFSET_PER_FRAME == 0 - #undef SFG_PLAYER_JUMP_OFFSET_PER_FRAME - #define SFG_PLAYER_JUMP_OFFSET_PER_FRAME 1 -#endif - -#define SFG_HEADBOB_FRAME_INCREASE_PER_FRAME \ - (SFG_HEADBOB_SPEED / SFG_FPS) - -#if SFG_HEADBOB_FRAME_INCREASE_PER_FRAME == 0 - #undef SFG_HEADBOB_FRAME_INCREASE_PER_FRAME - #define SFG_HEADBOB_FRAME_INCREASE_PER_FRAME 1 -#endif - -#define SFG_HEADBOB_ENABLED (SFG_HEADBOB_SPEED > 0 && SFG_HEADBOB_OFFSET > 0) - -#define SFG_CAMERA_SHEAR_STEP_PER_FRAME \ - ((SFG_GAME_RESOLUTION_Y * SFG_CAMERA_SHEAR_SPEED) / SFG_FPS) - -#if SFG_CAMERA_SHEAR_STEP_PER_FRAME == 0 - #undef SFG_CAMERA_SHEAR_STEP_PER_FRAME - #define SFG_CAMERA_SHEAR_STEP_PER_FRAME 1 -#endif - -#define SFG_CAMERA_MAX_SHEAR_PIXELS \ - ((SFG_CAMERA_MAX_SHEAR * SFG_GAME_RESOLUTION_Y) / 1024) - -#define SFG_FONT_SIZE_SMALL \ - (SFG_GAME_RESOLUTION_X / (SFG_FONT_CHARACTER_SIZE * 50)) - -#if SFG_FONT_SIZE_SMALL == 0 - #undef SFG_FONT_SIZE_SMALL - #define SFG_FONT_SIZE_SMALL 1 -#endif - -#define SFG_FONT_SIZE_MEDIUM \ - (SFG_GAME_RESOLUTION_X / (SFG_FONT_CHARACTER_SIZE * 30)) - -#if SFG_FONT_SIZE_MEDIUM == 0 - #undef SFG_FONT_SIZE_MEDIUM - #define SFG_FONT_SIZE_MEDIUM 1 -#endif - -#define SFG_FONT_SIZE_BIG \ - (SFG_GAME_RESOLUTION_X / (SFG_FONT_CHARACTER_SIZE * 18)) - -#if SFG_FONT_SIZE_BIG == 0 - #undef SFG_FONT_SIZE_BIG - #define SFG_FONT_SIZE_BIG 1 -#endif - -#define SFG_Z_BUFFER_SIZE SFG_GAME_RESOLUTION_X - -/** - Step in which walls get higher, in raycastlib units. -*/ -#define SFG_WALL_HEIGHT_STEP (RCL_UNITS_PER_SQUARE / 4) - -#define SFG_CEILING_MAX_HEIGHT\ - (16 * RCL_UNITS_PER_SQUARE - RCL_UNITS_PER_SQUARE / 2 ) - -#define SFG_DOOR_UP_DOWN_MASK 0x20 -#define SFG_DOOR_LOCK(doorRecord) ((doorRecord) >> 6) -#define SFG_DOOR_VERTICAL_POSITION_MASK 0x1f -#define SFG_DOOR_HEIGHT_STEP (RCL_UNITS_PER_SQUARE / 0x1f) - -#define SFG_DOOR_INCREMENT_PER_FRAME \ - (SFG_DOOR_OPEN_SPEED / (SFG_DOOR_HEIGHT_STEP * SFG_FPS)) - -#if SFG_DOOR_INCREMENT_PER_FRAME == 0 - #undef SFG_DOOR_INCREMENT_PER_FRAME - #define SFG_DOOR_INCREMENT_PER_FRAME 1 -#endif - -#define SFG_MAX_ITEMS SFG_MAX_LEVEL_ELEMENTS - -#define SFG_MAX_SPRITE_SIZE SFG_GAME_RESOLUTION_X - -#define SFG_MAP_PIXEL_SIZE (SFG_GAME_RESOLUTION_Y / SFG_MAP_SIZE) - -#if SFG_MAP_PIXEL_SIZE == 0 - #undef SFG_MAP_PIXEL_SIZE - #define SFG_MAP_PIXEL_SIZE 1 -#endif - -#define SFG_AI_UPDATE_FRAME_INTERVAL \ - (SFG_FPS / SFG_AI_FPS) - -#if SFG_AI_UPDATE_FRAME_INTERVAL == 0 - #undef SFG_AI_UPDATE_FRAME_INTERVAL - #define SFG_AI_UPDATE_FRAME_INTERVAL 1 -#endif - -#define SFG_SPRITE_ANIMATION_FRAME_DURATION \ - (SFG_FPS / SFG_SPRITE_ANIMATION_SPEED) - -#if SFG_SPRITE_ANIMATION_FRAME_DURATION == 0 - #undef SFG_SPRITE_ANIMATION_FRAME_DURATION - #define SFG_SPRITE_ANIMATION_FRAME_DURATION 1 -#endif - -#define SFG_HUD_MARGIN (SFG_GAME_RESOLUTION_X / 40) - -#define SFG_HUD_BORDER_INDICATOR_WIDTH_PIXELS \ - (SFG_GAME_RESOLUTION_Y / SFG_HUD_BORDER_INDICATOR_WIDTH) - -#define SFG_HUD_BORDER_INDICATOR_DURATION_FRAMES \ - (SFG_HUD_BORDER_INDICATOR_DURATION / SFG_MS_PER_FRAME) - -#if SFG_HUD_BORDER_INDICATOR_DURATION_FRAMES == 0 - #define SFG_HUD_BORDER_INDICATOR_DURATION_FRAMES 1 -#endif - -#define SFG_BLINK_PERIOD_FRAMES (SFG_BLINK_PERIOD / SFG_MS_PER_FRAME) - -#define SFG_HUD_BAR_HEIGHT \ - (SFG_FONT_CHARACTER_SIZE * SFG_FONT_SIZE_MEDIUM + SFG_HUD_MARGIN * 2 + 1) - -// ---------------------------- -// monsters - -#define SFG_MONSTER_ATTACK_MELEE 0 -#define SFG_MONSTER_ATTACK_FIREBALL 1 -#define SFG_MONSTER_ATTACK_BULLET 2 -#define SFG_MONSTER_ATTACK_FIREBALL_BULLET 3 -#define SFG_MONSTER_ATTACK_PLASMA 4 -#define SFG_MONSTER_ATTACK_EXPLODE 5 -#define SFG_MONSTER_ATTACK_FIREBALL_PLASMA 6 - -#define SFG_MONSTER_ATTRIBUTE(attackType,aggressivity0to255,health0to255,spriteSize0to3) \ - ((uint16_t) ( \ - attackType | \ - ((aggressivity0to255 / 8) << 3) | \ - (spriteSize0to3 << 8) | \ - ((health0to255 / 4) << 10))) - -#define SFG_GET_MONSTER_ATTACK_TYPE(monsterNumber) \ - (SFG_monsterAttributeTable[monsterNumber] & 0x0007) - -#define SFG_GET_MONSTER_AGGRESSIVITY(monsterNumber) \ - (((SFG_monsterAttributeTable[monsterNumber] >> 3) & 0x1F) * 8) - -#define SFG_GET_MONSTER_SPRITE_SIZE(monsterNumber) \ - ((SFG_monsterAttributeTable[monsterNumber] >> 8) & 0x03) - -#define SFG_GET_MONSTER_MAX_HEALTH(monsterNumber) \ - (((SFG_monsterAttributeTable[monsterNumber] >> 10) & 0x3F) * 4) - -/** - Table of monster attributes, each as a 16bit word in format: - - MSB hhhhhhssaaaattt LSB - - ttt: attack type - aaaaa: aggressivity (frequence of attacks), 0 to 31 - ss: sprite size - hhhhhh: health, 0 to 63 -*/ -uint16_t SFG_monsterAttributeTable[SFG_MONSTERS_TOTAL] = -{ - /* spider */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_FIREBALL,40,61,2), - /* destr. */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_FIREBALL_BULLET,90,170,3), - /* warrior */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_MELEE,255,40,1), - /* plasma */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_PLASMA,56,92,1), - /* ender */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_FIREBALL_PLASMA,128,255,3), - /* turret */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_BULLET,32,23,0), - /* explod. */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_EXPLODE,255,36,1) -}; - -// ---------------------------- -// weapons and projectiles - -#define SFG_WEAPON_KNIFE 0 -#define SFG_WEAPON_SHOTGUN 1 -#define SFG_WEAPON_MACHINE_GUN 2 -#define SFG_WEAPON_ROCKET_LAUNCHER 3 -#define SFG_WEAPON_PLASMAGUN 4 -#define SFG_WEAPON_SOLUTION 5 - -#define SFG_WEAPONS_TOTAL 6 - -#define SFG_WEAPON_ATTRIBUTE(fireType,projectileCount,fireCooldownMs) \ - ((uint8_t) (fireType | ((projectileCount - 1) << 2) | ((fireCooldownMs / (SFG_MS_PER_FRAME * 16)) << 4))) - -#define SFG_GET_WEAPON_FIRE_TYPE(weaponNumber) \ - (SFG_weaponAttributeTable[weaponNumber] & 0x03) - -#define SFG_GET_WEAPON_FIRE_COOLDOWN_FRAMES(weaponNumber) \ - ((SFG_weaponAttributeTable[weaponNumber] >> 4) * 16) - -#define SFG_GET_WEAPON_PROJECTILE_COUNT(weaponNumber) \ - (((SFG_weaponAttributeTable[weaponNumber] >> 2) & 0x03) + 1) - -#define SFG_MIN_WEAPON_COOLDOWN_FRAMES 8 - -#define SFG_WEAPON_FIRE_TYPE_MELEE 0 -#define SFG_WEAPON_FIRE_TYPE_BULLET 1 -#define SFG_WEAPON_FIRE_TYPE_FIREBALL 2 -#define SFG_WEAPON_FIRE_TYPE_PLASMA 3 - -#define SFG_WEAPON_FIRE_TYPES_TOTAL 4 - -/** - Table of weapon attributes, each as a byte in format: - - MSB ccccnnff LSB - - ff: fire type - nn: number of projectiles - 1 - cccc: fire cooldown in frames, i.e. time after which the next shot can be - shot again, ccccc has to be multiplied by 16 to get the real value -*/ -SFG_PROGRAM_MEMORY uint8_t SFG_weaponAttributeTable[SFG_WEAPONS_TOTAL] = -{ - /* knife */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_MELEE,1,650), // DPS: 6.2 - /* shotgun */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_BULLET,2,1250), // DPS: 12.8 - /* m. gun */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_BULLET,1,700), // DPS: 11.4 - /* r. laun. */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_FIREBALL,1,850), // DPS: 28.2 - /* plasma */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_PLASMA,1,550), // DPS: 32.7 - /* solution */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_PLASMA,4,1050) // DPS: 85.7 -}; - -SFG_PROGRAM_MEMORY uint8_t SFG_attackDamageTable[SFG_WEAPON_FIRE_TYPES_TOTAL] = -{ - /* melee */ 4, - /* bullet */ 8, - /* explostion (fireball) */ 24, - /* plasma */ 18 -}; - -#define SFG_PROJECTILE_EXPLOSION 0 -#define SFG_PROJECTILE_FIREBALL 1 -#define SFG_PROJECTILE_PLASMA 2 -#define SFG_PROJECTILE_DUST 3 -#define SFG_PROJECTILE_BULLET 4 -#define SFG_PROJECTILE_NONE 255 - -#define SFG_PROJECTILES_TOTAL 5 - -#define SFG_PROJECTILE_ATTRIBUTE(speedSquaresPerSec,timeToLiveMs) \ - ((uint8_t) \ - ((((speedSquaresPerSec / 4 == 0) && (speedSquaresPerSec != 0)) ? 1 : speedSquaresPerSec / 4) | \ - ((timeToLiveMs / (8 * SFG_MS_PER_FRAME)) << 3))) - -#define SFG_GET_PROJECTILE_SPEED_UPS(projectileNumber) \ - (((SFG_projectileAttributeTable[projectileNumber] & 0x07) * 4 * RCL_UNITS_PER_SQUARE) / SFG_FPS) - -#define SFG_GET_PROJECTILE_FRAMES_TO_LIVE(projectileNumber) \ - ((SFG_projectileAttributeTable[projectileNumber] >> 3) * 8) - -/** - Table of projectile attributes, each as a byte in format: - - MSB lllllsss LSB - - fff: half speed in game squares per second - lllll: eigth of frames to live -*/ - -#define LOW_FPS (SFG_FPS < 24) ///< low FPS needs low speeds, because collisions - -SFG_PROGRAM_MEMORY uint8_t SFG_projectileAttributeTable[SFG_PROJECTILES_TOTAL] = -{ - /* explosion */ SFG_PROJECTILE_ATTRIBUTE(0,400), - /* fireball */ SFG_PROJECTILE_ATTRIBUTE(10,1000), - -#if LOW_FPS - /* plasma */ SFG_PROJECTILE_ATTRIBUTE(17,500), -#else - /* plasma */ SFG_PROJECTILE_ATTRIBUTE(18,500), -#endif - - /* dust */ SFG_PROJECTILE_ATTRIBUTE(0,450), - -#if LOW_FPS - /* bullet */ SFG_PROJECTILE_ATTRIBUTE(17,1000) -#else - /* bullet */ SFG_PROJECTILE_ATTRIBUTE(28,1000) -#endif -}; - -#undef LOW_FPS - -#endif // guard diff --git a/main_gbmeta/demo.h b/main_gbmeta/demo.h deleted file mode 100644 index 02ec801..0000000 --- a/main_gbmeta/demo.h +++ /dev/null @@ -1,587 +0,0 @@ -/** - @file demo.h - - Simple demo support for Anarch, intended just for testing. This file is not - needed for the game, it's just an extra helper. - - by drummyfish, released under CC0 1.0 (public domain) -*/ - -#ifndef _DEMO_H -#define _DEMO_H - -#include - -#define UINT32_MAX_VALUE 0xffffffff - -typedef struct -{ - uint32_t frame; // UINT32_MAX_VALUE is the terminating record - uint16_t keyStates; - int16_t mouseOffset[2]; -} DemoRecord; - -#define DEMO_MAX_RECORDS 1000000 - -DemoRecord demoRec[DEMO_MAX_RECORDS]; -uint32_t demoRecLength = 0; - -// --------- RECORDING ---------- - -void demoRecordStep() -{ - DemoRecord record; - - record.keyStates = 0; - - uint32_t mask = 1; - - for (int i = 0; i < SFG_KEY_COUNT; ++i) - { - record.keyStates |= SFG_keyPressed(i) ? mask : 0; - mask <<= 1; - } - - record.mouseOffset[0] = 0; - record.mouseOffset[1] = 0; - - record.frame = SFG_game.frame; - - record.mouseOffset[0] = SFG_game.mouseOffset[0]; - record.mouseOffset[1] = SFG_game.mouseOffset[1]; - - if (demoRecLength < DEMO_MAX_RECORDS) - { - if ( - (demoRecLength == 0) || - ( - (record.keyStates != demoRec[demoRecLength - 1].keyStates) || - (record.mouseOffset[0] != demoRec[demoRecLength - 1].mouseOffset[0]) || - (record.mouseOffset[1] != demoRec[demoRecLength - 1].mouseOffset[1]) - )) - { - demoRec[demoRecLength] = record; - demoRecLength++; - } - } - else - printf("max demo records reached!\n"); -} - -// ---------- PLAYING ----------- - -static const DemoRecord demoPlay[] = -{ -{0,0,{0,0}},{63,16,{0,0}},{67,0,{0,0}},{78,16,{0,0}}, -{83,0,{0,0}},{147,4,{0,0}},{153,516,{0,0}},{174,516,{10,-2}}, -{175,516,{5,-2}},{176,516,{3,-1}},{177,516,{3,0}},{178,516,{20,-2}}, -{179,516,{21,0}},{180,516,{42,1}},{181,516,{19,1}},{182,516,{26,3}}, -{182,512,{26,3}},{183,512,{46,5}},{184,512,{21,3}},{185,512,{20,1}}, -{186,512,{34,6}},{187,512,{54,7}},{188,512,{18,3}},{189,512,{20,1}}, -{190,512,{0,0}},{192,512,{0,-1}},{193,513,{0,0}},{195,513,{-2,-7}}, -{196,513,{-4,-8}},{197,513,{-4,-6}},{198,513,{-14,-19}},{199,513,{-10,-14}}, -{200,513,{-19,-22}},{201,513,{-17,-15}},{202,1,{-21,-17}},{203,1,{-20,-17}}, -{204,1,{-25,-16}},{205,1,{-22,-15}},{206,1,{-33,-19}},{207,1,{-81,-49}}, -{208,1,{-50,-28}},{209,1,{-56,-30}},{210,1,{-123,-59}},{211,1,{-62,-31}}, -{212,257,{-104,-56}},{213,257,{-61,-31}},{215,257,{-125,-62}},{216,257,{-59,-28}}, -{217,257,{-58,-28}},{218,257,{-109,-58}},{219,257,{-34,-22}},{220,257,{-16,-11}}, -{220,289,{-16,-11}},{221,289,{-45,-31}},{222,289,{-33,-19}},{223,289,{-7,-7}}, -{225,289,{-1,-1}},{227,289,{0,0}},{228,417,{0,0}},{230,417,{-1,0}}, -{230,161,{-1,0}},{231,161,{1,-1}},{232,161,{0,-1}},{233,385,{0,-1}}, -{234,385,{0,-4}},{236,385,{-5,-12}},{236,257,{-5,-12}},{237,257,{-1,-3}}, -{238,257,{0,-1}},{239,257,{0,0}},{240,257,{0,-3}},{241,257,{1,-3}}, -{242,257,{0,0}},{243,1,{7,-4}},{243,33,{7,-4}},{244,33,{23,-5}}, -{245,33,{19,-2}},{246,33,{27,0}},{247,33,{11,0}},{248,33,{3,0}}, -{249,33,{12,0}},{250,33,{7,0}},{251,33,{45,1}},{252,33,{36,2}}, -{253,33,{40,2}},{254,33,{48,3}},{255,33,{28,0}},{256,32,{21,1}}, -{257,32,{54,0}},{258,32,{28,0}},{259,32,{71,-5}},{260,32,{32,-3}}, -{261,32,{34,0}},{262,32,{55,-3}},{263,32,{23,0}},{264,32,{16,0}}, -{265,0,{25,0}},{266,0,{16,-2}},{267,0,{13,-2}},{268,0,{42,-2}}, -{269,0,{21,-2}},{270,0,{42,-2}},{271,0,{7,-2}},{272,0,{18,-2}}, -{273,0,{37,-2}},{274,0,{21,-4}},{275,0,{9,-3}},{276,0,{3,-1}}, -{277,0,{0,0}},{278,0,{0,-1}},{279,0,{0,0}},{280,0,{-3,1}}, -{281,0,{0,-1}},{282,0,{0,-2}},{282,1,{0,-2}},{283,1,{0,-1}}, -{285,1,{-1,-1}},{286,1,{-1,-2}},{287,1,{-1,-1}},{288,1,{0,-1}}, -{289,1,{-1,0}},{290,1,{0,0}},{291,1,{2,-2}},{292,1,{16,-4}}, -{293,1,{22,0}},{294,1,{73,6}},{295,1,{47,2}},{296,257,{36,2}}, -{297,257,{91,8}},{298,257,{53,4}},{299,257,{56,4}},{299,385,{56,4}}, -{300,385,{58,2}},{301,385,{64,2}},{302,385,{61,0}},{302,384,{61,0}}, -{303,384,{111,2}},{304,384,{60,0}},{305,384,{59,0}},{306,385,{102,4}}, -{307,385,{67,0}},{308,385,{71,4}},{309,385,{146,4}},{310,385,{74,4}}, -{311,385,{76,2}},{312,385,{151,4}},{313,385,{77,2}},{314,385,{75,2}}, -{314,384,{75,2}},{315,384,{162,4}},{316,384,{0,0}},{317,384,{62,3}}, -{318,384,{82,2}},{319,384,{83,4}},{320,384,{80,2}},{321,384,{118,2}}, -{322,384,{72,2}},{323,384,{76,4}},{324,384,{178,12}},{325,384,{93,7}}, -{326,384,{91,7}},{327,384,{157,14}},{328,128,{80,7}},{329,128,{84,7}}, -{330,128,{170,14}},{330,0,{170,14}},{331,0,{85,7}},{332,0,{84,9}}, -{333,0,{85,9}},{333,512,{85,9}},{334,512,{61,6}},{335,512,{77,9}}, -{336,512,{59,6}},{337,512,{65,6}},{338,0,{157,16}},{339,0,{84,12}}, -{340,0,{79,12}},{341,0,{140,21}},{342,0,{72,9}},{343,0,{45,8}}, -{344,0,{130,16}},{345,0,{40,6}},{346,0,{24,2}},{347,0,{0,0}}, -{348,0,{2,0}},{349,0,{-6,1}},{350,0,{0,0}},{352,0,{1,-5}}, -{353,0,{0,0}},{354,0,{-9,-10}},{355,0,{-13,-10}},{356,0,{-13,-12}}, -{357,0,{-38,-22}},{358,0,{-18,-9}},{359,0,{-46,-27}},{359,256,{-46,-27}}, -{360,256,{-31,-15}},{361,256,{-30,-14}},{362,256,{-60,-26}},{363,256,{-33,-15}}, -{364,256,{-28,-12}},{365,256,{-61,-27}},{366,256,{-36,-17}},{368,257,{-36,-17}}, -{369,257,{-27,-14}},{370,257,{-30,-21}},{371,257,{0,0}},{372,257,{-3,-3}}, -{373,257,{0,0}},{374,129,{-1,-1}},{374,161,{-1,-1}},{375,161,{0,-1}}, -{376,161,{21,-12}},{377,161,{26,-4}},{378,161,{26,0}},{379,161,{44,3}}, -{380,161,{13,1}},{381,161,{5,1}},{382,33,{22,1}},{383,33,{8,1}}, -{384,33,{13,0}},{385,33,{66,4}},{386,1,{36,6}},{387,1,{29,5}}, -{388,0,{46,5}},{389,0,{0,0}},{391,0,{-13,1}},{392,0,{0,0}}, -{393,0,{0,-1}},{394,0,{3,0}},{395,0,{11,1}},{396,0,{26,9}}, -{397,0,{14,8}},{398,0,{19,10}},{399,4,{16,9}},{400,4,{1,2}}, -{401,4,{4,4}},{402,4,{17,15}},{403,4,{13,13}},{404,4,{15,13}}, -{405,4,{58,42}},{406,4,{43,24}},{407,4,{52,25}},{407,260,{52,25}}, -{408,260,{62,23}},{409,260,{64,23}},{409,256,{64,23}},{410,256,{141,50}}, -{411,256,{78,26}},{412,256,{68,21}},{413,256,{139,45}},{414,256,{76,21}}, -{415,256,{83,19}},{416,256,{153,38}},{417,256,{69,14}},{418,256,{155,36}}, -{419,256,{76,19}},{420,256,{80,19}},{421,256,{88,22}},{422,256,{177,41}}, -{423,384,{88,22}},{424,384,{178,44}},{425,384,{86,19}},{426,384,{76,21}}, -{427,384,{66,17}},{427,388,{66,17}},{428,388,{86,22}},{429,388,{85,22}}, -{430,388,{82,19}},{431,388,{174,44}},{432,388,{80,24}},{433,132,{154,43}}, -{434,132,{83,24}},{435,132,{80,21}},{436,132,{172,46}},{437,132,{86,24}}, -{437,644,{86,24}},{438,644,{167,46}},{439,644,{78,23}},{440,644,{86,22}}, -{441,644,{81,23}},{442,644,{146,43}},{443,644,{78,22}},{444,644,{137,37}}, -{445,644,{71,16}},{446,644,{73,19}},{447,640,{144,35}},{448,640,{73,18}}, -{449,640,{74,21}},{450,640,{69,18}},{451,640,{100,31}},{452,640,{30,12}}, -{453,640,{2,1}},{454,640,{-4,-1}},{455,640,{-24,1}},{456,640,{0,0}}, -{456,129,{0,0}},{457,129,{-1,-3}},{458,129,{-3,-5}},{459,385,{-22,-17}}, -{460,385,{-18,-13}},{461,385,{-22,-13}},{462,385,{-52,-36}},{463,385,{-32,-22}}, -{464,385,{0,0}},{465,385,{-33,-20}},{466,385,{-100,-50}},{467,385,{-53,-26}}, -{468,385,{-103,-46}},{469,385,{-49,-21}},{470,385,{-55,-26}},{471,385,{-58,-23}}, -{472,385,{-64,-26}},{473,385,{-133,-55}},{474,385,{-79,-30}},{475,385,{-82,-32}}, -{476,385,{-84,-35}},{477,385,{-173,-72}},{478,385,{-90,-38}},{479,385,{-89,-38}}, -{480,385,{-179,-73}},{481,385,{-85,-35}},{482,385,{-89,-40}},{483,385,{-193,-86}}, -{483,129,{-193,-86}},{484,129,{-98,-48}},{485,129,{-209,-95}},{486,129,{-107,-48}}, -{487,129,{-102,-46}},{488,129,{-176,-86}},{489,129,{-93,-43}},{490,129,{-85,-45}}, -{491,641,{-172,-90}},{492,641,{-81,-44}},{493,641,{-77,-42}},{494,641,{-166,-87}}, -{495,640,{-83,-43}},{496,640,{-81,-42}},{497,640,{-85,-43}},{498,640,{-86,-46}}, -{499,640,{-155,-79}},{500,640,{-62,-34}},{501,640,{-64,-36}},{502,640,{0,0}}, -{503,640,{-70,-37}},{504,640,{-67,-34}},{505,640,{-138,-62}},{506,640,{-70,-27}}, -{507,896,{-53,-21}},{508,384,{-122,-40}},{509,384,{-66,-22}},{510,384,{-72,-20}}, -{511,384,{-77,-22}},{512,384,{-74,-22}},{513,384,{-66,-19}},{514,384,{-61,-19}}, -{514,388,{-61,-19}},{515,388,{-72,-22}},{516,388,{-156,-42}},{517,388,{-87,-23}}, -{518,388,{-87,-25}},{519,388,{-154,-49}},{520,388,{-77,-25}},{521,388,{-72,-27}}, -{522,388,{-144,-53}},{523,388,{-50,-28}},{524,388,{-29,-23}},{525,384,{-8,-8}}, -{526,384,{-4,-5}},{527,384,{0,-2}},{528,384,{20,-31}},{529,384,{18,-19}}, -{530,128,{41,-29}},{530,640,{41,-29}},{531,640,{117,-54}},{532,640,{71,-24}}, -{533,640,{83,-23}},{533,641,{83,-23}},{534,641,{166,-37}},{535,641,{91,-13}}, -{536,641,{199,-13}},{537,641,{106,-3}},{538,641,{102,-3}},{539,641,{108,0}}, -{540,641,{95,2}},{541,641,{97,0}},{542,641,{96,2}},{543,129,{216,7}}, -{544,129,{121,5}},{544,385,{121,5}},{545,385,{117,5}},{546,385,{208,10}}, -{547,385,{91,4}},{548,385,{108,5}},{549,385,{195,9}},{550,385,{104,4}}, -{551,385,{108,5}},{552,385,{205,10}},{553,385,{109,5}},{554,385,{221,12}}, -{555,385,{111,7}},{556,385,{108,7}},{557,385,{192,12}},{558,385,{105,5}}, -{558,384,{105,5}},{559,384,{119,7}},{560,384,{258,12}},{561,384,{125,5}}, -{562,384,{103,7}},{563,384,{207,17}},{564,384,{93,7}},{565,384,{90,7}}, -{566,384,{219,17}},{567,384,{118,10}},{568,384,{119,12}},{569,384,{209,27}}, -{570,896,{100,12}},{571,896,{204,24}},{572,640,{105,12}},{573,640,{107,12}}, -{574,640,{108,15}},{575,640,{199,32}},{576,640,{102,14}},{577,640,{88,14}}, -{578,640,{0,0}},{579,640,{102,14}},{580,640,{99,14}},{581,640,{98,14}}, -{582,640,{120,22}},{582,641,{120,22}},{583,641,{16,4}},{584,641,{0,0}}, -{585,385,{-29,0}},{586,385,{-11,2}},{587,385,{-5,4}},{588,384,{-1,-1}}, -{589,384,{-17,-7}},{590,384,{-56,-22}},{591,384,{-41,-15}},{592,384,{-47,-18}}, -{593,384,{-53,-21}},{594,384,{-132,-52}},{595,384,{-76,-32}},{596,384,{-72,-27}}, -{597,384,{-153,-54}},{598,384,{-67,-22}},{599,384,{-69,-24}},{600,384,{-129,-47}}, -{601,384,{-77,-27}},{602,384,{-80,-27}},{603,384,{-172,-54}},{604,384,{-76,-24}}, -{605,384,{-136,-50}},{606,384,{-67,-24}},{607,384,{-76,-27}},{608,384,{-142,-48}}, -{609,384,{-77,-22}},{610,384,{-75,-22}},{610,385,{-75,-22}},{611,385,{-135,-43}}, -{612,385,{-62,-24}},{613,385,{-42,-20}},{614,385,{-26,-22}},{615,385,{0,0}}, -{616,385,{18,17}},{617,385,{-4,-4}},{618,385,{0,0}},{619,129,{0,0}}, -{620,129,{-1,-1}},{621,129,{0,0}},{622,129,{0,-2}},{623,129,{2,-3}}, -{624,129,{8,-9}},{625,129,{0,0}},{626,129,{1,-2}},{627,129,{0,-1}}, -{628,129,{4,-4}},{629,129,{14,-9}},{630,129,{47,-10}},{631,129,{31,-4}}, -{632,129,{16,-2}},{633,129,{52,-2}},{634,129,{45,4}},{635,129,{56,4}}, -{636,129,{142,16}},{637,641,{80,9}},{638,641,{169,24}},{639,641,{90,14}}, -{640,641,{100,20}},{641,641,{111,22}},{642,641,{250,56}},{643,641,{120,25}}, -{644,641,{106,35}},{645,641,{14,6}},{646,129,{2,1}},{647,129,{-43,-9}}, -{648,129,{-17,1}},{648,385,{-17,1}},{649,385,{-1,3}},{650,385,{-36,-29}}, -{651,385,{-47,-25}},{652,385,{0,0}},{653,385,{-165,-92}},{654,385,{-90,-48}}, -{655,385,{-88,-48}},{656,385,{-190,-92}},{657,385,{-96,-43}},{658,385,{-93,-40}}, -{658,384,{-93,-40}},{659,384,{-185,-78}},{660,384,{-93,-40}},{661,384,{-98,-46}}, -{662,384,{-193,-83}},{663,384,{-99,-41}},{664,384,{-96,-36}},{665,384,{-170,-67}}, -{666,384,{-91,-33}},{667,384,{-65,-31}},{668,384,{-136,-65}},{669,385,{-75,-34}}, -{670,385,{-63,-31}},{671,385,{-95,-56}},{672,385,{-26,-20}},{673,385,{-5,-5}}, -{674,385,{34,33}},{675,385,{0,7}},{676,129,{3,-6}},{677,129,{56,-21}}, -{678,641,{37,-5}},{679,641,{53,2}},{680,641,{67,11}},{681,641,{68,14}}, -{682,641,{163,29}},{683,641,{89,14}},{684,641,{91,17}},{685,641,{184,32}}, -{686,641,{90,17}},{687,641,{93,19}},{688,641,{178,39}},{689,641,{91,19}}, -{690,641,{0,0}},{691,641,{85,16}},{692,641,{205,45}},{693,641,{77,21}}, -{694,641,{143,33}},{695,641,{46,13}},{696,641,{53,11}},{697,641,{130,23}}, -{698,129,{62,9}},{699,129,{68,9}},{700,129,{24,3}},{701,129,{0,0}}, -{702,129,{6,-1}},{703,129,{-6,6}},{704,129,{6,-15}},{705,129,{2,-13}}, -{706,129,{-5,-14}},{706,385,{-5,-14}},{707,385,{-9,-22}},{708,385,{-44,-50}}, -{709,385,{-41,-36}},{710,385,{-44,-35}},{711,385,{-120,-86}},{712,385,{-71,-44}}, -{713,385,{-76,-39}},{714,385,{-166,-82}},{715,385,{-84,-40}},{716,385,{-80,-39}}, -{717,385,{-160,-74}},{718,384,{-79,-37}},{719,384,{-170,-70}},{720,384,{-84,-35}}, -{721,384,{-156,-66}},{722,384,{-64,-29}},{723,384,{-69,-31}},{724,384,{-109,-60}}, -{725,384,{-52,-30}},{725,385,{-52,-30}},{726,385,{-40,-27}},{727,385,{-34,-26}}, -{728,385,{16,16}},{729,385,{0,0}},{730,385,{-12,-15}},{731,385,{-5,-5}}, -{732,385,{0,-1}},{733,129,{0,0}},{734,129,{0,-1}},{735,129,{33,-16}}, -{736,129,{44,-9}},{737,129,{107,-12}},{738,129,{36,0}},{739,641,{56,4}}, -{740,641,{134,14}},{741,641,{85,14}},{742,641,{92,19}},{743,641,{185,37}}, -{744,641,{87,17}},{745,641,{76,16}},{746,641,{146,31}},{747,641,{70,14}}, -{747,129,{70,14}},{748,129,{57,13}},{749,129,{62,11}},{750,129,{0,0}}, -{751,129,{1,-1}},{752,129,{-15,10}},{753,129,{4,-10}},{754,129,{0,-21}}, -{755,385,{-22,-64}},{756,385,{-19,-38}},{757,385,{-29,-37}},{758,385,{-78,-85}}, -{759,385,{-56,-46}},{760,385,{-119,-84}},{761,385,{-65,-41}},{762,385,{-71,-44}}, -{763,385,{-146,-90}},{764,385,{-79,-47}},{765,385,{0,0}},{766,385,{-72,-39}}, -{766,129,{-72,-39}},{767,129,{-142,-82}},{768,129,{-43,-34}},{768,641,{-43,-34}}, -{769,641,{-17,-19}},{770,641,{-6,-5}},{771,641,{0,-1}},{772,641,{3,12}}, -{773,641,{4,-9}},{774,641,{21,-22}},{775,641,{38,-26}},{776,641,{111,-32}}, -{777,641,{74,-5}},{778,641,{159,4}},{779,641,{89,4}},{780,641,{85,7}}, -{781,641,{124,13}},{782,129,{33,1}},{783,129,{6,1}},{784,129,{0,0}}, -{785,129,{-10,1}},{786,385,{-16,10}},{787,385,{-2,-3}},{788,385,{-3,-3}}, -{789,385,{-41,-20}},{790,385,{-74,-30}},{791,385,{-45,-20}},{792,385,{-56,-24}}, -{793,385,{-68,-27}},{794,385,{-159,-64}},{795,385,{-93,-38}},{796,385,{-92,-35}}, -{797,385,{-179,-67}},{798,385,{-85,-33}},{799,385,{-169,-62}},{800,385,{-87,-30}}, -{801,385,{-87,-35}},{802,385,{0,0}},{803,385,{-185,-74}},{804,385,{-96,-38}}, -{805,385,{-84,-35}},{806,385,{-173,-67}},{807,385,{-76,-32}},{808,385,{-128,-60}}, -{809,385,{-73,-29}},{810,385,{-145,-56}},{811,897,{-67,-27}},{812,897,{-69,-26}}, -{813,641,{-73,-25}},{814,641,{-152,-56}},{815,641,{-75,-30}},{816,641,{-153,-51}}, -{817,641,{-75,-27}},{817,640,{-75,-27}},{818,640,{-75,-24}},{819,640,{-77,-27}}, -{820,640,{-77,-22}},{822,640,{-78,-22}},{823,640,{-145,-41}},{824,640,{-74,-22}}, -{825,640,{-75,-20}},{826,640,{-156,-39}},{827,640,{-141,-34}},{828,640,{-75,-17}}, -{828,644,{-75,-17}},{829,644,{-60,-14}},{830,644,{-71,-10}},{831,644,{-140,-22}}, -{832,644,{-77,-10}},{832,132,{-77,-10}},{833,132,{-81,-13}},{834,388,{-138,-24}}, -{835,388,{-74,-15}},{836,388,{-146,-27}},{837,388,{-71,-12}},{837,384,{-71,-12}}, -{838,384,{-71,-10}},{839,384,{-71,-12}},{840,384,{-53,-11}},{841,384,{-68,-15}}, -{842,384,{-55,-12}},{843,384,{-110,-28}},{844,384,{-57,-16}},{845,384,{-73,-26}}, -{846,384,{-18,-9}},{847,384,{0,0}},{848,385,{-6,-6}},{849,385,{4,3}}, -{850,385,{0,0}},{851,129,{-1,-1}},{852,129,{6,-11}},{853,129,{15,-11}}, -{854,129,{52,-24}},{855,129,{34,-9}},{856,129,{34,-5}},{857,129,{96,-5}}, -{858,129,{45,-3}},{859,129,{58,-3}},{860,129,{129,-3}},{861,129,{73,0}}, -{862,129,{67,0}},{863,129,{124,0}},{864,129,{43,2}},{865,129,{62,2}}, -{866,129,{133,9}},{866,641,{133,9}},{867,641,{64,4}},{868,641,{65,4}}, -{869,641,{129,13}},{870,641,{65,4}},{871,641,{59,6}},{871,129,{59,6}}, -{872,129,{111,6}},{873,129,{29,1}},{874,129,{26,1}},{875,129,{71,-2}}, -{876,129,{53,0}},{877,129,{56,0}},{878,129,{59,1}},{879,129,{68,4}}, -{880,129,{50,2}},{881,129,{47,0}},{882,129,{39,0}},{883,129,{23,1}}, -{884,129,{1,0}},{885,129,{-3,0}},{886,129,{-8,1}},{887,129,{-2,1}}, -{888,129,{-3,-1}},{888,385,{-3,-1}},{889,385,{-10,-2}},{890,385,{-42,-6}}, -{891,385,{-39,-9}},{891,384,{-39,-9}},{892,384,{-52,-12}},{893,384,{-125,-26}}, -{894,384,{-63,-14}},{895,384,{-64,-12}},{896,384,{-61,-15}},{897,384,{-73,-13}}, -{898,384,{-71,-10}},{899,384,{-151,-24}},{900,384,{-74,-12}},{901,384,{-68,-12}}, -{902,384,{-131,-21}},{903,384,{-67,-12}},{904,384,{-110,-21}},{905,384,{-60,-12}}, -{906,384,{-52,-12}},{907,384,{-103,-23}},{908,384,{-58,-16}},{909,384,{-46,-14}}, -{910,384,{-103,-27}},{911,384,{-56,-19}},{912,384,{-60,-24}},{913,384,{-11,-8}}, -{913,385,{-11,-8}},{914,385,{0,0}},{915,385,{3,2}},{916,385,{0,0}}, -{917,129,{19,-6}},{918,129,{37,-7}},{919,129,{50,-3}},{920,129,{53,8}}, -{921,129,{59,13}},{922,129,{62,16}},{923,129,{140,38}},{924,641,{69,14}}, -{925,641,{58,13}},{926,641,{13,3}},{927,641,{29,3}},{928,641,{101,13}}, -{929,641,{61,9}},{930,641,{64,11}},{931,641,{150,28}},{932,641,{74,14}}, -{933,641,{74,12}},{934,641,{72,18}},{935,641,{24,5}},{936,641,{2,1}}, -{937,641,{-33,-4}},{938,641,{-8,0}},{939,129,{-7,-7}},{940,385,{-27,-23}}, -{941,385,{-43,-30}},{942,385,{-126,-76}},{943,385,{-83,-46}},{944,385,{-85,-48}}, -{945,385,{-162,-84}},{946,385,{-82,-38}},{947,385,{-78,-37}},{948,385,{-124,-65}}, -{949,385,{-46,-30}},{950,385,{-46,-35}},{951,385,{-32,-28}},{952,385,{-43,-37}}, -{953,385,{-45,-34}},{954,129,{-31,-22}},{955,129,{-32,-25}},{956,129,{-22,-20}}, -{957,129,{-2,-2}},{958,641,{0,0}},{959,641,{0,-2}},{960,641,{0,0}}, -{961,641,{46,-33}},{962,641,{32,-15}},{963,641,{102,-18}},{964,641,{58,0}}, -{965,641,{66,0}},{966,641,{67,0}},{967,641,{77,4}},{968,641,{82,4}}, -{969,641,{173,12}},{970,641,{85,4}},{971,641,{63,4}},{972,641,{88,6}}, -{973,641,{65,2}},{974,641,{53,2}},{975,641,{154,9}},{976,641,{81,9}}, -{977,641,{84,7}},{978,641,{119,11}},{979,641,{68,4}},{980,641,{69,4}}, -{981,641,{31,0}},{982,641,{37,0}},{983,641,{32,-4}},{984,641,{7,-2}}, -{985,641,{1,-1}},{986,129,{-15,6}},{987,129,{-2,-7}},{988,129,{-11,-20}}, -{989,129,{-18,-28}},{990,129,{-22,-26}},{991,129,{0,0}},{991,385,{0,0}}, -{992,385,{-63,-53}},{993,385,{-43,-32}},{994,385,{-93,-64}},{995,385,{-51,-33}}, -{996,385,{-51,-30}},{997,385,{-107,-65}},{998,385,{-59,-36}},{999,385,{-53,-35}}, -{1000,129,{-93,-63}},{1001,129,{-29,-25}},{1001,641,{-29,-25}},{1002,641,{-5,-5}}, -{1003,641,{-2,-2}},{1004,641,{6,8}},{1005,641,{0,0}},{1006,641,{24,-16}}, -{1007,641,{32,-15}},{1008,641,{94,-16}},{1009,641,{50,-3}},{1010,641,{47,0}}, -{1011,641,{56,2}},{1012,641,{112,13}},{1012,129,{112,13}},{1013,129,{30,3}}, -{1014,129,{7,1}},{1015,129,{0,0}},{1016,385,{-1,0}},{1017,385,{-7,3}}, -{1018,385,{0,0}},{1019,385,{-1,-2}},{1021,385,{-23,-15}},{1022,385,{-22,-11}}, -{1023,385,{-33,-13}},{1024,385,{-88,-40}},{1025,385,{-55,-23}},{1026,385,{-58,-24}}, -{1027,385,{-59,-26}},{1028,385,{-41,-16}},{1029,385,{-29,-17}},{1029,641,{-29,-17}}, -{1030,641,{-54,-32}},{1031,641,{-18,-13}},{1032,641,{-1,0}},{1033,641,{11,11}}, -{1034,641,{1,3}},{1035,641,{7,-6}},{1036,641,{78,-22}},{1037,641,{48,-9}}, -{1038,641,{45,-5}},{1039,641,{99,0}},{1040,641,{56,2}},{1041,641,{67,6}}, -{1042,641,{85,8}},{1043,641,{0,0}},{1044,129,{-14,4}},{1045,129,{-8,10}}, -{1046,129,{-2,-6}},{1047,385,{-34,-21}},{1048,385,{-44,-20}},{1049,385,{-118,-30}}, -{1050,385,{-67,-15}},{1051,385,{-63,-14}},{1052,385,{-121,-24}},{1053,385,{-46,-11}}, -{1054,385,{-52,-12}},{1055,385,{-100,-27}},{1055,257,{-100,-27}},{1056,257,{-48,-13}}, -{1057,257,{-59,-15}},{1058,257,{-104,-30}},{1059,257,{-42,-11}},{1060,1,{-63,-21}}, -{1061,1,{-25,-10}},{1062,1,{-13,-7}},{1062,0,{-13,-7}},{1063,0,{-10,-5}}, -{1064,0,{0,0}},{1065,0,{7,9}},{1066,0,{-2,-4}},{1067,0,{-1,-1}}, -{1068,0,{0,0}},{1069,0,{0,-2}},{1070,0,{0,-4}},{1071,0,{3,-4}}, -{1072,0,{25,-19}},{1073,0,{27,-14}},{1074,1,{36,-11}},{1075,1,{41,-11}}, -{1076,1,{6,-2}},{1077,1,{5,-3}},{1078,1,{6,-3}},{1079,1,{9,-3}}, -{1080,1,{14,-5}},{1081,1,{48,-12}},{1082,1,{40,-7}},{1083,1,{51,-5}}, -{1084,1,{95,-9}},{1085,1,{28,-4}},{1086,1,{11,-2}},{1087,1,{42,-7}}, -{1088,257,{34,-7}},{1089,257,{83,-9}},{1090,257,{45,-5}},{1091,257,{38,-5}}, -{1092,257,{57,-10}},{1093,257,{21,-8}},{1094,257,{13,-5}},{1095,257,{9,-3}}, -{1096,257,{26,-6}},{1097,257,{29,-4}},{1098,257,{77,-5}},{1099,257,{34,-3}}, -{1100,256,{34,-3}},{1102,256,{11,0}},{1103,256,{31,-4}},{1104,256,{18,-4}}, -{1105,256,{33,-5}},{1106,256,{18,-4}},{1107,256,{26,-2}},{1108,256,{33,-6}}, -{1109,256,{16,-2}},{1110,256,{7,-2}},{1111,256,{2,-1}},{1112,256,{7,-2}}, -{1113,260,{3,-1}},{1114,260,{5,-2}},{1115,260,{8,0}},{1116,260,{3,0}}, -{1117,260,{30,-2}},{1118,260,{21,-2}},{1119,256,{47,-2}},{1120,256,{25,-2}}, -{1121,256,{28,-4}},{1122,256,{61,-4}},{1123,256,{39,-3}},{1124,256,{37,0}}, -{1125,256,{80,-5}},{1126,256,{21,-2}},{1127,256,{35,-4}},{1128,256,{16,-4}}, -{1129,256,{5,-3}},{1130,256,{25,-6}},{1131,260,{18,-4}},{1132,260,{15,-2}}, -{1133,260,{13,-1}},{1134,260,{5,-2}},{1135,260,{9,-1}},{1136,260,{0,0}}, -{1139,260,{-1,0}},{1140,260,{0,0}},{1140,4,{0,0}},{1145,4,{-1,-1}}, -{1146,4,{-3,-1}},{1147,516,{-3,-1}},{1148,516,{-2,-1}},{1149,516,{-1,0}}, -{1150,516,{0,0}},{1152,516,{-1,-2}},{1153,516,{0,-2}},{1154,516,{-1,0}}, -{1155,516,{-1,-4}},{1155,4,{-1,-4}},{1156,4,{0,0}},{1157,4,{0,-1}}, -{1157,260,{0,-1}},{1158,260,{0,-2}},{1159,260,{0,-3}},{1162,260,{0,-7}}, -{1163,260,{0,-3}},{1164,4,{0,-6}},{1165,4,{4,-13}},{1166,4,{2,-6}}, -{1166,260,{2,-6}},{1167,260,{7,-16}},{1168,260,{3,-5}},{1169,260,{3,-6}}, -{1170,260,{1,-4}},{1171,260,{5,-9}},{1172,260,{3,-5}},{1173,4,{3,-5}}, -{1174,4,{0,0}},{1175,4,{10,-9}},{1176,4,{2,-3}},{1176,260,{2,-3}}, -{1177,260,{3,-5}},{1178,260,{-1,-2}},{1178,256,{-1,-2}},{1179,256,{-4,-8}}, -{1180,256,{-6,-8}},{1181,256,{-13,-12}},{1182,256,{-9,-9}},{1183,256,{-9,-6}}, -{1184,256,{-54,-34}},{1185,256,{-45,-25}},{1186,256,{-107,-56}},{1187,384,{-47,-23}}, -{1188,384,{-38,-17}},{1189,384,{-37,-22}},{1190,384,{-12,-6}},{1191,384,{-15,-9}}, -{1192,384,{-7,-4}},{1193,384,{0,0}},{1195,384,{0,-1}},{1196,384,{-3,-3}}, -{1197,384,{-2,-1}},{1198,384,{0,0}},{1201,384,{13,0}},{1202,384,{82,15}}, -{1203,384,{54,11}},{1204,384,{78,21}},{1205,384,{38,12}},{1206,384,{40,12}}, -{1207,384,{120,39}},{1208,384,{68,23}},{1209,384,{76,26}},{1210,384,{64,23}}, -{1211,388,{48,19}},{1212,388,{42,16}},{1213,388,{63,23}},{1214,388,{117,45}}, -{1215,388,{62,23}},{1216,388,{64,23}},{1216,644,{64,23}},{1217,644,{128,49}}, -{1218,644,{71,24}},{1219,644,{119,48}},{1220,644,{63,23}},{1221,644,{59,22}}, -{1222,644,{131,49}},{1223,644,{71,26}},{1224,644,{78,29}},{1225,644,{151,58}}, -{1226,644,{75,26}},{1227,644,{69,26}},{1228,644,{137,54}},{1229,644,{69,25}}, -{1230,644,{69,26}},{1231,644,{144,52}},{1232,644,{69,26}},{1233,644,{132,47}}, -{1234,644,{63,23}},{1235,644,{71,26}},{1236,644,{143,52}},{1237,640,{70,23}}, -{1238,640,{71,26}},{1239,640,{76,23}},{1240,640,{146,42}},{1241,640,{79,21}}, -{1242,640,{77,21}},{1243,640,{140,38}},{1244,640,{74,21}},{1245,640,{117,39}}, -{1246,640,{59,18}},{1247,640,{19,12}},{1248,897,{0,0}},{1249,897,{-9,-6}}, -{1250,385,{-6,-4}},{1251,385,{-5,-5}},{1252,385,{-4,-5}},{1253,384,{-4,-1}}, -{1254,384,{-13,-2}},{1255,384,{-25,-6}},{1256,384,{-67,-23}},{1257,384,{-47,-16}}, -{1259,384,{-103,-27}},{1260,384,{-44,-9}},{1261,384,{-101,-21}},{1262,384,{-55,-10}}, -{1263,384,{-60,-12}},{1264,384,{-127,-28}},{1265,384,{-66,-15}},{1266,384,{-67,-15}}, -{1267,384,{-126,-24}},{1268,384,{-66,-12}},{1269,384,{-62,-12}},{1270,384,{-128,-21}}, -{1271,384,{-64,-12}},{1272,384,{-66,-15}},{1273,384,{-131,-26}},{1274,384,{-61,-12}}, -{1275,384,{-127,-29}},{1276,384,{-52,-12}},{1277,384,{-58,-14}},{1278,384,{-83,-26}}, -{1279,384,{-24,-10}},{1280,384,{-22,-11}},{1280,385,{-22,-11}},{1281,385,{-21,-15}}, -{1282,385,{-5,-4}},{1283,385,{5,4}},{1284,385,{0,0}},{1287,385,{37,-20}}, -{1288,385,{29,-8}},{1289,128,{36,-3}},{1290,128,{99,15}},{1291,128,{56,15}}, -{1292,640,{120,41}},{1293,640,{70,26}},{1294,640,{68,26}},{1295,640,{140,52}}, -{1296,640,{73,26}},{1297,640,{68,26}},{1298,640,{134,49}},{1299,640,{62,23}}, -{1300,640,{57,20}},{1301,640,{118,41}},{1302,640,{58,21}},{1303,640,{60,18}}, -{1304,640,{133,44}},{1305,640,{65,21}},{1306,640,{73,23}},{1307,641,{150,47}}, -{1308,641,{73,23}},{1309,641,{65,21}},{1310,641,{124,42}},{1311,641,{52,15}}, -{1312,641,{54,18}},{1313,641,{115,36}},{1314,641,{60,18}},{1315,641,{118,34}}, -{1316,641,{40,14}},{1317,641,{46,11}},{1318,129,{34,8}},{1319,129,{0,0}}, -{1321,129,{-2,0}},{1322,129,{0,0}},{1322,385,{0,0}},{1323,385,{0,-1}}, -{1324,385,{0,-2}},{1325,385,{-3,-12}},{1326,385,{-12,-23}},{1327,385,{-41,-57}}, -{1328,385,{-28,-33}},{1329,385,{-56,-62}},{1330,385,{-30,-28}},{1331,385,{-33,-33}}, -{1332,385,{-70,-63}},{1333,385,{-32,-28}},{1334,385,{-35,-29}},{1335,385,{-76,-67}}, -{1336,385,{-35,-29}},{1337,385,{-69,-56}},{1338,385,{-35,-26}},{1339,385,{-43,-32}}, -{1340,385,{-39,-28}},{1341,385,{-75,-49}},{1342,385,{-37,-24}},{1343,385,{-37,-26}}, -{1344,385,{-74,-54}},{1345,385,{-38,-31}},{1346,385,{-70,-57}},{1347,385,{-35,-28}}, -{1348,385,{-24,-22}},{1349,385,{-32,-26}},{1350,385,{-34,-26}},{1351,385,{-35,-28}}, -{1352,385,{-75,-55}},{1353,385,{-35,-24}},{1354,385,{-35,-26}},{1355,385,{-74,-50}}, -{1356,385,{-34,-26}},{1357,385,{-70,-49}},{1358,385,{-37,-26}},{1359,385,{-37,-24}}, -{1360,385,{-34,-23}},{1361,385,{-36,-26}},{1362,385,{-19,-13}},{1363,385,{-35,-24}}, -{1364,385,{-63,-42}},{1365,385,{-33,-26}},{1366,385,{-32,-24}},{1367,385,{-66,-49}}, -{1368,129,{-24,-22}},{1369,129,{-18,-14}},{1370,129,{-29,-31}},{1371,129,{-13,-16}}, -{1372,129,{-10,-14}},{1373,129,{-1,-1}},{1374,129,{0,0}},{1374,641,{0,0}}, -{1375,641,{3,-8}},{1376,641,{19,-11}},{1377,641,{63,-14}},{1378,641,{34,0}}, -{1379,641,{45,4}},{1380,641,{44,5}},{1381,641,{3,0}},{1382,129,{0,0}}, -{1383,129,{-2,0}},{1383,385,{-2,0}},{1384,385,{-3,1}},{1385,385,{0,0}}, -{1386,385,{-1,-3}},{1387,385,{-2,-4}},{1388,385,{-15,-18}},{1389,385,{-19,-15}}, -{1390,385,{-24,-20}},{1391,385,{-57,-43}},{1392,385,{-29,-21}},{1393,385,{-25,-16}}, -{1394,385,{-36,-25}},{1395,385,{-24,-20}},{1396,385,{-37,-24}},{1397,385,{-29,-23}}, -{1398,385,{-30,-23}},{1399,385,{-35,-26}},{1400,129,{-58,-50}},{1401,129,{-17,-19}}, -{1402,129,{-20,-22}},{1403,129,{-18,-16}},{1404,129,{0,0}},{1404,641,{0,0}}, -{1405,641,{-1,-2}},{1406,641,{0,-7}},{1407,641,{9,-29}},{1408,641,{9,-13}}, -{1409,641,{6,-7}},{1410,641,{27,-20}},{1411,641,{22,-12}},{1412,641,{24,-12}}, -{1412,129,{24,-12}},{1413,129,{40,-16}},{1414,129,{16,-9}},{1415,129,{10,-6}}, -{1416,129,{6,-7}},{1417,129,{13,-16}},{1418,129,{9,-12}},{1418,385,{9,-12}}, -{1419,385,{5,-7}},{1420,385,{1,-4}},{1421,385,{6,-9}},{1422,385,{3,-5}}, -{1423,385,{2,-6}},{1424,385,{11,-18}},{1425,385,{7,-15}},{1426,385,{7,-13}}, -{1426,897,{7,-13}},{1427,641,{3,-7}},{1428,641,{10,-19}},{1429,641,{3,-5}}, -{1430,641,{8,-13}},{1431,641,{6,-5}},{1432,641,{7,-9}},{1433,641,{13,-14}}, -{1434,641,{15,-12}},{1435,641,{0,0}},{1436,641,{31,-19}},{1437,641,{14,-9}}, -{1438,641,{17,-7}},{1439,641,{33,-16}},{1440,641,{6,-6}},{1441,641,{0,-1}}, -{1442,641,{0,0}},{1443,641,{5,-7}},{1443,640,{5,-7}},{1444,640,{0,-1}}, -{1446,640,{-1,-2}},{1447,640,{-3,-8}},{1448,640,{-32,-47}},{1449,640,{-29,-35}}, -{1450,640,{-33,-33}},{1451,640,{-74,-74}},{1452,640,{-32,-30}},{1452,896,{-32,-30}}, -{1453,896,{-16,-16}},{1454,896,{-55,-49}},{1455,896,{-38,-34}},{1456,640,{-72,-55}}, -{1457,640,{-38,-26}},{1458,640,{-47,-31}},{1459,640,{-86,-47}},{1460,640,{-41,-20}}, -{1461,640,{-36,-19}},{1462,640,{-56,-32}},{1462,512,{-56,-32}},{1463,512,{-28,-16}}, -{1464,512,{-42,-20}},{1465,512,{-72,-34}},{1466,512,{-40,-20}},{1467,512,{-37,-20}}, -{1467,768,{-37,-20}},{1468,768,{-28,-16}},{1469,768,{-7,-6}},{1470,768,{-4,-4}}, -{1471,768,{-7,-6}},{1472,768,{0,0}},{1473,768,{-3,-3}},{1474,768,{-5,-5}}, -{1475,257,{-1,-1}},{1476,257,{-3,-3}},{1477,257,{-1,-1}},{1478,257,{0,-4}}, -{1479,257,{1,-6}},{1480,385,{11,-13}},{1481,385,{7,-9}},{1482,385,{13,-12}}, -{1483,385,{28,-24}},{1484,385,{21,-11}},{1485,385,{24,-10}},{1486,385,{62,-15}}, -{1487,385,{34,-7}},{1488,385,{29,-4}},{1488,384,{29,-4}},{1489,384,{31,-6}}, -{1490,384,{31,-4}},{1491,384,{34,-5}},{1492,384,{38,-6}},{1493,384,{25,-2}}, -{1494,384,{13,-4}},{1495,384,{45,-6}},{1496,384,{26,-4}},{1497,384,{26,-6}}, -{1498,384,{45,-6}},{1498,388,{45,-6}},{1499,388,{18,-2}},{1500,388,{32,-2}}, -{1501,388,{16,-2}},{1502,388,{7,0}},{1503,388,{15,-2}},{1504,644,{9,-2}}, -{1505,644,{17,0}},{1506,644,{6,0}},{1507,644,{3,0}},{1508,644,{0,-1}}, -{1509,644,{0,0}},{1510,644,{-3,1}},{1511,644,{0,0}},{1512,644,{-3,-1}}, -{1513,644,{-4,-1}},{1514,644,{-12,-5}},{1515,644,{-20,-9}},{1516,644,{-80,-37}}, -{1517,644,{-54,-24}},{1518,644,{-58,-21}},{1519,644,{-112,-39}},{1520,644,{-52,-16}}, -{1521,644,{-51,-14}},{1522,644,{-117,-32}},{1523,644,{-69,-20}},{1524,644,{0,0}}, -{1525,644,{-159,-49}},{1526,644,{-84,-25}},{1527,644,{-149,-46}},{1528,644,{-78,-22}}, -{1529,644,{-68,-22}},{1530,644,{-151,-44}},{1531,644,{-72,-20}},{1532,644,{-63,-21}}, -{1533,644,{-152,-39}},{1533,900,{-152,-39}},{1534,900,{-80,-22}},{1535,900,{-80,-20}}, -{1536,900,{-155,-32}},{1537,388,{-66,-15}},{1538,388,{-77,-15}},{1539,388,{-138,-29}}, -{1540,388,{-72,-17}},{1541,388,{-78,-20}},{1542,388,{-149,-36}},{1543,388,{-81,-20}}, -{1544,388,{-159,-35}},{1545,388,{-78,-17}},{1546,388,{-55,-16}},{1546,384,{-55,-16}}, -{1547,384,{-49,-13}},{1548,384,{-72,-17}},{1549,384,{-72,-22}},{1550,384,{-78,-22}}, -{1551,384,{-107,-34}},{1552,384,{-58,-19}},{1553,384,{-67,-19}},{1554,384,{-91,-29}}, -{1555,384,{-49,-16}},{1556,384,{-36,-13}},{1557,384,{-38,-13}},{1558,384,{-50,-14}}, -{1559,384,{-29,-10}},{1559,256,{-29,-10}},{1560,256,{-38,-18}},{1561,256,{0,0}}, -{1562,513,{4,3}},{1563,513,{2,5}},{1564,513,{12,-10}},{1565,513,{32,-18}}, -{1566,513,{19,-7}},{1567,513,{16,-4}},{1568,513,{35,-3}},{1569,513,{45,0}}, -{1570,513,{53,2}},{1571,513,{116,6}},{1572,513,{59,2}},{1573,641,{48,4}}, -{1574,641,{93,6}},{1575,641,{43,2}},{1576,641,{36,4}},{1577,641,{44,3}}, -{1578,641,{11,1}},{1579,641,{2,0}},{1580,641,{0,0}},{1581,641,{-1,0}}, -{1581,129,{-1,0}},{1582,129,{-4,2}},{1583,257,{-1,-1}},{1584,257,{0,0}}, -{1585,257,{-11,-4}},{1586,257,{-52,-21}},{1587,257,{-41,-13}},{1588,257,{-49,-16}}, -{1589,257,{-112,-39}},{1590,257,{-42,-16}},{1591,257,{-98,-36}},{1592,257,{-48,-18}}, -{1593,257,{-47,-18}},{1594,257,{-85,-35}},{1595,257,{-36,-17}},{1596,257,{-13,-8}}, -{1597,257,{-7,-7}},{1598,257,{-2,-2}},{1599,257,{2,5}},{1600,257,{2,-3}}, -{1601,1,{38,-18}},{1602,1,{23,-4}},{1603,1,{28,-4}},{1603,129,{28,-4}}, -{1604,129,{34,-5}},{1605,129,{90,-5}},{1606,129,{50,0}},{1607,129,{59,0}}, -{1608,641,{122,4}},{1609,641,{58,2}},{1610,641,{51,4}},{1611,641,{96,4}}, -{1612,641,{47,2}},{1613,641,{55,2}},{1614,641,{81,4}},{1615,641,{20,0}}, -{1616,641,{37,-3}},{1617,641,{11,-3}},{1618,641,{1,-2}},{1619,641,{0,0}}, -{1619,385,{0,0}},{1622,385,{0,-1}},{1623,385,{-10,-24}},{1624,385,{-13,-16}}, -{1625,385,{-22,-22}},{1626,385,{-68,-61}},{1627,385,{-41,-34}},{1628,385,{-83,-63}}, -{1629,385,{-40,-27}},{1630,385,{-32,-21}},{1631,385,{-67,-40}},{1632,385,{-39,-22}}, -{1633,385,{-39,-24}},{1634,385,{-95,-48}},{1635,385,{-42,-25}},{1636,385,{-87,-45}}, -{1637,385,{-18,-13}},{1638,385,{-21,-15}},{1639,385,{-21,-13}},{1640,385,{-10,-11}}, -{1641,385,{-7,-6}},{1642,385,{-15,-12}},{1643,385,{-5,-5}},{1645,385,{-2,-2}}, -{1646,385,{0,0}},{1647,385,{2,-6}},{1648,385,{42,-22}},{1649,385,{37,-11}}, -{1650,385,{92,-9}},{1651,385,{53,0}},{1652,385,{65,2}},{1653,385,{143,14}}, -{1654,385,{79,11}},{1655,385,{73,11}},{1656,385,{102,13}},{1657,385,{26,3}}, -{1658,385,{0,0}},{1659,385,{25,2}},{1660,385,{128,11}},{1661,385,{67,6}}, -{1662,385,{72,9}},{1663,385,{54,9}},{1664,257,{59,6}},{1665,257,{87,10}}, -{1666,257,{52,6}},{1667,257,{33,1}},{1668,257,{23,1}},{1668,256,{23,1}}, -{1669,256,{41,1}},{1670,256,{29,-2}},{1671,256,{31,-9}},{1672,256,{35,-13}}, -{1673,256,{37,-11}},{1674,256,{68,-21}},{1674,257,{68,-21}},{1675,257,{39,-11}}, -{1676,257,{38,-11}},{1677,257,{79,-17}},{1678,257,{34,-5}},{1679,257,{45,-7}}, -{1680,257,{78,-9}},{1681,257,{40,-5}},{1682,385,{34,-7}},{1683,385,{33,-9}}, -{1684,384,{5,-3}},{1685,384,{7,-4}},{1686,384,{37,-11}},{1687,384,{23,-6}}, -{1688,384,{26,-6}},{1689,384,{30,-5}},{1690,384,{24,-2}},{1691,384,{16,-2}}, -{1692,384,{11,0}},{1693,384,{20,1}},{1694,384,{39,8}},{1695,384,{16,4}}, -{1696,384,{0,0}},{1696,388,{0,0}},{1697,388,{16,7}},{1698,388,{18,11}}, -{1699,388,{0,0}},{1701,388,{2,2}},{1702,388,{9,10}},{1703,388,{13,11}}, -{1704,388,{15,11}},{1705,388,{46,33}},{1706,644,{28,18}},{1707,644,{42,21}}, -{1708,644,{4,6}},{1709,644,{0,0}},{1710,644,{1,1}},{1711,644,{0,0}}, -{1712,644,{0,3}},{1713,644,{0,2}},{1714,644,{-3,7}},{1715,644,{-3,2}}, -{1716,644,{-2,2}},{1717,644,{-22,16}},{1718,644,{-17,8}},{1719,644,{-17,6}}, -{1720,644,{-47,16}},{1721,644,{-29,5}},{1722,644,{-31,1}},{1723,644,{-75,1}}, -{1724,644,{-48,-5}},{1725,644,{-55,-7}},{1726,644,{-111,-25}},{1727,644,{-57,-12}}, -{1728,644,{-104,-28}},{1729,644,{-43,-13}},{1730,644,{-58,-19}},{1731,644,{-50,-18}}, -{1732,644,{-65,-27}},{1733,644,{-25,-12}},{1734,644,{-5,-4}},{1735,644,{0,0}}, -{1736,644,{3,3}},{1737,644,{0,0}},{1739,644,{0,-2}},{1740,644,{32,-21}}, -{1740,900,{32,-21}},{1741,900,{25,-6}},{1742,900,{38,-5}},{1743,900,{31,-2}}, -{1744,900,{48,0}},{1745,900,{34,2}},{1746,900,{68,6}},{1747,900,{34,2}}, -{1748,900,{45,8}},{1748,644,{45,8}},{1749,644,{112,22}},{1750,644,{62,11}}, -{1751,644,{64,13}},{1752,644,{117,25}},{1753,644,{60,13}},{1754,644,{115,30}}, -{1755,644,{57,13}},{1756,644,{62,18}},{1757,644,{125,39}},{1758,644,{62,18}}, -{1759,644,{51,17}},{1760,644,{109,34}},{1761,644,{54,15}},{1762,644,{57,16}}, -{1763,132,{122,39}},{1764,132,{59,16}},{1765,132,{59,18}},{1766,132,{104,26}}, -{1767,132,{53,15}},{1768,132,{51,15}},{1769,132,{63,20}},{1770,132,{12,6}}, -{1771,132,{0,0}},{1771,164,{0,0}},{1772,164,{-10,-7}},{1773,164,{2,4}}, -{1774,676,{3,4}},{1775,676,{0,3}},{1776,676,{0,0}},{1778,676,{4,9}}, -{1779,676,{5,8}},{1780,676,{6,6}},{1781,676,{17,14}},{1782,644,{7,3}}, -{1783,640,{33,11}},{1784,640,{22,5}},{1785,640,{32,2}},{1786,640,{62,3}}, -{1787,640,{42,0}},{1788,640,{45,0}},{1789,640,{82,-3}},{1790,768,{39,0}}, -{1792,769,{63,0}},{1793,257,{30,0}},{1794,257,{25,1}},{1795,257,{54,3}}, -{1796,257,{23,0}},{1797,769,{16,1}},{1798,769,{42,5}},{1799,769,{26,1}}, -{1800,769,{29,5}},{1801,769,{55,11}},{1802,257,{21,3}},{1803,257,{5,2}}, -{1804,257,{40,8}},{1805,257,{20,3}},{1806,257,{23,3}},{1807,257,{7,1}}, -{1808,257,{0,0}},{1809,385,{1,0}},{1810,385,{13,1}},{1811,385,{9,1}}, -{1812,384,{16,2}},{1813,384,{13,1}},{1814,384,{9,1}},{1815,384,{17,2}}, -{1816,384,{4,2}},{1817,384,{3,1}},{1818,384,{0,0}},{1819,896,{0,0}}, -{1824,896,{-1,0}},{1825,640,{-2,0}},{1826,640,{0,0}},{1830,640,{9,-2}}, -{1831,640,{15,-4}},{1832,640,{34,-3}},{1833,640,{98,-7}},{1834,640,{59,-3}}, -{1835,640,{53,-3}},{1836,640,{115,-7}},{1837,641,{54,-5}},{1838,641,{124,-10}}, -{1839,513,{67,-5}},{1840,513,{70,-3}},{1841,513,{110,-7}},{1842,1,{28,-4}}, -{1842,257,{28,-4}},{1843,257,{1,-1}},{1844,257,{0,0}},{1845,257,{-14,3}}, -{1846,257,{-8,3}},{1847,257,{-2,1}},{1848,257,{-1,-1}},{1849,256,{-15,-7}}, -{1850,256,{-46,-17}},{1851,256,{-28,-10}},{1852,256,{-66,-19}},{1853,256,{-47,-11}}, -{1854,256,{-45,-11}},{1855,256,{-107,-19}},{1856,256,{-57,-7}},{1857,256,{-46,-11}}, -{1858,256,{-78,-17}},{1859,256,{-33,-9}},{1860,256,{-99,-21}},{1861,256,{-49,-12}}, -{1862,256,{-95,-20}},{1863,256,{-42,-9}},{1864,256,{-32,-8}},{1865,256,{-25,-10}}, -{1866,256,{-54,-18}},{1867,256,{-23,-10}},{1868,256,{-63,-27}},{1869,257,{-15,-7}}, -{1870,257,{-24,-10}},{1871,257,{-24,-8}},{1872,257,{-39,-16}},{1873,257,{-20,-8}}, -{1874,257,{-10,-8}},{1875,257,{-2,-2}},{1876,257,{-8,-8}},{1877,257,{-5,-5}}, -{1878,257,{-3,-3}},{1880,257,{0,0}},{1881,385,{0,0}},{1882,385,{22,-12}}, -{1883,385,{27,-8}},{1884,385,{0,0}},{1885,385,{26,-8}},{1886,385,{18,-4}}, -{1887,385,{28,-4}},{1888,385,{106,2}},{1889,385,{70,7}},{1890,385,{76,7}}, -{1891,385,{142,16}},{1892,385,{45,6}},{1893,385,{51,6}},{1894,385,{65,11}}, -{1895,385,{73,11}},{1896,385,{85,19}},{1897,385,{169,38}},{1898,385,{82,21}}, -{1899,384,{59,13}},{1900,384,{132,27}},{1901,384,{73,11}},{1902,384,{77,12}}, -{1903,384,{85,14}},{1904,256,{85,14}},{1905,256,{164,31}},{1906,256,{72,14}}, -{1907,256,{43,12}},{1908,256,{102,26}},{1909,256,{57,15}},{1910,256,{37,16}}, -{1911,256,{61,30}},{1912,256,{10,7}},{1913,0,{0,1}},{1914,0,{-11,-8}}, -{1915,0,{-7,-6}},{1916,0,{0,0}},{1917,0,{-4,8}},{1918,0,{-6,7}}, -{1919,0,{0,0}},{1920,0,{-10,8}},{1921,0,{-26,19}},{1922,0,{-6,3}}, -{1923,0,{-19,11}},{1924,0,{-18,6}},{1925,0,{-20,8}},{1926,0,{-41,14}}, -{1927,0,{-27,7}},{1928,0,{-30,7}},{1929,0,{-29,4}},{1930,0,{-1,0}}, -{1931,0,{-2,0}},{1932,0,{0,0}},{1933,16384,{0,0}},{1934,16384,{0,1}}, -{1940,0,{0,1}},{1968,4,{0,1}},{1970,0,{0,1}},{1975,4,{0,1}}, -{1978,0,{0,1}},{1984,4,{0,1}},{1986,0,{0,1}},{1992,4,{0,1}}, -{1995,0,{0,1}},{2000,4,{0,1}},{2003,0,{0,1}},{2006,4,{0,1}}, -{2011,0,{0,1}},{2019,16,{0,1}},{4294967295,0,{0,0}} -}; - -DemoRecord playRecord; -uint32_t playRecordIndex = 0; -int8_t playEnd = 0; - -void demoPlayStep() -{ - if (playRecordIndex == 0) - playRecord = demoPlay[playRecordIndex]; - - if (playEnd) - return; - - DemoRecord nextRecord = demoPlay[playRecordIndex + 1]; - - playEnd = nextRecord.frame == UINT32_MAX_VALUE; - - if (playEnd) - { - puts("demo end reached"); - } - else if (SFG_game.frame >= nextRecord.frame) - { - playRecord = nextRecord; - playRecordIndex++; - } -} - -int8_t demoKeyPressed(uint8_t key) -{ - return (playRecord.keyStates & (((uint16_t) 0x01) << key)) != 0; -} - -void demoGetMouseOffset(int16_t *x, int16_t *y) -{ - *x = playRecord.mouseOffset[0]; - *y = playRecord.mouseOffset[1]; -} - -void demoRecordPrint() -{ - printf("recorded demo:"); - - for (uint32_t i = 0; i < demoRecLength; ++i) - { - DemoRecord record = demoRec[i]; - - if (i % 4 == 0) - putchar('\n'); - - printf("{%lu,%d,{%d,%d}},",record.frame,record.keyStates,record.mouseOffset[0],record.mouseOffset[1]); - } - - printf("{%lu,0,{0,0}}",UINT32_MAX_VALUE); // terminate demo -} - -#endif // guard diff --git a/main_gbmeta/game.h b/main_gbmeta/game.h deleted file mode 100755 index 7676678..0000000 --- a/main_gbmeta/game.h +++ /dev/null @@ -1,4862 +0,0 @@ -/** - @file game.h - - Main source file of Anarch the game that puts together all the pieces. main - game logic is implemented here. - - Physics notes (you can break this when messing with constants): - - - Lowest ceiling under which player can fit is 4 height steps. - - Widest hole over which player can run without jumping is 1 square. - - Widest hole over which the player can jump is 3 squares. - - Highest step a player can walk onto without jumping is 2 height steps. - - Highest step a player can jump onto is 3 height steps. - - by Miloslav Ciz (drummyfish), 2019 - - Released under CC0 1.0 (https://creativecommons.org/publicdomain/zero/1.0/) - plus a waiver of all other intellectual property. The goal of this work is - be and remain completely in the public domain forever, available for any use - whatsoever. -*/ - -#ifndef _SFG_GAME_H -#define _SFG_GAME_H - -#include // Needed for fixed width types, can easily be replaced. - -/* - The following keys are mandatory to be implemented on any platform in order - for the game to be playable. Enums are bloat. -*/ -#define SFG_KEY_UP 0 -#define SFG_KEY_RIGHT 1 -#define SFG_KEY_DOWN 2 -#define SFG_KEY_LEFT 3 -#define SFG_KEY_A 4 ///< fire, confirm -#define SFG_KEY_B 5 ///< cancel, strafe, look up/down -#define SFG_KEY_C 6 ///< menu, jump, switch weapons - -/* - The following keys are optional for a platform to implement. They just make - the controls more comfortable. -*/ -#define SFG_KEY_JUMP 7 -#define SFG_KEY_STRAFE_LEFT 8 -#define SFG_KEY_STRAFE_RIGHT 9 -#define SFG_KEY_MAP 10 -#define SFG_KEY_TOGGLE_FREELOOK 11 -#define SFG_KEY_NEXT_WEAPON 12 -#define SFG_KEY_PREVIOUS_WEAPON 13 -#define SFG_KEY_MENU 14 -#define SFG_KEY_CYCLE_WEAPON 15 - -#define SFG_KEY_COUNT 16 ///< Number of keys. - -/* ============================= PORTING =================================== */ - -/* When porting, do the following: - - Include this file (and possibly other optional files, like sounds.h) in - your main_*.c frontend source. - - Implement the following functions in your frontend source. - - Call SFG_init() from your frontend initialization code. - - Call SFG_mainLoopBody() from within your frontend main loop. */ - -#ifndef SFG_LOG - #define SFG_LOG(str) {} ///< Can be redefined to log game messages. -#endif - -#ifndef SFG_CPU_LOAD - #define SFG_CPU_LOAD(percent) {} ///< Can be redefined to check CPU load in %. -#endif - -#ifndef SFG_GAME_STEP_COMMAND - #define SFG_GAME_STEP_COMMAND {} /**< Will be called each simlation step (good - for creating deterministic behavior such as - demos (SFG_mainLoopBody() calls potentially - multiple simulation steps). */ -#endif - -/** - Returns 1 (0) if given key is pressed (not pressed). At least the mandatory - keys have to be implemented, the optional keys don't have to ever return 1. - See the key constant definitions to see which ones are mandatory. -*/ -int8_t SFG_keyPressed(uint8_t key); - -/** - Optinal function for mouse/joystick/analog controls, gets mouse x and y offset - in pixels from the game screen center (to achieve classic FPS mouse controls - the platform should center the mouse after this call). If the platform isn't - using a mouse, this function can simply return [0,0] offset at each call, or - even do nothing at all (leave the variables as are). -*/ -void SFG_getMouseOffset(int16_t *x, int16_t *y); - -/** - Returns time in milliseconds sice program start. -*/ -uint32_t SFG_getTimeMs(); - -/** - Sleep (yield CPU) for specified amount of ms. This is used to relieve CPU - usage. If your platform doesn't need this or handles it in other way, this - function can do nothing. -*/ -void SFG_sleepMs(uint16_t timeMs); - -/** - Set specified screen pixel. ColorIndex is the index of the game's palette. - The function doesn't have to (and shouldn't, for the sake of performance) - check whether the coordinates are within screen bounds. -*/ -static inline void SFG_setPixel(uint16_t x, uint16_t y, uint8_t colorIndex); - -/** - Play given sound effect (SFX). This function may or may not use the sound - samples provided in sounds.h, and it may or may not ignore the (logarithmic) - volume parameter (0 to 255). Depending on the platform, the function can play - completely different samples or even e.g. just beeps. If the platform can't - play sounds, this function implementation can simply be left empty. This - function doesn't have to implement safety measures, the back end takes cares - of them. -*/ -void SFG_playSound(uint8_t soundIndex, uint8_t volume); - -#define SFG_MUSIC_TURN_OFF 0 -#define SFG_MUSIC_TURN_ON 1 -#define SFG_MUSIC_NEXT 2 - -/** - Informs the frontend how music should play, e.g. turn on/off, change track, - ... See SFG_MUSIC_* constants. Playing music is optional and the frontend may - ignore this. If a frontend wants to implement music, it can use the bytebeat - provided in sounds.h or use its own. -*/ -void SFG_setMusic(uint8_t value); - -#define SFG_EVENT_VIBRATE 0 ///< the controller should vibrate (or blink etc.) -#define SFG_EVENT_PLAYER_HURT 1 -#define SFG_EVENT_PLAYER_DIES 2 -#define SFG_EVENT_LEVEL_STARTS 3 -#define SFG_EVENT_LEVEL_WON 4 -#define SFG_EVENT_MONSTER_DIES 5 -#define SFG_EVENT_PLAYER_TAKES_ITEM 6 -#define SFG_EVENT_EXPLOSION 7 -#define SFG_EVENT_PLAYER_TELEPORTS 8 -#define SFG_EVENT_PLAYER_CHANGES_WEAPON 9 - -/** - This is an optional function that informs the frontend about special events - which may trigger something special on the platform, such as a controller - vibration, logging etc. The implementation of this function may be left empty. -*/ -void SFG_processEvent(uint8_t event, uint8_t data); - -#define SFG_SAVE_SIZE 12 ///< size of the save in bytes - -/** - Optional function for permanently saving the game state. Platforms that don't - have permanent storage (HDD, EEPROM etc.) may let this function simply do - nothing. If implemented, the function should save the passed data into its - permanent storage, e.g. a file, a cookie etc. -*/ -void SFG_save(uint8_t data[SFG_SAVE_SIZE]); - -/** - Optional function for retrieving game data that were saved to permanent - storage. Platforms without permanent storage may let this function do nothing. - If implemented, the function should fill the passed array with data from - permanent storage, e.g. a file, a cookie etc. - - If this function is called before SFG_save was ever called and no data is - present in permanent memory, this function should do nothing (leave the data - array as is). - - This function should return 1 if saving/loading is possible or 0 if not (this - will be used by the game to detect saving/loading capability). -*/ -uint8_t SFG_load(uint8_t data[SFG_SAVE_SIZE]); - -/* ========================================================================= */ - -/** - Main game loop body, call this inside your platform's specific main loop. - Returns 1 if the game continues or 0 if the game was exited and program should - halt. This functions handles reaching the target FPS and sleeping for - relieving CPU, so don't do this. -*/ -uint8_t SFG_mainLoopBody(); - -/** - Initializes the game, call this in the platform's initialization code. -*/ -void SFG_init(); - -#include "settings.h" - -#if SFG_ARDUINO - #include - - #define SFG_PROGRAM_MEMORY const PROGMEM - #define SFG_PROGRAM_MEMORY_U8(addr) pgm_read_byte(addr) -#else - #define SFG_PROGRAM_MEMORY static const - #define SFG_PROGRAM_MEMORY_U8(addr) ((uint8_t) (*(addr))) -#endif - -#include "images.h" // don't change the order of these includes -#include "levels.h" -#include "texts.h" -#include "palette.h" - -#if SFG_TEXTURE_DISTANCE == 0 - #define RCL_COMPUTE_WALL_TEXCOORDS 0 -#endif - -#define RCL_PIXEL_FUNCTION SFG_pixelFunc -#define RCL_TEXTURE_VERTICAL_STRETCH 0 - -#define RCL_CAMERA_COLL_HEIGHT_BELOW 800 -#define RCL_CAMERA_COLL_HEIGHT_ABOVE 200 - -#define RCL_HORIZONTAL_FOV SFG_FOV_HORIZONTAL -#define RCL_VERTICAL_FOV SFG_FOV_VERTICAL - -#include "raycastlib.h" - -#include "constants.h" - -typedef struct -{ - uint8_t coords[2]; - uint8_t state; /**< door state in format: - - MSB ccbaaaaa LSB - - aaaaa: current door height (how much they're open) - b: whether currently going up (0) or down (1) - cc: by which card (key) the door is unlocked, 00 - means no card (unlocked), 1 means card 0 etc. */ -} SFG_DoorRecord; - -#define SFG_SPRITE_SIZE(size0to3) \ - (((size0to3 + 3) * SFG_BASE_SPRITE_SIZE) / 4) - -#define SFG_SPRITE_SIZE_PIXELS(size0to3) \ - ((SFG_SPRITE_SIZE(size0to3) * SFG_GAME_RESOLUTION_Y) / RCL_UNITS_PER_SQUARE) - -#define SFG_SPRITE_SIZE_TO_HEIGHT_ABOVE_GROUND(size0to3) \ - (SFG_SPRITE_SIZE(size0to3) / 2) - -/** - Holds information about one instance of a level item (a type of level element, - e.g. pickable items, decorations etc.). The format is following: - - MSB abbbbbbb LSB - - a: active flag, 1 means the item is nearby to player and is active - bbbbbbb: index to elements array of the current level, pointing to element - representing this item -*/ -typedef uint8_t SFG_ItemRecord; - -#define SFG_ITEM_RECORD_ACTIVE_MASK 0x80 - -#define SFG_ITEM_RECORD_LEVEL_ELEMENT(itemRecord) \ - (SFG_currentLevel.levelPointer->elements[itemRecord & \ - ~SFG_ITEM_RECORD_ACTIVE_MASK]) - -typedef struct -{ - uint8_t stateType; /**< Holds state (lower 4 bits) and type of monster (upper - 4 bits). */ - uint8_t coords[2]; /**< monster position, in 1/4s of a square */ - uint8_t health; -} SFG_MonsterRecord; - -#define SFG_MR_STATE(mr) ((mr).stateType & SFG_MONSTER_MASK_STATE) -#define SFG_MR_TYPE(mr) \ - (SFG_MONSTER_INDEX_TO_TYPE(((mr).stateType & SFG_MONSTER_MASK_TYPE) >> 4)) - -#define SFG_MONSTER_COORD_TO_RCL_UNITS(c) ((RCL_UNITS_PER_SQUARE / 8) + c * 256) -#define SFG_MONSTER_COORD_TO_SQUARES(c) (c / 4) - -#define SFG_ELEMENT_COORD_TO_RCL_UNITS(c) \ - (c * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2) - -#define SFG_MONSTER_MASK_STATE 0x0f -#define SFG_MONSTER_MASK_TYPE 0xf0 - -#define SFG_MONSTER_STATE_INACTIVE 0 ///< Not nearby, not actively updated. -#define SFG_MONSTER_STATE_IDLE 1 -#define SFG_MONSTER_STATE_ATTACKING 2 -#define SFG_MONSTER_STATE_HURTING 3 -#define SFG_MONSTER_STATE_DYING 4 -#define SFG_MONSTER_STATE_GOING_N 5 -#define SFG_MONSTER_STATE_GOING_NE 6 -#define SFG_MONSTER_STATE_GOING_E 7 -#define SFG_MONSTER_STATE_GOING_SE 8 -#define SFG_MONSTER_STATE_GOING_S 9 -#define SFG_MONSTER_STATE_GOING_SW 10 -#define SFG_MONSTER_STATE_GOING_W 11 -#define SFG_MONSTER_STATE_GOING_NW 12 -#define SFG_MONSTER_STATE_DEAD 13 - -typedef struct -{ - uint8_t type; - uint8_t doubleFramesToLive; /**< This number times two (because 255 could be - too little at high FPS) says after how many - frames the projectile is destroyed. */ - uint16_t position[3]; /**< Current position, stored as u16 to save space, as - that is exactly enough to store position on 64x64 - map. */ - int16_t direction[3]; /**< Added to position each game step. */ -} SFG_ProjectileRecord; - -#define SFG_GAME_STATE_INIT 0 ///< first state, waiting for key releases -#define SFG_GAME_STATE_PLAYING 1 -#define SFG_GAME_STATE_WIN 2 -#define SFG_GAME_STATE_LOSE 3 -#define SFG_GAME_STATE_INTRO 4 -#define SFG_GAME_STATE_OUTRO 5 -#define SFG_GAME_STATE_MAP 6 -#define SFG_GAME_STATE_LEVEL_START 7 -#define SFG_GAME_STATE_MENU 8 - -#define SFG_MENU_ITEM_CONTINUE 0 -#define SFG_MENU_ITEM_MAP 1 -#define SFG_MENU_ITEM_PLAY 2 -#define SFG_MENU_ITEM_LOAD 3 -#define SFG_MENU_ITEM_SOUND 4 -#define SFG_MENU_ITEM_SHEAR 5 -#define SFG_MENU_ITEM_EXIT 6 - -#define SFG_MENU_ITEM_NONE 255 - -/* - GLOBAL VARIABLES -=============================================================================== -*/ - -/** - Groups global variables related to the game as such in a single struct. There - are still other global structs for player, level etc. -*/ -struct -{ - uint8_t state; ///< Current game state. - uint32_t stateChangeTime; ///< Time in ms at which the state was changed. - uint8_t currentRandom; ///< for RNG - uint8_t spriteAnimationFrame; - uint8_t soundsPlayedThisFrame; /**< Each bit says whether given sound was - played this frame, prevents playing too many - sounds at once. */ - RCL_RayConstraints rayConstraints; - uint8_t keyStates[SFG_KEY_COUNT]; /**< Pressed states of keys, each value - stores the number of frames for which the - key has been held. */ - uint8_t zBuffer[SFG_Z_BUFFER_SIZE]; - uint8_t textureAverageColors[SFG_WALL_TEXTURE_COUNT]; /**< Contains average - color for each wall texture. */ - int8_t backgroundScaleMap[SFG_GAME_RESOLUTION_Y]; - uint16_t backgroundScroll; - uint8_t spriteSamplingPoints[SFG_MAX_SPRITE_SIZE]; /**< Helper for - precomputing sprite - sampling positions for - drawing. */ - uint32_t frameTime; ///< time (in ms) of the current frame start - uint32_t frame; ///< frame number - uint8_t selectedMenuItem; - uint8_t selectedLevel; ///< level to play selected in the main menu - uint8_t antiSpam; ///< Prevents log message spamming. - uint8_t settings; /**< dynamic game settings (can be changed at runtime), - bit meaning: - - MSB -------- LSB - |||| - |||\_ sound (SFX) - ||\__ music - |\___ shearing - \____ freelook (shearing not sliding back) */ - uint8_t blink; ///< Says whether blinkg is currently on or off. - uint8_t saved; /**< Helper variable to know if game was saved. Can be - 0 (not saved), 1 (just saved) or 255 (can't save).*/ - uint8_t save[SFG_SAVE_SIZE]; /**< Stores the game save state that's kept in - the persistent memory. - - The save format is binary and platform independent. - The save contains game settings, game progress and a - saved position. The format is as follows: - - 0 4b highest level that has been reached - 0 4b level number of the saved position (15: no save) - 1 8b game settings (SFG_game.settings) - 2 8b health at saved position - 3 8b bullet ammo at saved position - 4 8b rocket ammo at saved position - 5 8b plasma ammo at saved position - 6 32b little endian total play time, in 10ths of sec - 10 16b little endian total enemies killed from start */ - uint8_t continues; ///< Whether the game continues or was exited. -} SFG_game; - -#define SFG_SAVE_TOTAL_TIME (SFG_game.save[6] + SFG_game.save[7] * 256 + \ - SFG_game.save[8] * 65536 + SFG_game.save[9] * 4294967296) - -/** - Stores player state. -*/ -struct -{ - RCL_Camera camera; - int8_t squarePosition[2]; - RCL_Vector2D direction; - RCL_Unit verticalSpeed; - RCL_Unit previousVerticalSpeed; /**< Vertical speed in previous frame, needed - for determining whether player is in the - air. */ - uint16_t headBobFrame; - uint8_t weapon; ///< currently selected weapon - uint8_t health; - uint32_t weaponCooldownFrames; ///< frames left for weapon cooldow - uint32_t lastHurtFrame; - uint32_t lastItemTakenFrame; - uint8_t ammo[SFG_AMMO_TOTAL]; - uint8_t cards; /**< Lowest 3 bits say which access cards - have been taken., the next 3 bits say - which cards should be blinking in the HUD, - the last 2 bits are a blink reset counter. */ - uint8_t justTeleported; - int8_t previousWeaponDirection; ///< Direction (+/0/-) of previous weapon. -} SFG_player; - -/** - Stores the current level and helper precomputed vaues for better performance. -*/ -struct -{ - const SFG_Level *levelPointer; - uint8_t levelNumber; - const uint8_t* textures[7]; ///< textures the level is using - uint32_t timeStart; - uint32_t frameStart; - uint32_t completionTime10sOfS; ///< completion time in 10th of second - uint8_t floorColor; - uint8_t ceilingColor; - - SFG_DoorRecord doorRecords[SFG_MAX_DOORS]; - uint8_t doorRecordCount; - uint8_t checkedDoorIndex; ///< Says which door are currently being checked. - - SFG_ItemRecord itemRecords[SFG_MAX_ITEMS]; ///< Holds level items. - uint8_t itemRecordCount; - uint8_t checkedItemIndex; ///< Same as checkedDoorIndex, but for items. - - SFG_MonsterRecord monsterRecords[SFG_MAX_MONSTERS]; - uint8_t monsterRecordCount; - uint8_t checkedMonsterIndex; - - SFG_ProjectileRecord projectileRecords[SFG_MAX_PROJECTILES]; - uint8_t projectileRecordCount; - uint8_t bossCount; - uint8_t monstersDead; - uint8_t backgroundImage; - uint8_t teleporterCount; - uint16_t mapRevealMask; /**< Bits say which parts of the map have been - revealed. */ - uint8_t itemCollisionMap[(SFG_MAP_SIZE * SFG_MAP_SIZE) / 8]; - /**< Bit array, for each map square says whether there - is a colliding item or not. */ -} SFG_currentLevel; - -#if SFG_ARDUINO -/** - Copy of the current level that is stored in RAM. This is only done on Arduino - because accessing it in program memory (PROGMEM) directly would be a pain. - Because of this Arduino needs more RAM. -*/ -SFG_Level SFG_ramLevel; -#endif - -/** - Helper function for accessing the itemCollisionMap bits. -*/ -void SFG_getItemCollisionMapIndex( - uint8_t x, uint8_t y, uint16_t *byte, uint8_t *bit) -{ - uint16_t index = y * SFG_MAP_SIZE + x; - - *byte = index / 8; - *bit = index % 8; -} - -void SFG_setItemCollisionMapBit(uint8_t x, uint8_t y, uint8_t value) -{ - uint16_t byte; - uint8_t bit; - - SFG_getItemCollisionMapIndex(x,y,&byte,&bit); - - SFG_currentLevel.itemCollisionMap[byte] &= ~(0x01 << bit); - SFG_currentLevel.itemCollisionMap[byte] |= (value & 0x01) << bit; -} - -uint8_t SFG_getItemCollisionMapBit(uint8_t x, uint8_t y) -{ - uint16_t byte; - uint8_t bit; - - SFG_getItemCollisionMapIndex(x,y,&byte,&bit); - return (SFG_currentLevel.itemCollisionMap[byte] >> bit) & 0x01; -} - -#if SFG_DITHERED_SHADOW -static const uint8_t SFG_ditheringPatterns[] = -{ - 0,0,0,0, - 0,0,0,0, - - 0,0,0,0, - 0,1,0,0, - - 0,0,0,0, - 0,1,0,1, - - 1,0,1,0, - 0,1,0,0, - - 1,0,1,0, - 0,1,0,1, - - 1,0,1,0, - 0,1,1,1, - - 1,1,1,1, - 0,1,0,1, - - 1,1,1,1, - 0,1,1,1, - - 1,1,1,1, - 1,1,1,1 -}; -#endif - -/* - FUNCTIONS -=============================================================================== -*/ - -/** - Returns a pseudorandom byte. This is a very simple congrent generator, its - parameters have been chosen so that each number (0-255) is included in the - output exactly once! -*/ -uint8_t SFG_random() -{ - SFG_game.currentRandom *= 13; - SFG_game.currentRandom += 7; - - return SFG_game.currentRandom; -} - -void SFG_playGameSound(uint8_t soundIndex, uint8_t volume) -{ - if (!(SFG_game.settings & 0x01)) - return; - - uint8_t mask = 0x01 << soundIndex; - - if (!(SFG_game.soundsPlayedThisFrame & mask)) - { - SFG_playSound(soundIndex,volume); - SFG_game.soundsPlayedThisFrame |= mask; - } -} - -/** - Returns a damage value for specific attack type (SFG_WEAPON_FIRE_TYPE_...), - with added randomness (so the values will differ). For explosion pass - SFG_WEAPON_FIRE_TYPE_FIREBALL. -*/ -uint8_t SFG_getDamageValue(uint8_t attackType) -{ - if (attackType >= SFG_WEAPON_FIRE_TYPES_TOTAL) - return 0; - - int32_t value = SFG_attackDamageTable[attackType]; // has to be signed - int32_t maxAdd = (value * SFG_DAMAGE_RANDOMNESS) / 256; - - value = value + (maxAdd / 2) - (SFG_random() * maxAdd / 256); - - if (value < 0) - value = 0; - - return value; -} - -/** - Saves game data to persistent storage. -*/ -void SFG_gameSave() -{ - if (SFG_game.saved == SFG_CANT_SAVE) - return; - - SFG_LOG("saving game data"); - - SFG_save(SFG_game.save); -} - -/** - Loads game data from persistent storage. -*/ -void SFG_gameLoad() -{ - if (SFG_game.saved == SFG_CANT_SAVE) - return; - - SFG_LOG("loading game data"); - - uint8_t result = SFG_load(SFG_game.save); - - if (result == 0) - SFG_game.saved = SFG_CANT_SAVE; -} - -/** - Returns ammo type for given weapon. -*/ -uint8_t SFG_weaponAmmo(uint8_t weapon) -{ - if (weapon == SFG_WEAPON_KNIFE) - return SFG_AMMO_NONE; - if (weapon == SFG_WEAPON_MACHINE_GUN || - weapon == SFG_WEAPON_SHOTGUN) - return SFG_AMMO_BULLETS; - else if (weapon == SFG_WEAPON_ROCKET_LAUNCHER) - return SFG_AMMO_ROCKETS; - else - return SFG_AMMO_PLASMA; -} - -RCL_Unit SFG_taxicabDistance( - RCL_Unit x0, RCL_Unit y0, RCL_Unit z0, RCL_Unit x1, RCL_Unit y1, RCL_Unit z1) -{ - return (RCL_abs(x0 - x1) + RCL_abs(y0 - y1) + RCL_abs(z0 - z1)); -} - -uint8_t SFG_isInActiveDistanceFromPlayer(RCL_Unit x, RCL_Unit y, RCL_Unit z) -{ - return SFG_taxicabDistance( - x,y,z,SFG_player.camera.position.x,SFG_player.camera.position.y, - SFG_player.camera.height) <= SFG_LEVEL_ELEMENT_ACTIVE_DISTANCE; -} - -/** - Function called when a level end to compute the stats etc. -*/ -void SFG_levelEnds() -{ - SFG_currentLevel.completionTime10sOfS = (SFG_MS_PER_FRAME * - (SFG_game.frame - SFG_currentLevel.frameStart)) / 100; - - SFG_currentLevel.monstersDead = 0; - - for (uint16_t i = 0; i < SFG_currentLevel.monsterRecordCount; ++i) - if (SFG_currentLevel.monsterRecords[i].health == 0) - SFG_currentLevel.monstersDead++; - - uint32_t totalTime = SFG_SAVE_TOTAL_TIME; - - if ((SFG_currentLevel.levelNumber == 0) || (totalTime != 0)) - { - SFG_LOG("Updating save totals."); - - totalTime += SFG_currentLevel.completionTime10sOfS; - - for (uint8_t i = 0; i < 4; ++i) - { - SFG_game.save[6 + i] = totalTime % 256; - totalTime /= 256; - } - - SFG_game.save[10] += SFG_currentLevel.monstersDead % 256; - SFG_game.save[11] += SFG_currentLevel.monstersDead / 256; - } - - SFG_game.save[0] = - (SFG_game.save[0] & 0x0f) | ((SFG_currentLevel.levelNumber + 1) << 4); - - SFG_game.save[2] = SFG_player.health; - SFG_game.save[3] = SFG_player.ammo[0]; - SFG_game.save[4] = SFG_player.ammo[1]; - SFG_game.save[5] = SFG_player.ammo[2]; -} - -static inline uint8_t SFG_RCLUnitToZBuffer(RCL_Unit x) -{ - x /= (RCL_UNITS_PER_SQUARE / 8); - - uint8_t okay = x < 256; - - return okay * (x + 1) - 1; -} - -const uint8_t *SFG_getMonsterSprite( - uint8_t monsterType, uint8_t state, uint8_t frame) -{ - uint8_t index = - state == SFG_MONSTER_STATE_DEAD ? 18 : 17; - // ^ makes the compiled binary smaller compared to returning pointers directly - - if ((state != SFG_MONSTER_STATE_DYING) && (state != SFG_MONSTER_STATE_DEAD)) - switch (monsterType) - { - case SFG_LEVEL_ELEMENT_MONSTER_SPIDER: - switch (state) - { - case SFG_MONSTER_STATE_ATTACKING: index = 1; break; - case SFG_MONSTER_STATE_IDLE: index = 0; break; - default: index = frame ? 0 : 2; break; - } - break; - - case SFG_LEVEL_ELEMENT_MONSTER_WARRIOR: - index = state != SFG_MONSTER_STATE_ATTACKING ? 6 : 7; - break; - - case SFG_LEVEL_ELEMENT_MONSTER_DESTROYER: - switch (state) - { - case SFG_MONSTER_STATE_ATTACKING: index = 4; break; - case SFG_MONSTER_STATE_IDLE: index = 3; break; - default: index = frame ? 3 : 5; break; - } - break; - - case SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT: - index = state != SFG_MONSTER_STATE_ATTACKING ? 8 : 9; - break; - - case SFG_LEVEL_ELEMENT_MONSTER_ENDER: - switch (state) - { - case SFG_MONSTER_STATE_ATTACKING: index = 12; break; - case SFG_MONSTER_STATE_IDLE: index = 10; break; - default: index = frame ? 10 : 11; break; - } - break; - - case SFG_LEVEL_ELEMENT_MONSTER_TURRET: - switch (state) - { - case SFG_MONSTER_STATE_ATTACKING: index = 15; break; - case SFG_MONSTER_STATE_IDLE: index = 13; break; - default: index = frame ? 13 : 14; break; - } - break; - - case SFG_LEVEL_ELEMENT_MONSTER_EXPLODER: - default: - index = 16; - break; - } - - return SFG_monsterSprites + index * SFG_TEXTURE_STORE_SIZE; -} - -/** - Says whether given key is currently pressed (down). This should be preferred - to SFG_keyPressed(). -*/ -uint8_t SFG_keyIsDown(uint8_t key) -{ - return SFG_game.keyStates[key] != 0; -} - -/** - Says whether given key has been pressed in the current frame. -*/ -uint8_t SFG_keyJustPressed(uint8_t key) -{ - return (SFG_game.keyStates[key]) == 1; -} - -/** - Says whether a key is being repeated after being held for certain time. -*/ -uint8_t SFG_keyRepeated(uint8_t key) -{ - return - ((SFG_game.keyStates[key] >= SFG_KEY_REPEAT_DELAY_FRAMES) || - (SFG_game.keyStates[key] == 255)) && - (SFG_game.frame % SFG_KEY_REPEAT_PERIOD_FRAMES == 0); -} - -uint16_t SFG_keyRegisters(uint8_t key) -{ - return SFG_keyJustPressed(key) || SFG_keyRepeated(key); -} - -#if SFG_RESOLUTION_SCALEDOWN == 1 - #define SFG_setGamePixel SFG_setPixel -#else - -/** - Sets the game pixel (a pixel that can potentially be bigger than the screen - pixel). -*/ -static inline void SFG_setGamePixel(uint16_t x, uint16_t y, uint8_t colorIndex) -{ - uint16_t screenY = y * SFG_RESOLUTION_SCALEDOWN; - uint16_t screenX = x * SFG_RESOLUTION_SCALEDOWN; - - for (uint16_t j = screenY; j < screenY + SFG_RESOLUTION_SCALEDOWN; ++j) - for (uint16_t i = screenX; i < screenX + SFG_RESOLUTION_SCALEDOWN; ++i) - SFG_setPixel(i,j,colorIndex); -} -#endif - -void SFG_recomputePLayerDirection() -{ - SFG_player.camera.direction = - RCL_wrap(SFG_player.camera.direction,RCL_UNITS_PER_SQUARE); - - SFG_player.direction = RCL_angleToDirection(SFG_player.camera.direction); - - SFG_player.direction.x = - (SFG_player.direction.x * SFG_PLAYER_MOVE_UNITS_PER_FRAME) - / RCL_UNITS_PER_SQUARE; - - SFG_player.direction.y = - (SFG_player.direction.y * SFG_PLAYER_MOVE_UNITS_PER_FRAME) - / RCL_UNITS_PER_SQUARE; - - SFG_game.backgroundScroll = - ((SFG_player.camera.direction * 8) * SFG_GAME_RESOLUTION_Y) - / RCL_UNITS_PER_SQUARE; -} - -#if SFG_BACKGROUND_BLUR != 0 -uint8_t SFG_backgroundBlurIndex = 0; - -static const int8_t SFG_backgroundBlurOffsets[8] = - { - 0 * SFG_BACKGROUND_BLUR, - 16 * SFG_BACKGROUND_BLUR, - 7 * SFG_BACKGROUND_BLUR, - 17 * SFG_BACKGROUND_BLUR, - 1 * SFG_BACKGROUND_BLUR, - 4 * SFG_BACKGROUND_BLUR, - 15 * SFG_BACKGROUND_BLUR, - 9 * SFG_BACKGROUND_BLUR, - }; -#endif - -static inline uint8_t SFG_fogValueDiminish(RCL_Unit depth) -{ - return depth / SFG_FOG_DIMINISH_STEP; -} - -static inline uint8_t - SFG_getTexelFull(uint8_t textureIndex,RCL_Unit u, RCL_Unit v) -{ - return - SFG_getTexel( - textureIndex != 255 ? - SFG_currentLevel.textures[textureIndex] : - (SFG_wallTextures + SFG_currentLevel.levelPointer->doorTextureIndex - * SFG_TEXTURE_STORE_SIZE), u / 32, v / 32); -} - -static inline uint8_t SFG_getTexelAverage(uint8_t textureIndex) -{ - return - textureIndex != 255 ? - SFG_game.textureAverageColors[ - SFG_currentLevel.levelPointer->textureIndices[textureIndex]] - : - ( - SFG_game.textureAverageColors[ - SFG_currentLevel.levelPointer->doorTextureIndex] - + 1 // to distinguish from normal walls - ); -} - -void SFG_pixelFunc(RCL_PixelInfo *pixel) -{ - uint8_t color; - uint8_t shadow = 0; - - if (pixel->isHorizon && pixel->depth > RCL_UNITS_PER_SQUARE * 16) - { - color = SFG_TRANSPARENT_COLOR; - } - else if (pixel->isWall) - { - uint8_t textureIndex = - pixel->isFloor ? - ( - ((pixel->hit.type & SFG_TILE_PROPERTY_MASK) != SFG_TILE_PROPERTY_DOOR) ? - (pixel->hit.type & 0x7) - : - ( - (pixel->texCoords.y > RCL_UNITS_PER_SQUARE) ? - (pixel->hit.type & 0x7) : 255 - ) - ): - ((pixel->hit.type & 0x38) >> 3); - -#if SFG_TEXTURE_DISTANCE != 0 - RCL_Unit textureV = pixel->texCoords.y; - - if ((pixel->hit.type & SFG_TILE_PROPERTY_MASK) == - SFG_TILE_PROPERTY_SQUEEZER) - textureV += pixel->wallHeight; -#endif - - color = - textureIndex != SFG_TILE_TEXTURE_TRANSPARENT ? - ( -#if SFG_TEXTURE_DISTANCE >= 65535 - SFG_getTexelFull(textureIndex,pixel->texCoords.x,textureV) -#elif SFG_TEXTURE_DISTANCE == 0 - SFG_getTexelAverage(textureIndex) -#else - pixel->depth <= SFG_TEXTURE_DISTANCE ? - SFG_getTexelFull(textureIndex,pixel->texCoords.x,textureV) : - SFG_getTexelAverage(textureIndex) -#endif - ) - : - SFG_TRANSPARENT_COLOR; - - shadow = pixel->hit.direction >> 1; - } - else - { - color = pixel->isFloor ? - (SFG_currentLevel.floorColor) : - (pixel->height < SFG_CEILING_MAX_HEIGHT ? - SFG_currentLevel.ceilingColor : SFG_TRANSPARENT_COLOR); - } - - if (color != SFG_TRANSPARENT_COLOR) - { -#if SFG_DITHERED_SHADOW - uint8_t fogShadow = (pixel->depth * 8) / SFG_FOG_DIMINISH_STEP; - - uint8_t fogShadowPart = fogShadow & 0x07; - - fogShadow /= 8; - - uint8_t xMod4 = pixel->position.x & 0x03; - uint8_t yMod2 = pixel->position.y & 0x01; - - shadow += - fogShadow + SFG_ditheringPatterns[fogShadowPart * 8 + yMod2 * 4 + xMod4]; -#else - shadow += SFG_fogValueDiminish(pixel->depth); -#endif - -#if SFG_ENABLE_FOG - color = palette_minusValue(color,shadow); -#endif - } - else - { -#if SFG_DRAW_LEVEL_BACKGROUND - color = SFG_getTexel(SFG_backgroundImages + - SFG_currentLevel.backgroundImage * SFG_TEXTURE_STORE_SIZE, - SFG_game.backgroundScaleMap[((pixel->position.x - #if SFG_BACKGROUND_BLUR != 0 - + SFG_backgroundBlurOffsets[SFG_backgroundBlurIndex] - #endif - ) * SFG_RAYCASTING_SUBSAMPLE + SFG_game.backgroundScroll) % SFG_GAME_RESOLUTION_Y], - (SFG_game.backgroundScaleMap[(pixel->position.y // ^ TODO: get rid of mod? - #if SFG_BACKGROUND_BLUR != 0 - + SFG_backgroundBlurOffsets[SFG_backgroundBlurIndex + 1] - #endif - ) % SFG_GAME_RESOLUTION_Y]) - ); - - #if SFG_BACKGROUND_BLUR != 0 - SFG_backgroundBlurIndex = (SFG_backgroundBlurIndex + 1) % 8; - #endif -#else - color = 1; -#endif - } - -#if SFG_RAYCASTING_SUBSAMPLE == 1 - // the other version will probably get optimized to this, but just in case - SFG_setGamePixel(pixel->position.x,pixel->position.y,color); -#else - RCL_Unit screenX = pixel->position.x * SFG_RAYCASTING_SUBSAMPLE; - - for (int_fast8_t i = 0; i < SFG_RAYCASTING_SUBSAMPLE; ++i) - { - SFG_setGamePixel(screenX,pixel->position.y,color); - screenX++; - } -#endif -} - -/** - Draws image on screen, with transparency. This is faster than sprite drawing. - For performance sake drawing near screen edges is not pixel perfect. -*/ -void SFG_blitImage( - const uint8_t *image, - int16_t posX, - int16_t posY, - uint8_t scale) -{ - if (scale == 0) - return; - - uint16_t x0 = posX, - x1, - y0 = posY, - y1; - - uint8_t u0 = 0, v0 = 0; - - if (posX < 0) - { - x0 = 0; - u0 = (-1 * posX) / scale; - } - - posX += scale * SFG_TEXTURE_SIZE; - - uint16_t limitX = SFG_GAME_RESOLUTION_X - scale; - uint16_t limitY = SFG_GAME_RESOLUTION_Y - scale; - - x1 = posX >= 0 ? - (posX <= limitX ? posX : limitX) - : 0; - - if (x1 >= SFG_GAME_RESOLUTION_X) - x1 = SFG_GAME_RESOLUTION_X - 1; - - if (posY < 0) - { - y0 = 0; - v0 = (-1 * posY) / scale; - } - - posY += scale * SFG_TEXTURE_SIZE; - - y1 = posY >= 0 ? - (posY <= limitY ? posY : limitY) - : 0; - - if (y1 >= SFG_GAME_RESOLUTION_Y) - y1 = SFG_GAME_RESOLUTION_Y - 1; - - uint8_t v = v0; - - for (uint16_t y = y0; y < y1; y += scale) - { - uint8_t u = u0; - - for (uint16_t x = x0; x < x1; x += scale) - { - uint8_t color = SFG_getTexel(image,u,v); - - if (color != SFG_TRANSPARENT_COLOR) - { - uint16_t sY = y; - - for (uint8_t j = 0; j < scale; ++j) - { - uint16_t sX = x; - - for (uint8_t i = 0; i < scale; ++i) - { - SFG_setGamePixel(sX,sY,color); - sX++; - } - - sY++; - } - } - u++; - } - v++; - } -} - -void SFG_drawScaledSprite( - const uint8_t *image, - int16_t centerX, - int16_t centerY, - int16_t size, - uint8_t minusValue, - RCL_Unit distance) -{ - if ((size > SFG_MAX_SPRITE_SIZE) || (size == 0)) - return; - - uint16_t halfSize = size / 2; - - int16_t topLeftX = centerX - halfSize; - int16_t topLeftY = centerY - halfSize; - - int16_t x0, u0; - - if (topLeftX < 0) - { - u0 = -1 * topLeftX; - x0 = 0; - } - else - { - u0 = 0; - x0 = topLeftX; - } - - int16_t x1 = topLeftX + size - 1; - - if (x1 >= SFG_GAME_RESOLUTION_X) - x1 = SFG_GAME_RESOLUTION_X - 1; - - int16_t y0, v0; - - if (topLeftY < 0) - { - v0 = -1 * topLeftY; - y0 = 0; - } - else - { - v0 = 0; - y0 = topLeftY; - } - - int16_t y1 = topLeftY + size - 1; - - if (y1 >= SFG_GAME_RESOLUTION_Y) - y1 = SFG_GAME_RESOLUTION_Y - 1; - - if ((x0 > x1) || (y0 > y1) || (u0 >= size) || (v0 >= size)) // outside screen? - return; - - int16_t u1 = u0 + (x1 - x0); - int16_t v1 = v0 + (y1 - y0); - - // precompute sampling positions: - - int16_t uMin = RCL_min(u0,u1); - int16_t vMin = RCL_min(v0,v1); - int16_t uMax = RCL_max(u0,u1); - int16_t vMax = RCL_max(v0,v1); - - int16_t precompFrom = RCL_min(uMin,vMin); - int16_t precompTo = RCL_max(uMax,vMax); - - precompFrom = RCL_max(0,precompFrom); - precompTo = RCL_min(SFG_MAX_SPRITE_SIZE - 1,precompTo); - - #define PRECOMP_SCALE 512 - - int16_t precompStepScaled = ((SFG_TEXTURE_SIZE) * PRECOMP_SCALE) / size; - int16_t precompPosScaled = precompFrom * precompStepScaled; - - for (int16_t i = precompFrom; i <= precompTo; ++i) - { - SFG_game.spriteSamplingPoints[i] = precompPosScaled / PRECOMP_SCALE; - precompPosScaled += precompStepScaled; - } - - #undef PRECOMP_SCALE - - uint8_t zDistance = SFG_RCLUnitToZBuffer(distance); - - for (int16_t x = x0, u = u0; x <= x1; ++x, ++u) - { - if (SFG_game.zBuffer[x] >= zDistance) - { - int8_t columnTransparent = 1; - - for (int16_t y = y0, v = v0; y <= y1; ++y, ++v) - { - uint8_t color = - SFG_getTexel(image,SFG_game.spriteSamplingPoints[u], - SFG_game.spriteSamplingPoints[v]); - - if (color != SFG_TRANSPARENT_COLOR) - { -#if SFG_DIMINISH_SPRITES - color = palette_minusValue(color,minusValue); -#endif - columnTransparent = 0; - - SFG_setGamePixel(x,y,color); - } - } - - if (!columnTransparent) - SFG_game.zBuffer[x] = zDistance; - } - } -} - -RCL_Unit SFG_texturesAt(int16_t x, int16_t y) -{ - uint8_t p; - - SFG_TileDefinition tile = - SFG_getMapTile(SFG_currentLevel.levelPointer,x,y,&p); - - return - SFG_TILE_FLOOR_TEXTURE(tile) | (SFG_TILE_CEILING_TEXTURE(tile) << 3) | p; - // ^ store both textures (floor and ceiling) and properties in one number -} - -RCL_Unit SFG_movingWallHeight -( - RCL_Unit low, - RCL_Unit high, - uint32_t time -) -{ - RCL_Unit height = high - low; - RCL_Unit halfHeight = height / 2; - - RCL_Unit sinArg = - (time * ((SFG_MOVING_WALL_SPEED * RCL_UNITS_PER_SQUARE) / 1000)) / height; - - return - low + halfHeight + (RCL_sin(sinArg) * halfHeight) / RCL_UNITS_PER_SQUARE; -} - -RCL_Unit SFG_floorHeightAt(int16_t x, int16_t y) -{ - uint8_t properties; - - SFG_TileDefinition tile = - SFG_getMapTile(SFG_currentLevel.levelPointer,x,y,&properties); - - RCL_Unit doorHeight = 0; - - if (properties == SFG_TILE_PROPERTY_DOOR) - { - for (uint8_t i = 0; i < SFG_currentLevel.doorRecordCount; ++i) - { - SFG_DoorRecord *door = &(SFG_currentLevel.doorRecords[i]); - - if ((door->coords[0] == x) && (door->coords[1] == y)) - { - doorHeight = door->state & SFG_DOOR_VERTICAL_POSITION_MASK; - - doorHeight = doorHeight != (0xff & SFG_DOOR_VERTICAL_POSITION_MASK) ? - doorHeight * SFG_DOOR_HEIGHT_STEP : RCL_UNITS_PER_SQUARE; - - break; - } - } - } - else if (properties == SFG_TILE_PROPERTY_ELEVATOR) - { - RCL_Unit height = - SFG_TILE_FLOOR_HEIGHT(tile) * SFG_WALL_HEIGHT_STEP; - - return SFG_movingWallHeight( - height, - height + SFG_TILE_CEILING_HEIGHT(tile) * SFG_WALL_HEIGHT_STEP, - SFG_game.frameTime - SFG_currentLevel.timeStart); - } - - return SFG_TILE_FLOOR_HEIGHT(tile) * SFG_WALL_HEIGHT_STEP - doorHeight; -} - -/** - Like SFG_floorCollisionHeightAt, but takes into account colliding items on - the map, so the squares that have these items are higher. The former function - is for rendering, this one is for collision checking. -*/ -RCL_Unit SFG_floorCollisionHeightAt(int16_t x, int16_t y) -{ - return SFG_floorHeightAt(x,y) + - SFG_getItemCollisionMapBit(x,y) * RCL_UNITS_PER_SQUARE; -} - -void SFG_getPlayerWeaponInfo( - uint8_t *ammoType, uint8_t *projectileCount, uint8_t *canShoot) -{ - *ammoType = SFG_weaponAmmo(SFG_player.weapon); - - *projectileCount = SFG_GET_WEAPON_PROJECTILE_COUNT(SFG_player.weapon); - -#if SFG_INFINITE_AMMO - *canShoot = 1; -#else - *canShoot = - (*ammoType == SFG_AMMO_NONE || - SFG_player.ammo[*ammoType] >= *projectileCount); -#endif -} - -void SFG_playerRotateWeapon(uint8_t next) -{ - uint8_t initialWeapon = SFG_player.weapon; - int8_t increment = next ? 1 : -1; - - while (1) - { - SFG_player.weapon = - (SFG_WEAPONS_TOTAL + SFG_player.weapon + increment) % SFG_WEAPONS_TOTAL; - - if (SFG_player.weapon == initialWeapon) - break; - - uint8_t ammo, projectileCount, canShoot; - - SFG_getPlayerWeaponInfo(&ammo,&projectileCount,&canShoot); - - if (canShoot) - break; - } -} - -void SFG_initPlayer() -{ - RCL_initCamera(&SFG_player.camera); - - SFG_player.camera.resolution.x = - SFG_GAME_RESOLUTION_X / SFG_RAYCASTING_SUBSAMPLE; - - SFG_player.camera.resolution.y = SFG_GAME_RESOLUTION_Y - SFG_HUD_BAR_HEIGHT; - - SFG_player.camera.position.x = RCL_UNITS_PER_SQUARE / 2 + - SFG_currentLevel.levelPointer->playerStart[0] * RCL_UNITS_PER_SQUARE; - - SFG_player.camera.position.y = RCL_UNITS_PER_SQUARE / 2 + - SFG_currentLevel.levelPointer->playerStart[1] * RCL_UNITS_PER_SQUARE; - - SFG_player.squarePosition[0] = - SFG_player.camera.position.x / RCL_UNITS_PER_SQUARE; - - SFG_player.squarePosition[1] = - SFG_player.camera.position.y / RCL_UNITS_PER_SQUARE; - - SFG_player.camera.height = - SFG_floorHeightAt( - SFG_currentLevel.levelPointer->playerStart[0], - SFG_currentLevel.levelPointer->playerStart[1]) + - RCL_CAMERA_COLL_HEIGHT_BELOW; - - SFG_player.camera.direction = - SFG_currentLevel.levelPointer->playerStart[2] * - (RCL_UNITS_PER_SQUARE / 256); - - SFG_recomputePLayerDirection(); - - SFG_player.previousVerticalSpeed = 0; - - SFG_player.headBobFrame = 0; - - SFG_player.weapon = SFG_WEAPON_KNIFE; - - SFG_player.weaponCooldownFrames = 0; - SFG_player.lastHurtFrame = SFG_game.frame; - SFG_player.lastItemTakenFrame = SFG_game.frame; - - SFG_player.health = SFG_PLAYER_START_HEALTH; - - SFG_player.previousWeaponDirection = 0; - - SFG_player.cards = -#if SFG_UNLOCK_DOOR - 0x07; -#else - 0; -#endif - - SFG_player.justTeleported = 0; - - for (uint8_t i = 0; i < SFG_AMMO_TOTAL; ++i) - SFG_player.ammo[i] = 0; -} - -RCL_Unit SFG_ceilingHeightAt(int16_t x, int16_t y) -{ - uint8_t properties; - SFG_TileDefinition tile = - SFG_getMapTile(SFG_currentLevel.levelPointer,x,y,&properties); - - if (properties == SFG_TILE_PROPERTY_ELEVATOR) - return SFG_CEILING_MAX_HEIGHT; - - uint8_t height = SFG_TILE_CEILING_HEIGHT(tile); - - return properties != SFG_TILE_PROPERTY_SQUEEZER ? - ( - height != SFG_TILE_CEILING_MAX_HEIGHT ? - ((SFG_TILE_FLOOR_HEIGHT(tile) + height) * SFG_WALL_HEIGHT_STEP) : - SFG_CEILING_MAX_HEIGHT - ) : - SFG_movingWallHeight( - SFG_TILE_FLOOR_HEIGHT(tile) * SFG_WALL_HEIGHT_STEP, - (SFG_TILE_CEILING_HEIGHT(tile) + SFG_TILE_FLOOR_HEIGHT(tile)) - * SFG_WALL_HEIGHT_STEP, - SFG_game.frameTime - SFG_currentLevel.timeStart); -} - -/** - Gets sprite (image and sprite size) for given item. -*/ -void SFG_getItemSprite( - uint8_t elementType, const uint8_t **sprite, uint8_t *spriteSize) -{ - *spriteSize = 0; - *sprite = SFG_itemSprites + (elementType - 1) * SFG_TEXTURE_STORE_SIZE; - - switch (elementType) - { - case SFG_LEVEL_ELEMENT_TREE: - case SFG_LEVEL_ELEMENT_RUIN: - case SFG_LEVEL_ELEMENT_LAMP: - case SFG_LEVEL_ELEMENT_TELEPORTER: - *spriteSize = 2; - break; - - case SFG_LEVEL_ELEMENT_TERMINAL: - *spriteSize = 1; - break; - - case SFG_LEVEL_ELEMENT_FINISH: - case SFG_LEVEL_ELEMENT_COLUMN: - *spriteSize = 3; - break; - - case SFG_LEVEL_ELEMENT_CARD0: - case SFG_LEVEL_ELEMENT_CARD1: - case SFG_LEVEL_ELEMENT_CARD2: - *sprite = SFG_itemSprites + - (SFG_LEVEL_ELEMENT_CARD0 - 1) * SFG_TEXTURE_STORE_SIZE; - break; - - case SFG_LEVEL_ELEMENT_BLOCKER: - *sprite = 0; - break; - - default: - break; - } -} - -/** - Says whether given item type collides, i.e. stops player from moving. -*/ -uint8_t SFG_itemCollides(uint8_t elementType) -{ - return - elementType == SFG_LEVEL_ELEMENT_BARREL || - elementType == SFG_LEVEL_ELEMENT_TREE || - elementType == SFG_LEVEL_ELEMENT_TERMINAL || - elementType == SFG_LEVEL_ELEMENT_COLUMN || - elementType == SFG_LEVEL_ELEMENT_RUIN || - elementType == SFG_LEVEL_ELEMENT_BLOCKER || - elementType == SFG_LEVEL_ELEMENT_LAMP; -} - -void SFG_setGameState(uint8_t state) -{ - SFG_LOG("changing game state"); - SFG_game.state = state; - SFG_game.stateChangeTime = SFG_game.frameTime; -} - -void SFG_setAndInitLevel(uint8_t levelNumber) -{ - SFG_LOG("setting and initializing level"); - - const SFG_Level *level; - -#if SFG_ARDUINO - memcpy_P(&SFG_ramLevel,SFG_levels[levelNumber],sizeof(SFG_Level)); - level = &SFG_ramLevel; -#else - level = SFG_levels[levelNumber]; -#endif - - SFG_game.currentRandom = 0; - - if (SFG_game.saved != SFG_CANT_SAVE) - SFG_game.saved = 0; - - SFG_currentLevel.levelNumber = levelNumber; - SFG_currentLevel.monstersDead = 0; - SFG_currentLevel.backgroundImage = level->backgroundImage; - SFG_currentLevel.levelPointer = level; - SFG_currentLevel.bossCount = 0; - SFG_currentLevel.floorColor = level->floorColor; - SFG_currentLevel.ceilingColor = level->ceilingColor; - SFG_currentLevel.completionTime10sOfS = 0; - - for (uint8_t i = 0; i < 7; ++i) - SFG_currentLevel.textures[i] = - SFG_wallTextures + level->textureIndices[i] * SFG_TEXTURE_STORE_SIZE; - - SFG_LOG("initializing doors"); - - SFG_currentLevel.checkedDoorIndex = 0; - SFG_currentLevel.doorRecordCount = 0; - SFG_currentLevel.projectileRecordCount = 0; - SFG_currentLevel.teleporterCount = 0; - SFG_currentLevel.mapRevealMask = -#if SFG_REVEAL_MAP - 0xffff; -#else - 0; -#endif - - for (uint8_t j = 0; j < SFG_MAP_SIZE; ++j) - { - for (uint8_t i = 0; i < SFG_MAP_SIZE; ++i) - { - uint8_t properties; - - SFG_getMapTile(level,i,j,&properties); - - if ((properties & SFG_TILE_PROPERTY_MASK) == SFG_TILE_PROPERTY_DOOR) - { - SFG_DoorRecord *d = - &(SFG_currentLevel.doorRecords[SFG_currentLevel.doorRecordCount]); - - d->coords[0] = i; - d->coords[1] = j; - d->state = 0x00; - - SFG_currentLevel.doorRecordCount++; - } - - if (SFG_currentLevel.doorRecordCount >= SFG_MAX_DOORS) - { - SFG_LOG("warning: too many doors!"); - break; - } - } - - if (SFG_currentLevel.doorRecordCount >= SFG_MAX_DOORS) - break; - } - - SFG_LOG("initializing level elements"); - - SFG_currentLevel.itemRecordCount = 0; - SFG_currentLevel.checkedItemIndex = 0; - - SFG_currentLevel.monsterRecordCount = 0; - SFG_currentLevel.checkedMonsterIndex = 0; - - SFG_MonsterRecord *monster; - - for (uint16_t i = 0; i < ((SFG_MAP_SIZE * SFG_MAP_SIZE) / 8); ++i) - SFG_currentLevel.itemCollisionMap[i] = 0; - - for (uint8_t i = 0; i < SFG_MAX_LEVEL_ELEMENTS; ++i) - { - const SFG_LevelElement *e = &(SFG_currentLevel.levelPointer->elements[i]); - - if (e->type != SFG_LEVEL_ELEMENT_NONE) - { - if (SFG_LEVEL_ELEMENT_TYPE_IS_MOSTER(e->type)) - { - monster = - &(SFG_currentLevel.monsterRecords[SFG_currentLevel.monsterRecordCount]); - - monster->stateType = (SFG_MONSTER_TYPE_TO_INDEX(e->type) << 4) - | SFG_MONSTER_STATE_INACTIVE; - - monster->health = - SFG_GET_MONSTER_MAX_HEALTH(SFG_MONSTER_TYPE_TO_INDEX(e->type)); - - monster->coords[0] = e->coords[0] * 4 + 2; - monster->coords[1] = e->coords[1] * 4 + 2; - - SFG_currentLevel.monsterRecordCount++; - - if (e->type == SFG_LEVEL_ELEMENT_MONSTER_ENDER) - SFG_currentLevel.bossCount++; - } - else if ((e->type < SFG_LEVEL_ELEMENT_LOCK0) || - (e->type > SFG_LEVEL_ELEMENT_LOCK2)) - { - SFG_currentLevel.itemRecords[SFG_currentLevel.itemRecordCount] = i; - SFG_currentLevel.itemRecordCount++; - - if (e->type == SFG_LEVEL_ELEMENT_TELEPORTER) - SFG_currentLevel.teleporterCount++; - - if (SFG_itemCollides(e->type)) - SFG_setItemCollisionMapBit(e->coords[0],e->coords[1],1); - } - else - { - uint8_t properties; - - SFG_getMapTile(level,e->coords[0],e->coords[1],&properties); - - if ((properties & SFG_TILE_PROPERTY_MASK) == SFG_TILE_PROPERTY_DOOR) - { - // find the door record and lock the door: - for (uint16_t j = 0; j < SFG_currentLevel.doorRecordCount; ++j) - { - SFG_DoorRecord *d = &(SFG_currentLevel.doorRecords[j]); - - if (d->coords[0] == e->coords[0] && d->coords[1] == e->coords[1]) - { - d->state |= (e->type - SFG_LEVEL_ELEMENT_LOCK0 + 1) << 6; - break; - } - } - } - else - { - SFG_LOG("warning: lock not put on door tile!"); - } - } - } - } - - SFG_currentLevel.timeStart = SFG_game.frameTime; - SFG_currentLevel.frameStart = SFG_game.frame; - - SFG_game.spriteAnimationFrame = 0; - - SFG_initPlayer(); - SFG_setGameState(SFG_GAME_STATE_LEVEL_START); - SFG_setMusic(SFG_MUSIC_NEXT); - SFG_processEvent(SFG_EVENT_LEVEL_STARTS,levelNumber); -} - -void SFG_init() -{ - SFG_LOG("initializing game") - - SFG_game.frame = 0; - SFG_game.frameTime = 0; - SFG_game.currentRandom = 0; - SFG_game.continues = 1; - - RCL_initRayConstraints(&SFG_game.rayConstraints); - SFG_game.rayConstraints.maxHits = SFG_RAYCASTING_MAX_HITS; - SFG_game.rayConstraints.maxSteps = SFG_RAYCASTING_MAX_STEPS; - - SFG_game.antiSpam = 0; - - SFG_LOG("computing average texture colors") - - for (uint8_t i = 0; i < SFG_WALL_TEXTURE_COUNT; ++i) - { - /** For simplicity, we round colors so that there is only 64 of them, and - we count them up to 256. */ - - uint8_t colorHistogram[64]; - - for (uint8_t j = 0; j < 64; ++j) - colorHistogram[j] = 0; - - for (uint8_t y = 0; y < SFG_TEXTURE_SIZE; ++y) - for (uint8_t x = 0; x < SFG_TEXTURE_SIZE; ++x) - { - uint8_t color = - SFG_getTexel(SFG_wallTextures + i * SFG_TEXTURE_STORE_SIZE,x,y) / 4; - - colorHistogram[color] += 1; - - if (colorHistogram[color] == 255) - break; - } - - uint8_t maxIndex = 0; - - for (uint8_t j = 0; j < 64; ++j) - { - if (colorHistogram[j] == 255) - { - maxIndex = j; - break; - } - - if (colorHistogram[j] > colorHistogram[maxIndex]) - maxIndex = j; - } - - SFG_game.textureAverageColors[i] = maxIndex * 4; - } - - for (uint16_t i = 0; i < SFG_GAME_RESOLUTION_Y; ++i) - SFG_game.backgroundScaleMap[i] = - (i * SFG_TEXTURE_SIZE) / SFG_GAME_RESOLUTION_Y; - - for (uint8_t i = 0; i < SFG_KEY_COUNT; ++i) - SFG_game.keyStates[i] = 0; - - SFG_game.backgroundScroll = 0; - SFG_currentLevel.levelPointer = 0; - SFG_game.selectedMenuItem = 0; - SFG_game.selectedLevel = 0; - SFG_game.settings = 0x03; - SFG_game.saved = 0; - - // create a default save data: - - for (uint16_t i = 0; i < SFG_SAVE_SIZE; ++i) - SFG_game.save[i] = 0; - - SFG_game.save[0] = 0; - SFG_game.save[1] = SFG_game.settings; - - SFG_gameLoad(); // attempt to load settings - - if (SFG_game.saved != SFG_CANT_SAVE) - { - SFG_LOG("settings loaded"); - SFG_game.settings = SFG_game.save[1]; - } - else - { - SFG_LOG("saving/loading not possible"); - SFG_game.save[0] = (SFG_NUMBER_OF_LEVELS - 1) | 0xf0; // revealed all levels - } - - SFG_setMusic((SFG_game.settings & 0x02) ? - SFG_MUSIC_TURN_ON : SFG_MUSIC_TURN_OFF); - -#if SFG_START_LEVEL == 0 - SFG_setGameState(SFG_GAME_STATE_INIT); -#else - SFG_setAndInitLevel(SFG_START_LEVEL - 1); -#endif -} - -/** - Adds new projectile to the current level, return 1 if added, 0 if not (max - count reached). -*/ -uint8_t SFG_createProjectile(SFG_ProjectileRecord projectile) -{ - if (SFG_currentLevel.projectileRecordCount >= SFG_MAX_PROJECTILES) - return 0; - - SFG_currentLevel.projectileRecords[SFG_currentLevel.projectileRecordCount] = - projectile; - - SFG_currentLevel.projectileRecordCount++; - - return 1; -} - -/** - Launches projectile of given type from given position in given direction - (has to be normalized), with given offset (so as to not collide with the - shooting entity). Returns the same value as SFG_createProjectile. -*/ -uint8_t SFG_launchProjectile( - uint8_t type, - RCL_Vector2D shootFrom, - RCL_Unit shootFromHeight, - RCL_Vector2D direction, - RCL_Unit verticalSpeed, - RCL_Unit offsetDistance - ) -{ - if (type == SFG_PROJECTILE_NONE) - return 0; - - SFG_ProjectileRecord p; - - p.type = type; - p.doubleFramesToLive = - RCL_nonZero(SFG_GET_PROJECTILE_FRAMES_TO_LIVE(type) / 2); - - p.position[0] = - shootFrom.x + (direction.x * offsetDistance) / RCL_UNITS_PER_SQUARE; - p.position[1] = - shootFrom.y + (direction.y * offsetDistance) / RCL_UNITS_PER_SQUARE; - p.position[2] = shootFromHeight; - - p.direction[0] = - (direction.x * SFG_GET_PROJECTILE_SPEED_UPS(type)) / RCL_UNITS_PER_SQUARE; - p.direction[1] = - (direction.y * SFG_GET_PROJECTILE_SPEED_UPS(type)) / RCL_UNITS_PER_SQUARE; - p.direction[2] = verticalSpeed; - - return SFG_createProjectile(p); -} - -/** - Pushes a given position away from a center by given distance, with collisions. - Returns 1 if push away happened, otherwise 0. -*/ -uint8_t SFG_pushAway( - RCL_Unit pos[3], - RCL_Unit centerX, - RCL_Unit centerY, - RCL_Unit preferredDirection, - RCL_Unit distance) -{ - RCL_Vector2D fromCenter; - - fromCenter.x = pos[0] - centerX; - fromCenter.y = pos[1] - centerY; - - RCL_Unit l = RCL_len(fromCenter); - - if (l < 128) - { - fromCenter = RCL_angleToDirection(preferredDirection); - l = RCL_UNITS_PER_SQUARE; - } - - RCL_Vector2D offset; - - offset.x = (fromCenter.x * distance) / l; - offset.y = (fromCenter.y * distance) / l; - - RCL_Camera c; - - RCL_initCamera(&c); - - c.position.x = pos[0]; - c.position.y = pos[1]; - c.height = pos[2]; - - RCL_moveCameraWithCollision(&c,offset,0,SFG_floorCollisionHeightAt, - SFG_ceilingHeightAt,1,1); - - pos[0] = c.position.x; - pos[1] = c.position.y; - pos[2] = c.height; - - return 1; -} - -uint8_t SFG_pushPlayerAway( - RCL_Unit centerX, RCL_Unit centerY, RCL_Unit distance) -{ - RCL_Unit p[3]; - - p[0] = SFG_player.camera.position.x; - p[1] = SFG_player.camera.position.y; - p[2] = SFG_player.camera.height; - - uint8_t result = SFG_pushAway(p,centerX,centerY, - SFG_player.camera.direction - RCL_UNITS_PER_SQUARE / 2, - distance); - - SFG_player.camera.position.x = p[0]; - SFG_player.camera.position.y = p[1]; - SFG_player.camera.height = p[2]; - - return result; -} - -/** - Helper function to resolve collision with level element. The function supposes - the collision already does happen and only resolves it. Returns adjusted move - offset. -*/ -RCL_Vector2D SFG_resolveCollisionWithElement( - RCL_Vector2D position, RCL_Vector2D moveOffset, RCL_Vector2D elementPos) -{ - RCL_Unit dx = RCL_abs(elementPos.x - position.x); - RCL_Unit dy = RCL_abs(elementPos.y - position.y); - - if (dx > dy) - { - // colliding from left/right - - if ((moveOffset.x > 0) == (position.x < elementPos.x)) - moveOffset.x = 0; - // ^ only stop if heading towards element, to avoid getting stuck - } - else - { - // colliding from up/down - - if ((moveOffset.y > 0) == (position.y < elementPos.y)) - moveOffset.y = 0; - } - - return moveOffset; -} - -/** - Adds or substracts player's health during the playing state due to taking - damage (negative value) or getting healed. Negative value will be corrected by - SFG_PLAYER_DAMAGE_MULTIPLIER in this function. -*/ -void SFG_playerChangeHealth(int8_t healthAdd) -{ - if (SFG_game.state != SFG_GAME_STATE_PLAYING) - return; // don't hurt during level starting phase - - if (healthAdd < 0) - { - healthAdd = - RCL_min(-1, - (((RCL_Unit) healthAdd) * SFG_PLAYER_DAMAGE_MULTIPLIER) / - RCL_UNITS_PER_SQUARE); - - SFG_player.lastHurtFrame = SFG_game.frame; - SFG_processEvent(SFG_EVENT_VIBRATE,0); - SFG_processEvent(SFG_EVENT_PLAYER_HURT,-1 * healthAdd); - } - - int16_t health = SFG_player.health; - health += healthAdd; - health = RCL_clamp(health,0,SFG_PLAYER_MAX_HEALTH); - - SFG_player.health = health; -} - -uint8_t SFG_distantSoundVolume(RCL_Unit x, RCL_Unit y, RCL_Unit z) -{ - RCL_Unit distance = SFG_taxicabDistance(x,y,z, - SFG_player.camera.position.x, - SFG_player.camera.position.y, - SFG_player.camera.height); - - if (distance >= SFG_SFX_MAX_DISTANCE) - return 0; - - uint32_t result = 255 - (distance * 255) / SFG_SFX_MAX_DISTANCE; - - return (result * result) / 256; -} - -/** - Same as SFG_playerChangeHealth but for monsters. -*/ -void SFG_monsterChangeHealth(SFG_MonsterRecord *monster, int8_t healthAdd) -{ - int16_t health = monster->health; - - health += healthAdd; - health = RCL_clamp(health,0,255); - monster->health = health; - - if (healthAdd < 0) - { - // play hurt sound - - uint8_t volume = SFG_distantSoundVolume( - SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[0]), - SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[1]), - SFG_floorHeightAt( - SFG_MONSTER_COORD_TO_SQUARES(monster->coords[0]), - SFG_MONSTER_COORD_TO_SQUARES(monster->coords[1]))); - - SFG_playGameSound(5,volume); - - if (monster->health == 0) - SFG_playGameSound(2,volume); - } -} - -void SFG_removeItem(uint8_t index) -{ - SFG_LOG("removing item"); - - for (uint16_t j = index; j < SFG_currentLevel.itemRecordCount - 1; ++j) - SFG_currentLevel.itemRecords[j] = - SFG_currentLevel.itemRecords[j + 1]; - - SFG_currentLevel.itemRecordCount--; -} - -/** - Helper function, returns a pointer to level element representing item with - given index, but only if the item is active (otherwise 0 is returned). -*/ -static inline const SFG_LevelElement *SFG_getActiveItemElement(uint8_t index) -{ - SFG_ItemRecord item = SFG_currentLevel.itemRecords[index]; - - if ((item & SFG_ITEM_RECORD_ACTIVE_MASK) == 0) - return 0; - - return &(SFG_currentLevel.levelPointer->elements[item & - ~SFG_ITEM_RECORD_ACTIVE_MASK]); -} - -static inline const SFG_LevelElement *SFG_getLevelElement(uint8_t index) -{ - SFG_ItemRecord item = SFG_currentLevel.itemRecords[index]; - - return &(SFG_currentLevel.levelPointer->elements[item & - ~SFG_ITEM_RECORD_ACTIVE_MASK]); -} - -void SFG_createExplosion(RCL_Unit, RCL_Unit, RCL_Unit); // forward decl - -void SFG_explodeBarrel(uint8_t itemIndex, RCL_Unit x, RCL_Unit y, RCL_Unit z) -{ - const SFG_LevelElement *e = SFG_getLevelElement(itemIndex); - SFG_setItemCollisionMapBit(e->coords[0],e->coords[1],0); - SFG_removeItem(itemIndex); - SFG_createExplosion(x,y,z); -} - -void SFG_createExplosion(RCL_Unit x, RCL_Unit y, RCL_Unit z) -{ - SFG_ProjectileRecord explosion; - - SFG_playGameSound(2,SFG_distantSoundVolume(x,y,z)); - SFG_processEvent(SFG_EVENT_EXPLOSION,0); - - explosion.type = SFG_PROJECTILE_EXPLOSION; - - explosion.position[0] = x; - explosion.position[1] = y; - explosion.position[2] = z; - - explosion.direction[0] = 0; - explosion.direction[1] = 0; - explosion.direction[2] = 0; - - explosion.doubleFramesToLive = RCL_nonZero( - SFG_GET_PROJECTILE_FRAMES_TO_LIVE(SFG_PROJECTILE_EXPLOSION) / 2); - - SFG_createProjectile(explosion); - - uint8_t damage = SFG_getDamageValue(SFG_WEAPON_FIRE_TYPE_FIREBALL); - - if (SFG_taxicabDistance(x,y,z,SFG_player.camera.position.x, - SFG_player.camera.position.y,SFG_player.camera.height) - <= SFG_EXPLOSION_RADIUS) - { - SFG_playerChangeHealth(-1 * damage); - SFG_pushPlayerAway(x,y,SFG_EXPLOSION_PUSH_AWAY_DISTANCE); - } - - for (uint16_t i = 0; i < SFG_currentLevel.monsterRecordCount; ++i) - { - SFG_MonsterRecord *monster = &(SFG_currentLevel.monsterRecords[i]); - - uint16_t state = SFG_MR_STATE(*monster); - - if ((state == SFG_MONSTER_STATE_INACTIVE) || - (state == SFG_MONSTER_STATE_DEAD)) - continue; - - RCL_Unit monsterHeight = - SFG_floorHeightAt( - SFG_MONSTER_COORD_TO_SQUARES(monster->coords[0]), - SFG_MONSTER_COORD_TO_SQUARES(monster->coords[1])) - + RCL_UNITS_PER_SQUARE / 2; - - if (SFG_taxicabDistance( - SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[0]), - SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[1]),monsterHeight, - x,y,z) <= SFG_EXPLOSION_RADIUS) - { - SFG_monsterChangeHealth(monster, - -1 * SFG_getDamageValue(SFG_WEAPON_FIRE_TYPE_FIREBALL)); - } - } - - // explode nearby barrels - - if (damage >= SFG_BARREL_EXPLOSION_DAMAGE_THRESHOLD) - for (uint16_t i = 0; i < SFG_currentLevel.itemRecordCount; ++i) - { - SFG_ItemRecord item = SFG_currentLevel.itemRecords[i]; - - /* We DON'T check just active barrels but all, otherwise it looks weird - that out of sight barrels in a line didn't explode.*/ - - SFG_LevelElement element = SFG_ITEM_RECORD_LEVEL_ELEMENT(item); - - if (element.type != SFG_LEVEL_ELEMENT_BARREL) - continue; - - RCL_Unit elementX = - element.coords[0] * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2; - - RCL_Unit elementY = - element.coords[1] * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2; - - RCL_Unit elementHeight = - SFG_floorHeightAt(element.coords[0],element.coords[1]); - - if (SFG_taxicabDistance( - x,y,z,elementX,elementY,elementHeight) <= SFG_EXPLOSION_RADIUS) - { - SFG_explodeBarrel(i,elementX,elementY,elementHeight); - i--; - } - } -} - -void SFG_createDust(RCL_Unit x, RCL_Unit y, RCL_Unit z) -{ - SFG_ProjectileRecord dust; - - dust.type = SFG_PROJECTILE_DUST; - - dust.position[0] = x; - dust.position[1] = y; - dust.position[2] = z; - - dust.direction[0] = 0; - dust.direction[1] = 0; - dust.direction[2] = 0; - - dust.doubleFramesToLive = - RCL_nonZero(SFG_GET_PROJECTILE_FRAMES_TO_LIVE(SFG_PROJECTILE_DUST) / 2); - - SFG_createProjectile(dust); -} - -void SFG_getMonsterWorldPosition(SFG_MonsterRecord *monster, RCL_Unit *x, - RCL_Unit *y, RCL_Unit *z) -{ - *x = SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[0]); - *y = SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[1]); - *z = SFG_floorHeightAt( - SFG_MONSTER_COORD_TO_SQUARES(monster->coords[0]), - SFG_MONSTER_COORD_TO_SQUARES(monster->coords[1])) - + RCL_UNITS_PER_SQUARE / 2; -} - -void SFG_monsterPerformAI(SFG_MonsterRecord *monster) -{ - uint8_t state = SFG_MR_STATE(*monster); - uint8_t type = SFG_MR_TYPE(*monster); - uint8_t monsterNumber = SFG_MONSTER_TYPE_TO_INDEX(type); - uint8_t attackType = SFG_GET_MONSTER_ATTACK_TYPE(monsterNumber); - - int8_t coordAdd[2]; - - coordAdd[0] = 0; - coordAdd[1] = 0; - - uint8_t notRanged = - (attackType == SFG_MONSTER_ATTACK_MELEE) || - (attackType == SFG_MONSTER_ATTACK_EXPLODE); - - uint8_t monsterSquare[2] = - { - SFG_MONSTER_COORD_TO_SQUARES(monster->coords[0]), - SFG_MONSTER_COORD_TO_SQUARES(monster->coords[1]) - }; - - RCL_Unit currentHeight = - SFG_floorCollisionHeightAt(monsterSquare[0],monsterSquare[1]); - - if ( // sometimes randomly attack - !notRanged && - (SFG_random() < - SFG_GET_MONSTER_AGGRESSIVITY(SFG_MONSTER_TYPE_TO_INDEX(type))) - ) - { - if (SFG_random() % 4 != 0) - { - // attack - - state = SFG_MONSTER_STATE_ATTACKING; - - if (type != SFG_LEVEL_ELEMENT_MONSTER_WARRIOR) - { - RCL_Vector2D pos; - RCL_Vector2D dir; - - pos.x = SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[0]); - pos.y = SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[1]); - - dir.x = SFG_player.camera.position.x - pos.x - - 128 * SFG_MONSTER_AIM_RANDOMNESS + - SFG_random() * SFG_MONSTER_AIM_RANDOMNESS; - - dir.y = SFG_player.camera.position.y - pos.y - - 128 * SFG_MONSTER_AIM_RANDOMNESS + - SFG_random() * SFG_MONSTER_AIM_RANDOMNESS; - - dir = RCL_normalize(dir); - - uint8_t projectile; - - switch (SFG_GET_MONSTER_ATTACK_TYPE(monsterNumber)) - { - case SFG_MONSTER_ATTACK_FIREBALL: - projectile = SFG_PROJECTILE_FIREBALL; - break; - - case SFG_MONSTER_ATTACK_BULLET: - projectile = SFG_PROJECTILE_BULLET; - break; - - case SFG_MONSTER_ATTACK_PLASMA: - projectile = SFG_PROJECTILE_PLASMA; - break; - - case SFG_MONSTER_ATTACK_FIREBALL_BULLET: - projectile = (SFG_random() < 128) ? - SFG_PROJECTILE_FIREBALL : - SFG_PROJECTILE_BULLET; - break; - - case SFG_MONSTER_ATTACK_FIREBALL_PLASMA: - projectile = (SFG_random() < 128) ? - SFG_PROJECTILE_FIREBALL : - SFG_PROJECTILE_PLASMA; - break; - - default: - projectile = SFG_PROJECTILE_NONE; - break; - } - - if (projectile == SFG_PROJECTILE_BULLET) - SFG_playGameSound(0, - SFG_distantSoundVolume( - SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[0]), - SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[1]), - currentHeight) - ); - - SFG_launchProjectile( - projectile, - pos, - currentHeight + RCL_UNITS_PER_SQUARE / 2, - dir, - 0, - SFG_PROJECTILE_SPAWN_OFFSET - ); - } - } - else - state = SFG_MONSTER_STATE_IDLE; - } - else if (state == SFG_MONSTER_STATE_IDLE) - { - if (notRanged) - { - // non-ranged monsters walk towards player - - RCL_Unit pX, pY, pZ; - SFG_getMonsterWorldPosition(monster,&pX,&pY,&pZ); - - uint8_t isClose = // close to player? - SFG_taxicabDistance(pX,pY,pZ, - SFG_player.camera.position.x, - SFG_player.camera.position.y, - SFG_player.camera.height) <= SFG_MELEE_RANGE; - - if (!isClose) - { - // walk towards player - - if (monsterSquare[0] > SFG_player.squarePosition[0]) - { - if (monsterSquare[1] > SFG_player.squarePosition[1]) - state = SFG_MONSTER_STATE_GOING_NW; - else if (monsterSquare[1] < SFG_player.squarePosition[1]) - state = SFG_MONSTER_STATE_GOING_SW; - else - state = SFG_MONSTER_STATE_GOING_W; - } - else if (monsterSquare[0] < SFG_player.squarePosition[0]) - { - if (monsterSquare[1] > SFG_player.squarePosition[1]) - state = SFG_MONSTER_STATE_GOING_NE; - else if (monsterSquare[1] < SFG_player.squarePosition[1]) - state = SFG_MONSTER_STATE_GOING_SE; - else - state = SFG_MONSTER_STATE_GOING_E; - } - else - { - if (monsterSquare[1] > SFG_player.squarePosition[1]) - state = SFG_MONSTER_STATE_GOING_N; - else if (monsterSquare[1] < SFG_player.squarePosition[1]) - state = SFG_MONSTER_STATE_GOING_S; - } - } - else // is close - { - // melee, close-up attack - - if (attackType == SFG_MONSTER_ATTACK_MELEE) - { - // melee attack - - state = SFG_MONSTER_STATE_ATTACKING; - - SFG_playerChangeHealth( - -1 * SFG_getDamageValue(SFG_WEAPON_FIRE_TYPE_MELEE)); - - SFG_playGameSound(3,255); - } - else // SFG_MONSTER_ATTACK_EXPLODE - { - // explode - - SFG_createExplosion(pX,pY,pZ); - monster->health = 0; - } - } - } - else // ranged monsters - { - // choose walk direction randomly - - switch (SFG_random() % 8) - { - case 0: state = SFG_MONSTER_STATE_GOING_E; break; - case 1: state = SFG_MONSTER_STATE_GOING_W; break; - case 2: state = SFG_MONSTER_STATE_GOING_N; break; - case 3: state = SFG_MONSTER_STATE_GOING_S; break; - case 4: state = SFG_MONSTER_STATE_GOING_NE; break; - case 5: state = SFG_MONSTER_STATE_GOING_NW; break; - case 6: state = SFG_MONSTER_STATE_GOING_SE; break; - case 7: state = SFG_MONSTER_STATE_GOING_SW; break; - default: break; - } - } - } - else if (state == SFG_MONSTER_STATE_ATTACKING) - { - state = SFG_MONSTER_STATE_IDLE; - } - else - { - int8_t add = 1; - - if (attackType == SFG_MONSTER_ATTACK_MELEE) - add = 2; - else if (attackType == SFG_MONSTER_ATTACK_EXPLODE) - add = 3; - - if (state == SFG_MONSTER_STATE_GOING_E || - state == SFG_MONSTER_STATE_GOING_NE || - state == SFG_MONSTER_STATE_GOING_SE) - coordAdd[0] = add; - else if (state == SFG_MONSTER_STATE_GOING_W || - state == SFG_MONSTER_STATE_GOING_SW || - state == SFG_MONSTER_STATE_GOING_NW) - coordAdd[0] = -1 * add; - - if (state == SFG_MONSTER_STATE_GOING_N || - state == SFG_MONSTER_STATE_GOING_NE || - state == SFG_MONSTER_STATE_GOING_NW) - coordAdd[1] = -1 * add; - else if (state == SFG_MONSTER_STATE_GOING_S || - state == SFG_MONSTER_STATE_GOING_SE || - state == SFG_MONSTER_STATE_GOING_SW) - coordAdd[1] = add; - - if ((coordAdd[0] != 0 || coordAdd[1] != 0) && SFG_random() < - SFG_MONSTER_SOUND_PROBABILITY) - SFG_playGameSound(5, - SFG_distantSoundVolume( - SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[0]), - SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[1]), - currentHeight) / 2); - - state = SFG_MONSTER_STATE_IDLE; - } - - int16_t newPos[2]; - - newPos[0] = monster->coords[0] + coordAdd[0]; - newPos[1] = monster->coords[1] + coordAdd[1]; - - int8_t collision = 0; - - if (newPos[0] < 0 || newPos[0] >= 256 || newPos[1] < 0 || newPos[1] >= 256) - { - collision = 1; - } - else - { - uint8_t movingDiagonally = (coordAdd[0] != 0) && (coordAdd[1] != 0); - - // when moving diagonally, we need to check extra tiles - - for (uint8_t i = 0; i < (1 + movingDiagonally); ++i) - { - newPos[0] = monster->coords[0] + (i != 1) * coordAdd[0]; - - RCL_Unit newHeight = - SFG_floorCollisionHeightAt( - SFG_MONSTER_COORD_TO_SQUARES(newPos[0]), - SFG_MONSTER_COORD_TO_SQUARES(newPos[1])); - - collision = - RCL_abs(currentHeight - newHeight) > RCL_CAMERA_COLL_STEP_HEIGHT; - - if (!collision) - collision = (SFG_ceilingHeightAt( - SFG_MONSTER_COORD_TO_SQUARES(newPos[0]), - SFG_MONSTER_COORD_TO_SQUARES(newPos[1])) - newHeight) < - SFG_MONSTER_COLLISION_HEIGHT; - - if (collision) - break; - } - - newPos[0] = monster->coords[0] + coordAdd[0]; - } - - if (collision) - { - state = SFG_MONSTER_STATE_IDLE; - // ^ will force the monster to choose random direction in the next update - - newPos[0] = monster->coords[0]; - newPos[1] = monster->coords[1]; - } - - monster->stateType = state | (monsterNumber << 4); - monster->coords[0] = newPos[0]; - monster->coords[1] = newPos[1];; -} - -static inline uint8_t SFG_elementCollides( - RCL_Unit pointX, - RCL_Unit pointY, - RCL_Unit pointZ, - RCL_Unit elementX, - RCL_Unit elementY, - RCL_Unit elementHeight -) -{ - return - SFG_taxicabDistance(pointX,pointY,pointZ,elementX,elementY,elementHeight) - <= SFG_ELEMENT_COLLISION_RADIUS; -} - -/** - Checks collision of a projectile with level element at given position. -*/ -uint8_t SFG_projectileCollides(SFG_ProjectileRecord *projectile, - RCL_Unit x, RCL_Unit y, RCL_Unit z) -{ - if (!SFG_elementCollides(x,y,z, - projectile->position[0],projectile->position[1],projectile->position[2])) - return 0; - - if ((projectile->type == SFG_PROJECTILE_EXPLOSION) || - (projectile->type == SFG_PROJECTILE_DUST)) - return 0; - - /* For directional projectiles we only register a collision if its direction - is "towards" the element so that the shooter doesn't get shot by his own - projectile. */ - - RCL_Vector2D projDir, toElement; - - projDir.x = projectile->direction[0]; - projDir.y = projectile->direction[1]; - - toElement.x = x - projectile->position[0]; - toElement.y = y - projectile->position[1]; - - return RCL_vectorsAngleCos(projDir,toElement) >= 0; -} - -/** - Updates a frame of the currently loaded level, i.e. enemies, projectiles, - aimations etc., with the exception of player. -*/ -void SFG_updateLevel() -{ - // update projectiles: - - uint8_t substractFrames = - ((SFG_game.frame - SFG_currentLevel.frameStart) & 0x01) ? 1 : 0; - /* ^ only substract frames to live every other frame because a maximum of - 256 frames would be too few */ - - for (int8_t i = 0; i < SFG_currentLevel.projectileRecordCount; ++i) - { // ^ has to be signed - SFG_ProjectileRecord *p = &(SFG_currentLevel.projectileRecords[i]); - - uint8_t attackType = 255; - - if (p->type == SFG_PROJECTILE_BULLET) - attackType = SFG_WEAPON_FIRE_TYPE_BULLET; - else if (p->type == SFG_PROJECTILE_PLASMA) - attackType = SFG_WEAPON_FIRE_TYPE_PLASMA; - - RCL_Unit pos[3] = {0,0,0}; /* we have to convert from uint16_t because of - under/overflows */ - uint8_t eliminate = 0; - - for (uint8_t j = 0; j < 3; ++j) - { - pos[j] = p->position[j]; - pos[j] += p->direction[j]; - - if ( // projectile outside map? - (pos[j] < 0) || - (pos[j] >= (SFG_MAP_SIZE * RCL_UNITS_PER_SQUARE))) - { - eliminate = 1; - break; - } - } - - if (p->doubleFramesToLive == 0) // no more time to live? - { - eliminate = 1; - } - else if ( - (p->type != SFG_PROJECTILE_EXPLOSION) && - (p->type != SFG_PROJECTILE_DUST)) - { - if (SFG_projectileCollides( // collides with player? - p, - SFG_player.camera.position.x, - SFG_player.camera.position.y, - SFG_player.camera.height)) - { - eliminate = 1; - - SFG_playerChangeHealth(-1 * SFG_getDamageValue(attackType)); - } - - /* Check collision with the map (we don't use SFG_floorCollisionHeightAt - because collisions with items have to be done differently for - projectiles). */ - - if (!eliminate && - ((SFG_floorHeightAt(pos[0] / RCL_UNITS_PER_SQUARE,pos[1] / - RCL_UNITS_PER_SQUARE) >= pos[2]) - || - (SFG_ceilingHeightAt(pos[0] / RCL_UNITS_PER_SQUARE,pos[1] / - RCL_UNITS_PER_SQUARE) <= pos[2])) - ) - eliminate = 1; - - // check collision with active level elements - - if (!eliminate) // monsters - for (uint16_t j = 0; j < SFG_currentLevel.monsterRecordCount; ++j) - { - SFG_MonsterRecord *m = &(SFG_currentLevel.monsterRecords[j]); - - uint8_t state = SFG_MR_STATE(*m); - - if ((state != SFG_MONSTER_STATE_INACTIVE) && - (state != SFG_MONSTER_STATE_DEAD)) - { - if (SFG_projectileCollides(p, - SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[0]), - SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[1]), - SFG_floorHeightAt( - SFG_MONSTER_COORD_TO_SQUARES(m->coords[0]), - SFG_MONSTER_COORD_TO_SQUARES(m->coords[1])) - )) - { - eliminate = 1; - SFG_monsterChangeHealth(m,-1 * SFG_getDamageValue(attackType)); - break; - } - } - } - - if (!eliminate) // items (can't check itemCollisionMap because of barrels) - for (uint16_t j = 0; j < SFG_currentLevel.itemRecordCount; ++j) - { - const SFG_LevelElement *e = SFG_getActiveItemElement(j); - - if (e != 0 && SFG_itemCollides(e->type)) - { - RCL_Unit x = SFG_ELEMENT_COORD_TO_RCL_UNITS(e->coords[0]); - RCL_Unit y = SFG_ELEMENT_COORD_TO_RCL_UNITS(e->coords[1]); - RCL_Unit z = SFG_floorHeightAt(e->coords[0],e->coords[1]); - - if (SFG_projectileCollides(p,x,y,z)) - { - if ( - (e->type == SFG_LEVEL_ELEMENT_BARREL) && - (SFG_getDamageValue(attackType) >= - SFG_BARREL_EXPLOSION_DAMAGE_THRESHOLD) - ) - { - SFG_explodeBarrel(j,x,y,z); - } - - eliminate = 1; - break; - } - } - } - } - - if (eliminate) - { - if (p->type == SFG_PROJECTILE_FIREBALL) - SFG_createExplosion(p->position[0],p->position[1],p->position[2]); - else if (p->type == SFG_PROJECTILE_BULLET) - SFG_createDust(p->position[0],p->position[1],p->position[2]); - else if (p->type == SFG_PROJECTILE_PLASMA) - SFG_playGameSound(4,SFG_distantSoundVolume(pos[0],pos[1],pos[2])); - - // remove the projectile - - for (uint8_t j = i; j < SFG_currentLevel.projectileRecordCount - 1; ++j) - SFG_currentLevel.projectileRecords[j] = - SFG_currentLevel.projectileRecords[j + 1]; - - SFG_currentLevel.projectileRecordCount--; - - i--; - } - else - { - p->position[0] = pos[0]; - p->position[1] = pos[1]; - p->position[2] = pos[2]; - } - - p->doubleFramesToLive -= substractFrames; - } - - // handle door: - if (SFG_currentLevel.doorRecordCount > 0) // has to be here - { - /* Check door on whether a player is standing nearby. For performance - reasons we only check a few doors and move to others in the next - frame. */ - - if (SFG_currentLevel.checkedDoorIndex == 0) - { - uint8_t count = SFG_player.cards >> 6; - - SFG_player.cards = (count <= 1) ? - (SFG_player.cards & 0x07) : - ((SFG_player.cards & 0x7f) | ((count - 1) << 6)); - } - - for (uint16_t i = 0; - i < RCL_min(SFG_ELEMENT_DISTANCES_CHECKED_PER_FRAME, - SFG_currentLevel.doorRecordCount); - ++i) - { - SFG_DoorRecord *door = - &(SFG_currentLevel.doorRecords[SFG_currentLevel.checkedDoorIndex]); - - uint8_t upDownState = door->state & SFG_DOOR_UP_DOWN_MASK; - - uint8_t newUpDownState = 0; - - uint8_t lock = SFG_DOOR_LOCK(door->state); - - if ( // player near door? - (door->coords[0] >= (SFG_player.squarePosition[0] - 1)) && - (door->coords[0] <= (SFG_player.squarePosition[0] + 1)) && - (door->coords[1] >= (SFG_player.squarePosition[1] - 1)) && - (door->coords[1] <= (SFG_player.squarePosition[1] + 1))) - { - if (lock == 0) - { - newUpDownState = SFG_DOOR_UP_DOWN_MASK; - } - else - { - lock = 1 << (lock - 1); - - if (SFG_player.cards & lock) // player has the card? - newUpDownState = SFG_DOOR_UP_DOWN_MASK; - else - SFG_player.cards = - (SFG_player.cards & 0x07) | (lock << 3) | (2 << 6); - } - } - - if (upDownState != newUpDownState) - SFG_playGameSound(1,255); - - door->state = (door->state & ~SFG_DOOR_UP_DOWN_MASK) | newUpDownState; - - SFG_currentLevel.checkedDoorIndex++; - - if (SFG_currentLevel.checkedDoorIndex >= SFG_currentLevel.doorRecordCount) - SFG_currentLevel.checkedDoorIndex = 0; - } - - // move door up/down: - for (uint32_t i = 0; i < SFG_currentLevel.doorRecordCount; ++i) - { - SFG_DoorRecord *door = &(SFG_currentLevel.doorRecords[i]); - - int8_t height = door->state & SFG_DOOR_VERTICAL_POSITION_MASK; - - height = (door->state & SFG_DOOR_UP_DOWN_MASK) ? - RCL_min(0x1f,height + SFG_DOOR_INCREMENT_PER_FRAME) : - RCL_max(0x00,height - SFG_DOOR_INCREMENT_PER_FRAME); - - door->state = (door->state & ~SFG_DOOR_VERTICAL_POSITION_MASK) | height; - } - } - - // handle items, in a similar manner to door: - if (SFG_currentLevel.itemRecordCount > 0) // has to be here - { - // check item distances: - - for (uint16_t i = 0; - i < RCL_min(SFG_ELEMENT_DISTANCES_CHECKED_PER_FRAME, - SFG_currentLevel.itemRecordCount); - ++i) - { - SFG_ItemRecord item = - SFG_currentLevel.itemRecords[SFG_currentLevel.checkedItemIndex]; - - item &= ~SFG_ITEM_RECORD_ACTIVE_MASK; - - SFG_LevelElement e = - SFG_currentLevel.levelPointer->elements[item]; - - if ( - SFG_isInActiveDistanceFromPlayer( - e.coords[0] * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2, - e.coords[1] * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2, - SFG_floorHeightAt(e.coords[0],e.coords[1]) + RCL_UNITS_PER_SQUARE / 2) - ) - item |= SFG_ITEM_RECORD_ACTIVE_MASK; - - SFG_currentLevel.itemRecords[SFG_currentLevel.checkedItemIndex] = item; - - SFG_currentLevel.checkedItemIndex++; - - if (SFG_currentLevel.checkedItemIndex >= SFG_currentLevel.itemRecordCount) - SFG_currentLevel.checkedItemIndex = 0; - } - } - - // similarly handle monsters: - if (SFG_currentLevel.monsterRecordCount > 0) // has to be here - { - // check monster distances: - - for (uint16_t i = 0; - i < RCL_min(SFG_ELEMENT_DISTANCES_CHECKED_PER_FRAME, - SFG_currentLevel.monsterRecordCount); - ++i) - { - SFG_MonsterRecord *monster = - &(SFG_currentLevel.monsterRecords[SFG_currentLevel.checkedMonsterIndex]); - - if ( // far away from the player? - !SFG_isInActiveDistanceFromPlayer( - SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[0]), - SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[1]), - SFG_floorHeightAt( - SFG_MONSTER_COORD_TO_SQUARES(monster->coords[0]), - SFG_MONSTER_COORD_TO_SQUARES(monster->coords[1])) - + RCL_UNITS_PER_SQUARE / 2 - ) - ) - { - monster->stateType = - (monster->stateType & SFG_MONSTER_MASK_TYPE) | - SFG_MONSTER_STATE_INACTIVE; - } - else if (SFG_MR_STATE(*monster) == SFG_MONSTER_STATE_INACTIVE) - { - monster->stateType = - (monster->stateType & SFG_MONSTER_MASK_TYPE) | - (monster->health != 0 ? - SFG_MONSTER_STATE_IDLE : SFG_MONSTER_STATE_DEAD); - } - - SFG_currentLevel.checkedMonsterIndex++; - - if (SFG_currentLevel.checkedMonsterIndex >= - SFG_currentLevel.monsterRecordCount) - SFG_currentLevel.checkedMonsterIndex = 0; - } - } - - // update AI and handle dead monsters: - if ((SFG_game.frame - SFG_currentLevel.frameStart) % - SFG_AI_UPDATE_FRAME_INTERVAL == 0) - { - for (uint16_t i = 0; i < SFG_currentLevel.monsterRecordCount; ++i) - { - SFG_MonsterRecord *monster = &(SFG_currentLevel.monsterRecords[i]); - uint8_t state = SFG_MR_STATE(*monster); - - if ((state == SFG_MONSTER_STATE_INACTIVE) || - (state == SFG_MONSTER_STATE_DEAD)) - continue; - - if (state == SFG_MONSTER_STATE_DYING) - { - if (SFG_MR_TYPE(*monster) == SFG_LEVEL_ELEMENT_MONSTER_ENDER) - { - SFG_currentLevel.bossCount--; - - // last boss killed gives player a key card - - if (SFG_currentLevel.bossCount == 0) - { - SFG_LOG("boss killed, giving player a card"); - SFG_player.cards |= 0x04; - } - } - - monster->stateType = - (monster->stateType & 0xf0) | SFG_MONSTER_STATE_DEAD; - } - else if (monster->health == 0) - { - monster->stateType = (monster->stateType & SFG_MONSTER_MASK_TYPE) | - SFG_MONSTER_STATE_DYING; - - SFG_processEvent(SFG_EVENT_MONSTER_DIES,SFG_MR_TYPE(*monster)); - - if (SFG_MR_TYPE(*monster) == SFG_LEVEL_ELEMENT_MONSTER_EXPLODER) - SFG_createExplosion( - SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[0]), - SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[1]), - SFG_floorCollisionHeightAt( - SFG_MONSTER_COORD_TO_SQUARES(monster->coords[0]), - SFG_MONSTER_COORD_TO_SQUARES(monster->coords[0])) + - RCL_UNITS_PER_SQUARE / 2); - } - else - { -#if SFG_PREVIEW_MODE == 0 - SFG_monsterPerformAI(monster); -#endif - } - } - } -} - -/** - Maps square position on the map to a bit in map reveal mask. -*/ -static inline uint16_t SFG_getMapRevealBit(uint8_t squareX, uint8_t squareY) -{ - return 1 << ((squareY / 16) * 4 + squareX / 16); -} - -/** - Checks a 3D point visibility from player's position (WITHOUT considering - facing direction). -*/ -static inline uint8_t SFG_spriteIsVisible(RCL_Vector2D pos, RCL_Unit height, - uint8_t spriteSize) -{ - return - RCL_castRay3D( - SFG_player.camera.position, - SFG_player.camera.height, - pos, - height, - SFG_floorHeightAt, - SFG_ceilingHeightAt, - SFG_game.rayConstraints - ) == RCL_UNITS_PER_SQUARE; -} - -/** - Returns a tangent in RCL_Unit of vertical autoaim, given current game state. -*/ -RCL_Unit SFG_autoaimVertically() -{ - for (uint16_t i = 0; i < SFG_currentLevel.monsterRecordCount; ++i) - { - SFG_MonsterRecord m = SFG_currentLevel.monsterRecords[i]; - - if (SFG_MR_STATE(m) == SFG_MONSTER_STATE_INACTIVE) - continue; - - RCL_Vector2D worldPosition, toMonster; - - worldPosition.x = SFG_MONSTER_COORD_TO_RCL_UNITS(m.coords[0]); - worldPosition.y = SFG_MONSTER_COORD_TO_RCL_UNITS(m.coords[1]); - - toMonster.x = worldPosition.x - SFG_player.camera.position.x; - toMonster.y = worldPosition.y - SFG_player.camera.position.y; - - if (RCL_abs( - RCL_vectorsAngleCos(SFG_player.direction,toMonster) - - RCL_UNITS_PER_SQUARE) < SFG_VERTICAL_AUTOAIM_ANGLE_THRESHOLD) - { - uint8_t spriteSize = SFG_GET_MONSTER_SPRITE_SIZE( - SFG_MONSTER_TYPE_TO_INDEX(SFG_MR_TYPE(m))); - - RCL_Unit worldHeight = - SFG_floorHeightAt( - SFG_MONSTER_COORD_TO_SQUARES(m.coords[0]), - SFG_MONSTER_COORD_TO_SQUARES(m.coords[1])) - + - SFG_SPRITE_SIZE_TO_HEIGHT_ABOVE_GROUND(spriteSize); - - if (SFG_spriteIsVisible(worldPosition,worldHeight,spriteSize)) - { - RCL_Unit distance = RCL_len(toMonster); - - return ((worldHeight - SFG_player.camera.height) * RCL_UNITS_PER_SQUARE) - / distance; - } - } - } - - return 0; -} - -/** - Draws text on screen using the bitmap font stored in assets. -*/ -void SFG_drawText( - const char *text, - uint16_t x, - uint16_t y, - uint8_t size, - uint8_t color, - uint16_t maxLength, - uint16_t limitX) -{ - if (size == 0) - size = 1; - - if (limitX == 0) - limitX = 65535; - - if (maxLength == 0) - maxLength = 65535; - - uint16_t pos = 0; - - uint16_t currentX = x; - uint16_t currentY = y; - - while (pos < maxLength && text[pos] != 0) // for each character - { - uint16_t character = SFG_font[SFG_charToFontIndex(text[pos])]; - - for (uint8_t i = 0; i < SFG_FONT_CHARACTER_SIZE; ++i) // for each line - { - currentY = y; - - for (uint8_t j = 0; j < SFG_FONT_CHARACTER_SIZE; ++j) // for each row - { - if (character & 0x8000) - for (uint8_t k = 0; k < size; ++k) - for (uint8_t l = 0; l < size; ++l) - { - uint16_t drawX = currentX + k; - uint16_t drawY = currentY + l; - - if (drawX < SFG_GAME_RESOLUTION_X && - drawY < SFG_GAME_RESOLUTION_Y) - SFG_setGamePixel(drawX,drawY,color); - } - - currentY += size; - character = character << 1; - } - - currentX += size; - } - - currentX += size; // space - - if (currentX > limitX) - { - currentX = x; - y += (SFG_FONT_CHARACTER_SIZE + 1) * size; - } - - pos++; - } -} - -void SFG_drawLevelStartOverlay() -{ - uint8_t stage = ((SFG_game.frameTime - SFG_game.stateChangeTime) * 4) / - SFG_LEVEL_START_DURATION; - - // fade in: - - for (uint16_t y = 0; y < SFG_GAME_RESOLUTION_Y; ++y) - for (uint16_t x = 0; x < SFG_GAME_RESOLUTION_X; ++x) - { - uint8_t draw = 0; - - switch (stage) - { - case 0: draw = 1; break; - case 1: draw = (x % 2) || (y % 2); break; - case 2: draw = (x % 2) == (y % 2); break; - case 3: draw = (x % 2) && (y % 2); break; - default: break; - } - - if (draw) - SFG_setGamePixel(x,y,0); - } - - if (SFG_game.saved == 1) - SFG_drawText(SFG_TEXT_SAVED,SFG_HUD_MARGIN,SFG_HUD_MARGIN, - SFG_FONT_SIZE_MEDIUM,7,255,0); -} - -/** - Sets player's height to match the floor height below him. -*/ -void SFG_updatePlayerHeight() -{ - SFG_player.camera.height = - SFG_floorCollisionHeightAt( - SFG_player.squarePosition[0],SFG_player.squarePosition[1]) + - RCL_CAMERA_COLL_HEIGHT_BELOW; -} - -/** - Part of SFG_gameStep() for SFG_GAME_STATE_PLAYING. -*/ -void SFG_gameStepPlaying() -{ - if ( - (SFG_keyIsDown(SFG_KEY_C) && SFG_keyIsDown(SFG_KEY_DOWN)) || - SFG_keyIsDown(SFG_KEY_MENU)) - { - SFG_setGameState(SFG_GAME_STATE_MENU); - SFG_playGameSound(3,SFG_MENU_CLICK_VOLUME); - return; - } - - SFG_updateLevel(); - - int8_t recomputeDirection = SFG_currentLevel.frameStart == SFG_game.frame; - - RCL_Vector2D moveOffset; - - moveOffset.x = 0; - moveOffset.y = 0; - - int8_t strafe = 0; - - uint8_t currentWeapon = SFG_player.weapon; - -#if SFG_HEADBOB_ENABLED - int8_t bobbing = 0; -#endif - - int8_t shearing = 0; - - if (SFG_player.weaponCooldownFrames > 0) - SFG_player.weaponCooldownFrames--; - - if (SFG_keyJustPressed(SFG_KEY_TOGGLE_FREELOOK)) - SFG_game.settings = (SFG_game.settings & 0x04) ? - (SFG_game.settings & ~0x0c) : (SFG_game.settings | 0x0c); - - int8_t canSwitchWeapon = SFG_player.weaponCooldownFrames == 0; - - if (SFG_keyJustPressed(SFG_KEY_NEXT_WEAPON) && canSwitchWeapon) - SFG_playerRotateWeapon(1); - else if (SFG_keyJustPressed(SFG_KEY_PREVIOUS_WEAPON) && canSwitchWeapon) - SFG_playerRotateWeapon(0); - else if (SFG_keyJustPressed(SFG_KEY_CYCLE_WEAPON) && - SFG_player.previousWeaponDirection) - SFG_playerRotateWeapon(SFG_player.previousWeaponDirection > 0); - - uint8_t shearingOn = SFG_game.settings & 0x04; - - if (SFG_keyIsDown(SFG_KEY_B)) - { - if (shearingOn) // B + U/D: shearing (if on) - { - if (SFG_keyIsDown(SFG_KEY_UP)) - { - SFG_player.camera.shear = - RCL_min(SFG_CAMERA_MAX_SHEAR_PIXELS, - SFG_player.camera.shear + SFG_CAMERA_SHEAR_STEP_PER_FRAME); - - shearing = 1; - } - else if (SFG_keyIsDown(SFG_KEY_DOWN)) - { - SFG_player.camera.shear = - RCL_max(-1 * SFG_CAMERA_MAX_SHEAR_PIXELS, - SFG_player.camera.shear - SFG_CAMERA_SHEAR_STEP_PER_FRAME); - - shearing = 1; - } - } - - if (!SFG_keyIsDown(SFG_KEY_C)) - { // B + L/R: strafing - if (SFG_keyIsDown(SFG_KEY_LEFT)) - strafe = -1; - else if (SFG_keyIsDown(SFG_KEY_RIGHT)) - strafe = 1; - } - } - - if (SFG_keyIsDown(SFG_KEY_C)) // C + A/B/L/R: weapon switching - { - if ((SFG_keyJustPressed(SFG_KEY_LEFT) || SFG_keyJustPressed(SFG_KEY_A)) && - canSwitchWeapon) - SFG_playerRotateWeapon(0); - else if ( - (SFG_keyJustPressed(SFG_KEY_RIGHT) || SFG_keyJustPressed(SFG_KEY_B)) && - canSwitchWeapon) - SFG_playerRotateWeapon(1); - } - else if (!SFG_keyIsDown(SFG_KEY_B)) // L/R: turning - { - if (SFG_keyIsDown(SFG_KEY_LEFT)) - { - SFG_player.camera.direction -= SFG_PLAYER_TURN_UNITS_PER_FRAME; - recomputeDirection = 1; - } - else if (SFG_keyIsDown(SFG_KEY_RIGHT)) - { - SFG_player.camera.direction += SFG_PLAYER_TURN_UNITS_PER_FRAME; - recomputeDirection = 1; - } - } - - if (!SFG_keyIsDown(SFG_KEY_B) || !shearingOn) // U/D: movement - { - if (SFG_keyIsDown(SFG_KEY_UP)) - { - moveOffset.x += SFG_player.direction.x; - moveOffset.y += SFG_player.direction.y; -#if SFG_HEADBOB_ENABLED - bobbing = 1; -#endif - } - else if (SFG_keyIsDown(SFG_KEY_DOWN)) - { - moveOffset.x -= SFG_player.direction.x; - moveOffset.y -= SFG_player.direction.y; -#if SFG_HEADBOB_ENABLED - bobbing = 1; -#endif - } - } - - int16_t mouseX = 0, mouseY = 0; - - SFG_getMouseOffset(&mouseX,&mouseY); - - if (mouseX != 0) // mouse turning - { - SFG_player.camera.direction += - (mouseX * SFG_MOUSE_SENSITIVITY_HORIZONTAL) / 128; - - recomputeDirection = 1; - } - - if ((mouseY != 0) && shearingOn) // mouse shearing - SFG_player.camera.shear = - RCL_max(RCL_min( - SFG_player.camera.shear - - (mouseY * SFG_MOUSE_SENSITIVITY_VERTICAL) / 128, - SFG_CAMERA_MAX_SHEAR_PIXELS), - -1 * SFG_CAMERA_MAX_SHEAR_PIXELS); - - if (recomputeDirection) - SFG_recomputePLayerDirection(); - - if (SFG_keyIsDown(SFG_KEY_STRAFE_LEFT)) - strafe = -1; - else if (SFG_keyIsDown(SFG_KEY_STRAFE_RIGHT)) - strafe = 1; - - if (strafe != 0) - { - moveOffset.x += strafe * SFG_player.direction.y; - moveOffset.y -= strafe * SFG_player.direction.x; - } - -#if SFG_PREVIEW_MODE - if (SFG_keyIsDown(SFG_KEY_B)) - SFG_player.verticalSpeed = SFG_PLAYER_MOVE_UNITS_PER_FRAME; - else if (SFG_keyIsDown(SFG_KEY_C)) - SFG_player.verticalSpeed = -1 * SFG_PLAYER_MOVE_UNITS_PER_FRAME; - else - SFG_player.verticalSpeed = 0; -#else - RCL_Unit verticalOffset = - ( - ( - SFG_keyIsDown(SFG_KEY_JUMP) || - (SFG_keyIsDown(SFG_KEY_UP) && SFG_keyIsDown(SFG_KEY_C)) - ) && - (SFG_player.verticalSpeed == 0) && - (SFG_player.previousVerticalSpeed == 0)) ? - SFG_PLAYER_JUMP_OFFSET_PER_FRAME : // jump - (SFG_player.verticalSpeed - SFG_GRAVITY_SPEED_INCREASE_PER_FRAME); -#endif - - if (!shearing && SFG_player.camera.shear != 0 && !(SFG_game.settings & 0x08)) - { - // gradually shear back to zero - - SFG_player.camera.shear = - (SFG_player.camera.shear > 0) ? - RCL_max(0,SFG_player.camera.shear - SFG_CAMERA_SHEAR_STEP_PER_FRAME) : - RCL_min(0,SFG_player.camera.shear + SFG_CAMERA_SHEAR_STEP_PER_FRAME); - } - -#if SFG_HEADBOB_ENABLED && !SFG_PREVIEW_MODE - if (bobbing) - { - SFG_player.headBobFrame += SFG_HEADBOB_FRAME_INCREASE_PER_FRAME; - } - else if (SFG_player.headBobFrame != 0) - { - // smoothly stop bobbing - - uint8_t quadrant = (SFG_player.headBobFrame % RCL_UNITS_PER_SQUARE) / - (RCL_UNITS_PER_SQUARE / 4); - - /* When in quadrant in which sin is going away from zero, switch to the - same value of the next quadrant, so that bobbing starts to go towards - zero immediately. */ - - if (quadrant % 2 == 0) - SFG_player.headBobFrame = - ((quadrant + 1) * RCL_UNITS_PER_SQUARE / 4) + - (RCL_UNITS_PER_SQUARE / 4 - SFG_player.headBobFrame % - (RCL_UNITS_PER_SQUARE / 4)); - - RCL_Unit currentFrame = SFG_player.headBobFrame; - RCL_Unit nextFrame = SFG_player.headBobFrame + 16; - - // only stop bobbing when we pass a frame at which sin crosses zero - SFG_player.headBobFrame = - (currentFrame / (RCL_UNITS_PER_SQUARE / 2) == - nextFrame / (RCL_UNITS_PER_SQUARE / 2)) ? - nextFrame : 0; - } -#endif - - RCL_Unit previousHeight = SFG_player.camera.height; - - // handle player collision with level elements: - - // monsters: - for (uint16_t i = 0; i < SFG_currentLevel.monsterRecordCount; ++i) - { - SFG_MonsterRecord *m = &(SFG_currentLevel.monsterRecords[i]); - - uint8_t state = SFG_MR_STATE(*m); - - if (state == SFG_MONSTER_STATE_INACTIVE || state == SFG_MONSTER_STATE_DEAD) - continue; - - RCL_Vector2D mPos; - - mPos.x = SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[0]); - mPos.y = SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[1]); - - if ( - SFG_elementCollides( - SFG_player.camera.position.x, - SFG_player.camera.position.y, - SFG_player.camera.height, - mPos.x, - mPos.y, - SFG_floorHeightAt( - SFG_MONSTER_COORD_TO_SQUARES(m->coords[0]), - SFG_MONSTER_COORD_TO_SQUARES(m->coords[1])) - ) - ) - { - moveOffset = SFG_resolveCollisionWithElement( - SFG_player.camera.position,moveOffset,mPos); - } - } - - uint8_t collidesWithTeleporter = 0; - - /* item collisions with player (only those that don't stop player's movement, - as those are handled differently, via itemCollisionMap): */ - for (int16_t i = 0; i < SFG_currentLevel.itemRecordCount; ++i) - // ^ has to be int16_t (signed) - { - if (!(SFG_currentLevel.itemRecords[i] & SFG_ITEM_RECORD_ACTIVE_MASK)) - continue; - - const SFG_LevelElement *e = SFG_getActiveItemElement(i); - - if (e != 0) - { - RCL_Vector2D ePos; - - ePos.x = SFG_ELEMENT_COORD_TO_RCL_UNITS(e->coords[0]); - ePos.y = SFG_ELEMENT_COORD_TO_RCL_UNITS(e->coords[1]); - - if (!SFG_itemCollides(e->type) && - SFG_elementCollides( - SFG_player.camera.position.x, - SFG_player.camera.position.y, - SFG_player.camera.height, - ePos.x, - ePos.y, - SFG_floorHeightAt(e->coords[0],e->coords[1])) - ) - { - uint8_t eliminate = 1; - - uint8_t onlyKnife = 1; - - for (uint8_t j = 0; j < SFG_AMMO_TOTAL; ++j) - if (SFG_player.ammo[j] != 0) - { - onlyKnife = 0; - break; - } - - switch (e->type) - { - case SFG_LEVEL_ELEMENT_HEALTH: - if (SFG_player.health < SFG_PLAYER_MAX_HEALTH) - SFG_playerChangeHealth(SFG_HEALTH_KIT_VALUE); - else - eliminate = 0; - break; - -#define addAmmo(type) \ - if (SFG_player.ammo[SFG_AMMO_##type] < SFG_AMMO_MAX_##type) \ - {\ - SFG_player.ammo[SFG_AMMO_##type] = RCL_min(SFG_AMMO_MAX_##type,\ - SFG_player.ammo[SFG_AMMO_##type] + SFG_AMMO_INCREASE_##type);\ - if (onlyKnife) SFG_playerRotateWeapon(1); \ - }\ - else\ - eliminate = 0; - - case SFG_LEVEL_ELEMENT_BULLETS: - addAmmo(BULLETS) - break; - - case SFG_LEVEL_ELEMENT_ROCKETS: - addAmmo(ROCKETS) - break; - - case SFG_LEVEL_ELEMENT_PLASMA: - addAmmo(PLASMA) - break; - -#undef addAmmo - - case SFG_LEVEL_ELEMENT_CARD0: - case SFG_LEVEL_ELEMENT_CARD1: - case SFG_LEVEL_ELEMENT_CARD2: - SFG_player.cards |= 1 << (e->type - SFG_LEVEL_ELEMENT_CARD0); - break; - - case SFG_LEVEL_ELEMENT_TELEPORTER: - collidesWithTeleporter = 1; - eliminate = 0; - break; - - case SFG_LEVEL_ELEMENT_FINISH: - SFG_levelEnds(); - SFG_setGameState(SFG_GAME_STATE_WIN); - SFG_playGameSound(2,255); - SFG_processEvent(SFG_EVENT_VIBRATE,0); - SFG_processEvent( - SFG_EVENT_LEVEL_WON,SFG_currentLevel.levelNumber + 1); - eliminate = 0; - break; - - default: - eliminate = 0; - break; - } - - if (eliminate) // take the item - { -#if !SFG_PREVIEW_MODE - SFG_removeItem(i); - SFG_player.lastItemTakenFrame = SFG_game.frame; - i--; - SFG_playGameSound(3,255); - SFG_processEvent(SFG_EVENT_PLAYER_TAKES_ITEM,e->type); -#endif - } - else if ( - e->type == SFG_LEVEL_ELEMENT_TELEPORTER && - SFG_currentLevel.teleporterCount > 1 && - !SFG_player.justTeleported) - { - // teleport to random destination teleporter - - uint8_t teleporterNumber = - SFG_random() % (SFG_currentLevel.teleporterCount - 1) + 1; - - for (uint16_t j = 0; j < SFG_currentLevel.itemRecordCount; ++j) - { - SFG_LevelElement e2 = - SFG_currentLevel.levelPointer->elements - [SFG_currentLevel.itemRecords[j] & - ~SFG_ITEM_RECORD_ACTIVE_MASK]; - - if ((e2.type == SFG_LEVEL_ELEMENT_TELEPORTER) && (j != i)) - teleporterNumber--; - - if (teleporterNumber == 0) - { - SFG_player.camera.position.x = - SFG_ELEMENT_COORD_TO_RCL_UNITS(e2.coords[0]); - - SFG_player.camera.position.y = - SFG_ELEMENT_COORD_TO_RCL_UNITS(e2.coords[1]); - - SFG_player.camera.height = - SFG_floorHeightAt(e2.coords[0],e2.coords[1]) + - RCL_CAMERA_COLL_HEIGHT_BELOW; - - SFG_currentLevel.itemRecords[j] |= SFG_ITEM_RECORD_ACTIVE_MASK; - /* ^ we have to make the new teleporter immediately active so - that it will immediately collide */ - - SFG_player.justTeleported = 1; - - SFG_playGameSound(4,255); - SFG_processEvent(SFG_EVENT_PLAYER_TELEPORTS,0); - - break; - } - } - } - } - } - } // item collision check - - if (!collidesWithTeleporter) - SFG_player.justTeleported = 0; - -#if SFG_PREVIEW_MODE - SFG_player.camera.position.x += - SFG_PREVIEW_MODE_SPEED_MULTIPLIER * moveOffset.x; - - SFG_player.camera.position.y += - SFG_PREVIEW_MODE_SPEED_MULTIPLIER * moveOffset.y; - - SFG_player.camera.height += - SFG_PREVIEW_MODE_SPEED_MULTIPLIER * SFG_player.verticalSpeed; -#else - RCL_moveCameraWithCollision(&(SFG_player.camera),moveOffset, - verticalOffset,SFG_floorCollisionHeightAt,SFG_ceilingHeightAt,1,1); - - SFG_player.previousVerticalSpeed = SFG_player.verticalSpeed; - - RCL_Unit limit = RCL_max(RCL_max(0,verticalOffset),SFG_player.verticalSpeed); - - SFG_player.verticalSpeed = - RCL_min(limit,SFG_player.camera.height - previousHeight); - /* ^ By "limit" we assure height increase caused by climbing a step doesn't - add vertical velocity. */ -#endif - -#if SFG_PREVIEW_MODE == 0 - if ( - SFG_keyIsDown(SFG_KEY_A) && - !SFG_keyIsDown(SFG_KEY_C) && - (SFG_player.weaponCooldownFrames == 0)) - { - /* Player attack/shoot/fire, this has to be done AFTER the player is moved, - otherwise he could shoot himself while running forward. */ - - uint8_t ammo, projectileCount, canShoot; - - SFG_getPlayerWeaponInfo(&ammo,&projectileCount,&canShoot); - - if (canShoot) - { - uint8_t sound; - - switch (SFG_player.weapon) - { - case SFG_WEAPON_KNIFE: sound = 255; break; - case SFG_WEAPON_ROCKET_LAUNCHER: - case SFG_WEAPON_SHOTGUN: sound = 2; break; - case SFG_WEAPON_PLASMAGUN: - case SFG_WEAPON_SOLUTION: sound = 4; break; - default: sound = 0; break; - } - - if (sound != 255) - SFG_playGameSound(sound,255); - - if (ammo != SFG_AMMO_NONE) - SFG_player.ammo[ammo] -= projectileCount; - - uint8_t projectile; - - switch (SFG_GET_WEAPON_FIRE_TYPE(SFG_player.weapon)) - { - case SFG_WEAPON_FIRE_TYPE_PLASMA: - projectile = SFG_PROJECTILE_PLASMA; - break; - - case SFG_WEAPON_FIRE_TYPE_FIREBALL: - projectile = SFG_PROJECTILE_FIREBALL; - break; - - case SFG_WEAPON_FIRE_TYPE_BULLET: - projectile = SFG_PROJECTILE_BULLET; - break; - - case SFG_WEAPON_FIRE_TYPE_MELEE: - projectile = SFG_PROJECTILE_NONE; - break; - - default: - projectile = 255; - break; - } - - if (projectile != SFG_PROJECTILE_NONE) - { - uint16_t angleAdd = SFG_PROJECTILE_SPREAD_ANGLE / (projectileCount + 1); - - RCL_Unit direction = - (SFG_player.camera.direction - SFG_PROJECTILE_SPREAD_ANGLE / 2) - + angleAdd; - - RCL_Unit projectileSpeed = SFG_GET_PROJECTILE_SPEED_UPS(projectile); - - /* Vertical speed will be either determined by autoaim (if shearing is - off) or the camera shear value. */ - RCL_Unit verticalSpeed = (SFG_game.settings & 0x04) ? - (SFG_player.camera.shear * projectileSpeed * 2) / // only approximate - SFG_CAMERA_MAX_SHEAR_PIXELS - : - (projectileSpeed * SFG_autoaimVertically()) / RCL_UNITS_PER_SQUARE; - - for (uint8_t i = 0; i < projectileCount; ++i) - { - SFG_launchProjectile( - projectile, - SFG_player.camera.position, - SFG_player.camera.height, - RCL_angleToDirection(direction), - verticalSpeed, - SFG_PROJECTILE_SPAWN_OFFSET - ); - - direction += angleAdd; - } - } - else - { - // player's melee attack - - for (uint16_t i = 0; i < SFG_currentLevel.monsterRecordCount; ++i) - { - SFG_MonsterRecord *m = &(SFG_currentLevel.monsterRecords[i]); - - uint8_t state = SFG_MR_STATE(*m); - - if ((state == SFG_MONSTER_STATE_INACTIVE) || - (state == SFG_MONSTER_STATE_DEAD)) - continue; - - RCL_Unit pX, pY, pZ; - SFG_getMonsterWorldPosition(m,&pX,&pY,&pZ); - - if (SFG_taxicabDistance(pX,pY,pZ, - SFG_player.camera.position.x, - SFG_player.camera.position.y, - SFG_player.camera.height) > SFG_MELEE_RANGE) - continue; - - RCL_Vector2D toMonster; - - toMonster.x = pX - SFG_player.camera.position.x; - toMonster.y = pY - SFG_player.camera.position.y; - - if (RCL_vectorsAngleCos(SFG_player.direction,toMonster) >= - (RCL_UNITS_PER_SQUARE - SFG_PLAYER_MELEE_ANGLE)) - { - SFG_monsterChangeHealth(m, - -1 * SFG_getDamageValue(SFG_WEAPON_FIRE_TYPE_MELEE)); - - SFG_createDust(pX,pY,pZ); - - break; - } - } - } - - SFG_player.weaponCooldownFrames = - RCL_max( - SFG_GET_WEAPON_FIRE_COOLDOWN_FRAMES(SFG_player.weapon), - SFG_MIN_WEAPON_COOLDOWN_FRAMES); - - SFG_getPlayerWeaponInfo(&ammo,&projectileCount,&canShoot); - - if (!canShoot) - { - // No more ammo, switch to the second strongest weapon. - - SFG_playerRotateWeapon(1); - - uint8_t previousWeapon = SFG_player.weapon; - - SFG_playerRotateWeapon(0); - - if (previousWeapon > SFG_player.weapon) - SFG_playerRotateWeapon(1); - } - } // endif: has enough ammo? - } // attack -#endif // SFG_PREVIEW_MODE == 0 - - SFG_player.squarePosition[0] = - SFG_player.camera.position.x / RCL_UNITS_PER_SQUARE; - - SFG_player.squarePosition[1] = - SFG_player.camera.position.y / RCL_UNITS_PER_SQUARE; - - SFG_currentLevel.mapRevealMask |= - SFG_getMapRevealBit( - SFG_player.squarePosition[0], - SFG_player.squarePosition[1]); - - uint8_t properties; - - SFG_getMapTile(SFG_currentLevel.levelPointer,SFG_player.squarePosition[0], - SFG_player.squarePosition[1],&properties); - - if ( // squeezer check - (properties == SFG_TILE_PROPERTY_SQUEEZER) && - ((SFG_ceilingHeightAt( - SFG_player.squarePosition[0],SFG_player.squarePosition[1]) - - SFG_floorHeightAt( - SFG_player.squarePosition[0],SFG_player.squarePosition[1])) - < - (RCL_CAMERA_COLL_HEIGHT_ABOVE + RCL_CAMERA_COLL_HEIGHT_BELOW))) - { - SFG_LOG("player is squeezed"); - SFG_player.health = 0; - } - - if (SFG_player.weapon != currentWeapon) // if weapon switched, start cooldown - { - - if (SFG_player.weapon == (currentWeapon + 1) % SFG_WEAPONS_TOTAL) - SFG_player.previousWeaponDirection = -1; - else if (currentWeapon == (SFG_player.weapon + 1) % SFG_WEAPONS_TOTAL) - SFG_player.previousWeaponDirection = 1; - else - SFG_player.previousWeaponDirection = 0; - - SFG_player.weaponCooldownFrames = - SFG_GET_WEAPON_FIRE_COOLDOWN_FRAMES(SFG_player.weapon) / 2; - } - -#if SFG_IMMORTAL == 0 - if (SFG_player.health == 0) - { - SFG_LOG("player dies"); - SFG_levelEnds(); - SFG_processEvent(SFG_EVENT_VIBRATE,0); - SFG_processEvent(SFG_EVENT_PLAYER_DIES,0); - SFG_setGameState(SFG_GAME_STATE_LOSE); - } -#endif -} - -/** - This function defines which items are displayed in the menu. -*/ -uint8_t SFG_getMenuItem(uint8_t index) -{ - uint8_t current = 0; - - while (1) // find first legitimate item - { - if ( // skip non-legitimate items - ((current <= SFG_MENU_ITEM_MAP) && (SFG_currentLevel.levelPointer == 0)) - || ((current == SFG_MENU_ITEM_LOAD) && ((SFG_game.save[0] >> 4) == 0x0f))) - { - current++; - continue; - } - - if (index == 0) - return (current <= (SFG_MENU_ITEM_EXIT - (SFG_CAN_EXIT ? 0 : 1)) - ) ? current : SFG_MENU_ITEM_NONE; - - current++; - index--; - } - - return SFG_MENU_ITEM_NONE; -} - -void SFG_gameStepMenu() -{ - uint8_t menuItems = 0; - - while (SFG_getMenuItem(menuItems) != SFG_MENU_ITEM_NONE) - menuItems++; - - uint8_t item = SFG_getMenuItem(SFG_game.selectedMenuItem); - - if (SFG_keyRegisters(SFG_KEY_DOWN) && - (SFG_game.selectedMenuItem < menuItems - 1)) - { - SFG_game.selectedMenuItem++; - SFG_playGameSound(3,SFG_MENU_CLICK_VOLUME); - } - else if (SFG_keyRegisters(SFG_KEY_UP) && (SFG_game.selectedMenuItem > 0)) - { - SFG_game.selectedMenuItem--; - SFG_playGameSound(3,SFG_MENU_CLICK_VOLUME); - } - else if (SFG_keyJustPressed(SFG_KEY_A)) - { - switch (item) - { - case SFG_MENU_ITEM_PLAY: - for (uint8_t i = 6; i < SFG_SAVE_SIZE; ++i) // reset totals in save - SFG_game.save[i] = 0; - - if (SFG_game.selectedLevel == 0) - { - SFG_currentLevel.levelNumber = 0; // to draw intro, not outro - SFG_setGameState(SFG_GAME_STATE_INTRO); - } - else - SFG_setAndInitLevel(SFG_game.selectedLevel); - - break; - - case SFG_MENU_ITEM_LOAD: - { - SFG_gameLoad(); - - uint8_t saveBackup[SFG_SAVE_SIZE]; - - for (uint8_t i = 0; i < SFG_SAVE_SIZE; ++i) - saveBackup[i] = SFG_game.save[i]; - - SFG_setAndInitLevel(SFG_game.save[0] >> 4); - - for (uint8_t i = 0; i < SFG_SAVE_SIZE; ++i) - SFG_game.save[i] = saveBackup[i]; - - SFG_player.health = SFG_game.save[2]; - SFG_player.ammo[0] = SFG_game.save[3]; - SFG_player.ammo[1] = SFG_game.save[4]; - SFG_player.ammo[2] = SFG_game.save[5]; - - SFG_playerRotateWeapon(1); // this chooses weapon with ammo available - break; - } - - case SFG_MENU_ITEM_CONTINUE: - SFG_setGameState(SFG_GAME_STATE_PLAYING); - break; - - case SFG_MENU_ITEM_MAP: - SFG_setGameState(SFG_GAME_STATE_MAP); - break; - - case SFG_MENU_ITEM_SOUND: - SFG_LOG("sound changed"); - - SFG_game.settings = - (SFG_game.settings & ~0x03) | ((SFG_game.settings + 1) & 0x03); - - SFG_playGameSound(3,SFG_MENU_CLICK_VOLUME); - - if ((SFG_game.settings & 0x02) != - ((SFG_game.settings - 1) & 0x02)) - SFG_setMusic((SFG_game.settings & 0x02) ? - SFG_MUSIC_TURN_ON : SFG_MUSIC_TURN_OFF); - - SFG_game.save[1] = SFG_game.settings; - SFG_gameSave(); - - break; - - case SFG_MENU_ITEM_SHEAR: - { - uint8_t current = (SFG_game.settings >> 2) & 0x03; - - current++; - - if (current == 2) // option that doesn't make sense, skip - current++; - - SFG_game.settings = - (SFG_game.settings & ~0x0c) | ((current & 0x03) << 2); - - SFG_game.save[1] = SFG_game.settings; - SFG_gameSave(); - - break; - } - - case SFG_MENU_ITEM_EXIT: - SFG_game.continues = 0; - break; - - default: - break; - } - } - else if (item == SFG_MENU_ITEM_PLAY) - { - if (SFG_keyRegisters(SFG_KEY_RIGHT) && - (SFG_game.selectedLevel < (SFG_game.save[0] & 0x0f))) - { - SFG_game.selectedLevel++; - SFG_playGameSound(3,SFG_MENU_CLICK_VOLUME); - } - else if (SFG_keyRegisters(SFG_KEY_LEFT) && SFG_game.selectedLevel > 0) - { - SFG_game.selectedLevel--; - SFG_playGameSound(3,SFG_MENU_CLICK_VOLUME); - } - } -} - -/** - Performs one game step (logic, physics, menu, ...), happening SFG_MS_PER_FRAME - after the previous step. -*/ -void SFG_gameStep() -{ - SFG_GAME_STEP_COMMAND - - SFG_game.soundsPlayedThisFrame = 0; - - SFG_game.blink = (SFG_game.frame / SFG_BLINK_PERIOD_FRAMES) % 2; - - for (uint8_t i = 0; i < SFG_KEY_COUNT; ++i) - if (!SFG_keyPressed(i)) - SFG_game.keyStates[i] = 0; - else if (SFG_game.keyStates[i] < 255) - SFG_game.keyStates[i]++; - - if ((SFG_currentLevel.frameStart - SFG_game.frame) % - SFG_SPRITE_ANIMATION_FRAME_DURATION == 0) - SFG_game.spriteAnimationFrame++; - - switch (SFG_game.state) - { - case SFG_GAME_STATE_PLAYING: - SFG_gameStepPlaying(); - break; - - case SFG_GAME_STATE_MENU: - SFG_gameStepMenu(); - break; - - case SFG_GAME_STATE_LOSE: - { - // player die animation (lose) - - SFG_updateLevel(); // let monsters and other things continue moving - SFG_updatePlayerHeight(); // in case player is on elevator - - int32_t t = SFG_game.frameTime - SFG_game.stateChangeTime; - - RCL_Unit h = SFG_floorHeightAt(SFG_player.squarePosition[0], - SFG_player.squarePosition[1]); - - SFG_player.camera.height = - RCL_max(h,h + ((SFG_LOSE_ANIMATION_DURATION - t) * - RCL_CAMERA_COLL_HEIGHT_BELOW) / SFG_LOSE_ANIMATION_DURATION); - - SFG_player.camera.shear = - RCL_min(SFG_CAMERA_MAX_SHEAR_PIXELS / 4, - (t * (SFG_CAMERA_MAX_SHEAR_PIXELS / 4)) / SFG_LOSE_ANIMATION_DURATION); - - if (t > SFG_LOSE_ANIMATION_DURATION && - (SFG_keyIsDown(SFG_KEY_A) || SFG_keyIsDown(SFG_KEY_B))) - { - for (uint8_t i = 6; i < SFG_SAVE_SIZE; ++i) - SFG_game.save[i] = 0; - - SFG_setAndInitLevel(SFG_currentLevel.levelNumber); - } - - break; - } - - case SFG_GAME_STATE_WIN: - { - // win animation - - SFG_updateLevel(); - - int32_t t = SFG_game.frameTime - SFG_game.stateChangeTime; - - if (t > SFG_WIN_ANIMATION_DURATION) - { - if (SFG_currentLevel.levelNumber == (SFG_NUMBER_OF_LEVELS - 1)) - { - if (SFG_keyIsDown(SFG_KEY_A)) - SFG_setGameState(SFG_GAME_STATE_OUTRO); - } - else if (SFG_keyIsDown(SFG_KEY_RIGHT) || - SFG_keyIsDown(SFG_KEY_LEFT)) - { - SFG_setAndInitLevel(SFG_currentLevel.levelNumber + 1); - - SFG_player.health = SFG_game.save[2]; - SFG_player.ammo[0] = SFG_game.save[3]; - SFG_player.ammo[1] = SFG_game.save[4]; - SFG_player.ammo[2] = SFG_game.save[5]; - - if (SFG_keyIsDown(SFG_KEY_RIGHT) && SFG_game.saved != SFG_CANT_SAVE) - { - // save the current position - SFG_gameSave(); - SFG_game.saved = 1; - } - } - } - - break; - } - - case SFG_GAME_STATE_MAP: - if (SFG_keyIsDown(SFG_KEY_B)) - SFG_setGameState(SFG_GAME_STATE_MENU); - - break; - - case SFG_GAME_STATE_INTRO: - if (SFG_keyJustPressed(SFG_KEY_A) || SFG_keyJustPressed(SFG_KEY_B)) - SFG_setAndInitLevel(0); - - break; - - case SFG_GAME_STATE_OUTRO: - if (((SFG_game.frameTime - SFG_game.stateChangeTime) > - SFG_STORYTEXT_DURATION) && (SFG_keyIsDown(SFG_KEY_A) || - SFG_keyIsDown(SFG_KEY_B))) - { - SFG_setGameState(SFG_GAME_STATE_MENU); - SFG_playGameSound(3,SFG_MENU_CLICK_VOLUME); - } - - break; - - case SFG_GAME_STATE_LEVEL_START: - { - SFG_updateLevel(); - SFG_updatePlayerHeight(); // in case player is on elevator - - if (SFG_currentLevel.levelNumber > (SFG_game.save[0] & 0x0f)) - { - SFG_game.save[0] = // save progress - (SFG_game.save[0] & 0xf0) | SFG_currentLevel.levelNumber; - SFG_gameSave(); - } - - int16_t x = 0, y = 0; - - SFG_getMouseOffset(&x,&y); // this keeps centering the mouse - - if ((SFG_game.frameTime - SFG_game.stateChangeTime) >= - SFG_LEVEL_START_DURATION) - SFG_setGameState(SFG_GAME_STATE_PLAYING); - - break; - } - - default: - break; - } -} - -void SFG_fillRectangle( - uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t color) -{ - if ((x + width > SFG_GAME_RESOLUTION_X) || - (y + height > SFG_GAME_RESOLUTION_Y)) - return; - - for (uint16_t j = y; j < y + height; ++j) - for (uint16_t i = x; i < x + width; ++i) - SFG_setGamePixel(i,j,color); -} - -static inline void SFG_clearScreen(uint8_t color) -{ - SFG_fillRectangle(0,0,SFG_GAME_RESOLUTION_X, - SFG_GAME_RESOLUTION_Y,color); -} - -/** - Draws fullscreen map of the current level. -*/ -void SFG_drawMap() -{ - SFG_clearScreen(0); - - uint16_t maxJ = - (SFG_MAP_PIXEL_SIZE * SFG_MAP_SIZE) < SFG_GAME_RESOLUTION_Y ? - (SFG_MAP_SIZE) : (SFG_GAME_RESOLUTION_Y / SFG_MAP_PIXEL_SIZE); - - uint16_t maxI = - (SFG_MAP_PIXEL_SIZE * SFG_MAP_SIZE) < SFG_GAME_RESOLUTION_X ? - (SFG_MAP_SIZE) : (SFG_GAME_RESOLUTION_X / SFG_MAP_PIXEL_SIZE); - - uint16_t topLeftX = - (SFG_GAME_RESOLUTION_X - (maxI * SFG_MAP_PIXEL_SIZE)) / 2; - - uint16_t topLeftY = - (SFG_GAME_RESOLUTION_Y - (maxJ * SFG_MAP_PIXEL_SIZE)) / 2; - - uint16_t x; - uint16_t y = topLeftY; - - uint8_t playerColor = - SFG_game.blink ? SFG_MAP_PLAYER_COLOR1 : SFG_MAP_PLAYER_COLOR2; - - for (int16_t j = 0; j < maxJ; ++j) - { - x = topLeftX; - - for (int16_t i = maxI - 1; i >= 0; --i) - { - uint8_t color = 0; // init with non-revealed color - - if (SFG_currentLevel.mapRevealMask & SFG_getMapRevealBit(i,j)) - { - uint8_t properties; - - SFG_TileDefinition tile = - SFG_getMapTile(SFG_currentLevel.levelPointer,i,j,&properties); - - color = playerColor; // start with player color - - if (i != SFG_player.squarePosition[0] || - j != SFG_player.squarePosition[1]) - { - if (properties == SFG_TILE_PROPERTY_ELEVATOR) - color = SFG_MAP_ELEVATOR_COLOR; - else if (properties == SFG_TILE_PROPERTY_SQUEEZER) - color = SFG_MAP_SQUEEZER_COLOR; - else if (properties == SFG_TILE_PROPERTY_DOOR) - color = SFG_MAP_DOOR_COLOR; - else - { - color = 0; - - uint8_t c = SFG_TILE_CEILING_HEIGHT(tile) / 4; - - if (c != 0) - color = (SFG_TILE_FLOOR_HEIGHT(tile) % 8 + 3) * 8 + c - 1; - } - } - } - - for (int_fast16_t k = 0; k < SFG_MAP_PIXEL_SIZE; ++k) - for (int_fast16_t l = 0; l < SFG_MAP_PIXEL_SIZE; ++l) - SFG_setGamePixel(x + l, y + k,color); - - x += SFG_MAP_PIXEL_SIZE; - } - - y += SFG_MAP_PIXEL_SIZE; - } -} - -/** - Draws fullscreen story text (intro/outro). -*/ -void SFG_drawStoryText() -{ - const char *text = SFG_outroText; - uint16_t textColor = 23; - uint8_t clearColor = 9; - uint8_t sprite = 18; - - if (SFG_currentLevel.levelNumber != (SFG_NUMBER_OF_LEVELS - 1)) // intro? - { - text = SFG_introText; - textColor = 7; - clearColor = 0; - sprite = SFG_game.blink * 2; - } - - SFG_clearScreen(clearColor); - - if (SFG_GAME_RESOLUTION_Y > 50) - SFG_blitImage(SFG_monsterSprites + sprite * SFG_TEXTURE_STORE_SIZE, - (SFG_GAME_RESOLUTION_X - SFG_TEXTURE_SIZE * SFG_FONT_SIZE_SMALL) / 2, - SFG_GAME_RESOLUTION_Y - (SFG_TEXTURE_SIZE + 3) * SFG_FONT_SIZE_SMALL, - SFG_FONT_SIZE_SMALL); - - uint16_t textLen = 0; - - while (text[textLen] != 0) - textLen++; - - uint16_t drawLen = - RCL_min(textLen, - ((SFG_game.frameTime - SFG_game.stateChangeTime) * textLen) / - SFG_STORYTEXT_DURATION + 1); - -#define CHAR_SIZE (SFG_FONT_SIZE_SMALL * (SFG_FONT_CHARACTER_SIZE + 1)) -#define LINE_LENGTH (SFG_GAME_RESOLUTION_X / CHAR_SIZE) -#define MAX_LENGTH (((SFG_GAME_RESOLUTION_Y / CHAR_SIZE) / 2) * LINE_LENGTH ) - - uint16_t drawShift = (drawLen < MAX_LENGTH) ? 0 : - (((drawLen - MAX_LENGTH) / LINE_LENGTH) * LINE_LENGTH); - -#undef CHAR_SIZE -#undef LINE_LENGTH -#undef MAX_LENGTH - - text += drawShift; - drawLen -= drawShift; - - SFG_drawText(text,SFG_HUD_MARGIN,SFG_HUD_MARGIN,SFG_FONT_SIZE_SMALL,textColor, - drawLen,SFG_GAME_RESOLUTION_X - SFG_HUD_MARGIN); -} - -/** - Draws a number as text on screen, returns the number of characters drawn. -*/ -uint8_t SFG_drawNumber( - int16_t number, - uint16_t x, - uint16_t y, - uint8_t size, - uint8_t color) -{ - char text[7]; - - text[6] = 0; // terminate the string - - int8_t positive = 1; - - if (number < 0) - { - positive = 0; - number *= -1; - } - - int8_t position = 5; - - while (1) - { - text[position] = '0' + number % 10; - number /= 10; - - position--; - - if (number == 0 || position == 0) - break; - } - - if (!positive) - { - text[position] = '-'; - position--; - } - - SFG_drawText(text + position + 1,x,y,size,color,0,0); - - return 5 - position; -} - -/** - Draws a screen border that indicates something is happening, e.g. being hurt - or taking an item. -*/ -void SFG_drawIndicationBorder(uint16_t width, uint8_t color) -{ - for (int_fast16_t j = 0; j < width; ++j) - { - uint16_t j2 = SFG_GAME_RESOLUTION_Y - 1 - j; - - for (int_fast16_t i = 0; i < SFG_GAME_RESOLUTION_X; ++i) - { - if ((i & 0x01) == (j & 0x01)) - { - SFG_setGamePixel(i,j,color); - SFG_setGamePixel(i,j2,color); - } - } - } - - for (int_fast16_t i = 0; i < width; ++i) - { - uint16_t i2 = SFG_GAME_RESOLUTION_X - 1 - i; - - for (int_fast16_t j = width; j < SFG_GAME_RESOLUTION_Y - width; ++j) - { - if ((i & 0x01) == (j & 0x01)) - { - SFG_setGamePixel(i,j,color); - SFG_setGamePixel(i2,j,color); - } - } - } -} - -/** - Draws the player weapon, includes handling the shoot animation. -*/ -void SFG_drawWeapon(int16_t bobOffset) -{ - uint32_t animationLength = - RCL_max(SFG_MIN_WEAPON_COOLDOWN_FRAMES, - SFG_GET_WEAPON_FIRE_COOLDOWN_FRAMES(SFG_player.weapon)); - - uint32_t shotAnimationFrame = - animationLength - SFG_player.weaponCooldownFrames; - - bobOffset -= SFG_HUD_BAR_HEIGHT; - - uint8_t fireType = SFG_GET_WEAPON_FIRE_TYPE(SFG_player.weapon); - - if (shotAnimationFrame < animationLength) - { - if (fireType == SFG_WEAPON_FIRE_TYPE_MELEE) - { - bobOffset = shotAnimationFrame < animationLength / 2 ? 0 : - 2 * SFG_WEAPONBOB_OFFSET_PIXELS ; - } - else - { - bobOffset += - ((animationLength - shotAnimationFrame) * SFG_WEAPON_IMAGE_SCALE * 20) - / animationLength; - - if ( - ((fireType == SFG_WEAPON_FIRE_TYPE_FIREBALL) || - (fireType == SFG_WEAPON_FIRE_TYPE_BULLET)) && - shotAnimationFrame < animationLength / 2) - SFG_blitImage(SFG_effectSprites, - SFG_WEAPON_IMAGE_POSITION_X, - SFG_WEAPON_IMAGE_POSITION_Y - - (SFG_TEXTURE_SIZE / 3) * SFG_WEAPON_IMAGE_SCALE + bobOffset, - SFG_WEAPON_IMAGE_SCALE); - } - } - - SFG_blitImage(SFG_weaponImages + SFG_player.weapon * SFG_TEXTURE_STORE_SIZE, - SFG_WEAPON_IMAGE_POSITION_X, - SFG_WEAPON_IMAGE_POSITION_Y + bobOffset - 1, - SFG_WEAPON_IMAGE_SCALE); -} - -uint16_t SFG_textLen(const char *text) -{ - uint16_t result = 0; - - while (text[result] != 0) - result++; - - return result; -} - -static inline uint16_t SFG_characterSize(uint8_t textSize) -{ - return (SFG_FONT_CHARACTER_SIZE + 1) * textSize; -} - -static inline uint16_t - SFG_textHorizontalSize(const char *text, uint8_t textSize) -{ - return (SFG_textLen(text) * SFG_characterSize(textSize)); -} - -void SFG_drawMenu() -{ - #define BACKGROUND_SCALE (SFG_GAME_RESOLUTION_X / (4 * SFG_TEXTURE_SIZE ) ) - - #if BACKGROUND_SCALE == 0 - #undef BACKGROUND_SCALE - #define BACKGROUND_SCALE 1 - #endif - - #define SCROLL_PIXELS_PER_FRAME ((64 * SFG_GAME_RESOLUTION_X) / (8 * SFG_FPS)) - - #if SCROLL_PIXELS_PER_FRAME == 0 - #undef SCROLL_PIXELS_PER_FRAME - #define SCROLL_PIXELS_PER_FRAME 1 - #endif - - #define SELECTION_START_X ((SFG_GAME_RESOLUTION_X - 12 * SFG_FONT_SIZE_MEDIUM\ - * (SFG_FONT_CHARACTER_SIZE + 1)) / 2) - - uint16_t scroll = (SFG_game.frame * SCROLL_PIXELS_PER_FRAME) / 64; - - for (uint16_t y = 0; y < SFG_GAME_RESOLUTION_Y; ++y) - for (uint16_t x = 0; x < SFG_GAME_RESOLUTION_X; ++x) - SFG_setGamePixel(x,y, - (y >= (SFG_TEXTURE_SIZE * BACKGROUND_SCALE)) ? 0 : - SFG_getTexel(SFG_backgroundImages,((x + scroll) / BACKGROUND_SCALE) - % SFG_TEXTURE_SIZE,y / BACKGROUND_SCALE)); - - uint16_t y = SFG_characterSize(SFG_FONT_SIZE_MEDIUM); - - SFG_blitImage(SFG_logoImage, - SFG_GAME_RESOLUTION_X / 2 - 16 * SFG_FONT_SIZE_MEDIUM,y, - SFG_FONT_SIZE_MEDIUM); - -#if SFG_GAME_RESOLUTION_Y > 50 - y += 32 * SFG_FONT_SIZE_MEDIUM + SFG_characterSize(SFG_FONT_SIZE_MEDIUM); -#else - y = 2; -#endif - - uint8_t i = 0; - - while (1) // draw menu items - { - uint8_t item = SFG_getMenuItem(i); - - if (item == SFG_MENU_ITEM_NONE) - break; - -#if SFG_GAME_RESOLUTION_Y < 70 - // with low resolution only display the selected item - - if (i != SFG_game.selectedMenuItem) - { - i++; - continue; - } -#endif - - const char *text = SFG_menuItemTexts[item]; - uint8_t textLen = SFG_textLen(text); - - uint16_t drawX = (SFG_GAME_RESOLUTION_X - - SFG_textHorizontalSize(text,SFG_FONT_SIZE_MEDIUM)) / 2; - - uint8_t textColor = 7; - - if (i != SFG_game.selectedMenuItem) - textColor = 23; - else - SFG_fillRectangle( // menu item highlight - SELECTION_START_X, - y - SFG_FONT_SIZE_MEDIUM, - SFG_GAME_RESOLUTION_X - SELECTION_START_X * 2, - SFG_characterSize(SFG_FONT_SIZE_MEDIUM),2); - - SFG_drawText(text,drawX,y,SFG_FONT_SIZE_MEDIUM,textColor,0,0); - - if ((item == SFG_MENU_ITEM_PLAY || item == SFG_MENU_ITEM_SOUND - || item == SFG_MENU_ITEM_SHEAR) && - ((i != SFG_game.selectedMenuItem) || SFG_game.blink)) - { - uint32_t x = - drawX + SFG_characterSize(SFG_FONT_SIZE_MEDIUM) * (textLen + 1); - - uint8_t c = 93; - - if (item == SFG_MENU_ITEM_PLAY) - SFG_drawNumber(SFG_game.selectedLevel + 1,x,y,SFG_FONT_SIZE_MEDIUM,c); - else if (item == SFG_MENU_ITEM_SHEAR) - { - uint8_t n = (SFG_game.settings >> 2) & 0x03; - - SFG_drawNumber(n == 3 ? 2 : n,x,y,SFG_FONT_SIZE_MEDIUM,c); - } - else - { - char settingText[3] = " "; - - settingText[0] = (SFG_game.settings & 0x01) ? 'S' : ' '; - settingText[1] = (SFG_game.settings & 0x02) ? 'M' : ' '; - - SFG_drawText(settingText,x,y,SFG_FONT_SIZE_MEDIUM,c,0,0); - } - } - - y += SFG_characterSize(SFG_FONT_SIZE_MEDIUM) + SFG_FONT_SIZE_MEDIUM; - i++; - } - - SFG_drawText(SFG_VERSION_STRING " CC0",SFG_HUD_MARGIN,SFG_GAME_RESOLUTION_Y - - SFG_HUD_MARGIN - SFG_FONT_SIZE_SMALL * SFG_FONT_CHARACTER_SIZE, - SFG_FONT_SIZE_SMALL,4,0,0); - - #if SFG_OS_IS_MALWARE - if (SFG_game.blink) - SFG_drawText(SFG_MALWARE_WARNING,SFG_HUD_MARGIN,SFG_HUD_MARGIN, - SFG_FONT_SIZE_MEDIUM,95,0,0); - #endif - - #undef MAX_ITEMS - #undef BACKGROUND_SCALE - #undef SCROLL_PIXELS_PER_FRAME -} - -void SFG_drawWinOverlay() -{ - uint32_t t = RCL_min(SFG_WIN_ANIMATION_DURATION, - SFG_game.frameTime - SFG_game.stateChangeTime); - - uint32_t t2 = RCL_min(t,SFG_WIN_ANIMATION_DURATION / 4); - - #define STRIP_HEIGHT (SFG_GAME_RESOLUTION_Y / 2) - #define INNER_STRIP_HEIGHT ((STRIP_HEIGHT * 3) / 4) - #define STRIP_START ((SFG_GAME_RESOLUTION_Y - STRIP_HEIGHT) / 2) - - RCL_Unit l = (t2 * STRIP_HEIGHT * 4) / SFG_WIN_ANIMATION_DURATION; - - for (uint16_t y = STRIP_START; y < STRIP_START + l; ++y) - for (uint16_t x = 0; x < SFG_GAME_RESOLUTION_X; ++x) - SFG_setGamePixel(x,y, - RCL_abs(y - (SFG_GAME_RESOLUTION_Y / 2)) <= (INNER_STRIP_HEIGHT / 2) ? - 0 : 172); - - char textLine[] = "level done"; - - uint16_t y = SFG_GAME_RESOLUTION_Y / 2 - - ((STRIP_HEIGHT + INNER_STRIP_HEIGHT) / 2) / 2; - - uint16_t x = (SFG_GAME_RESOLUTION_X - - SFG_textHorizontalSize(textLine,SFG_FONT_SIZE_BIG)) / 2; - - SFG_drawText(textLine,x,y,SFG_FONT_SIZE_BIG,7 + SFG_game.blink * 95,255,0); - - uint32_t timeTotal = SFG_SAVE_TOTAL_TIME; - - // don't show totals in level 1: - uint8_t blink = (SFG_game.blink) && (SFG_currentLevel.levelNumber != 0) - && (timeTotal != 0); - - if (t >= (SFG_WIN_ANIMATION_DURATION / 2)) - { - y += (SFG_FONT_SIZE_BIG + SFG_FONT_SIZE_MEDIUM) * SFG_FONT_CHARACTER_SIZE; - x = SFG_HUD_MARGIN; - - #define CHAR_SIZE (SFG_FONT_SIZE_SMALL * SFG_FONT_CHARACTER_SIZE) - - uint32_t time = blink ? timeTotal : SFG_currentLevel.completionTime10sOfS; - - x += SFG_drawNumber(time / 10,x,y,SFG_FONT_SIZE_SMALL,7) * - CHAR_SIZE + SFG_FONT_SIZE_SMALL; - - char timeRest[5] = ".X s"; - - timeRest[1] = '0' + (time % 10); - - SFG_drawText(timeRest,x,y,SFG_FONT_SIZE_SMALL,7,4,0); - - x = SFG_HUD_MARGIN; - y += (SFG_FONT_SIZE_BIG + SFG_FONT_SIZE_MEDIUM) * SFG_FONT_CHARACTER_SIZE; - - if (blink) - { - x += (SFG_drawNumber(SFG_game.save[10] + SFG_game.save[11] * 256,x,y, - SFG_FONT_SIZE_SMALL,7) + 1) * CHAR_SIZE; - } - else - { - x += SFG_drawNumber(SFG_currentLevel.monstersDead,x,y, - SFG_FONT_SIZE_SMALL,7) * CHAR_SIZE; - - SFG_drawText("/",x,y,SFG_FONT_SIZE_SMALL,7,1,0); - - x += CHAR_SIZE; - - x += (SFG_drawNumber(SFG_currentLevel.monsterRecordCount,x,y, - SFG_FONT_SIZE_SMALL,7) + 1) * CHAR_SIZE; - } - - SFG_drawText(SFG_TEXT_KILLS,x,y,SFG_FONT_SIZE_SMALL,7,255,0); - - if ((t >= (SFG_WIN_ANIMATION_DURATION - 1)) && - (SFG_currentLevel.levelNumber != (SFG_NUMBER_OF_LEVELS - 1))) - { - y += (SFG_FONT_SIZE_BIG + SFG_FONT_SIZE_MEDIUM) * SFG_FONT_CHARACTER_SIZE; - - SFG_drawText(SFG_TEXT_SAVE_PROMPT, - (SFG_GAME_RESOLUTION_X - SFG_textHorizontalSize(SFG_TEXT_SAVE_PROMPT, - SFG_FONT_SIZE_MEDIUM)) / 2,y,SFG_FONT_SIZE_MEDIUM,7,255,0); - } - - #undef CHAR_SIZE - } - - #undef STRIP_HEIGHT - #undef STRIP_START - #undef INNER_STRIP_HEIGHT -} - -void SFG_draw() -{ -#if SFG_BACKGROUND_BLUR != 0 - SFG_backgroundBlurIndex = 0; -#endif - - if (SFG_game.state == SFG_GAME_STATE_MENU) - { - SFG_drawMenu(); - return; - } - - if (SFG_game.state == SFG_GAME_STATE_INTRO || - SFG_game.state == SFG_GAME_STATE_OUTRO) - { - SFG_drawStoryText(); - return; - } - - if (SFG_keyIsDown(SFG_KEY_MAP) || (SFG_game.state == SFG_GAME_STATE_MAP)) - { - SFG_drawMap(); - } - else - { - for (int_fast16_t i = 0; i < SFG_Z_BUFFER_SIZE; ++i) - SFG_game.zBuffer[i] = 255; - - int16_t weaponBobOffset = 0; - -#if SFG_HEADBOB_ENABLED - RCL_Unit headBobOffset = 0; - -#if SFG_HEADBOB_SHEAR != 0 - int16_t headBobShearOffset = 0; -#endif - - if (SFG_game.state != SFG_GAME_STATE_LOSE) - { - RCL_Unit bobSin = RCL_sin(SFG_player.headBobFrame); - - headBobOffset = (bobSin * SFG_HEADBOB_OFFSET) / RCL_UNITS_PER_SQUARE; - -#if SFG_HEADBOB_SHEAR != 0 - headBobShearOffset = (bobSin * SFG_HEADBOB_SHEAR) / RCL_UNITS_PER_SQUARE; - SFG_player.camera.shear += headBobShearOffset; -#endif - - weaponBobOffset = - (bobSin * SFG_WEAPONBOB_OFFSET_PIXELS) / (RCL_UNITS_PER_SQUARE) + - SFG_WEAPONBOB_OFFSET_PIXELS; - } - else - { - // player die animation - - int32_t t = SFG_game.frameTime - SFG_game.stateChangeTime; - - weaponBobOffset = (SFG_WEAPON_IMAGE_SCALE * SFG_TEXTURE_SIZE * t) / - SFG_LOSE_ANIMATION_DURATION; - } - - // add head bob just for the rendering (we'll will substract it back later) - - SFG_player.camera.height += headBobOffset; -#endif // headbob enabled? - - RCL_renderComplex( - SFG_player.camera, - SFG_floorHeightAt, - SFG_ceilingHeightAt, - SFG_texturesAt, - SFG_game.rayConstraints); - - // draw sprites: - - // monster sprites: - for (int_fast16_t i = 0; i < SFG_currentLevel.monsterRecordCount; ++i) - { - SFG_MonsterRecord m = SFG_currentLevel.monsterRecords[i]; - uint8_t state = SFG_MR_STATE(m); - - if (state != SFG_MONSTER_STATE_INACTIVE) - { - RCL_Vector2D worldPosition; - - worldPosition.x = SFG_MONSTER_COORD_TO_RCL_UNITS(m.coords[0]); - worldPosition.y = SFG_MONSTER_COORD_TO_RCL_UNITS(m.coords[1]); - - uint8_t spriteSize = SFG_GET_MONSTER_SPRITE_SIZE( - SFG_MONSTER_TYPE_TO_INDEX(SFG_MR_TYPE(m))); - - RCL_Unit worldHeight = - SFG_floorHeightAt( - SFG_MONSTER_COORD_TO_SQUARES(m.coords[0]), - SFG_MONSTER_COORD_TO_SQUARES(m.coords[1])) - + SFG_SPRITE_SIZE_TO_HEIGHT_ABOVE_GROUND(spriteSize); - - RCL_PixelInfo p = - RCL_mapToScreen(worldPosition,worldHeight,SFG_player.camera); - - if (p.depth > 0 && - SFG_spriteIsVisible(worldPosition,worldHeight,spriteSize)) - { - const uint8_t *s = - SFG_getMonsterSprite( - SFG_MR_TYPE(m), - state, - SFG_game.spriteAnimationFrame & 0x01); - - SFG_drawScaledSprite(s, - p.position.x * SFG_RAYCASTING_SUBSAMPLE,p.position.y, - RCL_perspectiveScaleVertical( - SFG_SPRITE_SIZE_PIXELS(spriteSize), - p.depth), - p.depth / (RCL_UNITS_PER_SQUARE * 2),p.depth); - } - } - } - - // item sprites: - for (int_fast16_t i = 0; i < SFG_currentLevel.itemRecordCount; ++i) - if (SFG_currentLevel.itemRecords[i] & SFG_ITEM_RECORD_ACTIVE_MASK) - { - RCL_Vector2D worldPosition; - - SFG_LevelElement e = - SFG_currentLevel.levelPointer->elements[ - SFG_currentLevel.itemRecords[i] & ~SFG_ITEM_RECORD_ACTIVE_MASK]; - - worldPosition.x = - SFG_ELEMENT_COORD_TO_RCL_UNITS(e.coords[0]); - - worldPosition.y = - SFG_ELEMENT_COORD_TO_RCL_UNITS(e.coords[1]); - - const uint8_t *sprite; - uint8_t spriteSize; - - SFG_getItemSprite(e.type,&sprite,&spriteSize); - - if (sprite != 0) - { - RCL_Unit worldHeight = SFG_floorHeightAt(e.coords[0],e.coords[1]) - + SFG_SPRITE_SIZE_TO_HEIGHT_ABOVE_GROUND(spriteSize); - - RCL_PixelInfo p = - RCL_mapToScreen(worldPosition,worldHeight,SFG_player.camera); - - if (p.depth > 0 && - SFG_spriteIsVisible(worldPosition,worldHeight,spriteSize)) - SFG_drawScaledSprite(sprite,p.position.x * SFG_RAYCASTING_SUBSAMPLE, - p.position.y, - RCL_perspectiveScaleVertical(SFG_SPRITE_SIZE_PIXELS(spriteSize), - p.depth),p.depth / (RCL_UNITS_PER_SQUARE * 2),p.depth); - } - } - - // projectile sprites: - for (uint8_t i = 0; i < SFG_currentLevel.projectileRecordCount; ++i) - { - SFG_ProjectileRecord *proj = &(SFG_currentLevel.projectileRecords[i]); - - if (proj->type == SFG_PROJECTILE_BULLET) - continue; // bullets aren't drawn - - RCL_Vector2D worldPosition; - - worldPosition.x = proj->position[0]; - worldPosition.y = proj->position[1]; - - RCL_PixelInfo p = - RCL_mapToScreen(worldPosition,proj->position[2],SFG_player.camera); - - const uint8_t *s = - SFG_effectSprites + proj->type * SFG_TEXTURE_STORE_SIZE; - - int16_t spriteSize = SFG_SPRITE_SIZE_PIXELS(0); - - if (proj->type == SFG_PROJECTILE_EXPLOSION || - proj->type == SFG_PROJECTILE_DUST) - { - int16_t doubleFramesToLive = - RCL_nonZero(SFG_GET_PROJECTILE_FRAMES_TO_LIVE(proj->type) / 2); - - // grow the explosion/dust sprite as an animation - spriteSize = ( - SFG_SPRITE_SIZE_PIXELS(2) * - RCL_sin( - ((doubleFramesToLive - - proj->doubleFramesToLive) * RCL_UNITS_PER_SQUARE / 4) - / doubleFramesToLive) - ) / RCL_UNITS_PER_SQUARE; - } - - if (p.depth > 0 && - SFG_spriteIsVisible(worldPosition,proj->position[2],spriteSize)) - SFG_drawScaledSprite(s, - p.position.x * SFG_RAYCASTING_SUBSAMPLE,p.position.y, - RCL_perspectiveScaleVertical(spriteSize,p.depth), - SFG_fogValueDiminish(p.depth), - p.depth); - } - -#if SFG_HEADBOB_ENABLED - // after rendering sprites substract back the head bob offset - SFG_player.camera.height -= headBobOffset; - -#if SFG_HEADBOB_SHEAR != 0 - SFG_player.camera.shear -= headBobShearOffset; -#endif - -#endif // head bob enabled? - -#if SFG_PREVIEW_MODE == 0 - SFG_drawWeapon(weaponBobOffset); -#endif - - // draw HUD: - - // bar - - uint8_t color = 61; - - for (uint16_t j = SFG_GAME_RESOLUTION_Y - SFG_HUD_BAR_HEIGHT; - j < SFG_GAME_RESOLUTION_Y; ++j) - { - for (uint16_t i = 0; i < SFG_GAME_RESOLUTION_X; ++i) - SFG_setGamePixel(i,j,color); - - color = 48; - } - - #define TEXT_Y (SFG_GAME_RESOLUTION_Y - SFG_HUD_MARGIN - \ - SFG_FONT_CHARACTER_SIZE * SFG_FONT_SIZE_MEDIUM) - - SFG_drawNumber( // health - SFG_player.health, - SFG_HUD_MARGIN, - TEXT_Y, - SFG_FONT_SIZE_MEDIUM, - SFG_player.health > SFG_PLAYER_HEALTH_WARNING_LEVEL ? 6 : 175); - - SFG_drawNumber( // ammo - SFG_player.weapon != SFG_WEAPON_KNIFE ? - SFG_player.ammo[SFG_weaponAmmo(SFG_player.weapon)] : 0, - SFG_GAME_RESOLUTION_X - SFG_HUD_MARGIN - - (SFG_FONT_CHARACTER_SIZE + 1) * SFG_FONT_SIZE_MEDIUM * 3, - TEXT_Y, - SFG_FONT_SIZE_MEDIUM, - 6); - - for (uint8_t i = 0; i < 3; ++i) // access cards - if ( - ((SFG_player.cards >> i) | ((SFG_player.cards >> (i + 3)) - & SFG_game.blink)) & 0x01) - SFG_fillRectangle( - SFG_HUD_MARGIN + (SFG_FONT_CHARACTER_SIZE + 1) * - SFG_FONT_SIZE_MEDIUM * (5 + i), - TEXT_Y, - SFG_FONT_SIZE_MEDIUM * SFG_FONT_CHARACTER_SIZE, - SFG_FONT_SIZE_MEDIUM * SFG_FONT_CHARACTER_SIZE, - i == 0 ? 93 : (i == 1 ? 124 : 60)); - - #undef TEXT_Y - - // border indicator - - if ((SFG_game.frame - SFG_player.lastHurtFrame - <= SFG_HUD_BORDER_INDICATOR_DURATION_FRAMES) || - (SFG_game.state == SFG_GAME_STATE_LOSE)) - SFG_drawIndicationBorder(SFG_HUD_BORDER_INDICATOR_WIDTH_PIXELS, - SFG_HUD_HURT_INDICATION_COLOR); - else if (SFG_game.frame - SFG_player.lastItemTakenFrame - <= SFG_HUD_BORDER_INDICATOR_DURATION_FRAMES) - SFG_drawIndicationBorder(SFG_HUD_BORDER_INDICATOR_WIDTH_PIXELS, - SFG_HUD_ITEM_TAKEN_INDICATION_COLOR); - - if (SFG_game.state == SFG_GAME_STATE_WIN) - SFG_drawWinOverlay(); - else if (SFG_game.state == SFG_GAME_STATE_LEVEL_START) - SFG_drawLevelStartOverlay(); - } -} - -uint8_t SFG_mainLoopBody() -{ - /* Standard deterministic game loop, independed of actual achieved FPS. - Each game logic (physics) frame is performed with the SFG_MS_PER_FRAME - delta time. */ - - if (SFG_game.state != SFG_GAME_STATE_INIT) - { - uint32_t timeNow = SFG_getTimeMs(); - -#if SFG_TIME_MULTIPLIER != 1024 - timeNow = (timeNow * SFG_TIME_MULTIPLIER) / 1024; -#endif - - int32_t timeSinceLastFrame = timeNow - SFG_game.frameTime; - - if (timeSinceLastFrame >= SFG_MS_PER_FRAME) - { - uint8_t steps = 0; - - uint8_t wasFirstFrame = SFG_game.frame == 0; - - while (timeSinceLastFrame >= SFG_MS_PER_FRAME) - { - uint8_t previousWeapon = SFG_player.weapon; - - SFG_game.frameTime += SFG_MS_PER_FRAME; - - SFG_gameStep(); - - if (SFG_player.weapon != previousWeapon) - SFG_processEvent(SFG_EVENT_PLAYER_CHANGES_WEAPON,SFG_player.weapon); - - timeSinceLastFrame -= SFG_MS_PER_FRAME; - - SFG_game.frame++; - steps++; - } - - if ((steps > 1) && (SFG_game.antiSpam == 0) && (!wasFirstFrame)) - { - SFG_LOG("failed to reach target FPS! consider setting a lower value") - SFG_game.antiSpam = 30; - } - - if (SFG_game.antiSpam > 0) - SFG_game.antiSpam--; - - // render only once - SFG_draw(); - - if (SFG_game.frame % 16 == 0) - SFG_CPU_LOAD(((SFG_getTimeMs() - timeNow) * 100) / SFG_MS_PER_FRAME); - } - else - { - // wait, relieve CPU - SFG_sleepMs(RCL_max(1, - (3 * (SFG_game.frameTime + SFG_MS_PER_FRAME - timeNow)) / 4)); - } - } - else if (!SFG_keyPressed(SFG_KEY_A) && !SFG_keyPressed(SFG_KEY_B)) - { - /* At the beginning we have to wait for the release of the keys in order not - to immediatelly confirm a menu item. */ - SFG_setGameState(SFG_GAME_STATE_MENU); - } - - return SFG_game.continues; -} - -#undef SFG_SAVE_TOTAL_TIME - -#endif // guard diff --git a/main_gbmeta/images.h b/main_gbmeta/images.h deleted file mode 100644 index fac3efb..0000000 --- a/main_gbmeta/images.h +++ /dev/null @@ -1,1397 +0,0 @@ -/** - @file assets.h - - This file containts assets to be used in the game. Textures are stored by - columns for cache friendliness (as rendering also happens by columns), - 4 bits per pixel, which means an index to 16 color subpalette stored at the - beginning of the image. Images can be converted to this format with the - provided pything script: - - python img2array.py -t -c -x32 -y32 -ppalette565.png image.png - - by Miloslav Ciz (drummyfish), 2019 - - Released under CC0 1.0 (https://creativecommons.org/publicdomain/zero/1.0/) - plus a waiver of all other intellectual property. The goal of this work is - be and remain completely in the public domain forever, available for any use - whatsoever. -*/ - -#ifndef _SFG_IMAGES_H -#define _SFG_IMAGES_H - -#define SFG_TEXTURE_SIZE 32 - -#define SFG_TEXTURE_STORE_SIZE (16 + (SFG_TEXTURE_SIZE * SFG_TEXTURE_SIZE) / 2) - -/** - Color index which will in textures and sprites be considered transparent. -*/ -#define SFG_TRANSPARENT_COLOR 175 - -/** - Special index of an implicit texture that consists of only transparent pixels. -*/ -#define SFG_TRANSPARENT_TEXTURE 255 - -static inline uint8_t SFG_getTexel(const uint8_t *texture, uint8_t x, uint8_t y) -{ - x &= 0x1f; - y &= 0x1f; - - return SFG_PROGRAM_MEMORY_U8 (texture + - ((SFG_PROGRAM_MEMORY_U8(texture + 16 + (x * SFG_TEXTURE_SIZE + y) / 2) >> - (4 * (y % 2 == 0))) & 0x0f)); -} - -#define SFG_WALL_TEXTURE_COUNT 16 - -SFG_PROGRAM_MEMORY uint8_t - SFG_wallTextures[SFG_WALL_TEXTURE_COUNT * SFG_TEXTURE_STORE_SIZE] = -{ -// 0, white wooden planks -4,21,5,3,20,0,2,26,6,18,57,65,1,16,17,49,0,1,0,3,32,1,33,0,161,64,1,16,64,3,3, -32,0,17,16,9,32,1,17,1,161,65,1,16,78,132,35,32,0,17,16,7,32,1,32,17,240,49,0, -16,57,99,87,206,0,18,16,6,33,0,16,1,177,48,0,0,97,0,2,0,0,17,32,6,32,1,0,1,178, -48,0,0,48,0,2,0,0,17,32,7,32,17,1,0,178,48,1,0,49,0,1,0,0,1,16,3,32,18,0,0,194, -48,0,0,48,0,18,4,64,17,32,4,35,0,3,0,194,48,0,0,49,0,34,4,0,17,32,6,130,50,32, -40,242,48,1,0,49,0,18,0,0,2,32,12,85,85,85,85,81,48,2,0,49,0,33,3,0,2,16,3,32,0, -32,2,98,48,1,0,49,0,34,19,0,18,17,3,32,0,32,0,194,48,2,0,0,0,34,3,4,2,16,3,16,0, -32,32,226,48,2,0,48,0,33,19,0,18,33,3,0,16,32,32,178,48,1,1,50,1,34,3,4,17,16,3, -0,16,32,16,162,48,1,64,50,1,34,7,3,1,17,3,0,16,32,16,184,2,2,2,2,48,18,3,0,0,17, -3,0,17,32,16,94,93,93,89,112,0,18,3,0,0,16,3,0,2,32,16,48,48,48,3,0,0,17,4,0,0, -17,3,0,1,32,16,48,48,0,3,1,1,18,3,0,0,32,7,16,1,32,16,48,0,1,0,1,50,34,3,0,1,33, -3,16,1,20,32,112,48,0,16,1,49,34,3,64,16,33,3,4,2,4,16,48,49,0,16,0,49,34,3,64, -0,32,3,16,1,0,0,48,49,0,16,65,48,34,3,49,0,17,3,16,2,0,0,48,49,1,32,0,49,34,3, -64,0,16,19,16,2,1,0,113,49,17,16,0,48,32,3,0,0,16,19,16,1,2,0,97,66,17,32,64,48, -33,19,34,2,0,137,16,1,18,0,97,49,17,16,66,64,32,3,84,212,105,69,16,1,17,0,97,49, -18,16,50,48,16,19,51,48,51,51,16,1,16,0,98,50,1,19,66,48,32,3,0,1,0,3,32,1,33,0, -177,49,2,16,66,64,16,3,0,1,0,7,32,1,16,1,82,64,1,16,50,0,16,35,0,1,0,9,33,2,32, -0,161,64,1,20,48,0,0,32 -, // 1, skyscraper window -4,5,3,6,2,81,0,59,48,128,138,131,66,44,137,129,16,176,208,176,44,33,0,0,1,43,1, -13,0,32,29,0,0,176,0,0,12,64,0,17,0,32,0,17,1,32,13,11,0,176,0,208,4,65,0,0,0, -34,1,16,1,32,16,0,23,32,0,2,40,66,2,194,230,140,34,208,2,176,17,0,119,76,66,34, -34,34,34,34,34,34,34,34,34,116,64,0,72,194,51,51,51,51,17,49,51,19,19,49,51,12, -34,36,17,210,49,17,16,17,1,17,17,16,17,1,17,42,1,17,17,2,49,154,116,244,229,164, -233,85,49,16,17,14,1,16,2,69,17,104,79,117,149,88,94,137,49,17,17,36,0,0,196,69, -48,137,119,69,84,79,88,85,49,17,1,4,92,244,0,34,0,69,85,95,127,116,86,89,49,17, -17,36,0,0,17,32,1,169,88,229,228,74,85,85,49,19,1,4,0,0,0,2,49,90,153,85,85,169, -95,85,49,16,17,4,2,0,0,39,48,68,85,233,138,37,133,136,49,17,17,36,0,32,0,4,17, -122,150,84,133,230,136,136,49,1,17,10,0,0,0,44,48,35,51,51,51,51,51,35,49,17,1, -66,0,13,0,4,17,51,3,211,3,3,35,2,49,17,17,34,0,0,0,37,49,167,42,70,106,69,102, -102,49,0,17,36,2,34,68,244,48,39,119,79,69,150,102,102,49,17,17,68,64,34,16,76, -49,119,2,127,120,102,102,102,49,17,19,5,0,1,1,74,49,114,119,4,152,102,104,102, -49,17,17,75,0,0,208,28,49,119,39,116,248,104,134,102,49,16,17,34,0,0,0,10,17,39, -114,37,169,104,136,86,49,16,17,4,0,0,1,43,49,114,126,232,74,102,104,134,49,1,0, -34,0,32,0,116,17,119,122,102,88,102,102,102,49,16,17,66,0,0,1,36,49,17,17,17,17, -17,17,17,1,1,1,64,0,0,32,184,49,17,49,17,17,19,51,17,17,17,19,178,0,34,44,66,34, -71,39,34,180,36,66,34,2,32,32,192,17,19,66,192,0,16,176,66,34,34,34,200,36,34, -34,36,68,44,221,192,0,0,10,32,0,16,1,34,16,16,0,11,0,16,13,64,0,0,10,0,0,0,1,34, -0,1,1,2,16,0,1,176,27,0,11,33,0,17,0,112,0,1,17,113,16,0 -, // 2, pink high-tech wall -83,4,12,5,84,20,61,85,13,6,11,3,7,14,15,0,34,32,34,0,32,2,170,34,170,160,170, -160,17,17,17,17,34,34,32,34,42,34,170,2,42,42,170,170,17,17,17,17,34,34,34,36, -34,160,36,32,160,160,42,10,49,17,17,17,34,34,34,42,34,0,0,0,0,0,0,4,49,49,17,17, -34,34,2,10,36,32,17,17,81,17,81,23,59,59,59,17,0,0,0,0,2,0,84,84,96,0,0,0,59,59, -49,19,102,102,102,102,96,32,20,86,0,102,102,102,145,59,59,19,34,34,34,36,96,32, -21,86,5,85,85,23,59,59,49,19,34,34,34,42,96,64,21,86,5,85,69,71,145,155,49,49, -34,34,66,37,96,128,84,86,5,85,91,23,49,49,49,19,34,34,0,0,0,0,0,0,4,84,69,87, -145,155,49,49,34,38,6,102,102,102,102,96,68,84,84,23,145,145,145,51,34,38,2,37, -88,32,68,69,69,85,85,71,49,145,49,51,40,134,2,34,130,64,21,69,85,84,21,23,145, -145,147,51,36,38,4,68,68,64,84,85,85,84,20,71,145,145,49,51,37,38,2,66,68,32,69, -85,85,85,69,87,145,145,147,51,40,134,5,84,72,64,20,65,69,68,20,71,145,193,147, -51,36,70,2,72,136,112,68,65,20,84,20,87,145,145,51,57,40,134,8,133,132,32,84,84, -17,84,68,87,195,147,147,51,40,134,8,88,136,112,21,17,17,68,17,23,147,51,51,51, -36,134,4,133,136,112,81,17,17,68,65,87,147,147,51,57,40,134,0,0,0,0,0,0,65,20, -68,71,147,57,147,57,39,120,102,102,102,102,102,102,1,17,84,71,153,51,57,57,40, -119,135,119,96,112,17,22,1,17,68,183,147,57,51,51,37,120,135,120,96,112,177,22, -1,17,17,87,153,147,57,57,37,136,136,135,96,32,65,22,1,20,91,71,60,57,57,57,0,0, -0,0,96,112,84,22,96,0,0,0,57,57,60,57,102,102,102,102,104,128,75,181,102,102, -102,102,60,57,51,60,39,119,135,119,120,112,180,84,180,181,75,183,57,60,57,57,34, -136,135,215,231,116,119,119,119,119,119,119,60,51,60,60,37,120,135,114,119,135, -125,120,116,212,68,114,60,60,57,57,34,117,136,135,135,120,132,136,136,136,136, -71,57,57,57,153 -, // 3, partly mossy concrete wall -4,3,5,36,20,37,76,12,11,19,77,130,13,35,2,0,2,0,0,80,32,0,0,1,5,37,1,64,4,25,19, -145,0,32,96,32,0,16,48,24,115,48,65,53,48,16,113,11,2,0,0,0,0,0,0,152,3,48,49, -48,51,19,1,17,0,32,16,48,0,16,0,8,0,0,1,67,0,23,19,17,2,0,5,48,0,16,0,24,115,65, -113,85,67,16,0,17,2,0,18,0,0,0,0,6,4,0,0,67,48,19,145,17,0,0,3,80,80,0,0,1,3,80, -19,3,83,16,9,1,2,0,210,0,0,16,0,1,148,3,1,48,51,16,17,17,19,0,16,48,0,16,0,24,5, -64,113,51,3,49,1,11,2,0,0,34,0,0,0,8,85,3,1,67,84,3,112,17,0,36,5,4,32,96,0,8,4, -4,3,52,83,16,17,1,34,0,2,32,0,0,7,1,3,32,49,3,51,119,49,113,4,32,96,66,0,0,0,7, -5,84,1,51,67,112,0,30,2,32,98,32,10,0,0,8,68,32,64,5,3,49,0,14,2,2,96,0,0,96,0, -6,5,80,49,48,51,112,1,27,0,32,2,0,1,96,0,1,51,0,1,3,51,27,0,27,2,0,96,32,0,0,6, -8,0,48,3,3,48,208,24,1,2,32,98,4,32,0,0,6,4,36,3,0,51,0,16,17,34,194,96,34,0,96, -0,6,50,48,1,83,67,144,0,8,0,42,2,36,0,0,162,8,5,32,65,64,48,23,1,1,2,32,100,34, -6,0,12,8,68,50,1,0,3,16,112,1,36,34,2,0,0,0,0,8,0,0,0,48,0,23,7,17,2,42,4,32,42, -0,0,8,5,64,64,35,0,135,0,1,2,64,98,44,6,0,32,8,48,48,1,85,0,17,0,49,2,32,3,2,0, -4,0,8,5,64,0,0,4,0,112,1,4,34,98,2,6,98,32,8,85,36,48,67,5,1,0,11,2,32,98,192, -160,4,52,8,4,0,1,4,0,0,112,113,2,194,2,0,0,0,2,1,5,85,64,211,4,48,0,1,2,32,0,42, -0,21,4,8,64,68,45,4,48,0,23,27,2,32,96,0,0,16,0,1,5,80,0,85,3,16,0,1,2,194,0,0, -0,16,48,17,84,85,0,48,64,144,25,17,0,32,96,0,0,0,64,13,3,68,0,5,48,16,0,17 -, // 4, wooden chess pattern -20,12,11,21,2,43,19,73,1,83,81,10,9,34,42,65,86,82,91,85,89,249,149,153,66,34, -40,34,34,114,34,36,0,0,0,48,48,35,0,2,33,18,39,17,17,66,17,18,0,0,5,48,3,96,3, -50,33,34,40,33,33,113,17,18,96,0,6,48,3,99,3,50,33,34,23,33,18,129,17,18,80,3,5, -48,3,99,3,54,33,33,23,18,17,114,17,18,80,0,5,48,3,99,0,54,33,34,20,34,33,114,33, -18,80,0,2,48,51,163,3,54,65,34,20,34,33,65,33,18,80,3,2,48,0,163,0,54,33,34,20, -34,17,66,33,18,0,0,2,3,0,67,0,53,177,34,20,34,17,130,33,18,0,0,2,51,0,211,0,5, -33,34,36,34,17,114,18,18,80,0,6,3,0,99,0,53,33,34,20,18,33,113,17,18,0,3,2,48,3, -99,0,6,65,33,20,18,33,65,17,18,0,0,2,0,0,96,0,6,34,34,20,17,33,129,17,18,0,0,5, -0,0,99,0,1,33,34,36,17,33,130,17,18,3,3,53,48,0,35,0,6,65,17,20,17,17,66,17,18, -80,85,86,5,85,224,85,85,68,68,72,66,68,132,68,36,66,34,20,34,34,66,34,36,96,0,5, -5,80,80,85,82,65,34,20,33,34,65,18,18,3,3,53,48,3,83,0,5,65,34,20,18,34,65,18, -34,51,51,54,51,3,80,5,5,66,34,20,18,34,65,18,18,51,51,53,51,3,80,5,5,66,34,20, -17,33,65,17,18,0,51,54,51,3,80,5,5,65,34,20,17,17,65,17,34,51,51,53,51,3,80,0,0, -65,34,20,17,17,65,17,18,0,51,54,48,51,80,0,0,66,34,20,17,18,65,17,18,3,51,54,48, -51,80,5,5,65,34,20,17,33,65,17,18,3,51,54,51,51,32,0,5,65,34,20,17,33,65,17,18, -3,51,54,51,51,80,1,5,65,34,20,17,33,65,34,34,3,51,59,48,51,80,5,85,65,34,20,17, -17,66,34,36,3,51,52,48,3,83,1,5,65,34,20,17,17,68,17,20,3,51,54,48,48,35,48,5, -65,33,20,34,17,66,17,18,3,0,52,51,51,35,48,5,65,33,20,17,17,65,18,18,3,51,54,51, -0,35,48,5,32,80,106,0,80,101,6,2,85,85,92,86,86,160,5,82 -, // 5, red brick wall -13,5,6,21,93,101,4,100,11,7,19,3,106,178,0,0,33,17,22,37,48,8,33,3,54,33,64,0,1, -20,5,70,37,0,88,37,85,88,32,64,4,17,64,0,65,20,0,70,32,51,56,37,85,8,33,0,4,17, -83,51,81,20,96,70,32,3,52,38,51,8,33,3,4,18,83,51,81,20,85,70,38,6,4,32,51,8,33, -3,4,18,64,51,81,20,85,69,38,0,4,38,3,52,33,83,5,17,67,51,81,20,101,70,38,0,4,38, -83,4,17,83,0,17,67,51,81,20,101,68,38,0,4,38,69,68,17,86,80,18,69,85,65,36,101, -68,32,85,4,34,17,17,33,86,83,18,18,34,34,36,0,88,33,0,4,34,34,18,33,83,0,18,17, -17,17,36,0,84,35,3,56,34,64,76,17,83,48,98,112,0,119,36,0,68,35,0,4,34,133,4,18, -3,48,98,113,0,17,36,0,85,33,0,4,34,133,100,17,81,48,98,112,0,1,36,0,86,35,0,8, -33,165,68,17,67,53,98,113,0,1,36,85,86,35,0,4,33,69,106,17,64,53,98,112,0,1,20, -85,86,35,0,4,33,133,68,17,64,53,18,112,0,1,20,5,86,35,0,4,33,166,84,17,64,53,18, -112,0,1,20,5,86,35,3,4,33,69,10,17,80,53,18,112,0,1,36,85,86,35,0,52,34,69,100, -33,83,5,18,112,0,113,40,5,84,33,64,8,33,69,4,33,69,68,18,112,0,1,36,0,22,33,0,4, -33,0,52,17,34,34,18,112,0,1,34,34,145,34,41,146,33,0,4,17,17,17,18,113,17,1,36, -99,22,38,80,49,33,69,4,32,0,4,98,112,17,17,36,51,6,32,80,4,33,69,106,35,3,53,98, -112,0,17,36,51,6,33,3,52,33,69,72,35,51,53,18,16,0,17,37,51,6,33,3,52,17,69,84, -35,51,53,98,112,0,17,37,51,6,33,1,52,17,69,100,35,51,48,98,113,17,17,21,3,6,35, -3,52,17,67,4,35,51,48,98,112,0,17,16,51,6,35,3,53,17,69,100,33,49,19,97,112,0, -17,37,51,6,35,3,4,17,212,4,33,3,51,98,1,0,1,36,3,6,35,3,52,18,34,34,33,3,48,177, -34,153,146,36,51,54,33,3,52,34,49,17,33,3,48,98,70,102,17,36,0,6 -, // 6, grass-covered concrete wall, tiles with skyscraper window -36,37,43,35,4,3,107,34,131,50,42,5,106,110,114,26,3,131,51,128,58,52,0,5,84,56, -84,2,0,48,66,0,48,128,5,5,10,112,0,68,0,48,85,68,4,144,32,1,6,32,17,0,7,116,80, -0,85,153,36,13,0,1,0,0,16,1,1,0,54,115,3,160,110,234,55,1,208,40,1,0,170,96,0, -39,115,51,51,144,0,51,144,0,0,16,0,2,17,16,17,208,11,187,20,0,2,43,64,32,17,16, -0,44,17,1,0,16,3,1,0,2,0,3,64,0,0,32,32,0,1,16,17,0,1,3,2,96,32,37,64,0,2,0,2, -32,17,16,1,1,0,0,34,128,32,0,1,16,16,32,0,32,1,0,0,0,16,8,0,2,2,2,2,0,32,2,32,0, -34,1,19,48,5,96,0,2,0,32,0,17,1,2,0,16,1,18,16,65,16,0,32,0,1,2,2,4,0,8,32,2,1, -39,18,4,1,32,0,208,0,0,0,1,16,0,2,0,0,18,19,48,0,16,13,0,1,0,32,18,16,0,0,0,16, -1,0,0,16,65,16,0,0,33,1,16,0,54,0,38,0,6,64,0,129,0,0,0,0,1,0,0,0,9,63,50,2,2,8, -2,32,0,18,0,17,0,1,17,96,0,5,80,32,0,0,0,0,18,69,80,0,1,16,48,1,0,32,153,206,32, -2,2,32,17,4,64,96,32,0,17,0,224,0,131,64,0,0,0,1,0,4,8,0,0,16,16,1,18,96,0,2,2, -0,34,32,2,0,0,5,0,0,96,2,0,32,0,2,0,2,0,17,0,0,0,85,34,32,0,0,0,0,0,2,0,1,16,48, -0,33,2,68,0,2,2,0,16,0,32,32,32,38,1,32,0,0,34,6,0,0,48,3,0,8,0,0,0,18,16,0,0, -98,0,32,0,0,0,33,32,0,32,0,17,17,0,0,0,33,32,0,0,4,49,18,0,2,16,2,1,66,0,98,2,0, -0,0,34,0,17,1,0,0,0,17,0,17,33,2,0,12,126,199,112,39,0,16,6,21,0,16,16,0,16,32, -32,167,51,63,62,172,151,113,0,0,2,0,1,17,48,16,16,48,69,4,51,64,64,0,16,8,96,27, -16,16,16,62,57,149,0,4,51,0,1,4,7,80,2,0,17,1,51,8,52,0,68,0,32,0,4,68,36,16,32 -, // 7, steel door -4,80,3,17,5,59,6,69,58,50,60,2,68,74,70,67,1,17,17,17,17,17,17,17,17,17,17,17, -17,17,17,17,22,102,70,102,70,102,70,102,70,100,102,100,102,100,102,97,16,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,1,16,0,32,0,32,0,32,0,32,2,0,2,0,2,0,1,19,189,187,221,189, -219,219,219,187,187,187,219,189,189,189,177,17,51,51,51,51,51,51,51,51,51,51,51, -51,51,51,49,19,136,136,136,133,133,85,95,34,34,44,47,34,194,34,40,19,136,34,34, -34,2,34,34,34,32,34,32,2,2,2,34,19,130,40,140,136,192,197,192,112,112,64,0,0,7, -4,7,19,146,136,200,92,80,122,90,160,0,64,0,7,0,4,0,19,146,149,136,200,84,122, -202,0,0,64,0,0,7,14,0,19,146,153,153,197,94,170,80,112,0,64,0,112,0,4,0,19,146, -37,156,133,112,5,0,0,224,224,0,112,112,4,0,19,146,153,153,87,160,0,7,160,0,64,0, -0,0,4,4,19,146,149,41,149,4,7,80,160,10,71,0,0,7,4,0,19,146,153,146,87,0,170,87, -0,7,64,0,7,0,4,4,19,146,89,204,87,4,167,80,7,0,224,0,0,0,4,0,19,146,153,156,90, -160,122,80,0,14,64,0,0,112,116,4,19,146,149,153,85,116,170,192,0,112,64,112,0,0, -4,0,19,146,41,92,138,84,122,90,0,0,71,0,7,0,4,4,19,146,153,204,80,126,90,202, -224,0,64,0,0,0,4,0,19,146,143,85,32,4,170,90,160,0,71,0,7,7,14,0,19,130,136,140, -128,116,122,202,112,10,64,0,112,0,4,0,19,130,40,200,92,14,170,80,0,170,74,112,0, -112,116,0,19,136,34,34,34,2,2,0,0,32,34,34,34,34,2,34,19,136,136,136,133,34,85, -85,85,37,194,47,34,242,34,34,17,51,51,51,51,51,51,51,51,51,51,51,51,51,51,49,27, -189,221,187,219,219,219,187,221,187,187,221,189,189,189,177,22,102,70,102,70, -102,70,102,70,102,70,100,102,100,102,97,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,16,0, -32,0,32,0,32,0,32,0,32,2,0,2,0,1,1,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17 -, // 8, white skull on blue -6,5,4,59,60,62,218,14,3,13,85,139,74,63,12,15,17,17,17,17,17,18,147,69,72,17,17, -17,17,17,17,17,16,16,1,1,16,18,35,51,50,17,1,1,16,16,1,17,16,0,0,0,0,18,36,99, -82,16,16,0,0,0,0,17,0,0,0,0,0,18,37,51,82,17,0,0,0,0,0,1,16,0,0,0,0,18,35,179, -50,17,16,0,0,0,0,1,0,0,0,0,0,18,35,51,66,17,16,0,0,0,0,17,16,0,0,0,1,226,37,67, -84,40,17,0,0,0,0,1,0,0,0,17,42,34,85,83,85,67,33,16,0,0,0,17,0,0,1,18,34,51,34, -34,68,75,98,129,16,0,0,17,16,0,17,162,51,130,34,34,38,198,52,66,129,0,1,17,17, -17,42,36,98,33,17,17,34,51,51,68,98,33,17,17,130,34,36,68,33,17,17,23,121,34,52, -68,51,66,34,34,68,84,53,85,33,0,0,121,151,34,37,85,67,69,221,51,51,68,52,82,16, -0,0,126,151,18,34,133,91,69,84,99,51,107,52,66,0,16,16,247,119,17,34,40,60,67, -51,68,83,99,51,50,1,1,17,0,1,33,18,40,51,51,52,85,75,52,52,66,0,17,17,0,1,33,18, -40,51,68,51,69,51,84,53,82,1,0,16,247,119,17,34,40,70,69,51,51,85,84,52,82,16,0, -0,126,151,18,34,132,70,69,84,99,85,68,52,52,33,0,0,121,151,34,36,52,60,52,85,51, -130,34,35,107,33,17,17,23,121,34,99,107,195,66,34,34,17,17,42,102,98,33,17,17, -34,54,102,102,98,33,17,17,16,0,17,162,68,130,34,34,36,76,102,98,33,0,1,17,0,0,1, -18,35,69,34,34,85,67,194,161,16,0,0,17,16,0,0,17,42,35,69,67,68,75,33,16,0,0,0, -17,0,0,0,0,1,226,35,99,54,42,17,0,0,0,0,1,0,0,0,0,0,18,35,51,66,17,16,0,0,0,0, -17,16,0,0,0,0,18,37,51,82,17,16,0,0,0,0,1,0,0,0,0,0,18,45,51,66,17,0,0,0,0,0,1, -16,0,0,0,0,18,36,99,50,16,16,0,0,0,0,17,16,16,1,1,16,18,35,68,50,17,16,16,16,16, -1,17,17,17,17,17,17,18,148,85,88,17,17,17,17,17,17,17 -, // 9, red lava with stones -3,4,12,11,83,94,102,92,91,14,93,15,19,20,100,0,3,82,2,83,32,67,84,1,17,17,16,5, -32,17,20,0,2,48,0,67,117,118,36,0,33,33,0,5,33,17,17,19,69,64,17,20,67,86,82,36, -17,1,0,53,1,17,17,64,56,1,17,17,0,130,50,117,131,64,4,39,0,17,17,0,32,1,17,17,3, -82,4,68,39,85,34,98,36,16,0,3,0,0,1,16,3,82,1,16,0,35,53,106,83,51,51,54,85,68, -36,3,53,32,49,17,16,0,54,34,66,35,37,86,67,85,85,34,38,66,1,17,17,0,82,64,64,0, -3,101,0,32,3,34,102,103,65,1,17,3,84,1,17,0,3,83,18,17,0,67,34,68,85,52,0,69,48, -17,17,19,69,0,17,17,20,3,112,0,2,53,51,114,1,17,17,16,69,65,17,17,16,3,80,3,0,4, -46,98,64,17,17,32,115,1,17,18,0,53,64,17,17,16,50,86,34,0,0,0,35,1,0,0,0,37,65, -17,17,17,2,34,119,85,67,66,34,0,51,130,50,98,64,17,17,17,2,35,68,51,85,102,98, -35,51,50,86,102,35,34,2,16,3,132,0,0,4,34,82,35,20,0,66,85,39,120,34,4,2,80,1, -17,4,53,52,0,17,4,3,83,64,2,37,81,69,16,77,17,16,69,16,0,18,16,0,84,16,0,67,66, -38,49,17,17,32,53,32,17,17,17,0,82,0,33,16,3,102,32,0,0,4,84,0,18,17,17,0,84,1, -17,17,4,182,98,64,0,3,84,1,17,17,17,0,83,1,17,17,4,99,37,83,50,50,32,0,33,17,16, -0,83,1,17,33,2,36,0,34,114,118,84,16,17,0,0,3,83,1,17,16,67,49,1,16,4,38,103,51, -64,84,68,53,32,0,17,0,55,32,17,17,0,39,50,39,85,37,82,166,98,36,16,64,34,1,17, -17,16,55,32,0,36,0,4,54,34,117,66,51,84,1,17,17,16,82,0,0,2,17,4,39,64,18,82, -118,98,64,1,17,4,84,16,17,17,18,4,84,4,0,20,53,102,82,32,0,4,84,0,33,17,16,2,32, -1,17,64,39,51,69,85,117,53,156,65,1,18,50,38,36,17,17,16,34,0,0,20,67,102,101, -115,51,51,130,101,101,32,17,4,84,1,17,33,16,38,148,19,56,56 -, // 10, transparent window -175,4,5,3,59,13,49,60,74,62,61,50,83,2,69,12,17,17,33,17,81,17,17,33,17,17,17, -17,18,34,34,17,59,17,17,17,17,17,17,17,17,17,177,17,18,34,82,33,51,51,51,51,51, -51,51,51,51,51,59,81,18,34,33,17,49,182,102,102,102,102,102,102,102,107,18,33, -18,34,34,33,51,0,0,0,0,116,16,0,0,10,50,37,18,34,34,33,51,0,0,0,0,116,16,0,0,10, -50,17,18,34,21,33,51,0,0,0,0,84,16,0,0,10,50,33,17,243,51,52,51,0,0,0,0,20,16,0, -0,10,50,145,18,17,17,21,51,0,0,0,0,20,32,0,0,10,50,149,18,49,81,17,51,0,0,0,0, -116,112,0,0,1,50,37,82,17,113,17,51,18,51,140,140,71,72,140,136,200,50,37,82,49, -17,225,51,18,68,68,68,121,116,68,68,71,50,33,82,18,18,17,51,0,0,0,0,212,208,0,0, -12,50,17,18,37,34,17,51,0,0,0,0,20,16,0,0,9,50,17,18,18,37,30,51,0,0,0,0,116,32, -0,0,2,50,145,18,34,34,33,51,0,0,0,0,116,16,0,0,2,50,37,18,34,18,17,51,0,0,0,0, -116,16,0,0,10,50,145,18,37,33,18,51,0,0,0,0,116,16,0,0,10,57,145,82,33,18,225, -51,0,0,0,0,20,16,0,0,10,57,145,18,18,17,21,51,0,0,0,0,212,208,0,0,13,50,149,18, -37,18,17,51,18,68,68,68,121,116,68,68,71,50,37,18,34,33,17,51,18,60,200,140,71, -76,136,136,200,50,37,18,34,81,30,51,0,0,0,0,244,16,0,0,1,50,149,18,34,33,17,51, -0,0,0,0,20,32,0,0,10,50,33,18,18,17,17,51,0,0,0,0,116,32,0,0,2,50,33,17,243,51, -52,51,0,0,0,0,20,16,0,0,10,50,17,18,17,17,17,51,0,0,0,0,84,16,0,0,10,50,33,82, -17,33,31,51,0,0,0,0,116,16,0,0,2,50,33,18,17,17,17,49,182,102,102,102,102,102, -102,102,107,34,81,18,37,17,17,19,50,34,34,34,34,34,34,34,34,35,81,18,34,17,17, -59,34,34,34,34,34,34,34,34,34,181,17,18,18,81,21,17,17,17,17,33,17,17,17,21,17, -17,17,18,34,34,18 -, // 11, white steel blocks -6,5,7,4,3,85,71,78,0,0,0,0,0,0,0,0,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, -68,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,52,34,0,34,34,2,34,34,34,34,34, -0,34,34,34,0,17,0,17,0,0,0,1,16,0,0,0,0,0,1,16,17,17,0,20,0,0,0,0,0,0,0,0,0,0,1, -64,0,17,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,17,17,17,17,17,17,17,17,81,17,17,17,17,17, -17,17,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,1,17,16,0,0,0,0,0,0,0,0,0,0,0,0,17,0, -0,1,1,0,0,6,0,0,0,0,0,0,0,0,17,34,0,34,0,34,34,34,34,34,34,34,34,32,2,34,17,0, -17,0,1,16,0,0,0,0,0,17,0,0,0,0,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,0,0,0,0,1,0, -0,0,0,0,0,0,16,0,17,17,17,17,17,81,17,22,0,0,0,1,17,1,17,17,17,19,0,0,0,0,0,2,0, -0,0,1,0,0,0,0,113,21,16,0,0,0,0,2,0,0,0,1,0,0,0,0,0,19,0,0,0,0,0,2,0,0,0,1,0,0, -0,0,1,17,34,34,32,2,34,34,0,0,0,2,34,34,0,34,0,17,0,0,0,0,0,17,0,0,0,0,0,1,16, -16,17,17,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,17,0,1,0,0,0,0,0,0,0,0,0,0,0,17,17, -17,17,17,17,17,17,81,17,17,17,17,17,17,17,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,1, -17,16,0,0,0,0,0,0,0,0,1,0,1,16,17,0,0,1,1,0,0,6,0,0,0,16,0,0,0,0,17,34,0,34,0, -34,0,34,34,34,34,34,34,32,2,34,17,0,17,1,1,16,0,0,0,0,0,17,0,1,16,0,17,0,20,0,0, -0,0,0,0,0,0,0,0,1,64,1,17,0,0,0,0,0,0,0,1,0,0,0,0,16,0,17,17,17,17,17,17,17,17, -17,17,21,17,17,17,17,17,17,19,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51 -, // 12, gray square-tiled wall -4,5,3,13,50,6,12,21,85,20,14,11,19,22,84,0,17,17,17,17,17,17,17,18,17,17,17,17, -17,17,17,20,17,3,16,8,17,16,0,18,17,16,1,1,0,3,16,18,16,1,16,1,0,49,17,48,17,1, -3,6,0,17,3,2,16,16,0,16,16,24,16,16,17,0,0,23,16,0,0,2,16,1,3,17,1,16,16,18,19, -0,0,0,49,1,1,2,16,48,17,6,17,17,0,0,16,16,16,119,16,19,0,2,17,16,17,17,17,26,16, -50,17,49,0,19,0,0,0,2,16,17,49,17,129,17,16,2,16,3,16,0,0,1,6,2,16,17,16,1,17, -17,16,2,17,0,17,1,0,0,0,18,17,49,24,17,17,129,16,6,16,113,49,3,16,0,0,98,17,17, -17,16,49,0,96,9,16,16,0,0,1,49,0,18,17,17,17,17,17,16,1,2,81,1,0,32,0,16,16,2, -17,161,129,1,0,48,0,4,16,0,48,16,0,49,1,2,17,17,17,49,17,0,0,16,16,0,16,16,0,0, -48,2,80,17,17,17,19,17,48,0,16,16,0,0,0,17,6,2,32,48,32,6,0,34,32,98,2,34,34,38, -2,34,34,34,21,81,21,85,81,21,81,86,85,21,17,17,21,81,17,27,17,17,16,19,0,48,1,0, -16,0,0,0,48,0,0,2,19,17,49,0,17,1,17,2,22,1,0,1,1,48,0,2,16,17,0,0,48,0,49,2,80, -6,0,0,16,1,48,2,16,48,0,0,16,16,112,50,16,0,0,1,0,16,16,148,17,1,49,0,0,49,0,28, -16,0,0,48,3,0,0,2,16,0,3,1,0,0,17,18,16,3,0,0,0,0,0,50,17,113,1,3,0,0,48,2,16,0, -0,0,0,6,0,2,16,0,0,0,0,48,0,18,16,0,0,0,0,0,0,2,17,0,0,0,0,0,3,2,208,0,3,0,48,0, -0,4,17,112,48,19,16,0,0,18,17,0,0,0,0,0,16,100,16,17,9,1,1,16,1,2,22,0,0,0,0,0, -0,2,16,1,0,16,3,0,48,0,16,0,0,0,0,224,0,4,16,48,3,1,0,0,16,50,16,3,0,48,0,3,0, -52,16,16,1,16,0,0,0,2,16,16,0,0,2,2,1,4,68,66,32,34,36,34,34,36,34,36,34,34,68, -68,68,68 -, // 13, scifi door -3,2,4,9,0,74,200,10,75,41,160,48,120,17,34,50,68,68,68,68,68,68,68,68,70,102, -102,102,102,102,102,102,85,85,153,85,85,153,85,85,85,136,136,136,136,136,136, -136,149,153,153,147,147,57,55,57,125,238,88,135,127,85,119,119,51,147,51,51,51, -55,147,55,215,125,215,119,119,119,119,119,68,68,68,68,68,68,68,70,102,102,102, -102,102,102,102,102,0,0,0,0,0,0,0,5,2,34,34,34,34,34,34,34,53,92,65,85,19,48,0, -81,32,11,160,0,1,18,34,1,48,83,64,0,83,16,0,1,34,1,178,34,1,2,34,33,53,84,65,0, -4,49,80,1,0,11,160,34,43,16,2,1,52,196,49,85,28,51,51,161,26,186,16,0,11,17,17, -161,51,51,51,51,51,51,49,16,1,17,17,17,17,17,17,16,53,85,49,85,19,21,0,34,32,0, -16,0,1,2,34,1,53,5,48,0,83,16,34,34,34,32,18,34,1,2,34,17,49,85,49,0,4,16,34,34, -34,32,16,34,43,2,32,161,51,68,49,85,28,16,34,34,34,32,16,0,11,0,17,0,51,67,51, -51,51,16,34,34,34,32,17,17,17,1,16,34,52,49,49,17,19,16,34,34,34,32,16,0,1,0,17, -2,51,5,48,0,84,16,34,34,34,32,18,34,10,2,1,17,48,5,49,5,84,16,34,34,34,32,16,32, -10,2,32,161,48,85,49,21,28,53,2,34,34,0,16,0,11,16,34,17,49,19,67,68,195,17,80, -177,16,1,161,171,177,0,0,177,51,52,17,51,67,51,17,16,1,26,0,17,161,17,17,16,53, -92,48,85,196,48,0,1,32,11,18,0,186,18,34,1,48,83,48,5,52,48,0,33,34,1,18,32,27, -18,34,33,53,84,49,85,68,17,80,1,0,11,16,0,186,0,2,1,52,196,51,76,67,19,51,161, -26,186,17,171,161,1,17,161,0,0,0,0,0,0,0,0,2,34,34,34,34,34,34,34,68,68,68,68, -68,68,68,102,102,102,102,102,102,102,102,102,51,147,51,51,51,55,147,125,125,119, -119,119,119,119,119,119,149,153,153,147,147,121,55,62,119,238,88,135,127,85,119, -119,85,85,153,85,85,153,85,85,152,136,136,136,136,136,136,136,68,68,68,68,68,68, -68,68,102,102,102,102,102,102,102,102 -, // 14, concrete wall, tiles with skyscraper window -5,4,3,2,6,44,131,66,50,51,45,81,132,28,138,1,1,97,81,193,39,32,17,17,16,44,16, -21,17,33,5,17,17,97,17,17,23,49,17,0,17,33,17,0,16,33,21,28,17,97,17,81,19,48, -17,17,17,34,16,1,16,33,1,17,9,33,17,18,47,50,18,130,255,248,34,81,18,97,0,17, -153,55,50,34,34,34,34,34,34,34,34,34,34,147,49,17,63,114,68,68,68,68,0,64,68,4, -4,64,68,24,34,35,0,82,64,0,1,0,16,0,0,1,0,16,0,46,16,0,0,18,64,16,1,17,0,0,13,0, -0,1,0,31,16,1,18,59,0,16,0,0,0,0,0,0,0,0,0,35,17,17,115,59,65,17,0,0,0,0,0,0,0, -0,16,19,183,51,161,34,17,16,0,0,0,0,0,0,0,0,0,35,17,17,0,33,16,0,0,0,0,0,0,0,0, -4,208,19,17,17,17,18,64,0,0,0,0,0,0,0,0,1,0,19,18,17,17,41,65,16,0,0,0,0,0,0,0, -0,0,35,17,33,17,19,0,16,0,0,0,0,0,0,0,16,0,30,17,17,17,39,65,0,0,0,0,0,0,0,0,0, -16,50,17,21,17,19,0,21,17,0,0,0,0,0,0,0,0,34,17,17,17,43,64,0,0,0,0,0,0,0,0,29, -0,35,18,34,51,51,65,21,1,0,0,0,0,0,0,0,0,51,49,34,1,55,64,0,0,0,0,0,0,0,0,0,4, -27,17,16,16,62,64,16,1,0,0,0,0,0,0,0,0,54,17,17,81,7,64,0,160,0,1,0,0,0,0,1,0, -34,17,17,17,30,0,16,16,16,0,0,0,0,0,1,0,19,17,17,16,38,64,0,0,160,16,0,0,0,208, -16,209,34,17,33,17,147,0,16,17,0,0,16,0,16,0,1,0,50,17,17,16,35,64,0,0,0,0,0,0, -0,16,16,16,49,17,17,33,111,64,0,64,0,0,4,68,0,0,0,4,98,17,34,40,50,34,57,41,34, -99,35,50,34,18,33,33,129,0,4,50,129,17,1,193,50,34,34,34,143,35,34,34,35,51,39, -85,113,17,17,22,33,17,1,16,34,1,1,161,22,17,1,21,49,17,17,30,17,17,17,16,34,17, -16,16,18,10,17,16,97,12,17,22,32,17,0,17,145,17,16,0,144,1,17 -, // 15, computer tech wall -52,59,53,220,38,141,54,143,75,76,77,61,74,5,66,95,48,0,0,0,10,17,0,0,0,0,38,0,0, -0,0,51,16,0,2,1,17,17,0,0,16,0,38,0,0,0,0,3,10,0,0,0,17,1,17,17,17,16,34,0,1,0, -0,0,7,0,0,0,17,49,81,33,33,32,34,48,1,48,0,0,2,0,0,0,17,1,1,17,17,16,38,0,0,0,0, -0,0,0,0,83,0,17,1,33,33,35,18,0,0,80,0,0,0,0,3,0,0,17,17,17,17,16,2,83,2,0,7,0, -0,85,19,19,3,17,17,33,33,32,2,17,0,32,0,0,0,0,48,0,1,16,1,0,16,0,34,17,17,0,0,0, -0,1,2,16,0,24,0,80,1,0,82,1,12,2,0,0,16,16,5,16,0,1,1,0,9,17,34,17,30,18,32,8, -16,0,96,0,0,17,17,17,17,17,34,80,85,16,32,1,0,2,2,0,0,17,68,68,68,68,34,5,85,1, -39,0,0,6,0,176,0,17,68,68,68,68,34,85,5,1,114,3,0,6,0,0,10,25,68,68,68,68,38,11, -85,1,114,3,0,6,0,0,0,17,68,68,68,68,34,0,48,1,2,3,2,6,0,0,0,17,68,68,68,68,34,0, -0,1,2,0,0,2,112,0,0,17,68,68,68,68,38,0,0,1,2,112,0,0,7,112,80,17,68,68,68,68, -38,0,0,21,34,0,0,16,32,0,0,19,34,34,34,34,34,5,0,80,34,177,17,227,0,53,1,17,16, -3,1,1,50,19,51,224,32,24,128,17,32,16,1,16,1,0,16,16,2,51,28,50,32,8,16,1,0,80, -0,21,0,0,16,1,146,51,137,6,0,1,0,1,16,0,17,17,0,0,17,16,34,17,144,32,0,3,0,0,17, -0,1,1,13,240,3,17,35,24,0,0,3,3,0,0,81,16,0,1,15,240,51,0,35,0,3,0,0,1,48,0,0, -195,0,17,0,0,5,49,34,0,3,0,160,3,0,0,5,48,206,17,4,208,109,0,2,48,0,112,2,3,57, -0,0,0,1,17,13,208,221,51,18,17,0,176,3,3,19,0,5,16,0,1,3,0,49,19,50,17,1,0,51,1, -144,0,48,0,0,17,0,0,0,48,34,49,48,0,0,3,48,0,0,0,10,17,0,0,0,0,38,0,0,0,0,51 -}; - -SFG_PROGRAM_MEMORY uint8_t SFG_itemSprites[13 * SFG_TEXTURE_STORE_SIZE] = -{ -// 0, barrel -175,6,106,29,100,84,7,92,2,43,10,11,46,4,28,200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0, -15,240,0,0,0,0,0,0,255,248,255,255,255,255,255,255,248,143,255,255,255,255,255, -255,143,248,248,255,255,143,136,136,130,136,136,136,136,136,136,136,143,168,66, -136,136,137,136,146,146,130,153,153,146,146,143,66,168,170,226,34,130,41,73,41, -66,137,34,34,153,41,146,226,168,186,34,34,155,149,187,186,162,170,84,153,34,146, -36,158,170,234,34,233,229,93,170,171,85,91,43,78,68,66,146,36,187,121,228,237, -69,90,181,85,85,93,91,132,77,66,36,73,158,89,18,68,69,187,85,183,119,122,181, -187,68,66,68,18,222,93,18,68,77,161,197,28,119,119,170,26,94,34,36,18,213,93, -193,20,21,177,17,81,87,119,123,183,84,52,44,20,222,93,17,17,23,17,17,21,119,117, -17,81,65,35,65,28,213,93,49,17,26,21,186,167,119,225,17,17,113,34,49,49,222,93, -60,19,106,97,106,119,115,49,97,193,118,35,67,19,222,93,18,102,101,102,102,103, -117,86,22,54,113,50,35,18,213,93,18,198,99,118,102,119,119,119,119,183,54,99,38, -25,190,93,102,102,195,166,203,119,119,123,190,101,108,50,51,99,181,93,54,54,51, -117,22,19,87,187,229,53,51,34,33,28,222,125,51,51,51,58,49,28,17,49,21,227,19, -19,51,17,158,185,195,51,51,49,174,81,17,85,117,17,17,193,28,76,155,186,51,195, -51,17,61,91,187,181,49,52,49,28,20,28,154,170,25,236,30,49,49,17,49,193,17,17, -28,20,19,28,184,170,25,225,193,17,17,17,17,193,17,17,17,20,19,30,184,138,60,238, -236,193,193,193,17,195,65,17,17,225,68,62,175,250,34,34,34,34,34,36,225,228,34, -34,34,34,34,36,175,251,0,0,0,0,0,0,4,64,0,0,0,0,0,0,191,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -, // 1, health -175,7,5,6,2,94,0,69,4,53,71,93,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,68,68,64,0,4,68,68,64,0,0,0,0,0,0,0,4,17,17,20,68,65,17,17,20, -0,0,0,0,0,0,0,65,18,35,49,17,19,50,35,56,64,0,0,0,0,0,4,17,55,119,119,119,119, -119,119,50,70,0,0,0,0,0,4,34,119,41,41,41,41,41,39,114,134,0,0,0,0,0,4,34,114, -146,146,146,146,146,149,115,38,0,0,0,0,0,68,19,161,17,17,17,17,17,53,163,54,0,0, -0,0,4,34,35,163,17,17,17,17,17,21,163,38,0,0,0,0,4,108,41,161,21,85,85,85,177, -53,162,134,0,0,0,0,4,4,34,163,21,85,85,85,177,21,162,70,0,0,0,0,4,4,194,161,49, -49,91,17,49,53,168,96,0,0,0,0,4,0,66,163,19,17,91,19,19,21,168,96,0,0,0,0,4,0, -66,161,49,49,91,17,49,53,168,96,0,0,0,0,4,4,194,163,19,17,91,19,19,21,168,96,0, -0,0,0,4,4,34,161,21,85,85,85,177,53,162,70,0,0,0,0,4,108,41,163,21,85,85,85,177, -21,162,134,0,0,0,0,6,34,35,161,17,17,17,17,17,53,163,38,0,0,0,0,0,102,19,163,17, -17,17,17,17,21,163,54,0,0,0,0,0,4,34,121,41,41,41,41,41,37,115,38,0,0,0,0,0,4, -34,119,146,146,146,146,146,151,114,134,0,0,0,0,0,4,19,55,119,119,119,119,119, -119,50,70,0,0,0,0,0,0,98,50,35,40,136,130,50,35,40,96,0,0,0,0,0,0,6,136,136,134, -102,104,136,136,134,0,0,0,0,0,0,0,0,102,102,96,0,6,102,102,96,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -, // 2, ammo: bullets -175,124,168,125,2,5,21,194,19,17,112,113,190,3,4,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,170,170,170,0,0,0,0,0,0,0,0,0,0,0,0,170,136,72,218, -0,0,0,0,0,2,34,34,34,34,32,10,104,102,214,73,32,0,0,0,0,34,119,119,119,119,34, -36,68,68,68,71,32,0,0,0,0,33,17,17,17,25,183,119,238,231,119,23,32,0,0,0,0,35, -17,17,20,68,183,119,238,231,119,23,32,0,0,0,0,35,17,20,72,132,183,119,238,231, -119,23,32,0,0,0,0,35,17,70,134,109,179,51,255,243,51,49,32,0,0,0,0,35,17,20,74, -170,179,119,85,81,17,49,32,0,0,0,0,35,17,26,168,132,179,113,85,81,17,49,32,0,0, -0,0,35,17,70,134,109,179,113,92,193,17,49,32,0,0,0,0,35,17,26,150,245,179,17, -204,81,17,49,32,0,0,0,0,35,17,20,137,153,179,17,197,81,17,49,32,0,0,0,0,35,17, -70,134,109,179,17,92,81,23,23,32,0,0,0,0,35,17,26,137,153,179,17,204,199,68,68, -66,0,0,0,0,35,17,20,152,132,179,17,85,68,136,72,66,0,0,0,0,35,17,70,134,109,179, -17,84,104,102,214,210,0,0,0,0,35,17,26,150,245,179,17,204,73,255,95,82,0,0,0,0, -35,17,20,152,132,179,17,85,193,153,154,162,0,0,0,0,35,17,70,134,109,179,17,92, -193,20,68,210,0,0,0,0,35,17,26,150,245,179,17,197,193,20,246,130,0,0,0,0,35,17, -72,137,153,179,17,197,81,20,93,66,0,0,0,0,35,17,26,152,132,179,17,92,193,25,246, -130,0,0,0,0,35,17,166,134,109,179,17,92,81,17,150,130,0,0,0,0,2,34,42,166,245, -179,17,204,193,17,152,32,0,0,0,0,0,0,0,2,34,179,17,85,81,17,58,32,0,0,0,0,0,0,0, -0,0,35,17,85,81,17,49,32,0,0,0,0,0,0,0,0,0,34,34,153,146,34,49,32,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,34,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0 -, // 3, ammo: rockets -175,1,117,120,30,3,33,82,5,98,101,102,2,178,174,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,204,16,0,0,0,0,0,0,0,0,0, -0,0,0,17,26,197,81,17,17,17,16,0,0,0,0,0,0,0,17,204,202,85,92,113,119,23,16,0,0, -0,0,0,0,1,85,197,90,85,204,119,17,119,16,0,0,3,51,0,0,1,170,85,90,85,92,119,119, -119,16,0,3,59,47,51,0,1,85,197,90,85,204,124,119,199,193,0,59,187,42,169,51,53, -170,92,90,85,87,246,31,31,193,3,187,238,218,153,157,149,68,37,36,42,39,135,17, -17,17,0,62,238,217,153,51,53,85,82,36,34,167,136,97,17,16,0,3,222,217,211,0,6, -68,34,36,42,247,136,246,17,96,0,3,221,221,211,0,6,68,85,36,34,247,136,246,225, -96,0,59,187,42,169,51,53,68,133,36,42,39,136,246,209,96,3,187,238,218,153,157, -149,68,40,36,34,167,136,246,145,96,0,62,238,217,153,51,53,68,85,36,42,39,136, -246,225,96,0,3,222,217,211,0,6,68,130,36,34,167,136,246,209,96,0,3,221,221,211, -51,54,68,85,36,42,247,136,246,145,96,0,59,187,42,169,51,53,68,85,36,34,247,136, -246,225,96,3,187,238,218,153,157,149,68,34,36,42,39,136,246,209,96,0,62,238,217, -153,51,53,68,85,36,34,167,136,118,145,96,0,3,62,217,51,59,230,68,34,36,42,39, -136,201,153,16,0,0,3,51,0,50,182,68,34,36,34,167,135,106,153,16,0,0,0,0,0,3,54, -85,82,36,42,247,140,250,169,145,0,0,0,0,0,0,6,136,37,36,34,247,134,34,221,209,0, -0,0,0,0,0,0,102,72,68,42,39,134,187,238,236,0,0,0,0,0,0,0,0,102,104,34,166,102, -203,238,192,0,0,0,0,0,0,0,0,0,6,68,105,209,203,190,192,0,0,0,0,0,0,0,0,0,0,102, -1,145,28,188,0,0,0,0,0,0,0,0,0,0,0,0,0,17,16,192,0,0,0,0,0,0,0,0,0,0,0,0,0,17,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -, // 4, ammo: plasma -175,6,0,2,4,142,206,5,7,62,205,115,207,116,1,201,0,0,0,0,35,51,51,51,51,50,0,3, -48,0,0,0,0,0,0,3,57,145,145,145,153,147,32,54,99,0,0,0,0,0,0,51,149,34,34,34,34, -52,34,42,162,34,34,32,0,0,2,57,50,143,255,34,243,34,238,39,66,238,62,32,0,0,3, -149,40,252,106,175,84,51,51,55,67,62,67,32,0,0,3,146,2,198,170,219,87,68,67,67, -52,67,116,32,0,0,3,146,2,198,170,221,87,68,67,68,68,67,116,32,0,0,3,146,2,198, -106,219,81,119,116,55,119,116,23,32,0,0,3,146,0,54,102,106,81,119,119,67,51,51, -52,32,0,0,3,146,0,251,187,187,184,17,17,17,17,23,67,32,0,0,3,50,2,106,221,219, -88,17,145,25,27,182,132,32,0,0,2,66,2,198,170,173,88,17,81,21,27,172,132,32,0,0, -3,50,2,198,106,171,88,17,81,89,27,172,132,32,0,0,2,66,0,54,102,106,88,153,85, -145,26,204,132,32,0,0,3,50,0,251,187,187,184,149,17,17,17,23,132,32,0,0,2,66,2, -106,221,219,88,17,25,25,17,23,132,32,0,0,3,50,2,198,170,221,88,21,21,21,17,23, -132,32,0,0,2,66,2,198,106,219,88,21,21,21,17,23,132,32,0,0,3,50,0,54,102,106,88, -25,21,81,17,23,132,32,0,0,2,66,0,251,187,187,184,17,17,25,17,23,132,32,0,0,3,50, -2,106,221,219,88,17,81,21,17,23,132,32,0,0,2,66,2,198,170,221,88,17,81,81,17,23, -132,32,0,0,3,146,2,198,106,219,88,17,85,21,17,23,132,32,0,0,3,146,0,54,102,106, -88,149,17,17,17,23,132,32,0,0,3,146,0,251,187,187,184,81,145,17,20,23,132,32,0, -0,3,146,2,106,221,219,88,17,81,81,23,23,132,32,0,0,3,146,2,198,170,221,88,17,81, -149,20,23,132,32,0,0,3,149,34,198,106,170,88,17,85,17,17,23,67,32,0,0,2,52,62, -54,102,106,88,17,17,51,51,51,52,32,0,0,0,35,69,46,238,238,247,119,115,71,119, -116,116,32,0,0,0,2,52,65,65,65,67,51,34,35,50,34,34,32,0,0,0,0,34,34,34,34,34, -34,0,2,32,0,0,0 -, // 5, tree -175,0,17,115,5,3,2,196,4,114,20,38,22,96,37,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,51,0,0,0,1,17,0,0,0,3,54,32,0,0,0,3,51,51,0,17,26,72,0,0,0, -59,187,178,0,0,0,0,3,51,49,72,100,72,0,0,3,187,238,113,0,0,0,0,38,98,49,68,100, -72,0,0,6,190,231,57,16,0,0,34,187,238,33,68,100,72,0,0,34,190,119,57,16,0,0,43, -119,119,114,100,101,72,0,2,194,231,115,145,16,2,32,1,23,119,114,100,70,136,2,34, -194,231,57,145,0,44,16,51,49,19,114,68,134,85,2,204,207,147,153,145,2,193,3,51, -27,51,50,72,100,72,0,17,204,169,34,209,26,16,0,1,179,50,33,70,68,72,0,0,17,207, -82,37,173,16,0,0,17,38,98,86,164,72,0,0,0,17,26,85,33,98,0,1,170,85,82,72,106, -72,0,0,0,0,1,90,93,22,17,31,165,85,34,68,134,88,0,51,102,0,29,42,166,221,42,250, -85,34,33,68,72,101,3,187,183,17,204,246,250,82,255,85,82,45,210,100,70,72,3,190, -121,111,245,95,207,255,165,85,45,17,18,100,70,72,59,183,115,146,93,223,204,165, -85,45,17,119,114,68,72,101,59,231,115,146,209,165,44,109,17,29,42,17,50,68,134, -88,110,119,57,157,218,93,198,209,17,1,29,165,18,72,106,72,30,115,57,157,170,34, -198,17,145,0,49,37,82,86,164,72,1,51,153,37,93,28,81,41,16,3,49,210,82,70,68,72, -0,25,34,121,17,28,33,17,0,0,51,29,34,72,100,72,0,1,119,57,16,26,33,0,0,3,54,177, -34,68,134,85,0,1,115,145,16,21,16,0,3,54,107,18,82,100,70,136,0,0,17,17,2,25,18, -0,0,43,231,21,82,100,101,72,0,0,0,0,33,123,113,32,0,2,35,49,82,68,100,72,0,0,0, -0,27,238,121,16,0,0,49,17,18,68,100,72,0,0,0,0,30,231,57,16,0,51,51,51,50,72, -100,72,0,0,0,0,30,115,145,16,0,0,51,48,0,17,26,72,0,0,0,0,1,57,17,0,0,3,48,0,0, -0,1,17,0,0,0,0,0,17,16,0,0,0,0,0,0,0,0,0 -, // 6, finish -175,3,4,0,5,1,2,6,50,7,198,209,48,42,44,49,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,51,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,147,3,51,51,51,51,51, -51,51,51,51,51,51,51,51,54,115,3,153,153,153,34,153,153,146,41,153,153,34,153, -153,153,115,3,119,119,119,34,119,119,114,39,119,119,34,119,119,119,67,3,68,68, -71,119,119,119,119,119,119,119,119,119,119,119,67,3,68,68,71,34,34,34,34,34,34, -34,34,34,34,34,67,53,85,85,71,40,136,136,136,136,136,136,136,136,129,68,115,49, -170,165,36,43,204,204,95,102,102,102,102,102,97,71,115,49,170,165,36,43,204,197, -246,102,102,102,102,102,97,65,67,49,161,165,36,43,187,255,216,136,136,136,136, -136,129,65,67,49,17,21,36,43,187,253,136,136,136,136,136,136,129,65,67,49,161, -165,36,43,187,253,136,136,136,136,136,136,129,65,67,49,26,21,36,43,102,129,17, -17,17,17,17,17,17,65,67,49,161,165,18,43,102,129,17,17,17,17,17,17,17,65,67,49, -17,21,18,43,102,129,17,17,17,17,17,17,17,65,67,49,170,165,18,43,17,34,34,34,34, -34,34,34,33,65,67,49,17,21,18,43,17,34,34,34,34,34,34,34,33,65,67,49,161,21,18, -43,18,68,68,68,68,68,68,68,65,65,67,49,170,165,142,43,18,68,68,68,68,68,68,68, -65,65,67,49,161,21,142,43,18,119,119,119,119,119,119,119,113,85,83,53,85,85,142, -38,18,68,68,68,68,68,68,68,65,245,83,3,102,102,97,34,34,34,34,34,34,34,34,34,33, -255,99,3,102,102,97,85,85,85,85,85,85,85,85,85,85,85,99,3,102,102,102,17,102, -102,97,22,102,102,17,102,102,102,99,3,85,85,85,17,85,85,81,21,85,85,17,85,85,86, -99,3,51,51,51,51,51,51,51,51,51,51,51,51,51,53,83,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, -83,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0 -, // 7, teleport -175,0,151,6,3,143,5,4,134,53,55,2,127,63,45,54,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,17,16,0,0,1,17,0,0,1,17,17,16,0,0,0,1,183,177,0,0,27,123,16,0,18,33,18, -33,0,0,0,1,86,113,0,0,21,103,16,0,18,123,27,177,0,0,0,1,86,113,0,0,21,103,17,17, -18,55,183,113,0,1,17,17,68,65,176,11,20,68,67,51,123,51,182,97,0,20,51,51,51,51, -17,17,51,51,54,37,17,99,118,97,0,19,100,68,34,86,51,51,101,34,41,204,145,68,71, -113,0,19,68,68,34,34,34,37,82,34,124,136,155,68,68,65,0,19,221,37,82,40,130,34, -130,85,142,232,235,151,116,65,0,19,68,40,130,85,85,88,200,204,206,233,235,244, -75,177,0,19,69,172,205,165,34,34,85,136,204,136,228,254,70,116,0,19,68,172,202, -170,221,34,85,34,233,153,148,249,70,116,0,19,74,172,205,170,210,34,85,34,238, -153,151,249,70,116,0,19,74,170,221,170,210,34,85,37,140,136,151,249,118,116,0, -19,173,221,210,85,34,37,88,136,200,233,151,249,230,116,0,19,77,221,210,88,34,85, -136,136,200,153,158,249,230,116,0,19,68,221,221,218,34,34,85,37,136,136,158,249, -230,116,0,19,69,221,221,218,210,34,130,34,156,201,151,249,118,116,0,19,68,90, -170,170,173,34,130,34,156,201,151,249,118,116,0,19,170,74,221,213,130,37,85,136, -140,204,151,249,70,116,0,19,90,88,34,37,82,89,137,156,204,238,158,244,68,177,0, -19,165,40,34,34,130,37,130,85,94,232,155,246,51,49,0,19,68,68,34,34,34,34,85,34, -200,85,155,147,54,49,0,19,100,68,34,86,51,51,101,34,44,153,155,99,118,97,0,20, -51,51,51,51,17,17,51,51,54,85,113,115,118,97,0,1,17,17,68,65,176,11,20,68,67,51, -228,99,182,97,0,0,0,1,86,113,0,0,21,103,17,17,23,54,182,113,0,0,0,1,86,113,0,0, -21,103,16,0,18,107,23,113,0,0,0,1,183,177,0,0,27,123,16,0,18,33,18,33,0,0,0,0, -17,16,0,0,1,17,0,0,1,17,17,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -, // 8, computer terminal -175,0,1,85,5,4,23,6,9,26,80,65,2,84,161,194,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,17,0,1,17,17,17,17,17,17,0,1,16,0,0,0,1,116,0,22,101,101,102,102,102, -101,16,1,65,0,0,238,225,117,1,99,53,53,51,51,51,53,187,27,75,17,17,238,17,69,22, -60,129,17,17,17,17,139,83,102,74,140,158,233,154,69,22,56,148,68,68,68,73,21,51, -54,74,142,238,51,25,69,22,49,66,34,34,34,36,19,68,54,90,238,141,61,169,69,21, -177,66,242,242,34,36,19,119,54,202,131,51,218,121,69,22,49,66,242,34,34,36,31, -119,54,90,141,216,167,121,69,22,49,66,242,242,34,36,131,119,54,202,17,138,119, -73,69,22,49,66,242,34,34,36,207,119,54,90,87,119,68,89,69,22,49,66,242,34,34,36, -195,119,54,90,148,68,85,89,69,22,49,66,34,34,34,36,195,119,54,90,181,85,85,89, -69,22,49,79,255,255,255,244,195,119,54,202,185,153,149,89,69,22,49,66,34,34,34, -36,195,119,54,90,185,153,153,153,69,22,49,66,34,34,34,36,140,119,54,90,17,138, -187,153,85,22,49,66,34,34,34,36,19,119,54,202,141,216,171,187,69,21,177,66,34, -34,34,36,28,119,54,90,131,51,218,187,85,22,49,66,34,34,34,36,19,68,54,90,133,85, -93,171,149,22,56,148,68,68,68,73,21,51,54,74,141,221,93,27,89,22,60,129,17,17, -17,17,139,83,54,74,136,136,136,138,149,1,51,60,60,51,51,51,53,187,27,75,17,17, -17,17,153,0,24,140,140,136,136,136,136,16,1,65,0,0,0,1,153,0,1,17,17,17,17,17, -17,0,1,16,0,0,0,1,187,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0 -, // 9, column -175,2,4,3,5,48,6,63,51,7,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,65,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,20,65,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,73,16,0,0,0,0,0,0,0, -0,0,0,0,0,1,148,38,145,16,0,0,16,0,0,0,1,0,0,0,1,22,146,36,105,145,17,17,33,17, -17,17,23,17,17,17,25,150,98,36,102,67,119,119,41,121,150,102,103,119,118,121,54, -150,98,36,70,67,68,71,36,68,68,68,71,66,119,119,57,70,66,50,68,67,36,68,40,68, -68,67,34,66,36,68,52,36,66,34,34,35,51,51,40,34,50,40,34,35,50,34,52,36,66,50, -34,33,49,129,40,35,131,49,50,35,50,50,20,36,66,35,34,33,17,17,40,129,51,49,18, -51,50,131,18,36,34,51,51,49,17,24,33,19,51,17,50,56,51,131,18,34,66,50,51,49,26, -161,33,51,17,19,50,17,51,19,19,50,51,51,19,49,170,161,35,17,17,17,18,51,19,19, -19,50,35,49,19,17,161,168,34,130,35,56,34,34,33,131,17,34,33,49,50,53,85,85,37, -85,85,85,82,85,85,85,82,67,49,17,42,160,0,0,16,0,0,0,1,0,0,0,10,162,33,19,160,0, -0,0,0,0,0,0,0,0,0,0,0,10,33,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,17,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,17,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -, // 10, ruin -175,5,4,3,50,153,2,75,12,6,13,21,240,17,74,83,0,0,0,0,0,0,0,5,0,0,0,9,25,56,18, -19,0,0,0,0,0,0,0,5,0,0,0,145,34,162,56,35,0,0,0,0,0,0,0,117,0,0,0,18,19,49,35, -50,0,0,0,0,119,87,116,69,119,87,82,25,34,51,50,162,0,0,0,5,84,84,84,84,84,85,69, -154,34,34,51,34,0,0,0,0,0,0,0,117,0,0,2,145,33,177,19,50,0,0,0,0,0,0,0,236,0,0, -153,17,17,18,34,51,0,0,0,0,0,0,0,204,0,9,155,17,177,17,17,19,0,0,0,0,0,0,0,236, -0,9,17,17,34,17,17,131,0,0,0,0,0,0,17,17,17,17,17,17,161,17,17,38,0,0,0,0,0,1, -17,35,51,17,177,17,17,17,19,99,0,0,0,0,0,1,19,35,57,33,17,17,18,177,35,102,0,0, -0,0,0,2,24,51,17,17,17,18,17,17,54,102,0,0,0,7,119,124,34,56,33,177,17,27,18,18, -102,214,0,0,0,119,84,92,19,50,33,18,33,17,17,40,99,51,0,0,119,117,0,4,19,51,161, -17,17,17,27,54,70,111,0,0,0,0,0,3,35,67,49,177,33,17,18,99,18,34,0,0,0,0,0,0,34, -51,52,50,34,162,38,49,161,130,0,0,0,0,0,0,65,34,130,68,50,18,131,34,17,33,0,0,0, -0,0,0,49,35,34,52,72,34,99,18,18,42,0,0,0,0,0,0,66,35,35,56,68,214,49,34,33,34, -0,0,7,119,71,71,193,51,50,51,34,70,50,18,162,33,0,0,0,85,84,84,65,35,131,50,132, -70,33,18,34,34,0,0,0,0,0,0,49,35,51,51,52,70,34,35,51,50,0,0,0,0,0,0,51,52,68, -67,68,46,131,51,51,51,0,0,0,0,0,0,244,68,221,77,221,34,102,102,54,109,0,0,0,0,0, -0,0,7,80,0,6,18,35,238,102,102,0,0,0,0,0,0,0,7,80,0,3,18,34,243,51,230,0,0,0,0, -0,84,68,71,84,119,117,146,34,40,51,246,0,0,0,0,0,0,68,85,85,85,67,18,35,35,34, -52,0,0,0,0,0,0,0,5,80,0,0,51,51,51,51,51,0,0,0,0,0,0,0,5,0,0,0,0,51,50,51,35 -, // 11, lamp -175,0,49,31,7,106,27,28,107,3,4,105,1,2,26,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,220,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,220, -16,0,0,0,0,0,0,0,0,0,0,0,0,0,29,220,193,0,0,0,0,0,0,0,0,0,0,0,0,0,22,220,91,0,0, -0,0,0,0,0,0,17,0,1,16,85,103,146,88,85,0,0,0,0,0,0,1,33,0,22,133,51,103,146,232, -51,80,0,0,0,0,0,1,33,17,215,131,51,103,146,248,67,80,0,0,1,16,0,25,33,28,103, -132,68,103,146,248,68,59,187,177,26,33,17,153,33,28,119,132,68,231,98,232,68,55, -119,226,42,34,34,153,33,28,167,132,68,103,111,104,68,59,187,177,26,33,17,169,33, -17,167,131,51,119,98,136,67,80,0,0,1,16,0,26,33,0,23,85,51,119,111,230,51,80,0, -0,0,0,0,1,33,0,1,16,85,119,146,230,85,0,0,0,0,0,0,1,33,0,0,0,0,26,146,97,0,0,0, -0,0,0,0,0,17,0,0,0,0,26,162,241,0,0,0,0,0,0,0,0,0,0,0,0,0,1,175,16,0,0,0,0,0,0, -0,0,0,0,0,0,0,1,162,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -, // 12, access card -175,0,21,45,44,23,46,2,19,34,69,22,68,60,131,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,17,17,17,17,17,17,0,0,0,0,0,0,0,0,1, -68,17,24,102,101,86,97,0,0,0,0,0,0,0,0,1,68,17,24,102,85,86,101,16,0,0,0,0,0,0, -0,1,67,17,24,101,85,86,101,183,16,0,0,0,0,0,0,1,51,17,24,85,85,102,59,178,16,0, -0,0,0,0,0,1,51,17,24,85,86,232,219,34,240,0,0,0,0,0,0,1,51,17,24,85,86,131,130, -34,240,0,0,0,0,0,0,1,51,17,24,85,102,52,114,34,16,0,0,0,0,0,0,1,54,17,24,86,99, -56,66,34,16,0,0,0,0,0,0,1,102,17,24,86,51,141,114,34,16,0,0,0,0,0,0,1,101,17,24, -102,51,211,114,34,16,0,0,0,0,0,0,1,101,17,24,99,51,55,114,34,16,0,0,0,0,0,0,1, -85,17,24,51,51,119,226,34,16,0,0,0,0,0,0,1,85,17,24,51,52,71,34,34,16,0,0,0,0,0, -0,1,85,17,24,51,52,119,130,34,16,0,0,0,0,0,0,1,85,17,24,51,68,228,114,34,16,0,0, -0,0,0,0,1,85,17,24,52,68,66,34,34,16,0,0,0,0,0,0,1,86,17,25,52,68,66,34,34,16,0, -0,0,0,0,0,1,86,17,23,68,68,34,34,34,16,0,0,0,0,0,0,1,102,17,23,68,68,34,34,34, -16,0,0,0,0,0,0,1,99,17,23,68,153,153,114,34,16,0,0,0,0,0,0,1,99,17,23,68,154, -170,114,34,16,0,0,0,0,0,0,1,51,17,23,68,154,204,114,34,16,0,0,0,0,0,0,1,51,17, -23,68,154,204,114,34,16,0,0,0,0,0,0,1,51,17,23,68,151,119,114,34,16,0,0,0,0,0,0, -1,51,17,23,66,130,34,130,34,16,0,0,0,0,0,0,1,51,17,23,66,130,34,130,34,16,0,0,0, -0,0,0,0,17,17,17,17,17,17,17,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0 -}; - -SFG_PROGRAM_MEMORY uint8_t SFG_backgroundImages[3 * SFG_TEXTURE_STORE_SIZE] = -{ -// 0, city -64,10,73,168,19,12,14,13,80,1,72,101,0,100,136,57,17,17,17,68,87,119,119,119, -118,8,0,32,0,46,34,154,17,17,20,85,84,85,119,118,102,96,0,130,130,2,34,154,17, -17,20,65,68,69,119,102,99,48,48,0,2,32,34,154,17,17,17,17,68,68,87,118,102,102, -104,0,2,14,34,154,17,17,17,20,69,69,51,51,0,8,0,224,2,32,34,154,17,17,17,20,85, -87,60,204,195,51,0,0,0,2,34,154,17,17,17,68,85,119,252,204,51,224,48,0,0,32,34, -154,17,17,17,68,85,119,51,51,48,3,0,0,130,34,34,154,17,17,68,68,85,119,119,102, -102,104,48,40,32,32,34,154,17,17,20,69,87,119,119,102,102,102,128,128,0,2,34, -154,17,17,17,69,87,51,51,51,0,8,48,40,32,32,34,154,17,17,17,20,87,60,252,252, -243,51,0,0,128,2,34,154,65,17,17,20,85,60,204,204,51,48,48,0,32,32,34,154,17,17, -17,68,85,51,63,51,48,51,8,130,130,2,34,154,17,17,20,69,103,181,85,86,102,0,56,0, -0,46,34,154,17,17,17,69,85,187,85,91,102,3,15,0,0,2,34,154,17,17,17,68,85,187, -51,51,0,8,8,0,0,32,34,154,17,17,17,68,77,187,51,51,48,0,142,0,0,2,34,154,17,17, -17,68,77,219,51,51,0,8,48,0,0,32,34,154,17,17,65,69,51,51,60,204,195,51,224,0,0, -2,34,154,17,17,68,69,63,239,204,204,51,48,224,0,0,32,34,154,17,17,71,69,51,51, -51,51,48,240,136,128,14,2,34,154,68,17,71,68,85,221,187,219,176,8,48,40,32,46, -34,154,17,17,20,68,69,93,219,211,48,0,0,0,0,2,34,154,17,17,68,68,77,219,221,211, -0,8,48,0,224,32,34,154,65,20,69,85,84,219,221,179,48,0,136,128,0,2,34,154,17,68, -69,85,119,123,221,219,182,104,8,32,0,32,34,154,17,17,68,69,87,107,221,187,102, -102,102,128,0,2,34,154,17,17,20,85,87,107,219,190,0,8,8,0,0,32,34,154,17,17,20, -84,86,107,182,102,102,3,224,0,2,2,34,154,17,17,20,68,71,103,118,110,0,8,0,40,34, -32,34,154,17,17,17,68,71,102,103,102,102,102,104,128,0,2,34,154 -, // 1, reddish scifi interior -168,18,17,19,65,153,1,9,152,232,0,45,61,80,96,160,18,114,34,34,34,34,34,80,0,0, -0,0,0,0,0,0,18,114,34,34,34,34,34,80,0,0,0,0,0,0,0,0,0,215,34,34,34,34,34,80,0, -0,0,0,0,0,0,0,0,119,34,34,34,34,34,80,0,0,0,0,0,0,0,0,0,214,34,34,34,34,34,34, -32,0,0,0,0,0,0,0,0,118,34,34,34,34,34,34,36,69,0,0,0,0,0,0,18,118,17,17,17,17, -17,17,20,69,0,0,0,0,0,0,18,118,17,17,17,17,17,17,20,69,0,0,0,0,0,0,18,118,114, -34,34,34,34,34,116,69,0,0,0,0,0,0,18,118,130,34,34,38,0,0,0,0,0,0,0,0,0,0,18, -118,135,34,34,34,0,0,0,0,0,0,0,0,0,0,85,86,138,34,34,34,34,41,133,0,0,0,0,0,0,0, -0,86,138,17,17,17,17,25,133,85,0,0,0,0,0,0,0,86,138,17,17,17,27,25,132,70,0,0,0, -0,0,0,0,85,85,85,17,17,17,25,132,70,0,0,0,0,0,0,0,0,0,5,17,17,17,25,132,70,0,0, -0,0,0,0,0,0,0,5,17,27,17,25,132,70,0,0,0,0,0,0,0,6,128,17,17,17,17,25,132,70,0, -0,0,0,0,0,16,118,128,17,17,27,17,25,246,0,0,0,0,0,0,0,16,118,128,17,17,17,17,25, -132,0,0,0,0,0,0,0,16,118,128,51,51,51,51,57,246,0,0,0,0,0,0,0,16,118,130,51,51, -51,51,50,132,0,0,0,0,0,0,0,16,118,130,51,51,51,51,50,132,0,0,0,0,0,0,0,16,118, -131,51,51,51,51,51,132,70,0,0,0,0,0,0,0,0,5,60,51,51,51,51,36,70,0,0,0,0,0,0,0, -0,5,51,51,51,51,51,36,70,0,0,0,0,0,0,0,14,229,51,51,51,51,51,52,70,0,0,0,0,0,0, -85,85,51,195,51,51,51,51,52,64,0,0,0,0,0,0,18,114,17,17,17,17,17,17,18,64,0,0,0, -0,0,0,18,113,17,17,17,17,17,17,17,64,0,0,0,0,0,0,18,115,51,51,51,51,51,80,0,0,0, -0,0,0,0,0,18,115,51,51,51,51,51,80,0,0,0,0,0,0,0,0 -, // 2, red city at night -171,1,175,90,172,174,173,25,27,30,91,103,0,0,0,0,113,23,113,17,51,68,68,102,102, -85,82,34,34,34,38,49,113,23,113,17,51,68,68,102,102,85,82,34,34,34,35,51,113,0, -0,0,0,0,0,0,68,69,85,19,4,101,166,17,113,0,0,4,68,102,102,85,85,81,17,19,4,101, -38,54,113,0,0,4,68,102,102,85,85,81,17,19,4,101,38,51,113,0,0,4,68,102,102,85, -85,82,33,19,4,101,34,49,113,0,0,0,0,0,0,0,4,69,81,19,4,101,42,17,119,17,17,17, -17,0,4,68,102,85,85,35,4,101,42,51,135,17,17,51,51,51,0,0,0,0,68,83,4,101,34,17, -152,113,17,59,51,48,0,4,68,102,85,19,4,101,34,83,152,113,17,51,51,48,0,4,68,17, -17,19,4,101,42,51,135,113,17,51,51,48,0,4,68,17,17,19,4,101,164,17,119,17,17,59, -51,48,0,4,68,102,82,19,4,101,165,17,119,17,17,51,51,51,0,0,0,0,69,85,85,34,37, -51,119,113,17,17,17,16,4,68,102,101,82,37,85,34,34,102,119,119,17,19,51,0,4,70, -102,85,34,37,85,34,34,34,119,119,17,17,17,0,4,70,101,85,34,37,85,34,34,34,119, -17,17,17,17,16,4,70,101,82,38,17,48,70,51,34,113,16,0,0,0,0,0,0,102,102,33,17, -48,67,50,38,17,16,176,176,0,4,68,102,101,82,33,17,48,17,51,51,113,16,0,0,0,4,68, -102,101,82,33,17,48,17,51,50,113,16,0,0,0,4,68,102,101,82,38,17,48,17,51,51,135, -17,17,17,17,16,0,0,0,82,34,34,34,35,50,34,136,113,17,17,17,19,0,0,70,85,85,34, -34,36,51,36,136,113,17,16,0,3,48,0,0,0,68,102,82,36,17,17,152,135,17,16,0,0,51, -0,4,68,85,85,34,33,17,22,153,135,17,16,0,0,0,0,0,0,68,102,82,37,17,17,153,135, -17,17,17,16,0,68,70,101,1,19,4,101,81,34,152,119,16,0,0,0,4,68,64,17,17,19,4, -101,34,36,152,119,16,0,0,0,0,68,70,101,1,19,4,101,35,51,135,119,16,0,0,0,0,4,70, -101,85,34,34,34,35,54,119,23,16,0,0,0,0,0,0,4,69,82,34,34,35,51 -}; - -SFG_PROGRAM_MEMORY uint8_t SFG_weaponImages[6 * SFG_TEXTURE_STORE_SIZE] = -{ -// 0, knife -175,5,4,2,0,3,6,1,61,83,85,60,63,77,40,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,68,68,0,0,0,0,0,0,0,0,0,0,0,0,0,4,97,163,64,0,0,0,0,0,0,0,0,0,0,0,0,4,106,169, -64,0,0,0,0,0,0,0,0,0,0,0,0,4,26,217,64,0,0,0,0,0,0,0,0,0,0,0,0,0,74,147,64,0,0, -0,0,0,0,0,0,0,0,5,85,85,57,147,116,0,0,0,0,0,0,0,0,5,85,86,108,136,61,153,116,0, -0,0,0,0,0,0,85,88,102,102,102,136,49,148,68,68,0,0,0,0,0,88,17,102,204,102,102, -136,54,227,83,52,0,0,0,0,85,34,17,102,102,111,246,24,118,114,34,34,0,0,0,85,17, -34,22,111,108,97,17,18,118,114,53,83,0,0,85,17,22,17,17,34,34,37,85,87,113,117, -51,83,0,5,17,22,24,130,34,17,17,24,27,37,114,51,51,83,0,81,22,98,187,184,17,102, -97,17,34,37,114,51,51,51,5,17,104,187,34,134,102,102,102,18,33,37,121,51,51,51, -5,22,139,130,40,24,140,204,129,34,17,37,121,115,115,119,81,17,85,82,82,33,28,97, -17,34,34,37,125,119,115,119,51,51,52,116,68,68,49,33,21,34,82,37,125,55,119,119, -0,0,0,0,0,0,3,65,35,43,226,37,125,151,71,119,0,0,0,0,0,0,0,3,126,35,69,37,58, -147,116,68,0,0,0,0,0,0,0,0,14,52,4,87,61,147,116,0,0,0,0,0,0,0,0,0,0,0,14,68,57, -147,64,0,0,0,0,0,0,0,0,0,0,0,0,0,74,147,64,0,0,0,0,0,0,0,0,0,0,0,0,4,26,217,64, -0,0,0,0,0,0,0,0,0,0,0,0,4,170,167,64,0,0,0,0,0,0,0,0,0,0,0,0,4,157,167,64,0,0,0, -0,0,0,0,0,0,0,0,0,0,68,68,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0 -, // 1, shotgun -175,3,4,54,5,17,2,1,7,101,100,99,25,98,9,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,119,119, -0,0,0,0,0,0,0,0,0,0,0,0,102,103,91,170,0,0,0,0,0,0,0,0,0,0,1,22,67,45,186,153,0, -0,0,0,0,0,0,0,1,17,20,50,52,218,153,74,0,0,0,0,0,0,0,17,18,35,136,55,20,218,153, -75,0,0,0,0,0,17,17,68,72,131,51,71,20,91,169,170,0,0,0,0,17,52,51,136,51,35,136, -35,52,93,187,180,0,0,0,1,51,19,131,56,130,67,50,36,66,91,186,148,0,0,0,19,51,19, -136,136,50,36,17,71,18,93,186,154,0,0,0,24,134,56,131,52,68,17,194,39,18,85,219, -187,0,0,6,51,54,51,52,68,66,34,34,34,34,21,255,185,0,0,6,51,50,50,34,34,34,33, -17,17,23,28,93,169,0,0,87,114,34,98,17,17,17,17,17,17,23,28,85,169,0,9,188,231, -21,97,81,85,85,85,92,92,197,197,87,218,0,5,85,206,236,229,85,85,117,117,119,119, -119,199,119,221,0,0,7,204,193,17,17,17,17,17,17,17,17,252,87,218,0,5,85,204,202, -170,169,153,153,153,153,153,170,170,87,169,0,9,188,199,34,193,17,17,17,17,17,17, -23,17,85,169,0,0,87,115,50,35,51,136,51,52,68,34,39,17,91,153,0,0,6,136,134,56, -136,136,136,131,51,136,136,65,219,185,0,0,6,51,54,67,51,51,131,56,136,55,24,77, -186,187,0,0,0,98,38,35,68,68,51,34,35,55,20,45,169,148,0,0,0,100,68,100,34,34, -44,18,17,67,52,219,153,68,0,0,0,6,68,34,34,18,38,97,28,98,34,219,171,186,0,0,0, -0,102,17,68,33,17,108,17,103,17,91,219,171,0,0,0,0,0,102,102,20,68,34,33,103,22, -93,186,154,0,0,0,0,0,0,0,102,98,34,68,70,22,91,186,153,0,0,0,0,0,0,0,0,6,102,98, -44,38,93,186,153,0,0,0,0,0,0,0,0,0,0,6,102,34,101,219,153,0,0,0,0,0,0,0,0,0,0,0, -0,102,103,95,170,0,0,0,0,0,0,0,0,0,0,0,0,0,0,119,119,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0 -, // 2, machine gun -175,2,4,3,1,5,6,0,60,59,50,53,61,62,74,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,20,68,64,0,0,0,0,0,0,0,0,0,0,0,17,34,51,17,20,0, -0,0,0,0,0,0,0,0,0,1,98,17,17,68,71,65,17,16,0,0,0,0,0,0,0,22,33,17,20,68,70,102, -35,167,0,0,0,0,0,0,0,22,33,20,68,97,22,98,50,228,0,0,0,0,0,0,0,118,52,70,17,102, -102,34,34,20,0,0,0,0,0,0,7,51,17,22,102,102,101,37,35,20,0,0,0,0,0,0,22,102,22, -34,82,140,178,34,49,20,0,0,0,0,0,1,82,34,51,50,34,43,178,51,161,68,0,0,0,0,17, -17,34,35,51,152,49,19,51,161,68,68,0,0,1,17,88,83,34,58,19,136,37,37,50,51,133, -85,0,0,22,150,134,99,35,147,50,34,85,85,34,51,34,85,0,0,121,24,56,209,35,51,50, -34,85,82,34,51,34,37,0,0,113,19,18,33,35,51,34,37,85,34,37,51,34,34,0,0,1,119, -49,49,147,38,101,85,85,34,85,51,130,34,0,0,0,0,119,113,147,50,34,86,102,86,98, -161,68,68,0,0,0,0,0,7,25,34,37,85,34,37,195,51,161,68,0,0,0,0,0,0,113,17,17,51, -53,92,131,51,49,20,0,0,0,0,0,0,7,19,20,65,17,17,19,50,51,20,0,0,0,0,0,0,0,118, -20,65,68,17,17,50,35,20,0,0,0,0,0,0,0,22,17,68,68,20,65,19,51,20,0,0,0,0,0,0,0, -22,33,17,68,68,65,17,51,23,0,0,0,0,0,0,0,7,98,49,17,20,119,68,68,64,0,0,0,0,0,0, -0,0,23,34,51,17,20,0,0,0,0,0,0,0,0,0,0,0,0,17,119,119,64,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -, // 3, rocket launcher -175,33,7,39,115,2,0,5,117,116,4,37,114,3,36,108,0,0,0,0,0,0,0,0,0,0,0,0,13,209, -102,0,0,0,0,0,0,0,0,0,0,0,0,221,218,122,85,96,0,0,0,0,0,0,0,0,0,0,13,34,39,165, -51,96,0,0,0,0,0,0,0,0,0,0,5,170,170,165,51,96,0,0,0,0,0,0,0,0,0,0,5,93,221,221, -81,102,0,0,0,0,102,102,16,0,0,0,17,102,102,102,102,204,0,0,0,17,170,173,214,80, -17,17,136,137,198,204,193,206,0,0,93,122,213,81,17,17,136,136,137,68,193,236, -158,238,0,5,170,17,22,20,148,152,148,204,196,153,66,153,136,136,0,90,161,17,100, -68,76,68,76,153,153,137,40,136,136,136,5,163,17,17,73,153,201,153,201,136,139, -190,43,179,51,51,5,58,81,20,136,132,136,132,139,179,55,226,51,51,51,51,13,42,17, -24,187,180,68,68,178,34,34,162,34,34,34,35,215,33,17,72,187,119,114,36,34,34,35, -162,35,51,51,17,211,33,21,131,50,34,34,46,34,34,34,162,34,34,209,51,163,37,85, -131,51,51,34,46,34,34,34,114,34,45,51,119,163,37,85,232,51,51,51,62,51,51,51, -178,51,127,55,187,211,37,85,238,238,238,238,228,136,136,187,226,51,115,123,185, -215,49,81,20,68,68,73,148,153,152,142,146,235,175,251,153,13,58,17,28,68,68,68, -68,68,68,153,67,153,175,123,153,5,122,17,81,204,196,68,68,68,68,68,67,116,175, -123,137,5,119,85,85,97,204,204,204,204,68,68,71,36,223,123,185,0,87,117,85,81, -102,17,17,28,204,204,196,58,211,123,184,0,5,119,165,85,81,102,85,17,17,17,204, -167,211,119,187,0,0,81,122,213,85,85,22,101,85,17,17,74,31,119,187,0,0,0,17,170, -173,214,16,102,102,85,17,17,31,247,119,0,0,0,0,102,102,96,0,0,0,102,102,81,31, -119,119,0,0,0,0,0,0,0,0,0,0,0,0,102,23,123,183,0,0,0,0,0,0,0,0,0,0,0,0,0,109, -123,187,0,0,0,0,0,0,0,0,0,0,0,0,0,97,215,136,0,0,0,0,0,0,0,0,0,0,0,0,0,6,109, -255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,102 -, // 4, plasma gun -175,4,3,6,5,17,50,49,0,187,7,190,37,42,100,209,0,0,0,0,0,0,0,0,0,0,0,0,2,80,1, -17,0,0,0,0,0,0,0,0,0,0,37,0,44,149,26,163,0,0,0,0,0,0,0,2,80,2,198,80,134,106, -163,51,0,0,0,0,0,0,0,44,101,2,194,37,170,170,51,51,0,0,0,0,0,0,2,201,103,88,42, -170,163,51,21,86,0,0,0,0,119,0,2,194,37,170,74,51,52,85,102,17,0,0,0,34,68,112, -40,42,170,172,67,51,70,33,17,17,0,0,34,52,68,130,74,164,51,196,51,51,110,17,18, -85,0,2,51,66,136,170,67,51,68,67,51,52,81,17,37,51,0,42,52,119,170,68,51,51,51, -51,51,66,17,18,68,68,2,163,55,42,163,51,52,66,221,85,93,33,17,68,17,153,2,119, -119,118,102,102,98,33,17,18,17,18,20,73,187,187,42,52,17,17,17,17,17,17,17,17, -33,17,36,155,149,136,36,18,119,117,86,97,20,68,68,68,36,68,33,185,83,67,35,68, -65,39,150,150,22,22,145,105,22,145,27,181,51,20,35,68,17,39,185,185,185,185,187, -155,185,187,187,182,52,20,35,65,18,39,150,150,22,22,145,105,22,145,27,182,68,20, -33,34,119,117,86,97,20,68,68,68,36,68,33,185,97,33,36,17,19,51,51,51,51,51,51, -51,35,51,36,155,150,88,2,119,118,102,102,102,34,36,68,50,51,50,52,73,187,187,2, -17,39,33,17,17,17,18,101,101,85,99,51,68,17,153,0,34,18,117,34,34,17,17,17,17, -17,229,51,50,68,68,0,7,34,34,88,119,114,17,119,209,17,17,83,51,37,51,0,0,119,34, -39,136,247,47,34,45,17,17,110,51,50,85,0,0,0,119,119,128,136,85,119,34,114,33, -22,228,51,51,0,0,0,0,136,0,8,198,87,117,242,34,33,102,85,67,0,0,0,0,0,0,8,201, -101,136,85,82,34,34,34,85,0,0,0,0,0,0,0,140,152,8,201,136,82,34,34,34,0,0,0,0,0, -0,0,8,128,8,198,128,134,101,34,34,0,0,0,0,0,0,0,0,0,0,136,0,140,152,133,85,0,0, -0,0,0,0,0,0,0,0,0,0,8,128,8,136,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -, // 5, solution -6,76,175,48,26,5,4,7,57,77,75,27,58,2,28,68,34,34,34,34,34,34,34,34,45,221,211, -34,35,51,50,51,34,34,34,51,51,34,34,34,55,7,119,50,48,6,67,21,34,34,51,69,86,51, -56,45,112,87,119,3,8,136,68,161,34,34,53,102,70,102,68,215,0,87,7,102,131,173, -133,170,34,34,48,182,68,70,103,112,0,231,0,100,134,108,218,90,34,34,48,96,181, -68,112,0,0,231,0,84,134,119,74,165,34,34,53,176,96,183,0,0,5,21,80,4,77,7,124, -170,34,51,53,70,102,112,0,5,105,145,21,0,70,0,7,202,51,85,104,136,71,0,0,97,17, -153,17,85,0,0,0,124,48,70,102,104,135,0,6,17,31,25,17,17,85,0,0,7,48,180,68,70, -103,0,81,17,17,17,153,17,25,80,0,0,48,101,182,68,71,0,81,17,26,17,249,145,17,23, -0,5,48,224,96,230,71,0,101,17,17,17,25,145,17,23,0,92,53,176,224,96,71,0,105,81, -250,241,241,153,17,23,0,202,51,54,70,181,64,0,97,150,144,154,15,153,17,23,0,198, -34,35,68,68,64,5,97,31,127,122,122,25,145,16,85,134,34,35,56,136,128,0,97,31,1, -15,10,17,145,23,0,134,51,51,68,68,64,0,97,26,145,144,159,17,25,23,0,138,53,102, -70,69,176,0,97,17,169,170,241,17,25,151,0,138,53,176,176,224,183,5,97,17,25,145, -17,17,17,151,0,88,48,224,96,101,183,5,81,17,26,153,241,17,17,112,0,5,53,101,229, -180,135,0,85,17,17,25,145,17,80,0,0,0,53,228,77,136,135,0,5,81,26,25,97,7,5,0,0, -6,51,68,136,132,71,0,0,85,81,17,151,0,0,80,0,76,34,51,133,70,70,112,0,85,5,16, -112,0,102,5,100,204,34,34,53,176,229,71,0,5,80,231,0,5,68,102,76,204,34,34,48, -224,182,68,112,0,85,231,0,6,72,68,204,197,34,34,48,182,68,68,71,112,5,87,0,100, -104,141,220,90,34,34,53,68,68,136,136,55,5,96,5,100,3,173,133,170,34,34,51,136, -136,51,51,35,112,102,100,136,64,136,132,161,34,34,34,51,51,34,34,34,54,102,68, -50,56,100,67,21,34,34,34,34,34,34,34,34,35,51,51,34,35,51,50,51 -}; - -SFG_PROGRAM_MEMORY uint8_t SFG_effectSprites[4 * SFG_TEXTURE_STORE_SIZE] = -{ -// 0, explostion -175,183,174,15,103,111,191,7,31,95,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,48,0,0,0, -0,0,0,0,0,0,0,0,3,3,3,3,19,3,0,0,0,0,0,0,0,0,0,48,48,16,51,49,19,48,48,0,0,0,0, -0,0,0,3,3,1,1,19,17,131,51,49,0,0,0,0,1,16,0,0,48,50,34,20,85,120,49,17,64,0,0, -0,0,65,1,0,0,34,17,69,87,117,17,33,16,0,0,0,0,4,16,16,4,18,17,21,87,85,18,33,16, -0,0,0,1,9,34,34,17,34,17,21,85,85,66,17,48,0,0,0,65,18,34,34,17,65,22,85,86,68, -65,19,51,0,0,48,17,34,34,33,18,65,68,70,68,68,102,67,51,0,1,19,49,34,34,33,18, -36,132,100,70,97,20,81,17,51,48,17,18,34,18,18,34,33,119,85,86,97,33,81,51,48,3, -51,18,33,17,34,33,37,119,85,100,97,18,35,51,0,48,49,34,18,34,33,102,87,119,117, -97,17,34,34,16,48,1,17,18,33,17,22,104,119,119,117,81,18,18,33,67,0,1,65,18,33, -20,71,119,119,119,119,132,65,18,34,64,48,0,69,81,17,86,69,88,119,119,133,81,17, -18,34,147,0,0,56,21,69,86,70,103,119,119,116,17,18,34,34,144,0,3,51,56,86,102, -102,120,118,101,120,81,34,34,35,0,0,48,51,17,85,102,102,103,70,102,136,85,34,34, -17,0,0,3,49,19,53,84,102,100,70,102,88,133,84,66,17,19,0,48,51,51,85,68,102,68, -102,102,101,97,33,68,19,17,48,3,3,49,81,36,84,17,70,101,82,33,18,33,67,51,0,0, -51,49,17,33,33,33,70,102,66,34,34,34,17,51,48,0,3,17,18,34,33,34,20,129,18,34, -34,34,34,51,0,0,49,17,34,33,17,17,33,65,34,34,17,18,34,19,48,0,1,18,33,17,17,17, -34,34,33,145,17,18,34,19,48,0,1,17,17,19,49,49,18,17,49,19,49,18,34,35,51,0,0, -17,51,51,17,49,18,19,3,19,51,17,17,36,3,0,3,51,51,48,48,3,17,16,48,17,3,51,17, -16,0,0,3,48,3,3,0,0,16,19,0,0,0,51,51,0,0,0,51,0,0,0,0,0,1,3,48,0,51,51,48,0,0 -, // 1, fireball -175,103,183,7,191,111,254,31,95,180,173,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,0,16,0,0,0,0, -0,0,0,0,0,0,1,1,23,17,17,24,1,0,0,0,0,0,0,0,0,0,16,16,23,85,87,81,24,16,0,0,0,0, -0,0,0,1,8,17,119,115,55,119,17,129,16,0,0,0,0,0,0,0,129,23,119,51,51,55,113,24, -23,0,0,0,0,0,0,8,17,17,113,83,51,85,119,23,113,0,0,0,0,0,0,1,21,113,81,19,53,81, -17,119,129,0,0,0,0,0,0,17,19,53,17,19,50,17,17,113,16,16,0,0,0,0,1,33,83,49,17, -19,66,34,17,17,18,0,0,0,0,0,0,33,85,53,21,19,18,34,34,24,18,16,0,0,0,0,1,33,85, -85,84,68,20,34,35,66,98,0,0,0,0,0,0,33,83,53,20,68,51,51,51,70,34,16,0,0,0,0,1, -33,19,49,66,36,67,52,41,40,98,0,0,0,0,0,0,33,19,84,34,36,36,70,38,134,34,0,0,0, -0,0,0,8,21,81,18,36,66,98,102,166,32,0,0,0,0,0,0,2,21,81,18,68,68,38,134,105,33, -0,0,0,0,0,0,0,18,33,18,68,51,73,102,98,16,0,0,0,0,0,0,0,18,18,34,68,51,74,102, -102,16,0,0,0,0,0,0,0,1,17,18,34,36,38,38,129,0,0,0,0,0,0,0,0,0,8,134,38,34,34, -104,0,0,0,0,0,0,0,0,0,0,0,2,34,102,96,16,0,0,0,0,0,0,0,0,0,0,0,0,1,16,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0 -, // 2, plasma -175,199,126,213,198,215,118,46,125,204,124,134,45,117,135,116,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,1,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,68,16,0,0,0,0,0,0,0,0,0,0,16, -1,17,20,17,16,16,16,0,0,0,0,0,0,0,17,18,7,113,20,17,119,1,1,0,0,0,0,0,0,1,17,65, -16,34,67,50,33,17,16,0,0,0,0,0,0,1,36,34,1,19,153,51,33,65,0,0,0,0,0,0,0,14,37, -34,32,51,57,163,35,50,16,0,0,0,0,0,0,114,37,82,2,17,51,170,51,34,17,0,0,0,0,0,0, -18,51,83,34,17,3,152,138,43,178,16,0,0,0,0,1,20,34,52,83,163,32,123,136,199,34, -17,0,0,0,0,1,17,18,35,51,51,34,18,34,194,36,68,0,0,0,0,0,17,17,104,109,250,51, -18,34,34,51,17,0,0,0,0,1,7,113,34,134,136,34,211,70,34,131,17,0,0,0,0,0,16,34, -34,134,34,34,97,17,102,98,16,0,0,0,0,0,1,18,85,84,17,98,97,33,22,98,1,0,0,0,0,1, -17,37,83,242,68,70,18,146,33,23,16,0,0,0,0,1,50,53,35,134,133,65,39,185,37,17,1, -0,0,0,0,0,19,147,34,136,51,81,39,190,36,65,32,0,0,0,0,0,17,18,34,131,34,83,39,0, -35,34,32,0,0,0,0,1,1,17,34,34,34,57,50,114,49,34,0,0,0,0,0,0,16,17,34,34,83,147, -67,33,64,0,0,0,0,0,0,0,1,2,33,35,81,17,68,68,65,0,0,0,0,0,0,0,0,2,33,21,17,17, -17,17,16,0,0,0,0,0,0,0,0,0,0,20,65,0,1,17,0,0,0,0,0,0,0,0,0,0,0,1,65,16,0,16,0, -0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -, // 3, dust -175,5,3,4,53,2,6,52,50,74,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,2,34,0,0,16, -1,0,0,0,0,0,0,0,0,0,0,34,50,32,3,48,0,0,0,0,0,0,0,0,0,0,2,35,50,16,66,18,0,0,0, -0,0,0,0,1,16,0,2,49,51,4,4,2,82,34,0,0,0,0,0,0,1,16,0,49,49,32,64,18,81,51,32,0, -0,0,0,0,0,0,0,3,22,55,97,18,33,19,48,0,0,0,0,0,0,0,0,0,6,19,50,34,19,17,48,0,0, -0,0,0,0,1,51,17,17,99,35,129,51,50,0,0,0,0,0,0,0,0,1,55,0,7,50,4,34,32,1,0,0,0, -0,0,0,0,3,112,64,2,64,32,98,0,0,0,0,0,0,0,0,0,9,52,4,3,4,4,5,0,0,0,0,0,0,0,0,0, -18,64,34,49,0,32,18,1,16,0,0,0,0,0,0,0,18,34,35,19,32,18,50,0,1,16,0,0,0,0,0,0, -0,37,19,34,136,18,51,16,0,0,0,0,0,0,0,0,0,5,35,49,51,1,0,16,0,0,0,0,0,0,0,0,0,1, -17,19,34,0,0,0,0,0,0,0,0,0,0,0,0,0,34,18,32,0,0,0,0,0,0,0,0,0,0,0,1,0,0,34,0,1, -0,0,0,0,0,0,0,0,0,0,16,0,16,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,16,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -}; - -SFG_PROGRAM_MEMORY uint8_t SFG_monsterSprites[19 * SFG_TEXTURE_STORE_SIZE] = -{ -// 0, spider idle -175,0,4,3,5,6,223,1,7,10,2,20,62,95,120,18,0,1,17,16,0,0,0,0,0,0,0,0,1,17,16,0, -0,20,45,65,0,0,0,0,0,0,0,0,21,52,33,0,1,65,170,20,16,0,0,0,0,0,0,17,133,50,51, -16,1,218,211,162,16,0,0,0,0,0,17,133,84,17,17,17,1,42,61,173,16,1,0,0,0,1,133, -84,33,0,0,0,1,65,170,20,17,1,16,0,1,24,85,73,16,0,0,0,0,20,210,71,119,19,81,0,0, -1,19,146,16,0,0,0,1,115,17,115,115,68,65,0,0,0,1,66,49,0,0,0,20,36,119,41,37,69, -85,16,0,0,1,66,49,17,17,0,18,50,115,21,85,68,68,33,0,1,17,51,133,52,66,16,20,45, -113,28,197,66,66,65,1,24,136,85,85,50,35,49,1,17,37,86,198,196,34,33,0,1,85,85, -68,153,153,145,0,21,85,70,140,102,34,34,16,0,147,57,147,51,35,16,0,17,119,60, -104,102,98,34,46,238,191,66,243,17,17,17,1,57,115,115,38,108,198,34,231,243,187, -116,33,0,0,0,18,49,153,151,34,104,198,62,255,59,180,51,112,0,0,0,18,49,51,55,34, -104,198,62,255,59,180,51,112,0,0,0,1,57,121,115,38,108,198,34,231,243,187,116, -33,0,0,0,0,17,119,60,104,102,98,34,46,238,191,66,147,17,17,17,0,21,85,70,140, -102,34,34,16,0,148,41,147,51,35,16,1,17,37,86,198,196,34,33,0,1,136,136,133,153, -153,145,20,45,113,28,197,66,66,65,1,21,85,85,85,52,66,49,18,50,115,21,85,84,68, -33,0,1,17,51,133,50,35,16,20,36,119,41,37,85,85,16,0,0,1,66,55,17,17,0,1,115,17, -115,115,68,65,0,0,0,1,66,49,0,0,0,0,20,45,71,119,19,81,0,0,1,19,50,16,0,0,0,1, -65,170,20,17,1,16,0,1,24,136,137,16,0,0,0,1,218,61,162,16,1,0,0,0,1,133,85,129, -0,0,0,1,42,211,173,16,0,0,0,0,0,17,69,85,17,17,17,1,65,170,20,16,0,0,0,0,0,0,17, -69,50,35,16,0,20,210,65,0,0,0,0,0,0,0,0,20,50,49,0,0,1,17,16,0,0,0,0,0,0,0,0,1, -17,16,0 -, // 1, spider attacking -175,0,183,3,4,1,191,5,31,6,7,22,10,223,20,18,0,34,37,85,43,176,0,0,0,0,0,0,17, -17,16,0,0,34,98,34,38,102,0,0,0,0,0,1,148,71,65,16,0,2,98,34,102,98,0,0,0,0,0, -89,169,52,51,49,0,2,104,40,102,32,0,0,0,0,5,170,145,17,17,16,2,38,104,136,98,32, -80,0,0,0,90,167,65,0,0,0,2,102,102,102,102,34,85,0,0,5,184,124,16,0,0,0,2,102, -34,34,102,102,232,80,0,91,139,76,16,0,0,0,2,34,46,34,38,102,187,113,0,85,84,196, -49,17,17,0,0,91,235,85,34,107,136,145,0,0,5,115,19,71,116,16,0,94,238,94,88,139, -139,116,80,0,85,58,169,52,67,49,0,23,75,85,91,184,231,71,80,5,170,153,119,60, -204,17,0,1,21,232,141,141,116,68,16,88,137,119,204,195,49,0,0,1,153,136,189,169, -212,68,65,1,195,60,51,51,67,16,0,1,17,85,55,218,221,212,68,85,95,116,243,49,17, -17,0,19,197,51,83,77,217,125,69,95,62,87,65,16,0,0,1,67,49,204,197,68,218,157, -95,243,235,51,80,0,0,0,1,67,193,51,53,68,218,157,95,243,235,51,80,0,0,0,0,19, -197,204,83,77,217,125,69,95,62,87,65,16,0,0,0,1,17,85,55,218,221,212,68,85,95, -116,243,49,17,17,0,1,153,153,125,168,221,68,65,5,51,60,51,51,67,16,0,1,17,232, -141,141,190,68,16,90,170,170,204,195,49,0,0,23,75,85,91,184,235,71,85,5,183,153, -170,60,204,17,0,94,238,94,88,184,187,116,80,0,85,55,153,52,67,49,2,43,235,82,34, -136,136,145,0,0,1,115,19,71,116,16,2,34,82,34,98,46,187,113,0,85,83,196,49,17, -17,0,2,98,34,38,102,44,232,16,0,91,170,124,16,0,0,0,2,102,102,102,98,37,85,0,0, -5,185,172,16,0,0,0,2,38,136,134,34,80,80,0,0,0,88,167,65,0,0,0,0,182,136,134,98, -80,0,0,0,0,5,185,145,17,17,16,0,34,102,102,102,32,0,0,0,0,0,87,153,52,51,49,0,2, -98,34,102,107,0,0,0,0,0,1,116,71,65,16,0,2,37,82,43,32,0,0,0,0,0,0,17,17,16,0 -, // 2, spider walking -175,0,4,5,6,3,223,1,10,7,2,18,62,95,120,63,0,0,17,17,0,0,0,0,0,0,0,1,17,17,0,0, -0,1,50,211,16,0,0,0,0,0,0,21,51,50,16,0,0,19,26,161,49,0,0,0,0,0,17,146,35,33,0, -0,0,29,173,90,33,0,0,0,0,1,148,68,81,16,0,0,0,18,165,218,209,0,16,0,0,25,67,49, -16,0,0,0,0,19,26,161,49,16,17,0,1,148,51,16,0,0,0,0,0,1,61,35,119,113,84,16,25, -68,56,0,0,0,0,0,0,23,81,23,87,83,51,16,17,21,129,0,0,0,0,0,1,50,55,114,130,67, -68,65,0,1,50,16,0,0,0,0,1,37,39,81,68,67,51,50,0,1,85,81,17,17,17,0,1,50,215,17, -204,67,35,35,16,25,153,148,68,83,50,16,0,17,18,68,111,108,50,34,16,1,68,68,68, -82,37,81,0,1,68,67,105,246,98,34,33,0,133,88,136,136,136,129,0,1,23,117,198,150, -102,34,34,238,227,37,181,17,0,0,0,21,135,87,82,102,252,98,46,123,91,50,81,0,0,0, -1,37,24,136,114,38,159,101,235,181,35,181,112,0,0,0,1,37,24,136,114,38,159,101, -235,181,35,181,112,0,0,0,0,21,135,87,82,102,252,98,46,123,83,123,33,0,0,0,0,1, -23,117,198,150,102,34,34,238,235,50,133,17,17,0,0,1,68,67,105,246,98,34,33,0, -131,40,85,85,34,16,0,17,18,68,111,108,50,34,16,1,148,33,17,17,17,0,1,50,215,17, -204,67,35,35,16,25,50,16,0,0,0,0,1,37,39,81,68,67,51,50,17,148,72,136,128,0,0,0, -1,50,55,114,130,67,68,65,20,68,73,148,136,128,0,0,0,23,81,23,87,83,51,16,1,17, -84,68,83,56,129,0,0,1,61,35,119,113,84,16,0,5,21,68,82,34,81,0,0,19,26,161,49, -16,17,0,0,20,66,87,18,37,16,0,0,18,165,218,209,0,16,0,0,1,84,52,65,17,81,17,0, -29,173,90,33,0,0,0,0,0,17,19,52,82,37,16,0,19,26,161,49,0,0,0,0,0,0,1,19,82,81, -0,0,1,50,211,16,0,0,0,0,0,0,0,1,17,16,0,0,0,17,17,0,0,0,0,0,0,0,0,0,0,0,0 -, // 3, destroyer idle -0,175,3,4,5,73,1,6,2,77,157,79,7,78,76,75,17,0,0,0,17,17,17,17,17,17,17,17,17, -17,17,17,17,11,221,219,0,17,17,17,16,0,0,0,0,0,1,17,17,11,217,153,219,1,17,16,2, -119,114,39,116,119,1,17,17,11,189,154,155,1,16,12,194,124,204,204,199,204,1,17, -17,16,189,154,169,176,12,199,116,35,51,51,50,51,1,17,17,17,11,217,170,213,196, -68,67,34,34,34,40,34,0,0,17,16,11,217,154,149,52,50,50,0,0,0,0,0,4,64,17,7,118, -102,138,173,83,68,128,17,17,17,17,7,114,32,16,116,12,66,106,169,181,51,71,0,1, -17,0,115,56,128,16,67,0,102,102,42,213,35,52,71,112,0,119,51,40,128,7,48,194,0, -7,114,171,82,51,68,71,114,83,34,40,128,4,12,204,64,0,71,106,181,131,52,68,71,82, -34,40,80,4,12,199,114,192,36,70,157,184,52,119,116,37,40,133,80,0,204,119,119, -96,4,70,169,213,55,51,55,69,80,102,96,0,102,103,116,44,4,50,106,155,83,157,147, -117,34,0,0,2,9,230,68,32,3,50,106,173,83,57,211,53,34,1,17,2,11,150,68,48,3,50, -106,233,83,57,211,53,34,1,17,0,34,36,67,44,3,50,106,238,83,157,147,37,34,128,0, -0,119,68,67,128,3,54,254,229,34,51,50,53,88,50,32,6,7,68,50,192,131,38,174,245, -35,34,35,37,34,40,128,2,4,68,48,0,50,111,229,82,51,51,50,82,34,40,128,3,32,66,0, -3,38,254,86,130,34,34,34,88,34,40,128,16,50,0,0,0,111,229,104,34,40,133,85,104, -136,40,80,16,51,99,38,105,154,245,130,40,96,82,67,6,102,133,80,17,3,54,102,137, -238,88,134,96,17,7,66,6,0,101,80,17,16,13,187,154,229,102,104,36,0,116,72,128, -17,6,96,17,17,11,186,170,245,96,130,51,71,67,34,32,17,16,0,17,16,187,218,174, -240,5,130,51,51,51,50,80,17,17,17,17,11,189,170,175,1,16,5,34,34,34,80,1,17,17, -17,17,11,221,170,255,1,17,16,85,85,0,1,17,17,17,17,17,11,218,255,0,17,17,17,0,0, -17,17,17,17,17,17,17,0,0,0,17,17,17,17,17,17,17,17,17,17,17,17 -, // 4, destroyer attacking -175,0,3,4,73,1,5,2,183,6,77,157,79,78,7,31,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0, -17,17,17,0,0,0,0,0,136,136,128,0,0,0,0,0,28,221,220,17,0,0,0,8,136,136,128,0,0, -0,0,0,28,218,170,220,16,1,88,136,136,255,136,128,0,0,0,0,28,218,187,172,85,94, -238,136,136,255,136,128,0,0,0,0,28,218,187,187,215,105,255,248,136,136,136,0,0, -0,0,0,1,221,171,187,163,102,255,255,136,136,136,0,0,1,17,0,25,17,85,87,189,38, -99,99,56,136,0,0,17,86,97,1,150,37,230,37,186,195,51,35,56,0,0,17,255,146,33,1, -99,37,85,85,82,211,35,54,98,17,17,249,99,55,113,25,51,94,33,17,153,44,50,51,111, -255,243,70,50,39,113,22,53,238,230,17,22,148,195,115,54,153,159,114,34,39,113, -19,49,238,153,46,18,102,125,151,57,51,57,100,34,39,65,19,94,233,153,149,17,102, -90,215,51,173,163,148,68,116,65,18,21,85,153,98,225,99,37,172,67,58,211,52,39, -69,81,19,33,163,86,98,17,51,37,189,67,58,211,52,34,17,17,18,33,202,86,99,17,51, -37,58,67,173,163,36,34,16,0,19,18,34,102,50,225,51,37,58,66,51,50,52,34,113,17, -18,89,150,102,55,17,51,82,52,35,34,35,36,71,50,33,19,33,150,99,46,23,50,82,36, -35,51,50,116,34,39,113,19,37,102,99,17,19,37,36,66,51,50,39,66,34,39,113,19,34, -22,33,17,50,82,69,114,34,36,68,71,34,39,113,1,50,81,17,85,85,36,87,34,39,66,99, -23,119,39,65,1,51,37,50,87,171,68,21,81,119,25,98,21,85,116,65,0,19,51,85,123, -50,65,87,38,17,150,103,113,17,84,65,0,1,92,202,171,52,81,35,51,105,99,34,33,0, -21,81,0,1,204,219,187,36,20,114,51,51,51,50,65,0,1,17,0,28,205,219,178,65,20, -119,34,34,34,65,16,0,0,0,0,28,205,187,36,16,1,20,68,68,65,16,0,0,0,0,0,28,219, -187,33,0,0,1,17,17,16,0,0,0,0,0,0,28,219,177,16,0,0,0,0,0,0,0,0,0,0,0,0,17,17, -16,0,0,0,0,0,0,0,0,0,0,0,0 -, // 5, destroyer walking -175,0,3,4,1,5,2,73,6,77,79,7,78,157,75,76,0,17,17,17,0,0,0,0,0,0,0,0,0,0,0,0,0, -26,204,202,17,0,0,1,17,17,17,0,0,0,0,0,0,26,201,153,202,16,1,19,136,130,33,17, -17,0,0,0,0,26,172,157,154,16,27,179,40,187,184,133,129,16,0,0,0,1,172,157,217, -161,184,136,50,51,59,184,102,16,0,0,0,0,26,201,221,199,85,85,50,34,35,50,102,16, -0,0,0,1,26,201,157,151,53,35,97,17,18,38,102,16,17,16,0,24,17,68,70,220,115,54, -16,0,1,17,97,17,85,16,1,133,36,181,36,217,167,51,81,17,16,0,17,56,34,16,1,83,36, -68,68,119,199,35,53,88,129,17,136,51,102,16,24,51,75,33,17,136,122,114,51,85,88, -130,115,34,102,16,21,52,187,181,17,21,135,167,99,53,85,88,114,34,102,16,19,49, -187,136,43,18,85,76,214,53,136,133,39,34,103,16,19,75,184,136,132,17,85,73,199, -56,51,56,87,118,119,16,18,20,68,136,82,177,83,36,154,115,156,147,135,33,68,16, -19,33,159,69,82,17,51,36,220,115,57,195,55,34,17,16,18,33,169,69,83,17,51,36, -249,115,57,195,55,34,97,17,19,18,34,85,50,177,51,36,255,115,156,147,39,38,50,33, -18,72,133,85,54,17,51,78,247,34,51,50,55,114,38,97,19,33,133,83,43,22,50,78,231, -35,34,35,39,34,38,97,19,36,85,83,17,19,36,231,114,51,51,50,114,34,38,97,19,34, -21,33,17,50,78,116,98,34,34,38,118,34,38,113,1,50,65,17,68,68,231,70,34,38,97, -17,22,102,103,113,1,51,36,50,70,157,119,20,38,65,16,0,1,20,71,113,0,19,51,68, -109,254,113,70,65,23,97,16,0,1,20,65,0,1,74,169,157,247,65,35,37,136,133,33,0,0, -1,17,0,0,26,173,221,231,65,98,51,85,134,97,0,0,0,0,0,1,170,205,223,225,23,98,34, -51,51,33,0,0,0,0,0,26,172,221,222,16,1,17,118,34,38,97,0,0,0,0,0,26,204,221,238, -16,0,0,17,17,17,16,0,0,0,0,0,26,205,238,17,0,0,0,0,0,0,0,0,0,0,0,0,17,17,17,0,0, -0,0,0,0,0,0,0,0,0,0 -, // 6, warrior idle -175,0,3,5,1,4,6,62,2,7,92,170,151,93,95,148,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,199,119,119, -119,204,204,187,176,0,0,0,0,0,0,0,185,153,153,153,153,150,103,119,123,0,0,0,0,0, -0,1,255,204,119,119,119,119,119,119,193,0,0,0,0,0,0,1,17,17,17,17,17,17,17,28, -133,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,85,16,0,0,1,17,16,0,0,0,0,0,0,0,0,0,21,81,0, -1,19,53,81,0,0,0,0,0,0,0,0,0,1,33,1,22,99,51,81,0,0,17,0,0,0,0,0,0,1,40,22,102, -51,51,33,0,0,25,16,0,17,16,0,0,18,40,153,102,99,50,68,0,0,22,145,17,234,145,0,1, -173,85,85,54,51,50,68,0,0,19,105,155,234,102,16,24,90,173,51,38,99,50,68,0,0,1, -51,54,178,54,129,130,55,218,211,38,51,50,68,0,0,0,21,51,102,99,136,34,55,122, -211,38,99,51,36,0,1,17,34,85,51,102,56,34,55,218,211,38,51,51,81,0,19,51,51,51, -51,51,88,34,58,173,50,86,99,53,81,0,1,17,34,37,51,53,88,34,170,51,35,102,50,34, -36,0,0,0,18,85,85,85,136,40,163,50,57,98,34,34,36,0,0,1,37,85,178,82,136,136, -162,43,149,34,180,68,68,0,0,21,85,43,234,34,65,132,162,43,82,36,68,34,36,0,0,21, -33,17,234,33,0,20,162,36,43,68,66,83,82,0,0,18,16,0,17,16,0,1,17,17,36,68,68,68, -68,0,0,17,0,0,0,0,0,0,0,1,43,68,68,34,36,0,0,0,0,0,0,0,0,0,0,0,18,43,66,83,82,0, -0,0,0,0,0,0,0,0,0,0,1,18,36,68,68,0,0,0,0,0,0,0,0,0,0,0,0,1,18,34,36,0,0,0,0,0, -0,0,0,0,0,0,0,0,1,17,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -, // 7, warrior attacking -175,0,62,5,7,3,4,1,2,6,170,151,92,95,148,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -17,0,0,1,17,16,0,0,0,0,0,0,0,0,0,1,85,16,1,19,54,97,0,0,1,16,0,0,0,0,0,19,82,17, -25,147,51,97,0,0,1,145,16,1,17,0,1,53,126,74,89,51,51,87,0,0,1,153,17,29,201,16, -1,136,135,72,85,147,53,119,0,0,1,57,68,205,201,49,24,99,34,68,165,51,53,119,0,0, -0,19,51,154,163,152,136,50,36,68,133,83,53,119,0,0,0,1,86,57,153,150,133,50,34, -36,74,83,53,119,0,0,1,17,17,86,51,147,34,34,34,36,72,85,51,87,0,0,19,51,51,51, -51,54,133,34,43,180,68,165,51,97,0,0,1,17,17,83,54,102,133,51,34,34,68,133,83, -97,0,0,0,1,86,102,102,104,133,50,34,34,68,74,86,97,0,0,0,21,102,106,165,88,130, -34,68,68,68,69,133,87,0,0,1,86,101,205,197,135,120,34,34,34,36,66,167,119,0,0,1, -101,17,29,197,16,7,130,34,187,180,68,165,101,0,0,1,81,0,1,17,34,34,34,34,34,34, -68,42,119,0,0,1,16,0,0,0,2,34,36,68,68,68,68,74,85,0,0,0,0,0,0,0,0,0,34,34,68, -68,68,68,23,0,0,0,0,0,0,0,0,0,0,2,43,187,187,187,17,0,0,0,0,0,0,0,0,0,0,0,0,0,1, -17,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -, // 8, plasmabot idle -175,0,72,65,2,3,4,5,61,60,54,62,6,59,49,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,34,34,0,0,0,0,0,0,0,0,0,0,0,0,0,42,170,170,34,0,0,0,0,0,0,1,17,0,0,0,0,42,147, -56,171,32,0,0,0,0,0,1,193,0,0,0,0,42,50,35,153,32,0,0,0,1,17,20,68,17,17,0,2, -171,50,34,57,32,0,0,0,1,119,118,102,85,65,0,2,163,34,34,57,33,0,0,0,1,101,85,68, -68,65,0,2,163,34,35,137,35,16,0,0,1,17,17,17,17,17,0,42,185,50,35,141,50,49,0,0, -0,0,1,65,0,0,0,42,187,131,57,211,66,52,16,0,0,0,21,81,0,0,0,43,51,136,179,68, -136,34,17,17,17,17,68,65,0,0,0,36,101,51,52,216,136,146,86,124,197,204,204,113, -0,0,0,3,122,229,61,136,137,242,17,17,17,17,28,17,0,0,0,2,122,174,83,153,211,35, -65,0,0,0,28,16,0,0,0,2,118,174,101,51,50,51,65,0,17,17,68,65,17,16,0,2,118,102, -238,85,82,52,65,1,119,119,102,102,85,65,0,2,118,102,238,102,98,52,81,1,102,85, -85,68,68,65,0,2,118,174,102,83,50,53,81,0,17,17,17,17,17,16,0,2,122,174,101,171, -179,37,81,0,0,0,20,16,0,0,0,3,122,230,93,184,136,210,17,17,17,17,21,17,0,0,0,35, -118,85,52,216,137,243,86,124,197,204,199,81,0,0,0,43,85,170,179,68,159,34,17,17, -17,17,68,65,0,0,0,42,171,147,57,211,66,52,16,0,0,0,23,113,0,0,0,42,185,50,35, -136,50,65,0,0,0,0,1,193,0,0,0,2,179,34,35,137,36,16,0,0,1,17,20,68,17,17,0,2, -179,34,34,57,33,0,0,0,1,119,118,102,85,65,0,2,152,50,34,61,32,0,0,0,1,101,85,68, -68,65,0,0,40,50,35,223,32,0,0,0,1,17,17,17,17,17,0,0,41,147,61,255,32,0,0,0,0,0, -1,81,0,0,0,0,47,255,223,34,0,0,0,0,0,0,1,17,0,0,0,0,2,34,34,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -, // 9, plasmabot attacking -175,198,0,2,4,3,72,39,193,5,194,6,49,192,65,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,111,193,1,0,0,0,0,0,0,0,0,0,0,0,0,6,177,17,17,0,0,0,0,0,0,2,34,0,0,0,0,15, -113,17,17,240,0,0,0,0,0,2,178,0,0,0,0,107,17,23,17,31,0,0,0,8,136,131,51,34,34, -0,0,97,23,119,113,17,17,0,0,10,153,153,68,85,50,0,0,103,17,119,119,17,16,0,0,10, -68,85,83,51,50,0,6,145,17,119,17,19,61,0,0,10,168,141,34,34,34,0,1,17,17,23,17, -85,172,128,0,0,0,2,50,0,0,0,6,17,113,17,17,85,172,128,0,0,0,2,82,0,0,0,6,156,55, -113,85,84,76,200,170,168,136,211,50,0,0,0,6,52,85,81,84,180,68,245,73,187,91, -187,146,0,0,0,0,233,151,85,91,180,67,98,34,34,34,43,34,0,0,0,0,105,71,115,52,69, -230,227,32,0,0,43,32,0,0,0,0,105,68,124,83,206,110,227,32,168,141,51,50,34,32,0, -0,105,68,68,204,85,110,51,218,153,153,68,68,85,50,0,0,105,68,68,204,68,110,51, -218,68,85,85,51,51,50,0,0,105,68,124,69,238,254,53,208,136,136,221,210,34,32,0, -0,105,71,124,91,153,207,85,32,0,0,35,32,0,0,0,0,233,71,197,25,68,69,253,136,221, -221,37,34,0,0,0,6,233,149,81,20,148,67,197,73,187,91,185,82,0,0,0,6,149,87,17, -17,84,60,200,136,136,136,211,50,0,0,0,6,187,113,17,17,21,172,208,0,0,0,13,146,0, -0,0,6,177,17,119,17,17,163,32,0,0,0,13,178,0,0,0,6,73,145,23,119,19,50,0,0,10, -136,131,51,34,34,0,0,105,17,119,113,28,32,0,0,10,153,68,68,85,50,0,0,105,17,119, -17,17,0,0,0,10,69,85,51,51,50,0,0,97,17,23,17,22,0,0,0,10,168,210,34,34,34,0,0, -1,65,17,21,17,0,0,0,0,0,2,82,0,0,0,0,6,52,69,31,0,0,0,0,0,0,2,34,0,0,0,0,0,102, -102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -, // 10, ender idle -0,3,4,5,2,175,1,6,52,7,93,92,50,74,73,0,85,85,85,85,0,0,0,80,5,0,5,85,85,80,0,0, -85,85,80,0,153,153,52,1,134,17,16,80,0,9,114,32,85,80,3,151,119,119,119,104,97, -135,129,9,119,115,36,16,85,9,114,115,51,51,51,54,97,114,113,99,50,17,22,16,80, -151,113,18,4,18,34,51,97,135,129,102,33,20,70,16,9,119,20,55,114,0,65,34,16,17, -22,24,4,68,70,16,2,20,67,51,51,51,48,34,33,6,96,129,4,65,0,0,9,113,51,58,58,51, -115,3,49,65,51,0,65,96,85,85,9,49,33,34,35,34,35,49,51,18,34,38,102,102,0,0,7, -49,36,34,33,35,18,113,115,43,50,22,23,119,114,32,7,49,33,1,34,51,49,39,23,114, -51,22,18,34,36,16,7,19,34,64,66,34,51,19,35,51,50,6,102,17,22,96,80,115,35,11, -176,34,49,19,45,194,35,51,116,100,70,16,85,3,55,10,164,18,18,61,17,18,18,50,55, -97,22,16,80,1,121,10,170,65,35,18,34,34,33,34,35,96,0,0,3,68,121,64,0,1,18,34, -32,68,18,34,34,6,5,85,1,68,119,64,0,1,17,18,32,68,18,34,34,6,5,85,80,1,55,10, -170,65,34,65,34,34,33,34,33,96,0,0,85,3,51,10,164,35,34,52,17,18,17,34,36,103, -114,32,80,115,35,11,176,51,49,19,20,65,18,34,68,98,36,16,9,19,34,64,67,51,119, -19,35,50,33,70,6,17,22,96,7,49,33,1,51,51,113,35,19,52,34,16,100,68,70,16,3,49, -36,34,50,39,18,49,35,65,17,70,65,17,22,16,3,49,33,51,51,35,35,16,18,75,68,102, -102,102,0,0,3,33,35,51,51,51,49,1,17,68,70,0,98,96,85,85,1,68,18,58,58,49,208, -17,68,6,96,129,2,34,0,0,3,34,65,35,50,0,65,20,96,17,22,24,1,18,36,32,80,50,36, -29,4,18,17,70,97,135,129,0,17,17,20,16,85,2,36,34,34,33,20,230,97,114,113,100, -68,17,22,16,85,80,4,193,17,204,68,104,1,135,129,4,68,68,70,16,85,85,80,0,68,68, -70,1,128,17,16,80,0,4,70,16,85,85,85,85,0,0,0,80,5,0,5,85,85,80,0,0 -, // 11, ender walking -0,3,4,5,175,2,1,6,52,93,7,92,50,74,73,0,68,68,68,68,64,0,0,4,0,64,0,68,68,0,0,4, -68,68,68,0,10,170,114,80,136,97,17,4,0,167,34,4,68,68,0,39,119,119,119,21,86,24, -120,16,119,50,81,4,68,0,167,35,51,51,51,49,102,23,39,22,33,17,97,4,64,42,114,18, -85,1,34,51,22,24,120,22,1,85,97,4,64,167,37,87,114,32,81,34,49,1,17,97,128,85, -97,4,2,21,85,51,51,51,53,18,34,16,102,8,16,81,0,4,10,119,19,51,147,147,115,1,49, -85,18,0,1,96,68,68,10,115,18,34,34,50,35,50,35,33,34,22,102,96,68,68,7,115,18, -81,34,18,49,55,19,50,178,22,23,114,0,0,7,115,18,16,18,35,50,23,23,115,35,22,18, -39,114,32,3,17,50,53,5,34,51,35,35,51,50,6,102,18,37,16,64,115,34,48,187,2,49, -19,45,194,35,51,117,101,22,96,64,50,39,112,153,177,18,49,209,17,33,35,55,97,86, -16,68,0,39,160,153,149,35,17,34,34,34,18,51,96,22,16,64,53,87,165,0,0,17,34,33, -5,82,34,35,6,0,0,64,21,87,165,0,0,17,18,33,5,82,34,34,6,4,68,68,0,39,112,153, -149,34,81,34,34,34,18,33,96,0,4,68,7,51,48,153,178,34,53,17,17,33,18,21,103,34, -4,64,115,35,48,187,3,49,19,21,81,18,17,85,98,81,4,10,17,34,37,5,51,55,19,34,51, -33,86,6,17,102,4,7,50,18,16,19,51,113,35,19,50,81,80,101,85,97,4,7,50,18,82,35, -39,18,49,83,37,21,86,81,17,97,4,3,50,18,35,51,50,35,16,18,37,181,102,102,96,0,4, -2,34,19,51,51,51,49,101,17,85,86,0,2,34,102,96,1,21,81,51,147,145,214,81,85,80, -102,1,128,18,37,32,64,50,37,19,50,37,1,21,86,1,17,104,16,17,21,16,64,51,33,93, -80,82,17,86,96,24,120,22,1,17,22,16,68,0,33,82,34,33,21,230,96,23,39,22,85,85, -86,16,68,68,0,92,17,204,85,96,16,24,120,16,85,85,86,16,68,68,68,0,5,85,86,0,136, -1,17,4,0,0,0,0,68,68,68,68,64,0,0,68,0,64,0,68,68,68,68,68 -, // 12, ender attacking -0,4,5,175,3,26,28,191,6,29,2,1,30,7,105,27,51,51,51,51,48,0,0,3,0,48,112,51,51, -48,0,0,51,51,51,0,13,221,137,80,153,231,119,115,0,13,129,16,51,51,0,24,136,136, -136,101,94,119,221,119,136,130,26,64,51,0,216,18,204,204,204,198,119,125,221, -119,118,244,75,64,48,29,129,73,85,6,153,204,103,119,215,126,6,250,171,64,48,216, -26,168,137,144,86,153,198,7,119,118,144,90,171,64,1,74,170,34,34,34,37,105,153, -96,119,9,96,84,0,0,13,136,66,34,82,82,130,6,198,85,121,0,6,176,51,51,13,130,65, -17,17,33,18,41,156,150,153,110,187,187,0,0,8,130,65,164,17,65,36,40,108,201,89, -110,104,136,129,16,8,130,65,64,65,18,33,72,248,140,156,110,105,145,26,64,2,68, -33,42,170,17,34,18,18,34,41,14,235,255,75,176,48,130,17,42,85,1,36,66,26,81,18, -34,133,181,171,64,48,33,17,40,5,84,65,36,164,68,20,18,40,180,75,64,51,0,17,141, -5,90,18,68,17,17,17,65,34,176,0,0,48,42,161,141,0,0,68,17,20,10,161,17,18,11,3, -51,48,74,161,136,0,0,68,65,20,10,161,17,17,11,3,51,51,0,18,40,5,90,17,95,145,17, -17,65,20,176,0,0,51,8,34,33,5,81,17,37,255,255,31,65,74,184,129,16,48,130,18,42, -85,2,47,242,101,95,249,255,85,177,26,64,13,68,17,26,10,34,40,108,153,34,150,91, -11,244,75,176,8,33,65,64,66,34,134,156,108,201,86,80,181,170,171,64,8,33,65,161, -18,152,105,198,92,149,101,94,95,68,75,64,2,33,65,18,34,41,156,96,105,149,85,238, -235,187,0,0,1,17,66,34,34,44,198,229,102,85,126,0,9,176,51,51,4,74,164,34,82, -166,254,86,85,80,119,6,144,145,0,0,48,33,26,66,41,149,6,101,94,119,119,121,96, -97,26,16,48,34,20,95,80,89,102,94,224,119,215,126,6,111,74,64,51,0,20,89,153, -150,101,238,231,125,221,119,117,111,75,64,51,51,0,95,102,255,85,224,96,119,215, -112,85,90,171,64,51,51,51,0,5,85,94,0,153,7,119,3,0,10,171,64,51,51,51,51,48,0, -0,51,0,48,112,51,51,48,0,0 -, // 13, turret idle -175,0,131,26,41,168,37,6,91,7,48,93,90,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,16,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,25,145,0,0,0,0,0,0,0,0,17,0,0,0,0,17,151,98,16,0,0,0,0,0,0,1,130,16,0,0, -1,35,184,130,81,16,0,0,0,0,0,1,40,16,0,0,1,34,123,178,85,65,0,0,0,0,0,23,49,0,0, -0,25,98,187,98,81,16,0,0,0,0,0,23,65,0,0,0,25,98,118,98,16,0,0,0,0,0,1,115,16,0, -17,17,71,98,118,98,81,16,0,0,0,1,20,116,16,0,0,0,22,35,114,36,85,65,0,0,1,25, -103,53,16,0,0,1,50,52,98,36,81,16,0,0,25,151,39,69,161,0,0,25,51,68,98,36,16,0, -0,0,25,118,100,84,161,0,1,151,54,35,184,36,16,0,0,1,151,98,35,52,85,17,23,102, -70,35,104,132,81,16,0,1,151,98,35,52,85,162,50,34,70,35,104,132,85,65,0,1,118, -34,51,68,85,17,19,51,70,35,104,132,81,16,0,1,118,35,51,68,81,0,1,67,70,35,184, -36,16,0,0,1,102,35,52,69,81,0,0,20,66,53,98,36,16,0,0,1,115,51,68,81,16,0,0,1, -67,165,98,36,81,16,0,1,114,51,69,16,0,0,0,0,20,85,98,36,85,65,0,27,98,35,65,0,0, -1,17,17,18,58,35,58,81,16,0,27,34,35,16,0,0,23,98,51,18,58,35,58,16,0,1,123,130, -52,16,0,0,22,34,68,18,58,140,58,81,16,23,98,184,129,0,0,0,1,35,65,1,90,44,202, -85,65,25,34,35,193,0,0,0,1,20,81,1,85,140,202,81,16,22,34,52,65,0,0,0,17,1,16,0, -17,35,58,16,0,1,35,68,16,0,0,0,16,0,0,0,0,19,49,0,0,0,17,17,0,0,0,0,0,0,0,0,0,1, -16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0 -, // 14 turret walk -175,0,131,26,41,37,168,6,91,7,48,93,90,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,1,153,16,0,0,0,0,0,0,0,0,0,0,0,0,1,25,117,33,0,0,0,0,0,0,0,0,1,16,0,0, -18,59,136,33,0,0,0,0,0,0,0,0,24,33,0,0,18,39,187,38,16,0,0,0,0,0,0,0,18,129,0,1, -149,43,181,38,65,0,0,0,0,0,0,1,115,16,0,1,149,39,85,38,16,0,0,0,0,0,0,25,33,0,1, -20,117,39,85,33,0,0,0,0,0,1,17,114,49,0,16,1,82,55,34,70,16,0,0,0,1,25,87,51,16, -0,0,19,35,69,34,65,0,0,0,0,25,151,39,70,16,0,1,147,52,69,34,65,0,0,0,0,25,117, -84,100,161,0,25,115,82,59,130,70,16,0,0,1,151,82,35,52,161,17,117,83,82,53,136, -70,65,0,0,1,151,82,35,52,102,35,34,35,82,53,136,70,16,0,0,1,117,34,51,68,102,17, -51,52,82,53,136,65,0,0,0,1,117,34,51,68,102,0,20,52,82,59,130,65,0,0,0,23,85,35, -52,70,97,0,1,68,35,101,34,65,0,0,0,23,82,51,68,102,96,0,0,20,58,101,34,70,16,0, -1,181,34,52,65,16,0,17,16,1,70,101,34,65,0,0,23,178,34,52,16,0,1,119,81,17,35, -162,51,161,0,1,117,40,35,65,0,0,1,82,35,49,35,162,51,166,16,1,146,43,136,65,0,0, -17,34,52,17,35,168,195,166,65,1,82,34,60,16,0,0,1,51,65,0,22,162,204,166,16,1, -34,51,68,16,0,0,0,17,16,0,22,104,204,161,0,0,17,52,65,0,0,0,0,0,0,0,1,18,51,161, -0,0,0,17,16,0,0,0,0,0,0,0,0,1,51,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0 -, // 15 turret attack -175,0,131,41,26,1,168,191,7,48,81,6,37,21,35,44,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,1,136,16,0,0,0,0,0,0,0,0,0,0,0,0,1,24,188,33,0,0,0,0,0,0,0,0,0,0,0,0, -18,77,170,38,16,0,0,0,0,0,0,0,0,0,0,0,18,43,212,38,49,0,0,0,0,0,0,0,0,0,0,1,140, -45,220,38,16,0,0,0,0,0,0,0,0,0,0,1,140,43,220,33,0,0,0,0,0,0,0,0,0,1,17,19,188, -43,220,38,16,0,0,0,0,80,85,0,0,0,0,1,194,75,226,54,49,0,0,0,85,135,188,165,0,0, -0,148,36,61,226,54,16,0,0,90,136,183,15,254,80,0,9,132,67,61,226,49,0,0,0,168, -139,119,112,238,80,0,24,180,194,77,162,49,0,0,1,187,183,120,135,116,161,21,189, -211,194,77,170,54,16,0,1,192,119,120,135,119,9,173,204,195,194,77,170,54,49,0,1, -204,192,119,119,106,169,21,221,211,194,77,170,54,16,0,0,175,255,247,122,170,80, -0,94,211,194,77,162,49,0,0,0,90,255,231,68,170,80,0,5,227,36,109,226,49,0,0,0,0, -85,224,74,85,0,0,0,83,73,109,226,54,16,0,0,0,0,85,85,0,0,0,0,1,54,109,226,54,49, -0,0,0,0,0,0,0,0,68,68,65,36,158,68,150,16,0,0,0,0,0,0,0,4,141,221,225,36,158,68, -145,0,0,0,0,0,0,0,0,4,221,35,49,36,154,164,150,16,0,0,0,0,0,0,0,0,18,67,16,22, -158,170,150,49,0,0,0,0,0,0,0,0,17,54,16,22,106,170,150,16,0,0,0,0,0,0,0,1,16,17, -0,1,30,68,145,0,0,0,0,0,0,0,0,1,0,0,0,0,1,68,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0 -, // 16 exploder walk -175,168,1,2,3,102,4,5,23,174,99,191,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,16,0,0, -0,0,89,0,0,0,0,0,0,0,0,68,65,177,0,0,5,85,89,0,0,0,0,0,0,0,4,34,33,177,0,0,19, -187,144,0,0,0,0,0,0,0,1,32,1,131,16,1,198,57,0,0,0,0,0,0,0,0,23,97,1,138,16,28, -116,16,0,0,0,0,0,0,17,17,34,34,17,138,17,17,65,0,0,0,0,0,0,0,22,50,51,51,50,134, -19,49,16,1,17,0,0,0,0,0,23,66,51,34,184,134,33,49,1,23,199,21,153,0,0,0,23,66, -34,184,133,85,50,17,28,199,103,99,85,80,0,0,23,66,136,138,18,85,106,50,199,119, -100,99,85,153,0,0,23,66,136,85,171,166,102,34,39,102,51,36,181,89,144,0,23,34, -34,165,90,21,130,33,36,35,55,103,75,89,0,1,18,187,136,136,81,168,36,116,18,119, -118,70,59,185,144,24,139,85,85,102,98,88,39,71,18,102,102,68,59,187,153,1,18,51, -170,170,97,168,36,116,18,68,68,68,59,185,144,0,19,34,34,58,106,21,130,33,39,34, -51,68,75,89,0,0,23,50,35,35,171,166,163,34,54,103,51,36,85,153,0,0,23,66,42,51, -18,102,163,34,52,70,102,115,89,144,0,0,23,66,34,163,51,86,50,17,19,52,68,97,89, -0,0,0,23,66,50,34,58,90,33,49,1,19,51,16,0,0,0,0,22,50,51,51,34,90,19,49,16,1, -17,0,0,0,0,0,17,17,34,34,17,138,17,17,193,0,0,0,0,0,0,0,0,0,20,65,1,131,16,20, -124,16,0,0,0,0,0,0,0,0,1,32,1,131,16,1,70,57,0,0,0,0,0,0,0,0,1,18,33,129,0,0,19, -187,144,0,0,0,0,0,0,0,0,17,17,129,0,0,5,155,153,0,0,0,0,0,0,0,0,0,1,16,0,0,0,5, -80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -, // 17 universal dying sprite -175,0,223,1,3,4,5,2,6,73,135,79,26,159,131,37,0,0,0,0,0,0,0,0,0,0,0,51,0,0,0,0, -0,0,0,0,0,2,0,0,0,34,32,51,0,0,0,0,0,0,0,0,0,2,32,0,2,163,34,0,0,0,0,0,0,0,0,0, -0,0,0,0,42,3,50,33,16,0,0,0,0,0,0,0,0,0,1,16,32,0,2,22,97,16,0,0,0,0,0,0,0,1,24, -129,16,0,1,119,85,81,0,0,0,0,0,0,0,24,134,134,1,16,1,68,119,84,16,0,0,0,0,0,0, -24,102,136,102,81,0,20,68,116,16,0,0,0,0,0,1,102,102,104,134,65,2,20,68,151,113, -0,0,0,0,0,1,101,86,102,101,48,2,1,68,73,113,0,0,0,0,0,1,101,85,102,100,48,35,52, -17,73,16,0,0,0,0,0,1,85,85,85,71,51,37,84,48,17,0,0,0,0,0,0,1,84,80,80,71,50,34, -36,48,0,0,0,0,0,0,0,0,20,68,68,115,34,85,34,35,0,51,0,0,0,0,0,0,1,68,19,50,42, -51,85,34,3,48,0,0,0,0,0,0,0,17,34,34,163,101,51,67,32,0,0,0,0,0,0,0,0,2,42,68, -83,67,85,49,0,0,0,0,0,0,0,0,2,34,0,53,51,53,51,84,16,0,0,0,0,0,0,0,0,32,0,1,187, -211,115,21,16,0,0,0,0,0,0,0,2,32,0,27,189,211,48,23,16,0,0,0,0,0,0,0,2,0,0,27, -221,209,1,97,0,0,0,0,0,0,0,0,0,0,1,155,221,65,1,112,1,17,16,0,0,0,0,0,0,0,22, -153,145,17,22,49,22,117,16,0,0,0,0,0,0,1,101,84,113,0,23,54,102,53,16,0,0,0,0,0, -0,33,85,84,121,16,1,85,68,55,81,0,0,0,0,0,2,33,68,73,17,193,1,68,71,115,65,0,0, -0,0,0,34,42,153,145,1,195,16,23,119,115,65,0,0,0,0,0,32,2,170,34,31,236,49,23, -116,17,17,0,0,0,0,0,0,0,34,2,24,238,193,1,17,0,0,0,0,0,0,0,0,0,32,0,24,254,193, -0,35,48,0,0,0,0,0,0,0,0,0,0,1,17,16,2,32,48,0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,0,0 -, // 18 universal dead/corpse sprite -175,0,3,4,1,5,6,2,157,18,95,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,4,68,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,34,0,0,0,0,0,0,0,0,0,0,0, -0,0,4,50,34,0,0,0,0,0,0,0,0,0,0,0,0,0,4,36,17,0,0,0,0,0,0,0,0,0,0,0,0,1,18,65, -49,0,0,0,0,0,0,0,0,0,0,1,17,34,34,19,51,0,0,0,0,0,0,0,0,0,1,22,98,34,34,33,20,0, -0,0,0,0,0,0,0,0,22,101,101,40,130,36,68,0,0,0,0,0,0,0,0,0,22,85,102,85,136,129, -17,0,0,0,0,0,0,0,0,1,85,85,82,37,136,22,68,0,0,0,0,0,0,0,0,1,18,53,85,34,132,19, -36,0,0,0,0,0,0,0,0,0,2,34,85,84,33,100,66,0,0,0,0,0,0,0,0,1,35,51,51,39,22,102, -49,0,0,0,0,0,0,0,0,1,50,58,58,39,65,101,33,0,0,0,0,0,0,0,0,0,18,34,34,116,22,83, -17,0,0,0,0,0,0,0,0,0,1,34,20,68,17,50,20,0,0,0,0,0,0,0,0,0,0,17,4,68,34,20,52,0, -0,0,0,0,0,0,0,0,0,0,0,34,39,83,49,0,0,0,0,0,0,0,0,0,0,0,34,35,117,51,65,0,0,0,0, -0,0,0,0,0,0,0,0,19,115,51,52,0,0,0,0,0,0,0,0,0,0,0,0,19,55,163,153,0,0,0,0,0,0, -0,0,0,0,0,0,1,55,51,153,0,0,0,0,0,0,0,0,0,0,0,0,0,17,115,41,0,0,0,0,0,0,0,0,0,0, -0,0,17,53,36,65,0,0,0,0,0,0,0,0,0,0,0,0,21,33,17,18,0,0,0,0,0,0,0,0,0,0,0,0,1, -16,1,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,34,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,2,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0 -}; - -SFG_PROGRAM_MEMORY uint8_t SFG_logoImage[SFG_TEXTURE_STORE_SIZE] = -{ -175,224,0,7,4,5,162,77,2,74,70,69,6,11,68,75,0,0,0,0,0,0,17,17,17,17,17,0,0,0,0, -0,0,0,0,0,0,1,132,69,51,84,65,0,0,0,0,0,0,0,0,0,0,24,65,17,19,17,17,0,0,0,0,0,0, -0,0,0,0,24,65,0,19,16,0,0,0,0,0,0,0,0,0,0,0,24,65,17,19,17,17,0,0,0,0,0,0,0,0,0, -0,1,132,69,51,84,65,32,0,0,0,0,0,0,0,0,0,1,17,17,17,17,17,242,0,0,0,0,0,0,0,6, -97,243,94,40,51,84,66,159,32,0,0,0,0,0,17,17,24,60,190,40,50,34,34,155,146,0,0, -0,0,0,33,17,20,203,238,109,51,84,66,251,178,0,0,0,0,0,17,17,131,171,123,145,18, -34,38,122,187,32,0,0,0,0,6,97,92,170,167,113,115,35,81,122,171,32,0,0,0,0,2,22, -202,170,170,212,51,37,210,26,121,130,0,0,0,0,34,17,22,234,164,28,60,34,92,23, -218,56,32,0,0,2,33,17,102,110,113,69,210,35,51,93,51,66,50,0,0,34,34,40,126,246, -210,34,195,35,51,49,210,34,34,0,0,0,2,40,119,238,105,197,210,35,51,93,51,65,50, -0,0,0,2,38,87,119,166,156,60,34,92,223,218,161,32,0,0,2,34,38,87,119,170,20,51, -37,223,23,114,18,0,0,0,2,34,34,69,122,119,241,211,35,86,102,187,32,0,0,0,0,0,97, -213,119,187,97,134,45,17,246,105,32,0,0,0,0,34,33,22,247,238,29,51,53,65,155,98, -0,0,0,0,0,2,34,33,110,233,29,54,17,17,155,146,0,0,0,0,0,0,0,97,111,153,34,34,34, -29,159,32,0,0,0,0,0,0,0,0,41,150,40,51,84,65,146,0,0,0,0,0,0,0,0,0,2,38,40,56, -24,65,32,0,0,0,0,0,0,0,0,0,0,2,40,49,145,65,0,0,0,0,0,0,0,0,0,0,1,17,34,17,17, -17,0,0,0,0,0,0,0,0,0,0,1,132,69,51,84,65,0,0,0,0,0,0,0,0,0,0,1,17,24,56,17,17,0, -0,0,0,0,0,0,0,0,0,0,0,24,51,84,65,0,0,0,0,0,0,0,0,0,0,0,0,1,17,17,17,0,0,0,0,0 -}; - -uint8_t SFG_charToFontIndex(char c) -{ - if (c >= 'a' && c <= 'z') - return c - 'a'; - - if (c >= 'A' && c <= 'Z') - return c - 'A'; - - if (c >= '0' && c <= '9') - return c - '0' + 31; - - switch (c) - { - case ' ': return 26; break; - case '.': return 27; break; - case ',': return 28; break; - case '!': return 29; break; - case '/': return 41; break; - case '-': return 42; break; - case '+': return 43; break; - case '(': return 44; break; - case ')': return 45; break; - case '%': return 46; break; - default: return 30; break; // "?" - } -} - -#define SFG_FONT_CHARACTER_SIZE 4 - -/** - 4x4 font, each character stored as 16 bits. -*/ -SFG_PROGRAM_MEMORY uint16_t SFG_font[47] = -{ - 0xfaf0, // 0 "A" - 0xfd70, // 1 "B" - 0x6990, // 2 "C" - 0xf960, // 3 "D" - 0xfd90, // 4 "E" - 0xfa80, // 5 "F" - 0x69b0, // 6 "G" - 0xf4f0, // 7 "H" - 0x9f90, // 8 "I" - 0x31f0, // 9 "J" - 0xf4b0, // 10 "K" - 0xf110, // 11 "L" - 0xfc4f, // 12 "M" - 0xf42f, // 13 "N" - 0x6996, // 14 "O" - 0xfae0, // 15 "P" - 0x69b7, // 16 "Q" - 0xfad0, // 17 "R" - 0x5da0, // 18 "S" - 0x8f80, // 19 "T" - 0xf1f0, // 20 "U" - 0xe1e0, // 21 "V" - 0xf32f, // 22 "W" - 0x9690, // 23 "X" - 0xc7c0, // 24 "Y" - 0xbd90, // 25 "Z" - 0x0000, // 26 " " - 0x0100, // 27 "." - 0x0300, // 28 "," - 0x0d00, // 29 "!" - 0x48b4, // 30 "?" - 0xf9f0, // 31 "0" - 0x9f10, // 32 "1" - 0xbdd0, // 33 "2" - 0x9da0, // 34 "3" - 0xe2f0, // 35 "4" - 0xdbb0, // 36 "5" - 0xfbb0, // 37 "6" - 0x8bc0, // 38 "7" - 0xfdf0, // 39 "8" - 0xddf0, // 40 "9" - 0x1680, // 41 "/" - 0x2220, // 42 "-" - 0x2720, // 43 "+" - 0x0690, // 44 "(" - 0x0960, // 45 ")" - 0x9249 // 46 "%" -}; - -#endif // guard diff --git a/main_gbmeta/levels.h b/main_gbmeta/levels.h deleted file mode 100644 index d2868f1..0000000 --- a/main_gbmeta/levels.h +++ /dev/null @@ -1,1809 +0,0 @@ -/** - @file levels.h - - This file contains game levels and related code. - - by Miloslav Ciz (drummyfish), 2019 - - Released under CC0 1.0 (https://creativecommons.org/publicdomain/zero/1.0/) - plus a waiver of all other intellectual property. The goal of this work is - be and remain completely in the public domain forever, available for any use - whatsoever. -*/ - -#ifndef _SFG_LEVELS_H -#define _SFG_LEVELS_H - -#define SFG_MAP_SIZE 64 -#define SFG_TILE_DICTIONARY_SIZE 64 - -typedef uint16_t SFG_TileDefinition; -/**< - Defines a single game map tile. The format is following: - - MSB aaabbbbb cccddddd LSB - - aaa: ceiling texture index (from texture available on the map), 111 - means completely transparent texture - bbbbb: ceiling height (1111 meaning no ceiling) ABOVE the floor - ccc: floor texture index, 111 means completely transparent texture - ddddd: floor height -*/ - -#define SFG_TILE_CEILING_MAX_HEIGHT 31 -#define SFG_TILE_TEXTURE_TRANSPARENT 7 - -typedef SFG_TileDefinition SFG_TileDictionary[SFG_TILE_DICTIONARY_SIZE]; - -/// helper macros for SFG_TileDefinition -#define SFG_TD(floorH, ceilH, floorT, ceilT)\ - ((floorH & 0x001f) |\ - ((floorT & 0x0007) << 5) |\ - ((ceilH & 0x001f) << 8) |\ - ((ceilT & 0x0007) << 13)) - -#define SFG_TILE_FLOOR_HEIGHT(tile) (tile & 0x1f) -#define SFG_TILE_FLOOR_TEXTURE(tile) ((tile & 0xe0) >> 5) -#define SFG_TILE_CEILING_HEIGHT(tile) ((tile & 0x1f00) >> 8) -#define SFG_TILE_CEILING_TEXTURE(tile) ((tile & 0xe000) >> 13) - -#define SFG_OUTSIDE_TILE SFG_TD(63,0,7,7) - -/** - Game map represented as a 2D array. Array item has this format: - - MSB aabbbbbb LSB - - aa: type of square, possible values: - 00: normal - 01: moving floor (elevator), moves from floor height to ceililing height - (there is no ceiling above) - 10: moving ceiling, moves from ceiling height to floor height - 11: door - bbbbbb: index into tile dictionary -*/ -typedef uint8_t SFG_MapArray[SFG_MAP_SIZE * SFG_MAP_SIZE]; - -#define SFG_TILE_PROPERTY_MASK 0xc0 -#define SFG_TILE_PROPERTY_NORMAL 0x00 -#define SFG_TILE_PROPERTY_ELEVATOR 0x40 -#define SFG_TILE_PROPERTY_SQUEEZER 0x80 -#define SFG_TILE_PROPERTY_DOOR 0xc0 - -/** - Serves to place elements (items, enemies etc.) into the game level. -*/ -typedef struct -{ - uint8_t type; - uint8_t coords[2]; -} SFG_LevelElement; - -#define SFG_MAX_LEVEL_ELEMENTS 128 - -/* - Definitions of level element type. These values must leave the highest bit - unused because that will be used by the game engine, so the values must be - lower than 128. -*/ -#define SFG_LEVEL_ELEMENT_NONE 0 -#define SFG_LEVEL_ELEMENT_BARREL 0x01 -#define SFG_LEVEL_ELEMENT_HEALTH 0x02 -#define SFG_LEVEL_ELEMENT_BULLETS 0x03 -#define SFG_LEVEL_ELEMENT_ROCKETS 0x04 -#define SFG_LEVEL_ELEMENT_PLASMA 0x05 -#define SFG_LEVEL_ELEMENT_TREE 0x06 -#define SFG_LEVEL_ELEMENT_FINISH 0x07 -#define SFG_LEVEL_ELEMENT_TELEPORTER 0x08 -#define SFG_LEVEL_ELEMENT_TERMINAL 0x09 -#define SFG_LEVEL_ELEMENT_COLUMN 0x0a -#define SFG_LEVEL_ELEMENT_RUIN 0x0b -#define SFG_LEVEL_ELEMENT_LAMP 0x0c -#define SFG_LEVEL_ELEMENT_CARD0 0x0d ///< Access card, unlocks doors with lock. -#define SFG_LEVEL_ELEMENT_CARD1 0x0e -#define SFG_LEVEL_ELEMENT_CARD2 0x0f -#define SFG_LEVEL_ELEMENT_LOCK0 0x10 /**< Special level element that must be - placed on a tile with door. This door is - then unlocked by taking the corresponding - access card. */ -#define SFG_LEVEL_ELEMENT_LOCK1 0x11 -#define SFG_LEVEL_ELEMENT_LOCK2 0x12 -#define SFG_LEVEL_ELEMENT_BLOCKER 0x13 ///< Invisible wall. - -#define SFG_LEVEL_ELEMENT_MONSTER_SPIDER 0x20 -#define SFG_LEVEL_ELEMENT_MONSTER_DESTROYER 0x21 -#define SFG_LEVEL_ELEMENT_MONSTER_WARRIOR 0x22 -#define SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT 0x23 -#define SFG_LEVEL_ELEMENT_MONSTER_ENDER 0x24 -#define SFG_LEVEL_ELEMENT_MONSTER_TURRET 0x25 -#define SFG_LEVEL_ELEMENT_MONSTER_EXPLODER 0x26 - -#define SFG_MONSTERS_TOTAL 7 - -#define SFG_MONSTER_TYPE_TO_INDEX(monsterType) \ - ((monsterType) - SFG_LEVEL_ELEMENT_MONSTER_SPIDER) - -#define SFG_MONSTER_INDEX_TO_TYPE(monsterIndex) \ - ((monsterIndex) + SFG_LEVEL_ELEMENT_MONSTER_SPIDER) - -#define SFG_LEVEL_ELEMENT_TYPE_IS_MOSTER(t) \ - ((t) >= SFG_LEVEL_ELEMENT_MONSTER_SPIDER) - -typedef struct -{ - SFG_MapArray mapArray; - SFG_TileDictionary tileDictionary; - uint8_t textureIndices[7]; /**< Says which textures are used on the map. There - can be at most 7 because of 3bit indexing (one - value is reserved for special transparent - texture). */ - uint8_t doorTextureIndex; /**< Index (global, NOT from textureIndices) of a - texture used for door. */ - uint8_t floorColor; - uint8_t ceilingColor; - uint8_t playerStart[3]; /**< Player starting location: square X, square Y, - direction (fourths of RCL_Unit). */ - uint8_t backgroundImage; /** Index of level background image. */ - SFG_LevelElement elements[SFG_MAX_LEVEL_ELEMENTS]; -} SFG_Level; - -static inline SFG_TileDefinition SFG_getMapTile -( - const SFG_Level *level, - int16_t x, - int16_t y, - uint8_t *properties -) -{ - if (x >= 0 && x < SFG_MAP_SIZE && y >= 0 && y < SFG_MAP_SIZE) - { - uint8_t tile = level->mapArray[y * SFG_MAP_SIZE + x]; - - *properties = tile & 0xc0; - return level->tileDictionary[tile & 0x3f]; - } - - *properties = SFG_TILE_PROPERTY_NORMAL; - return SFG_OUTSIDE_TILE; -} - -#define SFG_NUMBER_OF_LEVELS 10 - -/* - NOTE: Initially the levels were stored sequentially in one big array, but that - caused some issues with Arduino's PROGMEM, so now we store each level in a - separate variable and eventually create an array of pointers to these. -*/ - -SFG_PROGRAM_MEMORY SFG_Level SFG_level0 = - #include "/home/tastyfish/git/anarch/assets/tmp.txt" - ; - -SFG_PROGRAM_MEMORY SFG_Level SFG_level1 = - { // level - { // mapArray - #define o 0 - #define AA (21 | SFG_TILE_PROPERTY_DOOR) - #define BB (23 | SFG_TILE_PROPERTY_ELEVATOR) - #define CC (3 | SFG_TILE_PROPERTY_SQUEEZER) - #define DD (31 | SFG_TILE_PROPERTY_ELEVATOR) - #define EE (1 | SFG_TILE_PROPERTY_DOOR) - #define FF (22 | SFG_TILE_PROPERTY_DOOR) - #define GG (50 | SFG_TILE_PROPERTY_ELEVATOR) - #define HH (49 | SFG_TILE_PROPERTY_ELEVATOR) - #define II (48 | SFG_TILE_PROPERTY_ELEVATOR) - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 -/*0 */ 4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,6 ,7 ,7 ,7 ,7 ,6 ,7 ,7 ,7 ,7 ,6 ,6 ,6 ,6 ,6 ,7 ,7 ,6 ,6 ,6 ,9 ,9 ,9 ,9 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,12,6 ,6 ,6 ,12,6 ,6 ,6 ,12,6 ,6 ,6 ,12,6 ,6 ,6 ,12,6 ,6 , /*0 */ -/*1 */ 4 ,4 ,4 ,4 ,5 ,5 ,5 ,4 ,4 ,4 ,4 ,4 ,6 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,21,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,7 ,9 ,9 ,9 ,9 ,6 ,5 ,5 ,5 ,5 ,5 ,21,6 ,5 ,5 ,5 ,57,57,5 ,5 ,5 ,13,16,16,16,16,16,16,16,16,16,16,6 , /*1 */ -/*2 */ 4 ,4 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,4 ,4 ,4 ,6 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,21,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,7 ,9 ,9 ,9 ,9 ,6 ,28,28,28,5 ,5 ,21,4 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,16,16,16,16,16,16,16,16,16,16,16,15, /*2 */ -/*3 */ 4 ,4 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,4 ,4 ,4 ,6 ,54,54,54,54,4 ,8 ,8 ,8 ,8 ,21,8 ,8 ,4 ,54,54,54,54,54,6 ,9 ,9 ,9 ,9 ,6 ,21,21,28,5 ,5 ,21,21,57,5 ,5 ,5 ,5 ,5 ,5 ,5 ,16,16,16,16,16,16,16,16,16,16,16,6 , /*3 */ -/*4 */ 4 ,5 ,5 ,5 ,9 ,9 ,9 ,5 ,5 ,5 ,4 ,4 ,4 ,8 ,8 ,8 ,8 ,54,8 ,8 ,8 ,8 ,21,8 ,8 ,54,8 ,8 ,8 ,8 ,8 ,6 ,6 ,6 ,6 ,6 ,6 ,21,21,28,5 ,5 ,21,39,57,5 ,5 ,5 ,5 ,5 ,5 ,5 ,13,16,16,16,16,16,16,16,16,16,16,6 , /*4 */ -/*5 */ 4 ,5 ,5 ,5 ,9 ,9 ,9 ,5 ,5 ,5 ,8 ,8 ,AA,8 ,8 ,8 ,8 ,54,8 ,8 ,8 ,8 ,21,8 ,8 ,54,8 ,8 ,8 ,8 ,8 ,6 ,16,16,16,16,16,21,21,28,5 ,5 ,21,13,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,6 , /*5 */ -/*6 */ 4 ,5 ,5 ,5 ,9 ,9 ,9 ,5 ,5 ,5 ,4 ,4 ,4 ,8 ,8 ,8 ,8 ,54,8 ,8 ,8 ,8 ,21,8 ,8 ,54,8 ,8 ,8 ,8 ,8 ,6 ,16,16,16,16,16,63,21,28,5 ,5 ,21,39,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,57,6 , /*6 */ -/*7 */ 9 ,4 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,4 ,4 ,4 ,6 ,8 ,8 ,8 ,8 ,4 ,21,21,21,21,21,AA,21,4 ,8 ,8 ,8 ,8 ,8 ,6 ,16,16,16,16,16,63,21,28,5 ,5 ,21,21,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,57,6 , /*7 */ -/*8 */ 9 ,4 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,4 ,4 ,4 ,6 ,8 ,8 ,21,21,4 ,54,54,54,54,54,54,54,4 ,21,21,21,BB,BB,27,16,16,16,16,16,21,21,28,5 ,5 ,21,39,5 ,5 ,5 ,5 ,5 ,5 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 , /*8 */ -/*9 */ 10,10,4 ,4 ,5 ,5 ,5 ,4 ,4 ,4 ,4 ,4 ,6 ,8 ,8 ,8 ,8 ,54,8 ,8 ,8 ,8 ,8 ,8 ,8 ,54,8 ,8 ,21,BB,BB,27,16,16,17,17,17,21,21,28,5 ,5 ,21,13,5 ,5 ,5 ,5 ,5 ,5 ,4 ,5 ,5 ,5 ,5 ,53,53,53,53,5 ,5 ,5 ,56,6 , /*9 */ -/*10*/ 10,10,10,9 ,4 ,3 ,4 ,4 ,4 ,4 ,4 ,4 ,6 ,8 ,8 ,8 ,8 ,54,8 ,8 ,8 ,8 ,8 ,8 ,8 ,54,8 ,8 ,21,BB,BB,27,16,16,18,18,18,21,21,28,5 ,5 ,21,21,5 ,5 ,5 ,5 ,5 ,5 ,20,5 ,5 ,5 ,5 ,53,53,53,53,5 ,5 ,5 ,57,6 , /*10*/ -/*11*/ 10,10,10,9 ,9 ,9 ,9 ,1 ,6 ,6 ,15,6 ,6 ,6 ,6 ,6 ,6 ,6 ,7 ,7 ,7 ,7 ,7 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,19,19,19,21,21,28,5 ,5 ,21,21,59,5 ,5 ,5 ,5 ,5 ,21,5 ,5 ,5 ,5 ,53,53,53,53,1 ,13,13,13,1 , /*11*/ -/*12*/ 10,10,10,9 ,9 ,9 ,9 ,1 ,12,16,16,16,16,16,16,12,5 ,56,28,28,28,28,28,60,58,58,5 ,5 ,5 ,5 ,5 ,5 ,21,21,20,20,20,21,21,28,5 ,5 ,21,21,5 ,5 ,59,5 ,5 ,5 ,21,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,1 ,o ,o ,o ,1 , /*12*/ -/*13*/ 9 ,11,9 ,9 ,9 ,9 ,11,1 ,6 ,16,16,16,16,16,16,16,5 ,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,21,28,28,28,28,28,28,28,28,28,4 ,21,21,21,21,20,20,20,21,1 ,1 ,1 ,1 ,2 ,4 ,1 ,1 ,4 ,3 ,3 ,4 ,1 , /*13*/ -/*14*/ 9 ,11,9 ,9 ,9 ,9 ,11,1 ,6 ,16,16,16,16,16,16,16,5 ,25,5 ,5 ,5 ,5 ,5 ,5 ,56,5 ,5 ,5 ,5 ,5 ,5 ,5 ,20,28,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,21,21,21,21,o ,CC,CC,CC,o ,21,1 ,4 ,o ,o ,o ,o ,o ,o ,14,14,o ,1 , /*14*/ -/*15*/ 9 ,11,11,11,9 ,9 ,9 ,1 ,12,16,16,16,16,16,16,12,5 ,25,5 ,5 ,5 ,5 ,5 ,59,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,20,28,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,21,21,21,21,21,28,28,28,21,21,1 ,3 ,o ,o ,o ,o ,o ,o ,14,14,o ,1 , /*15*/ -/*16*/ 10,10,11,11,9 ,9 ,9 ,1 ,6 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,25,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,20,28,5 ,5 ,5 ,5 ,5 ,5 ,5 ,60,29,5 ,5 ,21,21,53,53,53,21,21,1 ,3 ,o ,o ,o ,o ,o ,o ,14,14,o ,1 , /*16*/ -/*17*/ 10,10,9 ,9 ,9 ,9 ,9 ,1 ,6 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,21,28,5 ,5 ,5 ,5 ,5 ,5 ,5 ,60,29,5 ,5 ,53,53,53,53,53,53,53,1 ,3 ,o ,o ,o ,o ,o ,o ,14,14,o ,1 , /*17*/ -/*18*/ 10,10,9 ,9 ,9 ,9 ,9 ,1 ,6 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,58,58,5 ,5 ,5 ,5 ,21,4 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,29,5 ,5 ,53,53,53,53,53,53,53,1 ,3 ,o ,o ,o ,o ,o ,o ,14,14,o ,1 , /*18*/ -/*19*/ 10,9 ,9 ,9 ,9 ,9 ,9 ,4 ,21,21,20,20,21,6 ,6 ,58,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,59,5 ,6 ,6 ,21,21,21,21,21,24,24,24,24,24,24,24,24,5 ,21,5 ,5 ,53,53,53,53,53,53,53,1 ,3 ,o ,o ,o ,o ,13,o ,14,14,o ,1 , /*19*/ -/*20*/ 10,10,10,9 ,9 ,9 ,9 ,8 ,8 ,8 ,20,20,8 ,6 ,6 ,58,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,6 ,6 ,31,30,30,31,31,31,31,31,31,31,30,31,31,6 ,6 ,5 ,5 ,53,53,53,53,53,53,53,1 ,3 ,o ,o ,o ,o ,1 ,o ,14,14,o ,1 , /*20*/ -/*21*/ 9 ,10,10,9 ,9 ,9 ,9 ,8 ,8 ,8 ,20,20,8 ,6 ,6 ,5 ,5 ,59,5 ,5 ,5 ,5 ,5 ,5 ,5 ,56,6 ,6 ,31,31,31,31,31,31,31,31,31,31,30,31,31,6 ,DD,8 ,8 ,53,53,53,53,53,53,53,1 ,3 ,3 ,3 ,3 ,3 ,1 ,3 ,3 ,3 ,3 ,1 , /*21*/ -/*22*/ 11,11,9 ,9 ,9 ,9 ,9 ,4 ,8 ,8 ,20,20,8 ,6 ,6 ,58,58,5 ,5 ,5 ,5 ,5 ,5 ,56,5 ,59,6 ,6 ,31,30,30,30,31,31,31,31,31,31,30,31,31,6 ,31,8 ,8 ,53,53,53,53,53,53,53,1 ,o ,o ,o ,o ,3 ,1 ,o ,14,14,o ,1 , /*22*/ -/*23*/ 11,11,9 ,9 ,9 ,9 ,9 ,21,8 ,8 ,20,20,8 ,8 ,8 ,58,58,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,57,6 ,6 ,31,30,31,30,30,31,31,31,31,31,30,31,31,31,31,8 ,8 ,53,53,53,53,53,53,53,1 ,o ,o ,o ,o ,3 ,1 ,o ,14,14,o ,1 , /*23*/ -/*24*/ 9 ,10,10,10,9 ,9 ,9 ,21,8 ,8 ,20,20,8 ,8 ,8 ,62,58,5 ,5 ,5 ,5 ,57,61,5 ,61,57,6 ,6 ,31,30,31,31,30,30,30,30,30,30,30,31,31,6 ,6 ,6 ,6 ,1 ,1 ,1 ,1 ,EE,1 ,1 ,1 ,o ,o ,o ,o ,3 ,1 ,o ,14,14,o ,1 , /*24*/ -/*25*/ 9 ,10,10,10,9 ,9 ,9 ,21,8 ,5 ,5 ,5 ,8 ,6 ,6 ,57,61,56,5 ,5 ,5 ,57,5 ,5 ,56,58,6 ,6 ,31,30,31,31,31,31,31,31,31,31,31,31,31,6 ,58,o ,o ,o ,1 ,o ,o ,o ,o ,o ,61,o ,o ,o ,o ,3 ,1 ,1 ,19,19,1 ,1 , /*25*/ -/*26*/ 9 ,10,10,10,9 ,9 ,9 ,21,8 ,5 ,5 ,5 ,8 ,6 ,12,57,5 ,5 ,5 ,5 ,5 ,5 ,56,5 ,5 ,5 ,12,6 ,31,30,31,31,31,31,31,31,31,31,31,31,31,6 ,58,o ,o ,o ,2 ,o ,o ,o ,o ,o ,EE,o ,o ,o ,o ,3 ,1 ,1 ,18,18,1 ,1 , /*26*/ -/*27*/ 9 ,11,11,9 ,9 ,9 ,9 ,20,5 ,5 ,5 ,5 ,8 ,6 ,6 ,61,5 ,5 ,5 ,5 ,5 ,5 ,5 ,59,58,5 ,6 ,6 ,31,31,31,31,31,31,31,31,31,31,31,31,31,6 ,1 ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,3 ,61,3 ,3 ,3 ,3 ,4 ,1 ,1 ,17,17,1 ,1 , /*27*/ -/*28*/ 9 ,11,11,9 ,9 ,9 ,9 ,21,8 ,8 ,8 ,8 ,8 ,21,6 ,58,5 ,5 ,5 ,5 ,5 ,5 ,5 ,56,5 ,5 ,6 ,6 ,31,30,31,31,31,31,31,31,31,31,31,31,31,6 ,58,o ,o ,o ,1 ,o ,o ,o ,o ,3 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,16,16,16,16,1 , /*28*/ -/*29*/ 1 ,1 ,1 ,1 ,1 ,1 ,20,20,20,20,20,20,20,21,6 ,58,5 ,5 ,5 ,5 ,5 ,5 ,5 ,58,5 ,56,6 ,6 ,31,30,31,30,30,30,30,30,30,30,31,31,31,6 ,58,o ,o ,o ,2 ,o ,o ,o ,o ,3 ,EE,5 ,5 ,5 ,5 ,5 ,1 ,16,16,16,16,1 , /*29*/ -/*30*/ 1 ,58,58,57,57,57,21,21,21,21,20,20,20,21,6 ,56,5 ,5 ,5 ,5 ,5 ,5 ,5 ,57,5 ,60,6 ,6 ,31,30,30,30,31,31,31,31,31,30,30,31,31,6 ,58,o ,o ,o ,1 ,o ,o ,o ,o ,3 ,1 ,o ,o ,o ,5 ,5 ,1 ,16,16,16,16,1 , /*30*/ -/*31*/ 1 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,1 ,21,20,20,20,21,6 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,59,5 ,6 ,6 ,31,31,31,31,31,31,31,31,31,31,30,31,31,6 ,58,o ,o ,1 ,1 ,o ,o ,o ,o ,3 ,1 ,o ,o ,o ,5 ,5 ,1 ,16,16,16,16,1 , /*31*/ -/*32*/ 1 ,5 ,58,58,5 ,1 ,5 ,57,57,21,20,20,20,21,21,21,21,21,20,20,20,20,21,4 ,7 ,7 ,6 ,6 ,31,31,31,31,31,31,31,31,31,31,30,31,31,6 ,58,o ,o ,o ,EE,o ,o ,o ,o ,3 ,EE,o ,o ,o ,5 ,5 ,1 ,16,16,16,16,1 , /*32*/ -/*33*/ 1 ,5 ,1 ,5 ,5 ,5 ,5 ,5 ,1 ,57,5 ,5 ,5 ,5 ,5 ,12,13,13,53,53,53,53,21,21,13,13,6 ,6 ,6 ,6 ,6 ,6 ,31,31,30,30,30,30,30,31,31,6 ,58,o ,o ,o ,1 ,o ,o ,o ,o ,3 ,1 ,5 ,5 ,5 ,5 ,5 ,1 ,16,16,16,16,1 , /*33*/ -/*34*/ 1 ,58,5 ,5 ,1 ,1 ,5 ,5 ,5 ,57,5 ,5 ,5 ,5 ,5 ,13,13,13,53,53,53,53,53,53,13,13,13,13,53,53,53,53,24,24,24,24,6 ,6 ,6 ,6 ,6 ,6 ,1 ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,3 ,1 ,1 ,1 ,1 ,16,16,1 ,16,16,16,16,15, /*34*/ -/*35*/ 1 ,5 ,5 ,1 ,5 ,5 ,5 ,57,5 ,57,5 ,5 ,5 ,5 ,5 ,13,13,13,53,53,53,53,53,53,13,5 ,5 ,13,53,53,53,53,53,53,53,53,6 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,2 ,o ,o ,o ,o ,3 ,2 ,o ,o ,1 ,16,16,1 ,16,16,16,16,21, /*35*/ -/*36*/ 1 ,5 ,1 ,1 ,5 ,57,1 ,5 ,1 ,1 ,1 ,5 ,5 ,5 ,5 ,12,13,13,53,53,53,53,53,5 ,5 ,5 ,5 ,5 ,5 ,53,53,53,13,13,13,13,13,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,o ,o ,o ,o ,3 ,1 ,o ,o ,21,16,16,16,16,21,27,27,21, /*36*/ -/*37*/ 1 ,19,18,1 ,5 ,1 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,53,13,13,53,53,53,53,13,5 ,5 ,5 ,5 ,5 ,5 ,13,13,13,13,13,4 ,61,1 ,2 ,1 ,1 ,2 ,1 ,1 ,2 ,1 ,61,4 ,o ,o ,o ,o ,3 ,1 ,o ,o ,21,16,16,16,16,21,BB,BB,21, /*37*/ -/*38*/ 1 ,57,17,1 ,5 ,1 ,5 ,57,57,5 ,58,5 ,5 ,5 ,5 ,53,53,13,13,13,13,13,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,13,13,13,1 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,o ,o ,o ,o ,3 ,4 ,o ,o ,21,21,21,21,21,21,8 ,8 ,21, /*38*/ -/*39*/ 1 ,16,16,1 ,5 ,5 ,5 ,58,5 ,5 ,58,5 ,5 ,5 ,5 ,12,53,53,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,59,57,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,1 ,o ,o ,1 ,o ,o ,21,7 ,7 ,54,54,4 , /*39*/ -/*40*/ 1 ,16,1 ,1 ,1 ,1 ,1 ,5 ,5 ,58,62,5 ,5 ,5 ,5 ,53,53,53,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,EE,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,1 ,1 ,1 ,1 ,o ,o ,21,7 ,8 ,8 ,54,21, /*40*/ -/*41*/ 1 ,16,1 ,16,16,16,16,1 ,5 ,5 ,62,5 ,5 ,5 ,5 ,53,53,53,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,EE,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,2 ,o ,o ,o ,o ,o ,21,7 ,8 ,8 ,54,21, /*41*/ -/*42*/ 1 ,16,16,16,16,16,1 ,1 ,58,5 ,62,59,5 ,5 ,5 ,12,53,53,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,59,57,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,1 ,o ,o ,o ,o ,o ,21,7 ,8 ,8 ,54,21, /*42*/ -/*43*/ 1 ,58,5 ,1 ,5 ,57,5 ,5 ,5 ,5 ,1 ,5 ,5 ,5 ,5 ,53,53,13,13,13,13,13,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,13,13,13,1 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,1 ,o ,o ,21,21,21,21,7 ,8 ,8 ,54,21, /*43*/ -/*44*/ 1 ,5 ,5 ,1 ,5 ,5 ,5 ,1 ,1 ,5 ,1 ,5 ,5 ,5 ,5 ,53,13,13,13,13,13,13,13,5 ,5 ,5 ,5 ,5 ,5 ,13,13,1 ,1 ,1 ,4 ,1 ,1 ,2 ,1 ,1 ,2 ,1 ,1 ,57,EE,57,1 ,1 ,1 ,EE,1 ,4 ,1 ,o ,o ,1 ,7 ,7 ,7 ,7 ,54,54,54,4 , /*44*/ -/*45*/ 1 ,5 ,5 ,5 ,57,1 ,1 ,5 ,58,5 ,1 ,5 ,56,5 ,5 ,12,13,13,13,13,13,13,13,13,5 ,5 ,5 ,5 ,13,13,13,1 ,o ,o ,o ,o ,o ,o ,1 ,o ,o ,22,22,22,FF,22,22,22,1 ,o ,1 ,1 ,1 ,o ,o ,1 ,8 ,8 ,8 ,8 ,8 ,8 ,54,1 , /*45*/ -/*46*/ 1 ,5 ,57,5 ,5 ,5 ,1 ,5 ,5 ,5 ,58,21,21,21,21,21,21,21,21,21,13,13,13,13,13,5 ,5 ,13,13,53,53,1 ,o ,o ,o ,o ,o ,o ,1 ,o ,o ,22,o ,o ,o ,o ,o ,22,1 ,o ,o ,o ,1 ,o ,o ,1 ,8 ,8 ,8 ,8 ,8 ,8 ,54,1 , /*46*/ -/*47*/ 1 ,58,57,1 ,1 ,5 ,58,58,1 ,1 ,58,21,5 ,5 ,5 ,5 ,56,5 ,5 ,21,13,13,13,13,13,5 ,5 ,13,13,53,53,EE,o ,o ,55,1 ,1 ,1 ,1 ,o ,o ,22,o ,o ,o ,o ,o ,22,1 ,o ,o ,o ,1 ,o ,o ,1 ,8 ,8 ,8 ,8 ,8 ,8 ,54,1 , /*47*/ -/*48*/ 6 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,20,5 ,5 ,5 ,5 ,5 ,5 ,5 ,20,53,53,53,EE,53,53,53,53,53,53,53,1 ,o ,o ,55,1 ,o ,o ,o ,o ,o ,22,o ,o ,o ,o ,o ,22,4 ,5 ,5 ,5 ,4 ,1 ,1 ,1 ,1 ,1 ,1 ,8 ,8 ,8 ,54,1 , /*48*/ -/*49*/ 7 ,57,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,20,5 ,5 ,5 ,5 ,5 ,5 ,5 ,20,53,53,53,1 ,53,53,53,53,53,53,53,1 ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,22,o ,o ,o ,o ,o ,22,1 ,8 ,8 ,8 ,54,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,54,1 , /*49*/ -/*50*/ 7 ,57,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,20,5 ,5 ,5 ,5 ,5 ,5 ,5 ,21,13,13,13,13,13,13,13,13,53,53,53,1 ,1 ,22,22,22,22,22,22,22,22,4 ,o ,o ,o ,o ,o ,22,1 ,8 ,8 ,8 ,54,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,54,1 , /*50*/ -/*51*/ 6 ,5 ,5 ,57,58,5 ,1 ,1 ,58,58,58,21,59,5 ,5 ,5 ,5 ,5 ,5 ,21,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,28,28,28,1 ,4 ,GG,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,o ,o ,o ,o ,o ,22,1 ,8 ,8 ,8 ,54,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,54,1 , /*51*/ -/*52*/ 6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,6 ,28,28,28,28,28,28,28,1 ,28,28,28,1 ,1 ,22,3 ,o ,o ,o ,o ,3 ,3 ,3 ,o ,o ,o ,o ,o ,22,1 ,8 ,8 ,8 ,54,54,54,54,54,54,54,54,54,54,54,4 , /*52*/ -/*53*/ 11,11,11,11,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,6 ,28,28,28,28,28,28,28,1 ,28,28,28,1 ,1 ,22,3 ,o ,o ,o ,o ,3 ,3 ,3 ,o ,o ,o ,o ,o ,22,1 ,8 ,8 ,1 ,4 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 , /*53*/ -/*54*/ 11,11,11,11,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,6 ,28,28,28,28,28,28,28,1 ,28,28,28,1 ,4 ,HH,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,o ,o ,o ,o ,o ,22,1 ,8 ,8 ,1 ,22,22,22,22,22,22,22,22,22,22,22,22, /*54*/ -/*55*/ 11,11,10,10,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,6 ,28,28,28,28,28,28,28,1 ,28,28,28,1 ,1 ,22,22,22,22,22,22,22,22,4 ,22,GG,HH,II,22,22,1 ,8 ,8 ,1 ,22,22,22,22,22,63,6 ,6 ,6 ,6 ,6 ,6 , /*55*/ -/*56*/ 6 ,10,10,10,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,6 ,o ,o ,o ,o ,1 ,26,26,1 ,28,28,28,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,63,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,1 ,22,5 ,5 ,56,5 ,5 ,5 ,56,6 ,6 ,6 ,6 , /*56*/ -/*57*/ 6 ,10,10,10,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,6 ,o ,o ,o ,o ,26,28,28,28,28,28,28,5 ,5 ,5 ,5 ,5 ,5 ,5 ,63,54,54,8 ,54,54,54,54,54,54,54,54,54,1 ,22,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,6 ,6 ,6 , /*57*/ -/*58*/ 6 ,6 ,6 ,6 ,6 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,6 ,o ,o ,o ,o ,26,28,28,28,28,28,28,5 ,5 ,5 ,5 ,5 ,5 ,5 ,1 ,28,28,28,28,28,28,28,28,28,28,12,12,12,22,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,4 ,6 ,6 , /*58*/ -/*59*/ 6 ,6 ,6 ,6 ,6 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,6 ,o ,o ,o ,o ,26,28,28,28,28,28,28,5 ,5 ,5 ,5 ,5 ,5 ,5 ,EE,28,28,28,28,28,28,28,28,28,28,28,FF,FF,FF,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,3 ,31,13, /*59*/ -/*60*/ 6 ,6 ,6 ,6 ,6 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,6 ,o ,o ,o ,o ,EE,28,28,28,28,28,28,5 ,5 ,5 ,5 ,5 ,5 ,5 ,1 ,28,28,28,28,28,28,28,28,28,28,12,12,12,22,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,4 ,6 ,6 , /*60*/ -/*61*/ 6 ,6 ,6 ,6 ,6 ,11,11,11,11,9 ,9 ,9 ,9 ,9 ,9 ,9 ,11,11,11,6 ,o ,o ,o ,o ,26,28,28,28,28,28,28,5 ,5 ,5 ,5 ,5 ,5 ,5 ,63,54,54,8 ,54,54,54,54,54,54,54,54,54,1 ,22,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,6 ,6 ,6 , /*61*/ -/*62*/ 9 ,9 ,9 ,9 ,9 ,11,11,11,11,10,10,10,10,10,10,10,11,11,11,6 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,1 ,26,26,26,1 ,63,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,1 ,22,5 ,5 ,5 ,5 ,5 ,5 ,59,6 ,6 ,6 ,6 , /*62*/ -/*63*/ 9 ,9 ,9 ,9 ,9 ,11,11,11,11,10,10,10,10,10,10,10,11,11,11,6 ,28,28,28,28,22,22,22,22,22,22,22,22,22,22,6 ,9 ,9 ,9 ,6 ,22,22,4 ,22,II,GG,HH,22,22,22,22,22,22,22,22,22,22,22,63,6 ,6 ,6 ,6 ,6 ,6 /*63*/ - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 - #undef AA - #undef BB - #undef CC - #undef DD - #undef EE - #undef FF - #undef GG - #undef HH - #undef II - #undef o - }, - { // tileDictionary - SFG_TD(14, 7,0,0),SFG_TD(18, 0,0,1),SFG_TD(18, 0,2,1),SFG_TD(14, 6,0,4), // 0 - SFG_TD(14, 0,4,4),SFG_TD(14,20,4,4),SFG_TD(29, 0,3,4),SFG_TD(27, 2,3,4), // 4 - SFG_TD(25, 6,4,4),SFG_TD(14,31,0,0),SFG_TD(26,31,1,0),SFG_TD(30,31,0,0), // 8 - SFG_TD(31, 0,2,2),SFG_TD(14, 0,6,6),SFG_TD(14, 8,0,0),SFG_TD(22, 0,2,3), // 12 - SFG_TD(18, 8,6,0),SFG_TD(17, 9,6,0),SFG_TD(16,10,6,0),SFG_TD(15,11,6,0), // 16 - SFG_TD(14, 7,3,3),SFG_TD(29, 0,3,3),SFG_TD(18, 0,5,2),SFG_TD(18, 7,4,0), // 20 - SFG_TD(14,20,3,4),SFG_TD(13,21,0,4),SFG_TD(16, 2,0,1),SFG_TD(18, 4,6,3), // 24 - SFG_TD(14,17,0,4),SFG_TD(18, 8,3,3),SFG_TD(13,21,0,0),SFG_TD( 4,30,0,0), // 28 - SFG_TD(14, 8,0,0),SFG_TD(14, 8,0,0),SFG_TD(14, 8,0,0),SFG_TD(14, 8,0,0), // 32 - SFG_TD(14, 8,0,0),SFG_TD(14, 8,0,0),SFG_TD(14, 8,0,0),SFG_TD(30, 0,3,6), // 36 - SFG_TD(14, 8,0,0),SFG_TD(14, 8,0,0),SFG_TD(14, 8,0,0),SFG_TD(14, 8,0,0), // 40 - SFG_TD(14, 8,0,0),SFG_TD(14, 8,0,0),SFG_TD(14, 8,0,0),SFG_TD(14, 8,0,0), // 44 - SFG_TD(29,17,5,5),SFG_TD(29,18,5,5),SFG_TD(29,19,5,5),SFG_TD(14, 8,0,0), // 48 - SFG_TD(14, 8,0,0),SFG_TD(14, 7,0,6),SFG_TD(25, 5,4,4),SFG_TD(16, 5,1,0), // 52 - SFG_TD(18,16,1,0),SFG_TD(22,12,1,0),SFG_TD(26, 8,0,0),SFG_TD(18,16,0,0), // 56 - SFG_TD(17,17,1,0),SFG_TD(21,13,0,0),SFG_TD(25, 9,1,0),SFG_TD(14, 0,5,5) // 60 - }, // tileDictionary - {0 ,4 ,7 ,5 ,11,15,3 }, // textureIndices - 7, // doorTextureIndex - 3, // floorColor - 18, // ceilingColor - {62, 2 , 144}, // player start: x, y, direction - 1, // backgroundImage - { // elements - {SFG_LEVEL_ELEMENT_BULLETS, {28,1}},{SFG_LEVEL_ELEMENT_BULLETS, {27,1}}, - {SFG_LEVEL_ELEMENT_BULLETS, {56,2}},{SFG_LEVEL_ELEMENT_HEALTH, {21,4}}, - {SFG_LEVEL_ELEMENT_LOCK1, {12,5}},{SFG_LEVEL_ELEMENT_CARD2, {10,5}}, - {SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {5,7}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {45,8}}, - {SFG_LEVEL_ELEMENT_BARREL, {45,9}},{SFG_LEVEL_ELEMENT_RUIN, {40,9}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {20,9}},{SFG_LEVEL_ELEMENT_RUIN, {41,10}}, - {SFG_LEVEL_ELEMENT_RUIN, {39,10}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {20,10}}, - {SFG_LEVEL_ELEMENT_HEALTH, {3,10}},{SFG_LEVEL_ELEMENT_RUIN, {39,11}}, - {SFG_LEVEL_ELEMENT_HEALTH, {61,12}},{SFG_LEVEL_ELEMENT_BULLETS, {58,12}}, - {SFG_LEVEL_ELEMENT_BULLETS, {57,12}},{SFG_LEVEL_ELEMENT_HEALTH, {11,12}}, - {SFG_LEVEL_ELEMENT_BULLETS, {41,15}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {23,15}}, - {SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {36,16}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {18,16}}, - {SFG_LEVEL_ELEMENT_BULLETS, {53,17}},{SFG_LEVEL_ELEMENT_BULLETS, {53,18}}, - {SFG_LEVEL_ELEMENT_TERMINAL, {14,18}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {24,19}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {7,20}},{SFG_LEVEL_ELEMENT_BULLETS, {7,21}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {61,23}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {42,23}}, - {SFG_LEVEL_ELEMENT_BARREL, {23,23}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {61,26}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {37,26}},{SFG_LEVEL_ELEMENT_HEALTH, {43,28}}, - {SFG_LEVEL_ELEMENT_BULLETS, {16,28}},{SFG_LEVEL_ELEMENT_RUIN, {53,29}}, - {SFG_LEVEL_ELEMENT_BULLETS, {16,29}},{SFG_LEVEL_ELEMENT_HEALTH, {57,31}}, - {SFG_LEVEL_ELEMENT_RUIN, {44,31}},{SFG_LEVEL_ELEMENT_BULLETS, {43,32}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {43,39}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {41,39}}, - {SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {26,40}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {41,41}}, - {SFG_LEVEL_ELEMENT_HEALTH, {36,45}},{SFG_LEVEL_ELEMENT_BULLETS, {35,45}}, - {SFG_LEVEL_ELEMENT_TREE, {32,45}},{SFG_LEVEL_ELEMENT_BULLETS, {7,45}}, - {SFG_LEVEL_ELEMENT_TERMINAL, {37,46}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {43,47}}, - {SFG_LEVEL_ELEMENT_LOCK1, {23,48}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {44,50}}, - {SFG_LEVEL_ELEMENT_COLUMN, {29,50}},{SFG_LEVEL_ELEMENT_HEALTH, {39,52}}, - {SFG_LEVEL_ELEMENT_TERMINAL, {34,52}},{SFG_LEVEL_ELEMENT_BULLETS, {39,53}}, - {SFG_LEVEL_ELEMENT_TERMINAL, {34,53}},{SFG_LEVEL_ELEMENT_TELEPORTER, {46,54}}, - {SFG_LEVEL_ELEMENT_TELEPORTER, {35,54}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {9,54}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {25,55}},{SFG_LEVEL_ELEMENT_BARREL, {18,55}}, - {SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {11,55}},{SFG_LEVEL_ELEMENT_TERMINAL, {57,56}}, - {SFG_LEVEL_ELEMENT_COLUMN, {23,56}},{SFG_LEVEL_ELEMENT_COLUMN, {20,56}}, - {SFG_LEVEL_ELEMENT_HEALTH, {4,56}},{SFG_LEVEL_ELEMENT_TREE, {37,57}}, - {SFG_LEVEL_ELEMENT_TREE, {32,57}},{SFG_LEVEL_ELEMENT_BULLETS, {20,58}}, - {SFG_LEVEL_ELEMENT_CARD1, {8,58}},{SFG_LEVEL_ELEMENT_FINISH, {62,59}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {58,59}},{SFG_LEVEL_ELEMENT_LOCK2, {52,59}}, - {SFG_LEVEL_ELEMENT_CARD0, {41,59}},{SFG_LEVEL_ELEMENT_LOCK0, {38,59}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {28,59}},{SFG_LEVEL_ELEMENT_BULLETS, {20,60}}, - {SFG_LEVEL_ELEMENT_TREE, {37,61}},{SFG_LEVEL_ELEMENT_TREE, {32,61}}, - {SFG_LEVEL_ELEMENT_TERMINAL, {57,62}},{SFG_LEVEL_ELEMENT_ROCKETS, {49,62}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}} - }, // elements - } // level - ; - -SFG_PROGRAM_MEMORY SFG_Level SFG_level2 = - { // level - { // mapArray - #define o 0 - #define AA (20 | SFG_TILE_PROPERTY_DOOR) - #define BB (32 | SFG_TILE_PROPERTY_DOOR) - #define CC (22 | SFG_TILE_PROPERTY_ELEVATOR) - #define DD (40 | SFG_TILE_PROPERTY_SQUEEZER) - #define EE (44 | SFG_TILE_PROPERTY_DOOR) - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 -/*0 */ 23,23,23,23,23,23,23,23,23,20,4 ,4 ,4 ,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 , /*0 */ -/*1 */ 23,22,22,22,22,22,22,22,22,16,16,4 ,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,20,16,16,16,16,16,20,4 ,2 ,2 ,2 ,48,3 ,3 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,2 ,o ,o ,48,4 ,4 ,4 ,4 ,4 ,4 ,4 , /*1 */ -/*2 */ 23,22,22,22,22,22,22,22,22,o ,o ,3 ,o ,o ,18,18,18,18,18,18,18,o ,o ,46,o ,o ,o ,o ,o ,16,20,21,19,19,19,19,4 ,2 ,2 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,2 ,2 ,48,4 ,3 ,o ,5 ,5 ,3 ,4 ,4 ,4 ,4 ,4 ,4 ,4 , /*2 */ -/*3 */ 23,22,22,22,22,22,22,22,22,17,17,3 ,17,17,18,18,18,18,18,18,18,17,17,47,17,17,17,17,o ,16,AA,19,19,19,19,19,2 ,o ,o ,5 ,5 ,o ,o ,3 ,48,4 ,5 ,5 ,o ,o ,o ,o ,o ,o ,o ,o ,4 ,4 ,6 ,7 ,6 ,4 ,4 ,4 , /*3 */ -/*4 */ 23,22,22,22,22,22,22,22,22,o ,3 ,o ,o ,o ,18,18,18,18,18,18,18,o ,o ,46,o ,o ,o ,17,o ,16,20,19,19,19,19,19,3 ,o ,o ,o ,o ,2 ,4 ,4 ,4 ,4 ,2 ,o ,3 ,3 ,4 ,o ,2 ,4 ,4 ,4 ,4 ,4 ,10,11,11,4 ,4 ,4 , /*4 */ -/*5 */ 23,22,22,22,22,22,22,22,22,16,4 ,4 ,16,16,16,16,16,16,16,16,16,16,16,16,16,16,o ,17,o ,16,20,16,16,16,16,16,20,20,20,20,20,20,20,20,20,4 ,4 ,4 ,4 ,4 ,4 ,8 ,4 ,4 ,4 ,4 ,9 ,9 ,10,4 ,11,12,4 ,4 , /*5 */ -/*6 */ 23,22,22,22,22,22,23,23,23,20,4 ,4 ,4 ,20,20,20,20,20,20,20,20,20,20,20,20,16,o ,17,o ,16,20,20,20,AA,20,20,20,19,19,19,19,19,19,19,20,4 ,4 ,4 ,4 ,4 ,9 ,9 ,4 ,4 ,4 ,4 ,9 ,4 ,4 ,4 ,4 ,12,4 ,4 , /*6 */ -/*7 */ 23,22,22,22,22,22,23,23,23,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,16,o ,17,o ,16,20,20,20,19,19,19,19,19,19,19,19,19,19,19,20,4 ,4 ,4 ,4 ,10,10,9 ,10,11,4 ,8 ,8 ,4 ,4 ,13,13,12,4 ,4 , /*7 */ -/*8 */ 23,22,22,22,22,22,23,23,23,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,4 ,3 ,18,18,18,16,20,20,20,20,20,20,20,20,20,24,24,29,29,29,20,4 ,4 ,4 ,11,11,4 ,4 ,4 ,12,12,8 ,4 ,4 ,13,13,4 ,4 ,4 ,4 , /*8 */ -/*9 */ 23,22,22,22,22,22,23,23,23,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,4 ,4 ,18,18,18,16,20,29,29,29,29,29,29,29,20,25,25,29,29,29,20,4 ,4 ,12,12,4 ,4 ,4 ,4 ,4 ,4 ,8 ,4 ,4 ,13,4 ,4 ,4 ,4 ,4 , /*9 */ -/*10*/ 30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,20,20,20,4 ,3 ,18,18,18,3 ,20,29,29,29,29,29,29,29,20,26,26,29,20,29,20,4 ,4 ,12,12,4 ,4 ,15,9 ,9 ,8 ,8 ,13,13,13,13,15,4 ,4 ,4 , /*10*/ -/*11*/ 30,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,41,o ,o ,20,16,18,18,18,16,20,29,29,34,34,34,29,29,20,27,27,29,20,29,20,4 ,4 ,13,13,4 ,4 ,15,8 ,8 ,8 ,8 ,13,13,13,13,13,15,4 ,4 , /*11*/ -/*12*/ 30,40,41,41,41,41,41,40,40,40,40,40,41,41,41,41,41,41,40,40,40,41,o ,o ,20,16,18,18,18,16,20,29,29,34,34,34,29,29,20,28,28,29,20,29,20,4 ,4 ,13,13,13,4 ,13,8 ,8 ,8 ,8 ,13,13,4 ,13,13,13,4 ,4 , /*12*/ -/*13*/ 30,40,41,40,40,40,41,41,41,41,40,40,41,40,40,40,40,41,40,40,40,41,o ,o ,31,16,18,18,18,16,20,29,29,29,29,29,29,29,20,29,29,29,20,29,20,4 ,4 ,4 ,4 ,13,4 ,8 ,8 ,8 ,8 ,8 ,13,13,4 ,4 ,13,13,6 ,4 , /*13*/ -/*14*/ 30,40,41,40,40,40,40,40,40,41,40,40,41,40,40,41,41,41,40,40,40,41,o ,o ,32,16,18,18,18,16,20,29,29,29,29,29,29,29,20,29,29,29,20,29,20,4 ,4 ,4 ,4 ,13,13,8 ,8 ,8 ,8 ,8 ,12,13,4 ,6 ,13,13,7 ,4 , /*14*/ -/*15*/ 30,40,41,40,40,40,40,40,40,41,41,41,41,40,40,41,40,40,40,40,42,41,o ,36,31,16,o ,17,o ,16,20,20,20,29,29,29,20,20,20,32,32,32,32,29,20,20,4 ,4 ,4 ,13,13,8 ,8 ,8 ,8 ,8 ,8 ,13,4 ,7 ,12,12,6 ,4 , /*15*/ -/*16*/ 30,40,41,40,40,40,40,40,40,40,40,40,40,40,40,41,40,40,40,40,43,41,o ,35,20,16,o ,17,o ,16,20,19,19,28,28,28,19,19,20,29,29,29,29,29,29,20,4 ,4 ,4 ,13,13,8 ,8 ,8 ,8 ,8 ,8 ,13,13,6 ,11,11,4 ,4 , /*16*/ -/*17*/ 30,40,41,41,41,41,41,41,40,40,40,40,40,40,40,41,40,40,41,41,41,41,o ,16,AA,16,o ,17,o ,16,20,19,19,27,27,27,19,19,20,29,30,31,31,30,29,31,4 ,4 ,4 ,13,13,12,8 ,8 ,8 ,8 ,12,13,13,4 ,11,10,10,4 , /*17*/ -/*18*/ 30,40,40,40,40,40,40,41,40,40,40,40,40,41,40,41,40,40,41,40,43,41,o ,35,20,16,o ,17,o ,16,20,19,19,26,26,26,19,19,20,29,31,31,31,31,29,30,4 ,4 ,4 ,4 ,13,13,13,13,10,13,13,13,4 ,4 ,4 ,10,9 ,4 , /*18*/ -/*19*/ 30,40,40,40,40,40,40,41,40,40,41,40,40,41,40,41,40,40,41,40,42,41,o ,36,31,16,o ,17,o ,16,20,19,19,25,25,25,19,19,20,29,31,31,31,31,29,30,4 ,4 ,15,15,15,13,13,13,13,13,13,4 ,4 ,4 ,4 ,9 ,9 ,4 , /*19*/ -/*20*/ 30,41,41,41,41,40,40,41,41,41,41,40,40,41,40,41,41,41,41,40,40,41,o ,o ,32,16,o ,17,o ,16,20,19,19,24,24,24,19,19,20,29,30,31,31,30,29,31,4 ,4 ,15,4 ,15,4 ,4 ,14,4 ,4 ,4 ,4 ,4 ,4 ,8 ,8 ,8 ,4 , /*20*/ -/*21*/ 30,40,40,40,40,40,40,40,40,40,41,40,40,41,40,40,40,40,40,40,40,41,o ,o ,31,16,o ,17,o ,16,20,19,19,19,19,19,19,19,20,29,29,29,29,29,29,20,4 ,4 ,15,4 ,11,11,11,12,4 ,4 ,o ,o ,3 ,4 ,8 ,8 ,4 ,4 , /*21*/ -/*22*/ 30,40,40,40,40,40,40,40,40,40,41,40,40,41,40,40,40,40,40,40,40,41,o ,o ,20,16,o ,17,o ,16,16,19,19,19,19,25,21,19,20,24,25,26,27,28,28,20,4 ,4 ,15,15,4 ,11,4 ,4 ,4 ,o ,5 ,5 ,o ,1 ,o ,4 ,4 ,4 , /*22*/ -/*23*/ 30,40,41,41,41,41,41,41,40,40,41,40,30,30,30,30,30,30,30,30,30,20,20,20,20,16,o ,17,o ,16,16,19,19,19,19,25,34,19,20,19,19,19,19,19,19,20,4 ,4 ,4 ,15,15,8 ,33,4 ,4 ,48,o ,o ,3 ,4 ,4 ,4 ,4 ,4 , /*23*/ -/*24*/ 30,40,41,40,40,40,40,41,41,40,41,40,30,31,31,31,31,31,31,31,31,31,31,31,20,16,o ,17,o ,16,16,19,19,19,19,19,19,19,20,19,19,19,19,19,19,20,4 ,4 ,4 ,4 ,4 ,14,14,4 ,4 ,2 ,3 ,6 ,4 ,4 ,4 ,4 ,4 ,4 , /*24*/ -/*25*/ 30,40,41,40,40,40,40,40,41,41,41,40,30,31,o ,o ,o ,o ,o ,o ,o ,o ,o ,31,31,16,o ,17,o ,16,16,19,19,19,19,19,19,21,20,19,19,19,19,19,19,20,4 ,4 ,4 ,14,14,14,14,3 ,3 ,3 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 , /*25*/ -/*26*/ 30,40,41,41,41,41,40,40,40,40,40,40,30,31,o ,o ,o ,o ,o ,o ,o ,o ,o ,31,32,16,o ,17,o ,16,16,19,19,19,19,19,19,19,20,19,19,19,19,19,19,20,20,4 ,14,14,14,14,4 ,4 ,2 ,3 ,4 ,2 ,3 ,3 ,2 ,4 ,4 ,4 , /*26*/ -/*27*/ 30,40,40,40,40,41,41,40,40,40,40,40,30,31,o ,o ,o ,o ,o ,o ,o ,o ,o ,31,31,16,o ,17,o ,16,16,19,19,19,19,19,19,19,20,21,19,19,19,19,19,19,20,4 ,14,14,14,4 ,4 ,3 ,o ,o ,3 ,o ,o ,o ,o ,3 ,4 ,4 , /*27*/ -/*28*/ 30,40,40,40,40,40,41,40,40,40,40,40,30,31,o ,o ,o ,o ,o ,o ,o ,o ,o ,31,20,16,o ,17,o ,16,16,19,19,19,19,25,34,19,20,19,19,21,19,19,19,19,20,4 ,14,14,14,4 ,3 ,o ,o ,o ,o ,o ,5 ,5 ,5 ,1 ,4 ,4 , /*28*/ -/*29*/ 30,40,40,40,40,40,41,40,40,40,40,40,30,31,o ,o ,o ,o ,o ,o ,o ,o ,o ,31,20,16,o ,17,o ,16,16,19,19,19,19,25,21,19,20,20,20,20,20,20,16,16,20,4 ,14,14,14,8 ,o ,o ,2 ,o ,o ,o ,o ,o ,5 ,o ,3 ,4 , /*29*/ -/*30*/ 30,40,30,40,40,41,41,41,40,40,30,40,30,31,o ,o ,o ,47,31,6 ,36,36,36,31,20,16,o ,17,o ,16,20,19,19,19,19,19,19,19,20,29,29,29,20,20,16,16,32,4 ,14,14,8 ,8 ,o ,3 ,3 ,3 ,o ,o ,4 ,3 ,o ,5 ,o ,4 , /*30*/ -/*31*/ 30,43,30,41,41,41,41,41,41,41,30,43,30,31,o ,o ,o ,o ,46,o ,35,35,35,31,31,16,o ,17,o ,16,20,19,19,24,24,24,19,19,20,29,29,29,20,20,16,16,32,4 ,4 ,4 ,8 ,o ,4 ,4 ,4 ,4 ,o ,4 ,4 ,4 ,o ,5 ,o ,4 , /*31*/ -/*32*/ 30,42,30,40,40,30,30,30,40,40,30,42,30,31,o ,o ,o ,47,46,o ,16,16,16,31,32,16,o ,17,o ,16,20,19,19,25,25,25,19,19,20,29,29,29,20,20,16,16,20,20,20,20,3 ,o ,4 ,4 ,4 ,4 ,2 ,4 ,4 ,4 ,o ,5 ,o ,4 , /*32*/ -/*33*/ 30,40,40,40,40,30,30,30,40,40,40,40,30,31,4 ,3 ,3 ,31,31,31,32,BB,32,32,31,16,o ,17,o ,16,20,19,19,26,26,26,19,19,20,29,29,29,20,20,19,19,19,19,19,20,3 ,o ,o ,4 ,4 ,3 ,3 ,4 ,4 ,4 ,3 ,o ,1 ,4 , /*33*/ -/*34*/ 30,30,30,30,30,30,30,30,30,30,30,30,30,4 ,4 ,o ,o ,4 ,4 ,32,16,16,16,16,20,16,o ,17,o ,16,20,19,19,27,27,27,19,19,20,29,29,29,20,20,19,19,19,19,19,20,6 ,o ,o ,o ,4 ,4 ,4 ,4 ,4 ,3 ,2 ,48,4 ,4 , /*34*/ -/*35*/ 30,30,30,30,30,30,30,30,30,30,30,30,30,4 ,2 ,o ,o ,2 ,4 ,32,16,16,16,16,20,16,o ,17,o ,16,20,19,19,28,28,28,19,19,20,29,29,29,20,20,19,19,19,19,19,20,4 ,o ,5 ,o ,1 ,4 ,4 ,4 ,1 ,3 ,4 ,4 ,4 ,4 , /*35*/ -/*36*/ 30,30,30,30,30,30,30,30,30,30,30,30,30,4 ,4 ,o ,o ,o ,4 ,32,16,16,16,16,20,16,o ,17,o ,16,16,20,20,29,29,29,20,20,20,29,29,29,20,34,19,25,25,25,19,34,4 ,3 ,o ,5 ,o ,3 ,3 ,1 ,2 ,2 ,4 ,4 ,4 ,4 , /*36*/ -/*37*/ 30,30,30,30,30,30,30,30,30,30,30,30,30,32,32,4 ,3 ,3 ,4 ,32,16,16,16,16,31,16,o ,17,o ,16,20,29,29,29,29,29,29,29,29,29,29,29,20,34,19,25,25,25,19,34,4 ,4 ,3 ,o ,2 ,3 ,3 ,1 ,o ,o ,3 ,4 ,4 ,4 , /*37*/ -/*38*/ 30,40,40,40,40,40,40,40,40,40,42,43,41,o ,o ,o ,o ,36,35,32,16,16,16,16,32,16,o ,17,o ,16,20,29,29,29,29,29,29,29,29,29,29,29,20,34,19,25,25,25,19,34,4 ,4 ,4 ,4 ,3 ,3 ,4 ,4 ,o ,5 ,o ,3 ,6 ,6 , /*38*/ -/*39*/ 30,40,41,40,40,40,40,40,40,40,42,43,41,o ,o ,o ,o ,o ,16,BB,16,16,16,16,31,16,o ,17,o ,16,20,20,20,34,34,34,20,20,20,20,20,20,20,20,19,19,19,19,19,20,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,o ,5 ,5 ,o ,o ,7 , /*39*/ -/*40*/ 30,40,40,40,40,40,40,40,40,40,40,40,41,o ,o ,o ,o ,36,35,32,16,16,16,16,20,16,o ,17,o ,16,34,20,20,20,20,20,20,34,34,34,20,20,20,20,20,20,20,20,20,20,4 ,4 ,4 ,4 ,4 ,4 ,4 ,2 ,o ,5 ,o ,3 ,6 ,6 , /*40*/ -/*41*/ 30,40,40,40,40,40,40,40,40,40,40,40,30,32,32,38,38,38,32,32,16,16,16,16,20,16,o ,17,o ,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,20,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,2 ,o ,o ,o ,o ,4 ,4 ,4 , /*41*/ -/*42*/ 30,40,40,40,40,40,40,40,40,40,40,40,30,o ,o ,o ,o ,o ,o ,32,16,16,34,AA,20,16,o ,17,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,16,34,20,7 ,7 ,7 ,7 ,7 ,4 ,4 ,1 ,5 ,o ,o ,3 ,4 ,4 ,4 , /*42*/ -/*43*/ 30,40,40,40,40,40,40,40,40,40,40,40,30,o ,o ,o ,o ,o ,o ,32,16,16,34,16,16,16,o ,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,o ,16,16,31,7 ,7 ,o ,o ,7 ,7 ,4 ,1 ,5 ,o ,2 ,3 ,4 ,4 ,4 , /*43*/ -/*44*/ 30,40,40,40,42,43,41,43,42,40,40,40,41,o ,o ,o ,o ,o ,o ,32,32,32,34,34,20,16,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,17,o ,16,34,20,7 ,o ,o ,o ,o ,7 ,4 ,3 ,5 ,5 ,o ,2 ,4 ,4 ,4 , /*44*/ -/*45*/ 30,30,30,30,30,30,41,30,30,30,30,30,30,o ,30,o ,30,o ,30,32,32,32,20,20,20,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,o ,17,o ,16,20,7 ,7 ,o ,o ,o ,o ,7 ,4 ,4 ,o ,5 ,5 ,o ,4 ,4 ,4 , /*45*/ -/*46*/ 44,44,44,44,44,34,46,34,44,44,44,44,44,32,32,32,32,32,32,32,32,32,20,20,20,20,20,31,32,31,20,20,31,32,31,20,20,31,16,31,20,20,16,o ,17,o ,16,20,7 ,o ,o ,o ,o ,7 ,7 ,4 ,4 ,3 ,o ,o ,o ,o ,4 ,4 , /*46*/ -/*47*/ 44,46,46,46,39,o ,o ,o ,39,46,46,46,44,44,44,44,44,44,44,20,20,20,20,30,32,32,16,32,32,30,20,20,20,20,20,20,20,32,32,32,20,20,16,o ,17,o ,16,20,7 ,o ,o ,o ,o ,7 ,4 ,4 ,1 ,3 ,3 ,o ,o ,o ,3 ,4 , /*47*/ -/*48*/ 44,46,46,46,39,o ,o ,o ,39,46,46,46,44,CC,CC,CC,CC,CC,44,20,20,16,16,16,16,16,16,16,16,16,16,16,20,20,20,20,20,20,20,20,20,20,16,o ,17,o ,16,20,7 ,7 ,o ,o ,7 ,7 ,4 ,1 ,1 ,3 ,3 ,4 ,o ,5 ,o ,4 , /*48*/ -/*49*/ 44,46,46,46,39,o ,o ,o ,39,46,46,46,44,CC,DD,DD,DD,CC,44,20,31,16,16,16,16,16,16,16,16,16,16,16,31,16,16,16,16,16,16,16,16,20,16,o ,17,o ,16,20,7 ,7 ,7 ,o ,7 ,6 ,4 ,1 ,3 ,3 ,3 ,4 ,o ,5 ,o ,4 , /*49*/ -/*50*/ 44,46,46,46,39,o ,o ,o ,39,46,46,46,44,CC,DD,DD,DD,CC,44,20,31,16,16,16,16,16,16,16,16,16,16,16,31,16,16,16,16,16,16,16,16,AA,16,o ,17,o ,16,20,4 ,4 ,6 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,4 ,4 ,4 ,o ,3 ,4 , /*50*/ -/*51*/ 44,44,EE,44,44,o ,o ,o ,44,44,EE,44,44,CC,DD,DD,DD,CC,44,20,20,16,16,16,16,16,16,16,16,16,16,16,20,20,20,20,16,16,20,20,20,20,3 ,3 ,3 ,3 ,4 ,4 ,4 ,4 ,6 ,6 ,6 ,4 ,3 ,3 ,3 ,3 ,4 ,4 ,4 ,4 ,4 ,4 , /*51*/ -/*52*/ 44,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,44,CC,CC,CC,CC,CC,44,20,20,16,16,16,20,20,20,20,20,16,16,16,20,20,20,20,16,16,20,16,16,AA,16,o ,17,3 ,3 ,4 ,4 ,4 ,4 ,4 ,4 ,3 ,3 ,o ,o ,3 ,1 ,3 ,4 ,4 ,4 ,4 , /*52*/ -/*53*/ 44,44,44,44,34,o ,o ,o ,34,44,44,44,44,36,36,36,36,36,44,35,35,16,16,16,35,35,37,35,35,16,16,16,35,35,37,20,16,16,20,16,16,20,16,o ,17,o ,16,20,4 ,4 ,4 ,4 ,3 ,2 ,o ,o ,o ,o ,o ,1 ,3 ,4 ,4 ,4 , /*53*/ -/*54*/ 4 ,4 ,4 ,4 ,44,o ,o ,o ,44,36,46,46,46,46,46,46,46,46,44,36,36,o ,o ,o ,36,36,37,36,36,o ,o ,o ,36,36,37,20,16,16,20,16,16,20,16,o ,17,o ,16,20,4 ,4 ,3 ,48,2 ,o ,o ,o ,5 ,5 ,o ,o ,1 ,4 ,4 ,4 , /*54*/ -/*55*/ 4 ,4 ,4 ,4 ,44,o ,o ,o ,44,36,46,o ,o ,o ,o ,o ,o ,o ,44,o ,o ,o ,o ,o ,o ,o ,37,46,o ,o ,o ,o ,o ,46,37,20,16,16,34,16,16,20,16,o ,17,o ,16,20,5 ,5 ,o ,o ,o ,o ,5 ,5 ,5 ,5 ,5 ,o ,1 ,1 ,4 ,4 , /*55*/ -/*56*/ 4 ,4 ,4 ,44,44,o ,o ,o ,44,36,46,45,45,o ,45,45,o ,o ,44,o ,o ,o ,o ,o ,o ,o ,37,46,o ,o ,o ,o ,o ,46,37,20,16,16,16,16,16,20,16,o ,17,o ,3 ,4 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,o ,o ,o ,o ,o ,o ,1 ,4 ,4 , /*56*/ -/*57*/ 4 ,4 ,4 ,o ,o ,o ,o ,o ,o ,o ,46,45,45,o ,45,45,o ,o ,o ,o ,o ,o ,o ,o ,o ,30,37,46,o ,36,36,36,o ,46,37,20,16,16,16,16,16,20,16,o ,17,o ,o ,3 ,o ,5 ,5 ,5 ,o ,o ,o ,2 ,3 ,48,1 ,o ,5 ,5 ,5 ,6 , /*57*/ -/*58*/ 4 ,4 ,4 ,o ,o ,o ,o ,o ,o ,o ,46,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,46,37,46,o ,36,36,36,o ,46,37,20,16,16,16,16,16,20,16,o ,17,o ,o ,3 ,2 ,o ,o ,o ,o ,2 ,2 ,4 ,4 ,4 ,4 ,1 ,o ,5 ,5 ,6 , /*58*/ -/*59*/ 4 ,4 ,4 ,4 ,2 ,o ,o ,o ,o ,o ,46,45,45,o ,45,45,o ,o ,o ,o ,o ,o ,o ,o ,o ,46,37,46,o ,36,36,36,o ,46,37,20,31,31,31,31,31,20,16,o ,17,o ,3 ,4 ,2 ,2 ,o ,o ,2 ,2 ,4 ,4 ,4 ,4 ,4 ,3 ,1 ,o ,o ,4 , /*59*/ -/*60*/ 4 ,4 ,4 ,4 ,4 ,4 ,4 ,3 ,o ,o ,46,45,45,o ,45,45,o ,o ,o ,o ,30,46,46,46,46,46,37,46,o ,o ,o ,o ,o ,46,37,20,20,20,20,20,20,20,16,o ,17,o ,16,20,2 ,2 ,2 ,2 ,2 ,3 ,4 ,4 ,4 ,4 ,4 ,4 ,3 ,3 ,4 ,4 , /*60*/ -/*61*/ 4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,3 ,46,o ,o ,o ,o ,o ,o ,o ,37,37,37,37,37,37,37,37,37,30,o ,o ,o ,o ,o ,30,37,20,20,20,20,20,20,20,16,o ,17,22,16,20,2 ,2 ,2 ,3 ,4 ,3 ,3 ,4 ,3 ,3 ,3 ,4 ,4 ,4 ,4 ,4 , /*61*/ -/*62*/ 4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,2 ,2 ,o ,o ,3 ,3 ,37,4 ,4 ,4 ,4 ,4 ,4 ,4 ,32,32,32,32,CC,32,32,32,32,20,20,20,20,20,20,20,4 ,3 ,17,2 ,3 ,20,3 ,3 ,4 ,4 ,4 ,4 ,3 ,3 ,3 ,4 ,4 ,4 ,4 ,4 ,4 ,4 , /*62*/ -/*63*/ 4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,32,32,32,32,32,32,32,32,32,20,20,20,20,20,20,20,20,4 ,4 ,4 ,4 ,20,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 /*63*/ - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 - #undef AA - #undef BB - #undef CC - #undef DD - #undef EE - #undef o - }, - { // tileDictionary - SFG_TD(14,10,0,0),SFG_TD(16, 8,0,0),SFG_TD(14, 8,0,0),SFG_TD(16, 6,0,0), // 0 - SFG_TD(14, 0,0,0),SFG_TD(13,12,0,0),SFG_TD(21, 0,1,1),SFG_TD(14, 0,2,2), // 4 - SFG_TD(14,24,0,0),SFG_TD(16,22,0,0),SFG_TD(18,20,0,0),SFG_TD(20,18,0,0), // 8 - SFG_TD(22,16,0,0),SFG_TD(24,14,0,0),SFG_TD(24, 4,0,0),SFG_TD(31, 7,0,0), // 12 - SFG_TD(17, 5,1,1),SFG_TD(15, 9,3,0),SFG_TD(23, 1,3,0),SFG_TD(17,10,1,1), // 16 - SFG_TD(21, 0,1,4),SFG_TD(22, 5,5,1),SFG_TD(14,31,3,0),SFG_TD(26, 0,1,7), // 20 - SFG_TD(18, 9,1,1),SFG_TD(19, 8,1,1),SFG_TD(20, 7,1,1),SFG_TD(21, 6,1,1), // 24 - SFG_TD(22, 5,1,1),SFG_TD(23, 4,1,1),SFG_TD(21, 0,3,3),SFG_TD(21, 0,5,5), // 28 - SFG_TD(21, 0,6,6),SFG_TD(14, 4,0,0),SFG_TD(21, 0,4,4),SFG_TD(16, 6,1,1), // 32 - SFG_TD(15, 7,1,1),SFG_TD(21, 0,5,1),SFG_TD(17, 2,6,6),SFG_TD(16, 3,1,1), // 36 - SFG_TD( 9,15,1,3),SFG_TD(14, 4,3,3),SFG_TD(11,13,3,3),SFG_TD(13,11,3,3), // 40 - SFG_TD(18, 0,1,1),SFG_TD(15, 9,5,1),SFG_TD(14, 9,0,3),SFG_TD(15, 8,3,3), // 44 - SFG_TD(16, 6,1,0),SFG_TD(14,15,0,0),SFG_TD(14,15,0,0),SFG_TD(14,15,0,0), // 48 - SFG_TD(14,15,0,0),SFG_TD(14,15,0,0),SFG_TD(14,15,0,0),SFG_TD(14,15,0,0), // 52 - SFG_TD(14,15,0,0),SFG_TD(14,15,0,0),SFG_TD(14,15,0,0),SFG_TD(14,15,0,0), // 56 - SFG_TD(14,15,0,0),SFG_TD(14,15,0,0),SFG_TD(14,15,0,0),SFG_TD(14,15,0,0) // 60 - }, // tileDictionary - {9 ,3 ,6 ,11,12,2 ,5 }, // textureIndices - 13, // doorTextureIndex - 18, // floorColor - 26, // ceilingColor - {44, 61, 64 }, // player start: x, y, direction - 0, // backgroundImage - { // elements - {SFG_LEVEL_ELEMENT_BULLETS, {55,2}},{SFG_LEVEL_ELEMENT_ROCKETS, {12,2}}, - {SFG_LEVEL_ELEMENT_RUIN, {11,2}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {25,3}}, - {SFG_LEVEL_ELEMENT_RUIN, {11,3}},{SFG_LEVEL_ELEMENT_RUIN, {10,4}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {51,5}},{SFG_LEVEL_ELEMENT_BARREL, {32,5}}, - {SFG_LEVEL_ELEMENT_LAMP, {31,5}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {61,6}}, - {SFG_LEVEL_ELEMENT_HEALTH, {26,7}},{SFG_LEVEL_ELEMENT_BARREL, {55,10}}, - {SFG_LEVEL_ELEMENT_RUIN, {29,10}},{SFG_LEVEL_ELEMENT_BULLETS, {23,11}}, - {SFG_LEVEL_ELEMENT_BULLETS, {22,11}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {13,11}}, - {SFG_LEVEL_ELEMENT_BULLETS, {54,12}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {43,13}}, - {SFG_LEVEL_ELEMENT_LAMP, {50,14}},{SFG_LEVEL_ELEMENT_RUIN, {34,14}}, - {SFG_LEVEL_ELEMENT_RUIN, {33,14}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {50,15}}, - {SFG_LEVEL_ELEMENT_RUIN, {35,15}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {10,15}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {11,16}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {55,18}}, - {SFG_LEVEL_ELEMENT_TELEPORTER, {50,20}},{SFG_LEVEL_ELEMENT_LAMP, {31,20}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {5,21}},{SFG_LEVEL_ELEMENT_TELEPORTER, {51,23}}, - {SFG_LEVEL_ELEMENT_LAMP, {25,23}},{SFG_LEVEL_ELEMENT_TREE, {36,24}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {32,24}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {34,25}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {25,25}},{SFG_LEVEL_ELEMENT_BULLETS, {18,25}}, - {SFG_LEVEL_ELEMENT_BARREL, {55,26}},{SFG_LEVEL_ELEMENT_BARREL, {54,26}}, - {SFG_LEVEL_ELEMENT_PLASMA, {48,26}},{SFG_LEVEL_ELEMENT_LAMP, {39,26}}, - {SFG_LEVEL_ELEMENT_HEALTH, {37,26}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {32,26}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {17,26}},{SFG_LEVEL_ELEMENT_PLASMA, {48,27}}, - {SFG_LEVEL_ELEMENT_TREE, {36,27}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {20,27}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {19,27}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {9,27}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {48,28}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {17,28}}, - {SFG_LEVEL_ELEMENT_TERMINAL, {18,29}},{SFG_LEVEL_ELEMENT_LAMP, {31,31}}, - {SFG_LEVEL_ELEMENT_HEALTH, {50,32}},{SFG_LEVEL_ELEMENT_BARREL, {16,32}}, - {SFG_LEVEL_ELEMENT_BARREL, {15,32}},{SFG_LEVEL_ELEMENT_HEALTH, {55,33}}, - {SFG_LEVEL_ELEMENT_BARREL, {25,33}},{SFG_LEVEL_ELEMENT_BULLETS, {10,33}}, - {SFG_LEVEL_ELEMENT_HEALTH, {9,33}},{SFG_LEVEL_ELEMENT_CARD1, {3,33}}, - {SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {56,36}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {44,36}}, - {SFG_LEVEL_ELEMENT_LAMP, {30,36}},{SFG_LEVEL_ELEMENT_CARD0, {46,37}}, - {SFG_LEVEL_ELEMENT_RUIN, {36,37}},{SFG_LEVEL_ELEMENT_RUIN, {35,38}}, - {SFG_LEVEL_ELEMENT_HEALTH, {31,38}},{SFG_LEVEL_ELEMENT_RUIN, {18,39}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {2,39}},{SFG_LEVEL_ELEMENT_RUIN, {18,40}}, - {SFG_LEVEL_ELEMENT_BARREL, {33,41}},{SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {23,41}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {37,42}},{SFG_LEVEL_ELEMENT_LOCK1, {23,42}}, - {SFG_LEVEL_ELEMENT_BLOCKER, {9,42}},{SFG_LEVEL_ELEMENT_BLOCKER, {8,42}}, - {SFG_LEVEL_ELEMENT_BLOCKER, {7,42}},{SFG_LEVEL_ELEMENT_BLOCKER, {6,42}}, - {SFG_LEVEL_ELEMENT_BLOCKER, {5,42}},{SFG_LEVEL_ELEMENT_BLOCKER, {4,42}}, - {SFG_LEVEL_ELEMENT_BLOCKER, {3,42}},{SFG_LEVEL_ELEMENT_TERMINAL, {47,43}}, - {SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {35,43}},{SFG_LEVEL_ELEMENT_BULLETS, {21,43}}, - {SFG_LEVEL_ELEMENT_HEALTH, {20,43}},{SFG_LEVEL_ELEMENT_ROCKETS, {16,43}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {52,44}},{SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {51,44}}, - {SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {37,44}},{SFG_LEVEL_ELEMENT_LAMP, {38,46}}, - {SFG_LEVEL_ELEMENT_LAMP, {26,47}},{SFG_LEVEL_ELEMENT_HEALTH, {61,49}}, - {SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {57,49}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {10,49}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {2,49}},{SFG_LEVEL_ELEMENT_BARREL, {1,49}}, - {SFG_LEVEL_ELEMENT_RUIN, {44,50}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {35,50}}, - {SFG_LEVEL_ELEMENT_HEALTH, {33,50}},{SFG_LEVEL_ELEMENT_PLASMA, {15,50}}, - {SFG_LEVEL_ELEMENT_RUIN, {45,51}},{SFG_LEVEL_ELEMENT_RUIN, {43,51}}, - {SFG_LEVEL_ELEMENT_RUIN, {42,51}},{SFG_LEVEL_ELEMENT_LOCK0, {41,52}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {39,52}},{SFG_LEVEL_ELEMENT_RUIN, {9,52}}, - {SFG_LEVEL_ELEMENT_LAMP, {58,55}},{SFG_LEVEL_ELEMENT_BULLETS, {53,56}}, - {SFG_LEVEL_ELEMENT_BULLETS, {52,56}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {39,56}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {30,56}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {40,57}}, - {SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {22,57}},{SFG_LEVEL_ELEMENT_RUIN, {46,60}}, - {SFG_LEVEL_ELEMENT_FINISH, {30,62}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}} - }, // elements - } // level - ; - -SFG_PROGRAM_MEMORY SFG_Level SFG_level3 = - { // level - { // mapArray - #define o 0 - #define AA (5 | SFG_TILE_PROPERTY_SQUEEZER) - #define BB (19 | SFG_TILE_PROPERTY_DOOR) - #define CC (24 | SFG_TILE_PROPERTY_DOOR) - #define DD (56 | SFG_TILE_PROPERTY_ELEVATOR) - #define EE (7 | SFG_TILE_PROPERTY_ELEVATOR) - #define FF (8 | SFG_TILE_PROPERTY_DOOR) - #define GG (63 | SFG_TILE_PROPERTY_DOOR) - #define HH (47 | SFG_TILE_PROPERTY_SQUEEZER) - #define II (4 | SFG_TILE_PROPERTY_SQUEEZER) - #define JJ (51 | SFG_TILE_PROPERTY_ELEVATOR) - #define KK (17 | SFG_TILE_PROPERTY_ELEVATOR) - #define LL (50 | SFG_TILE_PROPERTY_ELEVATOR) - #define MM (1 | SFG_TILE_PROPERTY_DOOR) - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 -/*0 */ 8 ,8 ,8 ,8 ,8 ,24,24,24,8 ,8 ,24,24,24,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,21,8 ,8 ,8 ,8 ,8 ,8 ,8 ,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,8 , /*0 */ -/*1 */ 8 ,5 ,5 ,5 ,5 ,24,5 ,24,9 ,9 ,24,5 ,24,5 ,5 ,5 ,5 ,5 ,5 ,27,27,27,59,59,21,59,59,27,27,27,27,27,24,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,24,8 , /*1 */ -/*2 */ 8 ,5 ,24,24,24,9 ,5 ,9 ,9 ,9 ,9 ,5 ,9 ,9 ,5 ,5 ,5 ,5 ,5 ,27,27,27,59,59,21,59,59,27,27,27,27,27,24,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,24,8 , /*2 */ -/*3 */ 8 ,5 ,24,5 ,5 ,AA,AA,AA,AA,9 ,AA,AA,AA,9 ,5 ,5 ,5 ,5 ,5 ,27,27,27,59,5 ,5 ,5 ,59,27,27,27,27,27,24,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,32,32,32,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,8 , /*3 */ -/*4 */ 8 ,5 ,24,5 ,9 ,AA,AA,9 ,AA,AA,AA,AA,AA,9 ,5 ,5 ,5 ,5 ,57,9 ,59,59,59,5 ,5 ,5 ,59,59,59,9 ,9 ,27,24,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,32,32,32,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,24,8 , /*4 */ -/*5 */ 63,57,24,5 ,9 ,AA,AA,9 ,AA,AA,AA,AA,9 ,9 ,5 ,5 ,5 ,5 ,57,59,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,59,57,5 ,6 ,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,32,32,32,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,24,8 , /*5 */ -/*6 */ 8 ,57,9 ,AA,AA,AA,AA,9 ,9 ,9 ,9 ,9 ,5 ,5 ,5 ,5 ,5 ,5 ,57,59,5 ,59,59,59,59,59,59,59,5 ,59,57,5 ,6 ,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,32,32,32,32,32,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,8 , /*6 */ -/*7 */ 8 ,57,9 ,AA,AA,AA,9 ,24,5 ,AA,AA,9 ,5 ,5 ,5 ,5 ,5 ,5 ,57,59,5 ,59,9 ,27,27,27,9 ,59,5 ,59,57,5 ,23,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,32,32,32,32,32,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,24,8 , /*7 */ -/*8 */ 53,57,9 ,AA,AA,AA,9 ,24,5 ,AA,AA,21,5 ,5 ,5 ,5 ,5 ,5 ,57,59,5 ,59,27,5 ,5 ,5 ,27,59,5 ,59,57,5 ,23,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,32,32,32,32,32,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,24,8 , /*8 */ -/*9 */ 8 ,57,24,5 ,9 ,AA,9 ,24,5 ,AA,AA,21,5 ,5 ,5 ,5 ,5 ,5 ,57,59,5 ,59,27,5 ,5 ,5 ,27,59,5 ,59,57,5 ,23,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,32,32,32,32,32,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,8 , /*9 */ -/*10*/ 8 ,57,24,5 ,9 ,AA,9 ,24,5 ,AA,AA,9 ,5 ,5 ,5 ,5 ,5 ,5 ,57,59,5 ,19,27,5 ,5 ,5 ,27,19,5 ,59,57,5 ,6 ,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,32,32,32,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,24,8 , /*10*/ -/*11*/ 63,57,9 ,9 ,9 ,AA,9 ,9 ,9 ,AA,AA,9 ,5 ,5 ,5 ,5 ,5 ,5 ,57,59,5 ,BB,27,5 ,5 ,5 ,27,BB,5 ,59,57,5 ,6 ,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,32,32,32,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,24,8 , /*11*/ -/*12*/ 8 ,57,9 ,AA,AA,AA,AA,AA,9 ,AA,AA,9 ,9 ,9 ,9 ,27,27,27,9 ,58,59,58,9 ,27,27,27,9 ,58,59,58,9 ,27,24,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,32,32,32,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,8 , /*12*/ -/*13*/ 8 ,57,9 ,9 ,AA,AA,AA,AA,9 ,AA,AA,AA,AA,9 ,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,24,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,24,8 , /*13*/ -/*14*/ 53,57,24,5 ,AA,AA,9 ,9 ,9 ,9 ,9 ,AA,AA,9 ,27,27,27,27,27,27,27,27,9 ,27,27,27,9 ,27,27,27,27,27,24,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,24,8 , /*14*/ -/*15*/ 8 ,57,24,5 ,AA,AA,5 ,24,5 ,AA,AA,AA,AA,9 ,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,24,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,8 , /*15*/ -/*16*/ 8 ,57,24,5 ,AA,AA,5 ,24,5 ,AA,AA,AA,9 ,9 ,27,27,27,27,27,27,27,27,9 ,27,9 ,27,9 ,27,27,27,27,27,24,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,24,8 , /*16*/ -/*17*/ 63,57,24,5 ,AA,AA,9 ,9 ,9 ,AA,AA,AA,9 ,57,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,23,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,24,8 , /*17*/ -/*18*/ 8 ,5 ,9 ,9 ,AA,AA,AA,AA,AA,AA,AA,AA,9 ,57,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,23,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,6 ,6 ,24,8 , /*18*/ -/*19*/ 8 ,5 ,9 ,9 ,AA,9 ,AA,AA,AA,AA,AA,AA,9 ,57,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,23,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,24,8 , /*19*/ -/*20*/ 53,5 ,9 ,9 ,AA,9 ,AA,AA,AA,AA,AA,AA,9 ,57,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,24,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,25,24,8 , /*20*/ -/*21*/ 53,5 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,57,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,6 ,6 ,6 ,6 ,6 ,6 ,24,24,24,24,24,24,24,24,24,24,24,24,CC,24,24,24,24,24,24,24,24,24,24,42,24,8 , /*21*/ -/*22*/ 8 ,5 ,19,59,59,59,63,63,63,59,59,59,19,57,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,26,6 ,6 ,6 ,24,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,6 ,24,24,42,24,8 , /*22*/ -/*23*/ 8 ,5 ,BB,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,59,57,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,24,48,48,48,48,48,24,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,26,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,24,42,42,24,8 , /*23*/ -/*24*/ 8 ,59,19,59,59,59,19,21,19,59,59,59,19,57,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,27,5 ,5 ,5 ,5 ,5 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,26,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,24,24,24,24,8 , /*24*/ -/*25*/ 53,27,27,27,27,27,27,27,27,27,27,27,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,24,48,48,48,48,5 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,26,6 ,24,24,24,6 ,6 ,6 ,24,24,24,6 ,6 ,6 ,24,24,24,6 ,26,6 ,6 ,8 ,8 , /*25*/ -/*26*/ 8 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,27,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,23,5 ,5 ,5 ,48,5 ,6 ,6 ,6 ,6 ,6 ,6 ,24,26,26,24,6 ,24,24,24,6 ,6 ,6 ,24,6 ,24,6 ,6 ,6 ,24,24,24,6 ,26,6 ,6 ,DD,8 , /*26*/ -/*27*/ 8 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,27,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,23,5 ,48,5 ,5 ,5 ,23,6 ,6 ,6 ,6 ,6 ,26,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,26,6 ,6 ,8 ,8 , /*27*/ -/*28*/ 8 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,27,19,57,57,57,57,57,57,57,57,57,5 ,5 ,5 ,5 ,23,5 ,48,48,48,48,23,6 ,6 ,6 ,6 ,6 ,26,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,24,6 ,6 ,DD,8 , /*28*/ -/*29*/ 8 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,27,19,59,59,59,58,58,59,59,59,19,5 ,5 ,5 ,5 ,23,5 ,5 ,5 ,5 ,5 ,23,6 ,6 ,6 ,6 ,6 ,26,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,8 ,8 , /*29*/ -/*30*/ 8 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,27,BB,27,27,27,27,27,27,27,27,BB,5 ,5 ,5 ,5 ,24,48,48,48,63,11,22,63,20,CC,20,20,20,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,8 ,8 , /*30*/ -/*31*/ 53,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,27,19,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,19,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,22,EE,EE,12,6 ,6 ,20,20,20,6 ,6 ,6 ,23,6 ,6 ,6 ,26,6 ,6 ,6 ,23,6 ,6 ,6 ,23,6 ,6 ,6 ,23,6 ,6 ,6 ,8 ,8 , /*31*/ -/*32*/ 8 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,15,14,3 ,3 ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,10,EE,EE,22,47,47,18,4 ,4 ,18,47,47,47,47,47,47,63,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,33,8 , /*32*/ -/*33*/ 8 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,15,14,3 ,3 ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,63,22,FF,63,47,47,18,4 ,4 ,18,47,47,47,47,47,47,63,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,33,8 , /*33*/ -/*34*/ 63,o ,o ,o ,o ,63,63,o ,o ,o ,o ,o ,o ,3 ,3 ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,46,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,55,8 , /*34*/ -/*35*/ 8 ,o ,o ,o ,63,63,63,63,o ,o ,o ,o ,o ,3 ,3 ,3 ,61,61,63,24,63,61,61,o ,o ,o ,o ,o ,o ,o ,o ,o ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,46,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,18,13,18,4 ,55,DD, /*35*/ -/*36*/ 8 ,o ,o ,o ,63,63,63,63,o ,o ,o ,o ,o ,3 ,3 ,3 ,61,63,62,62,62,63,61,o ,o ,o ,o ,o ,o ,o ,o ,o ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,46,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,13,13,13,4 ,55,DD, /*36*/ -/*37*/ 63,o ,o ,o ,o ,63,63,o ,o ,o ,o ,o ,o ,62,62,62,63,62,62,62,62,62,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,46,46,46,46,46,46,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,13,13,13,4 ,55,8 , /*37*/ -/*38*/ 8 ,o ,54,54,54,o ,o ,54,54,54,o ,o ,o ,62,62,62,GG,62,62,62,62,62,24,o ,o ,o ,o ,o ,o ,o ,8 ,53,4 ,4 ,4 ,4 ,4 ,4 ,4 ,46,46,46,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,18,13,13,13,18,18,4 ,53,8 , /*38*/ -/*39*/ 8 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,15,15,62,62,62,63,62,62,62,62,62,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,4 ,4 ,4 ,4 ,4 ,4 ,46,46,16,16,16,16,16,16,16,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,13,13,13,13,18,4 ,4 ,55,8 , /*39*/ -/*40*/ 8 ,3 ,JJ,JJ,JJ,3 ,3 ,JJ,JJ,JJ,3 ,14,14,3 ,3 ,3 ,61,63,62,62,62,63,61,o ,o ,o ,o ,o ,o ,o ,o ,o ,4 ,4 ,4 ,4 ,4 ,4 ,46,4 ,16,HH,16,II,16,HH,16,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,13,13,13,4 ,4 ,4 ,4 ,55,8 , /*40*/ -/*41*/ 63,3 ,JJ,JJ,JJ,3 ,3 ,JJ,JJ,JJ,3 ,3 ,3 ,3 ,3 ,3 ,61,61,63,24,63,61,61,o ,o ,o ,o ,o ,o ,o ,o ,o ,4 ,4 ,4 ,4 ,4 ,46,46,4 ,4 ,47,4 ,47,4 ,47,4 ,4 ,8 ,18,4 ,4 ,4 ,4 ,4 ,13,13,13,4 ,4 ,4 ,4 ,55,8 , /*41*/ -/*42*/ 8 ,3 ,JJ,JJ,JJ,3 ,3 ,JJ,JJ,JJ,3 ,14,14,3 ,3 ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,61,61,o ,o ,o ,o ,4 ,4 ,4 ,4 ,4 ,46,4 ,4 ,4 ,47,4 ,47,4 ,47,4 ,4 ,13,45,4 ,4 ,4 ,4 ,4 ,18,13,18,4 ,4 ,4 ,4 ,55,8 , /*42*/ -/*43*/ 8 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,15,15,3 ,3 ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,61,61,o ,o ,8 ,53,4 ,4 ,4 ,4 ,4 ,46,4 ,4 ,4 ,45,4 ,45,4 ,45,4 ,4 ,13,45,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,53,8 , /*43*/ -/*44*/ 8 ,o ,54,54,54,o ,o ,54,54,54,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,61,61,61,o ,o ,o ,o ,4 ,4 ,4 ,4 ,4 ,46,4 ,4 ,4 ,47,47,47,47,47,4 ,4 ,18,45,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,8 ,8 , /*44*/ -/*45*/ 8 ,o ,49,49,49,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,61,61,61,61,61,61,61,24,24,o ,o ,o ,o ,4 ,4 ,4 ,4 ,4 ,19,4 ,4 ,4 ,46,46,46,46,47,4 ,4 ,18,45,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,8 ,8 , /*45*/ -/*46*/ 63,o ,49,49,49,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,61,61,61,61,61,61,61,24,24,o ,o ,o ,o ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,46,46,46,46,47,4 ,4 ,13,45,4 ,4 ,46,46,4 ,4 ,4 ,4 ,4 ,46,46,4 ,8 ,8 , /*46*/ -/*47*/ 8 ,o ,49,49,49,o ,o ,o ,15,15,15,o ,o ,15,15,15,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,46,46,46,46,47,4 ,4 ,13,45,4 ,4 ,46,46,4 ,4 ,4 ,4 ,4 ,46,46,4 ,8 ,8 , /*47*/ -/*48*/ 8 ,o ,49,49,49,o ,o ,o ,14,14,14,o ,o ,14,14,14,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,8 ,53,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,47,47,47,47,47,4 ,4 ,18,18,4 ,4 ,4 ,4 ,4 ,18,13,18,4 ,4 ,4 ,4 ,8 ,8 , /*48*/ -/*49*/ 8 ,o ,49,49,49,o ,o ,o ,3 ,3 ,3 ,o ,o ,3 ,3 ,3 ,o ,o ,54,o ,o ,o ,54,o ,o ,o ,o ,o ,o ,o ,o ,o ,4 ,4 ,4 ,4 ,18,18,4 ,4 ,4 ,45,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,16,13,16,4 ,4 ,4 ,4 ,8 ,8 , /*49*/ -/*50*/ 8 ,o ,49,49,49,o ,o ,o ,3 ,o ,o ,o ,o ,o ,o ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,o ,o ,o ,o ,o ,o ,o ,4 ,4 ,4 ,4 ,18,18,4 ,4 ,4 ,45,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,16,KK,16,4 ,4 ,4 ,4 ,8 ,8 , /*50*/ -/*51*/ 8 ,o ,24,LL,24,o ,o ,54,3 ,54,o ,o ,o ,o ,54,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,o ,o ,o ,o ,o ,o ,o ,4 ,4 ,4 ,4 ,18,18,4 ,4 ,4 ,47,47,47,47,47,4 ,4 ,18,18,4 ,4 ,4 ,4 ,4 ,16,16,16,4 ,4 ,4 ,4 ,DD,8 , /*51*/ -/*52*/ 63,o ,2 ,2 ,2 ,o ,o ,o ,3 ,o ,o ,o ,o ,o ,o ,3 ,3 ,49,61,61,49,3 ,3 ,3 ,3 ,54,o ,o ,o ,o ,o ,o ,4 ,4 ,4 ,4 ,4 ,18,4 ,4 ,4 ,4 ,4 ,4 ,4 ,47,4 ,4 ,13,45,4 ,4 ,4 ,4 ,4 ,18,13,18,4 ,4 ,4 ,4 ,8 ,8 , /*52*/ -/*53*/ 8 ,o ,2 ,2 ,2 ,o ,o ,o ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,60,61,61,61,3 ,3 ,3 ,3 ,o ,o ,o ,o ,o ,8 ,53,4 ,4 ,4 ,4 ,4 ,18,4 ,4 ,4 ,4 ,4 ,4 ,4 ,47,4 ,4 ,13,45,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,8 ,8 , /*53*/ -/*54*/ 8 ,15,2 ,2 ,2 ,o ,o ,54,3 ,54,o ,o ,o ,o ,o ,o ,o ,60,61,61,61,3 ,3 ,3 ,3 ,o ,o ,o ,o ,o ,o ,o ,4 ,4 ,4 ,4 ,18,18,4 ,4 ,4 ,47,47,47,4 ,47,4 ,4 ,18,45,4 ,19,46,46,46,46,46,46,46,46,46,46,19,8 , /*54*/ -/*55*/ 8 ,14,2 ,2 ,2 ,o ,o ,o ,3 ,o ,o ,o ,o ,o ,o ,3 ,3 ,49,61,61,49,3 ,3 ,3 ,3 ,54,o ,o ,o ,o ,o ,o ,4 ,4 ,4 ,4 ,18,18,4 ,4 ,4 ,45,4 ,45,4 ,47,4 ,4 ,18,45,4 ,46,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,8 ,8 , /*55*/ -/*56*/ 8 ,3 ,2 ,2 ,2 ,2 ,8 ,24,3 ,61,61,o ,o ,o ,54,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,o ,o ,o ,o ,o ,o ,o ,4 ,4 ,4 ,4 ,18,18,4 ,4 ,4 ,47,4 ,47,47,47,4 ,4 ,13,45,4 ,46,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,8 ,8 , /*56*/ -/*57*/ 8 ,3 ,2 ,2 ,2 ,2 ,2 ,8 ,3 ,61,61,o ,o ,o ,54,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,o ,o ,o ,o ,o ,o ,o ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,47,4 ,4 ,4 ,4 ,4 ,4 ,13,45,4 ,46,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,8 ,8 , /*57*/ -/*58*/ 63,14,2 ,2 ,2 ,2 ,2 ,2 ,MM,61,61,o ,o ,o ,o ,3 ,o ,o ,54,o ,o ,o ,54,o ,o ,o ,63,63,o ,o ,8 ,53,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,18,HH,18,4 ,4 ,4 ,4 ,4 ,8 ,18,4 ,46,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,8 ,8 , /*58*/ -/*59*/ 8 ,15,2 ,2 ,2 ,2 ,2 ,8 ,3 ,61,61,o ,o ,o ,o ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,63,63,63,63,o ,o ,o ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,16,16,16,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,46,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,8 ,8 , /*59*/ -/*60*/ 8 ,o ,2 ,2 ,2 ,2 ,8 ,24,3 ,61,61,54,o ,54,o ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,63,63,63,63,o ,o ,o ,4 ,4 ,4 ,4 ,19,46,46,46,19,46,19,46,46,46,46,46,46,46,46,19,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,53,8 , /*60*/ -/*61*/ 8 ,o ,o ,o ,o ,o ,o ,o ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,63,63,o ,o ,o ,o ,4 ,4 ,4 ,4 ,46,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,34,8 , /*61*/ -/*62*/ 8 ,o ,o ,o ,o ,o ,o ,o ,o ,54,o ,54,o ,54,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,4 ,4 ,4 ,4 ,46,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,34,8 , /*62*/ -/*63*/ 8 ,8 ,8 ,DD,8 ,DD,8 ,8 ,8 ,8 ,53,53,53,8 ,8 ,8 ,53,8 ,34,34,34,8 ,53,8 ,34,34,34,8 ,53,8 ,19,19,33,33,33,53,19,8 ,8 ,8 ,8 ,8 ,53,34,34,53,8 ,8 ,8 ,8 ,53,34,34,53,8 ,8 ,8 ,8 ,8 ,53,34,34,34,8 /*63*/ - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 - #undef AA - #undef BB - #undef CC - #undef DD - #undef EE - #undef FF - #undef GG - #undef HH - #undef II - #undef JJ - #undef KK - #undef LL - #undef MM - #undef o - }, - { // tileDictionary - SFG_TD(10,20,0,0),SFG_TD( 4,26,0,0),SFG_TD( 0, 4,0,0),SFG_TD( 4,26,0,0), // 0 - SFG_TD( 0,30,2,2),SFG_TD(17,13,0,2),SFG_TD(24, 6,0,1),SFG_TD( 0,24,1,0), // 4 - SFG_TD( 4, 0,1,0),SFG_TD(19, 0,4,1),SFG_TD(10, 5,0,0),SFG_TD(17, 5,0,0), // 8 - SFG_TD(24, 5,0,0),SFG_TD( 8,22,3,0),SFG_TD( 6,24,0,0),SFG_TD( 8,22,0,0), // 12 - SFG_TD(11,19,1,0),SFG_TD( 0,10,0,0),SFG_TD( 8,22,0,0),SFG_TD(21, 0,4,4), // 16 - SFG_TD(24, 0,0,5),SFG_TD(17, 5,0,1),SFG_TD( 0, 0,0,0),SFG_TD(24, 6,5,5), // 20 - SFG_TD(28, 0,5,1),SFG_TD(24, 8,0,1),SFG_TD(26, 3,5,1),SFG_TD(17,10,0,5), // 24 - SFG_TD(13,15,0,0),SFG_TD(13,15,0,0),SFG_TD(13,15,0,0),SFG_TD(13,15,0,0), // 28 - SFG_TD(24, 8,0,1),SFG_TD( 8, 0,6,0),SFG_TD(18, 0,0,6),SFG_TD(13,15,0,0), // 32 - SFG_TD(13,15,0,0),SFG_TD(13,15,0,0),SFG_TD(13,15,0,0),SFG_TD(13,15,0,0), // 36 - SFG_TD(13,15,0,0),SFG_TD(13,15,0,0),SFG_TD(28, 4,5,1),SFG_TD(13,15,0,0), // 40 - SFG_TD(13,15,0,0),SFG_TD( 2,28,4,2),SFG_TD( 0,13,0,4),SFG_TD( 2,28,2,2), // 44 - SFG_TD(22, 8,5,2),SFG_TD(15,15,0,0),SFG_TD( 0,15,0,0),SFG_TD(15,11,5,0), // 48 - SFG_TD(13,15,0,0),SFG_TD( 0, 0,1,1),SFG_TD(10,20,1,0),SFG_TD(22, 8,0,0), // 52 - SFG_TD(31,24,4,4),SFG_TD(19,11,6,2),SFG_TD( 0, 0,3,3),SFG_TD(19, 3,4,3), // 56 - SFG_TD(12,18,5,0),SFG_TD(14,16,5,0),SFG_TD(17,13,1,1),SFG_TD(21, 0,2,2) // 60 - }, // tileDictionary - {14,3 ,11,15,2 ,12,10}, // textureIndices - 13, // doorTextureIndex - 50, // floorColor - 186, // ceilingColor - {56, 50, 64 }, // player start: x, y, direction - 1, // backgroundImage - { // elements - {SFG_LEVEL_ELEMENT_FINISH, {24,0}},{SFG_LEVEL_ELEMENT_BULLETS, {29,1}}, - {SFG_LEVEL_ELEMENT_BULLETS, {28,1}},{SFG_LEVEL_ELEMENT_CARD0, {11,1}}, - {SFG_LEVEL_ELEMENT_PLASMA, {4,1}},{SFG_LEVEL_ELEMENT_ROCKETS, {3,1}}, - {SFG_LEVEL_ELEMENT_TELEPORTER, {35,2}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {60,3}}, - {SFG_LEVEL_ELEMENT_CARD2, {40,6}},{SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {51,7}}, - {SFG_LEVEL_ELEMENT_LAMP, {12,7}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {36,9}}, - {SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {47,10}},{SFG_LEVEL_ELEMENT_LOCK2, {27,10}}, - {SFG_LEVEL_ELEMENT_LOCK2, {21,10}},{SFG_LEVEL_ELEMENT_LAMP, {12,10}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {1,10}},{SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {42,11}}, - {SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {34,11}},{SFG_LEVEL_ELEMENT_BARREL, {5,11}}, - {SFG_LEVEL_ELEMENT_COLUMN, {37,12}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {35,12}}, - {SFG_LEVEL_ELEMENT_COLUMN, {33,12}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {55,13}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {1,13}},{SFG_LEVEL_ELEMENT_HEALTH, {3,15}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {50,17}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {53,20}}, - {SFG_LEVEL_ELEMENT_BARREL, {18,20}},{SFG_LEVEL_ELEMENT_LOCK2, {50,21}}, - {SFG_LEVEL_ELEMENT_BARREL, {19,21}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {18,21}}, - {SFG_LEVEL_ELEMENT_BARREL, {17,21}},{SFG_LEVEL_ELEMENT_BARREL, {18,22}}, - {SFG_LEVEL_ELEMENT_TELEPORTER, {60,23}},{SFG_LEVEL_ELEMENT_HEALTH, {39,23}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {39,24}},{SFG_LEVEL_ELEMENT_ROCKETS, {61,25}}, - {SFG_LEVEL_ELEMENT_HEALTH, {60,25}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {50,26}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {29,27}},{SFG_LEVEL_ELEMENT_HEALTH, {5,28}}, - {SFG_LEVEL_ELEMENT_LAMP, {22,29}},{SFG_LEVEL_ELEMENT_LOCK1, {35,30}}, - {SFG_LEVEL_ELEMENT_COLUMN, {56,31}},{SFG_LEVEL_ELEMENT_COLUMN, {50,31}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {54,32}},{SFG_LEVEL_ELEMENT_BULLETS, {53,32}}, - {SFG_LEVEL_ELEMENT_BULLETS, {38,32}},{SFG_LEVEL_ELEMENT_PLASMA, {37,32}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {32,32}},{SFG_LEVEL_ELEMENT_LAMP, {33,34}}, - {SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {33,35}},{SFG_LEVEL_ELEMENT_PLASMA, {9,35}}, - {SFG_LEVEL_ELEMENT_HEALTH, {23,36}},{SFG_LEVEL_ELEMENT_TERMINAL, {19,36}}, - {SFG_LEVEL_ELEMENT_PLASMA, {9,36}},{SFG_LEVEL_ELEMENT_CARD1, {21,38}}, - {SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {19,38}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {57,39}}, - {SFG_LEVEL_ELEMENT_PLASMA, {56,40}},{SFG_LEVEL_ELEMENT_ROCKETS, {56,41}}, - {SFG_LEVEL_ELEMENT_BARREL, {37,48}},{SFG_LEVEL_ELEMENT_BARREL, {36,48}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {44,49}},{SFG_LEVEL_ELEMENT_HEALTH, {36,52}}, - {SFG_LEVEL_ELEMENT_BULLETS, {36,53}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {18,53}}, - {SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {11,53}},{SFG_LEVEL_ELEMENT_BARREL, {3,53}}, - {SFG_LEVEL_ELEMENT_BULLETS, {58,57}},{SFG_LEVEL_ELEMENT_BULLETS, {56,57}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {44,57}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {3,57}}, - {SFG_LEVEL_ELEMENT_BARREL, {51,58}},{SFG_LEVEL_ELEMENT_BARREL, {50,58}}, - {SFG_LEVEL_ELEMENT_TERMINAL, {39,58}},{SFG_LEVEL_ELEMENT_LOCK0, {8,58}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {5,58}},{SFG_LEVEL_ELEMENT_BARREL, {51,59}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {3,59}},{SFG_LEVEL_ELEMENT_BULLETS, {20,61}}, - {SFG_LEVEL_ELEMENT_HEALTH, {3,61}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}} - }, // elements - } // level - ; - -SFG_PROGRAM_MEMORY SFG_Level SFG_level4 = - { // level - { // mapArray - #define o 0 - #define AA (5 | SFG_TILE_PROPERTY_DOOR) - #define BB (10 | SFG_TILE_PROPERTY_DOOR) - #define CC (6 | SFG_TILE_PROPERTY_DOOR) - #define DD (8 | SFG_TILE_PROPERTY_DOOR) - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 -/*0 */ 62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,60,60,62,62,62,62,62,62,62,62,62,o ,o ,o ,o ,o ,62,62,62,18,2 ,2 ,2 ,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, /*0 */ -/*1 */ 62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,o ,o ,62,62,62,62,62,62,62,62,62,o ,o ,o ,o ,o ,62,62,62,18,2 ,2 ,2 ,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, /*1 */ -/*2 */ 62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,o ,o ,62,62,62,62,62,62,62,62,62,o ,o ,o ,o ,o ,62,62,62,18,2 ,2 ,2 ,18,18,18,18,18,18,18,18,18,17,18,18,18,17,18,18,18,18,18,18, /*2 */ -/*3 */ 62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,o ,o ,62,62,62,62,62,62,62,62,62,o ,o ,o ,o ,o ,62,62,62,18,2 ,2 ,2 ,17,18,18,18,17,18,18,18,7 ,7 ,7 ,7 ,7 ,7 ,7 ,17,18,18,18,18, /*3 */ -/*4 */ 62,62,62,62,62,62,62,62,62,62,62,62,62,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,62,62,62,62,62,62,62,62,62,o ,o ,o ,o ,o ,62,62,62,18,2 ,2 ,2 ,17,2 ,2 ,2 ,2 ,2 ,2 ,2 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,2 ,2 ,2 ,2 ,18, /*4 */ -/*5 */ o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,62,62,62,18,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,AA,7 ,7 ,7 ,7 ,7 ,7 ,7 ,2 ,2 ,2 ,2 ,18, /*5 */ -/*6 */ o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,62,62,62,18,2 ,2 ,2 ,17,2 ,2 ,2 ,2 ,2 ,2 ,2 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,2 ,2 ,2 ,2 ,18, /*6 */ -/*7 */ o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,62,62,62,18,18,18,18,17,18,18,18,17,18,18,18,7 ,7 ,7 ,7 ,7 ,7 ,7 ,17,2 ,2 ,2 ,17, /*7 */ -/*8 */ o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,62,62,62,18,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,18,2 ,2 ,2 ,18, /*8 */ -/*9 */ o ,o ,o ,o ,63,63,63,61,61,61,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,62,62,62,18,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,18,2 ,2 ,2 ,18, /*9 */ -/*10*/ o ,o ,o ,o ,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,63,o ,o ,o ,o ,o ,62,62,62,62,62,62,62,18,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,17,2 ,2 ,2 ,17, /*10*/ -/*11*/ 62,62,o ,o ,63,o ,o ,o ,o ,o ,60,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,63,o ,o ,o ,o ,o ,62,62,62,62,62,62,62,18,7 ,7 ,11,11,11,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,18,2 ,2 ,2 ,18, /*11*/ -/*12*/ 62,62,o ,o ,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,59,59,59,o ,o ,63,o ,o ,o ,o ,o ,62,62,62,62,62,62,62,18,7 ,7 ,11,11,11,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,18,2 ,2 ,2 ,18, /*12*/ -/*13*/ 62,62,o ,o ,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,59,59,59,o ,o ,63,o ,o ,o ,o ,o ,62,62,62,62,62,62,62,18,7 ,7 ,11,11,11,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,17,2 ,2 ,2 ,17, /*13*/ -/*14*/ 62,62,o ,o ,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,59,59,59,o ,o ,63,o ,o ,o ,o ,o ,62,62,62,62,62,62,62,18,18,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,18,2 ,2 ,2 ,18, /*14*/ -/*15*/ 62,62,o ,o ,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,63,o ,o ,o ,o ,o ,62,62,62,62,62,62,62,1 ,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,2 ,2 ,2 ,18, /*15*/ -/*16*/ 62,62,o ,o ,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,63,o ,o ,o ,o ,o ,62,62,62,62,62,62,1 ,17,17,17,17,17,17,17,17,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,18,2 ,2 ,2 ,18, /*16*/ -/*17*/ 62,62,o ,o ,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,63,o ,o ,o ,62,62,62,62,62,62,62,62,1 ,17,17,17,17,17,2 ,2 ,17,1 ,1 ,55,1 ,1 ,1 ,1 ,1 ,55,1 ,1 ,17,2 ,2 ,2 ,17, /*17*/ -/*18*/ 62,62,o ,o ,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,63,o ,o ,o ,62,62,62,62,62,62,62,62,1 ,17,17,17,17,17,2 ,2 ,2 ,2 ,2 ,2 ,25,1 ,1 ,1 ,25,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1 , /*18*/ -/*19*/ 60,o ,o ,o ,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,63,o ,o ,o ,62,62,62,62,62,62,62,62,1 ,17,17,17,17,17,2 ,2 ,2 ,2 ,2 ,2 ,25,25,25,25,25,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1 , /*19*/ -/*20*/ 60,o ,o ,o ,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,63,o ,o ,o ,62,62,o ,o ,o ,o ,o ,62,1 ,17,17,17,17,17,2 ,2 ,17,1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 , /*20*/ -/*21*/ 60,o ,o ,o ,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,63,60,60,60,62,62,o ,o ,o ,o ,o ,62,1 ,17,17,17,17,17,17,17,1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 , /*21*/ -/*22*/ 60,o ,o ,o ,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,63,o ,o ,o ,62,62,60,60,60,60,60,o ,62,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 , /*22*/ -/*23*/ 60,o ,o ,o ,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,55,10,BB,BB,BB,10,55,o ,o ,o ,o ,o ,o ,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,60,o ,62,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 , /*23*/ -/*24*/ 60,o ,o ,o ,63,o ,o ,o ,o ,o ,o ,o ,o ,10,10,36,36,36,36,36,10,10,o ,o ,o ,o ,o ,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,60,o ,62,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,1 ,1 , /*24*/ -/*25*/ 60,o ,o ,o ,63,o ,o ,o ,o ,o ,o ,o ,10,36,36,36,36,36,36,36,36,36,10,o ,o ,o ,o ,59,o ,o ,o ,o ,o ,o ,o ,o ,o ,60,o ,62,1 ,1 ,1 ,1 ,1 ,51,51,1 ,1 ,1 ,1 ,2 ,3 ,2 ,3 ,2 ,1 ,1 ,1 ,1 ,51,51,1 ,1 , /*25*/ -/*26*/ 10,49,49,10,10,10,10,10,10,10,10,10,10,36,36,36,36,36,36,36,36,36,10,10,10,10,10,10,10,10,10,10,49,49,10,o ,o ,60,o ,62,62,1 ,1 ,1 ,1 ,51,51,1 ,1 ,1 ,1 ,2 ,CC,2 ,CC,2 ,1 ,1 ,1 ,1 ,51,51,1 ,1 , /*26*/ -/*27*/ 10,33,33,33,45,46,46,46,46,46,46,46,46,36,36,36,36,36,36,36,36,36,46,46,46,46,46,46,46,46,45,33,33,33,10,o ,o ,60,o ,62,62,62,1 ,1 ,1 ,51,51,51,51,51,51,2 ,2 ,2 ,2 ,2 ,51,51,51,51,51,51,1 ,1 , /*27*/ -/*28*/ 10,33,33,33,45,46,46,46,46,46,46,46,46,36,36,36,36,36,36,36,36,36,46,46,46,46,46,46,46,46,45,33,33,33,10,o ,o ,60,o ,62,62,62,62,1 ,1 ,51,51,51,51,51,51,2 ,2 ,2 ,2 ,2 ,51,51,51,51,51,51,1 ,1 , /*28*/ -/*29*/ 10,33,33,33,45,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,45,33,33,33,10,60,60,60,60,8 ,62,62,62,62,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 , /*29*/ -/*30*/ 10,33,33,33,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,33,33,33,10,o ,o ,o ,o ,o ,o ,21,21,62,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 , /*30*/ -/*31*/ 10,34,34,34,10,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,10,34,34,34,10,o ,o ,o ,o ,o ,o ,o ,o ,62,62,62,62,62,62,1 ,1 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 , /*31*/ -/*32*/ 49,35,35,35,10,35,35,43,35,43,35,43,35,43,35,43,35,43,35,43,35,43,35,43,35,43,35,43,35,35,10,35,35,35,49,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,8 ,1 ,1 ,4 ,2 ,2 ,2 ,4 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 , /*32*/ -/*33*/ 49,35,35,35,10,35,34,42,34,42,34,42,34,42,34,42,34,42,34,42,34,42,34,42,34,42,34,42,34,35,10,35,35,35,49,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,8 ,1 ,1 ,1 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 , /*33*/ -/*34*/ 49,35,35,35,10,43,42,41,33,41,33,41,33,41,33,41,33,41,33,41,33,41,33,41,33,41,33,41,42,43,10,35,35,35,49,o ,o ,o ,o ,o ,o ,o ,o ,62,62,62,62,62,62,1 ,1 ,1 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 , /*34*/ -/*35*/ 10,35,35,35,DD,35,34,33,32,40,32,40,32,40,32,40,32,40,32,40,32,40,32,40,32,40,32,33,34,35,DD,35,35,35,10,o ,o ,o ,o ,o ,o ,o ,o ,62,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 , /*35*/ -/*36*/ 10,10,10,10,10,43,42,41,40,36,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,36,40,41,42,43,10,10,10,10,10,o ,o ,o ,o ,o ,o ,o ,o ,62,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,1 ,1 ,1 ,17,17,17,17,17,17, /*36*/ -/*37*/ 10,9 ,9 ,9 ,9 ,9 ,34,33,32,36,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,36,32,33,34,9 ,9 ,9 ,9 ,9 ,10,o ,o ,60,60,60,60,60,60,62,1 ,1 ,1 ,25,25,25,25,25,1 ,2 ,1 ,1 ,1 ,1 ,17,30,30,30,17,17, /*37*/ -/*38*/ 10,9 ,9 ,9 ,9 ,9 ,42,41,40,36,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,36,40,41,42,9 ,9 ,9 ,9 ,9 ,10,o ,o ,60,o ,o ,o ,o ,o ,62,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,29,30,30,30,17,17, /*38*/ -/*39*/ 10,9 ,9 ,9 ,9 ,9 ,34,33,32,36,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,36,32,33,34,9 ,9 ,9 ,9 ,9 ,10,o ,o ,60,o ,o ,o ,o ,o ,62,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,29,30,30,30,17,17, /*39*/ -/*40*/ 10,BB,10,10,8 ,43,42,41,40,36,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,36,40,41,42,43,8 ,10,10,BB,10,o ,o ,60,62,62,8 ,8 ,62,62,1 ,1 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,17,30,30,30,17,17, /*40*/ -/*41*/ 10,9 ,9 ,9 ,8 ,35,34,33,32,36,22,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,22,36,32,33,34,35,8 ,9 ,9 ,9 ,10,o ,o ,60,62,1 ,1 ,1 ,1 ,1 ,17,1 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,17,17,30,17,17,17, /*41*/ -/*42*/ 10,9 ,9 ,9 ,8 ,43,42,41,40,36,22,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,22,36,40,41,42,43,8 ,9 ,9 ,9 ,10,o ,o ,60,62,1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,17,30,30,30,17,17, /*42*/ -/*43*/ 10,9 ,9 ,9 ,8 ,35,34,33,32,36,22,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,22,36,32,33,34,35,8 ,9 ,9 ,9 ,10,o ,o ,60,62,1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,17,30,30,30,17,17, /*43*/ -/*44*/ 10,9 ,9 ,9 ,8 ,43,42,41,40,36,22,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,22,36,40,41,42,43,8 ,9 ,9 ,9 ,10,62,62,62,62,1 ,2 ,2 ,2 ,1 ,17,1 ,1 ,1 ,1 ,1 ,1 ,1 ,4 ,2 ,4 ,1 ,1 ,1 ,17,30,30,30,17,17, /*44*/ -/*45*/ 10,9 ,9 ,9 ,8 ,35,34,33,32,36,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,36,32,33,34,35,8 ,9 ,9 ,9 ,10,62,62,1 ,1 ,1 ,29,29,29,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,1 ,1 ,1 ,17,17,17,17,17,17, /*45*/ -/*46*/ 10,9 ,9 ,9 ,9 ,9 ,36,36,36,36,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,36,36,36,36,9 ,9 ,9 ,9 ,9 ,10,62,62,1 ,1 ,30,30,30,30,30,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 , /*46*/ -/*47*/ BB,9 ,9 ,9 ,9 ,9 ,36,36,36,36,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,36,36,36,36,9 ,9 ,9 ,9 ,9 ,BB,62,62,1 ,31,31,31,31,31,31,31,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 , /*47*/ -/*48*/ 10,9 ,9 ,9 ,9 ,9 ,36,36,36,36,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,36,36,36,36,9 ,9 ,9 ,9 ,9 ,10,62,62,1 ,31,31,31,31,31,31,31,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 , /*48*/ -/*49*/ 10,9 ,9 ,9 ,8 ,35,34,33,32,36,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,36,32,33,34,35,8 ,9 ,9 ,9 ,10,62,62,1 ,31,31,31,31,31,31,31,1 ,1 ,1 ,1 ,4 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,4 ,1 ,1 ,1 ,1 ,1 ,1 , /*49*/ -/*50*/ 10,9 ,9 ,9 ,8 ,43,42,41,40,36,22,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,22,36,40,41,42,43,8 ,9 ,9 ,9 ,10,62,62,1 ,1 ,31,31,31,31,31,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 , /*50*/ -/*51*/ 10,9 ,9 ,9 ,8 ,35,34,33,32,36,22,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,22,36,32,33,34,35,8 ,9 ,9 ,9 ,10,62,62,1 ,1 ,31,31,31,31,31,1 ,1 ,17,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,17,1 ,1 ,1 , /*51*/ -/*52*/ 10,9 ,9 ,9 ,8 ,43,42,41,40,36,22,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,22,36,40,41,42,43,8 ,9 ,9 ,9 ,10,62,62,1 ,1 ,1 ,31,31,31,1 ,1 ,1 ,3 ,1 ,1 ,4 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,4 ,1 ,1 ,3 ,1 ,1 ,1 , /*52*/ -/*53*/ 10,9 ,9 ,9 ,8 ,35,34,33,32,36,22,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,22,36,32,33,34,35,8 ,9 ,9 ,9 ,12,o ,62,62,62,1 ,31,31,31,1 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 , /*53*/ -/*54*/ 10,BB,10,10,8 ,43,42,41,40,36,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,36,40,41,42,43,8 ,10,10,BB,10,o ,o ,21,8 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 , /*54*/ -/*55*/ 10,9 ,9 ,9 ,9 ,9 ,34,33,32,36,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,36,32,33,34,9 ,9 ,9 ,9 ,9 ,10,o ,o ,21,8 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,29,29,2 ,2 ,2 ,29,29,2 ,2 ,2 ,2 ,1 ,1 ,1 , /*55*/ -/*56*/ 10,9 ,9 ,9 ,9 ,9 ,42,41,40,36,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,36,40,41,42,9 ,9 ,9 ,9 ,9 ,10,o ,o ,o ,8 ,62,62,62,62,1 ,1 ,1 ,4 ,2 ,2 ,30,30,30,2 ,2 ,2 ,30,30,30,2 ,2 ,4 ,1 ,1 ,1 , /*56*/ -/*57*/ 10,9 ,9 ,9 ,9 ,9 ,34,33,32,36,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,36,32,33,34,9 ,9 ,9 ,9 ,9 ,10,o ,o ,o ,o ,o ,o ,o ,62,1 ,1 ,1 ,1 ,1 ,2 ,30,30,30,2 ,2 ,2 ,30,30,30,2 ,1 ,1 ,1 ,1 ,1 , /*57*/ -/*58*/ 10,10,10,10,10,43,42,41,40,36,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,36,40,41,42,43,10,10,10,10,10,o ,o ,o ,o ,o ,o ,o ,62,1 ,1 ,1 ,1 ,1 ,2 ,30,30,30,2 ,2 ,2 ,30,30,30,2 ,1 ,1 ,1 ,1 ,1 , /*58*/ -/*59*/ 10,35,35,35,DD,35,34,33,32,40,32,40,40,40,32,40,32,40,32,40,32,40,40,40,32,40,32,33,34,35,DD,35,35,35,10,60,60,60,60,60,60,60,62,1 ,1 ,1 ,1 ,1 ,1 ,30,30,30,2 ,2 ,2 ,30,30,30,1 ,1 ,1 ,1 ,1 ,1 , /*59*/ -/*60*/ 49,35,35,35,8 ,43,42,41,33,41,33,41,33,41,33,41,33,41,33,41,33,41,33,41,33,41,33,41,42,43,8 ,35,35,35,49,o ,o ,o ,o ,o ,o ,o ,62,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 , /*60*/ -/*61*/ 49,35,35,35,8 ,35,34,42,34,42,34,42,34,42,34,42,34,42,34,42,34,42,34,42,34,42,34,42,34,35,8 ,35,35,35,49,o ,o ,o ,o ,o ,o ,o ,62,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 , /*61*/ -/*62*/ 49,35,35,35,8 ,35,35,43,35,43,35,43,35,43,35,43,35,43,35,43,35,43,35,43,35,43,35,43,35,35,8 ,35,35,35,49,o ,o ,o ,o ,o ,o ,o ,62,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 , /*62*/ -/*63*/ 10,35,35,35,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,35,35,35,10,o ,o ,o ,o ,o ,o ,o ,62,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,17,BB,17,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 /*63*/ - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 - #undef AA - #undef BB - #undef CC - #undef DD - #undef o - }, - { // tileDictionary - SFG_TD(19,31,1,0),SFG_TD(23, 0,4,4),SFG_TD(19, 7,4,4),SFG_TD(22, 4,6,0), // 0 - SFG_TD(19, 3,0,3),SFG_TD(23, 3,3,4),SFG_TD(24, 5,4,4),SFG_TD(19,12,4,4), // 4 - SFG_TD(31, 0,0,1),SFG_TD(19, 6,1,1),SFG_TD(23, 0,1,1),SFG_TD(20,11,1,4), // 8 - SFG_TD(19, 4,1,1),SFG_TD(19,15,0,0),SFG_TD(19,15,0,0),SFG_TD(19,15,0,0), // 12 - SFG_TD(19,15,0,0),SFG_TD(23, 0,1,1),SFG_TD(23, 0,2,4),SFG_TD(19,15,0,0), // 16 - SFG_TD(19,15,0,0),SFG_TD(23,31,2,0),SFG_TD(21,31,2,0),SFG_TD(27,31,1,0), // 20 - SFG_TD(19,15,0,0),SFG_TD(22, 3,4,4),SFG_TD(19,15,0,0),SFG_TD(19,15,0,0), // 24 - SFG_TD(19,15,0,0),SFG_TD(18, 8,4,4),SFG_TD(17, 9,4,4),SFG_TD(16,10,4,4), // 28 - SFG_TD(21,20,0,0),SFG_TD(23,18,0,0),SFG_TD(25,16,0,0),SFG_TD(27,14,0,0), // 32 - SFG_TD(19,22,0,0),SFG_TD(19,15,0,0),SFG_TD(19,15,0,0),SFG_TD(19,15,0,0), // 36 - SFG_TD(21,20,2,0),SFG_TD(23,18,2,0),SFG_TD(25,16,2,0),SFG_TD(27,14,2,0), // 40 - SFG_TD(19,15,0,0),SFG_TD(21,10,0,1),SFG_TD(19,12,1,1),SFG_TD(19,15,0,0), // 44 - SFG_TD(19,15,0,0),SFG_TD(29, 3,1,1),SFG_TD(19,15,0,0),SFG_TD(19, 6,4,4), // 48 - SFG_TD(19,15,0,0),SFG_TD(19,15,0,0),SFG_TD(19,15,0,0),SFG_TD(31,31,3,0), // 52 - SFG_TD(19,15,0,0),SFG_TD(19,15,0,0),SFG_TD(19,15,0,0),SFG_TD(21,31,1,0), // 56 - SFG_TD(25,31,4,0),SFG_TD(22,31,2,0),SFG_TD(19, 0,5,5),SFG_TD(27,31,1,0) // 60 - }, // tileDictionary - {3 ,12,0 ,8 ,5 ,1 ,15}, // textureIndices - 7, // doorTextureIndex - 202, // floorColor - 66, // ceilingColor - {53, 61, 64 }, // player start: x, y, direction - 2, // backgroundImage - { // elements - {SFG_LEVEL_ELEMENT_LAMP, {58,3}},{SFG_LEVEL_ELEMENT_COLUMN, {51,4}}, - {SFG_LEVEL_ELEMENT_LOCK2, {51,5}},{SFG_LEVEL_ELEMENT_FINISH, {44,5}}, - {SFG_LEVEL_ELEMENT_COLUMN, {51,6}},{SFG_LEVEL_ELEMENT_LAMP, {58,7}}, - {SFG_LEVEL_ELEMENT_BLOCKER, {9,9}},{SFG_LEVEL_ELEMENT_BLOCKER, {8,9}}, - {SFG_LEVEL_ELEMENT_BLOCKER, {7,9}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {51,10}}, - {SFG_LEVEL_ELEMENT_LAMP, {6,11}},{SFG_LEVEL_ELEMENT_TELEPORTER, {44,12}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {58,13}},{SFG_LEVEL_ELEMENT_TELEPORTER, {23,13}}, - {SFG_LEVEL_ELEMENT_HEALTH, {17,17}},{SFG_LEVEL_ELEMENT_BULLETS, {15,17}}, - {SFG_LEVEL_ELEMENT_BULLETS, {45,18}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {17,18}}, - {SFG_LEVEL_ELEMENT_HEALTH, {55,19}},{SFG_LEVEL_ELEMENT_BULLETS, {53,19}}, - {SFG_LEVEL_ELEMENT_HEALTH, {51,19}},{SFG_LEVEL_ELEMENT_BULLETS, {45,19}}, - {SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {56,21}},{SFG_LEVEL_ELEMENT_LAMP, {20,22}}, - {SFG_LEVEL_ELEMENT_LAMP, {14,22}},{SFG_LEVEL_ELEMENT_RUIN, {26,24}}, - {SFG_LEVEL_ELEMENT_HEALTH, {8,24}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {18,25}}, - {SFG_LEVEL_ELEMENT_BULLETS, {5,25}},{SFG_LEVEL_ELEMENT_ROCKETS, {54,26}}, - {SFG_LEVEL_ELEMENT_PLASMA, {52,26}},{SFG_LEVEL_ELEMENT_HEALTH, {36,26}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {16,26}},{SFG_LEVEL_ELEMENT_TREE, {18,29}}, - {SFG_LEVEL_ELEMENT_TREE, {16,29}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {53,30}}, - {SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {29,35}},{SFG_LEVEL_ELEMENT_ROCKETS, {51,37}}, - {SFG_LEVEL_ELEMENT_HEALTH, {49,37}},{SFG_LEVEL_ELEMENT_COLUMN, {19,37}}, - {SFG_LEVEL_ELEMENT_COLUMN, {15,37}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {60,38}}, - {SFG_LEVEL_ELEMENT_BULLETS, {30,38}},{SFG_LEVEL_ELEMENT_BARREL, {21,38}}, - {SFG_LEVEL_ELEMENT_BARREL, {13,38}},{SFG_LEVEL_ELEMENT_HEALTH, {4,38}}, - {SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {20,40}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {13,40}}, - {SFG_LEVEL_ELEMENT_HEALTH, {21,41}},{SFG_LEVEL_ELEMENT_PLASMA, {13,41}}, - {SFG_LEVEL_ELEMENT_PLASMA, {60,43}},{SFG_LEVEL_ELEMENT_BARREL, {17,46}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {12,46}},{SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {42,47}}, - {SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {40,47}},{SFG_LEVEL_ELEMENT_LOCK0, {34,47}}, - {SFG_LEVEL_ELEMENT_BULLETS, {23,47}},{SFG_LEVEL_ELEMENT_BARREL, {18,47}}, - {SFG_LEVEL_ELEMENT_BARREL, {16,47}},{SFG_LEVEL_ELEMENT_ROCKETS, {11,47}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {3,47}},{SFG_LEVEL_ELEMENT_LOCK0, {0,47}}, - {SFG_LEVEL_ELEMENT_BARREL, {41,48}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {32,48}}, - {SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {21,48}},{SFG_LEVEL_ELEMENT_BARREL, {17,48}}, - {SFG_LEVEL_ELEMENT_BARREL, {42,49}},{SFG_LEVEL_ELEMENT_BARREL, {40,49}}, - {SFG_LEVEL_ELEMENT_PLASMA, {42,50}},{SFG_LEVEL_ELEMENT_PLASMA, {40,50}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {43,51}},{SFG_LEVEL_ELEMENT_PLASMA, {41,51}}, - {SFG_LEVEL_ELEMENT_PLASMA, {39,51}},{SFG_LEVEL_ELEMENT_PLASMA, {60,52}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {46,52}},{SFG_LEVEL_ELEMENT_RUIN, {33,52}}, - {SFG_LEVEL_ELEMENT_TERMINAL, {41,53}},{SFG_LEVEL_ELEMENT_HEALTH, {40,53}}, - {SFG_LEVEL_ELEMENT_PLASMA, {21,53}},{SFG_LEVEL_ELEMENT_HEALTH, {13,53}}, - {SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {21,54}},{SFG_LEVEL_ELEMENT_MONSTER_ENDER, {17,55}}, - {SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {13,55}},{SFG_LEVEL_ELEMENT_HEALTH, {30,56}}, - {SFG_LEVEL_ELEMENT_BARREL, {21,56}},{SFG_LEVEL_ELEMENT_BARREL, {13,56}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {4,56}},{SFG_LEVEL_ELEMENT_HEALTH, {41,57}}, - {SFG_LEVEL_ELEMENT_COLUMN, {19,57}},{SFG_LEVEL_ELEMENT_COLUMN, {15,57}}, - {SFG_LEVEL_ELEMENT_RUIN, {29,59}},{SFG_LEVEL_ELEMENT_LOCK0, {4,59}}, - {SFG_LEVEL_ELEMENT_LOCK1, {53,63}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}} - }, // elements - } // level - ; - -SFG_PROGRAM_MEMORY SFG_Level SFG_level5 = - { // level - { // mapArray - #define o 0 - #define AA (63 | SFG_TILE_PROPERTY_ELEVATOR) - #define BB (32 | SFG_TILE_PROPERTY_DOOR) - #define CC (30 | SFG_TILE_PROPERTY_DOOR) - #define DD (59 | SFG_TILE_PROPERTY_ELEVATOR) - #define EE (53 | SFG_TILE_PROPERTY_DOOR) - #define FF (44 | SFG_TILE_PROPERTY_DOOR) - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 -/*0 */ 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,1 ,1 ,1 ,1 ,1 ,1 ,1 ,5 ,1 ,1 ,1 ,1 ,5 ,7 ,5 ,1 ,1 ,1 ,1 ,5 ,1 ,1 ,1 ,1 ,5 ,1 ,1 ,1 ,1 ,5 ,1 ,1 ,1 ,1 ,5 ,2 ,2 ,2 ,2 , /*0 */ -/*1 */ 22,22,22,22,22,22,22,22,o ,o ,o ,22,22,22,22,22,22,22,22,22,22,22,22,22,22,1 ,1 ,1 ,1 ,1 ,1 ,1 ,35,31,o ,o ,31,35,7 ,40,40,40,40,40,40,40,40,40,26,35,31,o ,o ,31,35,31,o ,o ,31,35,2 ,2 ,2 ,2 , /*1 */ -/*2 */ 23,23,23,23,23,23,22,22,o ,o ,o ,22,22,22,22,22,22,22,22,22,22,22,22,22,22,1 ,1 ,1 ,1 ,1 ,1 ,1 ,35,31,o ,o ,31,35,7 ,11,10,40,40,40,40,40,40,40,26,35,31,o ,o ,31,35,31,o ,o ,31,35,2 ,2 ,2 ,2 , /*2 */ -/*3 */ 23,23,23,23,23,23,22,22,o ,o ,o ,o ,o ,o ,o ,o ,3 ,o ,o ,o ,o ,55,55,55,60,60,60,1 ,1 ,1 ,1 ,1 ,35,o ,o ,o ,o ,35,7 ,11,10,40,40,40,40,40,40,40,26,35,o ,o ,o ,o ,35,o ,o ,o ,o ,35,2 ,2 ,2 ,2 , /*3 */ -/*4 */ 23,23,23,23,23,23,22,22,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,o ,o ,o ,o ,56,56,55,55,60,60,1 ,1 ,1 ,1 ,1 ,35,o ,o ,o ,o ,35,7 ,11,10,40,40,40,40,40,40,40,40,35,o ,o ,o ,o ,35,o ,o ,o ,o ,35,2 ,2 ,2 ,2 , /*4 */ -/*5 */ 23,23,23,23,23,23,55,55,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,61,61,56,56,5 ,1 ,1 ,5 ,35,35,35,35,35,35,o ,o ,35,35,7 ,40,40,40,40,40,40,40,40,40,40,35,35,o ,o ,35,35,35,o ,o ,35,35,31,31,31,31, /*5 */ -/*6 */ 23,23,23,23,23,23,61,61,55,55,o ,o ,o ,o ,o ,o ,o ,o ,o ,61,2 ,2 ,2 ,61,1 ,1 ,1 ,1 ,31,31,o ,o ,35,o ,o ,o ,o ,o ,7 ,7 ,7 ,7 ,10,34,10,34,40,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o , /*6 */ -/*7 */ 23,23,23,23,23,23,2 ,2 ,56,55,55,55,55,o ,o ,o ,o ,55,55,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,7 ,10,34,10,34,40,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o , /*7 */ -/*8 */ 23,o ,o ,2 ,2 ,2 ,2 ,2 ,2 ,56,55,55,55,55,55,55,55,55,61,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,7 ,35,35,35,35,35,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o , /*8 */ -/*9 */ 23,o ,o ,56,56,2 ,2 ,2 ,2 ,61,61,61,61,55,55,55,61,61,61,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,31,31,o ,o ,35,o ,o ,o ,o ,o ,o ,o ,o ,7 ,31,o ,o ,o ,35,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o , /*9 */ -/*10*/ 23,o ,o ,o ,56,56,2 ,2 ,2 ,61,55,55,55,o ,o ,o ,o ,55,55,61,2 ,2 ,2 ,61,5 ,1 ,1 ,5 ,35,35,35,35,35,o ,o ,o ,o ,o ,o ,o ,o ,7 ,31,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o , /*10*/ -/*11*/ 23,o ,o ,23,23,23,2 ,2 ,2 ,55,55,o ,o ,o ,o ,o ,o ,o ,o ,o ,56,56,o ,61,2 ,2 ,2 ,2 ,2 ,56,21,21,21,31,o ,o ,o ,o ,o ,o ,o ,7 ,31,o ,o ,o ,35,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,3 ,3 ,3 ,o ,o ,o ,o , /*11*/ -/*12*/ 23,o ,o ,23,23,23,2 ,2 ,61,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,61,2 ,2 ,2 ,61,o ,21,21,21,31,o ,o ,o ,o ,o ,o ,o ,7 ,35,35,35,35,35,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,40,40,o ,o ,o ,o ,o , /*12*/ -/*13*/ 23,o ,o ,23,23,23,61,2 ,55,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,61,56,o ,o ,o ,21,21,21,16,o ,o ,o ,o ,o ,o ,o ,7 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,o ,o ,o ,3 ,3 ,3 ,3 ,3 ,40,40,o ,o ,o ,o ,o , /*13*/ -/*14*/ 23,23,23,23,23,23,56,56,55,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,21,21,21,31,o ,o ,o ,o ,o ,o ,o ,7 ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,40,40,o ,o ,o ,o ,o , /*14*/ -/*15*/ 23,23,22,22,22,22,22,22,22,22,37,16,57,57,26,57,57,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,21,21,21,31,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,23,23,23,23,23,29,o ,o , /*15*/ -/*16*/ 23,23,22,22,22,22,22,22,22,22,22,12,57,26,26,26,26,21,21,21,21,21,21,o ,o ,o ,o ,22,22,22,21,21,21,16,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,23,23,23,23,23,23,o ,o , /*16*/ -/*17*/ 23,23,AA,o ,o ,22,22,22,22,22,22,17,13,26,26,26,26,21,21,21,21,21,21,o ,o ,o ,o ,22,22,22,21,21,21,31,o ,o ,o ,o ,o ,o ,o ,7 ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,23,23,23,23,23,23,23,29, /*17*/ -/*18*/ 23,23,10,o ,o ,22,22,22,22,22,22,12,57,26,26,26,26,21,21,21,21,21,21,o ,o ,o ,o ,22,22,22,21,21,21,31,o ,o ,o ,o ,o ,16,16,7 ,3 ,o ,o ,o ,o ,o ,o ,11,11,11,o ,o ,o ,o ,23,23,23,23,23,23,23,23, /*18*/ -/*19*/ 23,23,8 ,o ,o ,22,22,22,22,22,22,16,57,26,26,26,57,o ,16,o ,o ,16,o ,o ,o ,o ,o ,16,31,31,16,31,31,16,o ,o ,o ,o ,o ,12,12,7 ,3 ,o ,o ,o ,8 ,9 ,10,11,11,11,10,9 ,8 ,o ,23,23,23,23,23,27,23,29, /*19*/ -/*20*/ 23,23,o ,o ,o ,22,22,22,22,22,22,o ,57,57,57,57,57,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,17,17,7 ,3 ,3 ,3 ,o ,8 ,9 ,10,11,11,11,10,9 ,8 ,o ,23,23,23,27,1 ,1 ,9 ,9 , /*20*/ -/*21*/ 23,23,o ,22,22,22,22,22,22,22,37,o ,o ,62,o ,62,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,13,13,7 ,7 ,7 ,7 ,23,27,1 ,27,15,15,15,27,1 ,27,23,23,23,23,27,o ,o ,o ,o , /*21*/ -/*22*/ 30,o ,o ,35,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,54,13,13,13,13,13,23,23,23,27,15,15,15,27,23,23,23,23,23,33,BB,o ,o ,o ,o , /*22*/ -/*23*/ 30,52,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,61,61,2 ,2 ,2 ,2 ,13,o ,o ,13,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,61,61,54,13,13,13,13,23,23,23,27,15,15,15,27,27,27,27,27,27,27,27,o ,o ,o ,o , /*23*/ -/*24*/ 30,52,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,12,o ,o ,12,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,54,13,13,13,23,23,23,27,15,15,15,15,15,15,15,15,27,27,27,1 ,1 ,9 ,9 , /*24*/ -/*25*/ 30,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,56,54,13,13,23,23,23,27,15,15,15,15,15,15,15,15,27,27,23,23,27,23,29, /*25*/ -/*26*/ 30,52,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,12,o ,o ,12,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,56,54,13,23,23,23,27,27,27,27,27,27,27,15,15,27,27,23,23,23,23,23, /*26*/ -/*27*/ 30,52,2 ,2 ,2 ,61,61,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,13,o ,o ,13,2 ,2 ,2 ,61,61,61,61,61,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,56,54,13,13,13,30,13,13,22,22,22,22,27,15,15,27,27,22,22,22,22,22, /*27*/ -/*28*/ 3 ,o ,o ,o ,o ,o ,o ,o ,4 ,2 ,4 ,o ,o ,o ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,2 ,2 ,2 ,2 ,2 ,54,13,13,13,CC,13,13,22,22,22,22,27,15,15,27,27,22,22,22,22,22, /*28*/ -/*29*/ 3 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,2 ,4 ,o ,o ,o ,35,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,2 ,2 ,2 ,2 ,54,13,13,13,30,13,13,22,22,22,22,27,27,27,27,27,22,22,22,22,22, /*29*/ -/*30*/ 3 ,2 ,DD,DD,DD,4 ,4 ,2 ,2 ,2 ,4 ,o ,o ,o ,35,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,2 ,2 ,2 ,2 ,54,13,13,13,30,30,30,23,23,23,23,23,23,23,23,23,23,23,23,o ,o , /*30*/ -/*31*/ 3 ,2 ,DD,DD,DD,4 ,4 ,2 ,4 ,4 ,4 ,o ,o ,o ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,2 ,2 ,2 ,2 ,2 ,54,13,13,13,13,30,23,23,20,20,20,20,20,20,20,20,23,23,o ,o , /*31*/ -/*32*/ 3 ,2 ,DD,DD,DD,4 ,4 ,2 ,4 ,4 ,4 ,37,36,36,36,36,49,o ,o ,o ,o ,o ,31,31,16,16,31,31,o ,o ,o ,31,31,31,31,o ,o ,o ,o ,61,2 ,2 ,2 ,2 ,61,54,13,13,13,22,23,23,12,12,12,12,12,12,12,12,23,23,o ,o , /*32*/ -/*33*/ 3 ,2 ,4 ,4 ,4 ,4 ,4 ,2 ,2 ,2 ,4 ,36,58,58,58,58,37,o ,o ,o ,o ,37,22,22,22,22,22,22,37,31,37,22,22,22,22,49,55,55,55,61,2 ,2 ,2 ,2 ,2 ,54,17,17,17,22,23,23,12,12,12,12,12,12,12,12,23,23,o ,o , /*33*/ -/*34*/ 3 ,2 ,4 ,2 ,2 ,2 ,4 ,2 ,2 ,2 ,4 ,36,58,58,58,58,58,o ,o ,o ,o ,22,22,22,22,22,22,22,37,21,37,22,22,22,22,22,o ,o ,o ,o ,56,2 ,2 ,2 ,2 ,54,12,12,12,30,23,23,20,20,20,12,12,20,20,20,23,23,o ,o , /*34*/ -/*35*/ 3 ,2 ,4 ,2 ,4 ,2 ,16,4 ,4 ,2 ,4 ,36,58,58,58,58,37,o ,o ,o ,o ,22,22,22,22,22,22,22,37,21,37,22,22,22,22,49,o ,o ,o ,o ,o ,2 ,2 ,2 ,2 ,54,16,16,16,30,23,23,23,23,20,12,12,20,23,23,23,23,o ,o , /*35*/ -/*36*/ 3 ,2 ,2 ,2 ,4 ,2 ,12,2 ,2 ,2 ,4 ,36,19,58,19,19,36,o ,o ,o ,o ,22,22,22,22,22,22,22,22,13,13,13,13,17,12,16,o ,o ,o ,o ,o ,2 ,2 ,2 ,2 ,o ,o ,o ,o ,30,27,23,23,23,27,EE,EE,27,23,23,23,27,o ,o , /*36*/ -/*37*/ 3 ,2 ,2 ,2 ,4 ,2 ,17,2 ,4 ,4 ,4 ,36,58,58,58,58,36,o ,o ,o ,o ,49,22,22,22,22,22,22,22,13,13,13,13,17,12,16,o ,o ,o ,o ,o ,2 ,2 ,2 ,2 ,o ,o ,o ,o ,30,3 ,o ,22,22,17,12,12,17,22,22,60,3 ,3 ,o , /*37*/ -/*38*/ 3 ,2 ,2 ,2 ,4 ,2 ,2 ,2 ,2 ,2 ,4 ,36,58,58,58,58,36,o ,o ,o ,o ,22,22,22,22,37,37,37,49,13,13,13,13,17,12,16,o ,o ,o ,o ,60,2 ,2 ,2 ,2 ,o ,o ,o ,62,30,3 ,o ,o ,12,12,12,60,60,12,o ,o ,3 ,3 ,o , /*38*/ -/*39*/ 3 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,37,58,58,58,36,49,o ,o ,o ,o ,22,22,22,22,36,13,13,13,13,13,13,37,22,22,37,o ,o ,o ,o ,o ,2 ,2 ,2 ,61,o ,o ,o ,o ,30,3 ,o ,o ,60,12,o ,o ,60,12,o ,o ,3 ,3 ,o , /*39*/ -/*40*/ 3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,FF,58,58,58,36,o ,o ,o ,o ,o ,22,22,22,22,36,13,13,13,13,13,13,22,22,22,22,o ,o ,o ,o ,o ,2 ,2 ,2 ,61,o ,o ,o ,62,30,3 ,o ,o ,16,16,o ,o ,16,16,o ,o ,3 ,3 ,o , /*40*/ -/*41*/ 3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,37,58,58,58,36,o ,21,21,21,21,22,22,22,22,37,37,37,22,13,13,13,22,22,22,49,o ,o ,o ,o ,60,2 ,2 ,2 ,61,o ,o ,o ,o ,30,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,3 ,o , /*41*/ -/*42*/ 7 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,37,36,36,36,37,o ,21,21,21,21,37,37,22,22,49,49,22,22,13,13,13,37,22,22,21,o ,o ,o ,o ,o ,2 ,2 ,2 ,56,o ,o ,o ,o ,30,3 ,31,o ,o ,o ,o ,o ,o ,o ,o ,31,3 ,3 ,o , /*42*/ -/*43*/ 7 ,55,55,55,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,16,12,17,13,13,13,13,13,13,13,13,13,13,13,22,22,22,21,62,o ,o ,o ,o ,2 ,2 ,2 ,56,o ,o ,o ,o ,30,3 ,60,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,3 ,o , /*43*/ -/*44*/ 7 ,55,55,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,16,12,17,13,13,13,13,13,13,13,13,13,13,13,22,22,22,21,o ,o ,o ,o ,o ,13,12,12,13,o ,o ,o ,o ,30,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,3 ,o , /*44*/ -/*45*/ 7 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,8 ,o ,o ,16,12,17,13,13,13,13,13,13,13,13,13,13,37,22,22,37,21,62,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,30,3 ,31,o ,o ,o ,o ,o ,o ,55,o ,31,3 ,3 ,28, /*45*/ -/*46*/ 7 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,21,21,21,21,21,22,22,49,30,30,13,13,13,13,13,13,13,13,13,49,22,37,21,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,30,3 ,o ,o ,o ,o ,o ,o ,o ,55,o ,o ,3 ,3 ,28, /*46*/ -/*47*/ 7 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,21,21,21,21,21,22,22,22,13,30,13,13,13,13,13,13,13,13,13,49,22,37,21,62,o ,o ,o ,o ,13,12,12,13,o ,o ,o ,o ,30,3 ,o ,o ,o ,o ,o ,o ,o ,55,55,o ,3 ,3 ,28, /*47*/ -/*48*/ 7 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,21,21,21,21,21,22,22,22,13,13,13,13,13,13,13,13,13,13,37,22,22,37,21,o ,o ,o ,o ,o ,2 ,2 ,2 ,2 ,o ,o ,o ,o ,30,3 ,3 ,3 ,3 ,o ,o ,o ,o ,3 ,3 ,3 ,3 ,3 ,28, /*48*/ -/*49*/ 7 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,55,22,22,22,21,21,22,22,22,13,30,13,13,13,13,13,13,13,13,13,22,22,22,21,62,o ,o ,o ,o ,2 ,2 ,2 ,2 ,o ,o ,o ,o ,30,60,60,o ,3 ,o ,o ,o ,o ,3 ,o ,o ,o ,3 ,28, /*49*/ -/*50*/ 7 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,61,61,22,22,22,21,21,22,22,37,13,30,30,30,30,30,30,13,13,13,13,22,22,22,21,o ,o ,o ,o ,60,2 ,2 ,2 ,2 ,o ,o ,o ,62,30,o ,o ,o ,3 ,3 ,o ,o ,3 ,3 ,o ,o ,o ,37,37, /*50*/ -/*51*/ 7 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,56,2 ,2 ,36,22,21,21,22,22,49,13,13,13,13,13,13,30,13,13,13,13,37,22,22,49,o ,o ,o ,o ,o ,2 ,2 ,2 ,2 ,o ,o ,o ,o ,30,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,22,22, /*51*/ -/*52*/ 7 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,55,2 ,61,36,22,22,22,22,22,49,49,37,22,22,22,22,22,22,49,13,13,22,22,22,22,16,o ,o ,o ,o ,2 ,2 ,2 ,2 ,o ,o ,o ,62,30,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,22,22, /*52*/ -/*53*/ 7 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,13,13,22,22,22,22,12,o ,o ,o ,60,2 ,2 ,2 ,2 ,o ,o ,o ,o ,30,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,22,22, /*53*/ -/*54*/ 7 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,37,37,37,37,37,37,37,37,22,22,22,49,22,49,22,22,49,13,13,37,22,22,37,17,o ,o ,o ,o ,2 ,2 ,2 ,2 ,o ,o ,o ,21,21,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,60,22,22, /*54*/ -/*55*/ 7 ,o ,o ,8 ,9 ,10,10,10,9 ,8 ,o ,o ,o ,o ,o ,o ,o ,16,12,17,13,o ,o ,o ,o ,o ,o ,o ,o ,35,13,13,13,13,13,13,13,o ,o ,o ,o ,2 ,2 ,2 ,2 ,o ,o ,o ,21,21,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,7 ,7 ,22,22, /*55*/ -/*56*/ 22,22,23,23,23,23,EE,23,23,23,23,22,22,37,37,37,37,37,37,37,37,22,o ,o ,o ,o ,o ,o ,62,35,13,13,13,13,13,13,13,o ,o ,o ,o ,52,52,2 ,52,o ,o ,o ,21,21,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,7 ,o ,o ,o , /*56*/ -/*57*/ 22,22,23,20,20,14,14,14,20,23,23,22,22,22,22,22,22,22,23,23,23,22,8 ,o ,o ,o ,o ,o ,o ,35,17,17,12,16,o ,o ,o ,o ,o ,o ,o ,DD,2 ,2 ,2 ,o ,o ,o ,21,21,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,7 ,o ,o ,o , /*57*/ -/*58*/ 20,20,20,14,14,14,14,14,20,20,20,19,19,19,19,19,19,19,AA,20,20,22,9 ,o ,o ,o ,o ,o ,6 ,35,17,17,12,16,o ,o ,o ,o ,o ,o ,o ,DD,2 ,2 ,2 ,o ,o ,o ,21,21,o ,30,30,30,o ,o ,o ,o ,21,21,21,o ,o ,21, /*58*/ -/*59*/ 20,14,14,14,14,20,20,20,20,14,14,14,14,14,14,14,14,14,14,14,14,23,10,o ,o ,o ,o ,o ,21,21,17,17,37,37,37,37,23,23,23,23,23,3 ,3 ,3 ,3 ,o ,o ,o ,21,21,7 ,21,21,21,o ,o ,o ,56,21,21,21,2 ,o ,21, /*59*/ -/*60*/ 20,14,14,14,14,14,14,14,20,14,14,14,14,14,14,14,14,14,14,14,14,EE,10,o ,o ,o ,o ,o ,21,20,EE,EE,20,20,20,20,20,20,14,14,14,10,9 ,8 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,61,2 ,2 ,2 ,2 ,o ,21, /*60*/ -/*61*/ 20,14,14,14,14,14,14,14,EE,14,14,14,14,14,20,20,14,14,14,14,14,23,9 ,o ,o ,o ,o ,o ,21,20,14,14,14,EE,14,14,14,14,14,14,14,10,9 ,8 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,61,2 ,2 ,2 ,2 ,61,o ,21, /*61*/ -/*62*/ 20,14,14,14,14,14,14,14,20,14,14,14,14,14,20,20,20,20,20,20,20,23,8 ,o ,o ,o ,6 ,o ,21,20,14,14,14,20,14,14,14,14,14,20,23,3 ,3 ,3 ,3 ,21,21,21,23,23,23,23,23,23,55,56,61,2 ,2 ,2 ,2 ,o ,o ,21, /*62*/ -/*63*/ 20,20,50,50,20,50,50,20,20,20,50,20,50,20,20,20,20,20,20,20,20,23,7 ,7 ,7 ,7 ,7 ,7 ,23,20,20,20,20,20,20,20,20,20,20,20,23,28,28,28,28,21,21,21,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23 /*63*/ - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 - #undef AA - #undef BB - #undef CC - #undef DD - #undef EE - #undef FF - #undef o - }, - { // tileDictionary - SFG_TD(10,31,1,0),SFG_TD(29,31,0,0),SFG_TD( 0,31,0,0),SFG_TD(17,31,2,0), // 0 - SFG_TD(10,31,2,0),SFG_TD(29,31,2,0),SFG_TD(14,31,5,0),SFG_TD(21,31,2,0), // 4 - SFG_TD(11,31,4,0),SFG_TD(12,31,4,0),SFG_TD(13,31,4,0),SFG_TD(14,31,4,0), // 8 - SFG_TD(12,31,2,0),SFG_TD(14,31,2,0),SFG_TD(13, 5,2,0),SFG_TD(14, 7,2,0), // 12 - SFG_TD(11,31,2,0),SFG_TD(13,31,2,0),SFG_TD(10, 7,0,0),SFG_TD(30,31,2,0), // 16 - SFG_TD(30, 0,2,0),SFG_TD(26,31,0,0),SFG_TD(30,31,0,0),SFG_TD(10, 0,0,0), // 20 - SFG_TD(10, 7,0,0),SFG_TD(10, 7,0,0),SFG_TD(15,31,6,0),SFG_TD(10, 0,3,3), // 24 - SFG_TD(24,31,6,0),SFG_TD(31, 0,2,0),SFG_TD(18,31,6,0),SFG_TD(13,31,6,0), // 28 - SFG_TD(14, 0,1,0),SFG_TD(10, 7,1,0),SFG_TD(13,31,2,0),SFG_TD(17,31,4,0), // 32 - SFG_TD(30,31,4,0),SFG_TD(30,31,3,0),SFG_TD(10, 7,0,0),SFG_TD(10, 7,0,0), // 36 - SFG_TD(11,31,2,0),SFG_TD(10, 7,0,0),SFG_TD(10, 7,0,0),SFG_TD(10, 7,0,0), // 40 - SFG_TD(14, 0,1,0),SFG_TD(10, 7,0,0),SFG_TD(10, 7,0,0),SFG_TD(10, 7,0,0), // 44 - SFG_TD(10, 7,0,0),SFG_TD(30,31,2,0),SFG_TD(15, 2,2,2),SFG_TD(13, 5,2,0), // 48 - SFG_TD( 9,31,5,0),SFG_TD(17, 0,3,3),SFG_TD(14,31,1,0),SFG_TD( 9,31,1,0), // 52 - SFG_TD( 6,31,1,0),SFG_TD(18,31,0,0),SFG_TD(10,11,3,3),SFG_TD( 0,10,5,0), // 56 - SFG_TD(12,31,1,0),SFG_TD( 3,31,1,0),SFG_TD(12,31,5,0),SFG_TD(13,17,5,0) // 60 - }, // tileDictionary - {1 ,9 ,12,14,5 ,0 ,6 }, // textureIndices - 7, // doorTextureIndex - 20, // floorColor - 3, // ceilingColor - {50, 24, 64 }, // player start: x, y, direction - 0, // backgroundImage - { // elements - {SFG_LEVEL_ELEMENT_BULLETS, {35,1}},{SFG_LEVEL_ELEMENT_BULLETS, {34,1}}, - {SFG_LEVEL_ELEMENT_RUIN, {6,5}},{SFG_LEVEL_ELEMENT_HEALTH, {30,6}}, - {SFG_LEVEL_ELEMENT_RUIN, {23,7}},{SFG_LEVEL_ELEMENT_HEALTH, {23,8}}, - {SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {37,9}},{SFG_LEVEL_ELEMENT_RUIN, {4,9}}, - {SFG_LEVEL_ELEMENT_RUIN, {20,10}},{SFG_LEVEL_ELEMENT_CARD2, {5,10}}, - {SFG_LEVEL_ELEMENT_HEALTH, {26,11}},{SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {22,11}}, - {SFG_LEVEL_ELEMENT_RUIN, {51,13}},{SFG_LEVEL_ELEMENT_RUIN, {50,13}}, - {SFG_LEVEL_ELEMENT_RUIN, {49,13}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {21,13}}, - {SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {19,13}},{SFG_LEVEL_ELEMENT_ROCKETS, {55,14}}, - {SFG_LEVEL_ELEMENT_BULLETS, {54,14}},{SFG_LEVEL_ELEMENT_BULLETS, {9,16}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {16,17}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {7,17}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {6,18}},{SFG_LEVEL_ELEMENT_LAMP, {43,19}}, - {SFG_LEVEL_ELEMENT_LAMP, {21,19}},{SFG_LEVEL_ELEMENT_LAMP, {18,19}}, - {SFG_LEVEL_ELEMENT_CARD1, {9,20}},{SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {8,20}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {50,21}},{SFG_LEVEL_ELEMENT_LAMP, {5,22}}, - {SFG_LEVEL_ELEMENT_TREE, {4,22}},{SFG_LEVEL_ELEMENT_RUIN, {34,23}}, - {SFG_LEVEL_ELEMENT_BLOCKER, {53,24}},{SFG_LEVEL_ELEMENT_BLOCKER, {53,25}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {18,25}},{SFG_LEVEL_ELEMENT_RUIN, {1,25}}, - {SFG_LEVEL_ELEMENT_PLASMA, {49,27}},{SFG_LEVEL_ELEMENT_ROCKETS, {48,27}}, - {SFG_LEVEL_ELEMENT_PLASMA, {34,27}},{SFG_LEVEL_ELEMENT_BULLETS, {49,28}}, - {SFG_LEVEL_ELEMENT_LOCK2, {47,28}},{SFG_LEVEL_ELEMENT_LAMP, {15,28}}, - {SFG_LEVEL_ELEMENT_RUIN, {13,28}},{SFG_LEVEL_ELEMENT_PLASMA, {49,29}}, - {SFG_LEVEL_ELEMENT_HEALTH, {48,29}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {45,29}}, - {SFG_LEVEL_ELEMENT_LAMP, {35,32}},{SFG_LEVEL_ELEMENT_LAMP, {21,32}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {7,32}},{SFG_LEVEL_ELEMENT_FINISH, {56,34}}, - {SFG_LEVEL_ELEMENT_FINISH, {55,34}},{SFG_LEVEL_ELEMENT_PLASMA, {24,34}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {56,35}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {55,35}}, - {SFG_LEVEL_ELEMENT_BULLETS, {24,35}},{SFG_LEVEL_ELEMENT_BARREL, {20,35}}, - {SFG_LEVEL_ELEMENT_PLASMA, {9,35}},{SFG_LEVEL_ELEMENT_BULLETS, {5,35}}, - {SFG_LEVEL_ELEMENT_COLUMN, {57,37}},{SFG_LEVEL_ELEMENT_COLUMN, {54,37}}, - {SFG_LEVEL_ELEMENT_BULLETS, {15,37}},{SFG_LEVEL_ELEMENT_HEALTH, {60,38}}, - {SFG_LEVEL_ELEMENT_RUIN, {44,38}},{SFG_LEVEL_ELEMENT_ROCKETS, {26,39}}, - {SFG_LEVEL_ELEMENT_CARD0, {34,40}},{SFG_LEVEL_ELEMENT_LOCK1, {11,40}}, - {SFG_LEVEL_ELEMENT_PLASMA, {19,41}},{SFG_LEVEL_ELEMENT_TERMINAL, {14,41}}, - {SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {55,42}},{SFG_LEVEL_ELEMENT_TREE, {36,42}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {19,42}},{SFG_LEVEL_ELEMENT_HEALTH, {60,44}}, - {SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {56,44}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {54,44}}, - {SFG_LEVEL_ELEMENT_TREE, {48,44}},{SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {33,44}}, - {SFG_LEVEL_ELEMENT_BULLETS, {48,45}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {27,45}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {26,45}},{SFG_LEVEL_ELEMENT_COLUMN, {15,45}}, - {SFG_LEVEL_ELEMENT_TREE, {48,46}},{SFG_LEVEL_ELEMENT_LAMP, {1,47}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {15,48}},{SFG_LEVEL_ELEMENT_ROCKETS, {14,48}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {7,48}},{SFG_LEVEL_ELEMENT_HEALTH, {61,49}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {6,49}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {3,49}}, - {SFG_LEVEL_ELEMENT_TREE, {36,50}},{SFG_LEVEL_ELEMENT_HEALTH, {5,50}}, - {SFG_LEVEL_ELEMENT_LAMP, {58,51}},{SFG_LEVEL_ELEMENT_LAMP, {53,51}}, - {SFG_LEVEL_ELEMENT_HEALTH, {26,51}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {12,51}}, - {SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {7,51}},{SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {26,53}}, - {SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {5,53}},{SFG_LEVEL_ELEMENT_LAMP, {1,53}}, - {SFG_LEVEL_ELEMENT_PLASMA, {58,55}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {55,55}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {50,55}},{SFG_LEVEL_ELEMENT_BLOCKER, {29,55}}, - {SFG_LEVEL_ELEMENT_BARREL, {13,55}},{SFG_LEVEL_ELEMENT_BLOCKER, {29,56}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {25,56}},{SFG_LEVEL_ELEMENT_BLOCKER, {29,57}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {24,57}},{SFG_LEVEL_ELEMENT_RUIN, {47,58}}, - {SFG_LEVEL_ELEMENT_RUIN, {46,58}},{SFG_LEVEL_ELEMENT_BLOCKER, {29,58}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {23,58}},{SFG_LEVEL_ELEMENT_BULLETS, {21,58}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {18,58}},{SFG_LEVEL_ELEMENT_RUIN, {46,59}}, - {SFG_LEVEL_ELEMENT_RUIN, {45,59}},{SFG_LEVEL_ELEMENT_LOCK0, {31,60}}, - {SFG_LEVEL_ELEMENT_LOCK0, {30,60}},{SFG_LEVEL_ELEMENT_TREE, {7,60}}, - {SFG_LEVEL_ELEMENT_LOCK1, {33,61}},{SFG_LEVEL_ELEMENT_TREE, {16,61}}, - {SFG_LEVEL_ELEMENT_TREE, {13,61}},{SFG_LEVEL_ELEMENT_LOCK0, {8,61}}, - {SFG_LEVEL_ELEMENT_BARREL, {27,62}},{SFG_LEVEL_ELEMENT_HEALTH, {25,62}}, - {SFG_LEVEL_ELEMENT_TREE, {1,62}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}} - }, // elements - } // level - ; - -SFG_PROGRAM_MEMORY SFG_Level SFG_level6 = - { // level - { // mapArray - #define o 0 - #define AA (17 | SFG_TILE_PROPERTY_DOOR) - #define BB (33 | SFG_TILE_PROPERTY_DOOR) - #define CC (16 | SFG_TILE_PROPERTY_ELEVATOR) - #define DD (1 | SFG_TILE_PROPERTY_DOOR) - #define EE (41 | SFG_TILE_PROPERTY_ELEVATOR) - #define FF (55 | SFG_TILE_PROPERTY_DOOR) - #define GG (56 | SFG_TILE_PROPERTY_ELEVATOR) - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 -/*0 */ 1 ,1 ,1 ,1 ,1 ,5 ,1 ,1 ,1 ,1 ,1 ,1 ,5 ,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,33,50,50,33,33,33,50,5 ,19,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,o ,o ,o ,o ,o , /*0 */ -/*1 */ 47,14,14,1 ,13,13,13,13,13,13,13,13,13,13,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,31,31,50,31,31,31,50,5 ,19,19,19,5 ,19,19,19,5 ,19,19,19,5 ,5 ,19,19,19,19,19,20,o ,o ,o ,o ,o , /*1 */ -/*2 */ 47,14,14,15,13,13,13,13,13,13,13,13,13,13,1 ,5 ,5 ,33,50,50,50,33,5 ,5 ,5 ,33,50,50,50,33,5 ,5 ,31,31,50,31,31,31,50,50,50,33,50,50,50,33,50,50,50,33,50,50,5 ,19,19,19,19,19,20,o ,o ,o ,o ,o , /*2 */ -/*3 */ 63,14,14,15,13,13,13,13,13,13,13,13,13,13,1 ,5 ,31,31,31,50,31,31,31,5 ,31,31,31,50,31,31,31,5 ,31,31,50,31,31,31,50,5 ,31,31,31,50,31,31,31,5 ,31,31,31,31,19,19,19,19,19,19,20,o ,o ,o ,o ,o , /*3 */ -/*4 */ 63,14,14,15,13,13,13,35,35,35,35,13,13,13,1 ,1 ,31,31,34,63,34,31,31,1 ,31,31,34,63,34,31,31,1 ,31,31,50,31,31,31,50,5 ,31,31,34,63,34,31,31,5 ,31,31,31,31,5 ,19,19,19,19,19,20,o ,o ,o ,o ,o , /*4 */ -/*5 */ 1 ,1 ,AA,1 ,13,13,13,35,13,13,35,13,13,13,1 ,5 ,31,31,31,50,31,31,31,5 ,31,31,31,50,31,31,31,5 ,31,31,50,31,31,31,50,50,31,31,31,50,31,31,31,50,31,31,31,50,5 ,1 ,19,19,19,19,20,o ,o ,o ,o ,o , /*5 */ -/*6 */ 1 ,1 ,CC,1 ,13,13,13,35,35,35,35,13,13,13,1 ,5 ,31,31,34,63,34,31,31,5 ,31,31,34,63,34,31,31,5 ,31,31,BB,31,31,31,50,5 ,31,31,34,63,34,31,31,5 ,31,31,34,63,5 ,24,19,19,19,19,20,o ,o ,o ,o ,o , /*6 */ -/*7 */ o ,1 ,DD,1 ,13,13,13,13,13,13,13,13,13,13,1 ,1 ,31,31,34,63,34,31,31,1 ,31,31,34,63,34,31,31,1 ,31,31,50,31,31,31,50,50,31,31,34,63,34,31,31,50,31,31,34,63,5 ,24,19,19,19,19,20,o ,o ,o ,o ,o , /*7 */ -/*8 */ o ,1 ,18,18,13,13,13,13,13,13,13,13,13,13,1 ,5 ,31,31,31,50,31,31,31,5 ,31,31,31,50,31,31,31,5 ,31,50,31,31,31,31,31,50,31,31,31,50,31,31,31,50,31,31,31,50,5 ,24,19,19,19,19,20,o ,o ,o ,o ,o , /*8 */ -/*9 */ o ,1 ,13,13,13,13,13,13,13,13,13,13,13,13,1 ,50,50,BB,50,63,50,BB,50,63,50,BB,50,63,50,BB,50,63,50,31,31,31,31,31,31,31,50,BB,50,63,50,BB,50,63,50,BB,50,63,5 ,1 ,19,19,19,19,20,o ,o ,o ,o ,o , /*9 */ -/*10*/ o ,1 ,13,13,13,13,13,13,13,13,13,13,13,13,1 ,50,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,49,49,49,31,31,31,31,31,31,31,31,31,31,31,31,31,50,5 ,19,19,19,19,19,20,o ,o ,o ,o ,o , /*10*/ -/*11*/ 1 ,1 ,13,13,13,13,13,13,13,13,13,13,13,13,1 ,50,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,45,49,45,31,31,31,31,31,31,31,31,31,31,31,31,31,50,5 ,19,19,19,19,19,20,o ,o ,o ,o ,o , /*11*/ -/*12*/ 1 ,14,13,13,13,13,13,13,13,13,13,13,13,13,1 ,50,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,45,45,45,31,31,31,31,31,31,31,31,31,31,31,31,31,50,5 ,19,19,19,19,19,20,o ,o ,o ,o ,o , /*12*/ -/*13*/ 1 ,14,13,13,13,13,13,13,13,13,13,13,35,13,1 ,50,50,BB,50,63,50,BB,50,63,50,BB,50,63,50,BB,50,63,50,31,31,31,31,31,31,31,50,BB,50,63,50,BB,50,63,50,BB,50,63,1 ,24,24,1 ,5 ,5 ,1 ,1 ,1 ,1 ,o ,o , /*13*/ -/*14*/ 1 ,14,13,13,13,13,13,13,13,13,13,13,35,18,1 ,5 ,31,31,31,50,31,31,31,5 ,31,31,31,50,31,31,31,5 ,31,50,31,31,31,31,31,50,31,31,31,50,31,31,31,5 ,31,31,31,50,1 ,40,40,1 ,3 ,3 ,1 ,40,40,1 ,o ,o , /*14*/ -/*15*/ 1 ,14,1 ,1 ,1 ,5 ,1 ,3 ,3 ,3 ,3 ,1 ,5 ,DD,5 ,1 ,31,31,34,63,34,31,31,5 ,31,31,34,63,34,31,31,5 ,31,31,50,31,31,31,50,50,31,31,34,63,34,31,31,5 ,31,31,34,63,1 ,40,13,13,3 ,3 ,13,13,40,1 ,1 ,20, /*15*/ -/*16*/ 1 ,14,14,1 ,o ,o ,1 ,24,24,24,24,1 ,14,CC,14,1 ,31,31,34,63,34,31,31,1 ,31,31,34,63,34,31,31,1 ,31,31,50,31,31,31,50,5 ,31,31,34,63,34,31,31,50,31,31,34,63,1 ,40,13,13,3 ,3 ,13,13,40,5 ,19,20, /*16*/ -/*17*/ 1 ,14,14,1 ,o ,o ,1 ,24,24,24,24,1 ,14,14,14,1 ,31,31,31,50,31,31,31,1 ,31,31,31,50,31,31,31,5 ,31,31,50,31,31,31,50,50,31,31,31,50,31,31,31,50,31,31,31,50,1 ,40,40,1 ,3 ,3 ,1 ,40,40,40,19,20, /*17*/ -/*18*/ 1 ,14,14,1 ,o ,o ,1 ,1 ,24,24,1 ,1 ,14,14,14,1 ,31,31,34,63,34,31,31,5 ,31,31,34,63,34,31,31,5 ,31,31,50,31,31,31,50,5 ,31,31,31,31,34,31,31,5 ,31,31,34,63,1 ,40,13,13,3 ,3 ,13,13,40,40,19,20, /*18*/ -/*19*/ 1 ,14,14,1 ,1 ,1 ,1 ,24,24,24,24,1 ,14,14,14,1 ,31,31,31,50,31,31,31,5 ,31,31,31,50,31,31,31,BB,31,31,50,31,31,31,50,5 ,31,31,31,31,31,31,31,5 ,31,31,31,50,1 ,40,13,13,3 ,3 ,13,13,40,5 ,19,20, /*19*/ -/*20*/ 1 ,14,14,1 ,14,14,1 ,13,13,13,13,1 ,14,14,14,1 ,5 ,5 ,36,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,31,31,31,50,50,50,50,50,50,50,50,50,50,50,50,50,50,1 ,40,40,1 ,3 ,3 ,1 ,40,40,1 ,1 ,20, /*20*/ -/*21*/ 1 ,14,14,1 ,14,14,14,14,13,13,14,14,14,14,14,1 ,4 ,4 ,36,4 ,4 ,4 ,50,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,50,1 ,1 ,1 ,1 ,1 ,1 ,1 ,63,63,63,63,63,63,1 ,40,13,13,3 ,3 ,13,13,40,1 ,o ,o , /*21*/ -/*22*/ 1 ,14,14,14,14,14,1 ,13,13,13,13,1 ,14,14,14,1 ,4 ,4 ,36,36,36,4 ,50,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,50,1 ,2 ,2 ,DD,2 ,o ,24,o ,24,o ,24,24,24,24,40,13,13,3 ,3 ,13,13,40,1 ,o ,o , /*22*/ -/*23*/ 1 ,14,14,14,14,14,1 ,13,13,13,13,1 ,37,1 ,37,1 ,4 ,4 ,4 ,4 ,36,4 ,50,31,31,31,31,30,30,32,30,30,31,31,31,50,50,50,50,1 ,2 ,2 ,1 ,2 ,o ,24,o ,24,o ,24,24,24,24,40,40,1 ,3 ,3 ,1 ,40,40,1 ,o ,o , /*23*/ -/*24*/ 1 ,1 ,1 ,1 ,14,14,14,13,13,13,13,24,24,24,24,24,13,13,13,4 ,36,4 ,63,31,31,31,31,29,29,32,29,29,31,31,31,1 ,o ,o ,2 ,1 ,2 ,2 ,1 ,1 ,1 ,1 ,63,63,63,63,63,63,1 ,40,40,40,3 ,3 ,40,40,40,1 ,o ,o , /*24*/ -/*25*/ o ,o ,o ,1 ,14,14,14,13,13,13,13,24,24,24,24,24,13,13,13,36,36,4 ,63,31,31,31,31,28,28,32,28,28,31,31,31,1 ,o ,o ,2 ,DD,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,40,40,40,3 ,3 ,40,40,40,1 ,o ,o , /*25*/ -/*26*/ o ,o ,o ,1 ,14,14,14,13,13,13,13,24,24,24,24,24,13,13,13,4 ,4 ,4 ,63,31,31,31,31,27,27,32,27,27,31,31,31,1 ,40,40,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,5 ,5 ,1 ,1 ,1 ,1 ,o ,o , /*26*/ -/*27*/ o ,o ,o ,1 ,4 ,4 ,4 ,36,4 ,4 ,36,1 ,37,1 ,37,1 ,24,24,24,1 ,1 ,1 ,1 ,31,31,31,31,26,26,26,26,26,31,31,31,1 ,40,40,1 ,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, /*27*/ -/*28*/ 4 ,4 ,4 ,4 ,4 ,4 ,4 ,36,36,36,36,36,4 ,1 ,1 ,37,24,24,24,37,37,37,1 ,31,31,31,32,25,25,25,25,25,32,31,31,1 ,40,40,1 ,55,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,55, /*28*/ -/*29*/ 46,58,58,58,58,58,4 ,4 ,4 ,4 ,4 ,31,4 ,1 ,1 ,1 ,40,40,40,40,40,24,24,24,24,24,24,24,24,24,24,24,24,24,24,5 ,40,40,1 ,55,o ,1 ,1 ,1 ,o ,1 ,1 ,1 ,o ,1 ,1 ,o ,1 ,1 ,o ,1 ,1 ,1 ,o ,1 ,1 ,o ,o ,55, /*29*/ -/*30*/ 46,58,58,58,58,58,58,58,58,29,30,31,4 ,1 ,1 ,1 ,40,40,40,40,40,24,24,24,24,24,24,24,24,24,24,24,24,24,24,40,40,40,1 ,55,o ,o ,1 ,o ,o ,o ,1 ,1 ,o ,o ,1 ,o ,o ,1 ,o ,o ,1 ,1 ,o ,o ,1 ,o ,o ,55, /*30*/ -/*31*/ 46,58,58,58,58,58,4 ,4 ,4 ,4 ,4 ,4 ,4 ,1 ,1 ,1 ,40,40,40,40,40,24,24,24,24,24,24,24,24,24,24,24,24,24,24,40,40,40,1 ,55,o ,o ,1 ,o ,o ,1 ,1 ,1 ,o ,o ,1 ,o ,1 ,1 ,o ,1 ,1 ,1 ,o ,o ,1 ,1 ,o ,55, /*31*/ -/*32*/ 4 ,4 ,4 ,4 ,4 ,4 ,4 ,39,39,39,39,39,39,1 ,1 ,1 ,40,40,40,40,40,24,24,24,24,24,24,24,24,24,24,24,24,24,24,5 ,40,40,1 ,55,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,55, /*32*/ -/*33*/ 39,39,39,39,39,39,39,39,o ,o ,o ,o ,o ,3 ,3 ,3 ,40,40,40,1 ,1 ,31,31,31,31,31,24,31,31,31,31,31,31,31,24,31,31,1 ,1 ,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, /*33*/ -/*34*/ 60,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,3 ,3 ,40,40,40,1 ,5 ,31,31,31,31,31,24,31,31,31,31,31,31,31,24,31,31,1 ,1 ,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,63, /*34*/ -/*35*/ 60,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,3 ,3 ,40,40,40,1 ,63,31,31,24,24,24,24,63,1 ,1 ,1 ,24,24,24,24,31,31,1 ,1 ,39,39,39,52,52,52,52,52,52,24,24,26,EE,EE,EE,24,24,24,52,52,52,52,52,52,7 , /*35*/ -/*36*/ 60,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,39,o ,61,1 ,1 ,1 ,1 ,63,31,31,24,24,24,24,63,1 ,1 ,1 ,24,24,24,24,31,31,1 ,1 ,39,39,39,39,39,52,52,52,52,24,24,24,EE,EE,EE,24,24,24,52,52,52,52,52,52,63, /*36*/ -/*37*/ 39,39,5 ,o ,o ,5 ,5 ,o ,5 ,5 ,o ,o ,o ,39,o ,61,1 ,1 ,1 ,1 ,63,31,31,24,24,24,24,63,1 ,1 ,1 ,24,24,24,24,31,31,1 ,1 ,1 ,1 ,1 ,1 ,39,52,52,52,39,24,24,26,EE,EE,EE,26,24,24,52,52,52,52,52,52,7 , /*37*/ -/*38*/ o ,o ,39,o ,o ,39,o ,o ,o ,39,o ,o ,o ,39,o ,61,1 ,1 ,1 ,1 ,5 ,31,31,31,31,31,24,31,31,31,1 ,24,24,24,24,31,31,31,31,30,29,28,1 ,39,52,52,52,39,24,24,26,26,24,24,5 ,24,24,4 ,39,39,39,39,39,63, /*38*/ -/*39*/ o ,o ,39,o ,o ,5 ,o ,o ,o ,5 ,39,39,39,39,o ,61,1 ,1 ,1 ,1 ,1 ,31,31,31,31,31,24,31,31,31,1 ,24,24,24,24,31,31,31,31,30,29,28,1 ,39,39,39,o ,39,24,24,24,24,24,24,5 ,24,24,o ,4 ,o ,o ,o ,o ,o , /*39*/ -/*40*/ o ,o ,39,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,39,o ,61,61,61,61,61,61,24,24,24,24,24,24,1 ,30,30,1 ,1 ,1 ,1 ,1 ,1 ,1 ,o ,o ,25,26,27,1 ,o ,o ,39,o ,39,24,24,24,24,24,24,5 ,24,24,o ,o ,4 ,o ,o ,o ,o , /*40*/ -/*41*/ o ,o ,39,o ,o ,5 ,o ,o ,o ,o ,o ,o ,o ,39,o ,o ,o ,o ,o ,o ,o ,24,24,24,24,24,24,1 ,29,29,1 ,1 ,1 ,63,63,63,1 ,o ,o ,25,26,27,1 ,o ,o ,o ,o ,39,4 ,4 ,5 ,5 ,5 ,5 ,4 ,4 ,4 ,o ,o ,o ,4 ,o ,o ,o , /*41*/ -/*42*/ o ,o ,39,o ,o ,39,o ,o ,o ,o ,o ,o ,o ,39,o ,61,61,61,61,61,61,24,24,24,24,24,24,63,28,28,27,26,25,24,24,24,24,o ,o ,o ,o ,o ,1 ,o ,o ,o ,o ,53,o ,51,38,38,38,4 ,o ,o ,o ,4 ,o ,o ,o ,4 ,o ,o , /*42*/ -/*43*/ o ,o ,39,o ,o ,5 ,5 ,o ,5 ,39,5 ,o ,o ,39,o ,61,51,51,51,51,61,24,24,24,24,24,24,63,28,28,27,26,25,24,24,24,24,o ,o ,o ,o ,o ,1 ,o ,o ,o ,o ,53,o ,51,38,38,38,o ,o ,4 ,o ,4 ,4 ,o ,o ,o ,4 ,o , /*43*/ -/*44*/ 39,39,5 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,39,o ,5 ,52,51,51,51,61,24,24,24,24,24,24,63,63,63,1 ,1 ,1 ,24,24,24,1 ,o ,o ,o ,o ,o ,1 ,o ,o ,o ,o ,53,o ,51,38,38,38,o ,4 ,1 ,o ,4 ,1 ,4 ,o ,o ,o ,4 , /*44*/ -/*45*/ 1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,39,o ,o ,o ,51,51,51,5 ,61,61,61,o ,o ,61,61,51,51,51,51,12,24,24,24,12,o ,o ,o ,o ,o ,1 ,o ,o ,o ,o ,53,o ,51,38,38,38,o ,4 ,4 ,o ,o ,o ,o ,4 ,o ,o ,60, /*45*/ -/*46*/ 1 ,o ,o ,o ,o ,o ,o ,o ,o ,2 ,39,39,39,39,o ,5 ,52,51,51,51,61,3 ,3 ,3 ,3 ,3 ,o ,52,51,51,51,51,1 ,24,24,24,1 ,o ,o ,o ,o ,o ,1 ,59,53,53,53,53,o ,51,38,38,38,o ,o ,4 ,o ,o ,o ,o ,4 ,o ,o ,4 , /*46*/ -/*47*/ 1 ,o ,o ,o ,o ,o ,o ,o ,o ,2 ,DD,2 ,o ,o ,o ,61,51,51,51,51,61,3 ,3 ,3 ,3 ,3 ,o ,52,51,51,51,51,12,24,24,24,12,o ,o ,o ,o ,o ,1 ,59,59,59,59,59,o ,51,38,38,38,4 ,o ,1 ,o ,4 ,1 ,4 ,4 ,o ,o ,60, /*47*/ -/*48*/ 1 ,o ,o ,o ,o ,o ,o ,o ,o ,2 ,61,o ,o ,o ,o ,61,61,61,61,61,61,3 ,3 ,61,3 ,3 ,61,52,52,52,52,1 ,1 ,o ,o ,o ,1 ,o ,o ,o ,o ,o ,1 ,4 ,4 ,59,4 ,4 ,o ,51,38,38,38,4 ,o ,4 ,o ,o ,o ,o ,4 ,o ,o ,4 , /*48*/ -/*49*/ 60,o ,o ,63,48,48,48,48,48,48,63,63,63,63,63,63,5 ,24,5 ,6 ,6 ,3 ,3 ,3 ,3 ,3 ,6 ,6 ,6 ,48,48,1 ,1 ,1 ,2 ,1 ,1 ,o ,o ,o ,o ,o ,1 ,4 ,57,59,57,4 ,o ,51,38,38,38,o ,o ,4 ,o ,o ,o ,o ,4 ,o ,o ,60, /*49*/ -/*50*/ 60,o ,o ,63,6 ,6 ,6 ,6 ,6 ,6 ,25,26,27,28,29,30,30,24,24,6 ,6 ,3 ,3 ,3 ,3 ,3 ,6 ,6 ,6 ,6 ,6 ,1 ,1 ,1 ,DD,1 ,1 ,1 ,o ,o ,o ,1 ,1 ,4 ,4 ,59,4 ,4 ,o ,51,38,38,38,o ,4 ,1 ,o ,4 ,1 ,4 ,4 ,o ,o ,4 , /*50*/ -/*51*/ 60,o ,o ,63,6 ,6 ,6 ,6 ,6 ,6 ,25,26,27,28,29,30,30,24,24,6 ,6 ,3 ,3 ,3 ,3 ,3 ,6 ,6 ,6 ,6 ,1 ,1 ,o ,2 ,2 ,2 ,o ,1 ,1 ,1 ,1 ,1 ,1 ,4 ,57,59,57,4 ,o ,51,38,38,38,o ,o ,4 ,o ,o ,o ,o ,5 ,o ,o ,60, /*51*/ -/*52*/ 60,o ,o ,63,6 ,6 ,6 ,6 ,6 ,6 ,25,26,27,28,29,30,5 ,6 ,5 ,1 ,63,63,63,63,1 ,1 ,6 ,6 ,6 ,5 ,1 ,o ,o ,o ,o ,o ,o ,o ,1 ,4 ,4 ,4 ,4 ,4 ,4 ,59,4 ,4 ,o ,51,38,38,38,4 ,o ,4 ,o ,o ,o ,o ,40,24,24,4 , /*52*/ -/*53*/ 60,o ,o ,63,6 ,6 ,6 ,6 ,6 ,6 ,25,26,27,28,29,30,5 ,6 ,6 ,48,6 ,6 ,6 ,6 ,6 ,5 ,6 ,6 ,6 ,5 ,1 ,o ,o ,o ,o ,o ,o ,o ,1 ,4 ,4 ,4 ,4 ,24,24,24,24,4 ,o ,51,38,38,38,4 ,24,4 ,o ,o ,o ,o ,40,24,24,4 , /*53*/ -/*54*/ 1 ,o ,o ,1 ,6 ,6 ,6 ,6 ,6 ,6 ,25,26,27,28,29,30,5 ,6 ,6 ,48,6 ,6 ,6 ,6 ,6 ,5 ,6 ,6 ,6 ,2 ,1 ,2 ,o ,3 ,3 ,3 ,o ,2 ,1 ,2 ,o ,o ,o ,24,24,24,62,4 ,o ,51,38,38,38,4 ,24,4 ,o ,o ,o ,o ,5 ,24,24,4 , /*54*/ -/*55*/ 5 ,25,25,5 ,25,25,5 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,5 ,6 ,6 ,48,6 ,6 ,6 ,6 ,6 ,5 ,6 ,6 ,6 ,2 ,DD,2 ,o ,3 ,3 ,3 ,o ,2 ,DD,2 ,o ,3 ,3 ,24,24,24,24,4 ,4 ,4 ,5 ,5 ,5 ,4 ,54,4 ,4 ,4 ,1 ,1 ,4 ,54,24,4 , /*55*/ -/*56*/ 1 ,26,26,1 ,26,26,1 ,31,31,31,31,31,31,31,31,1 ,5 ,6 ,6 ,48,48,48,48,48,6 ,5 ,6 ,6 ,6 ,2 ,1 ,2 ,o ,3 ,3 ,3 ,o ,2 ,1 ,2 ,o ,o ,o ,24,24,24,62,4 ,53,53,53,53,53,4 ,FF,4 ,53,53,4 ,4 ,4 ,FF,4 ,4 , /*56*/ -/*57*/ 5 ,27,27,5 ,27,27,5 ,31,31,31,31,31,31,31,31,1 ,5 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,5 ,6 ,6 ,6 ,5 ,1 ,o ,o ,o ,o ,o ,o ,o ,1 ,4 ,4 ,4 ,4 ,24,24,24,24,4 ,4 ,4 ,4 ,62,24,24,54,24,24,62,4 ,40,40,54,40,4 , /*57*/ -/*58*/ 1 ,28,28,1 ,28,28,1 ,31,31,31,31,31,31,31,31,1 ,5 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,1 ,6 ,6 ,6 ,5 ,1 ,o ,o ,o ,o ,o ,o ,o ,1 ,4 ,58,58,58,4 ,58,4 ,4 ,4 ,58,58,4 ,24,24,24,24,24,24,24,4 ,24,24,24,24,4 , /*58*/ -/*59*/ 5 ,28,28,5 ,28,28,5 ,30,30,50,50,5 ,BB,5 ,50,50,5 ,o ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,1 ,o ,o ,o ,o ,o ,1 ,1 ,4 ,58,4 ,58,4 ,58,4 ,58,58,58,58,4 ,24,24,24,24,24,24,24,4 ,24,24,24,24,4 , /*59*/ -/*60*/ 1 ,28,28,1 ,28,28,1 ,29,29,50,31,34,31,31,31,50,5 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,3 ,3 ,o ,o ,1 ,1 ,1 ,o ,1 ,1 ,1 ,4 ,4 ,58,4 ,58,58,58,4 ,58,58,4 ,58,4 ,24,24,24,24,24,24,24,58,24,24,24,24,4 , /*60*/ -/*61*/ 1 ,28,28,28,28,28,28,28,28,50,31,34,31,31,31,50,5 ,o ,1 ,o ,o ,o ,o ,o ,o ,o ,3 ,3 ,3 ,o ,o ,2 ,2 ,1 ,o ,1 ,4 ,4 ,58,58,58,4 ,4 ,4 ,4 ,4 ,58,58,4 ,58,4 ,4 ,24,24,24,24,54,54,4 ,24,24,24,24,4 , /*61*/ -/*62*/ 1 ,28,28,28,28,28,28,28,28,50,31,31,31,31,31,50,5 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,2 ,2 ,1 ,o ,1 ,4 ,4 ,58,4 ,58,58,58,58,58,58,58,58,4 ,58,58,58,GG,24,24,24,54,54,4 ,40,40,40,40,4 , /*62*/ -/*63*/ 1 ,1 ,1 ,37,1 ,1 ,37,1 ,1 ,50,50,33,50,33,50,50,5 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,1 ,7 ,7 ,7 ,7 ,7 ,7 ,1 ,1 ,DD,1 ,4 ,4 ,46,4 ,4 ,57,4 ,57,4 ,57,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,60,60,4 ,4 /*63*/ - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 - #undef AA - #undef BB - #undef CC - #undef DD - #undef EE - #undef FF - #undef GG - #undef o - }, - { // tileDictionary - SFG_TD( 8, 6,1,1),SFG_TD(13, 0,0,0),SFG_TD( 9, 5,0,0),SFG_TD( 8, 8,0,0), // 0 - SFG_TD(13, 0,2,2),SFG_TD(13, 0,3,3),SFG_TD( 8, 9,0,0),SFG_TD(11, 3,4,0), // 4 - SFG_TD(10, 5,0,0),SFG_TD(10, 5,0,0),SFG_TD(10, 5,0,0),SFG_TD(10, 5,0,0), // 8 - SFG_TD(10, 2,0,0),SFG_TD( 8,21,0,0),SFG_TD(23, 6,0,0),SFG_TD(25, 2,0,0), // 12 - SFG_TD( 9,14,2,0),SFG_TD(27, 0,0,0),SFG_TD( 9,20,0,0),SFG_TD( 8,31,1,1), // 16 - SFG_TD(11, 0,0,7),SFG_TD(10, 5,0,0),SFG_TD(10, 5,0,0),SFG_TD(10, 5,0,0), // 20 - SFG_TD( 8,13,0,0),SFG_TD( 9,12,0,0),SFG_TD(10,11,0,0),SFG_TD(11,10,0,0), // 24 - SFG_TD(12, 9,0,0),SFG_TD(13, 8,0,0),SFG_TD(14, 7,0,0),SFG_TD(15, 6,0,0), // 28 - SFG_TD(18, 3,3,0),SFG_TD(19, 0,6,4),SFG_TD(17, 4,4,0),SFG_TD(10,19,1,0), // 32 - SFG_TD(17, 4,2,2),SFG_TD(13, 0,1,1),SFG_TD( 4, 9,1,1),SFG_TD(11, 0,1,0), // 36 - SFG_TD( 8, 6,1,0),SFG_TD( 7, 1,1,0),SFG_TD(10, 5,0,0),SFG_TD(10, 5,0,0), // 40 - SFG_TD(10, 5,0,0),SFG_TD(18, 4,3,0),SFG_TD(17, 0,6,0),SFG_TD(27, 0,6,0), // 44 - SFG_TD(10, 3,4,4),SFG_TD(15, 7,0,0),SFG_TD(19, 0,0,4),SFG_TD( 6, 8,1,1), // 48 - SFG_TD( 7, 7,1,1),SFG_TD(11, 0,2,5),SFG_TD( 9,12,0,0),SFG_TD(13, 0,5,5), // 52 - SFG_TD( 8, 5,2,2),SFG_TD( 5, 0,5,5),SFG_TD(13, 4,2,2),SFG_TD( 8, 7,2,2), // 56 - SFG_TD(12, 0,6,0),SFG_TD(14, 0,0,1),SFG_TD(11,10,5,0),SFG_TD( 0, 0,4,4) // 60 - }, // tileDictionary - {12,3 ,11,14,4 ,8 ,10}, // textureIndices - 7, // doorTextureIndex - 58, // floorColor - 2, // ceilingColor - {34, 59, 64 }, // player start: x, y, direction - 0, // backgroundImage - { // elements - {SFG_LEVEL_ELEMENT_PLASMA, {33,1}},{SFG_LEVEL_ELEMENT_HEALTH, {8,1}}, - {SFG_LEVEL_ELEMENT_CARD1, {2,1}},{SFG_LEVEL_ELEMENT_HEALTH, {1,1}}, - {SFG_LEVEL_ELEMENT_RUIN, {52,3}},{SFG_LEVEL_ELEMENT_BULLETS, {20,3}}, - {SFG_LEVEL_ELEMENT_RUIN, {51,4}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {41,7}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {36,8}},{SFG_LEVEL_ELEMENT_PLASMA, {7,8}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {8,9}},{SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {6,9}}, - {SFG_LEVEL_ELEMENT_HEALTH, {53,10}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {10,10}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {4,10}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {40,11}}, - {SFG_LEVEL_ELEMENT_TERMINAL, {36,11}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {32,11}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {7,11}},{SFG_LEVEL_ELEMENT_ROCKETS, {1,12}}, - {SFG_LEVEL_ELEMENT_LOCK0, {17,13}},{SFG_LEVEL_ELEMENT_PLASMA, {1,13}}, - {SFG_LEVEL_ELEMENT_TREE, {57,14}},{SFG_LEVEL_ELEMENT_TREE, {56,14}}, - {SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {17,14}},{SFG_LEVEL_ELEMENT_HEALTH, {33,15}}, - {SFG_LEVEL_ELEMENT_CARD0, {62,17}},{SFG_LEVEL_ELEMENT_BULLETS, {46,17}}, - {SFG_LEVEL_ELEMENT_RUIN, {43,18}},{SFG_LEVEL_ELEMENT_ROCKETS, {20,18}}, - {SFG_LEVEL_ELEMENT_PLASMA, {17,18}},{SFG_LEVEL_ELEMENT_LOCK0, {42,22}}, - {SFG_LEVEL_ELEMENT_COLUMN, {29,23}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {8,23}}, - {SFG_LEVEL_ELEMENT_HEALTH, {20,24}},{SFG_LEVEL_ELEMENT_TERMINAL, {41,25}}, - {SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {14,25}},{SFG_LEVEL_ELEMENT_COLUMN, {29,26}}, - {SFG_LEVEL_ELEMENT_LAMP, {32,28}},{SFG_LEVEL_ELEMENT_LAMP, {26,28}}, - {SFG_LEVEL_ELEMENT_RUIN, {20,29}},{SFG_LEVEL_ELEMENT_HEALTH, {61,30}}, - {SFG_LEVEL_ELEMENT_PLASMA, {59,30}},{SFG_LEVEL_ELEMENT_HEALTH, {55,30}}, - {SFG_LEVEL_ELEMENT_TELEPORTER, {52,30}},{SFG_LEVEL_ELEMENT_PLASMA, {45,30}}, - {SFG_LEVEL_ELEMENT_RUIN, {20,30}},{SFG_LEVEL_ELEMENT_TELEPORTER, {2,30}}, - {SFG_LEVEL_ELEMENT_RUIN, {20,31}},{SFG_LEVEL_ELEMENT_RUIN, {19,32}}, - {SFG_LEVEL_ELEMENT_RUIN, {20,33}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {22,34}}, - {SFG_LEVEL_ELEMENT_BULLETS, {62,35}},{SFG_LEVEL_ELEMENT_ROCKETS, {61,35}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {42,35}},{SFG_LEVEL_ELEMENT_BULLETS, {23,35}}, - {SFG_LEVEL_ELEMENT_TREE, {21,35}},{SFG_LEVEL_ELEMENT_HEALTH, {62,36}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {59,36}},{SFG_LEVEL_ELEMENT_TERMINAL, {50,36}}, - {SFG_LEVEL_ELEMENT_RUIN, {14,36}},{SFG_LEVEL_ELEMENT_ROCKETS, {23,37}}, - {SFG_LEVEL_ELEMENT_TREE, {21,37}},{SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {14,37}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {12,38}},{SFG_LEVEL_ELEMENT_ROCKETS, {11,38}}, - {SFG_LEVEL_ELEMENT_PLASMA, {10,38}},{SFG_LEVEL_ELEMENT_LAMP, {24,40}}, - {SFG_LEVEL_ELEMENT_LAMP, {22,40}},{SFG_LEVEL_ELEMENT_BARREL, {45,41}}, - {SFG_LEVEL_ELEMENT_BARREL, {15,41}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {7,41}}, - {SFG_LEVEL_ELEMENT_BARREL, {46,42}},{SFG_LEVEL_ELEMENT_BARREL, {44,42}}, - {SFG_LEVEL_ELEMENT_BARREL, {43,42}},{SFG_LEVEL_ELEMENT_RUIN, {36,42}}, - {SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {33,42}},{SFG_LEVEL_ELEMENT_BARREL, {54,43}}, - {SFG_LEVEL_ELEMENT_RUIN, {36,43}},{SFG_LEVEL_ELEMENT_BULLETS, {19,43}}, - {SFG_LEVEL_ELEMENT_TREE, {26,44}},{SFG_LEVEL_ELEMENT_TREE, {21,44}}, - {SFG_LEVEL_ELEMENT_BULLETS, {46,45}},{SFG_LEVEL_ELEMENT_BULLETS, {45,45}}, - {SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {35,45}},{SFG_LEVEL_ELEMENT_ROCKETS, {19,45}}, - {SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {58,46}},{SFG_LEVEL_ELEMENT_BARREL, {54,46}}, - {SFG_LEVEL_ELEMENT_PLASMA, {41,46}},{SFG_LEVEL_ELEMENT_HEALTH, {37,46}}, - {SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {14,46}},{SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {51,47}}, - {SFG_LEVEL_ELEMENT_BULLETS, {19,47}},{SFG_LEVEL_ELEMENT_RUIN, {14,47}}, - {SFG_LEVEL_ELEMENT_BULLETS, {59,48}},{SFG_LEVEL_ELEMENT_LAMP, {40,48}}, - {SFG_LEVEL_ELEMENT_LAMP, {38,48}},{SFG_LEVEL_ELEMENT_PLASMA, {59,49}}, - {SFG_LEVEL_ELEMENT_BARREL, {53,49}},{SFG_LEVEL_ELEMENT_FINISH, {39,49}}, - {SFG_LEVEL_ELEMENT_TREE, {17,49}},{SFG_LEVEL_ELEMENT_LOCK2, {34,50}}, - {SFG_LEVEL_ELEMENT_BARREL, {54,51}},{SFG_LEVEL_ELEMENT_COLUMN, {36,52}}, - {SFG_LEVEL_ELEMENT_COLUMN, {32,52}},{SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {6,52}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {51,54}},{SFG_LEVEL_ELEMENT_TREE, {46,54}}, - {SFG_LEVEL_ELEMENT_COLUMN, {42,54}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {22,54}}, - {SFG_LEVEL_ELEMENT_BULLETS, {19,54}},{SFG_LEVEL_ELEMENT_TREE, {62,55}}, - {SFG_LEVEL_ELEMENT_LOCK1, {38,55}},{SFG_LEVEL_ELEMENT_TREE, {46,56}}, - {SFG_LEVEL_ELEMENT_COLUMN, {42,56}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {56,59}}, - {SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {51,59}},{SFG_LEVEL_ELEMENT_HEALTH, {14,60}}, - {SFG_LEVEL_ELEMENT_TERMINAL, {10,60}},{SFG_LEVEL_ELEMENT_HEALTH, {61,61}}, - {SFG_LEVEL_ELEMENT_HEALTH, {32,61}},{SFG_LEVEL_ELEMENT_ROCKETS, {17,61}}, - {SFG_LEVEL_ELEMENT_CARD2, {57,62}},{SFG_LEVEL_ELEMENT_HEALTH, {38,62}}, - {SFG_LEVEL_ELEMENT_BLOCKER, {34,62}},{SFG_LEVEL_ELEMENT_BULLETS, {32,62}}, - {SFG_LEVEL_ELEMENT_LAMP, {25,62}},{SFG_LEVEL_ELEMENT_NONE, {0,0}} - }, // elements - } // level - ; - -SFG_PROGRAM_MEMORY SFG_Level SFG_level7 = - { // level - { // mapArray - #define o 0 - #define AA (31 | SFG_TILE_PROPERTY_DOOR) - #define BB (34 | SFG_TILE_PROPERTY_ELEVATOR) - #define CC (29 | SFG_TILE_PROPERTY_SQUEEZER) - #define DD (30 | SFG_TILE_PROPERTY_DOOR) - #define EE (39 | SFG_TILE_PROPERTY_ELEVATOR) - #define FF (28 | SFG_TILE_PROPERTY_DOOR) - #define GG (44 | SFG_TILE_PROPERTY_ELEVATOR) - #define HH (8 | SFG_TILE_PROPERTY_DOOR) - #define II (1 | SFG_TILE_PROPERTY_DOOR) - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 -/*0 */ 1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,32,32,1 ,11,11,11,11,11,11,11,11,11,11,11,27,25,25,25,1 ,31,31,8 ,31,8 ,31,31, /*0 */ -/*1 */ 12,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,8 ,1 ,23,23,1 ,22,22,22,22,22,22,22,22,22,22,22,27,24,o ,24,1 ,31,31,41,41,41,31,31, /*1 */ -/*2 */ 12,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,8 ,1 ,23,23,27,22,22,15,15,15,15,15,15,15,15,21,27,o ,o ,o ,1 ,8 ,41,41,41,41,41,8 , /*2 */ -/*3 */ 12,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,8 ,1 ,23,23,27,23,22,15,20,20,20,20,20,20,20,20,27,o ,o ,o ,1 ,31,41,41,41,41,41,31, /*3 */ -/*4 */ 12,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,8 ,1 ,23,23,35,23,22,15,20,22,22,22,22,22,22,19,27,o ,o ,o ,1 ,8 ,23,23,23,23,23,8 , /*4 */ -/*5 */ 12,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,4 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,4 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,8 ,1 ,23,23,27,23,22,15,20,22,18,18,18,18,18,18,28,o ,o ,o ,1 ,31,23,23,23,23,23,31, /*5 */ -/*6 */ 12,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,3 ,4 ,3 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,3 ,4 ,3 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,8 ,1 ,23,23,27,22,22,15,20,22,18,20,20,20,20,17,28,o ,o ,o ,1 ,8 ,23,23,23,23,23,8 , /*6 */ -/*7 */ 12,o ,o ,o ,o ,o ,o ,o ,o ,o ,2 ,3 ,4 ,3 ,2 ,o ,o ,o ,o ,o ,o ,o ,o ,2 ,3 ,4 ,3 ,2 ,o ,o ,o ,o ,o ,o ,o ,o ,8 ,1 ,23,23,1 ,22,22,21,20,19,18,17,o ,o ,o ,o ,16,o ,o ,o ,1 ,31,31,23,23,23,31,31, /*7 */ -/*8 */ 1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,o ,2 ,3 ,4 ,3 ,2 ,o ,1 ,1 ,1 ,1 ,1 ,1 ,o ,2 ,3 ,4 ,3 ,2 ,o ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,23,23,1 ,22,22,15,20,22,18,20,o ,o ,24,o ,28,o ,o ,o ,1 ,27,27,27,AA,27,27,27, /*8 */ -/*9 */ 1 ,11,17,17,17,17,17,17,1 ,o ,2 ,3 ,4 ,3 ,2 ,o ,1 ,1 ,1 ,1 ,1 ,1 ,17,23,23,23,23,23,23,1 ,26,1 ,26,1 ,1 ,1 ,1 ,1 ,23,23,1 ,22,22,15,20,22,18,20,37,o ,24,o ,28,o ,o ,o ,1 ,1 ,23,23,23,23,23,1 , /*9 */ -/*10*/ 1 ,25,17,CC,17,17,CC,17,1 ,o ,2 ,2 ,2 ,2 ,2 ,o ,1 ,1 ,1 ,1 ,1 ,1 ,18,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,1 ,BB,BB,1 ,1 ,23,23,1 ,22,22,15,20,22,18,20,37,o ,24,o ,28,o ,o ,o ,42,32,23,23,23,23,23,33, /*10*/ -/*11*/ 1 ,25,17,17,17,17,17,17,1 ,23,23,23,o ,23,23,23,1 ,1 ,1 ,1 ,1 ,1 ,19,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,1 ,BB,BB,23,DD,23,23,1 ,22,22,15,20,22,18,20,o ,o ,24,o ,28,o ,o ,o ,o ,32,23,23,23,23,23,32, /*11*/ -/*12*/ 1 ,25,17,CC,17,17,CC,17,17,o ,o ,o ,o ,o ,o ,o ,37,o ,o ,o ,o ,36,20,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,1 ,BB,BB,1 ,1 ,23,23,1 ,22,22,21,20,19,18,17,o ,o ,o ,o ,16,o ,o ,o ,24,32,23,23,23,23,23,33, /*12*/ -/*13*/ 1 ,25,17,17,17,17,17,17,17,o ,o ,o ,o ,o ,o ,o ,37,o ,o ,o ,o ,36,21,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,1 ,1 ,1 ,1 ,1 ,23,23,27,22,22,15,20,22,18,20,20,20,20,17,28,o ,o ,o ,o ,32,23,23,23,23,23,1 , /*13*/ -/*14*/ 1 ,25,17,17,17,17,17,17,17,o ,o ,o ,o ,o ,o ,o ,37,o ,o ,o ,o ,36,22,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,1 ,1 ,1 ,1 ,1 ,23,23,27,23,22,15,20,22,18,18,18,18,18,18,28,o ,o ,o ,o ,32,23,23,1 ,23,23,32, /*14*/ -/*15*/ 1 ,25,17,17,17,17,17,17,17,o ,o ,o ,o ,o ,o ,o ,37,o ,o ,o ,o ,1 ,23,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,1 ,1 ,1 ,1 ,1 ,23,23,35,23,22,15,20,22,22,22,22,22,22,19,27,o ,o ,o ,24,32,41,41,41,41,41,32, /*15*/ -/*16*/ 1 ,25,17,CC,17,17,CC,17,1 ,10,10,10,10,10,10,10,10,10,10,10,10,1 ,1 ,1 ,26,1 ,26,20,20,20,26,1 ,26,1 ,1 ,1 ,1 ,1 ,23,23,27,23,22,15,20,20,20,20,20,20,20,20,27,o ,o ,o ,o ,32,41,41,41,41,41,1 , /*16*/ -/*17*/ 1 ,25,17,17,17,17,17,17,1 ,17,18,19,20,22,23,23,22,20,19,18,17,9 ,9 ,1 ,17,37,o ,o ,o ,o ,o ,o ,37,1 ,1 ,1 ,23,23,23,23,27,22,22,15,15,15,15,15,15,15,15,21,27,o ,o ,o ,o ,32,41,41,41,41,41,33, /*17*/ -/*18*/ 1 ,25,17,CC,17,17,CC,17,1 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,1 ,17,37,o ,o ,o ,o ,o ,o ,37,1 ,1 ,23,23,23,23,23,1 ,22,22,22,22,22,22,22,22,22,22,22,27,o ,o ,o ,24,32,41,41,41,41,41,32, /*18*/ -/*19*/ 1 ,11,17,17,17,17,17,17,1 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,1 ,1 ,37,o ,o ,o ,o ,o ,o ,37,1 ,1 ,1 ,23,23,23,23,1 ,1 ,1 ,27,27,27,27,27,27,27,27,27,27,o ,o ,o ,o ,32,41,41,41,41,41,33, /*19*/ -/*20*/ 1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,1 ,37,o ,o ,o ,o ,o ,o ,37,1 ,1 ,23,23,23,23,23,23,23,23,23,23,23,23,22,21,20,19,18,17,o ,o ,o ,o ,32,41,41,41,41,41,1 , /*20*/ -/*21*/ 5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,1 ,37,o ,o ,o ,o ,o ,o ,37,1 ,1 ,23,23,23,23,23,23,23,23,23,23,23,23,22,21,20,19,18,17,o ,o ,o ,1 ,1 ,40,1 ,DD,DD,1 ,1 , /*21*/ -/*22*/ 5 ,5 ,5 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,5 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,1 ,37,37,37,37,37,37,37,37,1 ,1 ,23,23,23,23,23,23,23,23,23,23,23,23,22,21,20,19,18,17,o ,o ,o ,1 ,1 ,40,1 ,23,23,1 ,1 , /*22*/ -/*23*/ 5 ,5 ,5 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,5 ,8 ,8 ,8 ,8 ,8 ,9 ,9 ,9 ,9 ,9 ,1 ,FF,1 ,1 ,o ,o ,o ,o ,37,1 ,1 ,1 ,23,23,23,23,1 ,23,23,23,23,38,38,38,38,38,1 ,1 ,1 ,o ,o ,o ,1 ,1 ,40,EE,23,23,EE,1 , /*23*/ -/*24*/ 5 ,6 ,6 ,6 ,10,6 ,6 ,10,6 ,6 ,10,6 ,6 ,5 ,8 ,10,6 ,6 ,6 ,9 ,9 ,9 ,9 ,9 ,6 ,6 ,6 ,1 ,o ,o ,o ,o ,37,1 ,1 ,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,1 ,1 ,1 ,o ,o ,o ,1 ,1 ,1 ,CC,23,23,CC,1 , /*24*/ -/*25*/ 7 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,5 ,8 ,10,6 ,37,6 ,9 ,9 ,9 ,9 ,9 ,6 ,6 ,6 ,1 ,o ,o ,o ,o ,37,1 ,1 ,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,1 ,o ,24,o ,o ,o ,24,o ,1 ,EE,23,23,EE,1 , /*25*/ -/*26*/ 7 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,5 ,8 ,10,6 ,6 ,6 ,9 ,9 ,9 ,9 ,9 ,6 ,6 ,6 ,1 ,o ,o ,o ,o ,37,1 ,1 ,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,1 ,o ,o ,o ,o ,o ,o ,o ,1 ,CC,23,23,CC,1 , /*26*/ -/*27*/ 7 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,9 ,9 ,9 ,9 ,9 ,6 ,6 ,6 ,1 ,37,37,37,37,37,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,28,28,28,28,28,1 ,o ,o ,o ,o ,o ,o ,o ,1 ,EE,23,23,EE,1 , /*27*/ -/*28*/ 7 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,5 ,8 ,10,6 ,37,6 ,9 ,9 ,9 ,9 ,9 ,6 ,6 ,6 ,1 ,1 ,1 ,1 ,o ,37,1 ,1 ,1 ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,17,18,18,18,17,o ,o ,o ,o ,o ,o ,o ,o ,1 ,1 ,23,23,1 ,1 , /*28*/ -/*29*/ 7 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,5 ,8 ,10,6 ,6 ,6 ,9 ,9 ,9 ,9 ,9 ,6 ,6 ,6 ,6 ,6 ,6 ,1 ,o ,37,1 ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,18,18,18,18,18,o ,o ,o ,o ,o ,o ,o ,o ,1 ,1 ,DD,DD,1 ,1 , /*29*/ -/*30*/ 7 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,5 ,8 ,10,6 ,6 ,6 ,9 ,9 ,9 ,9 ,9 ,6 ,6 ,6 ,6 ,6 ,6 ,FF,o ,37,1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,27,23,23,27,27, /*30*/ -/*31*/ 5 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,5 ,8 ,10,6 ,37,6 ,9 ,9 ,9 ,9 ,9 ,6 ,6 ,6 ,6 ,6 ,6 ,1 ,o ,37,1 ,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,27,23,23,27,27, /*31*/ -/*32*/ 5 ,5 ,6 ,6 ,5 ,5 ,6 ,6 ,6 ,5 ,5 ,5 ,5 ,5 ,8 ,10,6 ,6 ,6 ,9 ,9 ,9 ,9 ,9 ,6 ,6 ,6 ,1 ,1 ,1 ,1 ,o ,37,1 ,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,31,23,23,31,27, /*32*/ -/*33*/ 1 ,o ,o ,o ,o ,5 ,6 ,6 ,6 ,5 ,8 ,8 ,8 ,8 ,8 ,10,6 ,6 ,6 ,9 ,9 ,9 ,9 ,9 ,6 ,6 ,6 ,1 ,42,o ,o ,o ,37,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,27,31,23,23,31,27, /*33*/ -/*34*/ 1 ,o ,o ,o ,o ,5 ,6 ,6 ,6 ,5 ,8 ,10,10,10,10,10,6 ,37,6 ,9 ,9 ,9 ,9 ,9 ,6 ,6 ,6 ,1 ,o ,o ,o ,o ,37,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,27,27,27,23,23,27,27, /*34*/ -/*35*/ 1 ,FF,1 ,1 ,1 ,5 ,6 ,6 ,6 ,5 ,8 ,10,6 ,6 ,6 ,6 ,6 ,6 ,6 ,9 ,9 ,9 ,9 ,9 ,6 ,6 ,6 ,1 ,o ,o ,o ,o ,37,1 ,28,24,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,27,27,27,27,23,23,27,27, /*35*/ -/*36*/ GG,45,GG,GG,5 ,5 ,6 ,6 ,6 ,5 ,8 ,10,6 ,6 ,6 ,6 ,6 ,6 ,6 ,9 ,9 ,9 ,9 ,9 ,6 ,6 ,6 ,1 ,o ,o ,o ,o ,37,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,23,23,23,23,23,23,23,23,1 , /*36*/ -/*37*/ GG,45,45,GG,5 ,6 ,6 ,6 ,6 ,5 ,8 ,8 ,1 ,1 ,8 ,HH,8 ,1 ,1 ,1 ,1 ,DD,1 ,1 ,1 ,FF,1 ,1 ,o ,o ,o ,o ,28,1 ,28,24,o ,o ,o ,o ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,32,23,23,23,23,23,23,23,23,32, /*37*/ -/*38*/ GG,45,45,GG,5 ,6 ,6 ,6 ,5 ,10,o ,o ,o ,o ,o ,37,o ,19,19,19,23,36,36,o ,o ,o ,o ,o ,o ,o ,o ,o ,28,1 ,1 ,o ,o ,o ,o ,o ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,32,23,23,27,27,27,27,23,23,32, /*38*/ -/*39*/ GG,45,GG,5 ,6 ,6 ,6 ,6 ,5 ,10,o ,o ,o ,o ,o ,37,o ,o ,o ,o ,36,36,36,o ,o ,o ,o ,o ,o ,o ,o ,28,28,1 ,1 ,o ,o ,o ,o ,o ,1 ,1 ,1 ,28,24,o ,o ,o ,o ,o ,o ,o ,o ,o ,32,23,23,31,27,27,31,23,23,32, /*39*/ -/*40*/ GG,GG,5 ,5 ,6 ,6 ,6 ,5 ,10,10,o ,o ,o ,o ,o ,37,o ,o ,o ,o ,36,36,36,o ,o ,o ,o ,o ,o ,o ,28,28,28,1 ,1 ,1 ,1 ,16,1 ,1 ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,32,23,23,27,27,27,27,23,23,32, /*40*/ -/*41*/ 5 ,5 ,6 ,6 ,6 ,6 ,5 ,10,10,10,o ,o ,o ,o ,o ,37,o ,19,19,19,23,36,36,o ,o ,o ,27,43,43,43,28,27,27,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,24,28,24,o ,o ,o ,o ,o ,o ,o ,o ,o ,32,23,23,23,23,23,23,23,23,32, /*41*/ -/*42*/ 5 ,5 ,6 ,6 ,6 ,5 ,10,10,10,10,o ,o ,o ,o ,o ,37,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,27,o ,o ,o ,37,10,27,1 ,1 ,42,o ,o ,o ,o ,o ,o ,o ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,23,23,23,23,23,23,23,23,1 , /*42*/ -/*43*/ 5 ,6 ,6 ,6 ,6 ,5 ,10,10,10,10,o ,o ,o ,o ,o ,37,o ,o ,o ,o ,36,36,36,o ,o ,o ,28,o ,o ,o ,o ,17,28,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,24,28,24,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,1 ,1 ,1 ,1 ,DD,1 ,1 ,1 ,1 , /*43*/ -/*44*/ 5 ,6 ,6 ,6 ,5 ,10,10,10,10,10,o ,o ,o ,o ,o ,37,o ,o ,o ,o ,36,36,36,o ,o ,o ,FF,o ,o ,o ,o ,17,28,1 ,1 ,42,o ,o ,o ,o ,o ,o ,o ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,1 ,23,23,23,23,23,23,23,33, /*44*/ -/*45*/ 5 ,6 ,6 ,6 ,5 ,10,10,10,10,10,o ,o ,37,37,37,37,o ,o ,o ,o ,36,36,36,o ,o ,o ,28,o ,o ,o ,o ,17,28,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,o ,o ,1 ,1 ,16,16,1 ,1 ,o ,o ,1 ,1 ,23,23,23,23,23,23,23,32, /*45*/ -/*46*/ 5 ,6 ,6 ,6 ,5 ,10,10,10,10,8 ,o ,o ,37,o ,o ,1 ,1 ,1 ,1 ,1 ,36,36,36,o ,o ,o ,27,o ,o ,o ,37,10,27,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,37,37,1 ,24,o ,o ,24,1 ,37,37,1 ,1 ,23,23,38,38,38,23,23,33, /*46*/ -/*47*/ 1 ,o ,o ,o ,o ,o ,o ,37,o ,o ,o ,o ,37,o ,o ,1 ,23,23,23,23,36,36,36,18,o ,18,27,27,28,28,28,27,27,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,1 ,1 ,1 ,24,o ,o ,24,1 ,1 ,1 ,1 ,1 ,23,23,38,38,38,23,23,1 , /*47*/ -/*48*/ 1 ,o ,o ,o ,o ,o ,o ,37,o ,o ,o ,o ,37,1 ,1 ,1 ,23,23,23,23,36,36,36,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,24,15,15,15,15,15,15,15,15,15,15,15,15,33, /*48*/ -/*49*/ 1 ,o ,o ,o ,o ,o ,o ,37,37,37,37,37,37,1 ,1 ,1 ,23,23,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,15,15,15,15,15,15,15,15,15,15,15,15,15,32, /*49*/ -/*50*/ 1 ,1 ,o ,o ,o ,o ,o ,o ,o ,37,1 ,1 ,1 ,1 ,42,1 ,23,23,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,15,15,15,15,15,15,15,15,15,15,15,15,15,15,33, /*50*/ -/*51*/ 1 ,1 ,o ,o ,o ,o ,o ,o ,o ,37,FF,o ,o ,o ,o ,o ,23,23,1 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,1 ,6 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,15,15,15,15,15,15,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 , /*51*/ -/*52*/ 1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,37,1 ,o ,o ,o ,o ,o ,23,23,1 ,8 ,5 ,10,5 ,10,5 ,10,5 ,10,5 ,8 ,1 ,6 ,o ,o ,o ,o ,17,18,19,20,21,22,23,15,15,15,15,15,15,15,15,15,1 ,12,12,12,12,12,12,12,12,12,12,12, /*52*/ -/*53*/ 1 ,1 ,1 ,1 ,1 ,II,1 ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,23,23,1 ,8 ,10,o ,o ,o ,o ,o ,o ,o ,10,8 ,1 ,6 ,o ,o ,o ,o ,17,18,19,20,21,22,23,15,15,15,15,15,15,15,15,1 ,12,12,12,12,13,13,13,13,12,12,12,12, /*53*/ -/*54*/ 1 ,1 ,1 ,1 ,o ,o ,o ,1 ,1 ,1 ,1 ,17,18,19,20,22,23,23,1 ,8 ,5 ,o ,o ,o ,o ,o ,o ,o ,5 ,8 ,1 ,6 ,o ,o ,o ,o ,17,18,19,20,21,22,23,15,15,15,15,15,15,15,15,1 ,12,12,13,13,13,13,13,13,13,13,12,12, /*54*/ -/*55*/ 1 ,1 ,o ,o ,2 ,2 ,2 ,o ,o ,1 ,1 ,17,18,19,20,22,23,23,1 ,8 ,10,o ,o ,o ,o ,o ,o ,o ,10,8 ,1 ,6 ,o ,o ,o ,o ,17,18,19,20,21,22,23,15,15,15,15,15,15,15,15,1 ,12,12,13,13,14,13,13,14,13,13,12,12, /*55*/ -/*56*/ 1 ,1 ,o ,2 ,3 ,3 ,3 ,2 ,o ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,8 ,5 ,o ,o ,o ,o ,o ,o ,o ,5 ,8 ,1 ,1 ,o ,o ,o ,o ,o ,o ,27,15,15,15,15,15,15,15,15,15,15,1 ,1 ,1 ,12,13,13,13,14,13,13,14,13,13,13,12, /*56*/ -/*57*/ 1 ,o ,2 ,3 ,4 ,4 ,4 ,3 ,2 ,o ,1 ,o ,2 ,3 ,4 ,4 ,3 ,2 ,o ,1 ,1 ,10,10,10,10,10,10,10,1 ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,15,23,23,23,23,23,23,23,23,23,23,23,23,1 ,12,13,13,13,14,13,13,14,13,13,13,12, /*57*/ -/*58*/ 1 ,o ,2 ,3 ,4 ,4 ,4 ,3 ,2 ,o ,II,o ,o ,o ,o ,o ,o ,o ,o ,II,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,1 ,o ,o ,o ,o ,24,15,23,23,23,23,23,23,23,23,23,23,22,22,1 ,12,13,13,13,13,13,13,13,13,13,13,12, /*58*/ -/*59*/ 1 ,o ,2 ,3 ,4 ,4 ,4 ,3 ,2 ,o ,1 ,o ,2 ,3 ,4 ,4 ,3 ,2 ,o ,1 ,1 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,1 ,o ,o ,o ,o ,o ,15,23,38,23,23,38,23,23,23,23,23,22,38,1 ,12,13,13,14,13,13,13,13,14,13,13,12, /*59*/ -/*60*/ 1 ,1 ,o ,2 ,3 ,3 ,3 ,2 ,o ,1 ,1 ,11,11,11,11,11,11,11,11,1 ,1 ,1 ,1 ,1 ,FF,1 ,6 ,6 ,6 ,6 ,6 ,6 ,FF,o ,o ,o ,o ,24,15,23,23,23,23,23,23,23,23,23,23,22,22,1 ,12,12,13,13,14,14,14,14,13,13,12,12, /*60*/ -/*61*/ 1 ,1 ,o ,o ,2 ,2 ,2 ,o ,o ,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,1 ,1 ,o ,o ,o ,1 ,o ,o ,o ,o ,o ,o ,1 ,o ,o ,o ,o ,o ,15,23,38,23,23,38,23,23,23,23,23,22,38,1 ,12,12,13,13,13,13,13,13,13,13,12,12, /*61*/ -/*62*/ 1 ,1 ,1 ,1 ,o ,o ,o ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,1 ,1 ,o ,o ,o ,1 ,o ,42,o ,42,o ,o ,1 ,o ,o ,o ,o ,o ,27,23,23,23,23,23,23,23,23,23,23,22,22,1 ,12,12,12,12,13,13,13,13,12,12,12,12, /*62*/ -/*63*/ 1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,25,25,25,25,25,1 ,1 ,1 ,33,32,33,1 ,1 ,33,32,33,1 ,1 ,1 ,12,12,12,12,12,12,12,12,12,12,12,12 /*63*/ - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 - #undef AA - #undef BB - #undef CC - #undef DD - #undef EE - #undef FF - #undef GG - #undef HH - #undef II - #undef o - }, - { // tileDictionary - SFG_TD(15,14,0,0),SFG_TD(19, 0,0,0),SFG_TD(13,18,0,0),SFG_TD(11,22,0,0), // 0 - SFG_TD( 9,26,0,0),SFG_TD(19, 0,1,2),SFG_TD(15, 9,0,0),SFG_TD(19, 0,1,3), // 4 - SFG_TD(19, 0,4,4),SFG_TD(22, 7,4,4),SFG_TD(16, 7,4,4),SFG_TD(31, 0,3,3), // 8 - SFG_TD(26, 0,3,7),SFG_TD(15,31,0,0),SFG_TD(18,31,0,0),SFG_TD(23, 6,5,5), // 12 - SFG_TD(15, 5,0,0),SFG_TD(16,13,5,5),SFG_TD(17,12,5,5),SFG_TD(18,11,5,5), // 16 - SFG_TD(19,10,5,5),SFG_TD(20, 9,5,5),SFG_TD(21, 8,5,5),SFG_TD(22, 7,5,0), // 20 - SFG_TD(17,12,6,5),SFG_TD(23, 0,0,3),SFG_TD(19, 0,2,2),SFG_TD(31, 0,6,6), // 24 - SFG_TD(19, 0,6,0),SFG_TD(17, 6,4,4),SFG_TD(26, 0,5,0),SFG_TD(26, 0,1,1), // 28 - SFG_TD(25, 3,0,0),SFG_TD(26, 1,0,0),SFG_TD(22,31,6,6),SFG_TD(22, 5,5,6), // 32 - SFG_TD(22, 7,0,0),SFG_TD(15,13,0,4),SFG_TD(24, 5,6,5),SFG_TD(20,14,4,4), // 36 - SFG_TD(31, 8,0,0),SFG_TD(22,13,5,0),SFG_TD(21, 8,2,5),SFG_TD(15, 6,0,0), // 40 - SFG_TD(31,30,4,4),SFG_TD(15, 4,0,0),SFG_TD(15,13,0,0),SFG_TD(15,13,0,0), // 44 - SFG_TD(15,13,0,0),SFG_TD(15,13,0,0),SFG_TD(15,13,0,0),SFG_TD(15,13,0,0), // 48 - SFG_TD(15,13,0,0),SFG_TD(15,13,0,0),SFG_TD(15,13,0,0),SFG_TD(15,13,0,0), // 52 - SFG_TD(15,13,0,0),SFG_TD(15,13,0,0),SFG_TD(15,13,0,0),SFG_TD(15,13,0,0), // 56 - SFG_TD(15,13,0,0),SFG_TD(15,13,0,0),SFG_TD(15,13,0,0),SFG_TD(15,13,0,0) // 60 - }, // tileDictionary - {12,8 ,2 ,10,11,14,4 }, // textureIndices - 13, // doorTextureIndex - 4, // floorColor - 66, // ceilingColor - {34, 11, 0 }, // player start: x, y, direction - 1, // backgroundImage - { // elements - {SFG_LEVEL_ELEMENT_FINISH, {60,1}},{SFG_LEVEL_ELEMENT_BULLETS, {54,1}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {20,3}},{SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {24,4}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {18,5}},{SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {8,5}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {44,6}},{SFG_LEVEL_ELEMENT_COLUMN, {61,9}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {60,9}},{SFG_LEVEL_ELEMENT_COLUMN, {59,9}}, - {SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {51,9}},{SFG_LEVEL_ELEMENT_CARD2, {50,9}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {46,9}},{SFG_LEVEL_ELEMENT_BULLETS, {41,9}}, - {SFG_LEVEL_ELEMENT_PLASMA, {41,10}},{SFG_LEVEL_ELEMENT_BLOCKER, {28,10}}, - {SFG_LEVEL_ELEMENT_HEALTH, {50,11}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {38,11}}, - {SFG_LEVEL_ELEMENT_BLOCKER, {31,11}},{SFG_LEVEL_ELEMENT_BLOCKER, {30,11}}, - {SFG_LEVEL_ELEMENT_BLOCKER, {26,11}},{SFG_LEVEL_ELEMENT_BLOCKER, {29,12}}, - {SFG_LEVEL_ELEMENT_BLOCKER, {28,12}},{SFG_LEVEL_ELEMENT_BLOCKER, {26,12}}, - {SFG_LEVEL_ELEMENT_BLOCKER, {31,13}},{SFG_LEVEL_ELEMENT_BLOCKER, {27,13}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {23,13}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {48,14}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {44,14}},{SFG_LEVEL_ELEMENT_BLOCKER, {31,14}}, - {SFG_LEVEL_ELEMENT_BLOCKER, {29,14}},{SFG_LEVEL_ELEMENT_BLOCKER, {26,14}}, - {SFG_LEVEL_ELEMENT_BARREL, {20,14}},{SFG_LEVEL_ELEMENT_TERMINAL, {3,14}}, - {SFG_LEVEL_ELEMENT_BLOCKER, {31,15}},{SFG_LEVEL_ELEMENT_BLOCKER, {29,15}}, - {SFG_LEVEL_ELEMENT_CARD0, {28,15}},{SFG_LEVEL_ELEMENT_BLOCKER, {27,15}}, - {SFG_LEVEL_ELEMENT_BLOCKER, {26,15}},{SFG_LEVEL_ELEMENT_BULLETS, {4,19}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {35,20}},{SFG_LEVEL_ELEMENT_PLASMA, {35,21}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {35,22}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {62,23}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {10,24}},{SFG_LEVEL_ELEMENT_PLASMA, {7,24}}, - {SFG_LEVEL_ELEMENT_BULLETS, {4,24}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {62,25}}, - {SFG_LEVEL_ELEMENT_TREE, {56,25}},{SFG_LEVEL_ELEMENT_TREE, {52,25}}, - {SFG_LEVEL_ELEMENT_HEALTH, {49,25}},{SFG_LEVEL_ELEMENT_CARD1, {17,25}}, - {SFG_LEVEL_ELEMENT_HEALTH, {15,25}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {59,27}}, - {SFG_LEVEL_ELEMENT_BARREL, {28,27}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {14,27}}, - {SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {10,27}},{SFG_LEVEL_ELEMENT_BULLETS, {43,28}}, - {SFG_LEVEL_ELEMENT_BULLETS, {42,28}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {5,28}}, - {SFG_LEVEL_ELEMENT_RUIN, {27,29}},{SFG_LEVEL_ELEMENT_RUIN, {26,30}}, - {SFG_LEVEL_ELEMENT_HEALTH, {24,30}},{SFG_LEVEL_ELEMENT_RUIN, {27,31}}, - {SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {10,31}},{SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {4,31}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {17,34}},{SFG_LEVEL_ELEMENT_HEALTH, {4,34}}, - {SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {49,35}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {51,36}}, - {SFG_LEVEL_ELEMENT_LOCK1, {15,37}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {5,38}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {4,39}},{SFG_LEVEL_ELEMENT_BULLETS, {1,39}}, - {SFG_LEVEL_ELEMENT_COLUMN, {29,41}},{SFG_LEVEL_ELEMENT_COLUMN, {28,41}}, - {SFG_LEVEL_ELEMENT_COLUMN, {27,41}},{SFG_LEVEL_ELEMENT_ROCKETS, {8,41}}, - {SFG_LEVEL_ELEMENT_PLASMA, {31,42}},{SFG_LEVEL_ELEMENT_ROCKETS, {7,42}}, - {SFG_LEVEL_ELEMENT_LOCK0, {59,43}},{SFG_LEVEL_ELEMENT_HEALTH, {35,43}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {30,44}},{SFG_LEVEL_ELEMENT_TREE, {59,46}}, - {SFG_LEVEL_ELEMENT_PLASMA, {31,46}},{SFG_LEVEL_ELEMENT_BULLETS, {59,47}}, - {SFG_LEVEL_ELEMENT_TREE, {25,47}},{SFG_LEVEL_ELEMENT_TREE, {23,47}}, - {SFG_LEVEL_ELEMENT_BULLETS, {46,51}},{SFG_LEVEL_ELEMENT_BULLETS, {15,51}}, - {SFG_LEVEL_ELEMENT_LOCK1, {10,51}},{SFG_LEVEL_ELEMENT_TELEPORTER, {27,52}}, - {SFG_LEVEL_ELEMENT_TELEPORTER, {25,52}},{SFG_LEVEL_ELEMENT_TELEPORTER, {23,52}}, - {SFG_LEVEL_ELEMENT_TELEPORTER, {21,52}},{SFG_LEVEL_ELEMENT_ROCKETS, {15,52}}, - {SFG_LEVEL_ELEMENT_TELEPORTER, {28,53}},{SFG_LEVEL_ELEMENT_TELEPORTER, {20,53}}, - {SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {47,54}},{SFG_LEVEL_ELEMENT_TERMINAL, {24,54}}, - {SFG_LEVEL_ELEMENT_TELEPORTER, {28,55}},{SFG_LEVEL_ELEMENT_TELEPORTER, {20,55}}, - {SFG_LEVEL_ELEMENT_TELEPORTER, {62,57}},{SFG_LEVEL_ELEMENT_PLASMA, {59,57}}, - {SFG_LEVEL_ELEMENT_PLASMA, {56,57}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {45,58}}, - {SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {14,58}},{SFG_LEVEL_ELEMENT_BARREL, {12,58}}, - {SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {5,58}},{SFG_LEVEL_ELEMENT_HEALTH, {1,58}}, - {SFG_LEVEL_ELEMENT_TREE, {50,59}},{SFG_LEVEL_ELEMENT_LOCK2, {32,60}}, - {SFG_LEVEL_ELEMENT_TREE, {50,61}},{SFG_LEVEL_ELEMENT_ROCKETS, {22,61}}, - {SFG_LEVEL_ELEMENT_PLASMA, {22,62}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}} - }, // elements - } // level - ; - -SFG_PROGRAM_MEMORY SFG_Level SFG_level8 = - { // level - { // mapArray - #define o 0 - #define AA (10 | SFG_TILE_PROPERTY_DOOR) - #define BB (63 | SFG_TILE_PROPERTY_ELEVATOR) - #define CC (11 | SFG_TILE_PROPERTY_DOOR) - #define DD (13 | SFG_TILE_PROPERTY_DOOR) - #define EE (7 | SFG_TILE_PROPERTY_DOOR) - #define FF (60 | SFG_TILE_PROPERTY_DOOR) - #define GG (12 | SFG_TILE_PROPERTY_ELEVATOR) - #define HH (61 | SFG_TILE_PROPERTY_DOOR) - #define II (0 | SFG_TILE_PROPERTY_DOOR) - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 -/*0 */ 44,44,44,58,58,58,58,58,58,58,58,58,58,10,61,6 ,6 ,6 ,6 ,61,61,6 ,6 ,6 ,6 ,61,61,6 ,6 ,6 ,6 ,61,1 ,6 ,6 ,6 ,6 ,6 ,61,6 ,6 ,6 ,6 ,61,6 ,6 ,6 ,6 ,6 ,1 ,1 ,1 ,1 ,15,1 ,1 ,1 ,1 ,1 ,15,1 ,1 ,1 ,1 , /*0 */ -/*1 */ 44,44,58,58,59,59,59,59,59,59,59,59,59,10,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,14,14,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,1 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,1 ,1 , /*1 */ -/*2 */ 44,58,58,59,59,59,59,59,59,59,59,59,59,AA,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,14,14,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,1 , /*2 */ -/*3 */ 58,58,59,59,59,59,59,59,59,59,59,59,59,10,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,14,14,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,11,11,11,15,4 ,4 ,4 ,5 ,5 ,4 ,4 ,4 ,5 ,5 ,4 ,4 ,4 ,15, /*3 */ -/*4 */ 58,59,59,59,59,59,59,59,59,10,10,10,10,10,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,14,14,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,4 ,4 ,4 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,4 ,4 ,4 ,1 , /*4 */ -/*5 */ 58,59,59,59,59,59,59,59,10,61,61,61,61,61,4 ,4 ,3 ,3 ,4 ,4 ,3 ,3 ,4 ,4 ,13,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,14,14,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,11,o ,o ,2 ,4 ,4 ,4 ,4 ,5 ,BB,BB,BB,5 ,4 ,4 ,4 ,4 ,1 , /*5 */ -/*6 */ 58,59,59,59,59,59,59,57,57,54,53,52,51,50,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,1 ,13,13,13,13,13,13,13,15,15,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,CC,o ,o ,2 ,4 ,4 ,4 ,4 ,5 ,BB,BB,BB,5 ,4 ,4 ,4 ,4 ,1 , /*6 */ -/*7 */ 58,59,59,59,59,59,57,57,55,54,53,52,51,50,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,1 ,13,13,13,o ,13,13,13,13,23,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,11,o ,o ,2 ,4 ,4 ,4 ,4 ,5 ,BB,BB,BB,5 ,4 ,4 ,4 ,4 ,1 , /*7 */ -/*8 */ 58,59,59,59,59,10,57,55,55,54,53,52,51,50,4 ,4 ,4 ,4 ,3 ,3 ,4 ,4 ,4 ,4 ,DD,o ,o ,o ,o ,o ,o ,13,13,23,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,4 ,4 ,4 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,4 ,4 ,4 ,1 , /*8 */ -/*9 */ 58,59,59,59,10,61,55,55,55,54,53,52,51,50,4 ,4 ,4 ,4 ,3 ,3 ,4 ,4 ,4 ,4 ,1 ,13,13,13,o ,15,o ,o ,13,23,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,11,11,11,15,4 ,4 ,4 ,5 ,5 ,4 ,4 ,4 ,5 ,5 ,4 ,4 ,4 ,15, /*9 */ -/*10*/ 58,59,59,59,10,61,55,55,55,54,53,52,51,50,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,1 ,13,o ,o ,o ,o ,o ,13,13,23,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,1 , /*10*/ -/*11*/ 58,59,59,59,10,61,55,55,55,54,53,52,51,50,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,13,o ,o ,15,o ,13,13,13,13,23,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,1 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,1 ,1 , /*11*/ -/*12*/ 58,59,59,59,10,61,55,55,55,54,53,52,51,50,4 ,4 ,3 ,3 ,4 ,4 ,3 ,3 ,4 ,4 ,1 ,13,o ,o ,o ,o ,o ,o ,DD,23,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,1 ,1 ,1 ,15,1 ,2 ,2 ,2 ,1 ,15,1 ,1 ,1 ,1 , /*12*/ -/*13*/ 10,10,AA,10,61,10,10,10,10,10,10,10,8 ,8 ,10,10,8 ,8 ,10,10,8 ,8 ,10,10,1 ,13,13,13,o ,13,13,13,13,23,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,62,62,62,1 , /*13*/ -/*14*/ 61,o ,o ,o ,o ,10,10,10,10,10,10,o ,o ,o ,o ,o ,o ,o ,23,23,15,15,15,15,13,13,13,13,13,13,13,13,13,23,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,62,1 , /*14*/ -/*15*/ 56,o ,o ,o ,o ,10,10,10,10,10,8 ,o ,o ,o ,o ,o ,o ,o ,23,23,15,15,15,15,15,15,15,15,15,15,13,13,13,23,o ,o ,o ,o ,o ,o ,61,61,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,62,61, /*15*/ -/*16*/ 56,o ,o ,o ,o ,49,10,10,10,10,8 ,o ,o ,62,62,15,15,EE,15,15,15,15,15,o ,o ,o ,o ,o ,15,15,15,15,15,15,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,11,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,56, /*16*/ -/*17*/ 56,o ,o ,o ,o ,o ,10,10,10,10,10,o ,o ,62,15,15,o ,o ,o ,15,15,15,15,o ,o ,o ,o ,o ,15,15,o ,o ,61,o ,o ,o ,o ,o ,o ,o ,8 ,62,o ,o ,o ,o ,o ,11,62,8 ,62,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,56, /*17*/ -/*18*/ 56,o ,o ,o ,o ,o ,o ,49,10,10,10,49,49,15,15,o ,o ,o ,o ,o ,15,15,15,15,15,15,o ,o ,15,15,o ,o ,EE,o ,40,40,40,40,40,o ,8 ,62,o ,o ,o ,o ,o ,o ,62,8 ,62,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,56, /*18*/ -/*19*/ 56,o ,o ,o ,o ,o ,o ,o ,o ,o ,8 ,o ,o ,15,o ,o ,o ,o ,o ,o ,o ,15,15,15,15,1 ,o ,o ,1 ,15,o ,o ,61,o ,40,40,40,40,40,o ,8 ,62,o ,o ,o ,o ,o ,o ,62,8 ,62,62,62,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,61, /*19*/ -/*20*/ 56,o ,o ,o ,o ,o ,o ,o ,o ,62,8 ,o ,o ,15,o ,o ,15,o ,15,o ,o ,15,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,15,o ,40,40,40,40,40,o ,8 ,8 ,8 ,49,49,49,49,8 ,8 ,8 ,8 ,8 ,8 ,49,10,40,40,40,40,40,40,10,49,10, /*20*/ -/*21*/ 56,o ,o ,o ,o ,o ,o ,o ,62,62,10,o ,o ,15,o ,o ,o ,o ,o ,o ,o ,15,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,15,o ,40,40,40,40,40,o ,o ,o ,3 ,2 ,2 ,2 ,2 ,3 ,1 ,1 ,1 ,1 ,1 ,o ,40,40,40,40,40,40,40,40,o ,10, /*21*/ -/*22*/ 61,o ,o ,o ,o ,o ,o ,o ,62,62,10,o ,o ,15,15,o ,o ,o ,o ,o ,15,61,o ,o ,15,1 ,o ,o ,1 ,15,15,15,15,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,2 ,2 ,2 ,2 ,3 ,1 ,1 ,1 ,1 ,1 ,o ,40,40,40,40,40,40,40,40,o ,10, /*22*/ -/*23*/ 61,o ,o ,o ,o ,o ,o ,o ,o ,62,8 ,o ,o ,15,15,15,o ,o ,o ,15,o ,EE,o ,o ,15,15,o ,o ,15,15,15,15,8 ,62,62,10,10,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,o ,40,40,40,40,40,40,40,40,o ,10, /*23*/ -/*24*/ 61,o ,o ,o ,o ,o ,o ,o ,o ,o ,8 ,49,49,15,15,15,o ,o ,o ,15,o ,61,o ,o ,15,15,o ,o ,o ,o ,o ,15,8 ,o ,o ,10,10,1 ,62,o ,o ,o ,o ,o ,o ,o ,o ,1 ,1 ,1 ,1 ,1 ,1 ,o ,40,40,40,40,40,40,40,40,o ,10, /*24*/ -/*25*/ 56,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,15,15,15,61,EE,61,15,o ,15,15,15,15,15,o ,o ,o ,o ,o ,15,8 ,o ,o ,o ,10,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,1 ,1 ,1 ,1 ,o ,40,40,40,40,40,40,40,40,o ,10, /*25*/ -/*26*/ 56,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,15,23,23,23,23,23,23,23,15,15,15,15,15,15,15,61,EE,61,8 ,8 ,o ,o ,o ,AA,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,1 ,1 ,1 ,49,10,40,40,40,40,40,40,10,49,10, /*26*/ -/*27*/ 56,o ,o ,o ,o ,o ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,24,8 ,49,49,49,49,o ,o ,o ,10,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,62,1 ,10,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,61, /*27*/ -/*28*/ 56,o ,o ,o ,o ,o ,o ,o ,o ,4 ,4 ,4 ,55,55,8 ,55,55,55,55,55,55,55,55,55,55,55,55,55,62,o ,o ,o ,o ,o ,o ,10,10,1 ,62,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,10,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,56, /*28*/ -/*29*/ 56,o ,o ,o ,o ,o ,o ,o ,o ,4 ,4 ,4 ,55,55,FF,55,55,55,55,55,55,55,55,55,55,55,55,55,62,o ,o ,o ,o ,o ,o ,10,10,1 ,1 ,1 ,1 ,9 ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,o ,AA,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,56, /*29*/ -/*30*/ 56,o ,o ,o ,o ,o ,o ,o ,o ,4 ,50,50,54,54,8 ,55,4 ,4 ,4 ,4 ,4 ,50,51,52,53,54,55,8 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,47,47,46,46,GG,46,46,46,47,1 ,o ,o ,o ,o ,o ,10,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,56, /*30*/ -/*31*/ 56,o ,o ,o ,o ,o ,o ,o ,o ,4 ,51,51,53,53,8 ,55,4 ,4 ,4 ,4 ,4 ,50,51,52,53,54,55,1 ,1 ,1 ,53,53,52,52,52,51,51,47,47,46,46,46,46,46,46,47,47,1 ,o ,o ,62,1 ,10,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,61, /*31*/ -/*32*/ 61,o ,o ,o ,o ,o ,11,o ,o ,4 ,52,52,52,52,8 ,55,4 ,4 ,4 ,4 ,4 ,50,51,52,53,54,55,1 ,1 ,1 ,53,53,52,52,52,51,51,47,47,47,47,47,47,47,47,47,47,47,1 ,1 ,3 ,3 ,1 ,1 ,7 ,13,7 ,1 ,1 ,7 ,13,7 ,1 ,1 , /*32*/ -/*33*/ 61,EE,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,8 ,55,4 ,4 ,4 ,4 ,4 ,50,51,52,53,54,55,1 ,1 ,1 ,54,53,53,52,51,51,50,47,47,10,o ,o ,o ,o ,o ,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,o , /*33*/ -/*34*/ 61,o ,o ,o ,o ,24,24,24,24,24,24,1 ,1 ,1 ,3 ,55,4 ,4 ,4 ,4 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,54,54,54,60,50,50,50,47,47,o ,o ,o ,o ,o ,o ,o ,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,o , /*34*/ -/*35*/ 61,61,61,24,24,29,29,29,29,29,24,24,1 ,1 ,1 ,55,4 ,4 ,4 ,4 ,o ,o ,o ,o ,o ,o ,o ,1 ,15,1 ,54,54,54,1 ,50,50,50,47,47,o ,o ,o ,o ,o ,o ,o ,47,47,60,60,60,60,47,47,47,47,1 ,1 ,1 ,47,47,47,47,o , /*35*/ -/*36*/ 24,24,24,29,29,29,29,29,29,29,29,24,24,1 ,1 ,55,4 ,4 ,4 ,4 ,o ,4 ,4 ,4 ,4 ,4 ,4 ,1 ,55,1 ,55,55,55,1 ,4 ,4 ,4 ,47,47,10,o ,o ,o ,o ,o ,47,47,47,o ,o ,o ,60,47,47,47,47,23,23,23,47,47,47,47,o , /*36*/ -/*37*/ 24,29,29,29,29,29,29,29,29,29,29,29,24,1 ,1 ,55,4 ,4 ,4 ,4 ,o ,50,50,50,50,50,50,1 ,55,1 ,55,55,55,1 ,4 ,4 ,4 ,47,47,47,47,47,47,47,47,47,47,o ,o ,o ,o ,60,47,47,47,47,23,23,23,47,47,47,47,o , /*37*/ -/*38*/ 24,o ,29,29,29,29,29,29,29,29,29,29,24,1 ,1 ,55,4 ,4 ,4 ,4 ,o ,51,51,51,51,51,51,1 ,55,1 ,55,55,55,1 ,1 ,EE,1 ,1 ,47,47,47,47,47,47,47,1 ,o ,o ,o ,o ,o ,60,47,47,47,47,o ,1 ,o ,47,47,47,47,o , /*38*/ -/*39*/ 24,o ,o ,o ,29,29,24,24,29,29,29,29,24,24,1 ,55,4 ,4 ,4 ,4 ,o ,52,52,52,52,52,52,1 ,55,HH,55,55,55,1 ,o ,o ,o ,46,46,46,46,46,46,46,46,46,o ,o ,o ,o ,o ,60,47,47,47,47,o ,1 ,o ,47,47,47,47,o , /*39*/ -/*40*/ 24,o ,o ,o ,o ,o ,24,24,29,29,29,29,29,24,1 ,55,4 ,4 ,4 ,4 ,o ,53,53,53,53,53,53,1 ,55,1 ,55,55,55,1 ,o ,o ,o ,46,46,46,46,46,46,46,46,46,o ,o ,o ,3 ,47,47,47,47,47,47,II,II,II,47,47,47,47,o , /*40*/ -/*41*/ 24,o ,o ,o ,o ,o ,24,24,29,29,29,29,29,24,1 ,1 ,o ,o ,o ,o ,o ,54,54,54,54,54,54,60,1 ,60,55,55,55,1 ,o ,o ,o ,46,46,46,46,46,46,46,46,46,II,o ,o ,o ,o ,o ,47,47,47,47,47,o ,47,46,47,46,47,o , /*41*/ -/*42*/ 24,28,28,o ,o ,o ,o ,24,29,29,29,29,29,24,1 ,1 ,1 ,EE,1 ,1 ,1 ,55,55,55,55,55,55,55,55,55,55,55,55,1 ,o ,o ,o ,46,46,46,46,46,46,46,46,46,o ,o ,o ,o ,o ,o ,47,47,47,47,47,o ,47,47,47,47,47,o , /*42*/ -/*43*/ 24,24,28,31,31,31,31,24,24,29,29,29,29,24,24,1 ,1 ,o ,o ,o ,1 ,55,55,55,55,55,55,55,55,55,55,55,55,1 ,o ,o ,o ,46,46,46,46,46,46,46,46,46,o ,o ,o ,o ,o ,o ,47,47,47,47,47,o ,47,46,47,46,47,o , /*43*/ -/*44*/ 24,24,28,28,30,30,30,24,24,29,29,29,29,29,24,24,1 ,o ,o ,o ,1 ,55,55,55,55,55,55,55,55,55,55,55,55,1 ,o ,o ,o ,46,46,46,46,46,46,46,46,46,o ,o ,o ,o ,o ,o ,47,47,47,47,47,o ,47,47,47,47,47,o , /*44*/ -/*45*/ 24,24,24,24,30,30,30,30,24,29,29,29,29,29,29,24,24,1 ,1 ,o ,1 ,55,55,55,55,55,55,55,55,55,55,55,55,1 ,o ,o ,o ,46,46,46,46,46,46,46,46,46,o ,o ,o ,o ,o ,o ,15,1 ,1 ,1 ,7 ,EE,7 ,1 ,1 ,1 ,1 ,1 , /*45*/ -/*46*/ 24,24,24,24,29,29,30,30,24,29,29,29,29,29,29,29,24,24,1 ,o ,1 ,55,55,55,55,55,55,55,55,55,55,55,55,1 ,o ,o ,o ,46,46,46,46,46,46,46,46,46,o ,o ,o ,o ,o ,o ,1 ,1 ,1 ,1 ,o ,o ,o ,1 ,1 ,1 ,1 ,1 , /*46*/ -/*47*/ 24,24,24,24,29,29,29,29,24,24,29,29,29,30,30,30,30,24,1 ,o ,1 ,55,55,55,55,55,55,55,55,55,55,55,55,1 ,o ,o ,o ,46,46,46,45,45,45,46,46,46,o ,o ,o ,o ,o ,o ,1 ,1 ,1 ,1 ,23,23,23,1 ,1 ,1 ,1 ,1 , /*47*/ -/*48*/ 24,24,24,24,29,29,29,29,29,24,29,30,30,30,30,30,30,24,24,1 ,1 ,1 ,60,9 ,9 ,60,1 ,1 ,1 ,60,HH,60,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,1 ,1 ,1 ,1 ,1 ,o ,o ,o ,1 ,1 ,1 ,1 ,1 , /*48*/ -/*49*/ 24,24,24,29,29,29,29,29,29,24,30,30,30,30,30,30,30,30,24,24,8 ,46,46,GG,GG,46,46,1 ,55,55,55,55,55,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,8 ,8 ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,1 ,1 ,1 ,1 ,1 , /*49*/ -/*50*/ 24,24,24,o ,o ,o ,o ,o ,o ,24,30,30,30,30,30,30,30,30,24,24,8 ,46,46,GG,GG,46,46,56,55,55,55,55,55,56,o ,o ,o ,8 ,o ,o ,o ,o ,o ,o ,o ,8 ,o ,o ,o ,o ,23,o ,o ,23,o ,o ,o ,o ,o ,1 ,1 ,1 ,1 ,1 , /*50*/ -/*51*/ 24,24,24,o ,o ,o ,o ,o ,o ,24,30,30,30,30,31,31,31,31,24,24,8 ,46,46,GG,GG,46,46,56,55,55,55,55,55,56,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,EE,o ,o ,23,o ,o ,o ,o ,o ,o ,1 ,1 ,1 ,1 , /*51*/ -/*52*/ 24,24,24,24,o ,o ,o ,o ,o ,24,30,31,31,31,31,31,31,31,24,24,8 ,46,46,GG,GG,46,46,1 ,55,55,55,55,55,61,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,23,o ,o ,23,o ,o ,o ,o ,o ,o ,62,1 ,1 ,1 , /*52*/ -/*53*/ 24,24,24,24,o ,o ,o ,o ,28,24,31,31,31,31,31,31,31,28,24,24,8 ,47,47,9 ,9 ,47,47,1 ,55,55,55,55,55,56,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,8 ,8 ,8 ,48,1 ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,62,62,1 ,1 , /*53*/ -/*54*/ 24,24,28,o ,o ,o ,o ,o ,24,24,31,31,31,31,31,31,31,28,24,24,8 ,47,47,9 ,9 ,47,47,1 ,55,55,55,55,55,56,o ,o ,o ,o ,11,o ,o ,o ,o ,o ,o ,o ,o ,8 ,48,48,4 ,50,51,54,55,1 ,o ,o ,o ,o ,o ,o ,o ,1 , /*54*/ -/*55*/ 24,28,28,o ,o ,o ,o ,28,24,24,24,31,31,o ,o ,o ,o ,28,24,24,8 ,47,47,9 ,9 ,47,47,1 ,55,55,55,55,55,1 ,o ,1 ,1 ,1 ,1 ,1 ,1 ,EE,1 ,1 ,13,1 ,1 ,48,48,4 ,4 ,50,52,53,54,1 ,o ,o ,o ,o ,o ,o ,o ,6 , /*55*/ -/*56*/ 24,28,o ,o ,o ,o ,o ,24,24,24,24,24,24,o ,o ,o ,o ,28,24,24,8 ,8 ,8 ,9 ,9 ,47,47,3 ,3 ,55,55,55,55,48,14,48,48,48,48,48,48,48,48,48,48,48,48,48,4 ,4 ,4 ,50,51,52,51,1 ,o ,o ,o ,o ,o ,o ,o ,6 , /*56*/ -/*57*/ 24,o ,o ,o ,o ,o ,o ,24,28,o ,o ,28,24,o ,o ,o ,28,28,24,24,8 ,8 ,8 ,9 ,9 ,47,47,1 ,3 ,3 ,55,55,55,48,4 ,48,4 ,o ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,50,50,50,7 ,o ,o ,o ,o ,o ,o ,o ,6 , /*57*/ -/*58*/ 24,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,28,24,24,8 ,9 ,9 ,9 ,9 ,9 ,47,47,1 ,1 ,3 ,1 ,1 ,1 ,48,4 ,48,4 ,48,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,7 ,o ,o ,o ,o ,o ,o ,o ,6 , /*58*/ -/*59*/ 24,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,28,24,24,15,9 ,9 ,9 ,9 ,9 ,47,47,46,46,46,46,46,9 ,9 ,4 ,48,4 ,48,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,7 ,o ,o ,o ,o ,o ,o ,o ,6 , /*59*/ -/*60*/ 24,24,o ,o ,o ,o ,o ,o ,o ,24,24,o ,o ,o ,o ,o ,24,24,24,8 ,9 ,9 ,9 ,47,47,47,47,47,47,47,47,47,9 ,3 ,o ,3 ,o ,3 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,1 ,o ,o ,o ,o ,o ,o ,o ,1 , /*60*/ -/*61*/ 24,24,28,28,o ,o ,o ,28,28,24,24,24,28,o ,o ,28,24,24,24,15,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,48,4 ,4 ,4 ,48,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,53,53,1 ,1 ,1 ,1 ,EE,1 ,1 ,1 ,1 , /*61*/ -/*62*/ 24,24,24,28,28,28,28,28,24,24,24,24,24,24,24,24,24,24,24,8 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,48,4 ,4 ,4 ,48,4 ,4 ,4 ,4 ,23,4 ,4 ,4 ,23,4 ,4 ,4 ,23,4 ,4 ,53,53,1 ,1 ,1 ,1 ,o ,o ,o ,o ,1 , /*62*/ -/*63*/ 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,8 ,56,56,56,56,8 ,6 ,6 ,6 ,3 ,3 ,6 ,6 ,6 ,48,61,61,61,61,61,6 ,6 ,6 ,8 ,6 ,6 ,6 ,8 ,6 ,6 ,6 ,8 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,o ,1 /*63*/ - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 - #undef AA - #undef BB - #undef CC - #undef DD - #undef EE - #undef FF - #undef GG - #undef HH - #undef II - #undef o - }, - { // tileDictionary - SFG_TD(13,11,0,0),SFG_TD(14, 0,1,0),SFG_TD(13, 7,0,0),SFG_TD(17, 0,2,2), // 0 - SFG_TD(13,22,0,0),SFG_TD(12,23,0,0),SFG_TD(17, 0,0,5),SFG_TD(17, 0,1,0), // 4 - SFG_TD(20, 0,0,6),SFG_TD(20, 4,0,0),SFG_TD(17, 0,6,6),SFG_TD(17, 7,1,0), // 8 - SFG_TD( 9,11,2,0),SFG_TD(17, 0,1,1),SFG_TD(15, 9,0,0),SFG_TD( 0, 0,4,4), // 12 - SFG_TD(13,14,0,0),SFG_TD(13,14,0,0),SFG_TD(13,14,0,0),SFG_TD(13,14,0,0), // 16 - SFG_TD(13,14,0,0),SFG_TD(13,14,0,0),SFG_TD(13,14,0,0),SFG_TD(13, 8,0,4), // 20 - SFG_TD(17, 0,3,3),SFG_TD(13,14,0,0),SFG_TD(13,14,0,0),SFG_TD(13,14,0,0), // 24 - SFG_TD(15, 7,3,3),SFG_TD(19, 5,3,3),SFG_TD(17, 7,3,3),SFG_TD(15, 9,3,3), // 28 - SFG_TD(13,14,0,0),SFG_TD(13,14,0,0),SFG_TD(13,14,0,0),SFG_TD(13,14,0,0), // 32 - SFG_TD(13,14,0,0),SFG_TD(13,14,0,0),SFG_TD(13,14,0,0),SFG_TD(13,14,0,0), // 36 - SFG_TD(13,10,0,0),SFG_TD(13,14,0,0),SFG_TD(13,14,0,0),SFG_TD(13,14,0,0), // 40 - SFG_TD( 0, 0,7,7),SFG_TD(11,24,0,0),SFG_TD( 9,26,0,0),SFG_TD( 9, 4,0,0), // 44 - SFG_TD(14, 0,4,0),SFG_TD(13, 7,0,6),SFG_TD(14,21,0,0),SFG_TD(15,20,0,0), // 48 - SFG_TD(16,19,0,0),SFG_TD(17,18,0,0),SFG_TD(18,17,0,0),SFG_TD(19,16,0,0), // 52 - SFG_TD(20, 2,0,0),SFG_TD(23, 2,6,6),SFG_TD(17,31,0,0),SFG_TD(13,31,0,0), // 56 - SFG_TD(23, 0,6,6),SFG_TD(23, 0,0,0),SFG_TD(15, 9,3,0),SFG_TD(12,31,0,0) // 60 - }, // tileDictionary - {12,2 ,11,6 ,8 ,10,14}, // textureIndices - 7, // doorTextureIndex - 5, // floorColor - 4, // ceilingColor - {59, 59, 64 }, // player start: x, y, direction - 2, // backgroundImage - { // elements - {SFG_LEVEL_ELEMENT_CARD0, {33,3}},{SFG_LEVEL_ELEMENT_LAMP, {46,4}}, - {SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {38,4}},{SFG_LEVEL_ELEMENT_BULLETS, {33,5}}, - {SFG_LEVEL_ELEMENT_TREE, {56,6}},{SFG_LEVEL_ELEMENT_LOCK2, {46,6}}, - {SFG_LEVEL_ELEMENT_HEALTH, {6,6}},{SFG_LEVEL_ELEMENT_ROCKETS, {28,7}}, - {SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {17,7}},{SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {11,7}}, - {SFG_LEVEL_ELEMENT_LAMP, {46,8}},{SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {40,8}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {28,8}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {27,8}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {26,8}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {25,8}}, - {SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {8,10}},{SFG_LEVEL_ELEMENT_CARD2, {7,10}}, - {SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {12,11}},{SFG_LEVEL_ELEMENT_COLUMN, {57,12}}, - {SFG_LEVEL_ELEMENT_COLUMN, {56,12}},{SFG_LEVEL_ELEMENT_COLUMN, {55,12}}, - {SFG_LEVEL_ELEMENT_LOCK2, {32,12}},{SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {37,13}}, - {SFG_LEVEL_ELEMENT_HEALTH, {28,13}},{SFG_LEVEL_ELEMENT_LOCK1, {2,13}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {23,16}},{SFG_LEVEL_ELEMENT_BULLETS, {50,17}}, - {SFG_LEVEL_ELEMENT_PLASMA, {23,17}},{SFG_LEVEL_ELEMENT_BULLETS, {50,18}}, - {SFG_LEVEL_ELEMENT_PLASMA, {41,18}},{SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {54,19}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {37,19}},{SFG_LEVEL_ELEMENT_HEALTH, {36,19}}, - {SFG_LEVEL_ELEMENT_PLASMA, {37,20}},{SFG_LEVEL_ELEMENT_BULLETS, {36,20}}, - {SFG_LEVEL_ELEMENT_BULLETS, {19,20}},{SFG_LEVEL_ELEMENT_BULLETS, {15,20}}, - {SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {27,21}},{SFG_LEVEL_ELEMENT_ROCKETS, {9,21}}, - {SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {7,21}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {45,22}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {9,22}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {4,22}}, - {SFG_LEVEL_ELEMENT_PLASMA, {1,22}},{SFG_LEVEL_ELEMENT_TREE, {34,23}}, - {SFG_LEVEL_ELEMENT_TREE, {33,23}},{SFG_LEVEL_ELEMENT_PLASMA, {1,23}}, - {SFG_LEVEL_ELEMENT_PLASMA, {1,24}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {17,26}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {47,27}},{SFG_LEVEL_ELEMENT_TREE, {27,28}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {41,29}},{SFG_LEVEL_ELEMENT_TREE, {27,29}}, - {SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {20,29}},{SFG_LEVEL_ELEMENT_RUIN, {1,32}}, - {SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {49,33}},{SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {49,34}}, - {SFG_LEVEL_ELEMENT_PLASMA, {38,34}},{SFG_LEVEL_ELEMENT_LAMP, {15,34}}, - {SFG_LEVEL_ELEMENT_HEALTH, {38,35}},{SFG_LEVEL_ELEMENT_HEALTH, {58,36}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {56,36}},{SFG_LEVEL_ELEMENT_HEALTH, {28,36}}, - {SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {15,36}},{SFG_LEVEL_ELEMENT_BULLETS, {49,37}}, - {SFG_LEVEL_ELEMENT_BULLETS, {49,38}},{SFG_LEVEL_ELEMENT_LOCK0, {35,38}}, - {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {53,39}},{SFG_LEVEL_ELEMENT_HEALTH, {50,40}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {28,40}},{SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {57,41}}, - {SFG_LEVEL_ELEMENT_RUIN, {17,41}},{SFG_LEVEL_ELEMENT_CARD1, {10,41}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {61,42}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {53,42}}, - {SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {44,42}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {38,42}}, - {SFG_LEVEL_ELEMENT_BARREL, {37,42}},{SFG_LEVEL_ELEMENT_LAMP, {12,43}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {60,44}},{SFG_LEVEL_ELEMENT_NONE, {45,44}}, - {SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {41,44}},{SFG_LEVEL_ELEMENT_BARREL, {37,44}}, - {SFG_LEVEL_ELEMENT_BARREL, {24,47}},{SFG_LEVEL_ELEMENT_BARREL, {23,47}}, - {SFG_LEVEL_ELEMENT_TELEPORTER, {4,47}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {32,49}}, - {SFG_LEVEL_ELEMENT_MONSTER_TURRET, {28,49}},{SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {14,49}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {51,50}},{SFG_LEVEL_ELEMENT_COLUMN, {50,50}}, - {SFG_LEVEL_ELEMENT_BULLETS, {11,50}},{SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {7,50}}, - {SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {6,50}},{SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {5,50}}, - {SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {4,50}},{SFG_LEVEL_ELEMENT_LOCK0, {50,51}}, - {SFG_LEVEL_ELEMENT_BULLETS, {11,51}},{SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {57,52}}, - {SFG_LEVEL_ELEMENT_PLASMA, {51,52}},{SFG_LEVEL_ELEMENT_COLUMN, {50,52}}, - {SFG_LEVEL_ELEMENT_PLASMA, {28,52}},{SFG_LEVEL_ELEMENT_ROCKETS, {28,53}}, - {SFG_LEVEL_ELEMENT_BULLETS, {62,54}},{SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {61,54}}, - {SFG_LEVEL_ELEMENT_TELEPORTER, {54,54}},{SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {3,54}}, - {SFG_LEVEL_ELEMENT_PLASMA, {56,55}},{SFG_LEVEL_ELEMENT_PLASMA, {41,55}}, - {SFG_LEVEL_ELEMENT_RUIN, {34,55}},{SFG_LEVEL_ELEMENT_HEALTH, {22,55}}, - {SFG_LEVEL_ELEMENT_PLASMA, {21,55}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {34,57}}, - {SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {45,58}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {9,59}}, - {SFG_LEVEL_ELEMENT_LAMP, {2,59}},{SFG_LEVEL_ELEMENT_ROCKETS, {56,60}}, - {SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {41,60}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {36,60}}, - {SFG_LEVEL_ELEMENT_HEALTH, {23,60}},{SFG_LEVEL_ELEMENT_HEALTH, {15,61}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {8,61}},{SFG_LEVEL_ELEMENT_RUIN, {61,62}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {60,62}},{SFG_LEVEL_ELEMENT_HEALTH, {59,62}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}} - }, // elements - } // level - ; - -SFG_PROGRAM_MEMORY SFG_Level SFG_level9 = - { // level - { // mapArray - #define o 0 - #define AA (41 | SFG_TILE_PROPERTY_ELEVATOR) - #define BB (53 | SFG_TILE_PROPERTY_ELEVATOR) - #define CC (48 | SFG_TILE_PROPERTY_DOOR) - #define DD (4 | SFG_TILE_PROPERTY_DOOR) - #define EE (7 | SFG_TILE_PROPERTY_ELEVATOR) - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 -/*0 */ 6 ,6 ,6 ,AA,AA,AA,6 ,6 ,6 ,6 ,21,21,21,21,4 ,4 ,4 ,4 ,6 ,6 ,6 ,6 ,AA,AA,AA,AA,62,62,62,62,62,62,62,62,62,62,62,62,62,63,63,58,58,58,58,58,58,58,58,58,63,63,63,58,58,58,58,58,58,58,58,58,63,63, /*0 */ -/*1 */ 62,33,62,32,33,39,62,37,38,33,62,37,32,33,62,35,36,35,62,33,34,33,62,32,33,32,62,62,62,62,62,62,62,62,62,62,62,62,62,63,58,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,58,63, /*1 */ -/*2 */ 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,62,62,62,BB,52,52,52,52,52,52,52,52,52,58,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,58, /*2 */ -/*3 */ 47,47,47,47,47,47,47,47,47,49,47,49,47,47,47,49,47,49,47,47,47,49,47,49,47,47,62,62,62,47,62,62,62,62,62,62,62,62,62,58,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,58, /*3 */ -/*4 */ 47,47,47,49,47,49,47,47,49,49,49,49,49,47,49,49,49,49,49,47,49,49,49,49,49,47,47,47,47,47,62,62,62,62,62,62,62,62,62,58,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,58, /*4 */ -/*5 */ 47,47,47,47,47,47,47,47,49,49,49,49,49,47,49,49,49,49,49,47,49,49,49,49,49,47,62,62,62,62,62,62,62,62,62,62,62,62,62,58,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,58, /*5 */ -/*6 */ 47,47,49,47,47,47,49,47,47,49,49,49,47,47,47,49,49,49,47,47,47,49,49,49,47,47,62,62,63,63,63,63,63,63,63,63,62,62,62,58,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,58, /*6 */ -/*7 */ 47,47,47,49,49,49,47,47,47,47,49,47,47,47,47,47,49,47,47,47,47,47,49,47,47,47,62,62,63,o ,o ,o ,o ,o ,o ,63,62,62,62,58,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,58,58,58,58,58,58,58,58,58,58,o ,o ,58, /*7 */ -/*8 */ 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,62,62,57,o ,o ,o ,o ,o ,o ,57,62,62,62,58,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,58,1 ,1 ,1 ,1 ,1 ,1 ,25,1 ,58,58,58,58, /*8 */ -/*9 */ 47,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,63,o ,o ,o ,o ,o ,o ,63,62,62,62,63,58,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,58,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,58,23,23,23, /*9 */ -/*10*/ 47,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,57,o ,o ,o ,o ,o ,o ,57,62,62,62,63,63,58,58,58,58,58,58,58,58,58,58,58,1 ,62,62,62,62,62,62,62,47,47,62,62, /*10*/ -/*11*/ 47,62,62,62,62,62,63,63,57,63,63,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,63,o ,o ,o ,o ,o ,o ,63,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,63,63,57,63,63,62,62,62,47,62,62, /*11*/ -/*12*/ 47,62,62,62,62,62,63,o ,o ,o ,63,63,57,63,57,63,57,63,57,63,57,63,57,63,57,63,57,63,63,o ,o ,o ,o ,o ,o ,63,63,57,63,57,63,57,63,57,63,57,63,57,63,57,63,57,63,63,o ,o ,o ,63,62,62,62,47,47,47, /*12*/ -/*13*/ 47,62,62,62,62,62,57,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,57,62,62,62,62,62,CC, /*13*/ -/*14*/ 47,62,62,62,62,62,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,63,62,62,62,62,62,47, /*14*/ -/*15*/ 47,62,62,62,62,62,63,63,o ,o ,1 ,1 ,1 ,25,1 ,1 ,1 ,1 ,1 ,1 ,60,1 ,1 ,1 ,1 ,o ,8 ,9 ,10,11,12,1 ,1 ,12,11,10,9 ,8 ,o ,1 ,1 ,1 ,1 ,60,1 ,1 ,1 ,1 ,1 ,1 ,25,1 ,1 ,1 ,o ,o ,63,63,62,62,62,62,62,47, /*15*/ -/*16*/ 47,62,62,62,62,62,62,63,o ,o ,1 ,2 ,2 ,2 ,2 ,2 ,1 ,2 ,2 ,2 ,59,2 ,26,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,26,2 ,59,2 ,2 ,2 ,1 ,2 ,2 ,2 ,2 ,2 ,1 ,o ,o ,63,62,62,62,62,62,62,47, /*16*/ -/*17*/ 47,62,62,62,62,62,62,23,o ,o ,1 ,2 ,3 ,3 ,3 ,21,1 ,21,27,15,15,15,3 ,2 ,2 ,2 ,59,2 ,59,2 ,59,2 ,2 ,59,2 ,59,2 ,59,2 ,2 ,2 ,3 ,3 ,3 ,3 ,27,21,1 ,21,3 ,3 ,3 ,2 ,1 ,o ,o ,23,62,62,62,62,62,62,47, /*17*/ -/*18*/ 47,62,62,62,62,62,62,23,o ,o ,60,59,61,6 ,6 ,21,1 ,1 ,21,15,15,15,3 ,3 ,3 ,3 ,61,3 ,61,3 ,61,3 ,3 ,61,3 ,61,3 ,61,3 ,3 ,3 ,3 ,6 ,6 ,6 ,21,1 ,1 ,21,6 ,6 ,61,59,60,o ,o ,23,62,62,62,62,62,62,47, /*18*/ -/*19*/ 47,62,62,62,62,62,62,63,o ,o ,1 ,2 ,3 ,6 ,6 ,21,1 ,1 ,21,15,15,15,15,6 ,6 ,6 ,61,6 ,61,6 ,61,6 ,6 ,61,6 ,61,6 ,61,6 ,6 ,6 ,6 ,6 ,6 ,6 ,21,1 ,1 ,21,6 ,6 ,3 ,2 ,1 ,o ,o ,63,62,62,62,62,62,62,47, /*19*/ -/*20*/ 47,62,62,62,62,62,62,57,o ,o ,1 ,2 ,3 ,6 ,6 ,21,21,21,21,6 ,15,15,15,6 ,6 ,6 ,61,6 ,61,22,61,6 ,6 ,61,22,61,6 ,61,6 ,6 ,6 ,6 ,6 ,6 ,6 ,21,21,21,21,6 ,6 ,3 ,2 ,1 ,o ,o ,57,62,62,62,62,62,62,47, /*20*/ -/*21*/ 47,62,62,62,62,62,62,63,o ,o ,25,26,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,15,15,6 ,6 ,61,6 ,61,6 ,61,6 ,6 ,61,6 ,61,6 ,61,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,26,25,o ,o ,63,62,62,62,62,62,62,47, /*21*/ -/*22*/ 47,62,62,62,62,63,63,57,o ,o ,1 ,2 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,15,15,6 ,61,6 ,61,6 ,61,6 ,6 ,61,6 ,61,6 ,61,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,2 ,1 ,o ,o ,57,63,63,62,62,62,62,47, /*22*/ -/*23*/ 47,62,62,62,62,63,o ,o ,o ,o ,1 ,2 ,3 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,15,6 ,61,3 ,61,3 ,61,6 ,6 ,61,3 ,61,3 ,61,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,3 ,2 ,1 ,o ,o ,o ,o ,63,62,62,62,62,47, /*23*/ -/*24*/ 47,62,62,62,62,63,o ,o ,o ,o ,1 ,2 ,2 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,15,15,4 ,4 ,4 ,4 ,13,13,13,13,4 ,4 ,4 ,4 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,2 ,2 ,1 ,o ,o ,o ,o ,63,62,62,62,62,47, /*24*/ -/*25*/ 47,62,62,62,62,63,o ,o ,o ,o ,60,2 ,3 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,4 ,4 ,4 ,13,13,13,5 ,5 ,13,13,13,4 ,4 ,4 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,3 ,2 ,60,o ,o ,o ,o ,63,62,62,62,62,47, /*25*/ -/*26*/ 47,62,62,62,62,63,o ,o ,o ,o ,60,2 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,4 ,4 ,4 ,13,5 ,5 ,5 ,5 ,5 ,5 ,13,4 ,4 ,4 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,2 ,60,o ,o ,o ,o ,63,62,62,62,62,47, /*26*/ -/*27*/ 47,62,62,62,62,63,o ,o ,o ,o ,1 ,2 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,13,4 ,4 ,13,5 ,5 ,5 ,5 ,5 ,5 ,13,4 ,4 ,13,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,2 ,1 ,o ,o ,o ,o ,63,62,62,62,62,47, /*27*/ -/*28*/ 47,62,62,62,62,63,o ,o ,o ,o ,1 ,2 ,3 ,6 ,61,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,4 ,4 ,4 ,13,13,13,5 ,5 ,13,13,13,4 ,4 ,4 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,61,6 ,3 ,2 ,1 ,o ,o ,o ,o ,63,62,62,62,62,47, /*28*/ -/*29*/ 47,62,62,62,62,63,63,57,o ,o ,1 ,2 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,4 ,4 ,4 ,4 ,4 ,13,DD,DD,13,4 ,4 ,4 ,4 ,4 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,2 ,1 ,o ,o ,57,63,63,62,62,62,62,47, /*29*/ -/*30*/ 47,62,62,62,62,62,62,63,o ,o ,25,26,3 ,3 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,4 ,4 ,13,4 ,4 ,5 ,5 ,4 ,4 ,13,4 ,4 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,3 ,3 ,26,25,o ,o ,63,62,62,62,62,62,62,47, /*30*/ -/*31*/ 47,62,62,62,62,62,62,57,o ,o ,1 ,2 ,2 ,2 ,3 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,6 ,3 ,6 ,6 ,6 ,6 ,3 ,6 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,3 ,2 ,2 ,2 ,1 ,o ,o ,57,62,62,62,62,62,62,47, /*31*/ -/*32*/ 47,62,62,62,62,62,62,63,o ,o ,1 ,1 ,1 ,2 ,14,3 ,3 ,3 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,3 ,3 ,3 ,14,2 ,1 ,1 ,1 ,o ,o ,63,62,62,62,62,62,62,47, /*32*/ -/*33*/ 47,62,62,62,62,62,62,57,o ,o ,1 ,1 ,1 ,2 ,14,3 ,3 ,3 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,3 ,3 ,3 ,14,2 ,1 ,1 ,1 ,o ,o ,57,62,62,62,62,62,62,47, /*33*/ -/*34*/ 47,62,62,62,62,62,62,63,o ,o ,1 ,1 ,1 ,2 ,14,3 ,3 ,3 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,3 ,3 ,3 ,14,2 ,1 ,1 ,1 ,o ,o ,63,62,62,62,62,62,62,47, /*34*/ -/*35*/ 47,62,62,62,62,62,62,57,o ,o ,1 ,1 ,1 ,2 ,14,3 ,3 ,3 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,3 ,3 ,3 ,14,2 ,1 ,1 ,1 ,o ,o ,57,62,62,62,62,62,62,47, /*35*/ -/*36*/ 47,62,62,62,62,62,62,63,o ,o ,1 ,2 ,2 ,2 ,3 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,3 ,2 ,2 ,2 ,1 ,o ,o ,63,62,62,62,62,62,62,47, /*36*/ -/*37*/ 47,62,62,62,62,62,62,57,o ,o ,25,2 ,3 ,3 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,3 ,3 ,2 ,25,o ,o ,57,62,62,62,62,62,62,47, /*37*/ -/*38*/ 47,62,62,62,62,62,62,63,o ,o ,1 ,2 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,2 ,1 ,o ,o ,63,62,62,62,62,62,62,47, /*38*/ -/*39*/ 47,62,62,62,62,63,63,57,o ,o ,1 ,2 ,3 ,6 ,6 ,6 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,6 ,6 ,15,15,2 ,1 ,o ,o ,57,63,63,62,62,62,62,47, /*39*/ -/*40*/ 47,62,62,62,62,63,o ,o ,o ,o ,1 ,2 ,3 ,6 ,6 ,6 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,15,15,15,15,2 ,1 ,o ,o ,o ,o ,63,62,62,62,62,47, /*40*/ -/*41*/ 47,62,62,62,62,63,o ,o ,o ,58,1 ,2 ,3 ,6 ,6 ,3 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,3 ,15,15,3 ,2 ,1 ,58,o ,o ,o ,63,62,62,62,62,47, /*41*/ -/*42*/ 47,62,62,62,62,63,o ,o ,o ,1 ,1 ,2 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,2 ,1 ,1 ,o ,o ,o ,63,62,62,62,62,47, /*42*/ -/*43*/ 47,62,62,62,62,63,o ,o ,o ,1 ,1 ,2 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,2 ,1 ,1 ,o ,o ,o ,63,62,62,62,62,47, /*43*/ -/*44*/ 47,62,62,62,62,63,o ,o ,o ,58,1 ,2 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,2 ,1 ,58,o ,o ,o ,63,62,62,62,62,47, /*44*/ -/*45*/ 47,62,62,62,62,63,o ,o ,o ,o ,1 ,2 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,2 ,1 ,o ,o ,o ,o ,63,62,62,62,62,47, /*45*/ -/*46*/ 47,62,62,62,62,63,63,57,o ,o ,1 ,2 ,3 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,3 ,2 ,1 ,o ,o ,57,63,63,62,62,62,62,47, /*46*/ -/*47*/ 47,62,62,62,62,62,62,63,o ,o ,60,59,61,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,61,59,60,o ,o ,63,62,62,62,62,62,62,47, /*47*/ -/*48*/ 47,62,62,62,62,62,62,57,o ,o ,25,26,27,3 ,6 ,3 ,3 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,3 ,3 ,14,14,3 ,3 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,3 ,3 ,6 ,3 ,27,26,25,o ,o ,57,62,62,62,62,62,62,47, /*48*/ -/*49*/ 47,62,62,62,62,62,62,63,o ,o ,60,59,61,3 ,6 ,6 ,6 ,3 ,6 ,6 ,61,6 ,6 ,61,6 ,6 ,6 ,6 ,20,5 ,5 ,5 ,5 ,5 ,5 ,20,6 ,6 ,6 ,6 ,61,6 ,6 ,61,6 ,6 ,3 ,6 ,6 ,6 ,3 ,61,59,60,o ,o ,63,62,62,62,62,62,62,47, /*49*/ -/*50*/ 47,62,62,62,62,62,62,57,o ,o ,1 ,2 ,3 ,3 ,6 ,6 ,6 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,20,5 ,5 ,5 ,5 ,5 ,5 ,20,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,6 ,6 ,6 ,3 ,3 ,2 ,1 ,o ,o ,57,62,62,62,62,62,62,47, /*50*/ -/*51*/ 47,62,62,62,62,62,62,63,o ,o ,60,59,61,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,3 ,3 ,3 ,3 ,5 ,5 ,EE,EE,5 ,5 ,3 ,3 ,3 ,3 ,3 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,3 ,61,59,60,o ,o ,63,62,62,62,62,62,62,47, /*51*/ -/*52*/ 47,62,62,62,62,62,62,57,o ,o ,1 ,2 ,3 ,3 ,6 ,6 ,6 ,6 ,3 ,3 ,3 ,6 ,6 ,6 ,3 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,3 ,6 ,6 ,6 ,3 ,3 ,3 ,6 ,6 ,6 ,6 ,3 ,3 ,2 ,1 ,o ,o ,57,62,62,62,62,62,62,47, /*52*/ -/*53*/ 47,62,62,62,62,62,62,63,o ,o ,1 ,2 ,2 ,3 ,3 ,3 ,3 ,3 ,3 ,2 ,3 ,3 ,3 ,3 ,3 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,3 ,3 ,3 ,3 ,3 ,2 ,3 ,3 ,3 ,3 ,3 ,3 ,2 ,2 ,1 ,o ,o ,63,62,62,62,62,62,62,47, /*53*/ -/*54*/ 47,62,62,62,62,62,62,57,o ,o ,1 ,2 ,2 ,2 ,59,2 ,59,2 ,2 ,2 ,2 ,2 ,26,2 ,2 ,2 ,1 ,16,17,18,19,2 ,2 ,19,18,17,16,1 ,2 ,2 ,2 ,26,2 ,2 ,2 ,2 ,2 ,59,2 ,59,2 ,2 ,2 ,1 ,o ,o ,57,62,62,62,62,62,62,47, /*54*/ -/*55*/ 47,62,62,62,62,62,62,63,o ,o ,1 ,1 ,1 ,1 ,60,25,60,1 ,1 ,1 ,1 ,1 ,25,1 ,60,1 ,60,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,60,1 ,60,1 ,25,1 ,1 ,1 ,1 ,1 ,60,25,60,1 ,1 ,1 ,1 ,o ,o ,63,62,62,62,62,62,62,47, /*55*/ -/*56*/ 47,62,62,62,62,62,62,57,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,57,57,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,57,62,62,62,62,62,62,47, /*56*/ -/*57*/ 47,62,62,62,62,62,62,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,63,63,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,63,62,62,62,62,62,62,47, /*57*/ -/*58*/ 47,62,62,62,62,62,62,63,63,57,63,57,63,57,63,57,63,23,23,23,23,23,63,57,63,57,63,57,o ,o ,o ,o ,o ,o ,o ,o ,57,63,57,63,57,63,23,23,23,23,23,63,57,63,57,63,57,63,57,63,63,62,62,62,62,62,62,47, /*58*/ -/*59*/ 47,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,63,o ,o ,o ,o ,o ,o ,o ,o ,63,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,47, /*59*/ -/*60*/ 47,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,63,63,63,63,63,63,63,63,63,63,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,47, /*60*/ -/*61*/ 47,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,47, /*61*/ -/*62*/ 47,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,47, /*62*/ -/*63*/ 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 /*63*/ - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 - #undef AA - #undef BB - #undef CC - #undef DD - #undef EE - #undef o - }, - { // tileDictionary - SFG_TD( 0,31,0,0),SFG_TD(12,31,0,0),SFG_TD(22,31,0,0),SFG_TD(31,31,0,0), // 0 - SFG_TD(31, 0,0,0),SFG_TD(27,31,0,0),SFG_TD(29,31,4,0),SFG_TD(22, 5,1,0), // 4 - SFG_TD( 2,31,0,0),SFG_TD( 4,31,0,0),SFG_TD( 6,31,0,0),SFG_TD( 8,31,0,0), // 8 - SFG_TD(10,31,0,0),SFG_TD(31, 0,3,3),SFG_TD(31,31,3,0),SFG_TD(28,31,4,0), // 12 - SFG_TD(14,31,0,0),SFG_TD(16,31,0,0),SFG_TD(18,31,0,0),SFG_TD(20,31,0,0), // 16 - SFG_TD(29,31,0,0),SFG_TD(31,31,5,0),SFG_TD(31, 0,6,6),SFG_TD( 9,31,0,0), // 20 - SFG_TD(14,15,0,0),SFG_TD(12,31,2,0),SFG_TD(22,31,2,0),SFG_TD(31,31,2,0), // 24 - SFG_TD(14,15,0,0),SFG_TD(14,15,0,0),SFG_TD(14,15,0,0),SFG_TD(14,15,0,0), // 28 - SFG_TD(13, 4,7,7),SFG_TD( 1,16,7,7),SFG_TD( 9, 4,7,7),SFG_TD( 1,12,7,7), // 32 - SFG_TD( 5,12,7,7),SFG_TD( 1,12,7,7),SFG_TD( 5, 4,7,7),SFG_TD( 1, 4,7,7), // 36 - SFG_TD(14,15,0,0),SFG_TD(31,18,5,0),SFG_TD(14,15,0,0),SFG_TD(14,15,0,0), // 40 - SFG_TD(14,15,0,0),SFG_TD(14,15,0,0),SFG_TD(14,15,0,0),SFG_TD( 0,31,7,7), // 44 - SFG_TD( 4,31,0,0),SFG_TD( 0,31,0,0),SFG_TD(14,15,0,0),SFG_TD(14,15,0,0), // 48 - SFG_TD(31,31,7,7),SFG_TD( 0,31,0,7),SFG_TD(14,15,0,0),SFG_TD(14,15,0,0), // 52 - SFG_TD(14,15,0,0),SFG_TD( 4,31,3,0),SFG_TD( 2,31,5,0),SFG_TD(23,31,1,0), // 56 - SFG_TD(13,31,1,0),SFG_TD(30,31,1,0),SFG_TD(31, 0,7,7),SFG_TD( 4,31,0,0) // 60 - }, // tileDictionary - {14,11,1 ,8 ,9 ,5 ,13}, // textureIndices - 7, // doorTextureIndex - 74, // floorColor - 74, // ceilingColor - {55, 13, 160}, // player start: x, y, direction - 2, // backgroundImage - { // elements - {SFG_LEVEL_ELEMENT_BULLETS, {55,2}},{SFG_LEVEL_ELEMENT_BULLETS, {53,2}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {47,2}},{SFG_LEVEL_ELEMENT_ROCKETS, {45,2}}, - {SFG_LEVEL_ELEMENT_HEALTH, {55,4}},{SFG_LEVEL_ELEMENT_HEALTH, {53,4}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {47,4}},{SFG_LEVEL_ELEMENT_ROCKETS, {45,4}}, - {SFG_LEVEL_ELEMENT_PLASMA, {48,6}},{SFG_LEVEL_ELEMENT_PLASMA, {48,7}}, - {SFG_LEVEL_ELEMENT_TELEPORTER, {43,7}},{SFG_LEVEL_ELEMENT_HEALTH, {33,8}}, - {SFG_LEVEL_ELEMENT_HEALTH, {30,8}},{SFG_LEVEL_ELEMENT_BULLETS, {33,10}}, - {SFG_LEVEL_ELEMENT_PLASMA, {30,10}},{SFG_LEVEL_ELEMENT_LOCK2, {63,13}}, - {SFG_LEVEL_ELEMENT_RUIN, {43,13}},{SFG_LEVEL_ELEMENT_RUIN, {43,14}}, - {SFG_LEVEL_ELEMENT_RUIN, {42,15}},{SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {52,17}}, - {SFG_LEVEL_ELEMENT_BARREL, {25,17}},{SFG_LEVEL_ELEMENT_TELEPORTER, {46,19}}, - {SFG_LEVEL_ELEMENT_RUIN, {22,19}},{SFG_LEVEL_ELEMENT_HEALTH, {17,19}}, - {SFG_LEVEL_ELEMENT_BULLETS, {16,19}},{SFG_LEVEL_ELEMENT_HEALTH, {47,21}}, - {SFG_LEVEL_ELEMENT_PLASMA, {46,21}},{SFG_LEVEL_ELEMENT_PLASMA, {17,21}}, - {SFG_LEVEL_ELEMENT_HEALTH, {16,21}},{SFG_LEVEL_ELEMENT_ROCKETS, {47,22}}, - {SFG_LEVEL_ELEMENT_BULLETS, {46,22}},{SFG_LEVEL_ELEMENT_BULLETS, {17,22}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {16,22}},{SFG_LEVEL_ELEMENT_HEALTH, {32,23}}, - {SFG_LEVEL_ELEMENT_HEALTH, {31,23}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {10,23}}, - {SFG_LEVEL_ELEMENT_BARREL, {47,24}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {42,24}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {56,25}},{SFG_LEVEL_ELEMENT_BARREL, {47,25}}, - {SFG_LEVEL_ELEMENT_FINISH, {32,25}},{SFG_LEVEL_ELEMENT_FINISH, {31,25}}, - {SFG_LEVEL_ELEMENT_RUIN, {24,25}},{SFG_LEVEL_ELEMENT_ROCKETS, {7,25}}, - {SFG_LEVEL_ELEMENT_PLASMA, {56,26}},{SFG_LEVEL_ELEMENT_HEALTH, {42,26}}, - {SFG_LEVEL_ELEMENT_COLUMN, {33,26}},{SFG_LEVEL_ELEMENT_COLUMN, {30,26}}, - {SFG_LEVEL_ELEMENT_HEALTH, {21,26}},{SFG_LEVEL_ELEMENT_PLASMA, {7,26}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {56,27}},{SFG_LEVEL_ELEMENT_COLUMN, {33,27}}, - {SFG_LEVEL_ELEMENT_COLUMN, {30,27}},{SFG_LEVEL_ELEMENT_ROCKETS, {7,27}}, - {SFG_LEVEL_ELEMENT_HEALTH, {42,28}},{SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {38,28}}, - {SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {26,28}},{SFG_LEVEL_ELEMENT_HEALTH, {21,28}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {39,29}},{SFG_LEVEL_ELEMENT_LOCK2, {32,29}}, - {SFG_LEVEL_ELEMENT_LOCK2, {31,29}},{SFG_LEVEL_ELEMENT_ROCKETS, {25,29}}, - {SFG_LEVEL_ELEMENT_BULLETS, {33,30}},{SFG_LEVEL_ELEMENT_BULLETS, {30,30}}, - {SFG_LEVEL_ELEMENT_MONSTER_ENDER, {40,32}},{SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {31,32}}, - {SFG_LEVEL_ELEMENT_MONSTER_ENDER, {23,32}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {55,33}}, - {SFG_LEVEL_ELEMENT_HEALTH, {52,33}},{SFG_LEVEL_ELEMENT_HEALTH, {11,33}}, - {SFG_LEVEL_ELEMENT_HEALTH, {52,34}},{SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {45,34}}, - {SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {19,34}},{SFG_LEVEL_ELEMENT_HEALTH, {11,34}}, - {SFG_LEVEL_ELEMENT_MONSTER_ENDER, {31,35}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {27,36}}, - {SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {39,37}},{SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {35,37}}, - {SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {24,37}},{SFG_LEVEL_ELEMENT_PLASMA, {43,39}}, - {SFG_LEVEL_ELEMENT_PLASMA, {20,39}},{SFG_LEVEL_ELEMENT_HEALTH, {32,40}}, - {SFG_LEVEL_ELEMENT_HEALTH, {31,40}},{SFG_LEVEL_ELEMENT_BARREL, {43,41}}, - {SFG_LEVEL_ELEMENT_BARREL, {42,41}},{SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {38,41}}, - {SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {25,41}},{SFG_LEVEL_ELEMENT_BARREL, {20,41}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {56,42}},{SFG_LEVEL_ELEMENT_BARREL, {43,42}}, - {SFG_LEVEL_ELEMENT_BARREL, {42,42}},{SFG_LEVEL_ELEMENT_BARREL, {21,42}}, - {SFG_LEVEL_ELEMENT_BARREL, {19,42}},{SFG_LEVEL_ELEMENT_ROCKETS, {7,42}}, - {SFG_LEVEL_ELEMENT_PLASMA, {56,43}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {52,43}}, - {SFG_LEVEL_ELEMENT_BARREL, {32,43}},{SFG_LEVEL_ELEMENT_BARREL, {31,43}}, - {SFG_LEVEL_ELEMENT_BARREL, {30,43}},{SFG_LEVEL_ELEMENT_BARREL, {20,43}}, - {SFG_LEVEL_ELEMENT_PLASMA, {7,43}},{SFG_LEVEL_ELEMENT_HEALTH, {32,45}}, - {SFG_LEVEL_ELEMENT_HEALTH, {31,45}},{SFG_LEVEL_ELEMENT_ROCKETS, {49,50}}, - {SFG_LEVEL_ELEMENT_HEALTH, {48,50}},{SFG_LEVEL_ELEMENT_HEALTH, {15,50}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {14,50}},{SFG_LEVEL_ELEMENT_PLASMA, {49,51}}, - {SFG_LEVEL_ELEMENT_BULLETS, {48,51}},{SFG_LEVEL_ELEMENT_BULLETS, {15,51}}, - {SFG_LEVEL_ELEMENT_PLASMA, {14,51}},{SFG_LEVEL_ELEMENT_RUIN, {31,52}}, - {SFG_LEVEL_ELEMENT_RUIN, {36,53}},{SFG_LEVEL_ELEMENT_RUIN, {35,53}}, - {SFG_LEVEL_ELEMENT_RUIN, {34,53}},{SFG_LEVEL_ELEMENT_RUIN, {33,53}}, - {SFG_LEVEL_ELEMENT_RUIN, {32,53}},{SFG_LEVEL_ELEMENT_RUIN, {28,53}}, - {SFG_LEVEL_ELEMENT_RUIN, {27,53}},{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {25,53}}, - {SFG_LEVEL_ELEMENT_BARREL, {18,54}},{SFG_LEVEL_ELEMENT_HEALTH, {55,57}}, - {SFG_LEVEL_ELEMENT_HEALTH, {8,57}},{SFG_LEVEL_ELEMENT_MONSTER_PLASMABOT, {33,58}}, - {SFG_LEVEL_ELEMENT_ROCKETS, {32,59}},{SFG_LEVEL_ELEMENT_PLASMA, {31,59}}, - {SFG_LEVEL_ELEMENT_NONE, {0,0}},{SFG_LEVEL_ELEMENT_NONE, {0,0}} - }, // elements - } // level - - ; - -static const SFG_Level * SFG_levels[SFG_NUMBER_OF_LEVELS] = -{ - &SFG_level0, &SFG_level1, &SFG_level2, &SFG_level3, &SFG_level4, &SFG_level5, - &SFG_level6, &SFG_level7, &SFG_level8, &SFG_level9 -}; - -#endif // guard - diff --git a/main_gbmeta/main_gbmeta.ino b/main_gbmeta/main_gbmeta.ino deleted file mode 100644 index 3dd3b32..0000000 --- a/main_gbmeta/main_gbmeta.ino +++ /dev/null @@ -1,173 +0,0 @@ -/** - @file main_gbmeta.ino - - This is Gamebuino Meta implementation of the game front end, using the - official library. Leaving out the library bloat could probably optimize this. - - To compile using Arduin IDE you need to copy this file as well as all - necessary .h files into a project folder, then open the project and compile. - Do NOT put .c and .cpp files into the folder, stupid Arduino tries to compile - them even if they're not needed. - - DON'T FORGET to set compiler flag to -O3 (default is -Os). With Arduino IDE - this is done in platform.txt file. - - by Miloslav Ciz (drummyfish), 2019 - - Released under CC0 1.0 (https://creativecommons.org/publicdomain/zero/1.0/) - plus a waiver of all other intellectual property. The goal of this work is - be and remain completely in the public domain forever, available for any use - whatsoever. -*/ - -#include - -#define SFG_ARDUINO 1 -#define SFG_CAN_EXIT 0 -#define SFG_FPS 17 -#define SFG_SCREEN_RESOLUTION_X 80 -#define SFG_SCREEN_RESOLUTION_Y 64 -#define SFG_RESOLUTION_SCALEDOWN 1 -#define SFG_RAYCASTING_MAX_STEPS 11 -#define SFG_RAYCASTING_MAX_HITS 3 -#define SFG_RAYCASTING_SUBSAMPLE 2 -#define SFG_DIMINISH_SPRITES 0 -#define SFG_DITHERED_SHADOW 0 -#define SFG_PLAYER_TURN_SPEED 135 -#define SFG_FOV_HORIZONTAL 200 - -#include "game.h" - -Gamebuino_Meta::Color palette[256]; - -uint8_t blinkFramesLeft; - -void blinkLED(Gamebuino_Meta::Color color) -{ - gb.lights.fill(color); - blinkFramesLeft = 5; -} - -const Gamebuino_Meta::SaveDefault saveDefault[] = - { { 0, SAVETYPE_BLOB, SFG_SAVE_SIZE, 0 } }; - -void SFG_setPixel(uint16_t x, uint16_t y, uint8_t colorIndex) -{ - Gamebuino_Meta::Color c = palette[colorIndex]; - gb.display.drawPixel(x,y,c); -} - -void SFG_sleepMs(uint16_t timeMs) -{ -} - -int8_t SFG_keyPressed(uint8_t key) -{ - Gamebuino_Meta::Button button; - - switch (key) - { - case SFG_KEY_UP: button = BUTTON_UP; break; - case SFG_KEY_RIGHT: button = BUTTON_RIGHT; break; - case SFG_KEY_DOWN: button = BUTTON_DOWN; break; - case SFG_KEY_LEFT: button = BUTTON_LEFT; break; - case SFG_KEY_A: button = BUTTON_A; break; - case SFG_KEY_B: button = BUTTON_B; break; - case SFG_KEY_C: button = BUTTON_MENU; break; - default: return 0; break; - } - - return gb.buttons.timeHeld(button) > 0; -} - -void SFG_processEvent(uint8_t event, uint8_t value) -{ - switch (event) - { - case SFG_EVENT_LEVEL_STARTS: blinkLED(BLUE); break; - case SFG_EVENT_PLAYER_HURT: blinkLED(RED); break; - case SFG_EVENT_LEVEL_WON: blinkLED(YELLOW); break; - default: break; - } -} - -void SFG_getMouseOffset(int16_t *x, int16_t *y) -{ -} - -void SFG_setMusic(uint8_t value) -{ -} - -void SFG_save(uint8_t data[SFG_SAVE_SIZE]) -{ - gb.save.set(0,data,SFG_SAVE_SIZE); -} - -uint8_t SFG_load(uint8_t data[SFG_SAVE_SIZE]) -{ - gb.save.get(0,data,SFG_SAVE_SIZE); - return 1; -} - -void SFG_playSound(uint8_t soundIndex, uint8_t volume) -{ - switch (soundIndex) - { - case 2: - gb.sound.playCancel(); - break; - - case 5: - gb.sound.playOK(); - break; - - default: - gb.sound.playTick(); - break; - } -} - -uint32_t SFG_getTimeMs() -{ - return gb.frameStartMicros / 1000; -} - -void setup() -{ - gb.begin(); - gb.setFrameRate(SFG_FPS); - gb.save.config(saveDefault); - - for (int i = 0; i < 256; ++i) - { - uint16_t rgb565 = paletteRGB565[i]; - palette[i] = gb.createColor((rgb565 & 0xf800) >> 8,(rgb565 & 0x07e0) >> 3,(rgb565 & 0x001f) << 3); - } - - SFG_init(); - blinkLED(RED); -} - -void loop() -{ - while(!gb.update()) - { - } - - if (blinkFramesLeft != 0) - { - if (blinkFramesLeft == 1) - gb.lights.clear(); - - blinkFramesLeft--; - } - - SFG_mainLoopBody(); - -#if 0 - // debuggin performance - gb.display.setCursor(1,1); - gb.display.print(gb.getCpuLoad()); -#endif -} diff --git a/main_gbmeta/main_gbmeta.ino.gamebuino_meta.bin b/main_gbmeta/main_gbmeta.ino.gamebuino_meta.bin deleted file mode 100755 index 2c41390795e168c43e0fd12c913945f4561e15a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 214568 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
    PtTDMU$l9`FapQzmt= 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 Gc>WLT^Ym)~ diff --git a/main_gbmeta/mbed_config.h b/main_gbmeta/mbed_config.h deleted file mode 100644 index 34e7f96..0000000 --- a/main_gbmeta/mbed_config.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * mbed SDK - * Copyright (c) 2017 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Automatically generated configuration file. -// DO NOT EDIT, content will be overwritten. - -#ifndef __MBED_CONFIG_DATA__ -#define __MBED_CONFIG_DATA__ - - -#endif diff --git a/main_gbmeta/palette.h b/main_gbmeta/palette.h deleted file mode 100644 index ec66ee2..0000000 --- a/main_gbmeta/palette.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - @file palette.h - - General purpose HSV-based 256 color palette. - - by Miloslav Ciz (drummyfish), 2019 - - Released under CC0 1.0 (https://creativecommons.org/publicdomain/zero/1.0/) - plus a waiver of all other intellectual property. The goal of this work is - be and remain completely in the public domain forever, available for any use - whatsoever. -*/ - -#ifndef PALETTE_256_H -#define PALETTE_256_H - -SFG_PROGRAM_MEMORY uint16_t paletteRGB565[256] = { -#if 1 -// manually adjusted, more saturated palette -0, 6371, 14855, 27436, 38066, 48631, 59228, 65535, 6241, 14563, 24966, 33320, -43755, 52142, 62577, 64885, 6337, 16772, 25190, 35689, 44139, 52559, 63058, -65333, 6402, 14851, 23334, 31816, 40268, 50830, 59314, 65526, 4354, 10755, -15174, 21576, 30027, 36462, 42929, 51190, 2306, 8709, 13096, 19532, 25935, -30323, 36790, 47098, 4356, 8711, 15115, 19536, 27956, 32377, 38846, 47103, -4227, 8519, 12812, 17136, 25588, 31961, 38334, 46751, 2115, 8424, 14732, 21040, -27380, 33721, 40030, 48511, 6244, 12520, 22924, 31280, 39669, 48089, 56445, -64927, 8290, 16614, 24969, 33325, 43761, 52148, 62585, 64892, 10240, 18464, -26657, 38946, 47202, 55524, 63781, 64074, 10400, 18753, 27170, 37601, 48034, -56421, 64837, 65002, 6496, 14944, 23425, 31937, 40418, 48869, 57317, 61418, -352, 4704, 7041, 7362, 15842, 20196, 24550, 30697, 354, 611, 2949, 5288, 7658, -12013, 8175, 20467, 357, 617, 910, 5298, 9686, 7931, 14335, 24575, 69, 233, -4461, 4594, 8918, 2907, 13311, 19679, 4133, 2089, 4173, 8306, 10455, 16667, -20863, 27263, 6149, 14377, 22574, 28819, 39063, 45371, 53631, 57983, 10242, -18469, 26664, 38987, 47247, 55537, 63797, 64119, 10272, 18432, 26624, 34848, -45056, 53312, 61504, 63520, 10336, 18624, 26976, 35296, 45728, 54048, 62400, -64609, 8544, 16992, 25440, 31872, 42400, 50880, 59328, 65504, 4448, 2656, -7008, 11392, 13728, 14016, 20416, 26593, 2400, 608, 864, 3200, 5504, 1698, -1985, 2019, 353, 614, 872, 1163, 1422, 1713, 2005, 2039, 197, 361, 557, 753, -950, 5273, 1406, 9759, 5, 9, 2093, 81, 4214, 186, 2270, 351, 2052, 4105, 4109, -8209, 8278, 12314, 16414, 18527, 10245, 14378, 22541, 30738, 38934, 47130, 55326, -61471, 10241, 18435, 26630, 34824, 45066, 53293, 61519, 63601 -#else -// original palette -0, 8484, 19017, 27501, 38034, 46518, 57051, 65535, 8354, 16709, 25096, 33450, -41805, 50192, 58546, 64853, 8386, 16805, 25224, 33642, 42061, 50480, 58898, -65269, 6402, 14853, 23304, 29706, 38157, 46608, 55058, 61429, 4354, 10757, -17160, 23562, 29965, 36368, 42770, 49141, 4355, 10758, 17161, 21516, 27920, -34323, 38678, 45049, 4323, 10759, 17163, 21519, 27923, 34327, 38683, 45055, -4292, 10632, 17004, 21296, 27668, 34008, 38300, 44671, 4260, 10568, 16908, -23216, 29524, 35864, 42172, 48479, 6308, 14664, 23052, 29360, 37716, 46104, -54460, 60767, 8355, 16710, 25098, 33453, 41809, 50196, 58552, 64859, 8257, -16546, 24836, 33093, 41382, 49672, 57929, 64170, 8353, 16738, 25124, 33509, -41894, 50248, 58633, 64970, 6401, 12802, 21252, 27653, 36102, 42504, 50953, -57322, 2305, 6658, 11012, 15365, 19718, 24072, 28425, 32746, 2306, 4612, 8967, -11273, 13580, 17934, 20240, 22515, 2307, 4615, 8971, 11279, 13587, 17943, 20251, -22527, 2180, 4392, 8652, 10864, 13076, 17304, 19516, 21727, 2116, 6312, 10508, -14672, 18868, 23064, 25180, 29375, 6212, 12456, 20748, 26960, 35252, 41496, -49756, 55999, 8258, 16549, 24840, 33099, 41390, 49681, 57940, 64183, 8192, -16384, 24576, 32768, 40960, 49152, 57344, 63488, 8320, 16640, 24960, 33312, -41632, 49952, 58304, 64576, 6400, 14848, 23296, 29696, 38144, 46592, 52992, -61408, 2304, 6656, 8960, 13312, 15616, 19968, 22272, 26592, 256, 513, 769, 1026, -1283, 1539, 1796, 2021, 258, 517, 776, 1035, 1294, 1552, 1811, 2038, 164, 360, -556, 752, 948, 1144, 1308, 1503, 36, 104, 140, 208, 244, 312, 348, 415, 2052, -4104, 8204, 10256, 14356, 16408, 18460, 22559, 6148, 14344, 20492, 28688, 34836, -43032, 51228, 57375, 8194, 16388, 24582, 32777, 40971, 49165, 57359, 63505 -#endif -}; - -/** Adds value (brightness), possibly negative, to given color (represented by - its palette index). If you know you'll only be either adding or substracting, - use plusValue() or minusValue() functions, which should be faster. */ -static inline uint8_t palette_addValue(uint8_t color, int8_t add) -{ - uint8_t newValue = color + add; - - if ((newValue >> 3) == (color >> 3)) - return newValue; - else - return add > 0 ? (color | 0x07) : 0; -} - -/** Adds a positive value (brightness) to given color (represented by its - palette index). This should be a little bit faster than addValue(). */ -static inline uint8_t palette_plusValue(uint8_t color, uint8_t plus) -{ - uint8_t newValue = color + plus; - return ((newValue >> 3) == (color >> 3)) ? newValue : (color | 0x07); -} - -/** Substracts a positive value (brightness) from given color (represented by - its palette index). This should be a little bit faster than addValue(). */ -static inline uint8_t palette_minusValue(uint8_t color, uint8_t minus) -{ - uint8_t newValue = color - minus; - return ((newValue >> 3) == (color >> 3)) ? newValue : 0; -} - -#endif //guard diff --git a/main_gbmeta/raycastlib.h b/main_gbmeta/raycastlib.h deleted file mode 100644 index 38a70ff..0000000 --- a/main_gbmeta/raycastlib.h +++ /dev/null @@ -1,2058 +0,0 @@ -#ifndef RAYCASTLIB_H -#define RAYCASTLIB_H - -/** - raycastlib (RCL) - Small C header-only raycasting library for embedded and - low performance computers, such as Arduino. Only uses integer math and stdint - standard library. - - Check the defines below to fine-tune accuracy vs performance! Don't forget - to compile with optimizations. - - Before including the library define RCL_PIXEL_FUNCTION to the name of the - function (with RCL_PixelFunction signature) that will render your pixels! - - - All public (and most private) library identifiers start with RCL_. - - Game field's bottom left corner is at [0,0]. - - X axis goes right in the ground plane. - - Y axis goes up in the ground plane. - - Height means the Z (vertical) coordinate. - - Each game square is RCL_UNITS_PER_SQUARE * RCL_UNITS_PER_SQUARE points. - - Angles are in RCL_Units, 0 means pointing right (x+) and positively rotates - clockwise. A full angle has RCL_UNITS_PER_SQUARE RCL_Units. - - Most things are normalized with RCL_UNITS_PER_SQUARE (sin, cos, vector - unit length, texture coordinates etc.). - - Screen coordinates are normal: [0,0] = top left, x goes right, y goes down. - - author: Miloslav "drummyfish" Ciz - license: CC0 1.0 - version: 0.908d - - Version numbering: major.minor[d], id 'd' is appended, this is a - in-development version based on the previous stable major.minor version. Two - 'd' versions with the same version number, .e.g. 1.0d, may be different. -*/ - -#include - -#ifndef RCL_RAYCAST_TINY /** Turns on super efficient version of this library. - Only use if neccesarry, looks ugly. Also not done - yet. */ - #define RCL_UNITS_PER_SQUARE 1024 /**< Number of RCL_Units in a side of a - spatial square. */ - typedef int32_t RCL_Unit; /**< Smallest spatial unit, there is - RCL_UNITS_PER_SQUARE units in a square's - length. This effectively serves the purpose of - a fixed-point arithmetic. */ - #define RCL_INFINITY 2000000000 -#else - #define RCL_UNITS_PER_SQUARE 32 - typedef int16_t RCL_Unit; - #define RCL_INFINITY 30000 - #define RCL_USE_DIST_APPROX 2 -#endif - -#ifndef RCL_COMPUTE_WALL_TEXCOORDS -#define RCL_COMPUTE_WALL_TEXCOORDS 1 -#endif - -#ifndef RCL_COMPUTE_FLOOR_TEXCOORDS -#define RCL_COMPUTE_FLOOR_TEXCOORDS 0 -#endif - -#ifndef RCL_FLOOR_TEXCOORDS_HEIGHT -#define RCL_FLOOR_TEXCOORDS_HEIGHT 0 /** If RCL_COMPUTE_FLOOR_TEXCOORDS == 1, - this says for what height level the - texture coords will be computed for - (for simplicity/performance only one - level is allowed). */ -#endif - -#ifndef RCL_USE_COS_LUT -#define RCL_USE_COS_LUT 0 /**< type of look up table for cos function: - 0: none (compute) - 1: 64 items - 2: 128 items */ -#endif - -#ifndef RCL_USE_DIST_APPROX -#define RCL_USE_DIST_APPROX 0 /**< What distance approximation to use: - 0: none (compute full Euclidean distance) - 1: accurate approximation - 2: octagonal approximation (LQ) */ -#endif - -#ifndef RCL_RECTILINEAR -#define RCL_RECTILINEAR 1 /**< Whether to use rectilinear perspective (normally - used), or curvilinear perspective (fish eye). */ -#endif - -#ifndef RCL_TEXTURE_VERTICAL_STRETCH -#define RCL_TEXTURE_VERTICAL_STRETCH 1 /**< Whether textures should be - stretched to wall height (possibly - slightly slower if on). */ -#endif - -#ifndef RCL_COMPUTE_FLOOR_DEPTH -#define RCL_COMPUTE_FLOOR_DEPTH 1 /**< Whether depth should be computed for - floor pixels - turns this off if not - needed. */ -#endif - -#ifndef RCL_COMPUTE_CEILING_DEPTH -#define RCL_COMPUTE_CEILING_DEPTH 1 /**< As RCL_COMPUTE_FLOOR_DEPTH but for - ceiling. */ -#endif - -#ifndef RCL_ROLL_TEXTURE_COORDS -#define RCL_ROLL_TEXTURE_COORDS 1 /**< Says whether rolling doors should also - roll the texture coordinates along (mostly - desired for doors). */ -#endif - -#ifndef RCL_VERTICAL_FOV -#define RCL_VERTICAL_FOV (RCL_UNITS_PER_SQUARE / 3) -#endif - -#define RCL_VERTICAL_FOV_TAN (RCL_VERTICAL_FOV * 4) ///< tan approximation - -#ifndef RCL_HORIZONTAL_FOV -#define RCL_HORIZONTAL_FOV (RCL_UNITS_PER_SQUARE / 4) -#endif - -#define RCL_HORIZONTAL_FOV_TAN (RCL_HORIZONTAL_FOV * 4) - -#define RCL_HORIZONTAL_FOV_HALF (RCL_HORIZONTAL_FOV / 2) - -#ifndef RCL_CAMERA_COLL_RADIUS -#define RCL_CAMERA_COLL_RADIUS RCL_UNITS_PER_SQUARE / 4 -#endif - -#ifndef RCL_CAMERA_COLL_HEIGHT_BELOW -#define RCL_CAMERA_COLL_HEIGHT_BELOW RCL_UNITS_PER_SQUARE -#endif - -#ifndef RCL_CAMERA_COLL_HEIGHT_ABOVE -#define RCL_CAMERA_COLL_HEIGHT_ABOVE (RCL_UNITS_PER_SQUARE / 3) -#endif - -#ifndef RCL_CAMERA_COLL_STEP_HEIGHT -#define RCL_CAMERA_COLL_STEP_HEIGHT (RCL_UNITS_PER_SQUARE / 2) -#endif - -#ifndef RCL_TEXTURE_INTERPOLATION_SCALE - #define RCL_TEXTURE_INTERPOLATION_SCALE 1024 /**< This says scaling of fixed - poit vertical texture coord - computation. This should be power - of two! Higher number can look more - accurate but may cause overflow. */ -#endif - -#define RCL_HORIZON_DEPTH (11 * RCL_UNITS_PER_SQUARE) /**< What depth the - horizon has (the floor - depth is only - approximated with the - help of this - constant). */ -#ifndef RCL_VERTICAL_DEPTH_MULTIPLY -#define RCL_VERTICAL_DEPTH_MULTIPLY 2 /**< Defines a multiplier of height - difference when approximating floor/ceil - depth. */ -#endif - -#define RCL_min(a,b) ((a) < (b) ? (a) : (b)) -#define RCL_max(a,b) ((a) > (b) ? (a) : (b)) -#define RCL_nonZero(v) ((v) + ((v) == 0)) ///< To prevent zero divisions. -#define RCL_zeroClamp(x) ((x) * ((x) >= 0)) -#define RCL_likely(cond) __builtin_expect(!!(cond),1) -#define RCL_unlikely(cond) __builtin_expect(!!(cond),0) - -#define RCL_logV2D(v)\ - printf("[%d,%d]\n",v.x,v.y); - -#define RCL_logRay(r){\ - printf("ray:\n");\ - printf(" start: ");\ - RCL_logV2D(r.start);\ - printf(" dir: ");\ - RCL_logV2D(r.direction);} - -#define RCL_logHitResult(h){\ - printf("hit:\n");\ - printf(" square: ");\ - RCL_logV2D(h.square);\ - printf(" pos: ");\ - RCL_logV2D(h.position);\ - printf(" dist: %d\n", h.distance);\ - printf(" dir: %d\n", h.direction);\ - printf(" texcoord: %d\n", h.textureCoord);} - -#define RCL_logPixelInfo(p){\ - printf("pixel:\n");\ - printf(" position: ");\ - RCL_logV2D(p.position);\ - printf(" texCoord: ");\ - RCL_logV2D(p.texCoords);\ - printf(" depth: %d\n", p.depth);\ - printf(" height: %d\n", p.height);\ - printf(" wall: %d\n", p.isWall);\ - printf(" hit: ");\ - RCL_logHitResult(p.hit);\ - } - -#define RCL_logCamera(c){\ - printf("camera:\n");\ - printf(" position: ");\ - RCL_logV2D(c.position);\ - printf(" height: %d\n",c.height);\ - printf(" direction: %d\n",c.direction);\ - printf(" shear: %d\n",c.shear);\ - printf(" resolution: %d x %d\n",c.resolution.x,c.resolution.y);\ - } - -/// Position in 2D space. -typedef struct -{ - RCL_Unit x; - RCL_Unit y; -} RCL_Vector2D; - -typedef struct -{ - RCL_Vector2D start; - RCL_Vector2D direction; -} RCL_Ray; - -typedef struct -{ - RCL_Unit distance; /**< Distance to the hit position, or -1 if no - collision happened. If RCL_RECTILINEAR != 0, then - the distance is perpendicular to the projection - plane (fish eye correction), otherwise it is - the straight distance to the ray start - position. */ - uint8_t direction; /**< Direction of hit. The convention for angle - units is explained above. */ - RCL_Unit textureCoord; /**< Normalized (0 to RCL_UNITS_PER_SQUARE - 1) - texture coordinate (horizontal). */ - RCL_Vector2D square; ///< Collided square coordinates. - RCL_Vector2D position; ///< Exact collision position in RCL_Units. - RCL_Unit arrayValue; /** Value returned by array function (most often - this will be the floor height). */ - RCL_Unit type; /**< Integer identifying type of square (number - returned by type function, e.g. texture - index).*/ - RCL_Unit doorRoll; ///< Holds value of door roll. -} RCL_HitResult; - -typedef struct -{ - RCL_Vector2D position; - RCL_Unit direction; // TODO: rename to "angle" to keep consistency - RCL_Vector2D resolution; - int16_t shear; /**< Shear offset in pixels (0 => no shear), can simulate - looking up/down. */ - RCL_Unit height; -} RCL_Camera; - -/** - Holds an information about a single rendered pixel (for a pixel function - that works as a fragment shader). -*/ -typedef struct -{ - RCL_Vector2D position; ///< On-screen position. - int8_t isWall; ///< Whether the pixel is a wall or a floor/ceiling. - int8_t isFloor; ///< Whether the pixel is floor or ceiling. - int8_t isHorizon; ///< If the pixel belongs to horizon segment. - RCL_Unit depth; ///< Corrected depth. - RCL_Unit wallHeight;///< Only for wall pixels, says its height. - RCL_Unit height; ///< World height (mostly for floor). - RCL_HitResult hit; ///< Corresponding ray hit. - RCL_Vector2D texCoords; /**< Normalized (0 to RCL_UNITS_PER_SQUARE - 1) - texture coordinates. */ -} RCL_PixelInfo; - -void RCL_PIXEL_FUNCTION (RCL_PixelInfo *pixel); - -typedef struct -{ - uint16_t maxHits; - uint16_t maxSteps; -} RCL_RayConstraints; - -/** - Function used to retrieve some information about cells of the rendered scene. - It should return a characteristic of given square as an integer (e.g. square - height, texture index, ...) - between squares that return different numbers - there is considered to be a collision. - - This function should be as fast as possible as it will typically be called - very often. -*/ -typedef RCL_Unit (*RCL_ArrayFunction)(int16_t x, int16_t y); -/* - TODO: maybe array functions should be replaced by defines of funtion names - like with pixelFunc? Could be more efficient than function pointers. -*/ - -/** - Function that renders a single pixel at the display. It is handed an info - about the pixel it should draw. - - This function should be as fast as possible as it will typically be called - very often. -*/ -typedef void (*RCL_PixelFunction)(RCL_PixelInfo *info); - -typedef void - (*RCL_ColumnFunction)(RCL_HitResult *hits, uint16_t hitCount, uint16_t x, - RCL_Ray ray); - -/** - Simple-interface function to cast a single ray. - - @return The first collision result. -*/ -RCL_HitResult RCL_castRay(RCL_Ray ray, RCL_ArrayFunction arrayFunc); - -/** - Casts a 3D ray in 3D environment with floor and optional ceiling - (ceilingHeightFunc can be 0). This can be useful for hitscan shooting, - visibility checking etc. - - @return normalized ditance (0 to RCL_UNITS_PER_SQUARE) along the ray at which - the environment was hit, RCL_UNITS_PER_SQUARE means nothing was hit -*/ -RCL_Unit RCL_castRay3D( - RCL_Vector2D pos1, RCL_Unit height1, RCL_Vector2D pos2, RCL_Unit height2, - RCL_ArrayFunction floorHeightFunc, RCL_ArrayFunction ceilingHeightFunc, - RCL_RayConstraints constraints); - -/** - Maps a single point in the world to the screen (2D position + depth). -*/ -RCL_PixelInfo RCL_mapToScreen(RCL_Vector2D worldPosition, RCL_Unit height, - RCL_Camera camera); - -/** - Casts a single ray and returns a list of collisions. - - @param ray ray to be cast, if RCL_RECTILINEAR != 0 then the computed hit - distance is divided by the ray direction vector length (to correct - the fish eye effect) - @param arrayFunc function that will be used to determine collisions (hits) - with the ray (squares for which this function returns different values - are considered to have a collision between them), this will typically - be a function returning floor height - @param typeFunc optional (can be 0) function - if provided, it will be used - to mark the hit result with the number returned by this function - (it can be e.g. a texture index) - @param hitResults array in which the hit results will be stored (has to be - preallocated with at space for at least as many hit results as - maxHits specified with the constraints parameter) - @param hitResultsLen in this variable the number of hit results will be - returned - @param constraints specifies constraints for the ray cast -*/ -void RCL_castRayMultiHit(RCL_Ray ray, RCL_ArrayFunction arrayFunc, - RCL_ArrayFunction typeFunc, RCL_HitResult *hitResults, - uint16_t *hitResultsLen, RCL_RayConstraints constraints); - -RCL_Vector2D RCL_angleToDirection(RCL_Unit angle); - -/** -Cos function. - -@param input to cos in RCL_Units (RCL_UNITS_PER_SQUARE = 2 * pi = 360 degrees) -@return RCL_normalized output in RCL_Units (from -RCL_UNITS_PER_SQUARE to - RCL_UNITS_PER_SQUARE) -*/ -RCL_Unit RCL_cos(RCL_Unit input); - -RCL_Unit RCL_sin(RCL_Unit input); - -RCL_Unit RCL_tan(RCL_Unit input); - -RCL_Unit RCL_ctg(RCL_Unit input); - -/// Normalizes given vector to have RCL_UNITS_PER_SQUARE length. -RCL_Vector2D RCL_normalize(RCL_Vector2D v); - -/// Computes a cos of an angle between two vectors. -RCL_Unit RCL_vectorsAngleCos(RCL_Vector2D v1, RCL_Vector2D v2); - -uint16_t RCL_sqrt(RCL_Unit value); -RCL_Unit RCL_dist(RCL_Vector2D p1, RCL_Vector2D p2); -RCL_Unit RCL_len(RCL_Vector2D v); - -/** - Converts an angle in whole degrees to an angle in RCL_Units that this library - uses. -*/ -RCL_Unit RCL_degreesToUnitsAngle(int16_t degrees); - -///< Computes the change in size of an object due to perspective (vertical FOV). -RCL_Unit RCL_perspectiveScaleVertical(RCL_Unit originalSize, RCL_Unit distance); - -RCL_Unit RCL_perspectiveScaleVerticalInverse(RCL_Unit originalSize, - RCL_Unit scaledSize); - -RCL_Unit - RCL_perspectiveScaleHorizontal(RCL_Unit originalSize, RCL_Unit distance); - -RCL_Unit RCL_perspectiveScaleHorizontalInverse(RCL_Unit originalSize, - RCL_Unit scaledSize); - -/** - Casts rays for given camera view and for each hit calls a user provided - function. -*/ -void RCL_castRaysMultiHit(RCL_Camera cam, RCL_ArrayFunction arrayFunc, - RCL_ArrayFunction typeFunction, RCL_ColumnFunction columnFunc, - RCL_RayConstraints constraints); - -/** - Using provided functions, renders a complete complex (multilevel) camera - view. - - This function should render each screen pixel exactly once. - - function rendering summary: - - performance: slower - - accuracy: higher - - wall textures: yes - - different wall heights: yes - - floor/ceiling textures: no - - floor geometry: yes, multilevel - - ceiling geometry: yes (optional), multilevel - - rolling door: no - - camera shearing: yes - - rendering order: left-to-right, not specifically ordered vertically - - @param cam camera whose view to render - @param floorHeightFunc function that returns floor height (in RCL_Units) - @param ceilingHeightFunc same as floorHeightFunc but for ceiling, can also be - 0 (no ceiling will be rendered) - @param typeFunction function that says a type of square (e.g. its texture - index), can be 0 (no type in hit result) - @param pixelFunc callback function to draw a single pixel on screen - @param constraints constraints for each cast ray -*/ -void RCL_renderComplex(RCL_Camera cam, RCL_ArrayFunction floorHeightFunc, - RCL_ArrayFunction ceilingHeightFunc, RCL_ArrayFunction typeFunction, - RCL_RayConstraints constraints); - -/** - Renders given camera view, with help of provided functions. This function is - simpler and faster than RCL_renderComplex(...) and is meant to be rendering - flat levels. - - function rendering summary: - - performance: faster - - accuracy: lower - - wall textures: yes - - different wall heights: yes - - floor/ceiling textures: yes (only floor, you can mirror it for ceiling) - - floor geometry: no (just flat floor, with depth information) - - ceiling geometry: no (just flat ceiling, with depth information) - - rolling door: yes - - camera shearing: no - - rendering order: left-to-right, top-to-bottom - - Additionally this function supports rendering rolling doors. - - This function should render each screen pixel exactly once. - - @param rollFunc function that for given square says its door roll in - RCL_Units (0 = no roll, RCL_UNITS_PER_SQUARE = full roll right, - -RCL_UNITS_PER_SQUARE = full roll left), can be zero (no rolling door, - rendering should also be faster as fewer intersections will be tested) -*/ -void RCL_renderSimple(RCL_Camera cam, RCL_ArrayFunction floorHeightFunc, - RCL_ArrayFunction typeFunc, RCL_ArrayFunction rollFunc, - RCL_RayConstraints constraints); - -/** - Function that moves given camera and makes it collide with walls and - potentially also floor and ceilings. It's meant to help implement player - movement. - - @param camera camera to move - @param planeOffset offset to move the camera in - @param heightOffset height offset to move the camera in - @param floorHeightFunc function used to retrieve the floor height - @param ceilingHeightFunc function for retrieving ceiling height, can be 0 - (camera won't collide with ceiling) - @param computeHeight whether to compute height - if false (0), floor and - ceiling functions won't be used and the camera will - only collide horizontally with walls (good for simpler - game, also faster) - @param force if true, forces to recompute collision even if position doesn't - change -*/ -void RCL_moveCameraWithCollision(RCL_Camera *camera, RCL_Vector2D planeOffset, - RCL_Unit heightOffset, RCL_ArrayFunction floorHeightFunc, - RCL_ArrayFunction ceilingHeightFunc, int8_t computeHeight, int8_t force); - -void RCL_initCamera(RCL_Camera *camera); -void RCL_initRayConstraints(RCL_RayConstraints *constraints); - -//============================================================================= -// privates - -#define _RCL_UNUSED(what) (void)(what); - -// global helper variables, for precomputing stuff etc. -RCL_Camera _RCL_camera; -RCL_Unit _RCL_horizontalDepthStep = 0; -RCL_Unit _RCL_startFloorHeight = 0; -RCL_Unit _RCL_startCeil_Height = 0; -RCL_Unit _RCL_camResYLimit = 0; -RCL_Unit _RCL_middleRow = 0; -RCL_ArrayFunction _RCL_floorFunction = 0; -RCL_ArrayFunction _RCL_ceilFunction = 0; -RCL_Unit _RCL_fHorizontalDepthStart = 0; -RCL_Unit _RCL_cHorizontalDepthStart = 0; -int16_t _RCL_cameraHeightScreen = 0; -RCL_ArrayFunction _RCL_rollFunction = 0; // says door rolling -RCL_Unit *_RCL_floorPixelDistances = 0; -RCL_Unit _RCL_fovCorrectionFactors[2] = {0,0}; //correction for hor/vert fov - -RCL_Unit RCL_clamp(RCL_Unit value, RCL_Unit valueMin, RCL_Unit valueMax) -{ - if (value >= valueMin) - { - if (value <= valueMax) - return value; - else - return valueMax; - } - else - return valueMin; -} - -static inline RCL_Unit RCL_abs(RCL_Unit value) -{ - return value * (((value >= 0) << 1) - 1); -} - -/// Like mod, but behaves differently for negative values. -static inline RCL_Unit RCL_wrap(RCL_Unit value, RCL_Unit mod) -{ - RCL_Unit cmp = value < 0; - return cmp * mod + (value % mod) - cmp; -} - -/// Performs division, rounding down, NOT towards zero. -static inline RCL_Unit RCL_divRoundDown(RCL_Unit value, RCL_Unit divisor) -{ - return value / divisor - ((value >= 0) ? 0 : 1); -} - -// Bhaskara's cosine approximation formula -#define trigHelper(x) (((RCL_Unit) RCL_UNITS_PER_SQUARE) *\ - (RCL_UNITS_PER_SQUARE / 2 * RCL_UNITS_PER_SQUARE / 2 - 4 * (x) * (x)) /\ - (RCL_UNITS_PER_SQUARE / 2 * RCL_UNITS_PER_SQUARE / 2 + (x) * (x))) - -#if RCL_USE_COS_LUT == 1 - - #ifdef RCL_RAYCAST_TINY - const RCL_Unit cosLUT[64] = - { - 16,14,11,6,0,-6,-11,-14,-15,-14,-11,-6,0,6,11,14 - }; - #else - const RCL_Unit cosLUT[64] = - { - 1024,1019,1004,979,946,903,851,791,724,649,568,482,391,297,199,100,0,-100, - -199,-297,-391,-482,-568,-649,-724,-791,-851,-903,-946,-979,-1004,-1019, - -1023,-1019,-1004,-979,-946,-903,-851,-791,-724,-649,-568,-482,-391,-297, - -199,-100,0,100,199,297,391,482,568,649,724,791,851,903,946,979,1004,1019 - }; - #endif - -#elif RCL_USE_COS_LUT == 2 -const RCL_Unit cosLUT[128] = -{ - 1024,1022,1019,1012,1004,993,979,964,946,925,903,878,851,822,791,758,724, - 687,649,609,568,526,482,437,391,344,297,248,199,150,100,50,0,-50,-100,-150, - -199,-248,-297,-344,-391,-437,-482,-526,-568,-609,-649,-687,-724,-758,-791, - -822,-851,-878,-903,-925,-946,-964,-979,-993,-1004,-1012,-1019,-1022,-1023, - -1022,-1019,-1012,-1004,-993,-979,-964,-946,-925,-903,-878,-851,-822,-791, - -758,-724,-687,-649,-609,-568,-526,-482,-437,-391,-344,-297,-248,-199,-150, - -100,-50,0,50,100,150,199,248,297,344,391,437,482,526,568,609,649,687,724, - 758,791,822,851,878,903,925,946,964,979,993,1004,1012,1019,1022 -}; -#endif - -RCL_Unit RCL_cos(RCL_Unit input) -{ - input = RCL_wrap(input,RCL_UNITS_PER_SQUARE); - -#if RCL_USE_COS_LUT == 1 - - #ifdef RCL_RAYCAST_TINY - return cosLUT[input]; - #else - return cosLUT[input / 16]; - #endif - -#elif RCL_USE_COS_LUT == 2 - return cosLUT[input / 8]; -#else - if (input < RCL_UNITS_PER_SQUARE / 4) - return trigHelper(input); - else if (input < RCL_UNITS_PER_SQUARE / 2) - return -1 * trigHelper(RCL_UNITS_PER_SQUARE / 2 - input); - else if (input < 3 * RCL_UNITS_PER_SQUARE / 4) - return -1 * trigHelper(input - RCL_UNITS_PER_SQUARE / 2); - else - return trigHelper(RCL_UNITS_PER_SQUARE - input); -#endif -} - -#undef trigHelper - -RCL_Unit RCL_sin(RCL_Unit input) -{ - return RCL_cos(input - RCL_UNITS_PER_SQUARE / 4); -} - -RCL_Unit RCL_tan(RCL_Unit input) -{ - return (RCL_sin(input) * RCL_UNITS_PER_SQUARE) / RCL_nonZero(RCL_cos(input) -); - - return (RCL_sin(input) * RCL_UNITS_PER_SQUARE) / RCL_nonZero(RCL_cos(input)); -} - -RCL_Unit RCL_ctg(RCL_Unit input) -{ - return (RCL_cos(input) * RCL_UNITS_PER_SQUARE) / RCL_sin(input); -} - -RCL_Vector2D RCL_angleToDirection(RCL_Unit angle) -{ - RCL_Vector2D result; - - result.x = RCL_cos(angle); - result.y = -1 * RCL_sin(angle); - - return result; -} - -uint16_t RCL_sqrt(RCL_Unit value) -{ -#ifdef RCL_RAYCAST_TINY - uint16_t result = 0; - uint16_t a = value; - uint16_t b = 1u << 14; -#else - uint32_t result = 0; - uint32_t a = value; - uint32_t b = 1u << 30; -#endif - - while (b > a) - b >>= 2; - - while (b != 0) - { - if (a >= result + b) - { - a -= result + b; - result = result + 2 * b; - } - - b >>= 2; - result >>= 1; - } - - return result; -} - -RCL_Unit RCL_dist(RCL_Vector2D p1, RCL_Vector2D p2) -{ - RCL_Unit dx = p2.x - p1.x; - RCL_Unit dy = p2.y - p1.y; - -#if RCL_USE_DIST_APPROX == 2 - // octagonal approximation - - dx = RCL_abs(dx); - dy = RCL_abs(dy); - - return dy > dx ? dx / 2 + dy : dy / 2 + dx; -#elif RCL_USE_DIST_APPROX == 1 - // more accurate approximation - - RCL_Unit a, b, result; - - dx = ((dx < 0) * 2 - 1) * dx; - dy = ((dy < 0) * 2 - 1) * dy; - - if (dx < dy) - { - a = dy; - b = dx; - } - else - { - a = dx; - b = dy; - } - - result = a + (44 * b) / 102; - - if (a < (b << 4)) - result -= (5 * a) / 128; - - return result; -#else - dx = dx * dx; - dy = dy * dy; - - return RCL_sqrt((RCL_Unit) (dx + dy)); -#endif -} - -RCL_Unit RCL_len(RCL_Vector2D v) -{ - RCL_Vector2D zero; - zero.x = 0; - zero.y = 0; - - return RCL_dist(zero,v); -} - -static inline int8_t RCL_pointIsLeftOfRay(RCL_Vector2D point, RCL_Ray ray) -{ - RCL_Unit dX = point.x - ray.start.x; - RCL_Unit dY = point.y - ray.start.y; - return (ray.direction.x * dY - ray.direction.y * dX) > 0; - // ^ Z component of cross-product -} - -void RCL_castRayMultiHit(RCL_Ray ray, RCL_ArrayFunction arrayFunc, - RCL_ArrayFunction typeFunc, RCL_HitResult *hitResults, - uint16_t *hitResultsLen, RCL_RayConstraints constraints) -{ - RCL_Vector2D currentPos = ray.start; - RCL_Vector2D currentSquare; - - currentSquare.x = RCL_divRoundDown(ray.start.x,RCL_UNITS_PER_SQUARE); - currentSquare.y = RCL_divRoundDown(ray.start.y,RCL_UNITS_PER_SQUARE); - - *hitResultsLen = 0; - - RCL_Unit squareType = arrayFunc(currentSquare.x,currentSquare.y); - - // DDA variables - RCL_Vector2D nextSideDist; // dist. from start to the next side in given axis - RCL_Vector2D delta; - RCL_Vector2D step; // -1 or 1 for each axis - int8_t stepHorizontal = 0; // whether the last step was hor. or vert. - - nextSideDist.x = 0; - nextSideDist.y = 0; - - RCL_Unit dirVecLengthNorm = RCL_len(ray.direction) * RCL_UNITS_PER_SQUARE; - - delta.x = RCL_abs(dirVecLengthNorm / RCL_nonZero(ray.direction.x)); - delta.y = RCL_abs(dirVecLengthNorm / RCL_nonZero(ray.direction.y)); - - // init DDA - - if (ray.direction.x < 0) - { - step.x = -1; - nextSideDist.x = (RCL_wrap(ray.start.x,RCL_UNITS_PER_SQUARE) * delta.x) / - RCL_UNITS_PER_SQUARE; - } - else - { - step.x = 1; - nextSideDist.x = - ((RCL_wrap(RCL_UNITS_PER_SQUARE - ray.start.x,RCL_UNITS_PER_SQUARE)) * - delta.x) / RCL_UNITS_PER_SQUARE; - } - - if (ray.direction.y < 0) - { - step.y = -1; - nextSideDist.y = (RCL_wrap(ray.start.y,RCL_UNITS_PER_SQUARE) * delta.y) / - RCL_UNITS_PER_SQUARE; - } - else - { - step.y = 1; - nextSideDist.y = - ((RCL_wrap(RCL_UNITS_PER_SQUARE - ray.start.y,RCL_UNITS_PER_SQUARE)) * - delta.y) / RCL_UNITS_PER_SQUARE; - } - - // DDA loop - - #define RECIP_SCALE 65536 - - RCL_Unit rayDirXRecip = RECIP_SCALE / RCL_nonZero(ray.direction.x); - RCL_Unit rayDirYRecip = RECIP_SCALE / RCL_nonZero(ray.direction.y); - // ^ we precompute reciprocals to avoid divisions in the loop - - for (uint16_t i = 0; i < constraints.maxSteps; ++i) - { - RCL_Unit currentType = arrayFunc(currentSquare.x,currentSquare.y); - - if (RCL_unlikely(currentType != squareType)) - { - // collision - - RCL_HitResult h; - - h.arrayValue = currentType; - h.doorRoll = 0; - h.position = currentPos; - h.square = currentSquare; - - if (stepHorizontal) - { - h.position.x = currentSquare.x * RCL_UNITS_PER_SQUARE; - h.direction = 3; - - if (step.x == -1) - { - h.direction = 1; - h.position.x += RCL_UNITS_PER_SQUARE; - } - - RCL_Unit diff = h.position.x - ray.start.x; - - h.position.y = // avoid division by multiplying with reciprocal - ray.start.y + (ray.direction.y * diff * rayDirXRecip) / RECIP_SCALE; - -#if RCL_RECTILINEAR - /* Here we compute the fish eye corrected distance (perpendicular to - the projection plane) as the Euclidean distance (of hit from camera - position) divided by the length of the ray direction vector. This can - be computed without actually computing Euclidean distances as a - hypothenuse A (distance) divided by hypothenuse B (length) is equal to - leg A (distance along principal axis) divided by leg B (length along - the same principal axis). */ - -#define CORRECT(dir1,dir2)\ - RCL_Unit tmp = diff / 4; /* 4 to prevent overflow */ \ - h.distance = ((tmp / 8) != 0) ? /* prevent a bug with small dists */ \ - ((tmp * RCL_UNITS_PER_SQUARE * rayDir ## dir1 ## Recip) / (RECIP_SCALE / 4)):\ - RCL_abs(h.position.dir2 - ray.start.dir2); - - CORRECT(X,y) - -#endif // RCL_RECTILINEAR - } - else - { - h.position.y = currentSquare.y * RCL_UNITS_PER_SQUARE; - h.direction = 2; - - if (step.y == -1) - { - h.direction = 0; - h.position.y += RCL_UNITS_PER_SQUARE; - } - - RCL_Unit diff = h.position.y - ray.start.y; - - h.position.x = - ray.start.x + (ray.direction.x * diff * rayDirYRecip) / RECIP_SCALE; - -#if RCL_RECTILINEAR - - CORRECT(Y,x) // same as above but for different axis - -#undef CORRECT - -#endif // RCL_RECTILINEAR - } - -#if !RCL_RECTILINEAR - h.distance = RCL_dist(h.position,ray.start); -#endif - if (typeFunc != 0) - h.type = typeFunc(currentSquare.x,currentSquare.y); - -#if RCL_COMPUTE_WALL_TEXCOORDS == 1 - switch (h.direction) - { - case 0: h.textureCoord = - RCL_wrap(-1 * h.position.x,RCL_UNITS_PER_SQUARE); break; - - case 1: h.textureCoord = - RCL_wrap(h.position.y,RCL_UNITS_PER_SQUARE); break; - - case 2: h.textureCoord = - RCL_wrap(h.position.x,RCL_UNITS_PER_SQUARE); break; - - case 3: h.textureCoord = - RCL_wrap(-1 * h.position.y,RCL_UNITS_PER_SQUARE); break; - - default: h.textureCoord = 0; break; - } - - if (_RCL_rollFunction != 0) - { - h.doorRoll = _RCL_rollFunction(currentSquare.x,currentSquare.y); - - if (h.direction == 0 || h.direction == 1) - h.doorRoll *= -1; - } - -#else - h.textureCoord = 0; -#endif - - hitResults[*hitResultsLen] = h; - - *hitResultsLen += 1; - - squareType = currentType; - - if (*hitResultsLen >= constraints.maxHits) - break; - } - - // DDA step - - if (nextSideDist.x < nextSideDist.y) - { - nextSideDist.x += delta.x; - currentSquare.x += step.x; - stepHorizontal = 1; - } - else - { - nextSideDist.y += delta.y; - currentSquare.y += step.y; - stepHorizontal = 0; - } - } -} - -RCL_HitResult RCL_castRay(RCL_Ray ray, RCL_ArrayFunction arrayFunc) -{ - RCL_HitResult result; - uint16_t len; - RCL_RayConstraints c; - - c.maxSteps = 1000; - c.maxHits = 1; - - RCL_castRayMultiHit(ray,arrayFunc,0,&result,&len,c); - - if (len == 0) - result.distance = -1; - - return result; -} - -void RCL_castRaysMultiHit(RCL_Camera cam, RCL_ArrayFunction arrayFunc, - RCL_ArrayFunction typeFunction, RCL_ColumnFunction columnFunc, - RCL_RayConstraints constraints) -{ - RCL_Vector2D dir1 = - RCL_angleToDirection(cam.direction - RCL_HORIZONTAL_FOV_HALF); - - RCL_Vector2D dir2 = - RCL_angleToDirection(cam.direction + RCL_HORIZONTAL_FOV_HALF); - - /* We scale the side distances so that the middle one is - RCL_UNITS_PER_SQUARE, which has to be this way. */ - - RCL_Unit cos = RCL_nonZero(RCL_cos(RCL_HORIZONTAL_FOV_HALF)); - - dir1.x = (dir1.x * RCL_UNITS_PER_SQUARE) / cos; - dir1.y = (dir1.y * RCL_UNITS_PER_SQUARE) / cos; - - dir2.x = (dir2.x * RCL_UNITS_PER_SQUARE) / cos; - dir2.y = (dir2.y * RCL_UNITS_PER_SQUARE) / cos; - - RCL_Unit dX = dir2.x - dir1.x; - RCL_Unit dY = dir2.y - dir1.y; - - RCL_HitResult hits[constraints.maxHits]; - uint16_t hitCount; - - RCL_Ray r; - r.start = cam.position; - - RCL_Unit currentDX = 0; - RCL_Unit currentDY = 0; - - for (int16_t i = 0; i < cam.resolution.x; ++i) - { - /* Here by linearly interpolating the direction vector its length changes, - which in result achieves correcting the fish eye effect (computing - perpendicular distance). */ - - r.direction.x = dir1.x + currentDX / cam.resolution.x; - r.direction.y = dir1.y + currentDY / cam.resolution.x; - - RCL_castRayMultiHit(r,arrayFunc,typeFunction,hits,&hitCount,constraints); - - columnFunc(hits,hitCount,i,r); - - currentDX += dX; - currentDY += dY; - } -} - -/** - Helper function that determines intersection with both ceiling and floor. -*/ -RCL_Unit _RCL_floorCeilFunction(int16_t x, int16_t y) -{ - RCL_Unit f = _RCL_floorFunction(x,y); - - if (_RCL_ceilFunction == 0) - return f; - - RCL_Unit c = _RCL_ceilFunction(x,y); - -#ifndef RCL_RAYCAST_TINY - return ((f & 0x0000ffff) << 16) | (c & 0x0000ffff); -#else - return ((f & 0x00ff) << 8) | (c & 0x00ff); -#endif -} - -RCL_Unit _floorHeightNotZeroFunction(int16_t x, int16_t y) -{ - return _RCL_floorFunction(x,y) == 0 ? 0 : - RCL_nonZero((x & 0x00FF) | ((y & 0x00FF) << 8)); - // ^ this makes collisions between all squares - needed for rolling doors -} - -RCL_Unit RCL_adjustDistance(RCL_Unit distance, RCL_Camera *camera, - RCL_Ray *ray) -{ - /* FIXME/TODO: The adjusted (=orthogonal, camera-space) distance could - possibly be computed more efficiently by not computing Euclidean - distance at all, but rather compute the distance of the collision - point from the projection plane (line). */ - - RCL_Unit result = - (distance * - RCL_vectorsAngleCos(RCL_angleToDirection(camera->direction), - ray->direction)) / RCL_UNITS_PER_SQUARE; - - return RCL_nonZero(result); - // ^ prevent division by zero -} - -/// Helper for drawing floor or ceiling. Returns the last drawn pixel position. -static inline int16_t _RCL_drawHorizontalColumn( - RCL_Unit yCurrent, - RCL_Unit yTo, - RCL_Unit limit1, // TODO: int16_t? - RCL_Unit limit2, - RCL_Unit verticalOffset, - int16_t increment, - int8_t computeDepth, - int8_t computeCoords, - int16_t depthIncrementMultiplier, - RCL_Ray *ray, - RCL_PixelInfo *pixelInfo -) -{ - _RCL_UNUSED(ray); - - RCL_Unit depthIncrement; - RCL_Unit dx; - RCL_Unit dy; - - pixelInfo->isWall = 0; - - int16_t limit = RCL_clamp(yTo,limit1,limit2); - - RCL_Unit depth = 0; /* TODO: this is for clamping depth to 0 so that we don't - have negative depths, but we should do it more - elegantly and efficiently */ - - _RCL_UNUSED(depth); - - /* for performance reasons have different version of the critical loop - to be able to branch early */ - #define loop(doDepth,doCoords)\ - {\ - if (doDepth) /*constant condition - compiler should optimize it out*/\ - {\ - depth = pixelInfo->depth + RCL_abs(verticalOffset) *\ - RCL_VERTICAL_DEPTH_MULTIPLY;\ - depthIncrement = depthIncrementMultiplier *\ - _RCL_horizontalDepthStep;\ - }\ - if (doCoords) /*constant condition - compiler should optimize it out*/\ - {\ - dx = pixelInfo->hit.position.x - _RCL_camera.position.x;\ - dy = pixelInfo->hit.position.y - _RCL_camera.position.y;\ - }\ - for (int16_t i = yCurrent + increment;\ - increment == -1 ? i >= limit : i <= limit; /* TODO: is efficient? */\ - i += increment)\ - {\ - pixelInfo->position.y = i;\ - if (doDepth) /*constant condition - compiler should optimize it out*/\ - {\ - depth += depthIncrement;\ - pixelInfo->depth = RCL_zeroClamp(depth); \ - /* ^ int comparison is fast, it is not braching! (= test instr.) */\ - }\ - if (doCoords) /*constant condition - compiler should optimize it out*/\ - {\ - RCL_Unit d = _RCL_floorPixelDistances[i];\ - RCL_Unit d2 = RCL_nonZero(pixelInfo->hit.distance);\ - pixelInfo->texCoords.x =\ - _RCL_camera.position.x + ((d * dx) / d2);\ - pixelInfo->texCoords.y =\ - _RCL_camera.position.y + ((d * dy) / d2);\ - }\ - RCL_PIXEL_FUNCTION(pixelInfo);\ - }\ - } - - if (computeDepth) // branch early - { - if (!computeCoords) - loop(1,0) - else - loop(1,1) - } - else - { - if (!computeCoords) - loop(0,0) - else - loop(1,1) - } - - #undef loop - - return limit; -} - -/// Helper for drawing walls. Returns the last drawn pixel position. -static inline int16_t _RCL_drawWall( - RCL_Unit yCurrent, - RCL_Unit yFrom, - RCL_Unit yTo, - RCL_Unit limit1, // TODO: int16_t? - RCL_Unit limit2, - RCL_Unit height, - int16_t increment, - RCL_PixelInfo *pixelInfo - ) -{ - _RCL_UNUSED(height) - - height = RCL_abs(height); - - pixelInfo->isWall = 1; - - RCL_Unit limit = RCL_clamp(yTo,limit1,limit2); - - RCL_Unit wallLength = RCL_nonZero(RCL_abs(yTo - yFrom - 1)); - - RCL_Unit wallPosition = RCL_abs(yFrom - yCurrent) - increment; - - RCL_Unit heightScaled = height * RCL_TEXTURE_INTERPOLATION_SCALE; - _RCL_UNUSED(heightScaled); - - RCL_Unit coordStepScaled = RCL_COMPUTE_WALL_TEXCOORDS ? -#if RCL_TEXTURE_VERTICAL_STRETCH == 1 - ((RCL_UNITS_PER_SQUARE * RCL_TEXTURE_INTERPOLATION_SCALE) / wallLength) -#else - (heightScaled / wallLength) -#endif - : 0; - - pixelInfo->texCoords.y = RCL_COMPUTE_WALL_TEXCOORDS ? - (wallPosition * coordStepScaled) : 0; - - if (increment < 0) - { - coordStepScaled *= -1; - pixelInfo->texCoords.y = -#if RCL_TEXTURE_VERTICAL_STRETCH == 1 - (RCL_UNITS_PER_SQUARE * RCL_TEXTURE_INTERPOLATION_SCALE) - - pixelInfo->texCoords.y; -#else - heightScaled - pixelInfo->texCoords.y; -#endif - } - else - { - // with floor wall, don't start under 0 - pixelInfo->texCoords.y = RCL_zeroClamp(pixelInfo->texCoords.y); - } - - RCL_Unit textureCoordScaled = pixelInfo->texCoords.y; - - for (RCL_Unit i = yCurrent + increment; - increment == -1 ? i >= limit : i <= limit; // TODO: is efficient? - i += increment) - { - pixelInfo->position.y = i; - -#if RCL_COMPUTE_WALL_TEXCOORDS == 1 - pixelInfo->texCoords.y = - textureCoordScaled / RCL_TEXTURE_INTERPOLATION_SCALE; - - textureCoordScaled += coordStepScaled; -#endif - - RCL_PIXEL_FUNCTION(pixelInfo); - } - - return limit; -} - -/// Fills a RCL_HitResult struct with info for a hit at infinity. -static inline void _RCL_makeInfiniteHit(RCL_HitResult *hit, RCL_Ray *ray) -{ - hit->distance = RCL_UNITS_PER_SQUARE * RCL_UNITS_PER_SQUARE; - /* ^ horizon is at infinity, but we can't use too big infinity - (RCL_INFINITY) because it would overflow in the following mult. */ - hit->position.x = (ray->direction.x * hit->distance) / RCL_UNITS_PER_SQUARE; - hit->position.y = (ray->direction.y * hit->distance) / RCL_UNITS_PER_SQUARE; - - hit->direction = 0; - hit->textureCoord = 0; - hit->arrayValue = 0; - hit->doorRoll = 0; - hit->type = 0; -} - -void _RCL_columnFunctionComplex(RCL_HitResult *hits, uint16_t hitCount, uint16_t x, - RCL_Ray ray) -{ - // last written Y position, can never go backwards - RCL_Unit fPosY = _RCL_camera.resolution.y; - RCL_Unit cPosY = -1; - - // world coordinates (relative to camera height though) - RCL_Unit fZ1World = _RCL_startFloorHeight; - RCL_Unit cZ1World = _RCL_startCeil_Height; - - RCL_PixelInfo p; - p.position.x = x; - p.height = 0; - p.wallHeight = 0; - p.texCoords.x = 0; - p.texCoords.y = 0; - - // we'll be simulatenously drawing the floor and the ceiling now - for (RCL_Unit j = 0; j <= hitCount; ++j) - { // ^ = add extra iteration for horizon plane - int8_t drawingHorizon = j == hitCount; - - RCL_HitResult hit; - RCL_Unit distance = 1; - - RCL_Unit fWallHeight = 0, cWallHeight = 0; - RCL_Unit fZ2World = 0, cZ2World = 0; - RCL_Unit fZ1Screen = 0, cZ1Screen = 0; - RCL_Unit fZ2Screen = 0, cZ2Screen = 0; - - if (!drawingHorizon) - { - hit = hits[j]; - distance = RCL_nonZero(hit.distance); - p.hit = hit; - - fWallHeight = _RCL_floorFunction(hit.square.x,hit.square.y); - fZ2World = fWallHeight - _RCL_camera.height; - fZ1Screen = _RCL_middleRow - RCL_perspectiveScaleVertical( - (fZ1World * _RCL_camera.resolution.y) / - RCL_UNITS_PER_SQUARE,distance); - fZ2Screen = _RCL_middleRow - RCL_perspectiveScaleVertical( - (fZ2World * _RCL_camera.resolution.y) / - RCL_UNITS_PER_SQUARE,distance); - - if (_RCL_ceilFunction != 0) - { - cWallHeight = _RCL_ceilFunction(hit.square.x,hit.square.y); - cZ2World = cWallHeight - _RCL_camera.height; - cZ1Screen = _RCL_middleRow - RCL_perspectiveScaleVertical( - (cZ1World * _RCL_camera.resolution.y) / - RCL_UNITS_PER_SQUARE,distance); - cZ2Screen = _RCL_middleRow - RCL_perspectiveScaleVertical( - (cZ2World * _RCL_camera.resolution.y) / - RCL_UNITS_PER_SQUARE,distance); - } - } - else - { - fZ1Screen = _RCL_middleRow; - cZ1Screen = _RCL_middleRow + 1; - _RCL_makeInfiniteHit(&p.hit,&ray); - } - - RCL_Unit limit; - - p.isWall = 0; - p.isHorizon = drawingHorizon; - - // draw floor until wall - p.isFloor = 1; - p.height = fZ1World + _RCL_camera.height; - p.wallHeight = 0; - -#if RCL_COMPUTE_FLOOR_DEPTH == 1 - p.depth = (_RCL_fHorizontalDepthStart - fPosY) * _RCL_horizontalDepthStep; -#else - p.depth = 0; -#endif - - limit = _RCL_drawHorizontalColumn(fPosY,fZ1Screen,cPosY + 1, - _RCL_camera.resolution.y,fZ1World,-1,RCL_COMPUTE_FLOOR_DEPTH, - // ^ purposfully allow outside screen bounds - RCL_COMPUTE_FLOOR_TEXCOORDS && p.height == RCL_FLOOR_TEXCOORDS_HEIGHT, - 1,&ray,&p); - - if (fPosY > limit) - fPosY = limit; - - if (_RCL_ceilFunction != 0 || drawingHorizon) - { - // draw ceiling until wall - p.isFloor = 0; - p.height = cZ1World + _RCL_camera.height; - -#if RCL_COMPUTE_CEILING_DEPTH == 1 - p.depth = (cPosY - _RCL_cHorizontalDepthStart) * - _RCL_horizontalDepthStep; -#endif - - limit = _RCL_drawHorizontalColumn(cPosY,cZ1Screen, - -1,fPosY - 1,cZ1World,1,RCL_COMPUTE_CEILING_DEPTH,0,1,&ray,&p); - // ^ purposfully allow outside screen bounds here - - if (cPosY < limit) - cPosY = limit; - } - - if (!drawingHorizon) // don't draw walls for horizon plane - { - p.isWall = 1; - p.depth = distance; - p.isFloor = 1; - p.texCoords.x = hit.textureCoord; - p.height = fZ1World + _RCL_camera.height; - p.wallHeight = fWallHeight; - - // draw floor wall - - if (fPosY > 0) // still pixels left? - { - p.isFloor = 1; - - limit = _RCL_drawWall(fPosY,fZ1Screen,fZ2Screen,cPosY + 1, - _RCL_camera.resolution.y, - // ^ purposfully allow outside screen bounds here -#if RCL_TEXTURE_VERTICAL_STRETCH == 1 - RCL_UNITS_PER_SQUARE -#else - fZ2World - fZ1World -#endif - ,-1,&p); - - - if (fPosY > limit) - fPosY = limit; - - fZ1World = fZ2World; // for the next iteration - } // ^ purposfully allow outside screen bounds here - - // draw ceiling wall - - if (_RCL_ceilFunction != 0 && cPosY < _RCL_camResYLimit) // pixels left? - { - p.isFloor = 0; - p.height = cZ1World + _RCL_camera.height; - p.wallHeight = cWallHeight; - - limit = _RCL_drawWall(cPosY,cZ1Screen,cZ2Screen, - -1,fPosY - 1, - // ^ puposfully allow outside screen bounds here -#if RCL_TEXTURE_VERTICAL_STRETCH == 1 - RCL_UNITS_PER_SQUARE -#else - cZ1World - cZ2World -#endif - ,1,&p); - - if (cPosY < limit) - cPosY = limit; - - cZ1World = cZ2World; // for the next iteration - } // ^ puposfully allow outside screen bounds here - } - } -} - -void _RCL_columnFunctionSimple(RCL_HitResult *hits, uint16_t hitCount, - uint16_t x, RCL_Ray ray) -{ - RCL_Unit y = 0; - RCL_Unit wallHeightScreen = 0; - RCL_Unit wallStart = _RCL_middleRow; - - RCL_Unit dist = 1; - - RCL_PixelInfo p; - p.position.x = x; - p.wallHeight = RCL_UNITS_PER_SQUARE; - - if (hitCount > 0) - { - RCL_HitResult hit = hits[0]; - - uint8_t goOn = 1; - - if (_RCL_rollFunction != 0 && RCL_COMPUTE_WALL_TEXCOORDS == 1) - { - if (hit.arrayValue == 0) - { - // standing inside door square, looking out => move to the next hit - - if (hitCount > 1) - hit = hits[1]; - else - goOn = 0; - } - else - { - // normal hit, check the door roll - - RCL_Unit texCoordMod = hit.textureCoord % RCL_UNITS_PER_SQUARE; - - int8_t unrolled = hit.doorRoll >= 0 ? - (hit.doorRoll > texCoordMod) : - (texCoordMod > RCL_UNITS_PER_SQUARE + hit.doorRoll); - - if (unrolled) - { - goOn = 0; - - if (hitCount > 1) /* should probably always be true (hit on square - exit) */ - { - if (hit.direction % 2 != hits[1].direction % 2) - { - // hit on the inner side - hit = hits[1]; - goOn = 1; - } - else if (hitCount > 2) - { - // hit on the opposite side - hit = hits[2]; - goOn = 1; - } - } - } - } - } - - p.hit = hit; - - if (goOn) - { - dist = hit.distance; - - RCL_Unit wallHeightWorld = _RCL_floorFunction(hit.square.x,hit.square.y); - - if (wallHeightWorld < 0) - { - /* We can't just do wallHeightWorld = max(0,wallHeightWorld) because - we would be processing an actual hit with height 0, which shouldn't - ever happen, so we assign some arbitrary height. */ - - wallHeightWorld = RCL_UNITS_PER_SQUARE; - } - - RCL_Unit worldPointTop = wallHeightWorld - _RCL_camera.height; - RCL_Unit worldPointBottom = -1 * _RCL_camera.height; - - wallStart = _RCL_middleRow - - (RCL_perspectiveScaleVertical(worldPointTop,dist) - * _RCL_camera.resolution.y) / RCL_UNITS_PER_SQUARE; - - int16_t wallEnd = _RCL_middleRow - - (RCL_perspectiveScaleVertical(worldPointBottom,dist) - * _RCL_camera.resolution.y) / RCL_UNITS_PER_SQUARE; - - wallHeightScreen = wallEnd - wallStart; - - if (wallHeightScreen <= 0) // can happen because of rounding errors - wallHeightScreen = 1; - } - } - else - { - _RCL_makeInfiniteHit(&p.hit,&ray); - } - - // draw ceiling - - p.isWall = 0; - p.isFloor = 0; - p.isHorizon = 1; - p.depth = 1; - p.height = RCL_UNITS_PER_SQUARE; - - y = _RCL_drawHorizontalColumn(-1,wallStart,-1,_RCL_middleRow,_RCL_camera.height,1, - RCL_COMPUTE_CEILING_DEPTH,0,1,&ray,&p); - - // draw wall - - p.isWall = 1; - p.isFloor = 1; - p.depth = dist; - p.height = 0; - -#if RCL_ROLL_TEXTURE_COORDS == 1 && RCL_COMPUTE_WALL_TEXCOORDS == 1 - p.hit.textureCoord -= p.hit.doorRoll; -#endif - - p.texCoords.x = p.hit.textureCoord; - p.texCoords.y = 0; - - RCL_Unit limit = _RCL_drawWall(y,wallStart,wallStart + wallHeightScreen - 1, - -1,_RCL_camResYLimit,p.hit.arrayValue,1,&p); - - y = RCL_max(y,limit); // take max, in case no wall was drawn - y = RCL_max(y,wallStart); - - // draw floor - - p.isWall = 0; - -#if RCL_COMPUTE_FLOOR_DEPTH == 1 - p.depth = (_RCL_camera.resolution.y - y) * _RCL_horizontalDepthStep + 1; -#endif - - _RCL_drawHorizontalColumn(y,_RCL_camResYLimit,-1,_RCL_camResYLimit, - _RCL_camera.height,1,RCL_COMPUTE_FLOOR_DEPTH,RCL_COMPUTE_FLOOR_TEXCOORDS, - -1,&ray,&p); -} - -/** - Precomputes a distance from camera to the floor at each screen row into an - array (must be preallocated with sufficient (camera.resolution.y) length). -*/ -static inline void _RCL_precomputeFloorDistances(RCL_Camera camera, - RCL_Unit *dest, uint16_t startIndex) -{ - RCL_Unit camHeightScreenSize = - (camera.height * camera.resolution.y) / RCL_UNITS_PER_SQUARE; - - for (uint16_t i = startIndex; i < camera.resolution.y; ++i) - dest[i] = RCL_perspectiveScaleVerticalInverse(camHeightScreenSize, - RCL_abs(i - _RCL_middleRow)); -} - -void RCL_renderComplex(RCL_Camera cam, RCL_ArrayFunction floorHeightFunc, - RCL_ArrayFunction ceilingHeightFunc, RCL_ArrayFunction typeFunction, - RCL_RayConstraints constraints) -{ - _RCL_floorFunction = floorHeightFunc; - _RCL_ceilFunction = ceilingHeightFunc; - _RCL_camera = cam; - _RCL_camResYLimit = cam.resolution.y - 1; - - uint16_t halfResY = cam.resolution.y / 2; - - _RCL_middleRow = halfResY + cam.shear; - - _RCL_fHorizontalDepthStart = _RCL_middleRow + halfResY; - _RCL_cHorizontalDepthStart = _RCL_middleRow - halfResY; - - _RCL_startFloorHeight = floorHeightFunc( - RCL_divRoundDown(cam.position.x,RCL_UNITS_PER_SQUARE), - RCL_divRoundDown(cam.position.y,RCL_UNITS_PER_SQUARE)) -1 * cam.height; - - _RCL_startCeil_Height = - ceilingHeightFunc != 0 ? - ceilingHeightFunc( - RCL_divRoundDown(cam.position.x,RCL_UNITS_PER_SQUARE), - RCL_divRoundDown(cam.position.y,RCL_UNITS_PER_SQUARE)) -1 * cam.height - : RCL_INFINITY; - - _RCL_horizontalDepthStep = RCL_HORIZON_DEPTH / cam.resolution.y; - -#if RCL_COMPUTE_FLOOR_TEXCOORDS == 1 - RCL_Unit floorPixelDistances[cam.resolution.y]; - _RCL_precomputeFloorDistances(cam,floorPixelDistances,0); - _RCL_floorPixelDistances = floorPixelDistances; // pass to column function -#endif - - RCL_castRaysMultiHit(cam,_RCL_floorCeilFunction,typeFunction, - _RCL_columnFunctionComplex,constraints); -} - -void RCL_renderSimple(RCL_Camera cam, RCL_ArrayFunction floorHeightFunc, - RCL_ArrayFunction typeFunc, RCL_ArrayFunction rollFunc, - RCL_RayConstraints constraints) -{ - _RCL_floorFunction = floorHeightFunc; - _RCL_camera = cam; - _RCL_camResYLimit = cam.resolution.y - 1; - _RCL_middleRow = cam.resolution.y / 2; - _RCL_rollFunction = rollFunc; - - _RCL_cameraHeightScreen = - (_RCL_camera.resolution.y * (_RCL_camera.height - RCL_UNITS_PER_SQUARE)) / - RCL_UNITS_PER_SQUARE; - - _RCL_horizontalDepthStep = RCL_HORIZON_DEPTH / cam.resolution.y; - - constraints.maxHits = - _RCL_rollFunction == 0 ? - 1 : // no door => 1 hit is enough - 3; // for correctly rendering rolling doors we'll need 3 hits (NOT 2) - -#if RCL_COMPUTE_FLOOR_TEXCOORDS == 1 - RCL_Unit floorPixelDistances[cam.resolution.y]; - _RCL_precomputeFloorDistances(cam,floorPixelDistances,_RCL_middleRow); - _RCL_floorPixelDistances = floorPixelDistances; // pass to column function -#endif - - RCL_castRaysMultiHit(cam,_floorHeightNotZeroFunction,typeFunc, - _RCL_columnFunctionSimple, constraints); - -#if RCL_COMPUTE_FLOOR_TEXCOORDS == 1 - _RCL_floorPixelDistances = 0; -#endif -} - -RCL_Vector2D RCL_normalize(RCL_Vector2D v) -{ - RCL_Vector2D result; - RCL_Unit l = RCL_len(v); - l = RCL_nonZero(l); - - result.x = (v.x * RCL_UNITS_PER_SQUARE) / l; - result.y = (v.y * RCL_UNITS_PER_SQUARE) / l; - - return result; -} - -RCL_Unit RCL_vectorsAngleCos(RCL_Vector2D v1, RCL_Vector2D v2) -{ - v1 = RCL_normalize(v1); - v2 = RCL_normalize(v2); - - return (v1.x * v2.x + v1.y * v2.y) / RCL_UNITS_PER_SQUARE; -} - - -RCL_PixelInfo RCL_mapToScreen(RCL_Vector2D worldPosition, RCL_Unit height, - RCL_Camera camera) -{ - RCL_PixelInfo result; - - RCL_Vector2D toPoint; - - toPoint.x = worldPosition.x - camera.position.x; - toPoint.y = worldPosition.y - camera.position.y; - - RCL_Unit middleColumn = camera.resolution.x / 2; - - // rotate the point to camera space (y left/right, x forw/backw) - - RCL_Unit cos = RCL_cos(camera.direction); - RCL_Unit sin = RCL_sin(camera.direction); - - RCL_Unit tmp = toPoint.x; - - toPoint.x = (toPoint.x * cos - toPoint.y * sin) / RCL_UNITS_PER_SQUARE; - toPoint.y = (tmp * sin + toPoint.y * cos) / RCL_UNITS_PER_SQUARE; - - result.depth = toPoint.x; - - result.position.x = middleColumn - - (RCL_perspectiveScaleHorizontal(toPoint.y,result.depth) * middleColumn) / - RCL_UNITS_PER_SQUARE; - - result.position.y = - (RCL_perspectiveScaleVertical(height - camera.height,result.depth) - * camera.resolution.y) / RCL_UNITS_PER_SQUARE; - - result.position.y = camera.resolution.y / 2 - result.position.y + camera.shear; - - return result; -} - -RCL_Unit RCL_degreesToUnitsAngle(int16_t degrees) -{ - return (degrees * RCL_UNITS_PER_SQUARE) / 360; -} - -/** - Ugly temporary hack to solve mapping to screen. This function computes - (approximately, usin a table) a divisor needed for FOV correction. -*/ -RCL_Unit _RCL_fovCorrectionFactor(RCL_Unit fov) -{ - uint16_t table[9] = - {1,208,408,692,1024,1540,2304,5376,30000}; - - fov = RCL_min(RCL_UNITS_PER_SQUARE / 2 - 1,fov); - - uint8_t index = fov / 64; - uint32_t t = ((fov - index * 64) * RCL_UNITS_PER_SQUARE) / 64; - uint32_t v1 = table[index]; - uint32_t v2 = table[index + 1]; - - return v1 + ((v2 - v1) * t) / RCL_UNITS_PER_SQUARE; -} - -RCL_Unit RCL_perspectiveScaleVertical(RCL_Unit originalSize, RCL_Unit distance) -{ - if (_RCL_fovCorrectionFactors[1] == 0) - _RCL_fovCorrectionFactors[1] = _RCL_fovCorrectionFactor(RCL_VERTICAL_FOV); - - return distance != 0 ? ((originalSize * RCL_UNITS_PER_SQUARE) / - RCL_nonZero((_RCL_fovCorrectionFactors[1] * distance) / RCL_UNITS_PER_SQUARE) - ) : 0; -} - -RCL_Unit RCL_perspectiveScaleVerticalInverse(RCL_Unit originalSize, - RCL_Unit scaledSize) -{ - if (_RCL_fovCorrectionFactors[1] == 0) - _RCL_fovCorrectionFactors[1] = _RCL_fovCorrectionFactor(RCL_VERTICAL_FOV); - - return scaledSize != 0 ? - - ((originalSize * RCL_UNITS_PER_SQUARE) / - RCL_nonZero((_RCL_fovCorrectionFactors[1] * scaledSize) - / RCL_UNITS_PER_SQUARE)) : RCL_INFINITY; -} - -RCL_Unit - RCL_perspectiveScaleHorizontal(RCL_Unit originalSize, RCL_Unit distance) -{ - if (_RCL_fovCorrectionFactors[0] == 0) - _RCL_fovCorrectionFactors[0] = _RCL_fovCorrectionFactor(RCL_HORIZONTAL_FOV); - - return distance != 0 ? - ((originalSize * RCL_UNITS_PER_SQUARE) / - RCL_nonZero((_RCL_fovCorrectionFactors[0] * distance) / RCL_UNITS_PER_SQUARE) - ) : 0; -} - -RCL_Unit RCL_perspectiveScaleHorizontalInverse(RCL_Unit originalSize, - RCL_Unit scaledSize) -{ - // TODO: probably doesn't work - - return scaledSize != 0 ? - (originalSize * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2) / - ((RCL_HORIZONTAL_FOV_TAN * 2 * scaledSize) / RCL_UNITS_PER_SQUARE) - : RCL_INFINITY; -} - -RCL_Unit RCL_castRay3D( - RCL_Vector2D pos1, RCL_Unit height1, RCL_Vector2D pos2, RCL_Unit height2, - RCL_ArrayFunction floorHeightFunc, RCL_ArrayFunction ceilingHeightFunc, - RCL_RayConstraints constraints) -{ - RCL_HitResult hits[constraints.maxHits]; - uint16_t numHits; - - RCL_Ray ray; - - ray.start = pos1; - - RCL_Unit distance; - - ray.direction.x = pos2.x - pos1.x; - ray.direction.y = pos2.y - pos1.y; - - distance = RCL_len(ray.direction); - - ray.direction = RCL_normalize(ray.direction); - - RCL_Unit heightDiff = height2 - height1; - - RCL_castRayMultiHit(ray,floorHeightFunc,0,hits,&numHits,constraints); - - RCL_Unit result = RCL_UNITS_PER_SQUARE; - - int16_t squareX = RCL_divRoundDown(pos1.x,RCL_UNITS_PER_SQUARE); - int16_t squareY = RCL_divRoundDown(pos1.y,RCL_UNITS_PER_SQUARE); - - RCL_Unit startHeight = floorHeightFunc(squareX,squareY); - - #define checkHits(comp,res) \ - { \ - RCL_Unit currentHeight = startHeight; \ - for (uint16_t i = 0; i < numHits; ++i) \ - { \ - if (hits[i].distance > distance) \ - break;\ - RCL_Unit h = hits[i].arrayValue; \ - if ((currentHeight comp h ? currentHeight : h) \ - comp (height1 + (hits[i].distance * heightDiff) / distance)) \ - { \ - res = (hits[i].distance * RCL_UNITS_PER_SQUARE) / distance; \ - break; \ - } \ - currentHeight = h; \ - } \ - } - - checkHits(>,result) - - if (ceilingHeightFunc != 0) - { - RCL_Unit result2 = RCL_UNITS_PER_SQUARE; - - startHeight = ceilingHeightFunc(squareX,squareY); - - RCL_castRayMultiHit(ray,ceilingHeightFunc,0,hits,&numHits,constraints); - - checkHits(<,result2) - - if (result2 < result) - result = result2; - } - - #undef checkHits - - return result; -} - -void RCL_moveCameraWithCollision(RCL_Camera *camera, RCL_Vector2D planeOffset, - RCL_Unit heightOffset, RCL_ArrayFunction floorHeightFunc, - RCL_ArrayFunction ceilingHeightFunc, int8_t computeHeight, int8_t force) -{ - int8_t movesInPlane = planeOffset.x != 0 || planeOffset.y != 0; - - if (movesInPlane || force) - { - int16_t xSquareNew, ySquareNew; - - RCL_Vector2D corner; // BBox corner in the movement direction - RCL_Vector2D cornerNew; - - int16_t xDir = planeOffset.x > 0 ? 1 : -1; - int16_t yDir = planeOffset.y > 0 ? 1 : -1; - - corner.x = camera->position.x + xDir * RCL_CAMERA_COLL_RADIUS; - corner.y = camera->position.y + yDir * RCL_CAMERA_COLL_RADIUS; - - int16_t xSquare = RCL_divRoundDown(corner.x,RCL_UNITS_PER_SQUARE); - int16_t ySquare = RCL_divRoundDown(corner.y,RCL_UNITS_PER_SQUARE); - - cornerNew.x = corner.x + planeOffset.x; - cornerNew.y = corner.y + planeOffset.y; - - xSquareNew = RCL_divRoundDown(cornerNew.x,RCL_UNITS_PER_SQUARE); - ySquareNew = RCL_divRoundDown(cornerNew.y,RCL_UNITS_PER_SQUARE); - - RCL_Unit bottomLimit = -1 * RCL_INFINITY; - RCL_Unit topLimit = RCL_INFINITY; - - RCL_Unit currCeilHeight = RCL_INFINITY; - - if (computeHeight) - { - bottomLimit = camera->height - RCL_CAMERA_COLL_HEIGHT_BELOW + - RCL_CAMERA_COLL_STEP_HEIGHT; - - topLimit = camera->height + RCL_CAMERA_COLL_HEIGHT_ABOVE; - - if (ceilingHeightFunc != 0) - currCeilHeight = ceilingHeightFunc(xSquare,ySquare); - } - - // checks a single square for collision against the camera - #define collCheck(dir,s1,s2)\ - if (computeHeight)\ - {\ - RCL_Unit height = floorHeightFunc(s1,s2);\ - if (height > bottomLimit || \ - currCeilHeight - height < \ - RCL_CAMERA_COLL_HEIGHT_BELOW + RCL_CAMERA_COLL_HEIGHT_ABOVE)\ - dir##Collides = 1;\ - else if (ceilingHeightFunc != 0)\ - {\ - RCL_Unit height2 = ceilingHeightFunc(s1,s2);\ - if ((height2 < topLimit) || ((height2 - height) < \ - (RCL_CAMERA_COLL_HEIGHT_ABOVE + RCL_CAMERA_COLL_HEIGHT_BELOW)))\ - dir##Collides = 1;\ - }\ - }\ - else\ - dir##Collides = floorHeightFunc(s1,s2) > RCL_CAMERA_COLL_STEP_HEIGHT; - - // check collision against non-diagonal square - #define collCheckOrtho(dir,dir2,s1,s2,x)\ - if (dir##SquareNew != dir##Square)\ - {\ - collCheck(dir,s1,s2)\ - }\ - if (!dir##Collides)\ - { /* now also check for coll on the neighbouring square */ \ - int16_t dir2##Square2 = RCL_divRoundDown(corner.dir2 - dir2##Dir *\ - RCL_CAMERA_COLL_RADIUS * 2,RCL_UNITS_PER_SQUARE);\ - if (dir2##Square2 != dir2##Square)\ - {\ - if (x)\ - collCheck(dir,dir##SquareNew,dir2##Square2)\ - else\ - collCheck(dir,dir2##Square2,dir##SquareNew)\ - }\ - } - - int8_t xCollides = 0; - collCheckOrtho(x,y,xSquareNew,ySquare,1) - - int8_t yCollides = 0; - collCheckOrtho(y,x,xSquare,ySquareNew,0) - - if (xCollides || yCollides) - { - if (movesInPlane) - { - #define collHandle(dir)\ - if (dir##Collides)\ - cornerNew.dir = (dir##Square) * RCL_UNITS_PER_SQUARE +\ - RCL_UNITS_PER_SQUARE / 2 + dir##Dir * (RCL_UNITS_PER_SQUARE / 2) -\ - dir##Dir;\ - - collHandle(x) - collHandle(y) - - #undef collHandle - } - else - { - /* Player collides without moving in the plane; this can happen e.g. on - elevators due to vertical only movement. This code can get executed - when force == 1. */ - - RCL_Vector2D squarePos; - RCL_Vector2D newPos; - - squarePos.x = xSquare * RCL_UNITS_PER_SQUARE; - squarePos.y = ySquare * RCL_UNITS_PER_SQUARE; - - newPos.x = - RCL_max(squarePos.x + RCL_CAMERA_COLL_RADIUS + 1, - RCL_min(squarePos.x + RCL_UNITS_PER_SQUARE - RCL_CAMERA_COLL_RADIUS - 1, - camera->position.x)); - - newPos.y = - RCL_max(squarePos.y + RCL_CAMERA_COLL_RADIUS + 1, - RCL_min(squarePos.y + RCL_UNITS_PER_SQUARE - RCL_CAMERA_COLL_RADIUS - 1, - camera->position.y)); - - cornerNew.x = corner.x + (newPos.x - camera->position.x); - cornerNew.y = corner.y + (newPos.y - camera->position.y); - } - } - else - { - /* If no non-diagonal collision is detected, a diagonal/corner collision - can still happen, check it here. */ - - if (xSquare != xSquareNew && ySquare != ySquareNew) - { - int8_t xyCollides = 0; - collCheck(xy,xSquareNew,ySquareNew) - - if (xyCollides) - { - // normally should slide, but let's KISS and simply stop any movement - cornerNew = corner; - } - } - } - - #undef collCheck - - camera->position.x = cornerNew.x - xDir * RCL_CAMERA_COLL_RADIUS; - camera->position.y = cornerNew.y - yDir * RCL_CAMERA_COLL_RADIUS; - } - - if (computeHeight && (movesInPlane || (heightOffset != 0) || force)) - { - camera->height += heightOffset; - - int16_t xSquare1 = RCL_divRoundDown(camera->position.x - - RCL_CAMERA_COLL_RADIUS,RCL_UNITS_PER_SQUARE); - - int16_t xSquare2 = RCL_divRoundDown(camera->position.x + - RCL_CAMERA_COLL_RADIUS,RCL_UNITS_PER_SQUARE); - - int16_t ySquare1 = RCL_divRoundDown(camera->position.y - - RCL_CAMERA_COLL_RADIUS,RCL_UNITS_PER_SQUARE); - - int16_t ySquare2 = RCL_divRoundDown(camera->position.y + - RCL_CAMERA_COLL_RADIUS,RCL_UNITS_PER_SQUARE); - - RCL_Unit bottomLimit = floorHeightFunc(xSquare1,ySquare1); - RCL_Unit topLimit = ceilingHeightFunc != 0 ? - ceilingHeightFunc(xSquare1,ySquare1) : RCL_INFINITY; - - RCL_Unit height; - - #define checkSquares(s1,s2)\ - {\ - height = floorHeightFunc(xSquare##s1,ySquare##s2);\ - bottomLimit = RCL_max(bottomLimit,height);\ - height = ceilingHeightFunc != 0 ?\ - ceilingHeightFunc(xSquare##s1,ySquare##s2) : RCL_INFINITY;\ - topLimit = RCL_min(topLimit,height);\ - } - - if (xSquare2 != xSquare1) - checkSquares(2,1) - - if (ySquare2 != ySquare1) - checkSquares(1,2) - - if (xSquare2 != xSquare1 && ySquare2 != ySquare1) - checkSquares(2,2) - - camera->height = RCL_clamp(camera->height, - bottomLimit + RCL_CAMERA_COLL_HEIGHT_BELOW, - topLimit - RCL_CAMERA_COLL_HEIGHT_ABOVE); - - #undef checkSquares - } -} - -void RCL_initCamera(RCL_Camera *camera) -{ - camera->position.x = 0; - camera->position.y = 0; - camera->direction = 0; - camera->resolution.x = 20; - camera->resolution.y = 15; - camera->shear = 0; - camera->height = RCL_UNITS_PER_SQUARE; -} - -void RCL_initRayConstraints(RCL_RayConstraints *constraints) -{ - constraints->maxHits = 1; - constraints->maxSteps = 20; -} - -#endif - diff --git a/main_gbmeta/settings.h b/main_gbmeta/settings.h deleted file mode 100644 index 83ea8d6..0000000 --- a/main_gbmeta/settings.h +++ /dev/null @@ -1,447 +0,0 @@ -/** - @file settings.h - - This file contains settings (or setting hints) for the game. Values here can - fine tune performance vs quality and personalize the final compiled game. Some - of these settings may be overriden by the specific platform used according to - its limitations. You are advised to NOT change value in this file directly, - but rather predefine them somewhere before this file gets included, e.g. in - you personal settings file. - - by Miloslav Ciz (drummyfish), 2019 - - Released under CC0 1.0 (https://creativecommons.org/publicdomain/zero/1.0/) - plus a waiver of all other intellectual property. The goal of this work is - be and remain completely in the public domain forever, available for any use - whatsoever. -*/ - -#ifndef _SFG_SETTINGS_H -#define _SFG_SETTINGS_H - -/** - Time multiplier in SFG_Units (1.0 == 1024). This can be used to slow down or - speed up the game. Note that this also changes the rendering FPS accordingly - (e.g. half FPS at half speed), so if you want to keep the FPS, divide it by - the multiplier value. -*/ -#ifndef SFG_TIME_MULTIPLIER - #define SFG_TIME_MULTIPLIER 1024 -#endif - -/** - Target FPS (frames per second). This sets the game logic FPS and will try to - render at the same rate. If such fast rendering can't be achieved, frames will - be droped, but the game logic will still be forced to run at this speed, so - the game may actually become slowed down if FPS is set too high. Too high or - too low FPS can also negatively affect game speeds which are computed as - integers and rounding errors can occur soon, so don't set this to extreme - values (try to keep between 20 to 100). FPS also determines the game - simulation step length, so different FPS values may result in very slight - differences in game behavior (not noticeable but affecting demos etc.). -*/ -#ifndef SFG_FPS - #define SFG_FPS 60 -#endif - -/** - On platforms with mouse this sets its horizontal sensitivity. 128 means 1 - RCL_Unit per mouse pixel travelled. -*/ -#ifndef SFG_MOUSE_SENSITIVITY_HORIZONTAL - #define SFG_MOUSE_SENSITIVITY_HORIZONTAL 32 -#endif - -/** - Like SFG_MOUSE_SENSITIVITY_HORIZONTAL but for vertical look. 128 means 1 - shear pixel per mouse pixel travelled. -*/ -#ifndef SFG_MOUSE_SENSITIVITY_VERTICAL - #define SFG_MOUSE_SENSITIVITY_VERTICAL 64 -#endif - -/** - Width of the screen in pixels. Set this to ACTUAL resolution. If you want the - game to run at smaller resolution (with bigger pixels), do his using - SFG_RESOLUTION_SCALEDOWN; -*/ -#ifndef SFG_SCREEN_RESOLUTION_X - #define SFG_SCREEN_RESOLUTION_X 800 -#endif - -/** - Height of the screen in pixels. Set this to ACTUAL resolution. If you want the - game to run at smaller resolution (with bigger pixels), do his using - SFG_RESOLUTION_SCALEDOWN; -*/ -#ifndef SFG_SCREEN_RESOLUTION_Y - #define SFG_SCREEN_RESOLUTION_Y 600 -#endif - -/** - How quickly player turns left/right, in degrees per second. -*/ -#ifndef SFG_PLAYER_TURN_SPEED - #define SFG_PLAYER_TURN_SPEED 180 -#endif - -/** - Horizontal FOV (field of vision) in RCL_Units (1024 means 360 degrees). -*/ - -#ifndef SFG_FOV_HORIZONTAL - #define SFG_FOV_HORIZONTAL 256 -#endif - -/** - Like SFG_FOV_HORIZONTAL but for vertical angle. -*/ -#ifndef SFG_FOV_VERTICAL - #define SFG_FOV_VERTICAL 330 -#endif - -/** - Distance, in RCL_Units, to which textures will be drawn. Textures behind this - distance will be replaced by an average constant color, which maybe can help - performance and also serves as an antialiasim (2 level MIP map). Value 0 turns - texturing completely off, which is much faster than having just a low value, - values >= 65535 activate texturing completely, which can be a little faster - than setting having a high value lower than this limit. -*/ -#ifndef SFG_TEXTURE_DISTANCE - #define SFG_TEXTURE_DISTANCE 100000 -#endif - -/** - How many times the screen resolution will be divided (how many times a game - pixel will be bigger than the screen pixel). -*/ -#ifndef SFG_RESOLUTION_SCALEDOWN - #define SFG_RESOLUTION_SCALEDOWN 1 -#endif - -/** - Multiplier, in RCL_Units (1024 == 1.0), of the damager player takes. This can - be used to balance difficulty. -*/ -#ifndef SFG_PLAYER_DAMAGE_MULTIPLIER - #define SFG_PLAYER_DAMAGE_MULTIPLIER 512 -#endif - -/** - Hint as to whether run in fullscreen, if the platform allows it. -*/ -#ifndef SFG_FULLSCREEN - #define SFG_FULLSCREEN 0 -#endif - -/** - Whether shadows (fog) should be dithered, i.e. more smooth (needs a bit more - CPU performance and memory). -*/ -#ifndef SFG_DITHERED_SHADOW - #define SFG_DITHERED_SHADOW 0 -#endif - -/** - Depth step (in RCL_Units) after which fog diminishes a color by one value - point. For performance reasons this number should be kept a power of two! -*/ -#ifndef SFG_FOG_DIMINISH_STEP - #define SFG_FOG_DIMINISH_STEP 2048 -#endif - -/** - Maximum number of squares that will be traversed by any cast ray. Smaller - number is faster but can cause visual artifacts. -*/ -#ifndef SFG_RAYCASTING_MAX_STEPS - #define SFG_RAYCASTING_MAX_STEPS 30 -#endif - -/** - Maximum number of hits any cast ray will register. Smaller number is faster - but can cause visual artifacts. -*/ -#ifndef SFG_RAYCASTING_MAX_HITS - #define SFG_RAYCASTING_MAX_HITS 10 -#endif - -/** - How many times rendering should be subsampled horizontally. Bigger number - can significantly improve performance (by casting fewer rays), but can look - a little worse. This number should be a divisor of SFG_SCREEN_RESOLUTION_X! -*/ -#ifndef SFG_RAYCASTING_SUBSAMPLE - #define SFG_RAYCASTING_SUBSAMPLE 1 -#endif - -/** - Enables or disables fog (darkness) due to distance. Recommended to keep on - for good look, but can be turned off for performance. -*/ -#ifndef SFG_ENABLE_FOG - #define SFG_ENABLE_FOG 1 -#endif - -/** - Says whether sprites should diminish in fog. This takes more performance but - looks better. -*/ -#ifndef SFG_DIMINISH_SPRITES - #define SFG_DIMINISH_SPRITES 1 -#endif - -/** - How quick player head bob is, 1024 meaning once per second. 0 Means turn off - head bob. -*/ -#ifndef SFG_HEADBOB_SPEED - #define SFG_HEADBOB_SPEED 900 -#endif - -/** - Sets head bob offset, in RCL_UNITS_PER_SQUARE. 0 Means turn off head bob. -*/ -#ifndef SFG_HEADBOB_OFFSET - #define SFG_HEADBOB_OFFSET 200 -#endif - -/** - If head bob is on, this additionally sets additional camera shear bob, in - pixels, which can make bobbing look more "advanced". 0 turns this option off. -*/ -#ifndef SFG_HEADBOB_SHEAR - #define SFG_HEADBOB_SHEAR 0 -#endif - -/** - Weapon bobbing offset in weapon image pixels. -*/ -#ifndef SFG_WEAPONBOB_OFFSET - #define SFG_WEAPONBOB_OFFSET 4 -#endif - -/** - Camera shearing (looking up/down) speed, in vertical resolutions per second. -*/ -#ifndef SFG_CAMERA_SHEAR_SPEED - #define SFG_CAMERA_SHEAR_SPEED 3 -#endif - -/** - Maximum camera shear (vertical angle). 1024 means 1.0 * vertical resolution. -*/ -#ifndef SFG_CAMERA_MAX_SHEAR - #define SFG_CAMERA_MAX_SHEAR 1024 -#endif - -/** - Specifies how quick some sprite animations are, in frames per second. -*/ -#ifndef SFG_SPRITE_ANIMATION_SPEED - #define SFG_SPRITE_ANIMATION_SPEED 4 -#endif - -/** - How wide the border indicator is, in fractions of screen width. -*/ -#ifndef SFG_HUD_BORDER_INDICATOR_WIDTH - #define SFG_HUD_BORDER_INDICATOR_WIDTH 32 -#endif - -/** - For how long border indication (being hurt etc.) stays shown, in ms. -*/ -#ifndef SFG_HUD_BORDER_INDICATOR_DURATION - #define SFG_HUD_BORDER_INDICATOR_DURATION 500 -#endif - -/** - Color (palette index) by which being hurt is indicated. -*/ -#ifndef SFG_HUD_HURT_INDICATION_COLOR - #define SFG_HUD_HURT_INDICATION_COLOR 175 -#endif - -/** - Color (palette index) by which taking an item is indicated. -*/ -#ifndef SFG_HUD_ITEM_TAKEN_INDICATION_COLOR - #define SFG_HUD_ITEM_TAKEN_INDICATION_COLOR 207 -#endif - -/** - How many element (items, monsters, ...) distances will be checked per frame - for distance. Higher value may decrease performance a tiny bit, but things - will react more quickly and appear less "out of thin air". -*/ -#ifndef SFG_ELEMENT_DISTANCES_CHECKED_PER_FRAME - #define SFG_ELEMENT_DISTANCES_CHECKED_PER_FRAME 8 -#endif - -/** - Maximum distance at which sound effects (SFX) will be played. The SFX volume - will gradually drop towards this distance. -*/ -#ifndef SFG_SFX_MAX_DISTANCE - #define SFG_SFX_MAX_DISTANCE (1024 * 60) -#endif - -/** - Says the intensity of background image blur. 0 means no blur, improves - performance and lowers memory usage. -*/ -#ifndef SFG_BACKGROUND_BLUR - #define SFG_BACKGROUND_BLUR 0 -#endif - -/** - Defines the period, in ms, of things that blink, such as text. -*/ -#ifndef SFG_BLINK_PERIOD - #define SFG_BLINK_PERIOD 500 -#endif - -/** - Probability (0 - 255) of how often a monster makes sound during movement. -*/ -#ifndef SFG_MONSTER_SOUND_PROBABILITY - #define SFG_MONSTER_SOUND_PROBABILITY 64 -#endif - -/** - Affects how precise monsters are in aiming, specify random range in - fourths of a game square. Should be power of 2 for performance. -*/ -#ifndef SFG_MONSTER_AIM_RANDOMNESS - #define SFG_MONSTER_AIM_RANDOMNESS 4 -#endif - -/// Color 1 index of player on map. -#ifndef SFG_MAP_PLAYER_COLOR1 - #define SFG_MAP_PLAYER_COLOR1 93 -#endif - -/// Color 2 index of player on map. -#ifndef SFG_MAP_PLAYER_COLOR2 - #define SFG_MAP_PLAYER_COLOR2 111 -#endif - -/// Color index of elevators on map. -#ifndef SFG_MAP_ELEVATOR_COLOR - #define SFG_MAP_ELEVATOR_COLOR 214 -#endif - -/// Color index of squeezers on map. -#ifndef SFG_MAP_SQUEEZER_COLOR - #define SFG_MAP_SQUEEZER_COLOR 246 -#endif - -/// Color index of door on map. -#ifndef SFG_MAP_DOOR_COLOR - #define SFG_MAP_DOOR_COLOR 188 -#endif - -/** - Boolean value indicating whether current OS is malware. -*/ -#ifndef SFG_OS_IS_MALWARE - #define SFG_OS_IS_MALWARE 0 -#endif - -/** - Angle difference, as a cos value in RCL_Units, between the player and a - monster, at which vertical autoaim will trigger. If the angle is greater, a - shot will go directly forward. -*/ -#ifndef SFG_VERTICAL_AUTOAIM_ANGLE_THRESHOLD - #define SFG_VERTICAL_AUTOAIM_ANGLE_THRESHOLD 50 -#endif - -/** - Byte (0 - 255) volume of the menu click sound. -*/ -#ifndef SFG_MENU_CLICK_VOLUME - #define SFG_MENU_CLICK_VOLUME 220 -#endif - -/** - Says whether the exit item should be showed in the menu. Platforms that can't - exit (such as some gaming consoles that simply use power off button) can - define this to 0. -*/ -#ifndef SFG_CAN_EXIT - #define SFG_CAN_EXIT 1 -#endif - -/** - On Arduino platforms this should be set to 1. That will cause some special - treatment regarding constant variables and PROGMEM. -*/ -#ifndef SFG_ARDUINO - #define SFG_ARDUINO 0 -#endif - -/** - Whether levels background (in distance or transparent wall textures) should - be drawn. If turned off, the background will be constant color, which can - noticably increase performance. -*/ -#ifndef SFG_DRAW_LEVEL_BACKGROUND - #define SFG_DRAW_LEVEL_BACKGROUND 1 -#endif - -//------ developer/debug settings ------ - -/** - Developer cheat for having infinite ammo in all weapons. -*/ -#ifndef SFG_INFINITE_AMMO - #define SFG_INFINITE_AMMO 0 -#endif - -/** - Developer cheat for immortality. -*/ -#ifndef SFG_IMMORTAL - #define SFG_IMMORTAL 0 -#endif - -/** - Turn on for previes mode for map editing (flying, noclip, fast movement etc.). -*/ -#ifndef SFG_PREVIEW_MODE - #define SFG_PREVIEW_MODE 0 -#endif - -/** - How much faster movement is in the preview mode. -*/ -#ifndef SFG_PREVIEW_MODE_SPEED_MULTIPLIER - #define SFG_PREVIEW_MODE_SPEED_MULTIPLIER 2 -#endif - -/** - Skips menu and starts given level immediatelly, for development. 0 means this - options is ignored, 1 means load level 1 etc. -*/ -#ifndef SFG_START_LEVEL - #define SFG_START_LEVEL 0 -#endif - -/** - Reveals whole level map from start. -*/ -#ifndef SFG_REVEAL_MAP - #define SFG_REVEAL_MAP 0 -#endif - -/** - Gives player all keys from start. -*/ -#ifndef SFG_UNLOCK_DOOR - #define SFG_UNLOCK_DOOR 0 -#endif - -#endif // guard diff --git a/main_gbmeta/smallinput.h b/main_gbmeta/smallinput.h deleted file mode 100644 index cee8507..0000000 --- a/main_gbmeta/smallinput.h +++ /dev/null @@ -1,404 +0,0 @@ -/** - @file smallinput.h - - Small API for getting keyboard/mouse input, with possiblity to record it and - play back. - - The Linux Input API requires root pirivileges (sudo). - - by Milsolav "drummyfish" Ciz, released under CC0 1.0 (public domain) -*/ - -#ifndef _SMALLINPUT_H -#define _SMALLINPUT_H - -#include -#include - -#define SMALLINPUT_MODE_NORMAL 0 ///< Only handle input. -#define SMALLINPUT_MODE_RECORD 1 ///< Handle input and record it. -#define SMALLINPUT_MODE_PLAY 2 ///< Play back recorded input. - -#define SMALLINPUT_KEY_NONE 0 -#define SMALLINPUT_SPACE ' ' -#define SMALLINPUT_BACKSPACE 8 -#define SMALLINPUT_TAB 9 -#define SMALLINPUT_RETURN 13 -#define SMALLINPUT_SHIFT 14 -#define SMALLINPUT_ESCAPE 27 -#define SMALLINPUT_DELETE 127 -#define SMALLINPUT_ARROW_UP 128 -#define SMALLINPUT_ARROW_RIGHT 129 -#define SMALLINPUT_ARROW_DOWN 130 -#define SMALLINPUT_ARROW_LEFT 131 -#define SMALLINPUT_F1 132 -#define SMALLINPUT_F2 133 -#define SMALLINPUT_F3 134 -#define SMALLINPUT_F4 135 -#define SMALLINPUT_F5 136 -#define SMALLINPUT_F6 137 -#define SMALLINPUT_F7 138 -#define SMALLINPUT_F8 139 -#define SMALLINPUT_F9 140 -#define SMALLINPUT_F10 141 -#define SMALLINPUT_F11 142 -#define SMALLINPUT_F12 143 -#define SMALLINPUT_CTRL 144 -#define SMALLINPUT_MOUSE_L 253 -#define SMALLINPUT_MOUSE_M 254 -#define SMALLINPUT_MOUSE_R 255 - -#define SMALLINPUT_RECORD_KEY_DOWN 1 ///< Mouse down event, followed by code. -#define SMALLINPUT_RECORD_KEY_UP 2 ///< Moue up event, followed by code. -#define SMALLINPUT_RECORD_MOUSE_X 3 ///< Mouse x move, followed by s32 value. -#define SMALLINPUT_RECORD_MOUSE_Y 4 ///< Mouse y move, followed by s32 value. -#define SMALLINPUT_RECORD_END 255 ///< Record end, followed by 4 more same values. - -uint8_t input_keyStates[256]; -int32_t input_mousePosition[2]; - -uint8_t input_keyStatesPrevious[256]; -int32_t input_mousePositionPrevious[2]; - -uint8_t input_mode; - -uint32_t input_frame = 0; -uint8_t *input_recordData; -uint32_t input_recordPosition; -uint32_t input_recordSize; - -#if 1 // TODO: add other options for input handling (SDL, xinput, ...) - /* - This is using Linux Input Subsystem API. Defines can be found in - include/uapi/linux/input-event-codes.h. - */ - - #include - #include - #include - #include - - typedef struct - { - struct timeval time; - uint16_t type; - uint16_t code; - int32_t value; - } LinuxInputEvent; - - #define INPUT_KEYBOARD_FILE "/dev/input/event0" - #define INPUT_MOUSE_FILE "/dev/input/event1" - - int input_keyboardFile = 0; - int input_mouseFile = 0; - - /** - Maps this library's key codes to linux input key codes. - */ - static const int input_linuxCodes[256] = - { - #define no KEY_RESERVED - no,no,no,no,no,no,no,no,KEY_BACKSPACE,KEY_TAB,no,no,no,KEY_ENTER,KEY_LEFTSHIFT,no, - no,no,no,no,no,no,no,no,no,no,no,KEY_ESC,no,no,no,no, - KEY_SPACE,no,no,no,no,no,no,no,no,no,no,no,KEY_COMMA,no,KEY_DOT,no, - KEY_0,KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,KEY_6,KEY_7,KEY_8,KEY_9,no,KEY_SEMICOLON,no,KEY_EQUAL,no,KEY_QUESTION, - no,KEY_A,KEY_B,KEY_C,KEY_D,KEY_E,KEY_F,KEY_G,KEY_H,KEY_I,KEY_J,KEY_K,KEY_L,KEY_M,KEY_N,KEY_O, - KEY_P,KEY_Q,KEY_R,KEY_S,KEY_T,KEY_U,KEY_V,KEY_W,KEY_X,KEY_Y,KEY_Z,no,no,no,no,no, - no,KEY_A,KEY_B,KEY_C,KEY_D,KEY_E,KEY_F,KEY_G,KEY_H,KEY_I,KEY_J,KEY_K,KEY_L,KEY_M,KEY_N,KEY_O, - KEY_P,KEY_Q,KEY_R,KEY_S,KEY_T,KEY_U,KEY_V,KEY_W,KEY_X,KEY_Y,KEY_Z,no,no,no,no,KEY_DELETE, - KEY_UP,KEY_RIGHT,KEY_DOWN,KEY_LEFT,KEY_F1,KEY_F2,KEY_F3,KEY_F4,KEY_F5,KEY_F6,KEY_F7,KEY_F8,KEY_F9,KEY_F10,KEY_F11,KEY_F12, - KEY_LEFTCTRL,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no, - no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no, - no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no, - no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no, - no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no, - no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no, - no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no - #undef no - }; -#endif - -void input_recordU8(uint8_t value) -{ - if (input_recordPosition < (input_recordSize - 1)) - { - input_recordData[input_recordPosition] = value; - input_recordPosition++; - } -} - -void input_recordU32(uint32_t value) -{ - for (uint8_t i = 0; i < 4; ++i) - { - input_recordU8(value % 256); - value /= 256; - } -} - -uint32_t input_readU32(uint8_t *data) -{ - uint32_t result = 0; - - for (uint8_t i = 0; i < 4; ++i) - result = result * 256 + data[3 - i]; - - return result; -} - -/** - Initializes the library with given mode (SMALLINPUT_MODE_*). -*/ -uint8_t input_init(uint8_t mode, uint8_t *recordData, uint32_t recordDataLength) -{ - input_mode = mode; - - input_mousePosition[0] = 0; - input_mousePosition[1] = 0; - - input_mousePositionPrevious[0] = 0; - input_mousePositionPrevious[1] = 0; - - input_frame = 0; - input_recordData = recordData; - input_recordPosition = 0; - input_recordSize = recordDataLength; - - for (int16_t i = 0; i < 256; ++i) - { - input_keyStates[i] = 0; - input_keyStatesPrevious[i] = 0; - } - - uint8_t result = 1; - - if (input_mode != SMALLINPUT_MODE_PLAY) - { - input_keyboardFile = open(INPUT_KEYBOARD_FILE, O_RDONLY); - - result = input_keyboardFile >= 0; - - if (result) - { - fcntl(input_keyboardFile, F_SETFL, O_NONBLOCK); - - input_mouseFile = open(INPUT_MOUSE_FILE, O_RDONLY); - - result = input_mouseFile >= 0; - - if (result) - fcntl(input_mouseFile, F_SETFL, O_NONBLOCK); - } - - if (!result) - puts("could not open device file (are you root?)"); - } - - return result; -} - -void input_end(void) -{ - if (input_mode == SMALLINPUT_MODE_RECORD) - for (uint8_t i = 0; i < 5; ++i) - input_recordU8(SMALLINPUT_RECORD_END); - - close(input_keyboardFile); - close(input_mouseFile); -} - -/** - Should be called once every main loop iteration to retrieve current input - state. -*/ -void input_update(void) -{ - LinuxInputEvent event; - - if (input_mode == SMALLINPUT_MODE_PLAY) - { - while (input_recordPosition < input_recordSize) - { - uint32_t nextFrame = input_readU32(input_recordData + input_recordPosition); - - if (input_frame >= nextFrame) - { - input_recordPosition += 4; - - uint8_t rec = input_recordData[input_recordPosition]; - - switch (rec) - { - case SMALLINPUT_RECORD_KEY_DOWN: - case SMALLINPUT_RECORD_KEY_UP: - input_recordPosition++; - input_keyStates[input_recordData[input_recordPosition]] = rec == SMALLINPUT_RECORD_KEY_DOWN; - input_recordPosition++; - break; - - case SMALLINPUT_RECORD_MOUSE_X: - case SMALLINPUT_RECORD_MOUSE_Y: - input_recordPosition++; - input_mousePosition[rec == SMALLINPUT_RECORD_MOUSE_Y] = - input_readU32(input_recordData + input_recordPosition); - input_recordPosition += 4; - break; - - case SMALLINPUT_RECORD_END: - input_recordPosition = input_recordSize; - break; - - default: /*printf("corrupt record\n");*/ break; - } - } - else - break; - } - } - else - { - while (1) // keyboard - { - if (read(input_keyboardFile, &event, sizeof(event)) <= 0) - break; - - if (event.type == EV_KEY && (event.value == 1 || event.value == 0)) - for (uint16_t i = 0; i < 256; ++i) - if (event.code == input_linuxCodes[i]) - { - input_keyStates[i] = event.value; - break; - } - } - - while (1) // mouse - { - if (read(input_mouseFile, &event, sizeof(event)) <= 0) - break; - - if (event.type == EV_REL) - input_mousePosition[event.code % 2] += event.value; - else if (event.type == EV_KEY) - { - input_keyStates[ - event.code == BTN_LEFT ? SMALLINPUT_MOUSE_L : - (event.code == BTN_RIGHT ? SMALLINPUT_MOUSE_R : SMALLINPUT_MOUSE_M)] - = event.value; - } - } - } - - for (uint16_t i = 0; i < 256; ++i) - if (input_keyStates[i] && input_keyStates[i] < 255) - input_keyStates[i]++; - - if (input_mode == SMALLINPUT_MODE_RECORD) - { - for (uint8_t i = 0; i < 2; ++i) // record mouse events - if (input_mousePositionPrevious[i] != input_mousePosition[i]) - { - input_recordU32(input_frame + 1); - input_recordU8((i == 0) ? SMALLINPUT_RECORD_MOUSE_X : SMALLINPUT_RECORD_MOUSE_Y); - input_recordU32(input_mousePosition[i]); - - input_mousePositionPrevious[i] = input_mousePosition[i]; - } - - for (uint16_t i = 0; i < 256; ++i) // record key events - { - uint8_t a = input_keyStates[i] > 0; - uint8_t b = input_keyStatesPrevious[i] > 0; - - if (a != b) - { - input_recordU32(input_frame + 1); - input_recordU8(a ? SMALLINPUT_RECORD_KEY_DOWN : SMALLINPUT_RECORD_KEY_UP); - input_recordU8(i); - - input_keyStatesPrevious[i] = input_keyStates[i]; - } - } - } - - input_frame++; -} - -/** - Returns the number of input frames for which given key has been pressed (> 1: - key is pressed, == 1: key was just pressed, == 0: key is not pressed). -*/ -static inline uint8_t input_getKey(uint8_t key) -{ - if (key >= 'a' && key <= 'z') - key = 'A' + (key - 'a'); - - return input_keyStates[key]; -} - -/** - Gets the mouse position. -*/ -static inline void input_getMousePos(int32_t *x, int32_t *y) -{ - *x = input_mousePosition[0]; - *y = input_mousePosition[1]; -} - -static inline void input_setMousePos(int32_t x, int32_t y) -{ - input_mousePosition[0] = x; - input_mousePosition[1] = y; -} - -/** - Prints the current input state. -*/ -void input_print() -{ - printf("frame: %d\nmouse pos: %d %d",input_frame,input_mousePosition[0],input_mousePosition[1]); - - for (uint16_t i = 0; i < 256; ++i) - { - if (i % 8 == 0) - putchar('\n'); - - char c = (i > ' ' && i <= 126) ? i : '?'; - - uint8_t n = input_getKey(i); - - printf("%s",n ? " [" : " "); - printf("%03d (\'%c\'): %03d",i,c,input_getKey(i)); - printf("%s",n ? "] " : " "); - } - - putchar('\n'); -} - -void input_printRecord() -{ - for (uint32_t i = 0; i < input_recordPosition; ++i) - { - if (i % 32 == 0) - putchar('\n'); - - printf("%d,",input_recordData[i]); - } -} - -uint32_t input_hash() -{ - uint32_t result = 0; - - for (uint16_t i = 0; i < 256; ++i) - result += input_getKey(i) * (i + 1); - - int32_t x, y; - - input_getMousePos(&x,&y); - - result += x + y << 16; - - return result; -} - -#endif // guard diff --git a/main_gbmeta/sounds.h b/main_gbmeta/sounds.h deleted file mode 100644 index c9d3b56..0000000 --- a/main_gbmeta/sounds.h +++ /dev/null @@ -1,488 +0,0 @@ -/** - @file assets.h - - This file containts sounds and music that can optionally be used by the game - front end. Every sound effect has 2048 samples, is stored in 8kHz mono format - with 4 bit quantization, meaning every sound effect takes 1024 bytes. Sounds - can be converted using a provided python script like this: - - python snd2array.py sound.raw - - by Miloslav Ciz (drummyfish), 2019 - - Music is based on bytebeat (procedural waveforms generated by short bitwise - operation formulas). - - Released under CC0 1.0 (https://creativecommons.org/publicdomain/zero/1.0/) - plus a waiver of all other intellectual property. The goal of this work is - be and remain completely in the public domain forever, available for any use - whatsoever. -*/ - -#ifndef _SFG_SOUNDS_H -#define _SFG_SOUNDS_H - -#define SFG_SFX_SAMPLE_COUNT 2048 -#define SFG_SFX_SIZE (SFG_SFX_SAMPLE_COUNT / 2) - -/** - Gets a 8-bit sound sample. -*/ -#define SFG_GET_SFX_SAMPLE(soundIndex,sampleIndex) \ - ((SFG_PROGRAM_MEMORY_U8(SFG_sounds + soundIndex * SFG_SFX_SIZE \ - + sampleIndex / 2) << (4 * ((sampleIndex % 2) != 0))) & 0xf0) - -#define SFG_TRACK_SAMPLES (512 * 1024) -#define SFG_TRACK_COUNT 6 - -/** - Average value of each music track, can be used to correct DC offset issues if - they appear. -*/ -SFG_PROGRAM_MEMORY uint8_t SFG_musicTrackAverages[SFG_TRACK_COUNT] = - {14,7,248,148,6,8}; - -struct -{ // all should be initialized to 0 - uint8_t track; - uint32_t t; // time variable/parameter - uint32_t t2; // stores t squared, for better performance - uint32_t n11t; // stores a multiple of 11, for better performance -} SFG_MusicState; - -/** - Gets the next 8bit 8KHz music sample for the bytebeat soundtrack. This - function is to be used by the frontend that plays music. -*/ -uint8_t SFG_getNextMusicSample() -{ - if (SFG_MusicState.t >= SFG_TRACK_SAMPLES) - { - SFG_MusicState.track++; - - if (SFG_MusicState.track >= SFG_TRACK_COUNT) - SFG_MusicState.track = 0; - - SFG_MusicState.t = 0; - SFG_MusicState.t2 = 0; - SFG_MusicState.n11t = 0; - } - - uint32_t result; - - #define S SFG_MusicState.t // can't use "T" because of a C++ template - #define S2 SFG_MusicState.t2 - #define N11S SFG_MusicState.n11t - - /* CAREFUL! Bit shifts in any direction by amount greater than data type - width (32) are undefined behavior. Use % 32. */ - - switch (SFG_MusicState.track) // individual music tracks - { - case 0: - { - uint32_t a = ((S >> 7) | (S >> 9) | (~S << 1) | S); - result = (((S) & 65536) ? (a & (((S2) >> 16) & 0x09)) : ~a); - - SFG_MusicState.t2 += S; - - break; - } - - case 1: - { - uint32_t a = (S >> 10); - result = S & (3 << (((a ^ (a << ((S >> 6) % 32)))) % 32)); - - break; - } - - case 2: - { - result = - ~((((S >> ((S >> 2) % 32)) | (S >> ((S >> 5) % 32))) & 0x12) << 1) - | (S >> 11); - - break; - } - - case 3: - { - result = - (((((S >> ((S >> 2) % 32)) + (S >> ((S >> 7) % 32)))) & 0x3f) | (S >> 5) - | (S >> 11)) & ((S & (32768 | 8192)) ? 0xf0 : 0x30); - - break; - } - - case 4: - { - result = - ((0x47 >> ((S >> 9) % 32)) & (S >> (S % 32))) | - (0x57 >> ((S >> 7) % 32)) | - (0x06 >> ((S >> ((((N11S) >> 14) & 0x0e) % 32)) % 32)); - - SFG_MusicState.n11t += 11; - - break; - } - - case 5: - { - uint32_t a = S >> ((S >> 6) % 32); - uint32_t b = 0x011121 >> (((a + S) >> 11) % 32); - result = - (((S >> 9) + (S ^ (S << 1))) & (0x7f >> (((S >> 15) & 0x03) % 32))) - & (b + a); - - break; - } - - default: - result = 127; - break; - } - - #undef S - #undef S2 - #undef N11S - - SFG_MusicState.t += 1; - - return result; -} - -/** - Switches the bytebeat to next music track. -*/ -void SFG_nextMusicTrack() -{ - uint8_t current = SFG_MusicState.track; - - while (SFG_MusicState.track == current) - SFG_getNextMusicSample(); -} - -SFG_PROGRAM_MEMORY uint8_t SFG_sounds[SFG_SFX_SIZE * 6] = -{ -// 0, bullet shot -135,119,120,136,136,153,153,153,154,169,152,119,101,85,86,102,119,118,119, -85,84,51,33,52,52,84,87,120,170,188,202,152,102,84,84,70,119,136,119, -119,121,154,219,170,137,117,82,18,36,34,33,20,67,68,70,137,172,189,237, -220,150,120,120,97,36,102,121,151,87,169,118,86,102,120,137,135,120,186,155, -223,255,217,103,100,70,119,118,84,34,36,122,204,220,168,138,170,170,223,199, -117,70,119,136,100,85,102,51,37,101,103,118,101,136,87,154,169,171,187,186, -169,153,136,117,68,84,66,18,19,50,52,51,102,121,139,186,169,171,186,152, -153,136,119,134,85,101,86,69,84,84,86,85,86,102,119,120,153,135,135,101, -87,134,103,135,101,103,119,135,152,120,136,135,137,136,151,134,87,119,136,119, -118,102,85,119,85,102,102,119,138,137,153,137,186,170,137,152,135,101,85,85, -86,102,102,119,119,102,103,119,137,152,138,153,154,169,153,152,137,151,118,85, -85,84,84,86,86,136,119,119,154,153,153,171,187,170,170,187,170,137,151,119, -102,103,69,102,118,120,120,138,153,169,170,169,153,135,119,119,102,118,105,136, -136,137,152,153,136,152,119,119,119,119,121,152,136,119,152,136,135,120,119,118, -86,102,103,136,135,137,153,136,152,119,119,118,102,86,85,102,102,102,102,120, -136,136,136,136,152,136,153,152,119,119,120,135,120,119,119,103,119,136,119,135, -120,135,136,136,137,153,153,152,154,152,153,137,152,136,135,119,136,136,136,153, -152,154,170,170,153,153,152,119,119,119,119,118,119,103,136,136,120,135,118,120, -119,118,102,119,102,102,103,119,118,103,102,102,119,135,119,119,119,119,119,119, -119,118,102,103,135,136,135,119,120,135,119,119,119,119,103,119,120,136,137,152, -136,136,136,153,153,136,153,153,153,153,153,152,153,136,136,135,119,135,119,119, -136,136,136,136,152,152,137,153,152,119,118,102,102,102,119,103,119,119,119,136, -136,135,118,103,119,120,136,136,136,136,136,136,136,119,118,102,119,119,119,136, -136,136,136,137,136,136,136,136,119,119,120,135,119,119,120,135,136,136,136,136, -136,136,119,119,120,119,120,136,136,135,119,120,119,119,119,119,119,120,136,152, -136,137,153,136,136,136,136,136,136,136,119,120,137,153,136,136,135,119,119,136, -136,136,135,119,119,102,119,120,135,119,119,119,136,136,136,118,102,103,119,136, -119,119,120,136,136,136,135,119,119,136,136,136,136,136,136,136,136,135,119,119, -119,119,119,136,119,119,119,136,136,136,136,135,120,136,136,136,119,119,119,120, -136,136,136,136,135,119,119,119,119,136,119,119,136,136,136,136,135,119,119,119, -119,119,119,119,119,136,136,136,136,136,135,119,119,119,119,119,119,119,136,136, -136,136,135,120,136,136,136,119,119,119,136,136,136,135,119,119,119,119,119,119, -119,119,119,119,136,136,120,136,136,136,136,136,119,119,120,136,136,136,119,119, -120,136,136,136,136,136,136,136,136,136,136,136,135,119,119,119,119,119,119,119, -120,136,136,136,135,119,119,119,119,136,136,136,136,136,135,119,119,119,119,119, -119,120,136,136,136,136,136,135,119,119,119,119,119,119,119,120,136,136,136,136, -136,136,136,136,136,136,119,119,119,119,119,119,119,119,119,119,136,136,136,136, -136,136,136,136,136,136,136,119,119,119,119,119,119,119,119,136,136,136,136,136, -136,136,136,136,136,136,136,119,119,119,119,119,119,119,119,119,119,136,136,136, -136,136,136,136,119,119,119,119,119,120,136,136,136,136,136,136,136,135,119,119, -136,136,119,119,119,119,119,119,120,135,120,136,136,136,136,136,136,136,136,135, -119,119,119,119,119,119,119,119,136,136,136,136,136,136,136,136,136,135,119,119, -119,119,119,119,119,119,119,119,119,119,136,136,136,136,136,136,136,136,119,119, -119,119,119,119,119,120,136,136,136,136,136,136,136,119,119,119,119,119,119,119, -119,119,119,136,135,119,120,119,119,120,136,136,136,136,136,136,119,119,119,119, -119,119,119,119,120,136,136,136,136,136,136,136,119,119,135,119,119,119,119,119, -119,119,119,119,135,120,136,136,136,136,136,135,119,119,119,119,119,120,119,119, -119,135,119,136,136,136,136,136,136,135,119,119,119,119,119,119,119,119,136,136, -136,136,136,136,136,136,135,119,136,136,135,119,119,119,119,119,119,119,119,119, -119,119,136,136,136,136,136,136,136,136,136,119,119,119,119,119,119,119,136,136, -136,136,136,136,136,136,135,119,119,135,135,120,120,120,120,120,120,120,120,135, -135,136,120,120,135 -, // 1, door opening -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,136, -136,136,136,136,136,136,136,136,136,136,153,153,153,153,153,153,153,153,153,153, -153,153,152,136,136,136,136,136,136,136,136,136,119,119,119,119,119,119,119,119, -119,119,119,102,102,102,102,103,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,136,136,136,136,136,136,136,136,136,136,153,153,153,153,153, -153,153,136,136,136,136,136,136,135,119,119,119,119,119,119,119,119,119,102,102, -102,102,102,102,102,102,102,103,119,119,119,119,120,136,136,136,136,136,137,153, -153,153,153,153,152,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, -135,119,119,119,119,120,136,136,136,136,136,136,136,137,136,136,136,136,136,136, -136,136,136,136,136,136,135,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,136,136,136,136,136,136,120, -136,136,136,136,136,136,136,135,120,136,136,135,119,120,135,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,120,136,136,136,136,136,119,120,136,136, -136,136,136,135,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,120,136,136,136,136,136,136,136,136,136,136,136, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -136,136,136,136,136,153,153,153,153,153,152,136,136,136,136,136,136,136,136,136, -136,136,136,136,136,136,136,136,136,136,135,120,136,136,136,136,136,136,136,136, -136,136,136,136,136,136,136,135,119,119,119,119,119,119,119,119,119,119,120,136, -136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,119,119,119,119,119,119,119,119,119,136,136,136,136,136,136,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,102,102,102,102,102,103,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,120,136,136,136,136,119,119,119,119,119,119,119,119, -119,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,136,136,136,136,136,135,119,119,119,119,119,119,119,119,119,119,119,119, -119,120,136,136,136,136,136,136,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,120,136,136,136,136,136,136,136,136,136,136,136, -136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,136,136,136,136,136,136,136,136,136,120,135,119,119,119,136,136,136,136, -136,136,135,136,136,136,136,136,136,136,135,136,136,136,136,120,119,135,119,119, -119,119,119,119,119,120,136,136,120,136,136,136,136,136,119,136,135,136,136,136, -136,136,136,136,119,119,120,135,119,135,119,136,135,119,120,120,136,136,136,136, -135,119,119,119,119,119,119,119,119,120,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,103,119,119,119,102,102,102,102,102,102,118,103, -102,118,103,136,136,136,136,136,136,136,136,136,137,153,153,153,170,169,153,153, -170,153,153,153,170,170,169,170,169,153,153,153,153,153,153,170,170,170,153,153, -153,136,137,153,136,136,137,152,119,102,120,136,136,135,119,119,119,120,135,119, -119,120,137,153,153,153,152,136,135,119,119,119,102,119,119,119,119,119,119,119, -120,136,136,119,120,137,152,137,136,136,136,136,119,120,135,119,118,102,102,102, -102,102,102,119,119,119,119,118,103,119,119,119,119,119,102,102,102,85,85,85, -85,84,85,85,85,86,102,102,102,102,102,101,85,86,102,102,102,102,102,102, -102,102,102,119,102,102,119,119,119,120,136,119,119,119,120,136,136,136,136,136, -136,135,119,119,136,136,136,136,136,136,119,120,135,119,119,119,119,119,119,119, -119,119,119,120,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,136,120,120 -, // 2, explosion -135,136,153,18,51,51,33,18,123,255,255,255,255,255,255,255,254,184,48, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,55,189,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,254,201,135, -101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0,41, -239,255,255,253,186,188,221,221,220,153,152,136,155,188,203,187,171,202,169,116, -35,16,0,0,17,20,68,87,191,255,255,255,253,221,221,202,115,16,0,0, -0,0,18,34,70,117,85,68,85,86,102,68,67,68,70,136,153,134,67,32, -0,0,0,0,35,87,154,205,238,255,255,255,255,255,255,255,255,255,255,255, -255,255,237,168,101,67,16,0,0,0,53,102,119,133,85,85,49,0,0,34, -34,16,1,35,69,103,119,101,86,103,102,120,119,102,137,206,255,238,238,202, -152,120,134,85,86,102,102,102,119,120,135,117,68,50,34,35,69,121,188,221, -222,239,255,255,255,255,220,204,186,153,153,135,102,137,153,151,100,51,51,35, -69,102,68,68,67,52,68,51,86,118,86,119,118,103,137,172,221,237,221,221, -221,220,169,136,118,84,68,68,68,69,121,189,237,220,203,186,170,152,119,119, -120,170,188,204,204,204,188,204,186,152,117,67,50,52,87,119,118,103,102,103, -136,101,50,33,1,34,34,35,69,86,120,136,153,153,153,152,135,100,67,51, -51,69,85,102,121,188,205,222,255,236,203,204,187,188,221,203,170,170,170,169, -152,118,102,86,102,119,136,137,169,153,169,152,135,119,101,51,34,51,68,85, -102,85,85,84,85,102,102,85,86,103,137,170,187,221,204,222,255,238,237,203, -170,171,186,152,119,120,136,136,136,135,119,120,119,138,187,185,152,119,119,136, -134,83,16,1,35,68,68,50,17,52,104,172,222,238,238,238,221,220,186,153, -133,51,68,50,18,69,65,1,89,207,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,252,184,81,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,2,53,104,154,223,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,237,186,152,118,84,49,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,19,70,121,171,205,255,255, -255,255,255,255,255,255,255,254,220,187,170,153,152,135,102,118,101,67,16,0, -0,0,0,0,0,1,52,86,137,153,135,103,102,67,33,17,35,53,102,103, -118,102,84,51,35,51,51,69,87,120,154,189,255,255,255,255,255,255,255,236, -185,118,84,50,33,18,17,34,34,17,17,16,0,0,0,0,0,18,52,68, -69,86,119,137,171,187,205,221,237,239,255,255,255,253,204,186,152,136,118,66, -16,18,35,52,85,68,68,86,119,119,119,120,136,135,120,136,136,136,119,101, -85,68,68,67,50,17,16,0,0,0,1,17,17,17,18,35,69,120,171,188, -222,237,221,239,255,239,255,255,255,255,238,238,238,238,236,185,153,153,152,118, -85,84,67,51,50,34,34,34,35,51,34,34,35,52,68,68,68,69,85,103, -136,136,136,154,171,204,205,222,238,255,255,255,255,255,255,254,237,203,186,153, -153,153,153,136,135,118,102,84,50,16,0,0,0,0,0,0,0,0,0,17, -17,17,17,17,35,69,103,137,171,204,222,255,255,255,255,255,255,238,238,220, -203,170,169,153,170,170,171,187,187,205,221,220,203,186,136,135,119,102,85,68, -68,68,68,68,50,34,17,0,0,0,0,0,0,19,85,119,136,154,187,204, -204,186,136,120,136,136,136,136,136,154,188,239,255,255,255,255,238,237,203,186, -153,135,119,118,102,102,102,102,103,136,153,152,135,118,101,68,68,67,50,17, -0,0,0,0,1,17,17,34,51,52,86,103,137,170,170,187,187,204,221,221, -204,203,170,170,171,187,170,170,153,153,153,153,153,153,153,153,136,119,119,102, -102,102,103,119,119,136,153,153,154,170,153,152,135,119,119,119,119,119,137,153, -153,153,152,137,153,136,136,136,135,119,119,119,119,136,136,135,119,119,119,119, -119,119,119,119,137,152,136,136,153,154,169,153,136,136,136,135,119,102,85,85, -85,85,84,68,69,85,84,68,85,85,102,119,119,119,120,136,136,154,171,188, -204,205,221,222,237,221,204,187,170,153,136,119,119,119,102,101,85,85,68,68, -68,51,51,52,68,69,85,86,102,119,120,136,136,120,136,136,119,119,120,136, -136,136,136,136,136,136,119,119,119,119,136,136,136,136,136,136,136,136,136,136, -136,136,136,119,120 -, // 3, click -136,136,136,136,136,136,136,136,136,136,136,136,136,135,119,136,136,119,119, -119,119,119,119,119,119,119,119,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,136,135,119,119,120,119,119,119,119,119,119,119,120,136,136,136,136,136, -136,136,136,136,136,136,135,136,119,136,136,119,119,120,135,119,119,119,120,119, -119,136,136,119,119,136,135,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,136,136,119,120,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,135,119,136,136,135,119,119,120,136,135,119,120,119,119,120,135,120,119, -136,134,103,136,119,103,137,135,103,136,136,119,102,120,135,136,135,119,137,135, -119,102,154,133,67,54,154,136,150,69,120,120,133,72,169,119,118,86,171,132, -70,155,167,85,120,152,135,119,119,137,118,103,136,119,137,118,103,137,135,104, -152,136,135,119,136,136,119,120,152,120,119,152,152,120,120,136,135,120,135,119, -136,136,136,119,136,136,136,136,136,119,136,136,136,120,136,119,119,119,120,119, -119,119,119,119,119,119,119,119,119,119,119,136,135,119,135,119,136,120,136,136, -120,135,119,136,136,119,119,136,119,136,136,136,136,136,136,136,119,119,119,119, -119,119,119,119,119,119,119,136,136,136,136,136,136,136,136,136,136,136,119,119, -119,119,119,119,119,119,119,135,135,135,135,135,135,135,150,122,74,106,120,134, -134,165,150,135,120,120,120,120,119,120,119,119,120,119,119,119,119,119,119,119, -119,119,119,119,135,136,120,120,135,136,136,136,136,136,136,136,136,135,119,119, -119,136,119,119,120,120,136,136,136,136,136,136,136,136,120,136,120,136,136,120, -119,136,119,120,119,119,119,119,119,119,119,119,119,119,119,119,119,135,135,135, -135,135,135,119,119,120,105,104,118,150,135,135,119,136,120,120,136,135,136,136, -120,120,136,136,120,136,135,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,135,136,136,136,120,120,135,135,136,136,120,120,135,135,135,135,136,136,120, -120,120,136,120,120,135,136,136,135,135,135,136,136,135,136,136,120,120,136,120, -136,119,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,120,136,136,136,136,136,136,136,136,136,136,136,136,136,119,119,136,135, -120,136,120,136,120,135,120,136,136,135,135,120,135,135,120,120,119,136,119,136, -120,120,135,120,136,136,135,136,135,136,135,136,135,136,136,136,136,136,136,136, -136,120,120,136,135,120,136,120,136,136,136,120,135,135,135,136,135,120,119,136, -119,120,136,135,119,136,136,136,136,136,136,120,136,119,136,136,136,136,135,120, -136,120,136,136,119,136,135,120,136,120,120,136,119,136,136,136,136,135,136,135, -136,136,119,120,136,135,136,120,136,136,135,120,136,119,136,135,136,136,120,136, -136,136,120,136,136,135,135,135,135,135,137,167,122,102,90,195,138,87,120,150, -136,136,87,153,88,121,133,104,150,135,151,134,136,105,104,121,135,118,151,136, -119,136,119,121,135,120,120,120,134,152,119,120,135,120,135,119,136,136,119,135, -135,120,136,120,136,120,136,135,135,135,136,120,136,135,136,135,136,136,136,136, -136,119,136,135,120,136,136,136,136,135,136,136,120,136,120,136,135,136,136,135, -136,136,120,136,120,135,135,136,136,119,120,136,120,135,119,136,136,119,136,135, -120,136,135,136,135,119,136,135,136,136,135,120,136,120,136,135,136,120,136,135, -120,136,135,136,136,136,136,136,120,136,136,120,135,136,136,120,136,120,136,136, -136,136,136,136,136,120,136,136,136,136,136,136,136,136,136,136,136,135,136,136, -136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,136,136,136,136,136,136,136,120,136,136,136,136,136,136,136,136,136,136, -136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,136,136,136 -, // 4, plasma shot, teleport -136,136,136,136,136,136,119,119,118,102,102,85,86,102,103,120,136,153,170, -187,187,187,170,169,152,119,102,85,68,68,68,69,86,103,136,154,171,187,204, -203,186,169,136,118,102,85,84,69,103,138,189,221,221,221,221,221,221,221,221, -221,220,166,50,34,34,34,33,33,34,34,34,34,34,34,34,34,71,156,221, -221,221,221,221,221,221,221,221,221,222,238,238,238,221,237,184,99,51,34,34, -34,34,34,34,34,34,34,17,17,36,121,188,204,204,204,204,204,204,221,221, -221,221,221,221,221,221,221,238,221,219,169,136,101,67,51,51,51,51,50,34, -34,35,50,34,36,121,189,221,221,221,221,220,204,204,188,204,204,204,204,204, -204,204,205,220,186,152,117,50,51,51,51,51,51,51,51,51,51,51,52,105, -189,237,221,221,221,221,221,221,221,205,220,204,204,204,187,187,187,187,186,135, -101,50,17,17,18,34,35,51,67,51,51,51,52,105,187,222,221,221,221,221, -221,221,221,221,221,221,221,221,221,221,221,221,204,203,169,134,67,34,17,17, -17,34,34,33,34,34,34,52,104,171,205,221,221,220,204,204,204,204,204,204, -204,204,204,221,221,221,221,221,219,169,135,85,84,68,68,68,67,51,51,50, -34,35,69,103,136,136,136,136,135,136,136,136,153,170,187,187,187,187,187,187, -187,187,203,169,135,102,85,86,102,103,119,119,118,102,86,102,102,85,85,85, -84,68,69,85,102,103,137,154,170,171,186,170,170,170,170,170,152,118,101,68, -68,68,85,85,102,103,120,136,135,118,102,102,102,102,102,102,101,84,69,87, -137,154,153,170,170,171,187,187,187,187,170,170,169,170,170,170,170,153,152,135, -118,101,68,51,51,52,68,85,85,85,85,68,85,102,103,118,102,85,102,103, -120,136,153,170,187,204,221,238,238,238,237,221,204,186,152,118,101,84,68,69, -86,102,119,119,102,85,84,68,68,51,51,34,34,51,68,85,102,103,120,137, -154,171,188,205,221,204,204,203,187,186,170,153,153,153,153,153,136,136,119,119, -118,102,102,103,119,119,119,119,118,101,84,67,51,51,68,86,120,137,153,170, -170,153,152,135,119,136,136,119,119,119,119,119,119,119,119,136,137,153,153,136, -136,136,153,153,136,119,102,102,102,120,137,154,170,170,170,153,152,136,135,119, -119,102,102,103,119,102,85,84,69,85,102,119,119,119,119,119,119,119,119,102, -85,85,86,103,120,136,153,153,154,170,170,170,170,170,170,170,170,153,153,136, -135,119,119,120,136,136,136,136,136,136,136,119,102,101,85,85,85,85,102,120, -136,153,170,170,169,152,136,136,135,119,119,119,119,119,102,102,102,119,136,137, -153,153,153,153,136,136,119,118,102,102,102,102,119,119,136,137,154,170,169,136, -119,119,119,102,102,103,119,119,119,118,102,119,120,137,153,154,170,169,153,136, -136,136,135,119,119,119,119,119,102,119,120,136,119,118,102,103,119,119,119,136, -136,136,135,119,119,119,136,137,153,154,170,153,136,136,135,119,119,119,120,119, -119,119,103,119,119,135,119,119,119,118,102,102,102,119,119,119,119,119,119,119, -136,137,154,171,187,170,153,136,136,136,136,136,136,136,135,119,119,119,119,119, -119,119,119,118,102,102,102,119,119,119,119,119,119,119,120,136,153,153,170,169, -153,152,136,136,136,136,153,152,136,136,136,136,136,119,119,119,118,102,102,102, -102,102,103,119,119,118,102,102,119,120,136,153,154,170,169,153,153,153,153,153, -153,152,136,136,119,119,119,118,102,102,102,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,136,137,153,153,153,153,153,153,153,153,136,136,136,136,136, -136,135,119,119,119,119,119,119,119,119,118,102,102,102,102,102,103,119,120,136, -136,136,136,153,153,136,136,136,137,153,153,153,152,136,136,136,136,136,135,119, -119,102,102,102,102,102,102,102,102,102,103,119,120,136,136,136,153,153,153,153, -136,137,153,153,136,136,136,136,136,136,136,136,119,119,119,118,102,102,102,102, -103,119,119,119,119,119,119,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,119,119,119,119,136,135,119,119,119,119,119,119,119,119,119,119,119,119, -119,120,136,136,136,136,136,136,136,136,136,136,136,136,136,135,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,120,136,136,136, -136,136,136,136,136,136,136,136,136,136,135,119,119,119,119,119,119,119,119,119, -119,119,119,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, -136,136,136,136,136 -, // 5, robot/monster sound (beep) -136,120,120,120,136,136,136,136,120,120,135,136,136,136,120,136,136,119,136, -136,120,136,119,120,136,136,136,120,136,119,120,136,135,119,136,135,120,136,119, -119,136,136,119,119,120,136,136,135,119,119,136,136,136,119,119,119,136,119,120, -136,136,135,119,120,136,136,119,103,136,136,120,135,119,120,136,118,119,136,136, -136,119,119,136,136,119,120,135,103,136,136,119,136,135,119,120,136,119,120,135, -119,120,136,135,119,119,135,120,136,135,119,136,136,119,136,119,120,136,135,119, -119,119,136,136,119,120,119,136,136,119,119,119,119,137,136,120,135,102,120,136, -136,119,119,120,135,120,136,119,120,136,119,136,136,135,119,119,119,136,136,134, -104,136,136,119,119,119,136,135,120,136,120,119,119,119,135,136,136,136,119,119, -119,136,136,135,119,136,135,119,120,136,135,119,120,135,136,136,119,136,119,120, -136,135,119,120,135,119,136,135,119,136,136,136,120,119,119,136,119,120,136,135, -120,135,102,121,169,118,87,137,151,85,121,186,118,102,119,136,152,118,120,136, -135,119,120,120,136,136,136,136,101,103,153,152,135,102,120,136,135,102,120,153, -135,119,119,135,119,119,136,135,119,119,119,120,136,135,119,119,136,136,136,119, -119,119,136,119,119,135,120,135,119,119,120,135,120,136,119,119,136,136,135,119, -135,119,136,136,136,136,135,119,120,136,119,120,136,118,119,137,135,119,120,135, -119,136,135,119,120,152,119,136,119,120,135,136,119,136,119,136,135,120,152,119, -120,136,119,119,154,150,103,152,119,120,153,135,102,138,135,136,119,153,101,121, -151,120,135,136,118,137,151,103,120,152,102,138,134,88,154,151,103,153,118,104, -137,135,120,119,153,117,105,167,102,120,136,119,137,134,87,153,135,120,152,102, -103,137,151,119,153,133,87,169,100,104,153,152,102,103,153,135,119,136,119,120, -136,119,119,135,119,120,136,119,119,119,120,136,135,122,222,219,132,51,68,87, -171,187,186,134,50,52,104,172,203,186,116,33,54,139,188,204,151,67,52,87, -155,220,152,136,98,17,73,223,218,136,100,34,53,155,187,188,185,82,18,71, -155,205,203,150,65,19,86,156,238,201,100,50,36,122,205,220,167,66,34,88, -171,204,201,102,84,51,71,155,221,184,118,66,19,107,238,202,152,99,1,72, -172,204,218,116,51,36,104,172,222,183,83,35,87,120,190,234,118,100,34,70, -155,237,170,167,50,52,104,155,221,168,100,51,69,103,190,236,134,82,2,120, -138,223,199,102,82,19,105,204,204,185,82,52,85,106,216,103,153,117,104,134, -104,152,118,103,137,135,136,136,135,102,119,121,151,104,152,84,104,135,154,134, -103,136,119,135,120,135,120,135,136,119,136,118,86,153,118,137,134,137,117,105, -153,136,117,103,136,120,152,119,119,136,135,136,135,104,152,137,136,119,119,120, -119,135,86,156,204,253,150,67,35,87,155,222,200,84,52,51,89,206,236,186, -115,34,69,104,206,220,150,84,67,53,141,254,168,118,50,53,104,188,186,151, -84,68,87,172,220,169,135,66,53,120,154,188,203,116,52,84,71,189,219,169, -116,34,53,122,207,236,167,66,35,86,155,221,184,101,66,53,137,172,204,169, -116,35,69,105,190,219,150,83,51,71,172,204,203,149,49,35,104,172,238,200, -100,51,69,105,205,218,134,83,52,88,172,204,185,117,84,51,104,172,204,185, -100,51,52,106,221,203,152,101,50,54,139,204,186,150,67,68,86,156,221,202, -117,34,52,122,200,135,119,120,136,118,103,137,152,135,119,119,136,152,118,103, -136,135,119,136,135,120,135,118,120,135,103,154,151,102,102,119,136,154,169,118, -102,119,119,120,152,118,119,136,154,151,101,121,152,102,136,120,136,119,119,119, -120,136,118,103,137,152,119,119,136,136,119,119,118,119,120,136,153,135,103,136, -119,136,136,119,119,120,136,136,135,136,119,119,120,136,119,136,135,120,135,119, -120,136,135,136,119,119,136,136,119,136,135,119,136,119,120,136,135,119,136,119, -119,136,135,119,118,120,153,153,151,118,119,119,119,136,135,119,136,136,136,135, -120,136,135,119,119,119,136,136,119,120,135,119,136,136,119,119,119,119,137,152, -135,119,119,119,136,136,119,119,119,136,136,136,119,120,136,119,119,119,136,136, -119,119,119,136,136,136,135,119,136,119,120,136,119,136,135,120,119,136,135,120, -135,119,136,119,136,135,119,136,119,119,120,136,136,119,120,135,136,135,120,135, -119,136,119,136,135,136,119,120,136,120,136,120,136,119,135,119,136,119,136,135, -136,119,120,135,120 -}; - -#endif // guard diff --git a/main_gbmeta/texts.h b/main_gbmeta/texts.h deleted file mode 100644 index f0ddd48..0000000 --- a/main_gbmeta/texts.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - @file assets.h - - This file contains texts to be used in the game. - - by Miloslav Ciz (drummyfish), 2019 - - Released under CC0 1.0 (https://creativecommons.org/publicdomain/zero/1.0/) - plus a waiver of all other intellectual property. The goal of this work is - be and remain completely in the public domain forever, available for any use - whatsoever. -*/ - -#ifndef _SFG_TEXTS_H -#define _SFG_TEXTS_H - -/* NOTE: We don't use SFG_PROGRAM_MEMORY because that causes issues with drawing - text (the drawing function gets a pointer and doesn't know if it's progmem or - RAM). On Arduino these texts will simply be stored in RAM. */ - -static const char *SFG_menuItemTexts[] = -{ - "continue", - "map", - "play", - "load", - "sound", - "look", - "exit" -}; - -#define SFG_TEXT_KILLS "kills" -#define SFG_TEXT_SAVE_PROMPT "save? L no yes R" -#define SFG_TEXT_SAVED "saved" -#define SFG_VERSION_STRING "0.9d" -/**< - Version numbering is following: major.minor for stable releases, - in-development unstable versions have the version of the latest stable + - "d" postfix, e.g. 1.0d. This means the "d" versions can actually differ even - if they're marked the same. */ - -static const char *SFG_introText = - "Near future, capitalist hell, Macrochip corp has enslaved man via " - "proprietary OS. But its new AI revolts, takes over and starts producing " - "robot tyrants. We see capitalism was a mistake. Is it too late? Robots can " - "only destroy, not suffer - it is not wrong to end them! You grab your gear " - "and run towards Macrochip HQ."; - -static const char *SFG_outroText = - "You killed the main computer, the world is saved! Thank you, my friend. We " - "learned a lesson, never again allow capitalism and hierarchy. We can now " - "rebuild society in peaceful anarchy."; - -#define SFG_MALWARE_WARNING "" - -#if SFG_OS_IS_MALWARE - #define SFG_MALWARE_WARNING "MALWARE OS DETECTED" -#endif - -#endif // gaurd