目的
今までは人物を背景として描画して来たので、スプライトで表示できるようにしました。
見た目の変化はありませんが、座標を1画素単位で動かせるようになりました。
見たら仕様を思い出せるようにコードを書いたので細かい説明は割愛します。
実装
rgbasm -o sptest.o sptest.asm && \
rgblink -o sptest.gb sptest.o && \
rgbfix -v -p 0xFF sptest.gb && \
../SameBoy-master/build/bin/SDL/sameboy sptest.gb
sptest.asm
SECTION "Entry", ROM0[$0100]
jp start
SECTION "Main", ROM0[$0150]
start:
di ; 割り込み禁止
ld sp, $FFFE ; スタック設定
call display_off
; 画面クリア
call bj_clear
; パレット
ld a, %11100100 ; 4色(11 10 01 00)を設定
ld [$FF47], a ; 背景用
ld [$FF48], a ; スプライト用
; タイル読み込み
ld hl, hero
ld de, $8000
ld bc, 16*4 ; タイル4枚
call memcpy
; スプライト登録
ld hl, $FE00
ld [hl], 20 ; Y座標
inc hl
ld [hl], 20 ; X座標
inc hl
ld [hl], 0 ; タイル番号
inc hl
ld [hl], 0
inc hl
ld [hl], 20 ; Y座標
inc hl
ld [hl], 20+8 ; X座標
inc hl
ld [hl], 1 ; タイル番号
inc hl
ld [hl], 0
inc hl
ld [hl], 20+8 ; Y座標
inc hl
ld [hl], 20 ; X座標
inc hl
ld [hl], 2 ; タイル番号
inc hl
ld [hl], 0
inc hl
ld [hl], 20+8 ; Y座標
inc hl
ld [hl], 20+8 ; X座標
inc hl
ld [hl], 3 ; タイル番号
inc hl
ld [hl], 0
call display_on
hang:
jr hang
; 画面描画停止
display_off:
xor a
ldh[$FF40], a
ret
; 画面描画再開: BG有効
display_on:
ld a, %10010011
ldh [$FF40], a
ret
; メモリ複製関数
; HL=元, DE=先, BC=長さ
memcpy:
ld a, [hl]
ld [de], a
inc hl
inc de
dec bc
ld a, b ; B==CならBC==0 (B==$FF,C==$FFの時は失敗する)
or c
jr nz,memcpy ; BC!=0なら繰り返す
ret
; 画面全体にタイル255(真っ白)を登録する
; メモリは初めから0で初期化されているのでタイル255を故意に書き換え無ければ全て0
bj_clear:
ld bc, 32*32
ld hl, $9800
loop1:
ld [hl],255
inc hl
dec bc
ld a, b
or c
jr nz, loop1
ret
hero:
db %00000111, %00000111
db %00001111, %00001000
db %00011111, %00010000
db %00011111, %00010000
db %00111000, %00111000
db %00110111, %00110111
db %01010000, %01010000
db %01000010, %01000010
db %11100000, %11100000
db %11110000, %00010000
db %11111000, %00001000
db %11111000, %00001000
db %00111100, %00011100
db %11101100, %11101100
db %00001010, %00001010
db %01000010, %01000010
db %00110010, %00110010
db %00111001, %00111000
db %01001111, %01001111
db %01001111, %01001111
db %00111111, %00111001
db %00011110, %00010110
db %00011111, %00010001
db %00001110, %00001110
db %01001100, %01001100
db %10011100, %00011100
db %11110010, %11110010
db %11110010, %11110010
db %11111100, %10011100
db %01111000, %01101000
db %11111000, %10001000
db %01110000, %01110000
同日追記
タイルをスプライトに登録する部分をset_tile1616に纏めました。
tile.asmは以下の記事のものを流用しています。
ゲームボーイでドット絵を歩かせる
main.asm
SECTION "Entry", ROM0[$0100]
jp start
SECTION "Main", ROM0[$0150]
INCLUDE "tile.asm"
start:
di ; 割り込み禁止
ld sp, $FFFE ; スタック設定
call display_off
; 画面クリア
call bj_clear
; パレット
ld a, %11100100 ; 4色(11 10 01 00)を設定
ld [$FF47], a ; 背景用
ld [$FF48], a ; スプライト用
; タイル読み込み
ld hl, hero
ld de, $8000
ld bc, 16*4 ; タイル4枚
call memcpy
; スプライト登録
ld hl, $FE00
ld b, 20
ld c, 20
ld d, 0
call set_tile1616
ld hl, $FE00
call display_on
hang:
jr hang
; B:Y座標
; C:X座標
; D:左上タイル番号
set_tile1616:
; 左上
ld [hl], b ; Y座標
inc hl
ld [hl], c ; X座標
inc hl
ld [hl], d ; タイル番号
inc hl
ld [hl], 0
; 右上 X+8
inc hl
ld [hl], b ; Y座標
inc hl
ld a, c
add a,8
ld [hl], a ; X座標
inc hl
inc d
ld [hl], d ; タイル番号
inc hl
ld [hl], 0
; 左下 Y+8
inc hl
ld a, b
add a, 8
ld [hl], a ; Y座標
inc hl
ld [hl], c ; X座標
inc hl
inc d
ld [hl], d ; タイル番号
inc hl
ld [hl], 0
; 右下 X+8 Y+8
inc hl
ld a, b
add a,8
ld [hl], a ; Y座標
inc hl
ld a, c
add a, 8
ld [hl], a ; X座標
inc hl
inc d
ld [hl], d ; タイル番号
inc hl
ld [hl], 0
ret
; 画面描画停止
display_off:
xor a
ldh[$FF40], a
ret
; 画面描画再開: BG有効
display_on:
ld a, %10010011
ldh [$FF40], a
ret
; メモリ複製関数
; HL=元, DE=先, BC=長さ
memcpy:
ld a, [hl]
ld [de], a
inc hl
inc de
dec bc
ld a, b ; B==CならBC==0 (B==$FF,C==$FFの時は失敗する)
or c
jr nz,memcpy ; BC!=0なら繰り返す
ret
; 画面全体にタイル255(真っ白)を登録する
; メモリは初めから0で初期化されているのでタイル255を故意に書き換え無ければ全て0
bj_clear:
ld bc, 32*32
ld hl, $9800
loop1:
ld [hl],255
inc hl
dec bc
ld a, b
or c
jr nz, loop1
ret