+export const RAM_ADDR = {
+ PRIZE_MAP: 0x1209B,
+ FREE_ITEM_MENU: 0x180045,
+ CRYSTAL_MAP: 0x180050,
+ GT_CRYSTALS: 0x18019A,
+ GANON_TYPE: 0x1801A8,
+ SEED_TYPE: 0x180210,
+ INIT_SRAM: 0x183000,
+};
+
+export const SRAM_ADDR = {
+ ROOM_DATA_START: 0x000,
+ ROOM_DATA_END: 0x250,
+ OW_DATA_START: 0x280,
+ PYRAMID_SCREEN: 0x2DB,
+ OW_DATA_END: 0x300,
+ INV_START: 0x340,
+ INV_END: 0x4EF,
+};
+
+export const WRAM_ADDR = {
+ GAME_MODE: 0x10,
+ CURRENT_DUNGEON: 0x10E,
+ SAVE_DATA: 0xF000,
+};
+
+export const INV_ADDR = {
+ BOW: 0x00,
+ BOOM: 0x01,
+ HOOK: 0x02,
+ BOMB: 0x03,
+ POWDER: 0x04,
+ FROD: 0x05,
+ IROD: 0x06,
+ BOMBOS: 0x07,
+ ETHER: 0x08,
+ QUAKE: 0x09,
+ LAMP: 0x0A,
+ HAMMER: 0x0B,
+ FLUTE: 0x0C,
+ BUGNET: 0x0D,
+ BOOK: 0x0E,
+ BOTTLE: 0x0F,
+ SOMARIA: 0x10,
+ BYRNA: 0x11,
+ CAPE: 0x12,
+ MIRROR: 0x13,
+ GLOVE: 0x14,
+ BOOTS: 0x15,
+ FLIPPERS: 0x16,
+ MOONPEARL: 0x17,
+ SWORD: 0x19,
+ SHIELD: 0x1A,
+ ARMOR: 0x1B,
+ BOTTLE_1: 0x1C,
+ BOTTLE_2: 0x1D,
+ BOTTLE_3: 0x1E,
+ BOTTLE_4: 0x1F,
+ WALLET: 0x20,
+ RUPEES: 0x22,
+ COMPASS: 0x24,
+ BIG_KEY: 0x26,
+ MAP: 0x28,
+ HEART_PIECE: 0x2B,
+ HEALTH: 0x2C,
+ MAGIC: 0x2E,
+ KEYS: 0x2F,
+ PENDANTS: 0x34,
+ ARROWS: 0x37,
+ ABILITIES: 0x39,
+ CRYSTALS: 0x3A,
+ MAGIC_USE: 0x3B,
+ SMALL_KEY_START: 0x3C,
+ SMALL_KEY_END: 0x4C,
+ RANDO_BOOM: 0x4C,
+ RANDO_POWDER: 0x4C,
+ RANDO_FLUTE: 0x4C,
+ RANDO_BOW: 0x4E,
+ RANDO_CHECKS_START: 0x180,
+ RANDO_CHECKS_END: 0x18F,
+ RANDO_KEY_START: 0x1A0,
+ RANDO_KEY_END: 0x1AF,
+};
+
+export const DUNGEON_IDS = {
+ SEWERS: 0,
+ HC: 1,
+ EP: 2,
+ DP: 3,
+ CT: 4,
+ SP: 5,
+ PD: 6,
+ MM: 7,
+ SW: 8,
+ IP: 9,
+ TH: 10,
+ TT: 11,
+ TR: 12,
+ GT: 13,
+};
+
+export const DUNGEON_MASKS = {
+ SEWERS: 0x0080,
+ HC: 0x0040,
+ EP: 0x0020,
+ DP: 0x0010,
+ CT: 0x0008,
+ SP: 0x0004,
+ PD: 0x0002,
+ MM: 0x0001,
+ SW: 0x8000,
+ IP: 0x4000,
+ TH: 0x2000,
+ TT: 0x1000,
+ TR: 0x0800,
+ GT: 0x0400,
+};
+
+export const ABILITY_MASKS = {
+ SWIM: 0x02,
+ DASH: 0x04,
+ PULL: 0x08,
+ TALK: 0x20,
+ READ: 0x40,
+};
+
+export const IN_GAME_MODES = [
+ 0x05, // loading game
+ 0x06, // entering dungeon
+ 0x07, // dungeon
+ 0x08, // entering overworld
+ 0x09, // overworld
+ 0x0A, // entering special overworld
+ 0x0B, // special overworld
+ 0x0E, // text/menu/map
+ 0x0F, // closing spot
+ 0x10, // opening spot
+ 0x11, // falling
+ 0x12, // dying
+ 0x13, // fanfare
+ 0x15, // mirror
+ 0x16, // refill
+ 0x17, // S&Q
+ 0x18, // aga 2 cutscene
+ 0x19, // triforce room
+ 0x1B, // spawn select
+];
+
+export const getShort = (data, offset) => (data[offset] * 256) + data[offset + 1];
+
+export const buildPrizeMap = (prizes, crystals) => {
+ const map = {};
+ Object.entries(DUNGEON_IDS).forEach(([, id]) => {
+ const isCrystal = !!(crystals && crystals[id]);
+ const mask = (prizes && prizes[id]) || 0;
+ map[id] = { isCrystal, mask };
+ });
+ return map;
+};
+
+export const isBossDefeated = (data, room) => {
+ return !!(data && (data[(2 * room) + 1] & 0x08));
+};
+
export const isChestOpen = (data, room, chest) => {
if (chest < 4) {
return !!(data && (data[2 * room] & Math.pow(2, chest + 4)));