mirror of
https://github.com/isometimes/rpi4-osdev
synced 2024-11-13 22:00:40 +00:00
Added wspr.c and examples/wgt22.c to exercise the new sprite library
This commit is contained in:
parent
4ca24f9693
commit
cb35371aa1
5 changed files with 885 additions and 2 deletions
|
@ -23,11 +23,14 @@ bin/lettersspr.o: bin/letters.spr
|
||||||
bin/spacespr.o: bin/space.spr
|
bin/spacespr.o: bin/space.spr
|
||||||
$(LLVMPATH)/llvm-objcopy -I binary -O elf64-littleaarch64 -B aarch64 $< $@
|
$(LLVMPATH)/llvm-objcopy -I binary -O elf64-littleaarch64 -B aarch64 $< $@
|
||||||
|
|
||||||
|
bin/invaderspr.o: bin/invader.spr
|
||||||
|
$(LLVMPATH)/llvm-objcopy -I binary -O elf64-littleaarch64 -B aarch64 $< $@
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(LLVMPATH)/clang --target=aarch64-elf $(CLANGFLAGS) -c $< -o $@
|
$(LLVMPATH)/clang --target=aarch64-elf $(CLANGFLAGS) -c $< -o $@
|
||||||
|
|
||||||
kernel8.img: boot/boot.o $(OFILES) bin/wgt1pal.o bin/wgt1blk.o bin/wgt2blk.o bin/lettersspr.o bin/spacespr.o
|
kernel8.img: boot/boot.o $(OFILES) bin/wgt1pal.o bin/wgt1blk.o bin/wgt2blk.o bin/lettersspr.o bin/spacespr.o bin/invaderspr.o
|
||||||
$(LLVMPATH)/ld.lld -m aarch64elf -nostdlib boot/boot.o $(OFILES) bin/wgt1pal.o bin/wgt1blk.o bin/wgt2blk.o bin/lettersspr.o bin/spacespr.o -T boot/link.ld -o kernel8.elf
|
$(LLVMPATH)/ld.lld -m aarch64elf -nostdlib boot/boot.o $(OFILES) bin/wgt1pal.o bin/wgt1blk.o bin/wgt2blk.o bin/lettersspr.o bin/spacespr.o bin/invaderspr.o -T boot/link.ld -o kernel8.elf
|
||||||
$(LLVMPATH)/llvm-objcopy -O binary kernel8.elf kernel8.img
|
$(LLVMPATH)/llvm-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
BIN
part12-wgt/bin/invader.spr
Normal file
BIN
part12-wgt/bin/invader.spr
Normal file
Binary file not shown.
126
part12-wgt/examples/wgt22.c
Normal file
126
part12-wgt/examples/wgt22.c
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
#include "wgtspr.h"
|
||||||
|
#include "include/mem.h"
|
||||||
|
|
||||||
|
// ######## REQUIRED FUNCTIONS ########
|
||||||
|
|
||||||
|
unsigned long state0 = 1000;
|
||||||
|
unsigned long state1 = 2000;
|
||||||
|
|
||||||
|
unsigned long rand(void)
|
||||||
|
{
|
||||||
|
unsigned long s1 = state0;
|
||||||
|
unsigned long s0 = state1;
|
||||||
|
|
||||||
|
state0 = s0;
|
||||||
|
s1 ^= s1 << 23;
|
||||||
|
s1 ^= s1 >> 17;
|
||||||
|
s1 ^= s0;
|
||||||
|
s1 ^= s0 >> 26;
|
||||||
|
state1 = s1;
|
||||||
|
|
||||||
|
return state0 + state1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wait_msec(unsigned int n)
|
||||||
|
{
|
||||||
|
register unsigned long f, t, r;
|
||||||
|
|
||||||
|
// Get the current counter frequency
|
||||||
|
asm volatile ("mrs %0, cntfrq_el0" : "=r"(f));
|
||||||
|
// Read the current counter
|
||||||
|
asm volatile ("mrs %0, cntpct_el0" : "=r"(t));
|
||||||
|
// Calculate expire value for counter
|
||||||
|
t+=((f/1000)*n)/1000;
|
||||||
|
do{asm volatile ("mrs %0, cntpct_el0" : "=r"(r));}while(r<t);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######## STUB FUNCTIONS ########
|
||||||
|
|
||||||
|
unsigned int kb = 0;
|
||||||
|
|
||||||
|
unsigned int kbhit(void) {
|
||||||
|
kb++;
|
||||||
|
return kb / 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
void getch(void) {
|
||||||
|
wait_msec(0x500000);
|
||||||
|
kb = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######## WGT EXAMPLES ########
|
||||||
|
|
||||||
|
#define SPRITES_IN_FILE 50
|
||||||
|
|
||||||
|
color palette[256];
|
||||||
|
block sprites[SPRITES_IN_FILE+1];
|
||||||
|
void looper (void); /* a routine which controls the sprites */
|
||||||
|
|
||||||
|
void wgt22()
|
||||||
|
{
|
||||||
|
set_clock_rate(get_max_clock());
|
||||||
|
mem_init();
|
||||||
|
vga256 (); /* Initializes WGT system */
|
||||||
|
|
||||||
|
extern unsigned char _binary_bin_invader_spr_start[];
|
||||||
|
wloadsprites (palette, &_binary_bin_invader_spr_start[0], sprites, 0, SPRITES_IN_FILE);
|
||||||
|
/* load first 50 sprites */
|
||||||
|
wsetpalette (0, 255, palette);
|
||||||
|
|
||||||
|
initialize_sprites (sprites); /* initialize them */
|
||||||
|
maxsprite = 10; /* number of sprites on */
|
||||||
|
|
||||||
|
/* Spriteon has the following format:
|
||||||
|
Sprite number, x coord, y coord, sprite number in array of sprites
|
||||||
|
Therefore sprite #1 would be displayed at 160,150 with sprite 1 in the array */
|
||||||
|
|
||||||
|
spriteon (1, 160, 150, 1); /* turn on any sprites */
|
||||||
|
spriteon (2, 10, 100, 3); /* you need */
|
||||||
|
|
||||||
|
/* This move will go left 1, for 300 times, and right 1 for 300 times,
|
||||||
|
and repeat */
|
||||||
|
movex (2, "(1,300,0)(-1,300,0)R");
|
||||||
|
movexon (2);
|
||||||
|
|
||||||
|
movex (1, "(1,150,0)(-1,150,0)R"); /* set up any movement */
|
||||||
|
movexon (1); /* or animation needed */
|
||||||
|
|
||||||
|
/* This animation will animate sprite 2 through a sequence of sprites
|
||||||
|
in the sprite array and keep repeating. */
|
||||||
|
|
||||||
|
animate (2,"(3,50)(4,50)(5,50)(4,50)R");
|
||||||
|
animon (2);
|
||||||
|
|
||||||
|
do {
|
||||||
|
looper ();
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
spriteoff (1); /* turn off sprites */
|
||||||
|
spriteoff (2);
|
||||||
|
/* To be safe, turn off all sprites before ending program.
|
||||||
|
This will free any memory used from them. */
|
||||||
|
|
||||||
|
wfreesprites (sprites, 0, SPRITES_IN_FILE); /* free memory */
|
||||||
|
|
||||||
|
deinitialize_sprites ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void looper (void)
|
||||||
|
{
|
||||||
|
erase_sprites (); /* clear the sprites */
|
||||||
|
|
||||||
|
/* any direct sprite movements must be placed */
|
||||||
|
/* between erase_sprites and draw_sprites */
|
||||||
|
/* notice how sprites #1 and #2 move and animates on their own now!
|
||||||
|
You don't need to change anything to make them move! */
|
||||||
|
|
||||||
|
draw_sprites (1); /* draw them back on */
|
||||||
|
wait_msec(0x3E9F); /* Try removing this to see how fast the
|
||||||
|
sprite engine really is */
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
wgt22();
|
||||||
|
while (1);
|
||||||
|
}
|
67
part12-wgt/wgtspr.h
Normal file
67
part12-wgt/wgtspr.h
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#include "wgt.h"
|
||||||
|
|
||||||
|
/* The following defines should be altered to suit your program needs */
|
||||||
|
#define MAX_SPRITES 100
|
||||||
|
#define MAX_ANIMATION 40
|
||||||
|
#define MAX_MOVE 15
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned char num; /* Sprite number shown */
|
||||||
|
short x, y; /* Coordinates on screen */
|
||||||
|
unsigned char on; /* On/Off, for visibility */
|
||||||
|
|
||||||
|
int ox, oy, ox2, oy2;
|
||||||
|
|
||||||
|
signed char animon; /* Animation on/off */
|
||||||
|
short animation_images[MAX_ANIMATION]; /* Animation numbers */
|
||||||
|
unsigned char animation_speeds[MAX_ANIMATION]; /* Animation speeds */
|
||||||
|
signed char current_animation; /* Current animation counter */
|
||||||
|
unsigned char animation_count; /* Delay count for animation */
|
||||||
|
|
||||||
|
signed char movex_on; /* X movement on/off */
|
||||||
|
short movex_distance[MAX_MOVE]; /* X distance per frame */
|
||||||
|
short movex_number[MAX_MOVE]; /* Number of times to move */
|
||||||
|
unsigned char movex_speed[MAX_MOVE]; /* Delay between each movement */
|
||||||
|
signed char current_movex; /* Movement index */
|
||||||
|
short current_movex_number; /* Number of times moved */
|
||||||
|
unsigned char movex_count; /* Delay count for X movement */
|
||||||
|
|
||||||
|
signed char movey_on; /* Y movement on/off */
|
||||||
|
short movey_distance[MAX_MOVE]; /* Y distance per frame */
|
||||||
|
short movey_number[MAX_MOVE]; /* Number of times to move */
|
||||||
|
unsigned char movey_speed[MAX_MOVE]; /* Delay between each movement */
|
||||||
|
signed char current_movey; /* Movement index */
|
||||||
|
short current_movey_number; /* Number of times moved */
|
||||||
|
unsigned char movey_count; /* Delay count for Y movement */
|
||||||
|
} sprite_object;
|
||||||
|
|
||||||
|
extern sprite_object s[MAX_SPRITES];
|
||||||
|
|
||||||
|
extern block backgroundscreen; /* Holds the constant background */
|
||||||
|
extern block spritescreen; /* Work buffer */
|
||||||
|
|
||||||
|
extern short maxsprite;
|
||||||
|
|
||||||
|
extern short tempx1, tempx2, tempy1, tempy2;
|
||||||
|
|
||||||
|
extern block *sprite_images;
|
||||||
|
|
||||||
|
void animate (short spritenum, char *animation_sequence);
|
||||||
|
void animoff (short spritenum);
|
||||||
|
void animon (short spritenum);
|
||||||
|
void copy_sprites (void);
|
||||||
|
void deinitialize_sprites (void);
|
||||||
|
void draw_sprites (int movement_multiplier);
|
||||||
|
void erase_sprites (void);
|
||||||
|
void expand_dirty_rectangle (int sprite_num, int x, int y, int x2, int y2);
|
||||||
|
void initialize_sprites (block *sprite_blocks);
|
||||||
|
void movex (short spritenum, char *movement_sequence);
|
||||||
|
void movexoff (short spritenum);
|
||||||
|
void movexon (short spritenum);
|
||||||
|
void movey (short spritenum, char *movement_sequence);
|
||||||
|
void moveyoff (short spritenum);
|
||||||
|
void moveyon (short spritenum);
|
||||||
|
short overlap (short spritenum_1, short spritenum_2);
|
||||||
|
void spriteoff (short spritenum);
|
||||||
|
void spriteon (short spritenum, short xcoord, short ycoord, short arrnumber);
|
687
part12-wgt/wspr.c
Normal file
687
part12-wgt/wspr.c
Normal file
|
@ -0,0 +1,687 @@
|
||||||
|
#include "wgt.h"
|
||||||
|
|
||||||
|
/* The following defines should be altered to suit your program needs */
|
||||||
|
#define MAX_SPRITES 100
|
||||||
|
#define MAX_ANIMATION 40
|
||||||
|
#define MAX_MOVE 15
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned char num; /* Sprite number shown */
|
||||||
|
short x, y; /* Coordinates on screen */
|
||||||
|
unsigned char on; /* On/Off, for visibility */
|
||||||
|
|
||||||
|
int ox, oy, ox2, oy2;
|
||||||
|
|
||||||
|
signed char animon; /* Animation on/off */
|
||||||
|
short animation_images[MAX_ANIMATION]; /* Animation numbers */
|
||||||
|
unsigned char animation_speeds[MAX_ANIMATION]; /* Animation speeds */
|
||||||
|
signed char current_animation; /* Current animation counter */
|
||||||
|
unsigned char animation_count; /* Delay count for animation */
|
||||||
|
|
||||||
|
signed char movex_on; /* X movement on/off */
|
||||||
|
short movex_distance[MAX_MOVE]; /* X distance per frame */
|
||||||
|
short movex_number[MAX_MOVE]; /* Number of times to move */
|
||||||
|
unsigned char movex_speed[MAX_MOVE]; /* Delay between each movement */
|
||||||
|
signed char current_movex; /* Movement index */
|
||||||
|
short current_movex_number; /* Number of times moved */
|
||||||
|
unsigned char movex_count; /* Delay count for X movement */
|
||||||
|
|
||||||
|
signed char movey_on; /* Y movement on/off */
|
||||||
|
short movey_distance[MAX_MOVE]; /* Y distance per frame */
|
||||||
|
short movey_number[MAX_MOVE]; /* Number of times to move */
|
||||||
|
unsigned char movey_speed[MAX_MOVE]; /* Delay between each movement */
|
||||||
|
signed char current_movey; /* Movement index */
|
||||||
|
short current_movey_number; /* Number of times moved */
|
||||||
|
unsigned char movey_count; /* Delay count for Y movement */
|
||||||
|
} sprite_object;
|
||||||
|
|
||||||
|
sprite_object s[MAX_SPRITES];
|
||||||
|
|
||||||
|
block backgroundscreen = NULL; /* Holds the constant background */
|
||||||
|
block spritescreen = NULL; /* Work buffer */
|
||||||
|
|
||||||
|
short maxsprite;
|
||||||
|
|
||||||
|
int tempx1, tempy1, tempx2, tempy2;
|
||||||
|
|
||||||
|
block *sprite_images;
|
||||||
|
|
||||||
|
|
||||||
|
void spriteon (short number, short x, short y, short image);
|
||||||
|
void spriteoff (short number);
|
||||||
|
|
||||||
|
void draw_sprites (int movement_multiplier);
|
||||||
|
void initialize_sprites (block *sprite_blocks);
|
||||||
|
void deinitialize_sprites (void);
|
||||||
|
void erase_sprites (void);
|
||||||
|
|
||||||
|
void animate (short spnum, char *str);
|
||||||
|
void animon (short spnum);
|
||||||
|
void animoff (short spnum);
|
||||||
|
void movex (short spnum, char *str);
|
||||||
|
void movey (short spnum, char *str);
|
||||||
|
void movexon (short spnum);
|
||||||
|
void movexoff (short spnum);
|
||||||
|
void moveyon (short spnum);
|
||||||
|
void moveyoff (short spnum);
|
||||||
|
short overlap (short s1, short s2);
|
||||||
|
|
||||||
|
|
||||||
|
void expand_dirty_rectangle (int x, int y, int x2, int y2);
|
||||||
|
void copy_sprites (void);
|
||||||
|
|
||||||
|
|
||||||
|
void spriteon (short number, short x, short y, short image)
|
||||||
|
/* Turns a sprite on at (x,y), with sprites[image] */
|
||||||
|
{
|
||||||
|
tempx1 = x;
|
||||||
|
tempy1 = y;
|
||||||
|
tempx2 = x + wgetblockwidth (sprite_images[image]);
|
||||||
|
tempy2 = y + wgetblockheight (sprite_images[image]);
|
||||||
|
|
||||||
|
/* Find the update box */
|
||||||
|
if (tempx1 < tx) /* X1 */
|
||||||
|
tempx1 = tx;
|
||||||
|
else
|
||||||
|
if (tempx1 >= WGT_SYS.xres)
|
||||||
|
tempx1 = WGT_SYS.xres - 1;
|
||||||
|
|
||||||
|
if (tempy1 < ty) /* Y1 */
|
||||||
|
tempy1 = ty;
|
||||||
|
else
|
||||||
|
if (tempy1 >= WGT_SYS.yres)
|
||||||
|
tempy1 = WGT_SYS.yres - 1;
|
||||||
|
|
||||||
|
if (tempx2 < tx) /* X2 */
|
||||||
|
tempx2 = tx;
|
||||||
|
else
|
||||||
|
if (tempx2 >= WGT_SYS.xres)
|
||||||
|
tempx2 = WGT_SYS.xres - 1;
|
||||||
|
|
||||||
|
if (tempy2 < ty) /* Y2 */
|
||||||
|
tempy2 = ty;
|
||||||
|
else
|
||||||
|
if (tempy2 >= WGT_SYS.yres)
|
||||||
|
tempy2 = WGT_SYS.yres - 1;
|
||||||
|
|
||||||
|
s[number].x = x; /* Set up the coords */
|
||||||
|
s[number].y = y;
|
||||||
|
s[number].num = image;
|
||||||
|
s[number].on = 1;
|
||||||
|
|
||||||
|
s[number].ox = tempx1; /* Set the dirty rectangle location */
|
||||||
|
s[number].oy = tempy1;
|
||||||
|
s[number].ox2 = tempx2;
|
||||||
|
s[number].oy2 = tempy2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void spriteoff (short number)
|
||||||
|
/* Turns a sprite off */
|
||||||
|
{
|
||||||
|
if (s[number].on == 1)
|
||||||
|
s[number].on = 2; /* Signals sprite is to be taken off */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void erase_sprites (void)
|
||||||
|
/* Erases all sprites from background screen by copying the dirty
|
||||||
|
rectangles */
|
||||||
|
{
|
||||||
|
short i;
|
||||||
|
block curscreen;
|
||||||
|
short osx, osy;
|
||||||
|
|
||||||
|
sprite_object *spriteptr;
|
||||||
|
int x, y, x2, y2;
|
||||||
|
|
||||||
|
curscreen = abuf;
|
||||||
|
osx = WGT_SYS.xres;
|
||||||
|
osy = WGT_SYS.yres;
|
||||||
|
|
||||||
|
wsetscreen (spritescreen); /* Go to background screen */
|
||||||
|
|
||||||
|
spriteptr = s;
|
||||||
|
|
||||||
|
for (i = 0; i <= maxsprite; i++) /* Loop through all sprites */
|
||||||
|
{
|
||||||
|
if (spriteptr->on == 1) /* If sprite is on */
|
||||||
|
{
|
||||||
|
x = spriteptr->ox; /* Get the old dirty rectangle coordinates */
|
||||||
|
y = spriteptr->oy;
|
||||||
|
x2 = spriteptr->ox2;
|
||||||
|
y2 = spriteptr->oy2;
|
||||||
|
|
||||||
|
if (x < tx) /* Clip them, but don't change the original */
|
||||||
|
x = tx; /* values, because we need them later */
|
||||||
|
else if (x > bx)
|
||||||
|
x = bx;
|
||||||
|
if (y < ty)
|
||||||
|
y = ty;
|
||||||
|
else if (y > by)
|
||||||
|
y = by;
|
||||||
|
|
||||||
|
wcopyscreen (x, y, x2, y2, backgroundscreen, x, y, spritescreen);
|
||||||
|
}
|
||||||
|
spriteptr++; /* Next sprite */
|
||||||
|
}
|
||||||
|
|
||||||
|
abuf = curscreen;
|
||||||
|
WGT_SYS.xres = osx;
|
||||||
|
WGT_SYS.yres = osy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void expand_dirty_rectangle (int x, int y, int x2, int y2)
|
||||||
|
/* Find boundaries of the old and new sprite rectangle */
|
||||||
|
{
|
||||||
|
if (x < tempx1) /* Compare with */
|
||||||
|
tempx1 = x;
|
||||||
|
if (x2 > tempx2)
|
||||||
|
tempx2 = x2;
|
||||||
|
if (y < tempy1)
|
||||||
|
tempy1 = y;
|
||||||
|
if (y2 > tempy2)
|
||||||
|
tempy2 = y2;
|
||||||
|
|
||||||
|
if (tempx1 < tx) /* Compare with clipping boundaries */
|
||||||
|
tempx1 = tx;
|
||||||
|
|
||||||
|
if (tempx2 > bx)
|
||||||
|
tempx2 = bx;
|
||||||
|
|
||||||
|
if (tempy1 < ty)
|
||||||
|
tempy1 = ty;
|
||||||
|
|
||||||
|
if (tempy2 > by)
|
||||||
|
tempy2 = by;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void copy_sprites (void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
sprite_object *spriteptr;
|
||||||
|
int x, y, x2, y2;
|
||||||
|
|
||||||
|
spriteptr = s;
|
||||||
|
for (i = 0; i <= maxsprite; i++)
|
||||||
|
{
|
||||||
|
if (spriteptr->on > 0) /* If sprite is on */
|
||||||
|
{
|
||||||
|
if (spriteptr->on == 2)
|
||||||
|
spriteptr->on = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* Store these values because they are used more than once */
|
||||||
|
x = spriteptr->x;
|
||||||
|
y = spriteptr->y;
|
||||||
|
x2 = x + wgetblockwidth (sprite_images[spriteptr->num]) - 1;
|
||||||
|
y2 = y + wgetblockheight (sprite_images[spriteptr->num]) - 1;
|
||||||
|
|
||||||
|
/* Set the dirty rectangle to the current position of the sprite */
|
||||||
|
tempx1 = x;
|
||||||
|
tempy1 = y;
|
||||||
|
tempx2 = x2;
|
||||||
|
tempy2 = y2;
|
||||||
|
|
||||||
|
expand_dirty_rectangle (spriteptr->ox, spriteptr->oy,
|
||||||
|
spriteptr->ox2, spriteptr->oy2);
|
||||||
|
|
||||||
|
wcopyscreen (tempx1, tempy1, tempx2, tempy2, spritescreen, tempx1, tempy1,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
spriteptr->ox = x;
|
||||||
|
spriteptr->oy = y;
|
||||||
|
spriteptr->ox2 = x2;
|
||||||
|
spriteptr->oy2 = y2;
|
||||||
|
|
||||||
|
}
|
||||||
|
spriteptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void draw_sprites (int movement_multiplier)
|
||||||
|
/* Draw the sprites on the sprite screen */
|
||||||
|
{
|
||||||
|
short i;
|
||||||
|
block curscreen;
|
||||||
|
short osx, osy;
|
||||||
|
sprite_object *spriteptr;
|
||||||
|
int move;
|
||||||
|
|
||||||
|
curscreen = abuf;
|
||||||
|
osx = WGT_SYS.xres;
|
||||||
|
osy = WGT_SYS.yres;
|
||||||
|
|
||||||
|
wsetscreen (spritescreen); /* Go to sprite screen */
|
||||||
|
|
||||||
|
|
||||||
|
for (move = 0; move < movement_multiplier; move++)
|
||||||
|
{
|
||||||
|
spriteptr = s;
|
||||||
|
for (i = 0; i <= maxsprite; i++) /* Loop through all sprites */
|
||||||
|
{
|
||||||
|
if (spriteptr->on == 1) /* If sprite is on */
|
||||||
|
{
|
||||||
|
if (spriteptr->movex_on == 1) /* X movement on */
|
||||||
|
{
|
||||||
|
if (spriteptr->movex_count != 0)/* Delay Count not reached 0? */
|
||||||
|
spriteptr->movex_count--; /* Decrease count */
|
||||||
|
else /* Get the next move */
|
||||||
|
{
|
||||||
|
spriteptr->current_movex_number++; /* Increase # of times moved */
|
||||||
|
if (spriteptr->current_movex_number ==
|
||||||
|
spriteptr->movex_number[spriteptr->current_movex])
|
||||||
|
/* Moved the right number of times yet? */
|
||||||
|
{
|
||||||
|
spriteptr->current_movex++; /* Increase ptr in move array */
|
||||||
|
if (spriteptr->movex_number[spriteptr->current_movex] == - 1)
|
||||||
|
/* Repeat move */
|
||||||
|
spriteptr->current_movex = 0;
|
||||||
|
else if (spriteptr->movex_number[spriteptr->current_movex]
|
||||||
|
== - 2) /* End move */
|
||||||
|
{
|
||||||
|
spriteptr->current_movex--;
|
||||||
|
spriteptr->movex_on = 0; /* Turn off movement */
|
||||||
|
}
|
||||||
|
spriteptr->current_movex_number = 0;
|
||||||
|
/* Reset number of times moved */
|
||||||
|
}
|
||||||
|
spriteptr->movex_count = spriteptr->movex_speed
|
||||||
|
[spriteptr->current_movex]; /* Get delay */
|
||||||
|
spriteptr->x += spriteptr->movex_distance
|
||||||
|
[spriteptr->current_movex]; /* Update X coord */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (spriteptr->movey_on == 1) /* Y movement on */
|
||||||
|
{
|
||||||
|
if (spriteptr->movey_count != 0)/* Delay Count not reached 0? */
|
||||||
|
spriteptr->movey_count--; /* Decrease count */
|
||||||
|
else /* Get the next move */
|
||||||
|
{
|
||||||
|
spriteptr->current_movey_number++; /* Increase # of times moved */
|
||||||
|
if (spriteptr->current_movey_number ==
|
||||||
|
spriteptr->movey_number[spriteptr->current_movey])
|
||||||
|
/* Moved the right number of times yet? */
|
||||||
|
{
|
||||||
|
spriteptr->current_movey++; /* Increase ptr in move array */
|
||||||
|
if (spriteptr->movey_number[spriteptr->current_movey] == - 1)
|
||||||
|
/* Repeat move */
|
||||||
|
spriteptr->current_movey = 0;
|
||||||
|
else if (spriteptr->movey_number[spriteptr->current_movey]
|
||||||
|
== - 2) /* End move */
|
||||||
|
{
|
||||||
|
spriteptr->current_movey--;
|
||||||
|
spriteptr->movey_on = 0; /* Turn off movement */
|
||||||
|
}
|
||||||
|
spriteptr->current_movey_number = 0;
|
||||||
|
/* Reset number of times moved */
|
||||||
|
}
|
||||||
|
spriteptr->movey_count = spriteptr->movey_speed
|
||||||
|
[spriteptr->current_movey]; /* Get delay */
|
||||||
|
spriteptr->y += spriteptr->movey_distance
|
||||||
|
[spriteptr->current_movey]; /* Update Y coord */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (spriteptr->animon == 1) /* update animation */
|
||||||
|
{
|
||||||
|
if (spriteptr->animation_count != 0) /* Delay count at 0? */
|
||||||
|
spriteptr->animation_count--; /* No, so decrease by one. */
|
||||||
|
else /* Otherwise animate the sprite */
|
||||||
|
{
|
||||||
|
spriteptr->current_animation++; /* Increase animation ptr */
|
||||||
|
if (spriteptr->animation_images[spriteptr->current_animation]
|
||||||
|
== - 1) /* Repeat animation */
|
||||||
|
spriteptr->current_animation = 0;
|
||||||
|
|
||||||
|
if (spriteptr->animation_images[spriteptr->current_animation]
|
||||||
|
== - 2) /* End animation */
|
||||||
|
{
|
||||||
|
spriteptr->current_animation--;
|
||||||
|
spriteptr->animon = 0; /* Turn off animation */
|
||||||
|
}
|
||||||
|
|
||||||
|
spriteptr->num = spriteptr->animation_images
|
||||||
|
[spriteptr->current_animation]; /* Change sprite number */
|
||||||
|
spriteptr->animation_count = spriteptr->animation_speeds
|
||||||
|
[spriteptr->current_animation]; /* Reset delay count */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
spriteptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i <= maxsprite; i++) /* Loop through all sprites */
|
||||||
|
if ((s[i].on == 1) && (sprite_images[ s[i].num ] != NULL))
|
||||||
|
wputblock (s[i].x, s[i].y, sprite_images[ s[i].num ], 1);
|
||||||
|
|
||||||
|
abuf = curscreen;
|
||||||
|
WGT_SYS.xres = osx;
|
||||||
|
WGT_SYS.yres = osy;
|
||||||
|
copy_sprites ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void initialize_sprites (block *sprite_blocks)
|
||||||
|
/* Set up everything for the sprite engine */
|
||||||
|
{
|
||||||
|
short i;
|
||||||
|
|
||||||
|
maxsprite = MAX_SPRITES - 1;
|
||||||
|
|
||||||
|
sprite_images = sprite_blocks;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_SPRITES; i++) /* Turn off the sprites */
|
||||||
|
s[i].on = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if (spritescreen == NULL)
|
||||||
|
spritescreen = wnewblock (0, 0, WGT_SYS.xres - 1, WGT_SYS.yres - 1);
|
||||||
|
/* Make a virtual screen for the work buffer */
|
||||||
|
|
||||||
|
if (backgroundscreen == NULL)
|
||||||
|
backgroundscreen = wnewblock (0, 0, WGT_SYS.xres - 1, WGT_SYS.yres - 1);
|
||||||
|
/* Make a virtual screen for the background screen */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void deinitialize_sprites (void)
|
||||||
|
{
|
||||||
|
short i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_SPRITES; i++)
|
||||||
|
s[i].on = 0;
|
||||||
|
|
||||||
|
wfreeblock (spritescreen);
|
||||||
|
spritescreen = NULL;
|
||||||
|
|
||||||
|
wfreeblock (backgroundscreen);
|
||||||
|
backgroundscreen = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void animate (short spnum, char *str)
|
||||||
|
/* Parse animation string and put the data into an array */
|
||||||
|
{
|
||||||
|
short c, temp1;
|
||||||
|
short x, in, len, minus;
|
||||||
|
short change;
|
||||||
|
|
||||||
|
s[spnum].current_animation = 0; /* Reset current animation ptr */
|
||||||
|
s[spnum].animation_count = s[spnum].animation_speeds[
|
||||||
|
s[spnum].current_animation]; /* Reset delay count */
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
in = 0;
|
||||||
|
|
||||||
|
len = strlen (str);
|
||||||
|
|
||||||
|
/* Parse animation string */
|
||||||
|
|
||||||
|
do {
|
||||||
|
|
||||||
|
do {/* Find the first bracket */
|
||||||
|
c = str[x];
|
||||||
|
x++;
|
||||||
|
} while (c != '(');
|
||||||
|
|
||||||
|
change = 0;
|
||||||
|
do {
|
||||||
|
temp1 = 0;
|
||||||
|
minus = 0;
|
||||||
|
do {
|
||||||
|
c = str[x];
|
||||||
|
if ((c != ',') && (c != 'R') && (c != '-') && (c != ')'))
|
||||||
|
temp1 = (temp1 * 10) + (c - 48);
|
||||||
|
if (c == '-')
|
||||||
|
minus = 1;
|
||||||
|
x++;
|
||||||
|
} while ((x != len) && (c != ',') && (c != 'R') && (c != ')'));
|
||||||
|
|
||||||
|
if (minus == 1)
|
||||||
|
temp1 = - temp1;
|
||||||
|
if (change == 0)
|
||||||
|
s[spnum].animation_images[in] = temp1;
|
||||||
|
else
|
||||||
|
s[spnum].animation_speeds[in] = temp1;
|
||||||
|
change++;
|
||||||
|
} while (c != ')'); /* Until the last bracket */
|
||||||
|
|
||||||
|
in++;
|
||||||
|
if (in >= MAX_ANIMATION)
|
||||||
|
in = MAX_ANIMATION-1;
|
||||||
|
|
||||||
|
s[spnum].animation_images[in] = - 2;
|
||||||
|
|
||||||
|
c = str[x];
|
||||||
|
if (c == 'R')
|
||||||
|
{
|
||||||
|
x = len;
|
||||||
|
s[spnum].animation_images[in] = - 1;
|
||||||
|
}
|
||||||
|
} while (x != len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void animon (short spnum)
|
||||||
|
/* Turns animation for a sprite on */
|
||||||
|
{
|
||||||
|
s[spnum].animon = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void animoff (short spnum)
|
||||||
|
/* Turns animation for a sprite off */
|
||||||
|
{
|
||||||
|
s[spnum].animon = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* X movements */
|
||||||
|
|
||||||
|
void movexon (short spnum)
|
||||||
|
/* Turns a sprite's x movement on */
|
||||||
|
{
|
||||||
|
s[spnum].movex_on = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void movexoff (short spnum)
|
||||||
|
/* Turns a sprite's x movement off */
|
||||||
|
{
|
||||||
|
s[spnum].movex_on = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void movex (short spnum, char *str)
|
||||||
|
/* Parses a movement string and places data into movement arrays */
|
||||||
|
{
|
||||||
|
short c, temp1;
|
||||||
|
short x, in, len, minus;
|
||||||
|
short change;
|
||||||
|
|
||||||
|
s[spnum].current_movex = 0; /* First x movement */
|
||||||
|
s[spnum].movex_count = s[spnum].movex_speed[s[spnum].current_movex];
|
||||||
|
s[spnum].current_movex_number = 0; /* First time it moved */
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
in = 0;
|
||||||
|
|
||||||
|
len = strlen (str);
|
||||||
|
|
||||||
|
do {
|
||||||
|
do {
|
||||||
|
c = str[x];
|
||||||
|
x++;
|
||||||
|
} while (c != '(');
|
||||||
|
change = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
temp1 = 0;
|
||||||
|
minus = 0;
|
||||||
|
do {
|
||||||
|
c = str[x];
|
||||||
|
if ((c != ',') && (c != 'R') && (c != '-') && (c != ')'))
|
||||||
|
temp1 = (temp1*10) + (c - 48);
|
||||||
|
if (c == '-')
|
||||||
|
minus = 1;
|
||||||
|
x++;
|
||||||
|
} while ((x != len) && (c != ',') && (c != 'R') && (c != ')'));
|
||||||
|
|
||||||
|
if (minus == 1)
|
||||||
|
temp1 = - temp1;
|
||||||
|
if (change == 0)
|
||||||
|
s[spnum].movex_distance[in] = temp1;
|
||||||
|
else if (change == 1)
|
||||||
|
s[spnum].movex_number[in] = temp1;
|
||||||
|
else
|
||||||
|
s[spnum].movex_speed[in] = temp1;
|
||||||
|
|
||||||
|
change++;
|
||||||
|
} while (c != ')');
|
||||||
|
in++;
|
||||||
|
|
||||||
|
if (in == MAX_MOVE)
|
||||||
|
x = len;
|
||||||
|
s[spnum].movex_number[in] = - 2;
|
||||||
|
c = str[x];
|
||||||
|
if (c == 'R')
|
||||||
|
{
|
||||||
|
x = len;
|
||||||
|
s[spnum].movex_number[in] = - 1;
|
||||||
|
}
|
||||||
|
} while (x != len);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Y movements */
|
||||||
|
|
||||||
|
void moveyon (short spnum)
|
||||||
|
/* Turns a sprite's y movement on */
|
||||||
|
{
|
||||||
|
s[spnum].movey_on = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void moveyoff (short spnum)
|
||||||
|
/* Turns a sprite's y movement off */
|
||||||
|
{
|
||||||
|
s[spnum].movey_on = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void movey (short spnum, char *str)
|
||||||
|
/* Parses a movement string and places data into movement arrays */
|
||||||
|
{
|
||||||
|
short c, temp1;
|
||||||
|
short x, in, len, minus;
|
||||||
|
short change;
|
||||||
|
|
||||||
|
s[spnum].current_movey = 0; /* First x movement */
|
||||||
|
s[spnum].movey_count = s[spnum].movey_speed[s[spnum].current_movey];
|
||||||
|
s[spnum].current_movey_number = 0; /* First time it moved */
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
in = 0;
|
||||||
|
|
||||||
|
len = strlen (str);
|
||||||
|
|
||||||
|
do {
|
||||||
|
do {
|
||||||
|
c = str[x];
|
||||||
|
x++;
|
||||||
|
} while (c != '(');
|
||||||
|
change = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
temp1 = 0;
|
||||||
|
minus = 0;
|
||||||
|
do {
|
||||||
|
c = str[x];
|
||||||
|
if ((c != ',') && (c != 'R') && (c != '-') && (c != ')'))
|
||||||
|
temp1 = (temp1*10) + (c - 48);
|
||||||
|
if (c == '-')
|
||||||
|
minus = 1;
|
||||||
|
x++;
|
||||||
|
} while ((x != len) && (c != ',') && (c != 'R') && (c != ')'));
|
||||||
|
|
||||||
|
if (minus == 1)
|
||||||
|
temp1 = - temp1;
|
||||||
|
if (change == 0)
|
||||||
|
s[spnum].movey_distance[in] = temp1;
|
||||||
|
else if (change == 1)
|
||||||
|
s[spnum].movey_number[in] = temp1;
|
||||||
|
else
|
||||||
|
s[spnum].movey_speed[in] = temp1;
|
||||||
|
|
||||||
|
change++;
|
||||||
|
} while (c != ')');
|
||||||
|
in++;
|
||||||
|
|
||||||
|
if (in == MAX_MOVE)
|
||||||
|
x = len;
|
||||||
|
s[spnum].movey_number[in] = - 2;
|
||||||
|
c = str[x];
|
||||||
|
if (c == 'R')
|
||||||
|
{
|
||||||
|
x = len;
|
||||||
|
s[spnum].movey_number[in] = - 1;
|
||||||
|
}
|
||||||
|
} while (x != len);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
short overlap (short s1, short s2)
|
||||||
|
/* Tests if two sprites overlap
|
||||||
|
Not pixel precise, just checks rectangles */
|
||||||
|
{
|
||||||
|
short n1, n2;
|
||||||
|
short width1, height1;
|
||||||
|
short width2, height2;
|
||||||
|
|
||||||
|
if ((s[s2].on == 1) && (s[s1].on == 1)) // Make sure both are on
|
||||||
|
{
|
||||||
|
n1 = s[s1].num; // For easier reading
|
||||||
|
n2 = s[s2].num;
|
||||||
|
|
||||||
|
width1 = wgetblockwidth (sprite_images[n1]);
|
||||||
|
width2 = wgetblockwidth (sprite_images[n2]);
|
||||||
|
height1 = wgetblockheight (sprite_images[n1]);
|
||||||
|
height2 = wgetblockheight (sprite_images[n2]);
|
||||||
|
|
||||||
|
if (( s[s2].x >= s[s1].x - width2 ) &&
|
||||||
|
( s[s2].x <= s[s1].x + width1 ) &&
|
||||||
|
( s[s2].y >= s[s1].y - height2 ) &&
|
||||||
|
( s[s2].y <= s[s1].y + height1 ))
|
||||||
|
return 1; /* Collision! */
|
||||||
|
}
|
||||||
|
return 0; /* No collision */
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue