#include "sprites.h"
#define XWRAP 192
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef NULL
#define NULL 0
#endif
/* sprite types */
#define sp_MASK_SPRITE 0x00
/* Colour Attributes */
#define TRANSPARENT 0x80
/* Clear Rectangle Flags */
#define sp_CR_TILES 0x01
/* Print String Struct Flags */
#define sp_PSS_INVALIDATE 0x01
/* SP's Sprite Struct */
struct sp_SS {
u8 active;
i16 ptr;
i16 x;
i16 y;
u16 tile;
};
/* Small Rectangles with 8-bit coordinates (used by SP where units are characters) */
struct sp_Rect {
u8 row_coord; /* coordinate of top left corner */
u8 col_coord;
u8 height; /* size */
u8 width;
};
u8 sp_tile_buf[32*24];
u8 sp_attr_buf[32*24];
#define SPRITES_MAX 20
struct sp_SS spriteList[SPRITES_MAX];
u16 spriteBuf[SPRITES_MAX*4];
void sp_Init(void)
{
i16 i;
for(i=0;i<32*24;i++)
{
sp_tile_buf[i]=0;
sp_attr_buf[i]=0;
}
for(i=0;i<SPRITES_MAX;i++) spriteList[i].active=FALSE;
for(i=0;i<sizeof(spriteBuf);i++) spriteBuf[i]=0;
set_sprite(0/*i*/,0,0,SPRITE_END);
//sprites_start(); //яЁш ЁрчЁх°╕ээ√ї ёяЁрщЄрї ртЄюьрЄшўхёъш т√яюыэ хЄё ъюяшЁютрэшх т√тюфшьющ уЁрЇшъш т фтр ¤ъЁрэр
}
void sp_AttrSet(i16 x,i16 y,u8 a)
{
if(y<24) sp_attr_buf[(y<<5)+x]=a;
}
u8 sp_AttrGet(i16 x,i16 y)
{
return (y<24?sp_attr_buf[(y<<5)+x]:0);
}
void sp_TileSet(i16 col,i16 row,u16 tile)
{
draw_tile(col+4,row,tile);
}
/* background tiles */
void sp_PrintAtInv(u8 row, u8 col, u8 colour, u8 udg)
{
i16 ptr;
ptr=(row<<5)+col;
sp_attr_buf[ptr]=colour;
sp_tile_buf[ptr]=udg;
//sp_TileSet(col,row,udg);
draw_tile(col+4,row,udg);
}
void sp_GetTiles(struct sp_Rect *r, u8 *dest)
{
u16 i,j,ptr;
ptr=(r->row_coord<<5)+r->col_coord;
for(i=0;i<r->height;i++)
{
for(j=0;j<r->width;j++)
{
*dest++=sp_tile_buf[ptr++];
}
ptr+=(32-r->width);
}
}
void sp_PutTiles(struct sp_Rect *r, u8 *src)
{
u16 i,j,ptr;
ptr=(r->row_coord<<5)+r->col_coord;
for(i=0;i<r->height;i++)
{
for(j=0;j<r->width;j++)
{
sp_tile_buf[ptr]=*src++;
sp_TileSet(r->col_coord+j,r->row_coord+i,sp_tile_buf[ptr++]);
}
ptr+=(32-r->width);
}
}
/* sprites */
struct sp_SS *sp_CreateSpr(u8 type, u8 rows, u16 graphic, u8 plane, u8 extra)
{
u16 i;
for(i=0;i<SPRITES_MAX;i++)
{
if(!spriteList[i].active)
{
spriteList[i].active=TRUE;
spriteList[i].ptr=i;
spriteList[i].x=0;
spriteList[i].y=0;
spriteList[i].tile=graphic;
return &spriteList[i];
}
}
return NULL;
}
void sp_MoveSprAbs(struct sp_SS *sprite, struct sp_Rect *clip, u16 animate, u8 row, u8 col, u8 hpix, u8 vpix)
{
if(sprite)
{
//if(animate<33+16) animate+=PALETTE_NUM(1);
if(row<24)
{
sprite->x=(col<<3)+hpix/*+(col?128:0)*/;
sprite->y=(row<<3)+vpix/*+(col?128+16:0)*/;
}
sprite->tile=animate;
}
}
void sp_DeleteSpr(struct sp_SS *sprite)
{
if(sprite)
{
sprite->active=FALSE;
}
}
/* updater */
void sp_UpdateNow(void)
{
u16 i,cnt;
u8 x,y;
u16 tile;
//u16 link;
//u16 *buf;
cnt=0;
/*
link=1;
buf=spriteBuf;
for(i=0;i<SPRITES_MAX;i++) if(spriteList[i].active) cnt++;
if(!cnt)
{
*buf++=0;
*buf++=0;
*buf++=0;
*buf++=0;
}
*/
for(i=0;i<SPRITES_MAX;i++)
{
if(!spriteList[i].active) continue;
/*cnt--;
if(cnt==0) link=0;
*buf++=spriteList[i].y;
*buf++=0x0500|link;
*buf++=spriteList[i].tile;
*buf++=spriteList[i].x;
link++;*/
x = spriteList[i].x>>1;
if(x)
{
y = spriteList[i].y;
tile = spriteList[i].tile;
set_sprite(cnt,16+x,y,tile);
cnt++;
if(x<32)
{
//set_sprite(cnt,(16+(XWRAP/2))+x,y,tile);
//cnt++;
set_sprite(cnt,32-8,y,blacksquare);
cnt++;
//set_sprite(cnt,32+(XWRAP/2),y,blacksquare);
//cnt++;
}
else if(x>(16+(XWRAP/2)-8))
{
//set_sprite(cnt,(16-(XWRAP/2))+x,y,tile);
//cnt++;
//set_sprite(cnt,32-8,y,blacksquare);
//cnt++;
set_sprite(cnt,(u8)(32+(XWRAP/2)),y,blacksquare);
cnt++;
}
}
}
set_sprite(cnt,0,0,SPRITE_END);
swap_screen();
vsync();
//update_palette();
//vram_copy(SPRITES_ADR,spriteBuf,sizeof(spriteBuf));
}
void sp_ClearRect(struct sp_Rect *area, u8 colour, u8 udg, u8 flags)
{
u16 i,j;
for(i=0;i<24;i++)
{
for(j=0;j<32;j++)
{
sp_PrintAtInv(i,j,0,0);
}
}
}
/* additional stuff */
void sp_HideAllSpr(void)
{
u16 i;
for(i=0;i<SPRITES_MAX;i++)
{
if(spriteList[i].active)
{
spriteList[i].x=0;
spriteList[i].y=0;
}
//spriteList[i].active=FALSE;
}
sp_UpdateNow();
}
void sp_DelAllSpr(void)
{
u16 i;
for(i=0;i<SPRITES_MAX;i++)
{
spriteList[i].active=FALSE;
}
//sp_UpdateNow();
}