program Tutorial2_Sprites;

@use screens

/*
 The TRSE sprite packer will pack sprites from .flf files to a packed format, identifying
 tiles that are equal etc. The indices will be added to an index file. These should
 all be deleted & initialized on build, or else they'll just continue to grow indefinitely!
*/

// Delete the packed data
@deletefile "images/sprites_packed.flf"
// Delete the packed index lookup file
@deletefile "images/sprites_index.bin"

// Pack sprite 1 : girl at 0,0 - 2,3 in "sprites.flf"
@spritepacker "images/sprites.flf" "images/sprites_packed.flf" "images/sprites_index.bin" "gameboy" 0 0 2 3 0
// Pack sprite 2 : girl at 2,0 - 4,3 in "sprites.flf"
@spritepacker "images/sprites.flf" "images/sprites_packed.flf" "images/sprites_index.bin" "gameboy" 2 0 2 3 0
// Pack sprite 3 : girl at 4,0 - 6,3 in "sprites.flf"
@spritepacker "images/sprites.flf" "images/sprites_packed.flf" "images/sprites_index.bin" "gameboy" 4 0 2 3 0


// Export the packed file to a binary file
@export "images/sprites_packed.flf" "images/sprites_packed.bin" 64


var  
	// Bank to place sprites
	const spriteBank : byte = 2;
	
	sprites_index : incbin("images/sprites_index.bin") bank(spriteBank);
	sprites_data : incbin("images/sprites_packed.bin") bank(spriteBank);

	// 1 sprite takes up 4 bytes, the grl sprite is 3x2x4 bytes starting at $C000 (Sprite ram)
	sprGirl : array[3*2*4] of byte sprram;

	time,x,y,pos, doFlip  : byte;

	// Generate a sine table
    sine : array[256] of byte = BuildSineTable(255);


procedure UpdateSprite();
begin

	// Initialize sprite: address of internal table at $C000 (sprGirl), indices, position in sprite data, width, flipping

	doFlip := 0;
	if (64+time<128) then
		doFlip := sprite_flip_x;
		
	Screens::InitSpriteFromData(#sprGirl, #sprites_index,pos,6 ,2, doFlip);
		
	// Set some sprite X value		
	x:=sine[time]/2+16;
	// Set sprite position			
	Screens::SetSprite(#sprGirl,x,y, 2,3);
	
	// Advance to next sprite		
	if (time&15=0) then
	begin
		pos:=pos+6; // Point to next sprite. Each sprite is 6 bytes long in the index.
		if (pos=18) then pos:=0; // Reset sprite
	end;		


end;


// VBlank is called 1 time per ... vertical blank! 

procedure VBlank();
begin
	time:=time+1;
	UpdateSprite();
end;



begin
	Screens::InitDefaultScreen();
	current_bank:=spriteBank;

	// Tile palette - set background to dark grey 	
	background_palette:=%11010010;
	// Sprite palette
	object0_palette:=%11010010;
	Screens::CopyBankHB(#sprites_data, vram, 8); // Copy 8x$100 bytes of data
	
	time:=0;
	x:=0;
	y:=60;
	pos:=0;
	
	// must have Vertical blank in order to be able to display sprites
	InitVBlank(VBlank());
	EnableVBLank();
	Loop();	
end.
