Yeah, it seems that going in doors does switch between horizontal and vertical movements. The second type of door is used for items rooms, and doesn't seem to alter the scrolling. It also appears as if doors themselves stop scrolling for horizontal rooms. A few quick ASM hacks could revamp the scrolling system and make it much more controllable.
With regards to the precise design of such a hack, I assume some sort of "check value at location $(ABCD), y" would come into play during the bubble-door routine. The question is, how should such an offset table be designed?
Metroid's geographical layout consists of a 32x32 room grid (including the empty "pictureframe" around it). To assign a special
bit to each room would require 1024 bits, which is 128 bytes. I could not find a section of empty space (all $FF's) during my scan of the
Metroid ROM. The best I could come up with was a 48-byte snippet at $19980.
It might be more efficient to somehow encode the H/V scrolling status into the
screen type byte itself. Screens seem to be defined by values in the range of $[00-2D]. This means at least six of the eight bits are utilized in determining screen layout itself.
As a lark, I redefined the byte which assigns layout to the first screen in the game (where Samus teleports in, just next to the MaruMari). The screen's original ID is $09; using our two potentially-free bits, I assigned values of $49 and $89 to this spot. Neither crashed the game, but it was the latter that resulted in no observable difference in gameplay. ($49 resulted in a screen of near-nothingness, save a small partial platform at the top of the screen and a pool of invisible lava at the bottom.)
More research will be required to make sure that Bit 7 of the Screen Type bytes isn't already utilized for something, but I think something along those lines will be the most efficient way of bringing about selective scroll-control.
The actual ASM routine would be rather simple:
[
Samus enters a bubble door; the game starts going through it's usual routine; at the point where scrolling is affected, we insert something like this:]
LDA_zp: $GH (I'm assuming there's a zero-page location for "screen type we're going to".)
AND_imm: $80BNE: $07 (Let's assume a set 7th bit denotes vertical scrolling.)
LDA_imm: $00STA_zp: $JK (This will be the byte the original game uses to determine scrolling. Again, I'm assuming a $00 results in horizontal.)
JMP_abs: $LMNP (Whatever routine the original game goes to after determining scrolling.)
LDA_imm: $01 (We wind up here if the logic gate yielded a non-zero result.)
STA_zp: $JK (Let's make the next screen scroll vertically!)
JMP_abs: $LMNPThe beauty of this is that it would come into play ONLY during a bubble-door transition, allowing for "more clever/experienced hackers" to create intersecting maps. (A screen which scrolls vertically when entered via Brinstar, but horizontally when entered via Norfair.) I must admit to being rather n00bish in my knowledge of
Metroid from a hacking standpoint. I *do* fully intend to create a full-fledged rewrite sometime prior to 2015, and something like this routine will be a veritable certainty. That said, I'd love to hear from a veteran
Metroid hacker on this topic.