diff options
| author | Rangi <remy.oukaour+rangi42@gmail.com> | 2022-06-17 22:54:49 -0400 |
|---|---|---|
| committer | Rangi <remy.oukaour+rangi42@gmail.com> | 2022-06-17 22:54:49 -0400 |
| commit | 61b7f6c61647d4a60145049579fff101c0c44cd9 (patch) | |
| tree | 615397cfc448e31a1a1785e09d68b4a586e19735 /ram | |
| parent | Rename `SLP` to `SLP_MASK` (#89) (diff) | |
| download | pokeyellow-61b7f6c61647d4a60145049579fff101c0c44cd9.tar.gz pokeyellow-61b7f6c61647d4a60145049579fff101c0c44cd9.tar.xz pokeyellow-61b7f6c61647d4a60145049579fff101c0c44cd9.zip | |
Add a subdirectory for RAM files
Diffstat (limited to 'ram')
| -rw-r--r-- | ram/hram.asm | 412 | ||||
| -rw-r--r-- | ram/sram.asm | 53 | ||||
| -rw-r--r-- | ram/vram.asm | 31 | ||||
| -rw-r--r-- | ram/wram.asm | 2601 |
4 files changed, 3097 insertions, 0 deletions
diff --git a/ram/hram.asm b/ram/hram.asm new file mode 100644 index 00000000..0e9a61e1 --- /dev/null +++ b/ram/hram.asm @@ -0,0 +1,412 @@ +SECTION "HRAM", HRAM + +; Initialized to 16. +; Decremented each input iteration if the player +; presses the reset sequence (A+B+SEL+START). +; Soft reset when 0 is reached. +hSoftReset:: db + +UNION +hBaseTileID:: ; base tile ID to which offsets are added +hDexWeight:: +hWarpDestinationMap:: +hOAMTile:: +hROMBankTemp:: +hPreviousTileset:: +hRLEByteValue:: + db + +hSpriteIndexOrTextID:: ; DisplayTextID's argument +hPartyMonIndex:: + db + +hVRAMSlot:: + db + +hFourTileSpriteCount:: +hHalveItemPrices:: + db + +NEXTU +hItemPrice:: ds 3 ; BCD number + +NEXTU +hSlideAmount:: db + +; the total number of tiles being shifted each time the pic slides by one tile +hSlidingRegionSize:: db + +; -1 = left +; 0 = right +hSlideDirection:: db + +NEXTU +hSpriteInterlaceCounter:: +hSpriteWidth:: db ; in tiles +hSpriteHeight:: db ; in tiles +hSpriteOffset:: db + +NEXTU +; counters for blinking down arrow +hDownArrowBlinkCount1:: db +hDownArrowBlinkCount2:: db + +NEXTU +hMapStride:: +hEastWestConnectedMapWidth:: +hNorthSouthConnectionStripWidth:: + db +hMapWidth:: +hNorthSouthConnectedMapWidth:: + db + +NEXTU +hSpriteDataOffset:: db +hSpriteIndex:: db +hSpriteImageIndex:: +hSpriteFacingDirection:: +hSpriteMovementByte2:: + db + +NEXTU + ds 2 +hLoadSpriteTemp1:: db +hLoadSpriteTemp2:: db + +NEXTU + ds 2 +hEnemySpeed:: dw +ENDU + +UNION +hSpriteOffset2:: db +hOAMBufferOffset:: db +hSpriteScreenX:: db +hSpriteScreenY:: db + +NEXTU +hFF8F:: db +hFF90:: db +hFF91:: db +hFF92:: db +ENDU + +hTilePlayerStandingOn:: db + +hSpritePriority:: db + +UNION +; Multiplication and division variables are meant +; to overlap for back-to-back usage. Big endian. +UNION + ds 1 +hMultiplicand:: ds 3 +hMultiplier:: db + ds 1 +hMultiplyBuffer:: ds 4 +NEXTU +hProduct:: ds 4 +NEXTU +hDividend:: ds 4 +hDivisor:: db +hDivideBuffer:: ds 5 +NEXTU +hQuotient:: ds 4 +hRemainder:: db +ENDU + +NEXTU +; PrintNumber (big endian). +hPastLeadingZeros:: db ; last char printed +hNumToPrint:: ds 3 +hPowerOf10:: ds 3 +hSavedNumToPrint:: ds 3 + +NEXTU +hNPCMovementDirections2Index:: +hNPCSpriteOffset:: +; distance in steps between NPC and player +hNPCPlayerYDistance:: + db +hNPCPlayerXDistance:: + db +hFindPathNumSteps:: db +; bit 0: set when the end of the path's Y coordinate matches the target's +; bit 1: set when the end of the path's X coordinate matches the target's +; When both bits are set, the end of the path is at the target's position +; (i.e. the path has been found). +hFindPathFlags:: db +hFindPathYProgress:: db +hFindPathXProgress:: db +; 0 = from player to NPC +; 1 = from NPC to player +hNPCPlayerRelativePosPerspective:: db + ds 1 +; bit 0: +; 0 = target is to the south or aligned +; 1 = target is to the north +; bit 1: +; 0 = target is to the east or aligned +; 1 = target is to the west +hNPCPlayerRelativePosFlags:: db + +NEXTU +hSwapItemID:: db +hSwapItemQuantity:: db + +NEXTU +hSignCoordPointer:: dw + +NEXTU + ds 1 +hMutateWY:: db +hMutateWX:: db + +NEXTU +; temp value used when swapping bytes or words +hSwapTemp:: db +hExperience:: ds 3 ; big endian +ENDU + +UNION +hMoney:: ds 3 ; BCD number +NEXTU +; some code zeroes this for no reason when writing a coin amount +hUnusedCoinsByte:: db +hCoins:: ds 2 ; BCD number +ENDU + +hDivideBCDDivisor:: +hDivideBCDQuotient:: + ds 3 ; BCD number +hDivideBCDBuffer:: + ds 3 ; BCD number + + ds 1 + +hSerialReceivedNewData:: db +; $01 = using external clock +; $02 = using internal clock +; $ff = establishing connection +hSerialConnectionStatus:: db +hSerialIgnoringInitialData:: db +hSerialSendData:: db +hSerialReceiveData:: db + +; these values are copied to rSCX, rSCY, and rWY during V-blank +hSCX:: db +hSCY:: db +hWY:: db + +hJoyLast:: db +hJoyReleased:: db +hJoyPressed:: db +hJoyHeld:: db +hJoy5:: db +hJoy6:: db +hJoy7:: db + +hLoadedROMBank:: db +hSavedROMBank:: db + +; is automatic background transfer during V-blank enabled? +; if nonzero, yes +; if zero, no +hAutoBGTransferEnabled:: db + +; 00 = top third of background +; 01 = middle third of background +; 02 = bottom third of background +hAutoBGTransferPortion:: db + +; the destination address of the automatic background transfer +hAutoBGTransferDest:: dw + +hRedrawMapViewRowOffset:: db + +; temporary storage for stack pointer during memory transfers that use pop +; to increase speed +hSPTemp:: dw + +; source address for VBlankCopyBgMap function +; the first byte doubles as the byte that enabled the transfer. +; if it is 0, the transfer is disabled +; if it is not 0, the transfer is enabled +; this means that XX00 is not a valid source address +hVBlankCopyBGSource:: dw + +; destination address for VBlankCopyBgMap function +hVBlankCopyBGDest:: dw + +; number of rows for VBlankCopyBgMap to copy +hVBlankCopyBGNumRows:: db + +; size of VBlankCopy transfer in 16-byte units +hVBlankCopySize:: db + +; source address for VBlankCopy function +hVBlankCopySource:: dw + +; destination address for VBlankCopy function +hVBlankCopyDest:: dw + +; size of source data for VBlankCopyDouble in 8-byte units +hVBlankCopyDoubleSize:: db + +; source address for VBlankCopyDouble function +hVBlankCopyDoubleSource:: dw + +; destination address for VBlankCopyDouble function +hVBlankCopyDoubleDest:: dw + +; controls whether a row or column of 2x2 tile blocks is redrawn in V-blank +; 00 = no redraw +; 01 = redraw column +; 02 = redraw row +hRedrawRowOrColumnMode:: db + +hRedrawRowOrColumnDest:: dw + +hRandomAdd:: db +hRandomSub:: db + +hFrameCounter:: db ; decremented every V-blank (used for delays) + +; V-blank sets this to 0 each time it runs. +; So, by setting it to a nonzero value and waiting for it to become 0 again, +; you can detect that the V-blank handler has run since then. +hVBlankOccurred:: db + +; Controls which tiles are animated. +; 0 = no animations (breaks Surf) +; 1 = water tile $14 is animated +; 2 = water tile $14 and flower tile $03 are animated +hTileAnimations:: db + +hMovingBGTilesCounter1:: db + + ds 1 + +hCurrentSpriteOffset:: db ; multiple of $10 + +UNION +hPlayerFacing:: db +hPlayerYCoord:: db +hPlayerXCoord:: db + +NEXTU + +; $00 = bag full +; $01 = got item +; $80 = didn't meet required number of owned mons +; $FF = player cancelled +hOaksAideResult:: +hOaksAideRequirement:: ; required number of owned mons + db +hOaksAideRewardItem:: db +hOaksAideNumMonsOwned:: db + +NEXTU +hVendingMachineItem:: db +hVendingMachinePrice:: ds 3 ; BCD number + +NEXTU +hGymGateIndex:: db +hGymGateAnswer:: db + +NEXTU +hDexRatingNumMonsSeen:: db +hDexRatingNumMonsOwned:: db + +NEXTU +hItemToRemoveID:: db +hItemToRemoveIndex:: db + +NEXTU +hItemCounter:: +hSavedCoordIndex:: +hMissableObjectIndex:: +hGymTrashCanRandNumMask:: + db + +NEXTU +hFFDB:: db +hFFDC:: db + +NEXTU +hCanceledPrinting:: db +ENDU + + ds 1 + +hBackupGymGateIndex:: +hUnlockedSilphCoDoors:: + db + +; the first tile ID in a sequence of tile IDs that increase by 1 each step +hStartTileID:: db + + ds 2 + +hNewPartyLength:: db + +UNION +hDividend2:: db +hDivisor2:: db +hQuotient2:: db + +NEXTU +hIsHiddenMissableObject:: db +ENDU + +hMapROMBank:: db + +hSpriteVRAMSlotAndFacing:: db + +hCoordsInFrontOfPlayerMatch:: +hSpriteAnimFrameCounter:: + db + +UNION +hSpriteScreenYCoord:: db +hSpriteScreenXCoord:: db +hSpriteMapYCoord:: db +hSpriteMapXCoord:: db + +NEXTU +hItemAlreadyFound:: db + ds 2 +hDidntFindAnyHiddenObject:: db + +NEXTU + ds 1 +hSavedMapTextPtr:: dw + ds 1 +ENDU + + ds 4 + +hWhoseTurn:: db ; 0 on player's turn, 1 on enemy's turn + +hLCDCPointer:: db + +hJoyInput:: db + + ds 2 + +hDisableJoypadPolling:: db + +hClearLetterPrintingDelayFlags:: db + +; bit 0: draw HP fraction to the right of bar instead of below (for party menu) +; bit 1: menu is double spaced +hUILayoutFlags:: db + +hFieldMoveMonMenuTopMenuItemX:: db + +hPikachuSpriteVRAMOffset:: db + + ds 1 + +; 0 if DMG, != 0 if GBC +hGBC:: db diff --git a/ram/sram.asm b/ram/sram.asm new file mode 100644 index 00000000..6cb45371 --- /dev/null +++ b/ram/sram.asm @@ -0,0 +1,53 @@ +SECTION "Sprite Buffers", SRAM + +sSpriteBuffer0:: ds SPRITEBUFFERSIZE +sSpriteBuffer1:: ds SPRITEBUFFERSIZE +sSpriteBuffer2:: ds SPRITEBUFFERSIZE + + ds $100 + +sHallOfFame:: ds HOF_TEAM * HOF_TEAM_CAPACITY + + +SECTION "Save Data", SRAM + + ds $598 + +sGameData:: +sPlayerName:: ds NAME_LENGTH +sMainData:: ds wMainDataEnd - wMainDataStart +sSpriteData:: ds wSpriteDataEnd - wSpriteDataStart +sPartyData:: ds wPartyDataEnd - wPartyDataStart +sCurBoxData:: ds wBoxDataEnd - wBoxDataStart +sTileAnimations:: db +sGameDataEnd:: +sMainDataCheckSum:: db + + +; The PC boxes will not fit into one SRAM bank, +; so they use multiple SECTIONs +DEF box_n = 0 +MACRO boxes + REPT \1 + DEF box_n += 1 + sBox{d:box_n}:: ds wBoxDataEnd - wBoxDataStart + ENDR +ENDM + +SECTION "Saved Boxes 1", SRAM + +; sBox1 - sBox6 + boxes 6 +sBank2AllBoxesChecksum:: db +sBank2IndividualBoxChecksums:: ds 6 + +SECTION "Saved Boxes 2", SRAM + +; sBox7 - sBox12 + boxes 6 +sBank3AllBoxesChecksum:: db +sBank3IndividualBoxChecksums:: ds 6 + +; All 12 boxes fit within 2 SRAM banks + ASSERT box_n == NUM_BOXES, \ + "boxes: Expected {d:NUM_BOXES} total boxes, got {d:box_n}" diff --git a/ram/vram.asm b/ram/vram.asm new file mode 100644 index 00000000..21230ac0 --- /dev/null +++ b/ram/vram.asm @@ -0,0 +1,31 @@ +SECTION "VRAM", VRAM + +UNION +; generic +vChars0:: ds $80 tiles +vChars1:: ds $80 tiles +vChars2:: ds $80 tiles +vBGMap0:: ds BG_MAP_WIDTH * BG_MAP_HEIGHT +vBGMap1:: ds BG_MAP_WIDTH * BG_MAP_HEIGHT + +NEXTU +; battle/menu +vSprites:: ds $80 tiles +vFont:: ds $80 tiles +vFrontPic:: ds 7 * 7 tiles +vBackPic:: ds 7 * 7 tiles + +NEXTU +; overworld +vNPCSprites:: ds $80 tiles +vNPCSprites2:: ds $80 tiles +vTileset:: ds $80 tiles + +NEXTU +; title + ds $80 tiles +vTitleLogo:: ds $80 tiles + ds 7 * 7 tiles +vTitleLogo2:: ds 30 tiles + +ENDU diff --git a/ram/wram.asm b/ram/wram.asm new file mode 100644 index 00000000..80cd15a6 --- /dev/null +++ b/ram/wram.asm @@ -0,0 +1,2601 @@ +SECTION "Audio RAM", WRAM0 + +wUnusedC000:: db + +wSoundID:: db + +; bit 7: whether sound has been muted +; all bits: whether the effective is active +; Store 1 to activate effect (any value in the range [1, 127] works). +; All audio is muted and music is paused. Sfx continues playing until it +; ends normally. +; Store 0 to resume music. +wMuteAudioAndPauseMusic:: db + +wDisableChannelOutputWhenSfxEnds:: db + +wStereoPanning:: db + +wSavedVolume:: db + +wChannelCommandPointers:: ds NUM_CHANNELS * 2 +wChannelReturnAddresses:: ds NUM_CHANNELS * 2 + +wChannelSoundIDs:: ds NUM_CHANNELS + +wChannelFlags1:: ds NUM_CHANNELS +wChannelFlags2:: ds NUM_CHANNELS + +wChannelDutyCycles:: ds NUM_CHANNELS +wChannelDutyCyclePatterns:: ds NUM_CHANNELS + +; reloaded at the beginning of a note. counts down until the vibrato begins. +wChannelVibratoDelayCounters:: ds NUM_CHANNELS +wChannelVibratoExtents:: ds NUM_CHANNELS +; high nybble is rate (counter reload value) and low nybble is counter. +; time between applications of vibrato. +wChannelVibratoRates:: ds NUM_CHANNELS +wChannelFrequencyLowBytes:: ds NUM_CHANNELS +; delay of the beginning of the vibrato from the start of the note +wChannelVibratoDelayCounterReloadValues:: ds NUM_CHANNELS + +wChannelPitchSlideLengthModifiers:: ds NUM_CHANNELS +wChannelPitchSlideFrequencySteps:: ds NUM_CHANNELS +wChannelPitchSlideFrequencyStepsFractionalPart:: ds NUM_CHANNELS +wChannelPitchSlideCurrentFrequencyFractionalPart:: ds NUM_CHANNELS +wChannelPitchSlideCurrentFrequencyHighBytes:: ds NUM_CHANNELS +wChannelPitchSlideCurrentFrequencyLowBytes:: ds NUM_CHANNELS +wChannelPitchSlideTargetFrequencyHighBytes:: ds NUM_CHANNELS +wChannelPitchSlideTargetFrequencyLowBytes:: ds NUM_CHANNELS + +; Note delays are stored as 16-bit fixed-point numbers where the integer part +; is 8 bits and the fractional part is 8 bits. +wChannelNoteDelayCounters:: ds NUM_CHANNELS +wChannelLoopCounters:: ds NUM_CHANNELS +wChannelNoteSpeeds:: ds NUM_CHANNELS +wChannelNoteDelayCountersFractionalPart:: ds NUM_CHANNELS + +wChannelOctaves:: ds NUM_CHANNELS +; also includes fade for hardware channels that support it +wChannelVolumes:: ds NUM_CHANNELS + +wMusicWaveInstrument:: db +wSfxWaveInstrument:: db +wMusicTempo:: dw +wSfxTempo:: dw +wSfxHeaderPointer:: dw + +wNewSoundID:: db + +wAudioROMBank:: db +wAudioSavedROMBank:: db + +wFrequencyModifier:: db +wTempoModifier:: db + +wc0f3:: dw + + ds 11 + + +SECTION "Sprite State Data", WRAM0 + +wSpriteDataStart:: + +; data for all sprites on the current map +; holds info for 16 sprites with $10 bytes each +wSpriteStateData1:: +; struct fields: +; - 0: picture ID (fixed, loaded at map init) +; - 1: movement status (0: uninitialized, 1: ready, 2: delayed, 3: moving) +; - 2: sprite image index (changed on update, $ff if off screen, includes facing direction, progress in walking animation and a sprite-specific offset) +; - 3: Y screen position delta (-1,0 or 1; added to Y pixels on each walking animation update) +; - 4: Y screen position (in pixels, always 4 pixels above grid which makes sprites appear to be in the center of a tile) +; - 5: X screen position delta (-1,0 or 1; added to field X pixels on each walking animation update) +; - 6: X screen position (in pixels, snaps to grid if not currently walking) +; - 7: intra-animation-frame counter (counting upwards to 4 until animation frame counter is incremented) +; - 8: animation frame counter (increased every 4 updates, hold four states (totalling to 16 walking frames) +; - 9: facing direction ($0: down, $4: up, $8: left, $c: right) +; - A: adjusted Y coordinate +; - B: adjusted X coordinate +; - C: direction of collision +; - D +; - E +; - F +wSpritePlayerStateData1:: spritestatedata1 wSpritePlayerStateData1 ; player is struct 0 +; wSprite02StateData1 - wSprite15StateData1 +FOR n, 1, NUM_SPRITESTATEDATA_STRUCTS - 1 +wSprite{02d:n}StateData1:: spritestatedata1 wSprite{02d:n}StateData1 +ENDR +wSpritePikachuStateData1:: spritestatedata1 wSpritePikachuStateData1 ; pikachu is struct 15 + +; more data for all sprites on the current map +; holds info for 16 sprites with $10 bytes each +wSpriteStateData2:: +; struct fields: +; - 0: walk animation counter (counting from $10 backwards when moving) +; - 1: +; - 2: Y displacement (initialized at 8, supposed to keep moving sprites from moving too far, but bugged) +; - 3: X displacement (initialized at 8, supposed to keep moving sprites from moving too far, but bugged) +; - 4: Y position (in 2x2 tile grid steps, topmost 2x2 tile has value 4) +; - 5: X position (in 2x2 tile grid steps, leftmost 2x2 tile has value 4) +; - 6: movement byte 1 (determines whether a sprite can move, $ff:not moving, $fe:random movements, others unknown) +; - 7: (?) (set to $80 when in grass, else $0; may be used to draw grass above the sprite) +; - 8: delay until next movement (counted downwards, movement status is set to ready if reached 0) +; - 9: original facing direction (backed up by DisplayTextIDInit, restored by CloseTextDisplay) +; - A +; - B +; - C +; - D: picture ID +; - E: sprite image base offset (in video ram, player always has value 1, used to compute sprite image index) +; - F +wSpritePlayerStateData2:: spritestatedata2 wSpritePlayerStateData2 ; player is struct 0 +; wSprite02StateData2 - wSprite15StateData2 +FOR n, 1, NUM_SPRITESTATEDATA_STRUCTS - 1 +wSprite{02d:n}StateData2:: spritestatedata2 wSprite{02d:n}StateData2 +ENDR +wSpritePikachuStateData2:: spritestatedata2 wSpritePikachuStateData2 ; pikachu is struct 15 + +; The high byte of a pointer to anywhere within wSpriteStateData1 can be incremented +; to reach within wSpriteStateData2, and vice-versa for decrementing. +ASSERT HIGH(wSpriteStateData1) + 1 == HIGH(wSpriteStateData2) +ASSERT LOW(wSpriteStateData1) == 0 && LOW(wSpriteStateData2) == 0 + +wSpriteDataEnd:: + + +SECTION "OAM Buffer", WRAM0 + +; buffer for OAM data. Copied to OAM by DMA +wOAMBuffer:: +; wOAMBufferSprite00 - wOAMBufferSprite39 +FOR n, NUM_SPRITE_OAM_STRUCTS +wOAMBufferSprite{02d:n}:: sprite_oam_struct wOAMBufferSprite{02d:n} +ENDR +wOAMBufferEnd:: + + +SECTION "Tilemap", WRAM0 + +; buffer for tiles that are visible on screen (20 columns by 18 rows) +wTileMap:: ds SCREEN_WIDTH * SCREEN_HEIGHT + +UNION +; buffer for temporarily saving and restoring current screen's tiles +; (e.g. if menus are drawn on top) +wTileMapBackup:: ds SCREEN_WIDTH * SCREEN_HEIGHT + +NEXTU +; list of indexes to patch with SERIAL_NO_DATA_BYTE after transfer +wSerialPartyMonsPatchList:: ds 200 + +; list of indexes to patch with SERIAL_NO_DATA_BYTE after transfer +wSerialEnemyMonsPatchList:: ds 200 + +NEXTU +; this looks similar to the address structure for Gen 2 OAM animations. +wAnimatedObjectsData:: + +wAnimatedObjectStartTileOffsets:: ds 10 * 2 + +wAnimatedObjectDataStructs:: +; wAnimatedObject0 - wAnimatedObject9 +FOR n, 10 +wAnimatedObject{d:n}:: animated_object wAnimatedObject{d:n} +ENDR + +wNumLoadedAnimatedObjects:: db +wCurrentAnimatedObjectOAMBufferOffset:: + ds 3 +wAnimatedObjectSpawnStateDataPointer:: dw +wAnimatedObjectFramesDataPointer:: dw +wAnimatedObjectJumptablePointer:: dw +wAnimatedObjectOAMDataPointer:: dw + +wCurAnimatedObjectOAMAttributes:: db +wCurrentAnimatedObjectVTileOffset:: db +wCurrentAnimatedObjectXCoord:: db +wCurrentAnimatedObjectYCoord:: db +wCurrentAnimatedObjectXOffset:: db +wCurrentAnimatedObjectYOffset:: db +wAnimatedObjectGlobalYOffset:: db +wAnimatedObjectGlobalXOffset:: db + +wAnimatedObjectsDataEnd:: + +; Surfing minigame +wSurfingMinigameData:: db +wSurfingMinigameRoutineNumber:: db +wc5d2:: db +wSurfingMinigameWaveFunctionNumber:: dw +wc5d5:: db +wSurfingMinigamePikachuHP:: dw ; little-endian BCD +wc5d8:: db ; unused? +; number of consecutive tricks +wSurfingMinigameRadnessMeter:: db +wSurfingMinigameRadnessScore:: dw ; little-endian BCD +wSurfingMinigameTotalScore:: dw ; little-endian BCD +wc5de:: db +wc5df:: db +wc5e0:: db +wc5e1:: db +wc5e2:: db +wSurfingMinigamePikachuSpeed:: dw ; little-endian +wc5e5:: ds 3 ; big-endian +wSurfingMinigameWaveHeightBuffer:: dw +wSurfingMinigamePikachuObjectHeight:: db +wc5eb:: db +wc5ec:: db +wc5ed:: db +wc5ee:: db +wSurfingMinigameBGMapReadBuffer:: ds 1 tiles + ds 24 +wSurfingMinigameSCX:: db +wSurfingMinigameSCX2:: db +wSurfingMinigameSCXHi:: db +wSurfingMinigameWaveHeight:: ds SCREEN_WIDTH +wSurfingMinigameXOffset:: db +wSurfingMinigameTrickFlags:: db +wc630:: db +wc631:: db +wSurfingMinigameRoutineDelay:: db +wSurfingMinigameIntroAnimationFinished:: db + +; Yellow intro +wYellowIntroCurrentScene:: +wc634:: db +wYellowIntroSceneTimer:: +wc635:: db +wYellowIntroAnimatedObjectStructPointer:: db +wSurfingMinigameDataEnd:: +ENDU + + ds 80 + + +SECTION "Overworld Map", WRAM0 + +UNION +wOverworldMap:: ds 1300 +wOverworldMapEnd:: + +NEXTU +wTempPic:: ds 7 * 7 tiles + +NEXTU +wPrinterData:: +wPrinterSendState:: db +wPrinterRowIndex:: db + +; Printer data header +wPrinterDataHeader:: +wc6ea:: db +wc6eb:: db +wc6ec:: db +wc6ed:: db +wPrinterChecksum:: dw + +UNION +wPrinterSerialReceived:: db +; bit 7: set if error 1 (battery low) +; bit 6: set if error 4 (too hot or cold) +; bit 5: set if error 3 (paper jammed or empty) +; if this and the previous byte are both $ff: error 2 (connection error) +wPrinterStatusReceived:: db + +wc6f2:: db +wc6f3:: db + ds 12 +wLYOverrides:: ds $100 +wLYOverridesEnd:: +wLYOverridesBuffer:: ds $100 +wLYOverridesBufferEnd:: + +NEXTU +wPrinterSendDataSource1:: ds 20 tiles +wPrinterSendDataSource2:: ds 20 tiles +ENDU + +wPrinterSendDataSource1End:: + +wPrinterHandshake:: db +wPrinterStatusFlags:: db +wHandshakeFrameDelay:: db +wPrinterSerialFrameDelay:: db +wPrinterSendByteOffset:: dw +wPrinterDataSize:: dw +wPrinterTileBuffer:: ds SCREEN_HEIGHT * SCREEN_WIDTH +wPrinterStatusIndicator:: dw +wcae2:: db +wPrinterSettingsTempCopy:: db + ds 16 +wPrinterQueueLength:: db +wPrinterDataEnd:: + +wPrinterPokedexEntryTextPointer:: dw + ds 2 +wPrinterPokedexMonIsOwned:: db + ds 226 +UNION +wcbdc:: ds 1 tiles +NEXTU + ds 14 +wcbea:: dw +ENDU +wcbec:: ds 1 tiles +ENDU + + +SECTION "WRAM", WRAM0 + +; the tiles of the row or column to be redrawn by RedrawRowOrColumn +wRedrawRowOrColumnSrcTiles:: ds SCREEN_WIDTH * 2 + +; coordinates of the position of the cursor for the top menu item (id 0) +wTopMenuItemY:: db +wTopMenuItemX:: db + +; the id of the currently selected menu item +; the top item has id 0, the one below that has id 1, etc. +; note that the "top item" means the top item currently visible on the screen +; add this value to [wListScrollOffset] to get the item's position within the list +wCurrentMenuItem:: db + +; the tile that was behind the menu cursor's current location +wTileBehindCursor:: db + +; id of the bottom menu item +wMaxMenuItem:: db + +; bit mask of keys that the menu will respond to +wMenuWatchedKeys:: db + +; id of previously selected menu item +wLastMenuItem:: db + +; It is mainly used by the party menu to remember the cursor position while the +; menu isn't active. +; It is also used to remember the cursor position of mon lists (for the +; withdraw/deposit/release actions) in Bill's PC so that it doesn't get lost +; when you choose a mon from the list and a sub-menu is shown. It's reset when +; you return to the main Bill's PC menu. +wPartyAndBillsPCSavedMenuItem:: db + +; It is used by the bag list to remember the cursor position while the menu +; isn't active. +wBagSavedMenuItem:: db + +; It is used by the start menu to remember the cursor position while the menu +; isn't active. +; The battle menu uses it so that the cursor position doesn't get lost when +; a sub-menu is shown. It's reset at the start of each battle. +wBattleAndStartSavedMenuItem:: db + +wPlayerMoveListIndex:: db + +; index in party of currently battling mon +wPlayerMonNumber:: db + +; the address of the menu cursor's current location within wTileMap +wMenuCursorLocation:: dw + + ds 2 + +; how many times should HandleMenuInput poll the joypad state before it returns? +wMenuJoypadPollCount:: db + +; id of menu item selected for swapping (counts from 1) (0 means that no menu item has been selected for swapping) +wMenuItemToSwap:: db + +; offset of the current top menu item from the beginning of the list +; keeps track of what section of the list is on screen +wListScrollOffset:: db + +; If non-zero, then when wrapping is disabled and the player tries to go past +; the top or bottom of the menu, return from HandleMenuInput. This is useful for +; menus that have too many items to display at once on the screen because it +; allows the caller to scroll the entire menu up or down when this happens. +wMenuWatchMovingOutOfBounds:: db + +wTradeCenterPointerTableIndex:: db + + ds 1 + +; destination pointer for text output +; this variable is written to, but is never read from +wTextDest:: dw + +; if non-zero, skip waiting for a button press after displaying text in DisplayTextID +wDoNotWaitForButtonPressAfterDisplayingText:: db + +UNION +; the received menu selection is stored twice +wLinkMenuSelectionReceiveBuffer:: dw + ds 3 +; the menu selection byte is stored twice before sending +wLinkMenuSelectionSendBuffer:: dw + ds 3 +wEnteringCableClub:: +wLinkTimeoutCounter:: db + +NEXTU +; temporary nybble used by Serial_ExchangeNybble +wSerialExchangeNybbleTempReceiveData:: +; the final received nybble is stored here by Serial_SyncAndExchangeNybble +wSerialSyncAndExchangeNybbleReceiveData:: db +; the final received nybble is stored here by Serial_ExchangeNybble +wSerialExchangeNybbleReceiveData:: db + ds 3 +; this nybble is sent when using Serial_SyncAndExchangeNybble or Serial_ExchangeNybble +wSerialExchangeNybbleSendData:: db + ds 4 +wUnknownSerialCounter:: dw +ENDU + +; $00 = player mons +; $01 = enemy mons +wWhichTradeMonSelectionMenu:: +; 0 = player's party +; 1 = enemy party +; 2 = current box +; 3 = daycare +; 4 = in-battle mon +; +; AddPartyMon uses it slightly differently. +; If the lower nybble is 0, the mon is added to the player's party, else the enemy's. +; If the entire value is 0, then the player is allowed to name the mon. +wMonDataLocation:: db + +; set to 1 if you can go from the bottom to the top or top to bottom of a menu +; set to 0 if you can't go past the top or bottom of the menu +wMenuWrappingEnabled:: db + +; whether to check for 180-degree turn (0 = don't, 1 = do) +wCheckFor180DegreeTurn:: db + + ds 1 + +wMissableObjectIndex:: db + +wPredefID:: db +wPredefHL:: dw +wPredefDE:: dw +wPredefBC:: dw + +wTrainerHeaderFlagBit:: db + + ds 1 + +; which NPC movement script pointer is being used +; 0 if an NPC movement script is not running +wNPCMovementScriptPointerTableNum:: db + +; ROM bank of current NPC movement script +wNPCMovementScriptBank:: db + + ds 2 + +; This union spans 180 bytes. +UNION +wVermilionDockTileMapBuffer:: ds 5 * BG_MAP_WIDTH + SCREEN_WIDTH +wVermilionDockTileMapBufferEnd:: + +NEXTU +wOaksAideRewardItemName:: ds ITEM_NAME_LENGTH + +NEXTU +wElevatorWarpMaps:: ds 11 * 2 + +NEXTU +; List of bag items that has been filtered to a certain type of items, +; such as drinks or fossils. +wFilteredBagItems:: ds 4 + +NEXTU +; Saved copy of OAM for the first frame of the animation to make it easy to +; flip back from the second frame. +wMonPartySpritesSavedOAM:: ds $60 + +NEXTU +wTrainerCardBlkPacket:: ds $40 + +NEXTU +wHallOfFame:: ds HOF_TEAM + +NEXTU +wNPCMovementDirections:: ds 180 + +NEXTU +wDexRatingNumMonsSeen:: db +wDexRatingNumMonsOwned:: db +wDexRatingText:: db + +NEXTU +; If a random number greater than this value is generated, then the player is +; allowed to have three 7 symbols or bar symbols line up. +; So, this value is actually the chance of NOT entering that mode. +; If the slot is lucky, it equals 250, giving a 5/256 (~2%) chance. +; Otherwise, it equals 253, giving a 2/256 (~0.8%) chance. +wSlotMachineSevenAndBarModeChance:: db + ds 2 +; ROM back to return to when the player is done with the slot machine +wSlotMachineSavedROMBank:: db + ds 166 +wLuckySlotHiddenObjectIndex:: db + +NEXTU +; values between 0-6. Shake screen horizontally, shake screen vertically, blink Pokemon... +wAnimationType:: db + ds 29 +wAnimPalette:: db + +NEXTU + ds 60 +; temporary buffer when swapping party mon data +wSwitchPartyMonTempBuffer:: ds 44 ; party_struct size + +NEXTU + ds 120 +; this is the end of the joypad states +; the list starts above this address and extends downwards in memory until here +; overloaded with below labels +wSimulatedJoypadStatesEnd:: + +NEXTU +wBoostExpByExpAll:: +wUnusedCC5B:: db + + ds 59 + +wNPCMovementDirections2:: ds 10 +; used in Pallet Town scripted movement +wNumStepsToTake:: db + + ds 48 + +wRLEByteCount:: db + +wParentMenuItem:: +; 0 = not added +; 1 = added +wAddedToParty:: +; 1 flag for each party member indicating whether it can evolve +; The purpose of these flags is to track which mons levelled up during the +; current battle at the end of the battle when evolution occurs. +; Other methods of evolution simply set it by calling TryEvolvingMon. +wCanEvolveFlags:: db + +wForceEvolution:: db + +; if [wAILayer2Encouragement] != 1, the second AI layer is not applied +wAILayer2Encouragement:: db + + ds 1 + +; current HP of player and enemy substitutes +wPlayerSubstituteHP:: db +wEnemySubstituteHP:: db + +; The player's selected move during a test battle. +; InitBattleVariables sets it to the move Pound. +wTestBattlePlayerSelectedMove:: db + + ds 1 + +; 0=regular, 1=mimic, 2=above message box (relearn, heal pp..) +wMoveMenuType:: db + +wPlayerSelectedMove:: db +wEnemySelectedMove:: db + +wLinkBattleRandomNumberListIndex:: db + +; number of times remaining that AI action can occur +wAICount:: db + + ds 2 + +wEnemyMoveListIndex:: db + +; The enemy mon's HP when it was switched in or when the current player mon +; was switched in, which was more recent. +; It's used to determine the message to print when switching out the player mon. +wLastSwitchInEnemyMonHP:: dw + +; total amount of money made using Pay Day during the current battle +wTotalPayDayMoney:: ds 3 + +wSafariEscapeFactor:: db +wSafariBaitFactor:: db + + ds 1 + +wTransformedEnemyMonOriginalDVs:: dw + +wMonIsDisobedient:: db + +wPlayerDisabledMoveNumber:: db +wEnemyDisabledMoveNumber:: db + +; When running in the scope of HandlePlayerMonFainted, it equals 1. +; When running in the scope of HandleEnemyMonFainted, it equals 0. +wInHandlePlayerMonFainted:: db + +wPlayerUsedMove:: db +wEnemyUsedMove:: db + +wEnemyMonMinimized:: db + +wMoveDidntMiss:: db + +; flags that indicate which party members have fought the current enemy mon +wPartyFoughtCurrentEnemyFlags:: flag_array PARTY_LENGTH + +; Whether the low health alarm has been disabled due to the player winning the +; battle. +wLowHealthAlarmDisabled:: db + +wPlayerMonMinimized:: db + + ds 13 + +; number of hits by enemy in attacks like Double Slap, etc. +wEnemyNumHits:: ; db +; the amount of damage accumulated by the enemy while biding +wEnemyBideAccumulatedDamage:: dw + + ds 8 + +NEXTU + ds 2 +wTrainerCardBadgeAttributes:: ds 6 * 9 + 1 + +NEXTU +wPikaPicUsedGFXCount:: db + +wPikaPicUsedGFX:: ds 8 * 2 +wPikaPicUsedGFXEnd:: + + ds 43 + +wPikaPicAnimObjectDataBufferSize:: db + +wPikaPicAnimObjectDataBuffer:: +; 4 structs each of length 8 +; 0: buffer index +; 1: script index +; 2: frame index +; 3: frame timer +; 4: vtile offset +; 5: x offset +; 6: y offset +; 7: unused + ds 4 * 8 +wPikaPicAnimObjectDataBufferEnd:: +ENDU + +; This union spans 39 bytes. +UNION +wInGameTradeGiveMonSpecies:: db +wInGameTradeTextPointerTablePointer:: dw +wInGameTradeTextPointerTableIndex:: db +wInGameTradeGiveMonName:: ds NAME_LENGTH +wInGameTradeReceiveMonName:: ds NAME_LENGTH +wInGameTradeMonNick:: ds NAME_LENGTH +wInGameTradeReceiveMonSpecies:: db + +NEXTU +wPlayerMonUnmodifiedLevel:: db +wPlayerMonUnmodifiedMaxHP:: dw +wPlayerMonUnmodifiedAttack:: dw +wPlayerMonUnmodifiedDefense:: dw +wPlayerMonUnmodifiedSpeed:: dw +wPlayerMonUnmodifiedSpecial:: dw + +; stat modifiers for the player's current pokemon +; value can range from 1 - 13 ($1 to $D) +; 7 is normal +wPlayerMonStatMods:: +wPlayerMonAttackMod:: db +wPlayerMonDefenseMod:: db +wPlayerMonSpeedMod:: db +wPlayerMonSpecialMod:: db +wPlayerMonAccuracyMod:: db +wPlayerMonEvasionMod:: db + ds 2 +wPlayerMonStatModsEnd:: + + ds 1 + +wEnemyMonUnmodifiedLevel:: db +wEnemyMonUnmodifiedMaxHP:: dw +wEnemyMonUnmodifiedAttack:: dw +wEnemyMonUnmodifiedDefense:: dw +wEnemyMonUnmodifiedSpeed:: dw +wEnemyMonUnmodifiedSpecial:: dw + +; stat modifiers for the enemy's current pokemon +; value can range from 1 - 13 ($1 to $D) +; 7 is normal +wEnemyMonStatMods:: +wEnemyMonAttackMod:: db +wEnemyMonDefenseMod:: db +wEnemyMonSpeedMod:: db +wEnemyMonSpecialMod:: db +wEnemyMonAccuracyMod:: db +wEnemyMonEvasionMod:: db + ds 2 +wEnemyMonStatModsEnd:: + +NEXTU + ds 30 +wEngagedTrainerClass:: db +wEngagedTrainerSet:: db +ENDU + + ds 1 + +wNPCMovementDirections2Index:: +wUnusedCD37:: +; number of items in wFilteredBagItems list +wFilteredBagItemsCount:: db + +; the next simulated joypad state is at wSimulatedJoypadStatesEnd plus this value minus 1 +; 0 if the joypad state is not being simulated +wSimulatedJoypadStatesIndex:: db + +; written to but nothing ever reads it +wWastedByteCD39:: db + +; written to but nothing ever reads it +wWastedByteCD3A:: db + +; mask indicating which real button presses can override simulated ones +; XXX is it ever not 0? +wOverrideSimulatedJoypadStatesMask:: db + + ds 1 + +; This union spans 30 bytes. +UNION +wTradedPlayerMonSpecies:: db +wTradedEnemyMonSpecies:: db + ds 2 +wTradedPlayerMonOT:: ds NAME_LENGTH +wTradedPlayerMonOTID:: dw +wTradedEnemyMonOT:: ds NAME_LENGTH +wTradedEnemyMonOTID:: dw + +NEXTU +wTradingWhichPlayerMon:: db +wTradingWhichEnemyMon:: db +wNameOfPlayerMonToBeTraded:: ds NAME_LENGTH + +NEXTU +; one byte for each falling object +wFallingObjectsMovementData:: ds 20 + +NEXTU +; array of the number of mons in each box +wBoxMonCounts:: ds NUM_BOXES + +NEXTU +wPriceTemp:: ds 3 ; BCD + +NEXTU +; the current mon's field moves +wFieldMoves:: ds NUM_MOVES +wNumFieldMoves:: db +wFieldMovesLeftmostXCoord:: db +wLastFieldMoveID:: db ; unused + +NEXTU +wBoxNumString:: ds 3 + +NEXTU +; 0 = upper half (Y < 9) +; 1 = lower half (Y >= 9) +wBattleTransitionCircleScreenQuadrantY:: db +wBattleTransitionCircleScreenQuadrantX:: db + +NEXTU +; after 1 row/column has been copied, the offset to the next one to copy from +wBattleTransitionCopyTilesOffset:: dw + +NEXTU +; counts down from 7 so that every time 7 more tiles of the spiral have been +; placed, the tile map buffer is copied to VRAM so that progress is visible +wInwardSpiralUpdateScreenCounter:: db + ds 9 +; 0 = outward, 1 = inward +wBattleTransitionSpiralDirection:: db + +NEXTU +; multiplied by 16 to get the number of times to go right by 2 pixels +wSSAnneSmokeDriftAmount:: db +; 0 = left half (X < 10) +; 1 = right half (X >= 10) +wSSAnneSmokeX:: db + +NEXTU +wHoFMonSpecies:: +wHoFTeamIndex:: db +wHoFPartyMonIndex:: db +wHoFMonLevel:: db +; 0 = mon, 1 = player +wHoFMonOrPlayer:: db +wHoFTeamIndex2:: db +wHoFTeamNo:: db + +NEXTU +wRivalStarterTemp:: db +wRivalStarterBallSpriteIndex:: db + +NEXTU +wFlyAnimUsingCoordList:: db +; $ff sentinel values at each end +wFlyLocationsList:: ds NUM_CITY_MAPS + 2 + +NEXTU +wWhichTownMapLocation:: db +wFlyAnimCounter:: db +wFlyAnimBirdSpriteImageIndex:: db + +NEXTU + ds 1 +; difference in X between the next ball and the current one +wHUDPokeballGfxOffsetX:: db +wHUDGraphicsTiles:: ds 3 + +NEXTU +; the level of the mon at the time it entered day care +wDayCareStartLevel:: db +wDayCareNumLevelsGrown:: db +wDayCareTotalCost:: dw ; BCD +wDayCarePerLevelCost:: dw ; BCD (always $100) + +NEXTU +; which wheel the player is trying to stop +; 0 = none, 1 = wheel 1, 2 = wheel 2, 3 or greater = wheel 3 +wStoppingWhichSlotMachineWheel:: db +wSlotMachineWheel1Offset:: db +wSlotMachineWheel2Offset:: db +wSlotMachineWheel3Offset:: db +; the OAM tile number of the upper left corner of the winning symbol minus 2 +wSlotMachineWinningSymbol:: +wSlotMachineWheel1BottomTile:: db +wSlotMachineWheel1MiddleTile:: db +wSlotMachineWheel1TopTile:: db +wSlotMachineWheel2BottomTile:: db +wSlotMachineWheel2MiddleTile:: db +wSlotMachineWheel2TopTile:: db +wSlotMachineWheel3BottomTile:: db +wSlotMachineWheel3MiddleTile:: db +wSlotMachineWheel3TopTile:: db +wPayoutCoins:: dw +; These flags are set randomly and control when the wheels stop. +; bit 6: allow the player to win in general +; bit 7: allow the player to win with 7 or bar (plus the effect of bit 6) +wSlotMachineFlags:: db +; wheel 1 can "slip" while this is non-zero +wSlotMachineWheel1SlipCounter:: db +; wheel 2 can "slip" while this is non-zero +wSlotMachineWheel2SlipCounter:: db +; The remaining number of times wheel 3 will roll down a symbol until a match is +; found, when winning is enabled. It's initialized to 4 each bet. +wSlotMachineRerollCounter:: db +; how many coins the player bet on the slot machine (1 to 3) +wSlotMachineBet:: db + +NEXTU +wCanPlaySlots:: db + ds 8 +; temporary variable used to add payout amount to the player's coins +wTempCoins1:: dw + ds 2 +; temporary variable used to subtract the bet amount from the player's coins +wTempCoins2:: dw + +NEXTU +wHiddenObjectFunctionArgument:: db +wHiddenObjectFunctionRomBank:: db +wHiddenObjectIndex:: db +wHiddenObjectY:: db +wHiddenItemOrCoinsIndex:: +wHiddenObjectX:: db + +NEXTU +wPlayerSpinInPlaceAnimFrameDelay:: db +wPlayerSpinInPlaceAnimFrameDelayDelta:: db +wPlayerSpinInPlaceAnimFrameDelayEndValue:: db +wPlayerSpinInPlaceAnimSoundID:: db + ds 6 + db ; temporary space used when wFacingDirectionList is rotated +; used when spinning the player's sprite +wFacingDirectionList:: ds 4 + ds 3 +wSavedPlayerScreenY:: db +wSavedPlayerFacingDirection:: db + +NEXTU +wPlayerSpinWhileMovingUpOrDownAnimDeltaY:: db +wPlayerSpinWhileMovingUpOrDownAnimMaxY:: db +wPlayerSpinWhileMovingUpOrDownAnimFrameDelay:: db + +NEXTU +wTrainerSpriteOffset:: db +wTrainerEngageDistance:: db +wTrainerFacingDirection:: db +wTrainerScreenY:: db +wTrainerScreenX:: db + +NEXTU +wTrainerInfoTextBoxWidthPlus1:: db +wTrainerInfoTextBoxWidth:: db +wTrainerInfoTextBoxNextRowOffset:: db + +NEXTU +wOptionsTextSpeedCursorX:: db +wOptionsBattleAnimCursorX:: db +wOptionsBattleStyleCursorX:: db +wOptionsCancelCursorX:: db + +NEXTU +; tile ID of the badge number being drawn +wBadgeNumberTile:: db +; first tile ID of the name being drawn +wBadgeNameTile:: db +; a list of the first tile IDs of each badge or face (depending on whether the +; badge is owned) to be drawn on the trainer screen +; the byte after the list gets read when shifting back one byte +wBadgeOrFaceTiles:: ds NUM_BADGES + 1 + ds 1 +; temporary list created when displaying the badges on the trainer screen +; one byte for each badge; 0 = not obtained, 1 = obtained +wTempObtainedBadgesBooleans:: ds NUM_BADGES + +NEXTU +wUnusedCD3D:: db +; the number of credits mons that have been displayed so far +wNumCreditsMonsDisplayed:: db + +NEXTU + ds 1 + db ; temporary space used when wJigglypuffFacingDirections is rotated +wJigglypuffFacingDirections:: ds 4 + +NEXTU + ds 16 +; $3d = tree tile, $52 = grass tile +wCutTile:: db + ds 2 +; 0 = cut animation, 1 = boulder dust animation +wWhichAnimationOffsets:: db + +NEXTU + ds 18 +; the index of the sprite the emotion bubble is to be displayed above +wEmotionBubbleSpriteIndex:: db +wWhichEmotionBubble:: db + +NEXTU +wChangeBoxSavedMapTextPointer:: dw + +NEXTU +wSavedY:: +wTempSCX:: +; which entry from TradeMons to select +wWhichTrade:: +wDexMaxSeenMon:: +wPPRestoreItem:: +wWereAnyMonsAsleep:: +wNumShakes:: +wWhichBadge:: +wTitleMonSpecies:: +wPlayerCharacterOAMTile:: +; the number of small stars OAM entries to move down +wMoveDownSmallStarsOAMCount:: +wChargeMoveNum:: +wCoordIndex:: +wSwappedMenuItem:: +; 0 = no bite +; 1 = bite +; 2 = no fish on map +wRodResponse:: +wOptionsCursorLocation:: + db + +NEXTU +wTitleScreenScene:: db +wTitleScreenTimer:: db +ENDU + +; 0 = neither +; 1 = warp pad +; 2 = hole +wStandingOnWarpPadOrHole:: +wOAMBaseTile:: +wGymTrashCanIndex:: db + +wSymmetricSpriteOAMAttributes:: db + +wMonPartySpriteSpecies:: db + +; in the trade animation, the mon that leaves the left gameboy +wLeftGBMonSpecies:: db + +; in the trade animation, the mon that leaves the right gameboy +wRightGBMonSpecies:: db + +; bit 0: is player engaged by trainer (to avoid being engaged by multiple trainers simultaneously) +; bit 1: boulder dust animation (from using Strength) pending +; bit 3: using generic PC +; bit 5: don't play sound when A or B is pressed in menu +; bit 6: tried pushing against boulder once (you need to push twice before it will move) +wFlags_0xcd60:: db + + ds 9 + +; This has overlapping related uses. +; When the player tries to use an item or use certain field moves, 0 is stored +; when the attempt fails and 1 is stored when the attempt succeeds. +; In addition, some items store 2 for certain types of failures, but this +; cannot happen in battle. +; In battle, a non-zero value indicates the player has taken their turn using +; something other than a move (e.g. using an item or switching pokemon). +; So, when an item is successfully used in battle, this value becomes non-zero +; and the player is not allowed to make a move and the two uses are compatible. +wActionResultOrTookBattleTurn:: db + +; Set buttons are ignored. +wJoyIgnore:: db + +; size of downscaled mon pic used in pokeball entering/exiting animation +; $00 = 5×5 +; $01 = 3×3 +wDownscaledMonSize:: +; FormatMovesString stores the number of moves minus one here +wNumMovesMinusOne:: db + +UNION +wcd6d:: ds NAME_BUFFER_LENGTH ; buffer for various data + +NEXTU +wEvosMoves:: ds MAX_EVOLUTIONS * EVOLUTION_SIZE + 1 +wEvosMovesEnd:: + +NEXTU + ds 4 +; temp variable used to print a move's current PP on the status screen +wStatusScreenCurrentPP:: db + ds 6 +; list of normal max PP (without PP up) values +wNormalMaxPPList:: ds NUM_MOVES + ds 5 +ENDU + +UNION +; buffer for transferring the random number list generated by the other gameboy +wSerialOtherGameboyRandomNumberListBlock:: ds $11 +NEXTU +; second buffer for temporarily saving and restoring current screen's tiles (e.g. if menus are drawn on top) +wTileMapBackup2:: ds SCREEN_WIDTH * SCREEN_HEIGHT +ENDU + +; This union spans 30 bytes. +UNION +; Temporary storage area +wBuffer:: ds 30 + +NEXTU +wEvoOldSpecies:: db +wEvoNewSpecies:: db +wEvoMonTileOffset:: db +wEvoCancelled:: db + +NEXTU +wNamingScreenNameLength:: db +; non-zero when the player has chosen to submit the name +wNamingScreenSubmitName:: db +; 0 = upper case +; 1 = lower case +wAlphabetCase:: db + ds 1 +wNamingScreenLetter:: db + +NEXTU +wChangeMonPicEnemyTurnSpecies:: db +wChangeMonPicPlayerTurnSpecies:: db + +NEXTU +wHPBarMaxHP:: dw +wHPBarOldHP:: dw +wHPBarNewHP:: dw +wHPBarDelta:: db +wHPBarTempHP:: dw + ds 11 +wHPBarHPDifference:: dw + +NEXTU +; lower nybble is x, upper nybble is y +wTownMapCoords:: +; whether WriteMonMoves is being used to make a mon learn moves from day care +; non-zero if so +wLearningMovesFromDayCare:: + db + + ds 27 + +; the item that the AI used +wAIItem:: db +wUsedItemOnWhichPokemon:: db +ENDU + +; sound ID during battle animations +wAnimSoundID:: db + +; used as a storage value for the bank to return to after a BankswitchHome (bankswitch in homebank) +wBankswitchHomeSavedROMBank:: db + +; used as a temp storage value for the bank to switch to +wBankswitchHomeTemp:: db + +; 0 = nothing bought or sold in pokemart +; 1 = bought or sold something in pokemart +; this value is not used for anything +wBoughtOrSoldItemInMart:: db + +; $00 - win +; $01 - lose +; $02 - draw +wBattleResult:: db + +; bit 0: if set, DisplayTextID automatically draws a text box +wAutoTextBoxDrawingControl:: db + +wcf0d:: db ; used with some overworld scripts (not exactly sure what it's used for) + +; used in CheckForTilePairCollisions2 to store the tile the player is on +wTilePlayerStandingOn:: db + +wNPCNumScriptedSteps:: db + +; which script function within the pointer table indicated by +; wNPCMovementScriptPointerTableNum +wNPCMovementScriptFunctionNum:: db + +; bit 0: set when printing a text predef so that DisplayTextID doesn't switch +; to the current map's bank +wTextPredefFlag:: db + +wPredefParentBank:: db + +wSpriteIndex:: db + +; movement byte 2 of current sprite +wCurSpriteMovement2:: db + + ds 2 + +; sprite offset of sprite being controlled by NPC movement script +wNPCMovementScriptSpriteOffset:: db + +wScriptedNPCWalkCounter:: db + + ds 1 + +; if running on SGB, it's 1, else it's 0 +wOnSGB:: db + +wDefaultPaletteCommand:: db + +UNION +wPlayerHPBarColor:: dw + +NEXTU +; species of the mon whose palette is used for the whole screen +wWholeScreenPaletteMonSpecies:: db + +wEnemyHPBarColor:: db +ENDU + +; 0: green +; 1: yellow +; 2: red +wPartyMenuHPBarColors:: ds PARTY_LENGTH + +wStatusScreenHPBarColor:: db + + ds 7 + +wCopyingSGBTileData:: +wWhichPartyMenuHPBar:: +wPalPacket:: + db + +; This union spans 49 bytes. +UNION +wPartyMenuBlkPacket:: ds $30 + +NEXTU + ds 29 +; storage buffer for various strings +wStringBuffer:: ds 20 + +NEXTU + ds 29 +; the total amount of exp a mon gained +wExpAmountGained:: dw +wGainBoostedExp:: db + +NEXTU + ds 9 +wPartyHPBarAttributes:: ds PARTY_LENGTH +ENDU + +wGymCityName:: ds 17 + +wGymLeaderName:: ds NAME_LENGTH + +wItemList:: ds 16 + +wListPointer:: dw + +; used to store pointers, but never read +wUnusedCF8D:: dw + +wItemPrices:: dw + +wcf91:: db ; used with a lot of things (too much to list here) + +; which pokemon you selected +wWhichPokemon:: db + +; if non-zero, then print item prices when displaying lists +wPrintItemPrices:: db + +; type of HP bar +; $00 = enemy HUD in battle +; $01 = player HUD in battle / status screen +; $02 = party menu +wHPBarType:: +; ID used by DisplayListMenuID +wListMenuID:: db + +; if non-zero, RemovePokemon will remove the mon from the current box, +; else it will remove the mon from the party +wRemoveMonFromBox:: +; 0 = move from box to party +; 1 = move from party to box +; 2 = move from daycare to party +; 3 = move from party to daycare +wMoveMonType:: db + +wItemQuantity:: db + +wMaxItemQuantity:: db + +; LoadMonData copies mon data here +wLoadedMon:: party_struct wLoadedMon + +; bit 0: The space in VRAM that is used to store walk animation tile patterns +; for the player and NPCs is in use for font tile patterns. +; This means that NPC movement must be disabled. +; The other bits are unused. +wFontLoaded:: db + +; walk animation counter +wWalkCounter:: db + +; background tile number in front of the player (either 1 or 2 steps ahead) +wTileInFrontOfPlayer:: db + +; The desired fade counter reload value is stored here prior to calling +; PlaySound in order to cause the current music to fade out before the new +; music begins playing. Storing 0 causes no fade out to occur and the new music +; to begin immediately. +; This variable has another use related to fade-out, as well. PlaySound stores +; the sound ID of the music that should be played after the fade-out is finished +; in this variable. FadeOutAudio checks if it's non-zero every V-Blank and +; fades out the current audio if it is. Once it has finished fading out the +; audio, it zeroes this variable and starts playing the sound ID stored in it. +wAudioFadeOutControl:: db + +wAudioFadeOutCounterReloadValue:: db + +wAudioFadeOutCounter:: db + +; This is used to determine whether the default music is already playing when +; attempting to play the default music (in order to avoid restarting the same +; music) and whether the music has already been stopped when attempting to +; fade out the current music (so that the new music can be begin immediately +; instead of waiting). +; It sometimes contains the sound ID of the last music played, but it may also +; contain $ff (if the music has been stopped) or 0 (because some routines zero +; it in order to prevent assumptions from being made about the current state of +; the music). +wLastMusicSoundID:: db + +; $00 = causes sprites to be hidden and the value to change to $ff +; $01 = enabled +; $ff = disabled +; other values aren't used +wUpdateSpritesEnabled:: db + +wEnemyMoveNum:: db +wEnemyMoveEffect:: db +wEnemyMovePower:: db +wEnemyMoveType:: db +wEnemyMoveAccuracy:: db +wEnemyMoveMaxPP:: db +wPlayerMoveNum:: db +wPlayerMoveEffect:: db +wPlayerMovePower:: db +wPlayerMoveType:: db +wPlayerMoveAccuracy:: db +wPlayerMoveMaxPP:: db + +wEnemyMonSpecies2:: db +wBattleMonSpecies2:: db + +wEnemyMonNick:: ds NAME_LENGTH + +wEnemyMon:: battle_struct wEnemyMon + +wEnemyMonBaseStats:: ds NUM_STATS +wEnemyMonActualCatchRate:: db +wEnemyMonBaseExp:: db + +wBattleMonNick:: ds NAME_LENGTH +wBattleMon:: battle_struct wBattleMon + + +wTrainerClass:: db + + ds 1 + +wTrainerPicPointer:: dw + + ds 1 + +UNION +wTempMoveNameBuffer:: ds 14 + +NEXTU +; The name of the mon that is learning a move. +wLearnMoveMonName:: ds NAME_LENGTH +ENDU + + ds 2 + +; money received after battle = base money × level of highest-level enemy mon +wTrainerBaseMoney:: dw ; BCD + +wMissableObjectCounter:: db + + ds 1 + +; 13 bytes for the letters of the opposing trainer +; the name is terminated with $50 with possible +; unused trailing letters +wTrainerName:: ds 13 + +; lost battle, this is -1 +; no battle, this is 0 +; wild battle, this is 1 +; trainer battle, this is 2 +wIsInBattle:: db + +; flags that indicate which party members should be be given exp when GainExperience is called +wPartyGainExpFlags:: flag_array PARTY_LENGTH + +; in a wild battle, this is the species of pokemon +; in a trainer battle, this is the trainer class + OPP_ID_OFFSET +wCurOpponent:: db + +; in normal battle, this is 0 +; in old man battle, this is 1 +; in safari battle, this is 2 +wBattleType:: db + +; bits 0-6: Effectiveness + ; $0 = immune + ; $5 = not very effective + ; $a = neutral + ; $14 = super-effective +; bit 7: STAB +wDamageMultipliers:: db + +; which entry in LoneAttacks to use +; it's actually the same thing as ^ +wLoneAttackNo:: +wGymLeaderNo:: db +; which instance of [youngster, lass, etc] is this? +wTrainerNo:: db + +; $00 = normal attack +; $01 = critical hit +; $02 = successful OHKO +; $ff = failed OHKO +wCriticalHitOrOHKO:: db + +wMoveMissed:: db + +; always 0 +wPlayerStatsToDouble:: db + +; always 0 +wPlayerStatsToHalve:: db + +; bit 0 - bide +; bit 1 - thrash / petal dance +; bit 2 - attacking multiple times (e.g. double kick) +; bit 3 - flinch +; bit 4 - charging up for attack +; bit 5 - using multi-turn move (e.g. wrap) +; bit 6 - invulnerable to normal attack (using fly/dig) +; bit 7 - confusion +wPlayerBattleStatus1:: db + +; bit 0 - X Accuracy effect +; bit 1 - protected by "mist" +; bit 2 - focus energy effect +; bit 4 - has a substitute +; bit 5 - need to recharge +; bit 6 - rage +; bit 7 - leech seeded +wPlayerBattleStatus2:: db + +; bit 0 - toxic +; bit 1 - light screen +; bit 2 - reflect +; bit 3 - transformed +wPlayerBattleStatus3:: db + +; always 0 +wEnemyStatsToDouble:: db + +; always 0 +wEnemyStatsToHalve:: db + +wEnemyBattleStatus1:: db +wEnemyBattleStatus2:: db +wEnemyBattleStatus3:: db + +; when the player is attacking multiple times, the number of attacks left +wPlayerNumAttacksLeft:: db + +wPlayerConfusedCounter:: db + +wPlayerToxicCounter:: db + +; high nibble: which move is disabled (1-4) +; low nibble: disable turns left +wPlayerDisabledMove:: db + + ds 1 + +; when the enemy is attacking multiple times, the number of attacks left +wEnemyNumAttacksLeft:: db + +wEnemyConfusedCounter:: db + +wEnemyToxicCounter:: db + +; high nibble: which move is disabled (1-4) +; low nibble: disable turns left +wEnemyDisabledMove:: db + + ds 1 + +UNION +; the amount of damage accumulated by the player while biding +wPlayerBideAccumulatedDamage:: dw + +NEXTU +wUnknownSerialCounter2:: dw + +NEXTU +; number of hits by player in attacks like Double Slap, etc. +wPlayerNumHits:: db +ENDU + + ds 2 + +; non-zero when an item or move that allows escape from battle was used +wEscapedFromBattle:: db + +UNION +wAmountMoneyWon:: ds 3 ; BCD + +NEXTU +wObjectToHide:: db +wObjectToShow:: db +ENDU + +; the map you will start at when the debug bit is set +wDefaultMap:: +wMenuItemOffset:: +; ID number of the current battle animation +wAnimationID:: db + +wNamingScreenType:: +wPartyMenuTypeOrMessageID:: +; temporary storage for the number of tiles in a tileset +wTempTilesetNumTiles:: db + +; used by the pokemart code to save the existing value of wListScrollOffset +; so that it can be restored when the player is done with the pokemart NPC +wSavedListScrollOffset:: db + + ds 2 + +; base coordinates of frame block +wBaseCoordX:: db +wBaseCoordY:: db + +; low health alarm counter/enable +; high bit = enable, others = timer to cycle frequencies +wLowHealthAlarm:: db + +; counts how many tiles of the current frame block have been drawn +wFBTileCounter:: db + +wMovingBGTilesCounter2:: db + +; duration of each frame of the current subanimation in terms of screen refreshes +wSubAnimFrameDelay:: db +; counts the number of subentries left in the current subanimation +wSubAnimCounter:: db + +; 1 = no save file or save file is corrupted +; 2 = save file exists and no corruption has been detected +wSaveFileStatus:: db + +; number of tiles in current battle animation frame block +wNumFBTiles:: db + +UNION +wSpiralBallsBaseY:: db +wSpiralBallsBaseX:: db + +NEXTU +; bits 0-6: index into FallingObjects_DeltaXs array (0 - 8) +; bit 7: direction; 0 = right, 1 = left +wFallingObjectMovementByte:: db +wNumFallingObjects:: db + +NEXTU +wFlashScreenLongCounter:: +wNumShootingBalls:: +; $01 if mon is moving from left gameboy to right gameboy; $00 if vice versa +wTradedMonMovingRight:: +wOptionsInitialized:: +wNewSlotMachineBallTile:: +; how much to add to the X/Y coord +wCoordAdjustmentAmount:: +wUnusedD08A:: + db + +wSlideMonDelay:: +; generic counter variable for various animations +wAnimCounter:: +; controls what transformations are applied to the subanimation +; 01: flip horizontally and vertically +; 02: flip horizontally and translate downwards 40 pixels +; 03: translate base coordinates of frame blocks, but don't change their internal coordinates or flip their tiles +; 04: reverse the subanimation +wSubAnimTransform:: + db +ENDU + +wEndBattleWinTextPointer:: dw +wEndBattleLoseTextPointer:: dw + ds 2 +wEndBattleTextRomBank:: db + + ds 1 + +; the address _of the address_ of the current subanimation entry +wSubAnimAddrPtr:: dw + +UNION +; the address of the current subentry of the current subanimation +wSubAnimSubEntryAddr:: dw + +NEXTU +; If non-zero, the allow matches flag is always set. +; There is a 1/256 (~0.4%) chance that this value will be set to 60, which is +; the only way it can increase. Winning certain payout amounts will decrement it +; or zero it. +wSlotMachineAllowMatchesCounter:: db +ENDU + + ds 2 + +wOutwardSpiralTileMapPointer:: db + +wPartyMenuAnimMonEnabled:: +; non-zero when enabled. causes nest locations to blink on and off. +; the town selection cursor will blink regardless of what this value is +wTownMapSpriteBlinkingEnabled:: +wUnusedD09B:: db + +; current destination address in OAM for frame blocks (big endian) +wFBDestAddr:: dw + +; controls how the frame blocks are put together to form frames +; specifically, after finishing drawing the frame block, the frame block's mode determines what happens +; 00: clean OAM buffer and delay +; 02: move onto the next frame block with no delay and no cleaning OAM buffer +; 03: delay, but don't clean OAM buffer +; 04: delay, without cleaning OAM buffer, and do not advance [wFBDestAddr], so that the next frame block will overwrite this one +wFBMode:: db + +; 0 = small +; 1 = big +wLinkCableAnimBulgeToggle:: +wIntroNidorinoBaseTile:: +wOutwardSpiralCurrentDirection:: +wDropletTile:: +wNewTileBlockID:: +wWhichBattleAnimTileset:: +; 0 = left +; 1 = right +wSquishMonCurrentDirection:: +; the tile ID of the leftmost tile in the bottom row in AnimationSlideMonUp_ +wSlideMonUpBottomRowLeftTile:: + db + +wDisableVBlankWYUpdate:: db ; if non-zero, don't update WY during V-blank + +wSpriteCurPosX:: db +wSpriteCurPosY:: db +wSpriteWidth:: db +wSpriteHeight:: db +; current input byte +wSpriteInputCurByte:: db +; bit offset of last read input bit +wSpriteInputBitCounter:: db + +; determines where in the output byte the two bits are placed. Each byte contains four columns (2bpp data) +; 3 -> XX000000 1st column +; 2 -> 00XX0000 2nd column +; 1 -> 0000XX00 3rd column +; 0 -> 000000XX 4th column +wSpriteOutputBitOffset:: db + +; bit 0 determines used buffer (0 -> sSpriteBuffer1, 1 -> sSpriteBuffer2) +; bit 1 loading last sprite chunk? (there are at most 2 chunks per load operation) +wSpriteLoadFlags:: db +wSpriteUnpackMode:: db +wSpriteFlipped:: db + +; pointer to next input byte +wSpriteInputPtr:: dw +; pointer to current output byte +wSpriteOutputPtr:: dw +; used to revert pointer for different bit offsets +wSpriteOutputPtrCached:: dw +; pointer to differential decoding table (assuming initial value 0) +wSpriteDecodeTable0Ptr:: dw +; pointer to differential decoding table (assuming initial value 1) +wSpriteDecodeTable1Ptr:: dw + +wd0b5:: db ; used as a temp storage area for Pokemon Species, and other Pokemon/Battle related things + +wNameListType:: db + +wPredefBank:: db + +wMonHeader:: +; In the ROM base stats data structure, this is the dex number, but it is +; overwritten with the internal index number after the header is copied to WRAM. +wMonHIndex:: db +wMonHBaseStats:: +wMonHBaseHP:: db +wMonHBaseAttack:: db +wMonHBaseDefense:: db +wMonHBaseSpeed:: db +wMonHBaseSpecial:: db +wMonHTypes:: +wMonHType1:: db +wMonHType2:: db +wMonHCatchRate:: db +wMonHBaseEXP:: db +wMonHSpriteDim:: db +wMonHFrontSprite:: dw +wMonHBackSprite:: dw +wMonHMoves:: ds NUM_MOVES +wMonHGrowthRate:: db +wMonHLearnset:: flag_array NUM_TMS + NUM_HMS + ds 1 +wMonHeaderEnd:: + +; saved at the start of a battle and then written back at the end of the battle +wSavedTileAnimations:: db + + ds 2 + +wDamage:: dw + + ds 2 + +wRepelRemainingSteps:: db + +; list of moves for FormatMovesString +wMoves:: ds NUM_MOVES + +wMoveNum:: db + +wMovesString:: ds 56 + +wUnusedD119:: db + +; wWalkBikeSurfState is sometimes copied here, but it doesn't seem to be used for anything +wWalkBikeSurfStateCopy:: db + +; the type of list for InitList to init +wInitListType:: db + +; 0 if no mon was captured +wCapturedMonSpecies:: db + +; Non-zero when the first player mon and enemy mon haven't been sent out yet. +; It prevents the game from asking if the player wants to choose another mon +; when the enemy sends out their first mon and suppresses the "no will to fight" +; message when the game searches for the first non-fainted mon in the party, +; which will be the first mon sent out. +wFirstMonsNotOutYet:: db + +wPokeBallCaptureCalcTemp:: +; lower nybble: number of shakes +; upper nybble: number of animations to play +wPokeBallAnimData:: +wUsingPPUp:: +wMaxPP:: +; 0 for player, non-zero for enemy +wCalculateWhoseStats:: +wTypeEffectiveness:: +wMoveType:: +wNumSetBits:: +; used as a Pokemon and Item storage value. Also used as an output value for CountSetBits +wd11e:: + db + +; When this value is non-zero, the player isn't allowed to exit the party menu +; by pressing B and not choosing a mon. +wForcePlayerToChooseMon:: db + +; number of times the player has tried to run from battle +wNumRunAttempts:: db + +wEvolutionOccurred:: db + +wVBlankSavedROMBank:: db + +wFarCopyDataSavedROMBank:: db + +wIsKeyItem:: db + +wTextBoxID:: db + +wCurrentMapScriptFlags:: db ; not exactly sure what this is used for, but it seems to be used as a multipurpose temp flag value + +wCurEnemyLVL:: db + +; pointer to list of items terminated by $FF +wItemListPointer:: dw + +; number of entries in a list +wListCount:: db + +wLinkState:: db + +wTwoOptionMenuID:: db + +; the id of the menu item the player ultimately chose +wChosenMenuItem:: +; non-zero when the whole party has fainted due to out-of-battle poison damage +wOutOfBattleBlackout:: db + +; the way the user exited a menu +; for list menus and the buy/sell/quit menu: +; $01 = the user pressed A to choose a menu item +; $02 = the user pressed B to cancel +; for two-option menus: +; $01 = the user pressed A with the first menu item selected +; $02 = the user pressed B or pressed A with the second menu item selected +wMenuExitMethod:: db + +; the size is always 6, so they didn't need a variable in RAM for this +wDungeonWarpDataEntrySize:: +; 0 = museum guy +; 1 = gym guy +wWhichPewterGuy:: +; there are 3 windows, from 0 to 2 +wWhichPrizeWindow:: +; a horizontal or vertical gate block +wGymGateTileBlock:: db + +wSavedSpriteScreenY:: db +wSavedSpriteScreenX:: db +wSavedSpriteMapY:: db +wSavedSpriteMapX:: db + + ds 5 + +wWhichPrize:: db + +; counts downward each frame +; when it hits 0, bit 5 (ignore input bit) of wd730 is reset +wIgnoreInputCounter:: db + +; counts down once every step +wStepCounter:: db + +; after a battle, you have at least 3 steps before a random battle can occur +wNumberOfNoRandomBattleStepsLeft:: db + +wPrize1:: db +wPrize2:: db +wPrize3:: db + + ds 1 + +UNION +wSerialRandomNumberListBlock:: ds $11 + +NEXTU +wPrize1Price:: dw +wPrize2Price:: dw +wPrize3Price:: dw + + ds 1 + +; shared list of 9 random numbers, indexed by wLinkBattleRandomNumberListIndex +wLinkBattleRandomNumberList:: ds 10 +ENDU + +wSerialPlayerDataBlock:: ; ds $1a8 + +; When a real item is being used, this is 0. +; When a move is acting as an item, this is the ID of the item it's acting as. +; For example, out-of-battle Dig is executed using a fake Escape Rope item. In +; that case, this would be ESCAPE_ROPE. +wPseudoItemID:: db + +wUnusedD153:: db + + ds 2 + +wEvoStoneItemID:: db + +wSavedNPCMovementDirections2Index:: db + +wPlayerName:: ds NAME_LENGTH + + +SECTION "Party Data", WRAM0 + +wPartyDataStart:: + +wPartyCount:: db +wPartySpecies:: ds PARTY_LENGTH + 1 + +wPartyMons:: +; wPartyMon1 - wPartyMon6 +FOR n, 1, PARTY_LENGTH + 1 +wPartyMon{d:n}:: party_struct wPartyMon{d:n} +ENDR + +wPartyMonOT:: +; wPartyMon1OT - wPartyMon6OT +FOR n, 1, PARTY_LENGTH + 1 +wPartyMon{d:n}OT:: ds NAME_LENGTH +ENDR + +wPartyMonNicks:: +; wPartyMon1Nick - wPartyMon6Nick +FOR n, 1, PARTY_LENGTH + 1 +wPartyMon{d:n}Nick:: ds NAME_LENGTH +ENDR +wPartyMonNicksEnd:: + +wPartyDataEnd:: + + +SECTION "Main Data", WRAM0 + +wMainDataStart:: + +wPokedexOwned:: flag_array NUM_POKEMON +wPokedexOwnedEnd:: + +wPokedexSeen:: flag_array NUM_POKEMON +wPokedexSeenEnd:: + +wNumBagItems:: db +; item, quantity +wBagItems:: ds BAG_ITEM_CAPACITY * 2 + 1 + +wPlayerMoney:: ds 3 ; BCD + +wRivalName:: ds NAME_LENGTH + +; bit 7 = battle animation +; 0: On +; 1: Off +; bit 6 = battle style +; 0: Shift +; 1: Set +; bits 0-3 = text speed (number of frames to delay after printing a letter) +; 1: Fast +; 3: Medium +; 5: Slow +wOptions:: db + +wObtainedBadges:: flag_array NUM_BADGES + + ds 1 + +; bit 0: If 0, limit the delay to 1 frame. Note that this has no effect if +; the delay has been disabled entirely through bit 1 of this variable +; or bit 6 of wd730. +; bit 1: If 0, no delay. +wLetterPrintingDelayFlags:: db + +wPlayerID:: dw + +wMapMusicSoundID:: db +wMapMusicROMBank:: db + +; offset subtracted from FadePal4 to get the background and object palettes for the current map +; normally, it is 0. it is 6 when Flash is needed, causing FadePal2 to be used instead of FadePal4 +wMapPalOffset:: db + +wCurMap:: db + +; pointer to the upper left corner of the current view in the tile block map +wCurrentTileBlockMapViewPointer:: dw + +; player's position on the current map +wYCoord:: db +wXCoord:: db + +; player's position (by block) +wYBlockCoord:: db +wXBlockCoord:: db + +wLastMap:: db + +wUnusedD366:: db + +wCurMapTileset:: db + +; blocks +wCurMapHeight:: db +wCurMapWidth:: db + +wMapDataPtr:: dw +wMapTextPtr:: dw +wMapScriptPtr:: dw + +wMapConnections:: db +wNorthConnectionHeader:: map_connection_struct wNorth +wSouthConnectionHeader:: map_connection_struct wSouth +wWestConnectionHeader:: map_connection_struct wWest +wEastConnectionHeader:: map_connection_struct wEast + +; sprite set for the current map (11 sprite picture ID's) +wSpriteSet:: ds 11 +; sprite set ID for the current map +wSpriteSetID:: db + +wObjectDataPointerTemp:: dw + + ds 2 + +; the tile shown outside the boundaries of the map +wMapBackgroundTile:: db + +; number of warps in current map (up to 32) +wNumberOfWarps:: db + +; current map warp entries +wWarpEntries:: ds 32 * 4 ; Y, X, warp ID, map ID + +; if $ff, the player's coordinates are not updated when entering the map +wDestinationWarpID:: db + +wPikachuOverworldStateFlags:: db +wPikachuSpawnState:: db +wd432:: db +wd433:: db +wd434:: db +wd435:: db +wd436:: db +wPikachuFollowCommandBufferSize:: db +wPikachuFollowCommandBuffer:: ds 16 + +wExpressionNumber:: db +wPikaPicAnimNumber:: db + +wPikachuMovementScriptBank:: db +wPikachuMovementScriptAddress:: dw +; bit 6 - spawn shadow +; bit 7 - signal end of command +wPikachuMovementFlags:: db + +UNION +wCurPikaMovementData:: +wCurPikaMovementParam1:: db +wCurPikaMovementFunc1:: db +wCurPikaMovementParam2:: db +wCurPikaMovementFunc2:: db +wd451:: db +wCurPikaMovementSpriteImageIdx:: db +wPikaSpriteX:: db +wPikaSpriteY:: db +wPikachuMovementXOffset:: db +wPikachuMovementYOffset:: db +wPikachuStepTimer:: db +wPikachuStepSubtimer:: db + ds 5 +wCurPikaMovementDataEnd:: + +NEXTU +wPikaPicAnimPointer:: dw +wPikaPicAnimPointerSetupFinished:: db +wPikaPicAnimCurGraphicID:: db +wPikaPicAnimTimer:: dw +wPikaPicAnimDelay:: db +wPikaPicPikaDrawStartX:: db +wPikaPicPikaDrawStartY:: db + +wCurPikaPicAnimObject:: +wCurPikaPicAnimObjectVTileOffset:: db +wCurPikaPicAnimObjectXOffset:: db +wCurPikaPicAnimObjectYOffset:: db +wCurPikaPicAnimObjectScriptIdx:: db +wCurPikaPicAnimObjectFrameIdx:: db +wCurPikaPicAnimObjectFrameTimer:: db + ds 1 +wCurPikaPicAnimObjectEnd:: + + ds 18 +ENDU + +wPikachuHappiness:: db +wPikachuMood:: db +wd472:: db +wd473:: db + ds 1 +wd475:: db + ds 4 +wd47a:: db + ds 24 +wd492:: db + ds 1 +wSurfingMinigameHiScore:: dw ; little-endian BCD + ds 1 +wPrinterSettings:: db +wUnknownSerialFlag_d499:: db +wPrinterConnectionOpen:: db +wPrinterOpcode:: db +wd49c:: db + + ds 19 + +; number of signs in the current map (up to 16) +wNumSigns:: db + +wSignCoords:: ds 16 * 2 ; Y, X +wSignTextIDs:: ds 16 + +; number of sprites on the current map (up to 16) +wNumSprites:: db + +; these two variables track the X and Y offset in blocks from the last special warp used +; they don't seem to be used for anything +wYOffsetSinceLastSpecialWarp:: db +wXOffsetSinceLastSpecialWarp:: db + +wMapSpriteData:: ds 16 * 2 ; movement byte 2, text ID +wMapSpriteExtraData:: ds 16 * 2 ; trainer class/item ID, trainer set ID + +; map height in 2x2 meta-tiles +wCurrentMapHeight2:: db + +; map width in 2x2 meta-tiles +wCurrentMapWidth2:: db + +; the address of the upper left corner of the visible portion of the BG tile map in VRAM +wMapViewVRAMPointer:: dw + +; In the comments for the player direction variables below, "moving" refers to +; both walking and changing facing direction without taking a step. + +; if the player is moving, the current direction +; if the player is not moving, zero +; map scripts write to this in order to change the player's facing direction +wPlayerMovingDirection:: db + +; the direction in which the player was moving before the player last stopped +wPlayerLastStopDirection:: db + +; if the player is moving, the current direction +; if the player is not moving, the last the direction in which the player moved +wPlayerDirection:: db + +wTilesetBank:: db + +; maps blocks (4x4 tiles) to tiles +wTilesetBlocksPtr:: dw + +wTilesetGfxPtr:: dw + +; list of all walkable tiles +wTilesetCollisionPtr:: dw + +wTilesetTalkingOverTiles:: ds 3 + +wGrassTile:: db + + ds 4 + +wNumBoxItems:: db +; item, quantity +wBoxItems:: ds PC_ITEM_CAPACITY * 2 + 1 + +; bits 0-6: box number +; bit 7: whether the player has changed boxes before +wCurrentBoxNum:: dw + +; number of HOF teams +wNumHoFTeams:: db + +wUnusedD5A3:: db + +wPlayerCoins:: ds 2 ; BCD + +; bit array of missable objects. set = removed +wMissableObjectFlags:: flag_array $100 +wMissableObjectFlagsEnd:: + + ds 7 + +; temp copy of SPRITESTATEDATA1_IMAGEINDEX (used for sprite facing/anim) +wd5cd:: db + +; each entry consists of 2 bytes +; * the sprite ID (depending on the current map) +; * the missable object index (global, used for wMissableObjectFlags) +; terminated with $FF +wMissableObjectList:: ds 16 * 2 + 1 + + ds 1 + +wGameProgressFlags:: +wOaksLabCurScript:: db +wPalletTownCurScript:: db + ds 1 +wBluesHouseCurScript:: db +wViridianCityCurScript:: db + ds 2 +wPewterCityCurScript:: db +wRoute3CurScript:: db +wRoute4CurScript:: db +wFanClubCurScript:: db +wViridianGymCurScript:: db +wPewterGymCurScript:: db +wCeruleanGymCurScript:: db +wVermilionGymCurScript:: db +wCeladonGymCurScript:: db +wRoute6CurScript:: db +wRoute8CurScript:: db +wRoute24CurScript:: db +wRoute25CurScript:: db +wRoute9CurScript:: db +wRoute10CurScript:: db +wMtMoon1FCurScript:: db +wMtMoonB2FCurScript:: db +wSSAnne1FRoomsCurScript:: db +wSSAnne2FRoomsCurScript:: db +wRoute22CurScript:: db + ds 1 +wRedsHouse2FCurScript:: db +wViridianMartCurScript:: db +wRoute22GateCurScript:: db +wCeruleanCityCurScript:: db + ds 7 +wSSAnneBowCurScript:: db +wViridianForestCurScript:: db +wMuseum1FCurScript:: db +wRoute13CurScript:: db +wRoute14CurScript:: db +wRoute17CurScript:: db +wRoute19CurScript:: db +wRoute21CurScript:: db +wSafariZoneGateCurScript:: db +wRockTunnelB1FCurScript:: db +wRockTunnel1FCurScript:: db + ds 1 +wRoute11CurScript:: db +wRoute12CurScript:: db +wRoute15CurScript:: db +wRoute16CurScript:: db +wRoute18CurScript:: db +wRoute20CurScript:: db +wSSAnneB1FRoomsCurScript:: db +wVermilionCityCurScript:: db +wPokemonTower2FCurScript:: db +wPokemonTower3FCurScript:: db +wPokemonTower4FCurScript:: db +wPokemonTower5FCurScript:: db +wPokemonTower6FCurScript:: db +wPokemonTower7FCurScript:: db +wRocketHideoutB1FCurScript:: db +wRocketHideoutB2FCurScript:: db +wRocketHideoutB3FCurScript:: db +wRocketHideoutB4FCurScript:: db + ds 1 +wRoute6GateCurScript:: db +wRoute8GateCurScript:: db + ds 1 +wCinnabarIslandCurScript:: db +wPokemonMansion1FCurScript:: db + ds 1 +wPokemonMansion2FCurScript:: db +wPokemonMansion3FCurScript:: db +wPokemonMansionB1FCurScript:: db +wVictoryRoad2FCurScript:: db +wVictoryRoad3FCurScript:: db +wCeladonCityCurScript:: db +wFightingDojoCurScript:: db +wSilphCo2FCurScript:: db +wSilphCo3FCurScript:: db +wSilphCo4FCurScript:: db +wSilphCo5FCurScript:: db +wSilphCo6FCurScript:: db +wSilphCo7FCurScript:: db +wSilphCo8FCurScript:: db +wSilphCo9FCurScript:: db +wHallOfFameCurScript:: db +wChampionsRoomCurScript:: db +wLoreleisRoomCurScript:: db +wBrunosRoomCurScript:: db +wAgathasRoomCurScript:: db +wCeruleanCaveB1FCurScript:: db +wVictoryRoad1FCurScript:: db + ds 1 +wLancesRoomCurScript:: db + ds 4 +wSilphCo10FCurScript:: db +wSilphCo11FCurScript:: db + ds 1 +wFuchsiaGymCurScript:: db +wSaffronGymCurScript:: db + ds 1 +wCinnabarGymCurScript:: db +wGameCornerCurScript:: db +wRoute16Gate1FCurScript:: db +wBillsHouseCurScript:: db +wRoute5GateCurScript:: db +wPowerPlantCurScript:: ; overload +wRoute7GateCurScript:: db + ds 1 +wSSAnne2FCurScript:: db +wSeafoamIslandsB3FCurScript:: db +wRoute23CurScript:: db +wSeafoamIslandsB4FCurScript:: db +wRoute18Gate1FCurScript:: db + ds 78 +wGameProgressFlagsEnd:: + + ds 56 + +wObtainedHiddenItemsFlags:: flag_array 112 + +wObtainedHiddenCoinsFlags:: flag_array 16 + +; $00 = walking +; $01 = biking +; $02 = surfing +wWalkBikeSurfState:: db + + ds 10 + +wTownVisitedFlag:: flag_array NUM_CITY_MAPS + +; starts at 502 +wSafariSteps:: dw + +; item given to cinnabar lab +wFossilItem:: db +; mon that will result from the item +wFossilMon:: db + + ds 2 + +; trainer classes start at OPP_ID_OFFSET +wEnemyMonOrTrainerClass:: db + +wPlayerJumpingYScreenCoordsIndex:: db + +wRivalStarter:: db + +IF DEF(_DEBUG) +; this byte gets set to NUM_POKEMON by DebugStart +wUnknownDebugByte:: db +ELSE + ds 1 +ENDC + +wPlayerStarter:: db + +; sprite index of the boulder the player is trying to push +wBoulderSpriteIndex:: db + +wLastBlackoutMap:: db + +; destination map (for certain types of special warps, not ordinary walking) +wDestinationMap:: db + +wUnusedD71B:: db + +; used to store the tile in front of the boulder when trying to push a boulder +; also used to store the result of the collision check ($ff for a collision and $00 for no collision) +wTileInFrontOfBoulderAndBoulderCollisionResult:: db + +; destination map for dungeon warps +wDungeonWarpDestinationMap:: db + +; which dungeon warp within the source map was used +wWhichDungeonWarp:: db + +wUnusedD71F:: db + + ds 8 + +; bit 0: using Strength outside of battle +; bit 1: set by IsSurfingAllowed when surfing's allowed, but the caller resets it after checking the result +; bit 3: received Old Rod +; bit 4: received Good Rod +; bit 5: received Super Rod +; bit 6: gave one of the Saffron guards a drink +; bit 7: set by ItemUseCardKey, which is leftover code from a previous implementation of the Card Key +wd728:: db + + ds 1 + +; redundant because it matches wObtainedBadges +; used to determine whether to show name on statue and in two NPC text scripts +wBeatGymFlags:: db + + ds 1 + +; bit 0: if not set, the 3 minimum steps between random battles have passed +; bit 1: prevent audio fade out +wd72c:: db + +; This variable is used for temporary flags and as the destination map when +; warping to the Trade Center or Colosseum. +; bit 0: sprite facing directions have been initialised in the Trade Center +; bit 3: do scripted warp (used to warp back to Lavender Town from the top of the pokemon tower) +; bit 4: on a dungeon warp +; bit 5: don't make NPCs face the player when spoken to +; Bits 6 and 7 are set by scripts when starting major battles in the storyline, +; but they do not appear to affect anything. Bit 6 is reset after all battles +; and bit 7 is reset after trainer battles (but it's only set before trainer +; battles anyway). +wd72d:: db + +; bit 0: the player has received Lapras in the Silph Co. building +; bit 1: set in various places, but doesn't appear to have an effect +; bit 2: the player has healed pokemon at a pokemon center at least once +; bit 3: the player has a received a pokemon from Prof. Oak +; bit 4: disable battles +; bit 5: set when a battle ends and when the player blacks out in the overworld due to poison +; bit 6: using the link feature +; bit 7: set if scripted NPC movement has been initialised +wd72e:: db + + ds 1 + +; bit 0: NPC sprite being moved by script +; bit 5: ignore joypad input +; bit 6: print text with no delay between each letter +; bit 7: set if joypad states are being simulated in the overworld or an NPC's movement is being scripted +wd730:: db + + ds 1 + +; bit 0: play time being counted +; bit 1: remnant of debug mode; only set by the debug build. +; if it is set: +; 1. skips most of Prof. Oak's speech, and uses NINTEN as the player's name and SONY as the rival's name +; 2. does not have the player start in floor two of the player's house (instead sending them to [wLastMap]) +; 3. allows wild battles to be avoided by holding down B +; furthermore, in the debug build: +; 4. allows trainers to be avoided by holding down B +; 5. skips Safari Zone step counter by holding down B +; 6. skips the NPC who blocks Route 3 before beating Brock by holding down B +; 7. skips Cerulean City rival battle by holding down B +; 8. skips Pokémon Tower rival battle by holding down B +; bit 2: the target warp is a fly warp (bit 3 set or blacked out) or a dungeon warp (bit 4 set) +; bit 3: used warp pad, escape rope, dig, teleport, or fly, so the target warp is a "fly warp" +; bit 4: jumped into hole (Pokemon Mansion, Seafoam Islands, Victory Road) or went down waterfall (Seafoam Islands), so the target warp is a "dungeon warp" +; bit 5: currently being forced to ride bike (cycling road) +; bit 6: map destination is [wLastBlackoutMap] (usually the last used pokemon center, but could be the player's house) +wd732:: db + +; bit 0: running a test battle +; bit 1: prevent music from changing when entering new map +; bit 2: skip the joypad check in CheckWarpsNoCollision (used for the forced warp down the waterfall in the Seafoam Islands) +; bit 3: trainer wants to battle +; bit 4: use variable [wCurMapScript] instead of the provided index for next frame's map script (used to start battle when talking to trainers) +; bit 7: used fly out of battle +wFlags_D733:: db + +; bit 1: set when you beat Lorelei and reset in Indigo Plateau lobby +; the game uses this to tell when Elite 4 events need to be reset +wBeatLorelei:: db + + ds 1 + +; bit 0: check if the player is standing on a door and make him walk down a step if so +; bit 1: the player is currently stepping down from a door +; bit 2: standing on a warp +; bit 6: jumping down a ledge / fishing animation +; bit 7: player sprite spinning due to spin tiles (Rocket hideout / Viridian Gym) +wd736:: db + +wCompletedInGameTradeFlags:: dw + + ds 2 + +wWarpedFromWhichWarp:: db +wWarpedFromWhichMap:: db + + ds 2 + +wCardKeyDoorY:: db +wCardKeyDoorX:: db + + ds 2 + +wFirstLockTrashCanIndex:: db +wSecondLockTrashCanIndex:: db + + ds 2 + +wEventFlags:: flag_array NUM_EVENTS + + +UNION +wGrassRate:: db +wGrassMons:: ds 10 * 2 + + ds 8 + +wWaterRate:: db +wWaterMons:: ds 10 * 2 + +NEXTU +; linked game's trainer name +wLinkEnemyTrainerName:: ds NAME_LENGTH + + ds 1 + +wSerialEnemyDataBlock:: ; ds $1a8 + + ds 9 + +wEnemyPartyCount:: ds 1 +wEnemyPartySpecies:: ds PARTY_LENGTH + 1 + +wEnemyMons:: +; wEnemyMon1 - wEnemyMon6 +FOR n, 1, PARTY_LENGTH + 1 +wEnemyMon{d:n}:: party_struct wEnemyMon{d:n} +ENDR + +wEnemyMonOT:: +; wEnemyMon1OT - wEnemyMon6OT +FOR n, 1, PARTY_LENGTH + 1 +wEnemyMon{d:n}OT:: ds NAME_LENGTH +ENDR + +wEnemyMonNicks:: +; wEnemyMon1Nick - wEnemyMon6Nick +FOR n, 1, PARTY_LENGTH + 1 +wEnemyMon{d:n}Nick:: ds NAME_LENGTH +ENDR + +ENDU + + +wTrainerHeaderPtr:: dw + + ds 6 + +; the trainer the player must face after getting a wrong answer in the Cinnabar +; gym quiz +wOpponentAfterWrongAnswer:: +wUnusedDA38:: db + +; index of current map script, mostly used as index for function pointer array +; mostly copied from map-specific map script pointer and written back later +wCurMapScript:: db + + ds 7 + +wPlayTimeHours:: db +wPlayTimeMaxed:: db +wPlayTimeMinutes:: db +wPlayTimeSeconds:: db +wPlayTimeFrames:: db + +wSafariZoneGameOver:: db + +wNumSafariBalls:: db + + +; 0 if no pokemon is in the daycare +; 1 if pokemon is in the daycare +wDayCareInUse:: db + +wDayCareMonName:: ds NAME_LENGTH +wDayCareMonOT:: ds NAME_LENGTH + +wDayCareMon:: box_struct wDayCareMon + +wMainDataEnd:: + + +SECTION "Current Box Data", WRAM0 + +wBoxDataStart:: + +wBoxCount:: db +wBoxSpecies:: ds MONS_PER_BOX + 1 + +wBoxMons:: +; wBoxMon1 - wBoxMon20 +FOR n, 1, MONS_PER_BOX + 1 +wBoxMon{d:n}:: box_struct wBoxMon{d:n} +ENDR + +wBoxMonOT:: +; wBoxMon1OT - wBoxMon20OT +FOR n, 1, MONS_PER_BOX + 1 +wBoxMon{d:n}OT:: ds NAME_LENGTH +ENDR + +wBoxMonNicks:: +; wBoxMon1Nick - wBoxMon20Nick +FOR n, 1, MONS_PER_BOX + 1 +wBoxMon{d:n}Nick:: ds NAME_LENGTH +ENDR +wBoxMonNicksEnd:: + +wBoxDataEnd:: + + +SECTION "GBC Palette Data", WRAM0 + +wGBCBasePalPointers:: ds NUM_ACTIVE_PALS * 2 +wGBCPal:: ds PALETTE_SIZE +wLastBGP:: db +wLastOBP0:: db +wLastOBP1:: db +wdef5:: db +wBGPPalsBuffer:: ds NUM_ACTIVE_PALS * PALETTE_SIZE + + +SECTION "Stack", WRAM0 + +; the stack grows downward + ds $eb - 1 +wStack:: db |
