Skip to content
Permalink
Browse files

Libbet faces the chosen direction

  • Loading branch information
pinobatch committed Oct 14, 2018
1 parent bba4a58 commit 54e8c7ebe35bb6e6ed07e98802c907aeba8e855b
@@ -2,8 +2,8 @@ It's actually happening.

- Instructions screen
- Draw door opening once quota reached
- Sprite converter: Output cel in mspr format
- Animate Libbet rolling
- Animate Libbet jumping
- Sound effect engine
- Sequence of map sizes

@@ -86,6 +86,10 @@ obj/gb/floorvram.o: \
obj/gb/floorpieces-h.chrgb.pb16 obj/gb/floorborder-h.chrgb.pb16
obj/gb/statusbar.o: \
obj/gb/bigdigits-h.chr1
obj/gb/metasprite.o: \
obj/gb/Libbet.z80
obj/gb/main.o: \
obj/gb/Libbet.chrgb.pb16

# Graphics conversion

@@ -104,3 +108,13 @@ obj/gb/%-h.chr1: tilesets/%.png

%.pb16: tools/pb16.py %
$(PY) $^ $@

# One Make quirk that's very annoying to work around is that it's
# remotely possible for recipes with multiple outputs to fall out
# of sync.

obj/gb/Libbet.chrgb: tools/extractcels.py tilesets/Libbet.ec tilesets/Libbet.png
$(PY) $^ $@ obj/gb/Libbet.z80

obj/gb/Libbet.z80: obj/gb/Libbet.chrgb
touch $@
@@ -275,13 +275,12 @@ prepare_hDrawCell::
ld b,a

; Calculate base tile ID (shades: 0, 4, 8, C; deadends: 40, 44, 48, 4C)
and $0F ; save only deadend and bits
and $0F ; save only deadend, entered, and shade bits
add a
add a
; If bits 2 (not round trip reachable) and 3 (entered) are both
; true, this is a dead end, for which tiles $40-$4F should be used.
; Otherwise, tiles $00-$0F (plus arrows) should be used.
; move deadend bit from bit 4 to bit 6
; true, this is an entered dead end, drawn with tiles $40-$4F.
; Otherwise it's a regular cell, drawn with $00-$0F (plus arrows).
add $10
and $4C

@@ -1,6 +1,9 @@
include "src/hardware.inc"
include "src/global.inc"

section "movevars", WRAM0
cur_facing: ds 1

section "main", ROM0

timer_handler::
@@ -19,10 +22,10 @@ main::

call load_floor_chr
call load_statusbar_chr
ld hl,plain_boulder
ld de,CHRRAM0
ld bc,16
call memcpy
ld hl,CHRRAM0
ld de,Libbet_pb16
ld b,40
call pb16_unpack_block
ld bc,2
call srand
call run_dma ; shut up BGB
@@ -36,6 +39,8 @@ another_floor:
call make_good_floor
xor a
ld [cur_score],a
ld a,2
ld [cur_facing],a

call lcd_off

@@ -88,15 +93,21 @@ forever:
add b
add 24
ldh [hmsprXLo],a


ld a,[cur_facing]
ld de,Libbet_facing_to_frame
call de_index_a
ld a,l
ldh [hmsprAttr],a
ld a,h
ldh [hmsprFrame],a

xor a
ldh [hmsprXHi],a
ldh [hmsprYHi],a

ld a,$00
ldh [hmsprSheetID],a
ldh [hmsprAttr],a
ldh [hmsprFrame],a
ldh [hmsprBaseTile],a
call draw_metasprite

@@ -129,6 +140,8 @@ forever:
inc c
rra
jr nc,.ctzloop
ld a,c
ld [cur_facing],a
ld a,[cur_keys]
bit PADB_A,a ; key A
jr z,.notjump
@@ -198,12 +211,8 @@ forever:
jp another_floor


plain_boulder:
dw `00111100
dw `01333310
dw `13333331
dw `13333331
dw `13333331
dw `13333331
dw `01333310
dw `00111100
Libbet_pb16:
incbin "obj/gb/Libbet.chrgb.pb16"

Libbet_facing_to_frame:
dw $0E00, $0E20, $1C00, $0000
@@ -3,6 +3,7 @@ include "src/hardware.inc"
include "src/global.inc"

SPRITEHT = 8
SPRITEWID = 8

; args
rsset hLocals
@@ -28,37 +29,31 @@ hmsprStripXHi rb 1
section "metasprite", ROM0

draw_metasprite::
; Subtract 119 if flipped else 112 from each coord
; so that ones' complement addition works as expected
ldh a,[hmsprAttr]
ld c,a

ld d,112
bit OAMB_YFLIP,c
jr z,.noycoordflipcorrect
ld d,111 + SPRITEHT
.noycoordflipcorrect:
; Correct coordinates for offset binary representation
ldh a,[hmsprYLo]
sub d
sub 128-16
ldh [hmsprYLo],a
ldh a,[hmsprYHi]
sbc 0
ldh [hmsprYHi],a

