2
/////////////////////////////////////////////////////////////
6
// Up to this point we have been using a single clipping
7
// rectangle in all the sp1_MoveSpr*() calls we have been
8
// making with little explanation of what this clipping rectangle
9
// is for. It's exactly what you think it is -- the sprite
10
// is drawn such that only the parts of the sprite inside
11
// the rectangle get drawn. By using the full screen as
12
// clipping rectangle up to this point we have been
13
// accomplishing one important function of the clipping
14
// rectangle and that is preventing the sprite engine from
15
// drawing into non-existent areas of the screen.
17
// Now we are going to use the clipping rectangle for a
18
// second purpose which is to control where the sprites
19
// can appear on screen. Two new clipping rectangles are
20
// defined and the sp1_MoveSprAbs() call in the main loop
21
// uses clipping rectangle #1 for the first five sprites
22
// created (the MASKed sprites) and clipping rectangle #2
23
// for the rest (the XOR sprites). The result is,
24
// although the rectangles are freely moving across the
25
// entire screen, they are only drawn when they appear
26
// in their respective clipping rectangles.
28
// Clipping can only be done to character cell boundaries.
30
// Among applications of this, consider a vertical gate
31
// hidden in a doorway. As the player approaches it drops
32
// closed. If the gate is a sprite with clipping rectangle
33
// covering the doorway only, it can appear to drop into
34
// place by being moved from over the doorway onto the
36
/////////////////////////////////////////////////////////////
38
// zcc +ts2068 -vn ex4c.c -o ex4c.bin -create-app -lsp1 -lmalloc
40
#include <sprites/sp1.h>
45
#pragma output STACKPTR=47104 // place stack at $b800 at startup
46
long heap; // malloc's heap pointer
49
// Memory Allocation Policy
51
void *u_malloc(uint size) {
55
void u_free(void *addr) {
59
// Clipping Rectangle for Sprites
61
struct sp1_Rect cr = {0, 0, 64, 24}; // full screen
62
struct sp1_Rect clip1 = {1, 2, 24, 12}; // clip region 1
63
struct sp1_Rect clip2 = {10, 36, 24, 12}; // clip region 2
65
// Table Holding Movement Data for Each Sprite
68
struct sp1_ss *s; // sprite handle returned by sp1_CreateSpr()
69
char dx; // signed horizontal speed in pixels
70
char dy; // signed vertical speed in pixels
73
struct sprentry sprtbl[] = {
74
{0,2,0}, {0,0,1}, {0,2,2}, {0,4,1}, {0,2,3}, // double the spectrum's dx speed as we have
75
{0,6,1}, {0,4,3}, {0,6,2}, {0,2,1}, {0,4,2} // double the horizontal resolution
78
// A Hashed UDG for Background
80
uchar hash[] = {0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa};
82
// Attach C Variable to Sprite Graphics Declared in ASM at End of File
84
extern uchar gr_window[];
97
// Initialize MALLOC.LIB
99
heap = 0L; // heap is empty
100
sbrk(40000, 6000); // make available memory from 40000-45999
102
// Set 512x192 Video Mode
104
memset(16384, 0, 6144); // clear both halves of the display file before switching video mode
105
memset(24576, 0, 6144);
106
ts_vmod(PAPER_BLACK | VMOD_HIRES); // select 64-col mode with black background
108
// Initialize SP1.LIB
110
sp1_Initialize(SP1_IFLAG_MAKE_ROTTBL | SP1_IFLAG_OVERWRITE_TILES | SP1_IFLAG_OVERWRITE_DFILE, ' ');
111
sp1_TileEntry(' ', hash); // redefine graphic associated with ' ' character
113
// mark the two rectangular areas on screen so we can see them
115
sp1_ClearRect(&clip1, '+', SP1_RFLAG_TILE);
116
sp1_ClearRect(&clip2, '+', SP1_RFLAG_TILE);
118
sp1_Invalidate(&cr); // invalidate entire screen so that it is all initially drawn
119
sp1_UpdateNow(); // draw screen area managed by sp1 now
121
// Create Ten Masked Software-Rotated Sprites
123
for (i=0; i!=10; i++) {
127
s = sprtbl[i].s = sp1_CreateSpr(SP1_DRAW_MASK2LB, SP1_TYPE_2BYTE, 3, 0, i);
128
sp1_AddColSpr(s, SP1_DRAW_MASK2, 0, 48, i);
129
sp1_AddColSpr(s, SP1_DRAW_MASK2RB, 0, 0, i);
130
sp1_MoveSprAbs(s, &cr, gr_window, 10, 14, 0, 4);
134
s = sprtbl[i].s = sp1_CreateSpr(SP1_DRAW_XOR2LB, SP1_TYPE_2BYTE, 3, 0, i);
135
sp1_AddColSpr(s, SP1_DRAW_XOR2, 0, 48, i);
136
sp1_AddColSpr(s, SP1_DRAW_XOR2RB, 0, 0, i);
137
sp1_MoveSprAbs(s, &cr, gr_window, 10, 14, 0, 4);
142
while (1) { // main loop
144
sp1_UpdateNow(); // draw screen now
146
for (i=0; i!=10; i++) { // move all sprites
151
sp1_MoveSprRel(se->s, &clip1, 0, 0, 0, se->dy, se->dx);
153
sp1_MoveSprRel(se->s, &clip2, 0, 0, 0, se->dy, se->dx);
155
if (se->s->row > 21) // if sprite went off screen, reverse direction
158
if (se->s->col > 61) // notice if coord moves less than 0, it becomes
159
se->dx = - se->dx; // 255 which is also caught by these cases
169
defb @11111111, @00000000
170
defb @11111111, @00000000
171
defb @11111111, @00000000
172
defb @11111111, @00000000
173
defb @11111111, @00000000
174
defb @11111111, @00000000
175
defb @11111111, @00000000
177
; ASM source file created by SevenuP v1.20
178
; SevenuP (C) Copyright 2002-2006 by Jaime Tejedor Gomez, aka Metalbrain
181
;Pixel Size: ( 16, 24)
183
;Sort Priorities: Mask, Char line, Y char, X char
186
;Mask: Yes, before graphic
190
DEFB 128,127, 0,192, 0,191, 30,161
191
DEFB 30,161, 30,161, 30,161, 0,191
192
DEFB 0,191, 30,161, 30,161, 30,161
193
DEFB 30,161, 0,191, 0,192,128,127
194
DEFB 255, 0,255, 0,255, 0,255, 0
195
DEFB 255, 0,255, 0,255, 0,255, 0
197
DEFB 1,254, 0, 3, 0,253,120,133
198
DEFB 120,133,120,133,120,133, 0,253
199
DEFB 0,253,120,133,120,133,120,133
200
DEFB 120,133, 0,253, 0, 3, 1,254
201
DEFB 255, 0,255, 0,255, 0,255, 0
202
DEFB 255, 0,255, 0,255, 0,255, 0