X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=resources%2Fjs%2Fhelpers%2Falttp-ram.js;h=d5bfa1bf2ef8f581c78907a09814b456664286ee;hb=b5a50d74cf042fa7fc874d8184dc37ae20bb74dd;hp=2ae71cf58f48b857aa2b8a14fa6b1311f4d0fc37;hpb=b833b712555c4db00ada3d1fe3b2cee4774dc3e0;p=alttp.git diff --git a/resources/js/helpers/alttp-ram.js b/resources/js/helpers/alttp-ram.js index 2ae71cf..d5bfa1b 100644 --- a/resources/js/helpers/alttp-ram.js +++ b/resources/js/helpers/alttp-ram.js @@ -1,3 +1,165 @@ +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_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)));