0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ゲームボーイ_スプライト表示

0
Last updated at Posted at 2026-09-12

目的

今までは人物を背景として描画して来たので、スプライトで表示できるようにしました。
見た目の変化はありませんが、座標を1画素単位で動かせるようになりました。
見たら仕様を思い出せるようにコードを書いたので細かい説明は割愛します。

截图 2026-09-12 13-20-06

実装

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
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?