I've been cooking up something for the Gameboy, and while it's just a few fades and a main menu, already I have learned tons of stuff. Bank switching is actually alright on the GB, for one.
Anyway, I want to at least share something with you all (having been absent for a while now), so here's my code for scrolling text. You call it like this: (macro)
and here's the code: (note, you need these lovely defines)
An example of some text could be:
It would be called like this:
and would print on the screen as such:
note that the gameboy screen probably isn't big enough for the width of that text.
If you do not want the text to scroll, then easy, just remove the halts to keep from pausing. Maybe replace one of them with a "call wait_vblank" to make sure things don't mess up with vblank and all that.
The code might be a little sloppy, but it works for me. I'll probably cook up a little demo to show it off in action soon.
Anyway, I want to at least share something with you all (having been absent for a while now), so here's my code for scrolling text. You call it like this: (macro)
Code:
print_text: macro
ld hl,\3 ; the text
ld bc,bank(\3) ; the text bank
ld de,_SCRN0+\1+(SCRN_VY_B*\2) ; \1 is x, \2 is y
call f_print_text ; do it!
endm
ld hl,\3 ; the text
ld bc,bank(\3) ; the text bank
ld de,_SCRN0+\1+(SCRN_VY_B*\2) ; \1 is x, \2 is y
call f_print_text ; do it!
endm
and here's the code: (note, you need these lovely defines)
Code:
line_nl = $fe
line_end = $ff
line_length = 32
section "wram", wram0
counter:: db
; wait for vblank
section "wait_vblank", rom0
wait_vblank::
ldh a, [rSTAT-$ff00]
and 2 ; unimportant bytes
jr nz, wait_vblank
ret
section "f_print_text", rom0
f_print_text::
; set line counter
push hl
ld hl,counter
ld [hl],line_length
pop hl
; set bank
ld a,c
ld [$2000],a
call wait_vblank
.loop:
ld a,[hl+] ; get a byte
push af
ld a, [counter]
dec a ; lower line counter
ld [counter],a
pop af
cp line_nl ; is it time for newline?
jr z, .newline ; yep.
cp line_end ; is it done?
ret z ; yes, we're done.
.back:
add $6f ; this is assuming the text tiles are $70 higher than the raw data text
ld [de],a
ei
inc de
halt ; wait a bit!
halt ; wait some more!
; the last frame is only called
; if a is pressed...
; that functionality works, but is
; not wanted just yet.
;call controller
;bit PADB_A,a
;jr nz,.ext_halt
halt ; keep waiting!
;.ext_halt:
jr .loop
.newline:
ld a, [counter]
ld b,a
xor a
; fill until next line
.nl_loop:
xor a
ld [de],a
inc de
dec b
jr nz, .nl_loop
ld a, line_length
ld [counter],a
xor a
jr .back
line_end = $ff
line_length = 32
section "wram", wram0
counter:: db
; wait for vblank
section "wait_vblank", rom0
wait_vblank::
ldh a, [rSTAT-$ff00]
and 2 ; unimportant bytes
jr nz, wait_vblank
ret
section "f_print_text", rom0
f_print_text::
; set line counter
push hl
ld hl,counter
ld [hl],line_length
pop hl
; set bank
ld a,c
ld [$2000],a
call wait_vblank
.loop:
ld a,[hl+] ; get a byte
push af
ld a, [counter]
dec a ; lower line counter
ld [counter],a
pop af
cp line_nl ; is it time for newline?
jr z, .newline ; yep.
cp line_end ; is it done?
ret z ; yes, we're done.
.back:
add $6f ; this is assuming the text tiles are $70 higher than the raw data text
ld [de],a
ei
inc de
halt ; wait a bit!
halt ; wait some more!
; the last frame is only called
; if a is pressed...
; that functionality works, but is
; not wanted just yet.
;call controller
;bit PADB_A,a
;jr nz,.ext_halt
halt ; keep waiting!
;.ext_halt:
jr .loop
.newline:
ld a, [counter]
ld b,a
xor a
; fill until next line
.nl_loop:
xor a
ld [de],a
inc de
dec b
jr nz, .nl_loop
ld a, line_length
ld [counter],a
xor a
jr .back
An example of some text could be:
Code:
the_text:
db "hello this is nicklausw", line_nl
db "and i do not tap dance", line_end
db "hello this is nicklausw", line_nl
db "and i do not tap dance", line_end
It would be called like this:
Code:
print_text 0, 0, the_text
and would print on the screen as such:
Code:
hello this is nicklausw
and i do not tap dance
and i do not tap dance
note that the gameboy screen probably isn't big enough for the width of that text.
If you do not want the text to scroll, then easy, just remove the halts to keep from pausing. Maybe replace one of them with a "call wait_vblank" to make sure things don't mess up with vblank and all that.
The code might be a little sloppy, but it works for me. I'll probably cook up a little demo to show it off in action soon.