Haunted: Halloween '86 (The Curse of Possum Hollow)

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Haunted: Halloween '86 (The Curse of Possum Hollow)
by on (#208893)
Haunted: Halloween '86
The Curse of Possum Hollow

Published by Retrotainment Games, a unit of Cash-In Culture

This has been out on NES cartridge and Steam (Windows only) for a while, but somehow it never got a topic until now. It's a sequel to Haunted: Halloween '85, whose first topic became toxic to say the least.
Re: Haunted: Halloween '86 (The Curse of Possum Hollow)
by on (#208895)
Neat, i'll repost my question here so it is on topic.

This is going to be very off topic, but how does Curse of Possum Hollow use its 4 pages of 8kB [ed: chr-ram]? Large loads between levels? Midscreen flicking?

No need to answer, but i'm just curious about ways of getting more mileage out of that many pages of chr-ram as opposed to one or two pages of chr-ram or many pages of chr-rom.
Re: Haunted: Halloween '86 (The Curse of Possum Hollow)
by on (#208896)
Curse is unusual among games using the MMC3 because it uses more than 8 KiB of CHR RAM. The board is mostly equivalent to TGROM, except the CHR RAM is 32 KiB instead of 8 KiB. A year after its release, I feel comfortable describing how its engine uses the CHR RAM. I've hinted at it before but never gave a full post-mortem of how it organizes memory.

Three words: poor man's TQROM.

Pin Bot and High Speed use the TQROM board, which lets the MMC3 switch between a 64 KiB CHR ROM in banks 0-63 and an 8 KiB CHR RAM in banks 64-71. This allows both rapid switching among static tile sets and more dynamic tile sets with selective replacement. I presume that this board didn't see wider use because two memories are more expensive than one.

CHR bank use

Banks 0-3: Playfield
Replaced between levels and during a level

This is decompressed at runtime. As in its predecessor Haunted: Halloween '85, background tiles are compressed with a subset of the PB53 codec used in Action 53. As the camera proceeds through a map, tiles used only in the beginning are replaced with tiles used only at the end, but only 256 tiles are active in any given stretch of a level. The first 16 tiles are reserved for CHR rotation techniques, which produce for example the moving train tracks in the tunnel and the steam effects in the steel mill.

Banks 4-7: Parallax loops
Replaced between levels

Each level may have a 512x240-pixel repeating pattern displayed outside the playfield. The tiles for this repeating pattern come from a separate 4K region, allowing for a total of far more than 256 tiles on the screen. This is most commonly used for a loop that scrolls faster or slower than the main loop.

Banks 8-11: Kana font
Loaded at power-on

This hiragana and katakana font is used only in the Japanese version. Each 8x16 pixel glyph is split into a top half (mostly for voicing diacritics) and a bottom half (the character proper). This RAM is unused in the English language version of the game.

Banks 12-15: Password and Latin fonts
Loaded at power-on

Characters in the password use a 16x16 font with only 32 characters, eating half this 4K page. The rest is for the 8x16-pixel font used for Latin text. This and the kana font must remain available all the time because several levels show dialogue on scanlines 192-223.

Banks 16-23: Donny or Tami
Loaded at game start and during transformation

The player character's animations are entirely replaced when the player presses Select to switch between Donny and Tami.

Banks 24-30: Other actors
Loaded during a level

Seven banks are free for enemy tiles. Interspersed with terrain data in ROM is a list of enemy starting positions, and the terrain reader places these into a list in RAM of enemies waiting to spawn. Once it's an enemy's turn to spawn, the engine tries to load its tiles into a currently unused part of CHR RAM, which takes about eight frames, and releases the enemy from this holding area into the actor table.

Bank 31: Utility sprites
Mostly loaded at game start

This is for sprites that must always be available when needed, such as power-ups, crates, priority exploit boxes, splashes when something enters or leaves water, and the glow around a transforming player character. The last few tiles of this are for the shape of the current level's lift (moving platform).

Except for the lift in bank 31, all banks are loaded all the way or not at all. This means that if cost weren't an issue, the game could have been made using the CHR mapping scheme of TQROM:

CHR ROM banks 0-15: Donny and Tami
CHR ROM banks 16-23: Fonts
CHR ROM banks 24-63: Enemies
CHR RAM banks 64-67: Playfield
CHR RAM banks 68-70: Parallax background
CHR RAM bank 71: Utility sprites

CHR window use

In MMC3, CHR windows make a particular bank visible in a particular part of CHR RAM.

Window 0 ($0000-$07FF): Background
Window 1 ($0800-$0FFF): Background

These are usually set to 12 and 14 (password and Latin font) in menus. In-game, they're set to 0 and 2 (playfield), 4 and 6 (parallax loop), 8 and 10 (Japanese dialogue), or 12 and 14 (English dialogue).

Window 2 ($1000-$13FF): Player character
Window 3 ($1400-$17FF): Enemy
Window 4 ($1800-$1BFF): Enemy
Window 5 ($1C00-$1FFF): Utility sprites

Window 2 is constantly changing during gameplay as the player performs different moves. Windows 3 and 4 change when a new kind of enemy pops out. Some sorts of enemies commonly seen together share a 1K sprite sheet. Which enemies must be decided in advance; it cannot be changed at runtime due to engine limits. An enemy whose sprite sheet exceeds 1K, such as a boss, reserves a window for itself to change when it performs moves.

Incidentally, most of the enemy "pop-in" seen in the final game is not caused by loading sprite sheets into CHR RAM. It's caused by one of two things: a limit of five enemies at once to avoid excessive slowdown, and contention for windows 3 and 4.

Mapper simplification

The shipping board doesn't actually implement full oversize TGROM. To fit it into the CPLD, Paul at Infinite NES Lives had to cut out a few features.

TGROM has 3-bit CHR bank numbers; an oversize version would have 5. This would have meant 12 more bits of state and two more multiplexed outputs, for a total of 14 macrocells on the architecture of the CPLD that we were using. To compensate, we cut out enough to save 9 bits and 2 muxed outs:

  • The C bit in $8000, which swaps PPU $0000-$0FFF and $1000-$1FFF, for 1 bit
  • The P bit in $8000, which swaps CPU $8000-$9FFF and $C000-$DFFF, for 1 bit
  • Bit 4 of all CHR bank numbers, for 6 bits and 1 muxed out. Instead, CHR RAM A14 is hardwired to PA12. This means only the background (windows 0 and 1) can use banks 0-15, and only sprites (windows 2-5) can use banks 16-31.
  • The mirroring bit in $A000, which multiplexes PA10 and PA11 into A10 out, for 1 bit and 1 muxed out. We instead hardwire vertical mirroring.
  • WRAM control wasn't present in TGROM anyway.

It's also compatible with a full MMC3 because emulators emulate a full MMC3, though my test ROM for MMC3 with bigger CHR RAM actually adheres to the simplifications of the Curse board. Lately, Paul has switched to level-translated boards that run at 3.3 V internally. These use a larger Lattice CPLD that can hold a full MMC3. I don't know if later copies of Curse are on this board or if he's still using the dwindling supplies of the older CPLD. Apart from initial consultation about which mapper simplifications are acceptable, I've stayed mostly on the software side of this project.
Re: Haunted: Halloween '86 (The Curse of Possum Hollow)
by on (#208903)
If anyone isn't aware, I just posted the music to HH86 on my YouTube channel. It is very good.