Since nobody downloaded any affected versions yet, I also added a few other changes to the most recent release that fix bugs in certain situations :-)
More information in the release announcement
Regarding the doors-closing at night feature, here's the background tile indexes for the open door and the closed door:
Closed door: Open door:
DE DF E0 E1 DE DF E0 E1
AD 77 AF 9D AD 00 00 9D
94 78 7C 97 94 00 00 97
94 79 7D 97 94 00 00 97
94 78 7C 97 94 00 00 97
94 7B EF 97 94 F0 F0 97
AA 8E 8F AB AA 8E 8F AB
Nintendulator's debugger was useful here. I would normally use FCEUX's here, but for some reason invoking FCEUX's debugger seems to crash Aero.
Basically we'd need some additional set of bytes in the level data, that would be interpreted to mean "00 00 00 00 00 00 00 00" at day and "77 78 79 7B 7C 7D AF EF" at night. Such as, "01 02 03 04 05 06 07 08". These would be replaced with the first table or the second table depending on hour. And when the hour changes, the screen background graphics would be refreshed as if the screen just scrolled.
Every open door in the town map data would need to be replaced with:
DE DF E0 E1
AD 01 07 9D
94 02 05 97
94 03 06 97
94 02 05 97
94 04 08 97
AA 8E 8F AB
So the list of changes needed would be:
1) Change level data to use different tile numbers for open doors.
Currently it suffices to know that if I put "AD 01 07 9D 94 02 05 97" at $85A9 and "94 03 06 97 04 02 05 97 94 04 08 97" at 86E1 in bank 4, I have accomplished this part, without knowing much else about the level data.
2) Change level-data reading routines to substitute these tile numbers depending on hour of day.
This requires understanding the routines that read the level data, which I don't (not fully at least). However, doing a search for "lda ($63),y" should find many relevant places, because $63 holds the pointer to the data that was modified in step #1. Furthermore, after some mathematics is applied to that pointer, $16 holds the pointer to the actual byte; so searching for "lda ($16),y" it is. The instruction at $F452 for instance loads the byte that is written when undoing the dialog box. $E54A loads the byte that is written when scrolling vertically. $E855 loads the byte that is written when scrolling horizontally or when restoring the screen. Changing all these to do the translation of the byte would be necessary, but I don't know if that's all that is required.
these two-byte "lda ($16),y" instructions would need to be changed into this 16-byte code (+8-byte table):
lda ($16),y ; original instruction, kept as is
beq skip ; cost so far: 3 cycles if $00, 2 cycles otherwise
cmp #9 ; cost so far: 4 cycles
bcs skip ; cost so far: 7 cycles if >=$09, 6 otherwise
tay ; cost so far: 8 cycles
lda IsNightTime ; cost so far: 11 cycles
beq skip ; cost so far: 14 cycles if day, 13 otherwise
lda Table_NightDoor-1,y ; cost so far: 17 cycles
; cost so far: 3 cycles if $00, 7 cycles if not door, 14 cycles if day, 17 cycles if night
;continue as before
Which would add 3 to 17 cycles of extra cost for every single 8x8 tile rendering, assuming this code could fit in the space of those original 2 bytes. Because it can't, a JSR+RTS must be added, which adds an additional cost of 12 cycles. Thus, the cost of rendering a single column of 32 8x8 tiles when scrolling horizontally would be by average around 32*(12+11) = 736 cycles, which is quite
a lot. It would make the already lag-prone game even laggier.
EDIT: After studying the surrounding code in each of those three locations, it seems that by rewriting the game's original code to use a small amount of sense
, it's possible to add this town door thing and still come out a winner cycle-wise. This just leaves step #3...
3) Change the day-night transition such that it triggers a whole screen refresh. There is no such whole-screen refresh background job in the game, so it would have to be created. There's a whole-screen refresh that works while the screen is blanked and game paused (this is used when returning from sramsave/map screens, resuming from death, and when entering/exiting a door or new scene), but blanking the screen is exactly what we don't want here.
This is something that may go horribly wrong and require dozens of hours of iterative development and testing to get it right.