examples: new sprite animation demo
This commit is contained in:
parent
bde01e402c
commit
e08d610aef
6 changed files with 186 additions and 24 deletions
136
examples/animate.pas
Normal file
136
examples/animate.pas
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
program animate;
|
||||
uses sprites;
|
||||
|
||||
type PictData = record
|
||||
magic,mode:integer;
|
||||
palette: array [0..15] of integer;
|
||||
pixeldata: array [0..31999] of integer;
|
||||
end;
|
||||
|
||||
Sprite = record
|
||||
x,y:integer;
|
||||
oldX,oldY:integer;
|
||||
xdelta,ydelta:integer;
|
||||
curFrame:integer;
|
||||
frameCount:integer;
|
||||
frameTime:integer;
|
||||
frameLeft:integer;
|
||||
changed:boolean;
|
||||
frame:array [0..3] of SpritePixels;
|
||||
end;
|
||||
|
||||
var pic:PictData;
|
||||
filename:string;
|
||||
infile:file;
|
||||
ch:char;
|
||||
stickMan:Sprite;
|
||||
|
||||
procedure WaitVSync; external;
|
||||
|
||||
procedure loadPalette(var pic:PictData);
|
||||
var i:integer;
|
||||
begin
|
||||
for i := 0 to 15 do
|
||||
setpalette(i, pic.palette[i]);
|
||||
end;
|
||||
|
||||
procedure showPic(var pic:PictData);
|
||||
begin
|
||||
PutScreen(pic.pixeldata);
|
||||
end;
|
||||
|
||||
procedure loadSpriteFrame(var aSprite:Sprite;spriteIndex:integer;
|
||||
var sheetFile:file;sheetIndex:integer);
|
||||
begin
|
||||
seek(sheetFile, 8 + sheetIndex * 512);
|
||||
read(sheetFile, aSprite.frame[spriteIndex]);
|
||||
if aSprite.frameCount <= spriteIndex then
|
||||
aSprite.frameCount := spriteIndex + 1;
|
||||
|
||||
aSprite.curFrame := 0;
|
||||
writeln('loaded sprite frame ', spriteIndex, ' from ', sheetIndex);
|
||||
end;
|
||||
|
||||
procedure animateSprite(var aSprite:Sprite);
|
||||
var frameIndex:integer;
|
||||
frameTime,frameLeft:integer;
|
||||
ydelta:integer;
|
||||
oldX,oldY:integer;
|
||||
begin
|
||||
ydelta := aSprite.ydelta;
|
||||
frameIndex := aSprite.curFrame;
|
||||
frameTime := aSprite.frameTime;
|
||||
frameLeft := aSprite.frameLeft;
|
||||
oldX := aSprite.x; oldY := aSprite.y;
|
||||
aSprite.oldX := oldX; aSprite.oldY := oldY;
|
||||
|
||||
frameLeft := frameLeft - 1;
|
||||
if frameLeft <= 0 then
|
||||
begin
|
||||
frameIndex := frameIndex + 1;
|
||||
frameLeft := aSPrite.frameTime;
|
||||
aSprite.frameLeft := frameLeft;
|
||||
aSprite.curFrame := frameIndex;
|
||||
if frameIndex >= aSprite.frameCount then
|
||||
aSprite.curFrame := 0;
|
||||
|
||||
aSprite.frameLeft := frameLeft;
|
||||
|
||||
aSprite.x := aSprite.x + aSprite.xdelta;
|
||||
aSprite.y := aSprite.y + aSprite.ydelta;
|
||||
|
||||
if aSprite.x > 608 then aSprite.x := 0;
|
||||
end;
|
||||
aSprite.frameLeft := frameLeft;
|
||||
end;
|
||||
|
||||
procedure animLoop;
|
||||
var i:integer;
|
||||
oldX,oldY:integer;
|
||||
begin
|
||||
stickMan.x := 0;
|
||||
stickMan.y := 310;
|
||||
stickMan.frameTime := 6;
|
||||
stickMan.frameLeft := stickMan.frameTime;
|
||||
stickMan.curFrame := 0;
|
||||
stickMan.xdelta := 2;
|
||||
stickMan.ydelta := 0;
|
||||
|
||||
oldX := stickMan.x;
|
||||
oldY := stickMan.y;
|
||||
|
||||
while not ConAvail do
|
||||
begin
|
||||
oldX := stickMan.x;
|
||||
oldY := stickMan.y;
|
||||
|
||||
PutSprite(oldX, oldY, stickMan.frame[stickMan.curFrame]);
|
||||
|
||||
animateSprite(stickMan);
|
||||
Delay(10);
|
||||
WaitVSync;
|
||||
|
||||
UndrawSprite(oldX, oldY, pic.pixeldata);
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
filename := 'grey.pict';
|
||||
open(infile, filename, ModeReadonly);
|
||||
read(infile, pic);
|
||||
close(infile);
|
||||
|
||||
writeln('magic: ', pic.magic, ' mode:', pic.mode);
|
||||
|
||||
loadPalette(pic);
|
||||
showPic(pic);
|
||||
|
||||
open(infile, 'Walking.sprt', ModeReadOnly);
|
||||
loadSpriteFrame(stickMan, 0, infile, 0);
|
||||
loadSpriteFrame(stickMan, 1, infile, 1);
|
||||
loadSpriteFrame(stickMan, 2, infile, 2);
|
||||
loadSpriteFrame(stickMan, 3, infile, 3);
|
||||
close(infile);
|
||||
|
||||
animLoop;
|
||||
end.
|
||||
BIN
examples/grey.pict
Normal file
BIN
examples/grey.pict
Normal file
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
type SpritePixels = array[0..31] of integer;
|
||||
type SpritePixels = array[0..128] of integer;
|
||||
type BackgroundPixels = array[0..31999] of integer;
|
||||
|
||||
procedure PutSprite(x,y:integer; var sprite: SpritePixels); external;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
.EQU SPRITE_HEIGHT 16
|
||||
.EQU SPRITE_HEIGHT 32 ; height in lines
|
||||
.EQU SPRITE_STRIPES 4 ; width in words i.e. 8-pixel stripes
|
||||
|
||||
.EQU WORDS_PER_LINE 80
|
||||
.EQU FB_RA $900
|
||||
|
|
@ -65,7 +66,8 @@ CALC_VMEM_ADDR:
|
|||
.EQU PS_Y 16
|
||||
.EQU PS_SHIFT_C 20
|
||||
.EQU PS_SPILL 24
|
||||
.EQU PS_FS 28
|
||||
.EQU PS_STRIPE_C 28
|
||||
.EQU PS_FS 32
|
||||
PUTSPRITE:
|
||||
FPADJ -PS_FS
|
||||
STORE PS_SPRITE_DATA
|
||||
|
|
@ -160,10 +162,14 @@ PS_LOOP2_X:
|
|||
STOREI ; store result into i/o reg
|
||||
DROP
|
||||
|
||||
;
|
||||
; process spilled bits and right half of sprite data
|
||||
;
|
||||
; set counter for remaining stripes
|
||||
LOADC SPRITE_STRIPES - 1
|
||||
STORE PS_STRIPE_C
|
||||
|
||||
;
|
||||
; process spilled bits and next vertical stripe of sprite data
|
||||
;
|
||||
PS_NEXT_STRIPE:
|
||||
; put spill bits on stack for later
|
||||
LOAD PS_SPILL
|
||||
|
||||
|
|
@ -177,6 +183,8 @@ PS_LOOP2_X:
|
|||
LOADC 0
|
||||
STORE PS_SPILL
|
||||
|
||||
; last spill bits are on ToS now
|
||||
|
||||
; shift pixel data to right
|
||||
LOAD PS_SHIFT_C ; load shift count
|
||||
PS_LOOP3: ; test it for zero
|
||||
|
|
@ -231,7 +239,13 @@ PS_LOOP3_X:
|
|||
STOREI
|
||||
DROP
|
||||
|
||||
; write spilled bits into next vmem word
|
||||
LOAD PS_STRIPE_C ; decrement stripe count
|
||||
DEC 1
|
||||
DUP
|
||||
STORE PS_STRIPE_C
|
||||
CBRANCH.NZ PS_NEXT_STRIPE ; if non-zero, next stripe
|
||||
|
||||
; write spilled bits of the last stripe into next vmem word
|
||||
LOAD PS_SPILL ; get spill bits
|
||||
DUP
|
||||
LOADCP CALC_MASK ; calculate sprite mask for spill bits
|
||||
|
|
@ -274,7 +288,8 @@ PS_L_XT:
|
|||
.EQU UD_S_BGDATA 12
|
||||
.EQU UD_S_OFFSET 16
|
||||
.EQU UD_S_BGORIG 20
|
||||
.EQU UD_S_FS 24
|
||||
.EQU UD_STRIPE_C 24
|
||||
.EQU UD_S_FS 28
|
||||
UNDRAWSPRITE:
|
||||
FPADJ -UD_S_FS
|
||||
STORE UD_S_BGORIG
|
||||
|
|
@ -318,25 +333,35 @@ UD_S_L1:
|
|||
STOREI
|
||||
; reuse addr from STOREI
|
||||
|
||||
; load 2nd word of background data
|
||||
LOADC SPRITE_STRIPES - 1 ; set remaining stripe count
|
||||
STORE UD_STRIPE_C
|
||||
|
||||
UD_NEXT_STRIPE:
|
||||
; load next word of background data
|
||||
LOAD UD_S_BGDATA
|
||||
INC 4
|
||||
DUP
|
||||
STORE UD_S_BGDATA
|
||||
LOADI
|
||||
STOREI ; and write it to vmem
|
||||
DROP
|
||||
; reuse addr from STOREI
|
||||
|
||||
; if pixel shift is zero, no 3rd word
|
||||
LOAD UD_STRIPE_C ; decrease remaining stripe count
|
||||
DEC 1
|
||||
DUP
|
||||
STORE UD_STRIPE_C
|
||||
CBRANCH.NZ UD_NEXT_STRIPE ; if non-zero, next stripe
|
||||
|
||||
DROP ; remove addr from STOREI
|
||||
|
||||
; if pixel shift is zero, no spill word
|
||||
LOAD UD_S_PXS
|
||||
CBRANCH.Z UD_S_L2
|
||||
|
||||
; load 3rd word of background data
|
||||
; load next word of background data
|
||||
LOADCP FB_IO
|
||||
LOAD UD_S_BGDATA
|
||||
INC 4
|
||||
DUP
|
||||
STORE UD_S_BGDATA
|
||||
LOADI
|
||||
STOREI ; and write it to vmem
|
||||
DROP
|
||||
|
|
|
|||
BIN
examples/walking.sprt
Normal file
BIN
examples/walking.sprt
Normal file
Binary file not shown.
|
|
@ -2,6 +2,9 @@
|
|||
import sys
|
||||
import png
|
||||
|
||||
sprite_width = 32
|
||||
sprite_height = 32
|
||||
|
||||
def process_pixdata(outfile, pixdata, frameindex = 0, pix_w=640, pix_h=400):
|
||||
|
||||
pixmask = 15
|
||||
|
|
@ -72,22 +75,20 @@ def write_pict_file(width, height, px, metadata, outfile):
|
|||
|
||||
|
||||
def write_sprite_file(width, height, px, metadata, outfile):
|
||||
sprite_height=16
|
||||
|
||||
print("processing as SPRT file with {} sprites...".format(height//sprite_height))
|
||||
if width != 16:
|
||||
print("width must be 16, aborting")
|
||||
if width != sprite_width:
|
||||
print("width must be {}, aborting".format(sprite_width))
|
||||
sys.exit(1)
|
||||
pixdata = list(px)
|
||||
palette = metadata['palette']
|
||||
|
||||
if len(palette) != 16:
|
||||
print("palette must have 16 colors, aborting")
|
||||
print("palette must have 16 colors instead of {}, aborting".format(len(palette)))
|
||||
sys.exit(0)
|
||||
|
||||
with open(outfile,'wb') as f:
|
||||
write_sprite_header(f)
|
||||
process_pixdata(f, pixdata, pix_w=16, pix_h=height)
|
||||
process_pixdata(f, pixdata, pix_w=sprite_width, pix_h=height)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
@ -103,8 +104,8 @@ if __name__ == '__main__':
|
|||
width, height, px, metadata = p
|
||||
if width == 640:
|
||||
write_pict_file(width, height, px, metadata, outfile)
|
||||
elif width == 16:
|
||||
elif width == sprite_width:
|
||||
write_sprite_file(width, height, px, metadata, outfile)
|
||||
else:
|
||||
print("Can't handle this file, need a width of\n640 or 16 pixels with 16 color palette.")
|
||||
print("Can't handle this file, need a width of\n640 or {} pixels with 16 color palette.".format(sprite_width))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue