ZELDA 3 - Time + Day/Night v1.1 - by JaSp
Zeldix :: Zelda III Hacking :: Workshop :: ASM Hacking
Page 1 of 1
Re: ZELDA 3 - Time + Day/Night v1.1 - by JaSp
JaSp wrote:
ZELDA3 TIME + DAY/NIGHT SYSTEM v1.1
===================================
Made by
JaSp
Thanks to
MathOnNapkins' "ZeldaFlow" document and help
Euclid's status bar explanations and help
d4s' help
Byuu's xkas assembler
Geiger's Snes9x Debugger
FuSoYa's zcompress utility
Last update : September, 6 2006
-----------------------------
History:
--------
v2.0:
*Major improvement: complete system re-write. The night effect works on the palettes now, and it works in all situations : layers, mosaic, HDMA warping, sub-areas...
v1.1:
*fixed the pause and save dialog box problems, time no longer increases when a dialog box is openned
v1.0:
*first release
/!\ The IPS PATCH is for an US headered ROM whereas /!\
/!\ the ASM PATCH is for an US headerless ROM /!\
This archive contains :
=======================
*readme_z3 time system.txt this readme file
*z3_time+daynight_source.asm source asm file for use with an assembler on a unheadered Zelda3 ROM
*Zelda3 Time&DayNight_v2.ips ips patch to apply to a headered Zelda3 ROM
*ZeldaGFX.bin graphics file for use with zcompress (http://fusoya.panicus.org/zelda/index.html) containing the "Time-" graphics for HUD
So, what is it ?
================
This patch adds a time control (hours/minutes) to "Zelda 3 : A link to the Past", with a Day/Night handler using this new time feature.
A time indicator has been added to the status bar, showing the hours and minutes. The format is as 24-hour clock, that means from 00:00 to 23:59.
The Day/Night works as follow : on each hour, the palette is updated and changed according to 3 tables telling how many units to substract from the original palette color.
The color units to substract are editable within the ASM source file.
The system is currently set so that 12 real-life minutes correspond to 24 in-game hours, according that the game runs at 60 fps (1 minute in the game = 0.5 real second).
This is also editable within the ASM patch.How to use it for my custom asm hacks ?
- Code:
lorom
;/!\ Patch designed for a HEADERLESS Zelda3 US ROM /!\
;-----------------------------------------------
; ZELDA 3 - Time + Day/Night handling code v2.0
; by JaSp
;
;Last update: September, 6 2006
;
; This patch just adds a timer and a day/night
; handling system.
; Take a look at the readme for further details.
;
; If you have any questions or bug reports :
; jaspile(at)hotmail.com
;
;Thanks to
; MathOnNapkins' "ZeldaFlow" document & Help
; Euclid's status bar explanations & Help
; d4s' Help
; Geiger's Snes9x Debugger
; FuSoYa's zcompress utility
;-----------------------------------------------
;-----------------------------------------------
;----------------[ Time system ]----------------
;-----------------------------------------------
; tiles locations on HUD (status bar)
!hud_min_low = $7EC79E
!hud_min_high = $7EC79C
!hud_hours_low = $7EC798
!hud_hours_high = $7EC796
!hud_template = $0DFF07
org !hud_template
db $10,$24,$11,$24,$12,$24,$90,$24,$90,$24,$13,$24,$90,$24,$90,$24 ;HUD Template(adjusts timer's color)
org $068361
jsl $1CFF30 ;originally JSL $09B06E, executed every frame
org $1CFF30
jsr counter_preroutine
ldx #$00
debut:
ldy #$00
lda $7EE000,x
debut2:
cmp #$0A
bmi draw
sbc #$0A
iny
bra debut2
draw:
adc #$90
cpx #$01
beq minutes_low
sta !hud_hours_low
bra 04
minutes_low:
sta !hud_min_low
tya
clc
adc #$90
cpx #$01
beq minutes_high
sta !hud_hours_high
bra 04
minutes_high:
sta !hud_min_high
inx
cpx #$02
bmi debut
jsl $09B06E
rtl
;--------------------------------
counter_preroutine:
lda $10 ;checks current event in game
cmp #$07 ;dungeon/building?
beq counter_increasing
cmp #$09 ;overworld?
beq overworld
cmp #$0B
beq overworld ;sub-area ? (under the bridge; zora domain...)
cmp #$0E ;dialog box?
beq dialog
rts
overworld:
lda $11
cmp #$23 ;hdma transfer? (warping)
bne mosaic
mosaic:
cmp #$0D ;mosaic ?
bmi counter_increasing
rts
dialog:
lda $11 ;which kind of dialog? (to prevent the counter from increasing if save menu or item menu openned)
cmp #$02 ;NPC/signs speech
beq counter_increasing
rts
counter_increasing:
lda $1A
and #$05 ;change value (1,3,5,7,F,1F,3F,7F,FF) to have different time speed, #$3F is almost 1 sec = 1 game minute
beq increase_minutes
end:
rts
increase_minutes:
lda $7EE001
inc a
sta $7EE001
cmp #$3C ; minutes = #60 ?
bpl increase_hours
rts
increase_hours:
lda #$00
sta $7EE001
lda $7EE000
inc a
sta $7EE000
cmp #$18 ; hours = #24 ?
bpl reset_hours
lda $1B ;check indoors/outdoors
beq outdoors0
rts
outdoors0:
jsl rom_to_buff ;update buffer palette
jsl buff_to_eff ;update effective palette
lda $8C
cmp #$9F ;rain layer ?
beq skip_bg_updt0
jsl $0BFE70 ;update background color
bra inc_hours_end
skip_bg_updt0: ;prevent the sub layer from disappearing ($1D zeroed)
jsl $0BFE72
inc_hours_end:
rts
reset_hours:
lda #$00
sta $7EE000
lda $1B ;check indoors/outdoors
beq outdoors1
rts
outdoors1:
jsl rom_to_buff
jsl buff_to_eff
lda $8C
cmp #$9F ;rain layer ?
beq skip_bg_updt1
jsl $0BFE70 ;update background color
bra reset_end
skip_bg_updt1: ;prevent the sub layer from disappearing ($1D zeroed)
jsl $0BFE72
reset_end:
rts
;-----------------------------------------------
;----[ Day / Night system * palette effect ]----
;-----------------------------------------------
!blue_value = $7EE010
!green_value = $7EE012
!red_value = $7EE014
!temp_value = $7EE016
!pal_color = $7EE018
!x_reg = $08
org $02FF70 ; free space on bank $02
buff_to_eff:
jsr $C769 ; $02:C65F -> palette buffer to effective routine
rtl
rom_to_buff:
jsr $AAF4 ; $02:AAF4 -> change buffer palette of trees,houses,rivers,etc.
jsr $C692 ; $02:C692 -> rom to palette buffer for other colors
rtl
; part of rom pal to buffer routine
;$1B/EF61 9F 00 C3 7E STA $7EC300,x[$7E:C422]
;$1B/EF3D 9F 00 C3 7E STA $7EC300,x[$7E:C412]
;$1B/EF84 9F 00 C3 7E STA $7EC300,x[$7E:C4B2]
org $1BEF3D
jsl new_palette_load
org $1BEF61
jsl new_palette_load
org $1BEF84
jsl new_palette_load
org $0EEE25 ; free space
new_palette_load:
sta !pal_color
cpx #$0041
bpl title_check
sta $7EC300,x
rtl
title_check:
lda $10
and #$00FF
cmp #$0002 ; title or file select screen ?
bpl outin_check
lda !pal_color
sta $7EC300,x
rtl
outin_check:
lda $1B
and #$00FF
beq outdoors2
lda !pal_color
sta $7EC300,x
rtl
outdoors2:
phx
jsl color_sub_effect
plx
sta $7EC300,x
rtl
;--------------------------------
color_sub_effect:
lda $7EE000 ; lda #hours
and #$00FF
clc
adc $7EE000 ; #hours * 2
and #$00FF
tax
do_blue:
LDA !pal_color
AND #$7C00
STA !blue_value
SEC
SBC blue_table,x ; substract amount to blue field based on a table
STA !temp_value
AND #$7C00 ; mask out everything except the blue bits
CMP !temp_value ; overflow ?
BEQ no_blue_sign_change
blue_sign_change:
LDA #$0400 ; lda smallest blue value
no_blue_sign_change:
STA !blue_value
do_green:
LDA !pal_color
AND #$03E0
STA !green_value
SEC
SBC green_table,x ; substract amount to blue field based on a table
STA !temp_value
AND #$03E0 ; mask out everything except the green bits
CMP !temp_value ; overflow ?
BEQ no_green_sign_change
green_sign_change:
LDA #$0020 ; lda smallest green value
no_green_sign_change:
STA !green_value
do_red:
LDA !pal_color
AND #$001F
STA !red_value
SEC
SBC red_table,x ; substract amount to red field based on a table
STA !temp_value
AND #$001F ; mask out everything except the red bits
CMP !temp_value ; overflow ?
BEQ no_red_sign_change
red_sign_change:
LDA #$0001 ; lda smallest red value
no_red_sign_change:
STA !red_value
LDA !blue_value
ORA !green_value
ORA !red_value
rtl
; color_sub_tables : 24 * 2 bytes each = 48 bytes (2 bytes = 1 color sub for each hour)
blue_table:
dw $1000, $1000, $1000, $1000, $1000, $1000, $1000, $0800, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0400, $0800, $0800, $0800, $1000, $1000, $1000
green_table:
dw $0100, $0100, $0100, $0100, $0100, $00C0, $0080, $0040, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0020, $0040, $0080, $00C0, $0100, $0100, $0100
red_table:
dw $0008, $0008, $0008, $0008, $0008, $0006, $0004, $0002, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0002, $0004, $0006, $0008, $0008
background_fix:
beq no_effect ;branch if A=#$0000 (transparent bg)
jsl color_sub_effect
no_effect:
sta $7EC500
sta $7EC300
sta $7EC540
sta $7EC340
rtl
subareas_fix:
sta !pal_color
phx
jsl color_sub_effect
plx
STA $7EC300
STA $7EC340
rtl
thunder_fix:
STA $7EC570,x
LDA $F507,y
sta !pal_color
phx
jsl color_sub_effect
plx
STA $7EC590,x ; 17 bytes instead of 7
LDA $F515,y
sta !pal_color
phx
jsl color_sub_effect
plx
STA $7EC5E0,x ; 17 bytes instead of 7
LDA $F523,y
sta !pal_color
phx
jsl color_sub_effect
plx
STA $7EC5F0,x ; 17 bytes instead of 7
rts
gloves_fix:
sta !pal_color
lda $1B
and #$00FF
beq outdoors3
lda !pal_color
STA $7EC4FA
rtl
outdoors3:
phx
jsl color_sub_effect
plx
STA $7EC4FA
rtl
; $0BFE70 -> background color loading routine
;Background color write fix - 16 bytes
;$0B/FEB6 8F 00 C5 7E STA $7EC500
;$0B/FEBA 8F 00 C3 7E STA $7EC300
;$0B/FEBE 8F 40 C5 7E STA $7EC540
;$0B/FEC2 8F 40 C3 7E STA $7EC340
org $0BFEB6
sta !pal_color
jsl background_fix
nop #8
; Subareas background color fix (under the bridge; zora...)
;$0E/D601 8F 00 C3 7E STA $7EC300[$7E:C300]
;$0E/D605 8F 40 C3 7E STA $7EC340[$7E:C340]
org $0ED601
jsl subareas_fix
;--------------------------------
; Death Mountain thunder routine:
;$0E/F5F1 B9 EB F4 LDA $F4EB,y[$0E:F4EB]
;$0E/F5F4 9F 60 C5 7E STA $7EC560,x[$7E:C562]
;$0E/F5F8 B9 F9 F4 LDA $F4F9,y[$0E:F4F9]
;$0E/F5FB 9F 70 C5 7E STA $7EC570,x[$7E:C572]
;$0E/F5FF B9 07 F5 LDA $F507,y[$0E:F507]
;$0E/F602 9F 90 C5 7E STA $7EC590,x[$7E:C592]
;$0E/F606 B9 15 F5 LDA $F515,y[$0E:F515]
;$0E/F609 9F E0 C5 7E STA $7EC5E0,x[$7E:C5E2]
;$0E/F60D B9 23 F5 LDA $F523,y[$0E:F523]
;$0E/F610 9F F0 C5 7E STA $7EC5F0,x[$7E:C5F2]
;
; 35 bytes
org $0EF5F1
LDA $F4EB,y
sta !pal_color
phx
jsl color_sub_effect
plx
STA $7EC560,x
LDA $F4F9,y
sta !pal_color
phx
jsl color_sub_effect
plx
jsr thunder_fix ; (jsr since it's from bank $0E)
nop #2
;--------------------------------
; Gloves color loading routine
;$1B/EE1B C2 30 REP #$30
;$1B/EE1D AF 54 F3 7E LDA $7EF354[$7E:F354]
;$1B/EE21 29 FF 00 AND #$00FF
;$1B/EE24 F0 0F BEQ $0F [$EE35]
;$1B/EE26 3A DEC A
;$1B/EE27 0A ASL A
;$1B/EE28 AA TAX
;$1B/EE29 BF F5 ED 1B LDA $1BEDF5,x[$1B:EDF7]
;$1B/EE2D 8F FA C4 7E STA $7EC4FA[$7E:C4FA]
;$1B/EE31 8F FA C6 7E STA $7EC6FA[$7E:C6FA]
;$1B/EE35 E2 30 SEP #$30
;$1B/EE37 E6 15 INC $15 [$00:0015]
;$1B/EE39 6B RTL
org $1BEE2D
jsl gloves_fix
=======================================
RAM Addresses :
Hours $7EE000
Minutes $7EE001
How does the ASM source file work ?
===================================
This file is for use with an assembler, I used xkas (http://byuu.cinnamonpirate.com/?page=utils) so it is fully compatible with this assembler.
The code is quite commented, though you may only want to just change the counter_increasing value (to have faster/slower minutes) or the color_sub_tables.
Here is a little help for the units to substract with the tables :
val BLUE GREEN RED
----------------------------
00 0000 0000 0000
01 0400 0020 0001
02 0800 0040 0002
03 0C00 0060 0003
04 1000 0080 0004
05 1400 00A0 0005
06 1800 00C0 0006
07 1C00 00E0 0007
08 2000 0100 0008
09 2400 0120 0009
0A 2800 0140 000A
0B 2C00 0160 000B
0C 3000 0180 000C
0D 3400 01A0 000D
0E 3800 01C0 000E
0F 3C00 01E0 000F
10 4000 0200 0010
11 4400 0220 0011
12 4800 0240 0012
13 4C00 0260 0013
14 5000 0280 0014
15 5400 02A0 0015
16 5800 02C0 0016
17 5C00 02E0 0017
18 6000 0300 0018
19 6400 0320 0019
1A 6800 0340 001A
1B 6C00 0360 001B
1C 7000 0380 001C
1D 7400 03A0 001D
1E 7800 03C0 001E
1F 7C00 03E0 001F
I prefer to work with hex editors
=================================
Time speed control is at 0xE8198 (headered ROM), current value is 1F.
Change it to a value as 1,3,5,7,F,1F,3F,7F,FF to keep it increasing periodically.
Color tables :
Blue is at 0x770EA
Green is at 0x7711A
Red is at 0x7714A
Two bytes per color (low byte, high byte*), 24 colors per table. Use the table above for help.
* example : 34 12 in hex will be $1234 in the game.
Contact Informations
====================
E-mail/MSN : jaspile@hotmail.com (be sure to mention a related object for your mail)
Homepage (currently only for my SMB3 hack) : http://klikechange.free.fr/smb3-sud/
You are allowed to share this patch or link it anywhere, as long as the archive isn't modified and that you don't say you made it.
You are allowed to release a modified version of the asm source if you don't claim the whole code as your own.
When used in hack, credit is recommended though not necessary.
Here's the link to the patch: https://www.dropbox.com/s/oe5x8w9d0yr5ra8/Z3-Time%26DayNight-FINAL.zip
2 small changes to this patch:
First, a minor bug fix. If you get turned into a bunny indoors by the golden star sprite, or use Ether, the palette transformation is applied to Link's sprite based on the current time of day, most noticeable at night because it makes him appear dark. The fix is to check if you're indoors before applying the palette transform. I figured this out for PW, but I'm not 100% sure which subroutines are which in PW vs the original patch here, so I'll just link to the PW fix, and leave it as an exercise to the reader to apply the fix properly.
https://www.zeldix.net/t1087-parallel-worlds-indoor-night-palette-glitch-fix
Essentially, before one of the jsl color_sub_effect subroutine calls (or even before all of them, just to be safe, but in PW I only ended up needing to apply it to one), check the value of $1B. 0=outdoors, call color_sub_effect, 1=indoors, don't call it.
Second, I wanted to add the ability to manually set the time that you exit the church for the first time, for consistency's sake. Personally, I chose to set the time to 04:30 for PW (so it's dark as you walk out, but the first palette change occurs very soon after exiting, to be more noticeable to the player), but this is easily changed. The easiest place to set this is right at the point where the game progress indicator is set to $02, which is actually right as Zelda walks to her place in the sanctuary, so time progresses during the discussion in the sanctuary, but it's good enough.
- Code:
seek($05EDE6)
jsl reset_clock
- Code:
seek($2483D0) // This is the location I used for PW, can be relocated to any free space
reset_clock:
lda #$04 // hours: $00-$17
sta $7EE000
lda #$20 // minutes: $00-$3B
sta $7EE001
jml $00FC62
qwertymodo- Since : 2014-10-21
Re: ZELDA 3 - Time + Day/Night v1.1 - by JaSp
qwerty, do you know, how to turn this ASM off, ie NOP it out. I'm just asking, since sometimes in a night mode in a combo of the forest (or other) overlay the game is way to dark.
And I've never seen PW with this feature turned off.
And I've never seen PW with this feature turned off.
Puzzledude- Since : 2012-06-20
Re: ZELDA 3 - Time + Day/Night v1.1 - by JaSp
It's not as simple as NOPing out code, unfortunately. However, I did manage to do the legwork to figure out how to force time to stop during part 0 and 1 so it doesn't end up looking like day time in the middle of the rain storm. I could probably do something similar with the overlays, but I'd have to figure out how to save and restore the actual time when you leave.
In PW, if you wanted to just completely disable it, probably the easiest way would be to overwrite at $24816C with
But I haven't tested it. I have a feeling it might just make it always night instead, because the "midnight" palette is the one used at index 0 of the lookup table in PW (I changed this in 1.2 so when you load your game, it starts at "noon" instead). And if you were to rotate the lookup table, like I did, then you'd end up with it being full daylight during part 0, which would be weird. So it would probably require a more complicated approach.
In PW, if you wanted to just completely disable it, probably the easiest way would be to overwrite at $24816C with
- Code:
lda $7EE018
sta $7EC300,x
rtl
But I haven't tested it. I have a feeling it might just make it always night instead, because the "midnight" palette is the one used at index 0 of the lookup table in PW (I changed this in 1.2 so when you load your game, it starts at "noon" instead). And if you were to rotate the lookup table, like I did, then you'd end up with it being full daylight during part 0, which would be weird. So it would probably require a more complicated approach.
qwertymodo- Since : 2014-10-21
Re: ZELDA 3 - Time + Day/Night v1.1 - by JaSp
Looks like I actually went ahead and just made everything harder for myself for no real reason. No need to rotate the color palette in PW, I just accidentally overwrote the subroutine responsible for setting the time when you load your save file. Derp.
However, I would like to change the time that it sets. In PW, when you load your save file, it sets the clock to 10:00. To set it to 12:00 instead, change
However, I would like to change the time that it sets. In PW, when you load your save file, it sets the clock to 10:00. To set it to 12:00 instead, change
- Code:
0x03FE0E: $0A -> $0C
qwertymodo- Since : 2014-10-21
Re: ZELDA 3 - Time + Day/Night v1.1 - by JaSp
Good job qwertymodo. Keep up the good work.
Mr.x- Fluteboy
- Since : 2014-04-10
Re: ZELDA 3 - Time + Day/Night v1.1 - by JaSp
I'd love to see this updated honestly, I ADORE this idea.. but it makes the cycle way too fast, each day/night is about 30 seconds, maybe 10
zorazer0- Leever
- Since : 2014-04-08
Similar topics
» The Legend of Zelda - Gates of Time/Darkness
» Day/Night Cycle Thread Gone?
» BS Zelda and BS Zelda Ancient Stone Tablets MSU 1
» Saturday Night Slam Masters
» Unholy Night: The Darkness Hunter
» Day/Night Cycle Thread Gone?
» BS Zelda and BS Zelda Ancient Stone Tablets MSU 1
» Saturday Night Slam Masters
» Unholy Night: The Darkness Hunter
Zeldix :: Zelda III Hacking :: Workshop :: ASM Hacking
Page 1 of 1
Permissions in this forum:
You cannot reply to topics in this forum