ld de,120 * 256 + 8
bit OAMB_XFLIP,c
jr z,.noxcoordflipcorrect
ld de,(119 + 8) * 256 + (256 - 8)
.noxcoordflipcorrect:
ldh a,[hmsprXLo]
sub d
sub 128-8
ldh [hmsprXLo],a
ldh a,[hmsprXHi]
sbc 0
ldh [hmsprXHi],a
ld a,e

; Set increase direction for X flip
ldh a,[hmsprAttr]
ld c,a
ld a,8
bit OAMB_XFLIP,c
jr z,.noxcoordflipcorrect
ld a,-8
.noxcoordflipcorrect:
ldh [hmsprXAdd],a

; Look up metasprite address for this cel
ld de,sheet_msprtables
ldh a,[hmsprSheetID]
call de_index_a
@@ -67,8 +62,13 @@ draw_metasprite::
ldh a,[hmsprFrame]
call de_index_a

; Load destination address
ld a,[oam_used]
ld e,a
ld d,high(SOAM)
.rowloop:
; Invariants here:
; DE is multiple of 4 and within shadow OAM
; HL at start of sprite strip
; C equals [hmsprAttr], not modified by a strip
; Load Y strip offset
@@ -140,10 +140,7 @@ draw_metasprite::
inc a
ld b,a

; Prepare to copy sprites to OAM
ld a,[oam_used]
ld e,a
ld d,high(SOAM)
; Copy sprites to OAM
.spriteloop:
push bc ; sprite count and strip attribute
ld a,[hmsprStripY]
@@ -205,8 +202,4 @@ sheet_msprtables:
dw Libbet_mspraddrs

Libbet_mspraddrs:
dw mspr_Libbet_default

mspr_Libbet_default:
db 128-8,128-4,$00,$00
db 0
include "obj/gb/Libbet.z80"
File renamed without changes.
File renamed without changes.
@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""
Extract sprite cels from an image
@@ -21,7 +21,6 @@
import re
import argparse
from collections import OrderedDict
sys.path.append("../../thwaite-nes/tools")
import pilbmp2nes

# Parsing the strips file
@@ -157,7 +156,7 @@ def add_frame(self, words):

def add_strip(self, words):
frame = self.frames[self.cur_frame]
palette, cliprect = int(words[0]), None
palette, rect = int(words[0]), frame.cliprect
if len(words) == 5 and all(x.isdigit() for x in words[1:5]):
rect = tuple(int(x) for x in words[1:5])
elif len(words) != 1:
@@ -377,12 +376,40 @@ def gbtilestoim(tiles):
im.putpalette(previewpalette)
return im

def emit_frames(framestrips, nt, framenames):
ntoffset = 0
out = [" dw mspr_" + n for n in framenames]
for framename, strips in zip(framenames, framestrips):
out.append("mspr_%s:" % framename)
for palette, tiles, x, y in strips:
ntiles = len(tiles)
y += 128
x += 128
palette |= (ntiles - 1) << 5
ntend = ntoffset + ntiles
tiles = ",".join(
"$%02x" % (((x & 0x6000) >> 7) | (x & 0x3F))
for x in nt[ntoffset:ntend]
)
ntoffset = ntend
out.append(" db %3d,%3d,$%02x,%s" % (y, x, palette, tiles))
out.append(" db 0\n")
out.extend("FRAME_%s equ %d" % (n, i) for i, n in enumerate(framenames))
out.extend(" global FRAME_%s" % (n,) for n in framenames)
return "\n".join(out)

# CLI front end

def parse_argv(argv):
p = argparse.ArgumentParser()
p.add_argument("STRIPSFILE")
p.add_argument("CELIMAGE")
p.add_argument("CHRFILE", nargs="?",
help="where to write unique tiles")
p.add_argument("ASMFILE", nargs="?",
help="where to write asm")
p.add_argument("-v", "--verbose", action="store_true",
help="print debug info and write preview images")
return p.parse_args(argv[1:])

def main(argv=None):
@@ -397,14 +424,22 @@ def main(argv=None):
tile for frame in framestrips for row in frame for tile in row[1]
]
utiles, nt = flipuniq(alltiles)
print("%d tiles, %d unique" % (len(nt), len(utiles)))

stripsvis(im, doc.frames).save("_stripsvis.png")
gbtilestoim(alltiles).save("_alltiles.png")
gbtilestoim(utiles).save("_utiles.png")
if args.verbose:
print("%d tiles, %d unique" % (len(nt), len(utiles)),
file=sys.stderr)
stripsvis(im, doc.frames).save("_stripsvis.png")
gbtilestoim(alltiles).save("_alltiles.png")
gbtilestoim(utiles).save("_utiles.png")
if args.CHRFILE:
with open(args.CHRFILE, "wb") as outfp:
outfp.writelines(utiles)
if args.ASMFILE:
with open(args.ASMFILE, "w") as outfp:
outfp.write(emit_frames(framestrips, nt, list(doc.frames)))

if __name__=='__main__':
if "idlelib" in sys.modules:
if "idlelib" in sys.modules and len(sys.argv) < 2:
main("""
extractcels.py Libbet.ec.txt spritesheet-side.png
""".split())

0 comments on commit 54e8c7e

Please sign in to comment.
You can’t perform that action at this time.