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

目的

昨日表計算ソフトでドット絵を描き、手作業でバイナリをアセンブリソース内に打ち込みましたが、途中で心が折れたのでマクロで自動化しました。
ゲームボーイでドット絵を表示

本当は会社でも使っているExcelが良かったのですが、買いたくないので無料のLibreOfficeを使ってマクロを描きました。

やっていること

ドットの色は4種類あり、それぞれ2バイトの値で表します。各ドットは左と右に分けて配置します。
例えば左上のドット00は以下の括弧[]で囲ったように左と右に分けて配置します。
エクセル上のドットに書き込まれた値を以下の形式に変換するマクロを作りました。
タイルは8×8なので、この主人公のように16×16の場合は4回実行することになります。
カーソルを合わせた位置を左上として8×8のドットをバイナリに変換するので、位置がずれると表示もずれます。

    db %[0]1000010, %[0]1000010
    db %01110010, %01110010
    db %01011001, %01011000
    db %00111111, %00111111
    db %00011111, %00011011
    db %00011111, %00011110
    db %00001111, %00001001
    db %00000111, %00000111

マクロのソースは以下です。

Sub ExportGameBoyTiles
    Dim oDoc As Object
    Dim oSheet As Object
    Dim oOutSheet As Object
    Dim oSelection As Object
    Dim startCol As Long, startRow As Long
    Dim r As Long, c As Long
    Dim cellValue As String
    Dim dbleft As String
    Dim dbRight As String
    
    oDoc = ThisComponent
    oSheet = oDoc.getCurrentController().getActiveSheet()
    
    ' カーソルの置かれているセル座標を取得
    oSelection = oDoc.getCurrentSelection()
    startCol = oSelection.getRangeAddress().StartColumn
    startRow = oSelection.getRangeAddress().StartRow
    
    ' 2枚目のシートを取得(存在しなければ作成)
    If oDoc.getSheets().getCount() < 2 Then ' シートが1枚しか無ければもう一枚生成
        oDoc.getSheets().insertNewByName("Output", 1)
    End If
    oOutSheet = oDoc.getSheets().getByIndex(1)
        
    For r = 0 To 7
        dbleft = "" ' db左
        dbRight = "" ' db右
        
        For c = 0 To 7
            cellValue = oSheet.getCellByPosition(startCol + c, startRow + r).getString()
            cellValue = Trim(cellValue) ' 前後の空白を除去
            
            If Len(cellValue) >= 2 Then ' 2文字以上あるか(11等)
                dbleft = dbleft & Mid(cellValue, 1, 1)   ' db左側にcellの1文字目(左側)を連結
                dbRight = dbRight & Mid(cellValue, 2, 1) ' db左側にcellの2文字目(右側)を連結
            Else ' 空セルは0とする
                dbleft = dbleft & "0"
                dbRight = dbRight & "0"
            End If
        Next c
        
        ' 出力
        oOutSheet.getCellByPosition(0, r).setString("    db %" & dbleft & ", %" & dbRight)
    Next r
    
    MsgBox "Sheet2 A列 に出力完了", 0, "Done"
End Sub

流れ

ドット絵を描いて、左端にカーソルを合わせます
截图 2026-09-09 20-34-02

マクロ画面を開き実行します
截图 2026-09-09 20-34-23

2枚目のシートに値が出力されるので、アセンブリのソースに貼り付けます。
截图 2026-09-09 20-34-15

ソースコード

マクロで変換した値をソースコードの中に貼り付けて、表示できるか見てみます。

截图 2026-09-09 20-34-07

無事表示されました。

rgbasm -o main.o main.asm && \
rgblink -o main.gb main.o && \
rgbfix -v -p 0xFF main.gb && \
../SameBoy-master/build/bin/SDL/sameboy main.gb
main.asm
SECTION "Entry", ROM0[$0100]
    jp start

SECTION "Main", ROM0[$0150]

start:
    di ; 割り込み禁止
    ld sp, $FFFE ; スタック設定
    
    ; 画面描画停止
    xor a
    ldh[$FF40], a
    
    ; 画面全体を白くする(タイル0を白で初期化して画面全体に適応)
    ld hl, white_tile ; 真っ白(全0)のデータが登録されているタイル
    ld de, $8000      ; タイル0の開始アドレス
    ld bc, 16         ; 1タイルのバイト数    
    call memcpy
        
    ; 画面全体にタイル0(真っ白)を登録する
    ld bc, 32*32
    ld hl, $9800
tile_init:
    ld [hl],0
    inc hl
    dec bc
    ld a, b
    or c
    jr nz, tile_init
        
    ;  主人公
    ld hl, tile1
    ld de, $8000+1*16
    ld bc, 16*4
    call memcpy
    
    ld hl, $9800
    ld [hl],1    ; 主人公左上
    inc hl
    ld [hl],2    ; 主人公右上
    
    ld hl, $9800+32
    ld [hl],3    ; 主人公左下
    inc hl
    ld [hl],4    ; 主人公右下
    
    
    ; パレット
    ld a, %11100100 ; 4色(11 10 01 00)を設定
    ld [$FF47], a
    
    ; 画面描画再開: BG有効
    ld a, %10010001
    ldh [$FF40], a

hang:
    jr hang
    
; メモリ複製関数
; 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
    
white_tile:
    db %00000000, %00000000
    db %00000000, %00000000
    db %00000000, %00000000
    db %00000000, %00000000
    db %00000000, %00000000
    db %00000000, %00000000
    db %00000000, %00000000
    db %00000000, %00000000

; ここから下がマクロで変換したデータ
; 主人公左上
tile1:
    db %00000000, %00000000
    db %00000111, %00000111
    db %00001111, %00001000
    db %00011111, %00010000
    db %00011111, %00010000
    db %00111100, %00111000
    db %00111111, %00111111
    db %01010000, %01010000
    
; 主人公右上
tile2:
    db %00000000, %00000000
    db %11100000, %11100000
    db %11110000, %00010000
    db %11111000, %00001000
    db %11111000, %00001000
    db %00111100, %00011100
    db %11111100, %11111100
    db %00001010, %00001010


; 主人公左下
tile3:
    db %01000010, %01000010
    db %01110010, %01110010
    db %01011001, %01011000
    db %00111111, %00111111
    db %00011111, %00011011
    db %00011111, %00011110
    db %00001111, %00001001
    db %00000111, %00000111



; 主人公右下
tile4:
    db %01000010, %01000010
    db %01001100, %01001100
    db %10011100, %00010100
    db %11110100, %11110100
    db %11001100, %11001100
    db %11001100, %01001100
    db %10111000, %10111000
    db %00000000, %00000000
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?