-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsprites.html
241 lines (221 loc) · 17 KB
/
sprites.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>sprites.h</TITLE>
<STYLE TYPE="TEXT/CSS">
<!--
.IE3-DUMMY { CONT-SIZE: 100%; }
BODY { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; BACKGROUND-COLOR: #E0E0E0; }
P { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
H1 { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
H2 { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
H3 { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
H4 { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
H5 { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
H6 { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
UL { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
TD { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; BACKGROUND-COLOR: #FFFFFF; }
.NOBORDER { BACKGROUND-COLOR: #E0E0E0; PADDING: 0pt; }
.NOBORDER TD { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; BACKGROUND-COLOR: #E0E0E0; PADDING: 0pt; }
.CODE { FONT-FAMILY: Courier New; }
-->
</STYLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#E0E0E0">
<FONT SIZE="5"><B>The <sprites.h> Header File</B></FONT>
<HR>
<P><B>Simple sprite routines</B></P>
<H3><U>Functions</U></H3>
<DL INDENT="20"><DT><B><A HREF="#ClipSprite8">ClipSprite8</A></B><DD>Safely draws a sprite with a width of 8 pixels or less on the screen.<IMG WIDTH="1" HEIGHT="20" ALIGN="TOP"><DT><B><A HREF="#ClipSprite16">ClipSprite16</A></B><DD>Safely draws a sprite with a width of 16 pixels or less on the screen.<IMG WIDTH="1" HEIGHT="20" ALIGN="TOP"><DT><B><A HREF="#ClipSprite32">ClipSprite32</A></B><DD>Safely draws a sprite with a width of 32 pixels or less on the screen.<IMG WIDTH="1" HEIGHT="20" ALIGN="TOP"><DT><B><A HREF="#Sprite8">Sprite8</A></B><DD>Draws a sprite with a width of 8 pixels or less on the screen.<IMG WIDTH="1" HEIGHT="20" ALIGN="TOP"><DT><B><A HREF="#Sprite16">Sprite16</A></B><DD>Draws a sprite with a width of 16 pixels or less on the screen.<IMG WIDTH="1" HEIGHT="20" ALIGN="TOP"><DT><B><A HREF="#Sprite32">Sprite32</A></B><DD>Draws a sprite with a width of 32 pixels or less on the screen.</DL>
<H3><U>Predefined Types</U></H3>
<DL INDENT="20"><DT><B><A HREF="#SprtModes">SprtModes</A></B><DD>An enumeration to describe possible modes of sprite drawing.</DL>
<P>For lots of advanced drawing routines, we recommend you to download either the <A HREF="http://tict.ticalc.org/">ExtGraph static library</A> by the <A HREF="http://tict.ticalc.org/">TI-Chess Team</A> or <A HREF="http://www.yaronet.com/t3/?id=20">Genlib "kernel"-based dynamic library</A> by the <A HREF="http://www.yaronet.com/t3/">Time To Team</A>.</P>
<P>See also: <A HREF="graph.html">graph.h</A>, <A HREF="gray.html">gray.h</A></P>
<HR>
<H3><A NAME="ClipSprite8"><U>ClipSprite8</U></A></H3>
<P><TABLE BORDER="1" CELLPADDING="2"><TR><TD CLASS="CODE"><B><A HREF="keywords.html#void">void</A></B> ClipSprite8 (<B><A HREF="keywords.html#short">short</A></B> x, <B><A HREF="keywords.html#short">short</A></B> y, <B><A HREF="keywords.html#short">short</A></B> height, <B><A HREF="keywords.html#const">const</A></B> <B><A HREF="keywords.html#short">unsigned</A></B> <B><A HREF="keywords.html#int">char</A></B> *sprite, <B><A HREF="keywords.html#void">void</A></B> *vm_addr, <B><A HREF="keywords.html#short">short</A></B> mode);</TD></TR></TABLE></P>
<P><B>Safely draws a sprite with a width of 8 pixels or less on the screen.</B></P>
<P>ClipSprite8 works exactly like <A HREF="#Sprite8">Sprite8</A>, but it doesn't draw out of the boundaries of a 240x128 screen,
unlike Sprite8 if given <CODE>x < 0</CODE>, <CODE>y < 0</CODE>, <CODE>x > 232</CODE> or <CODE>y > 128 - height</CODE>.
<BR><BR>
See <A HREF="#Sprite8">Sprite8</A> for more info about sprites.</P>
<P>See also: <A HREF="#Sprite8">Sprite8</A></P>
<HR>
<H3><A NAME="ClipSprite16"><U>ClipSprite16</U></A></H3>
<P><TABLE BORDER="1" CELLPADDING="2"><TR><TD CLASS="CODE"><B><A HREF="keywords.html#void">void</A></B> ClipSprite16 (<B><A HREF="keywords.html#short">short</A></B> x, <B><A HREF="keywords.html#short">short</A></B> y, <B><A HREF="keywords.html#short">short</A></B> height, <B><A HREF="keywords.html#const">const</A></B> <B><A HREF="keywords.html#short">unsigned</A></B> <B><A HREF="keywords.html#short">short</A></B> *sprite, <B><A HREF="keywords.html#void">void</A></B> *vm_addr, <B><A HREF="keywords.html#short">short</A></B> mode);</TD></TR></TABLE></P>
<P><B>Safely draws a sprite with a width of 16 pixels or less on the screen.</B></P>
<P>ClipSprite16 works exactly like <A HREF="#Sprite16">Sprite16</A>, but it doesn't draw out of the boundaries of a 240x128 screen,
unlike Sprite16 if given <CODE>x < 0</CODE>, <CODE>y < 0</CODE>, <CODE>x > 224</CODE> or <CODE>y > 128 - height</CODE>.
<BR><BR>
See <A HREF="#Sprite8">Sprite8</A> for more info about sprites.</P>
<P>See also: <A HREF="#Sprite16">Sprite16</A></P>
<HR>
<H3><A NAME="ClipSprite32"><U>ClipSprite32</U></A></H3>
<P><TABLE BORDER="1" CELLPADDING="2"><TR><TD CLASS="CODE"><B><A HREF="keywords.html#void">void</A></B> ClipSprite32 (<B><A HREF="keywords.html#short">short</A></B> x, <B><A HREF="keywords.html#short">short</A></B> y, <B><A HREF="keywords.html#short">short</A></B> height, <B><A HREF="keywords.html#const">const</A></B> <B><A HREF="keywords.html#short">unsigned</A></B> <B><A HREF="keywords.html#short">long</A></B> *sprite, <B><A HREF="keywords.html#void">void</A></B> *vm_addr, <B><A HREF="keywords.html#short">short</A></B> mode);</TD></TR></TABLE></P>
<P><B>Safely draws a sprite with a width of 32 pixels or less on the screen.</B></P>
<P>ClipSprite32 works exactly like <A HREF="#Sprite32">Sprite32</A>, but it doesn't draw out of the boundaries of a 240x128 screen,
unlike Sprite32 if given <CODE>x < 0</CODE>, <CODE>y < 0</CODE>, <CODE>x > 208</CODE> or <CODE>y > 128 - height</CODE>.
<BR><BR>
See <A HREF="#Sprite8">Sprite8</A> for more info about sprites.</P>
<P>See also: <A HREF="#Sprite32">Sprite32</A></P>
<HR>
<H3><A NAME="Sprite8"><U>Sprite8</U></A></H3>
<P><TABLE BORDER="1" CELLPADDING="2"><TR><TD CLASS="CODE"><B><A HREF="keywords.html#void">void</A></B> Sprite8 (<B><A HREF="keywords.html#short">short</A></B> x, <B><A HREF="keywords.html#short">short</A></B> y, <B><A HREF="keywords.html#short">short</A></B> height, <B><A HREF="keywords.html#const">const</A></B> <B><A HREF="keywords.html#short">unsigned</A></B> <B><A HREF="keywords.html#int">char</A></B> *sprite, <B><A HREF="keywords.html#void">void</A></B> *vm_addr, <B><A HREF="keywords.html#short">short</A></B> mode);</TD></TR></TABLE></P>
<P><B>Draws a sprite with a width of 8 pixels or less on the screen.</B></P>
<P>Sprite8 draws a sprite with a width of 8 pixels or less on the screen. See <A HREF="#ClipSprite8">ClipSprite8</A>
for a version that handles out-of-screen sprites gracefully, and <A HREF="#Sprite16">Sprite16</A>, <A HREF="#ClipSprite16">ClipSprite16</A>,
<A HREF="#Sprite32">Sprite32</A> or <A HREF="#ClipSprite32">ClipSprite32</A> for wider sprites.
This routine is much faster than TIOS routines such as <A HREF="graph.html#DrawIcon">DrawIcon</A>,
<A HREF="graph.html#BitmapPut">BitmapPut</A>, etc.
<I>x</I> and <I>y</I> are the coordinates of the upper left corner of the sprite.
<I>height</I> is the height of the sprite. <I>sprite</I> is a pointer to the array of
unsigned characters which define the shape of the sprite (line by line). <I>vm_addr</I> is the pointer
to the video plane; it should be <A HREF="graph.html#LCD_MEM">LCD_MEM</A> if you are not using
grayscale or the <A HREF="graph.html#PortSet">PortSet</A> function. <I>mode</I> is the drawing
mode, and it may have one of the following values (these constants are defined in the enum
<A HREF="#SprtModes">SprtModes</A>):
<BR><BR>
<TABLE BORDER CELLPADDING="3">
<TR>
<TD VALIGN="TOP">SPRT_XOR</TD>
<TD>XOR the sprite into a background. This is used only for non-masked sprites.
XOR mode switches every pixel with a corresponding '1' bit in the <I>sprite</I> array from white to black and verse vica.</TD>
</TR>
<TR>
<TD VALIGN="TOP">SPRT_OR</TD>
<TD>OR the sprite into a background. This is mainly used for masked sprites together with SPRT_AND.
OR means that every pixel with a corresponding '1' bit in the <I>sprite</I> array will be set to black, but all other pixels stay the same.
If you want to turn all other pixels to white instead, use SPRT_RPLC.</TD>
</TR>
<TR>
<TD VALIGN="TOP">SPRT_AND</TD>
<TD>AND the sprite into a background. This is used for masked sprites together with SPRT_OR.
AND turns off every pixel with a corresponding '0' bit in the <I>sprite</I> array, but all other pixels remain untouched.
If you want to turn all other pixels to black instead, use SPRT_RPLC.</TD>
</TR>
<TR>
<TD VALIGN="TOP">SPRT_RPLC</TD>
<TD>RePLaCe the sprite into a background.
RPLC sets every pixel with a corresponding '1' bit to black and every pixel with a corresponding '0' bit to white.
This is equivalent to calling <CODE>Sprite8(x,y,h,sprite,plane,SPRT_AND); Sprite8(x,y,h,sprite,plane,SPRT_OR);</CODE>.</TD>
</TR>
</TABLE>
<BR>
In fact, you can use one of two techniques to draw sprites:</P>
<UL>
<LI><P><B>Non-masked sprites.</B> Using this method, the sprites are simply XORed into the background. This
technique was popular in many games on old 8-bit computers. To erase the sprite, it is
enough to call the routine again on the same position.</P></LI>
<LI><P><B>Masked sprites.</B> This is the more advanced method, which needs more programming practice,
but produces much better results. Using this method, you first need to erase a
part of the background which occupies a space where the sprite need to be displayed,
then to draw the actual sprite shape. To do this, AND the inverse of the sprite mask
to the background, then OR the sprite at the same location. However, it is not so
easy to restore the background later. For solving this problem, a lot of advanced
methods are developed (like "double-buffering", etc.). These methods are quite
common in advanced ASM games, and they are explained in many ASM tutorials.</P></LI>
</UL>
<P>Here is a simple example (called "Masked Sprite"), which first draws a simple "background", then draws a "masked"
sprite (which is a simple 8x8 square with solid edges and blank interior) at (30,30):</P>
<PRE>// Display a masked sprite over an arbitrary background
#define USE_TI89 // Compile for TI-89
#define USE_TI92PLUS // Compile for TI-92 Plus
#define USE_V200 // Compile for V200
#define OPTIMIZE_ROM_CALLS // Use ROM Call Optimization
#define MIN_AMS 100 // Compile for AMS 1.00 or higher
#define SAVE_SCREEN // Save/Restore LCD Contents
#include <tigcclib.h> // Include All Header Files
// Main Function
void _main(void)
{
static const unsigned char sprite[] = {0xFF,0x81,0x81,0x81,0x81,0x81,0x81,0xFF};
static const unsigned char imask[] = {(unsigned char)~0xFF,(unsigned char)~0xFF,
(unsigned char)~0xFF,(unsigned char)~0xFF,(unsigned char)~0xFF,
(unsigned char)~0xFF,(unsigned char)~0xFF,(unsigned char)~0xFF};
int i;
ClrScr ();
for (i = 0; i <= LCD_WIDTH; i++)
DrawLine (i, 0, i, LCD_HEIGHT, A_SHADE_NS); // A simple background
Sprite8 (30, 30, 8, imask, LCD_MEM, SPRT_AND);
Sprite8 (30, 30, 8, sprite, LCD_MEM, SPRT_OR);
ngetchx ();
}
</PRE>
<P>Here the sprite mask is <CODE>{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}</CODE>, but it needs to
be inverted before passing it to the Sprite8 function. For this purpose, the operator '~' may be
very useful. Note that '~' is "bitwise NOT". Of course, ~0xFF is the same as 0x00, but this notation
makes the program more clear (and it does not increase the code size, because the inverting will
be performed at compilation time). And if you want to use <A HREF="#Sprite16">Sprite16</A>,
<A HREF="#ClipSprite16">ClipSprite16</A>, <A HREF="#Sprite32">Sprite32</A> or
<A HREF="#ClipSprite32">ClipSprite32</A>, the notation ~0xFF will still be valid in a short int
array, or in a long int array if you add the <B>'L'</B> suffix (see the respective info about
<A HREF="#Sprite32">Sprite32</A> and <A HREF="#ClipSprite32">ClipSprite32</A>).
Without this notation, you must use 0x00 in Sprite8, but 0xFF00 in
<A HREF="#Sprite16">Sprite16</A>/<A HREF="#ClipSprite16">ClipSprite16</A>, and
0xFFFFFF00 in <A HREF="#Sprite32">Sprite32</A>/<A HREF="#ClipSprite32">ClipSprite32</A>.
This is why a notation like ~0xFF is more universal.
<BR><BR>
You can use binary numbers to define your sprites. On the one hand, it makes the program
incompatible with some other C dialects. On the other hand, it makes designing a sprite
much easier and also allows for editing the sprite at a later time without having to
reconvert it. The binary representation of the sprite presented above would look like this:</P>
<PRE>static const unsigned char sprite[]={
0b11111111,
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b11111111};
</PRE>
<P>See also: <A HREF="#ClipSprite8">ClipSprite8</A></P>
<HR>
<H3><A NAME="Sprite16"><U>Sprite16</U></A></H3>
<P><TABLE BORDER="1" CELLPADDING="2"><TR><TD CLASS="CODE"><B><A HREF="keywords.html#void">void</A></B> Sprite16 (<B><A HREF="keywords.html#short">short</A></B> x, <B><A HREF="keywords.html#short">short</A></B> y, <B><A HREF="keywords.html#short">short</A></B> height, <B><A HREF="keywords.html#const">const</A></B> <B><A HREF="keywords.html#short">unsigned</A></B> <B><A HREF="keywords.html#short">short</A></B> *sprite, <B><A HREF="keywords.html#void">void</A></B> *vm_addr, <B><A HREF="keywords.html#short">short</A></B> mode);</TD></TR></TABLE></P>
<P><B>Draws a sprite with a width of 16 pixels or less on the screen.</B></P>
<P>Sprite16 works exactly like <A HREF="#Sprite8">Sprite8</A>, but it takes sprites with a width of 16 pixels.
<I>sprite</I> is now a pointer to the array of unsigned short integers which defines the sprite.
So, to define a sprite (or sprite mask), use something like</P>
<PRE>static const unsigned short sprite[] = {...};
</PRE>
<P>See <A HREF="#Sprite8">Sprite8</A> for more info about sprites, and
<A HREF="#ClipSprite16">ClipSprite16</A> for a version that handles out-of-screen sprites gracefully.</P>
<P>See also: <A HREF="#ClipSprite16">ClipSprite16</A></P>
<HR>
<H3><A NAME="Sprite32"><U>Sprite32</U></A></H3>
<P><TABLE BORDER="1" CELLPADDING="2"><TR><TD CLASS="CODE"><B><A HREF="keywords.html#void">void</A></B> Sprite32 (<B><A HREF="keywords.html#short">short</A></B> x, <B><A HREF="keywords.html#short">short</A></B> y, <B><A HREF="keywords.html#short">short</A></B> height, <B><A HREF="keywords.html#const">const</A></B> <B><A HREF="keywords.html#short">unsigned</A></B> <B><A HREF="keywords.html#short">long</A></B> *sprite, <B><A HREF="keywords.html#void">void</A></B> *vm_addr, <B><A HREF="keywords.html#short">short</A></B> mode);</TD></TR></TABLE></P>
<P><B>Draws a sprite with a width of 32 pixels or less on the screen.</B></P>
<P>Sprite32 works exactly like <A HREF="#Sprite8">Sprite8</A>, but it takes sprites with a width of 32 pixels.
<I>sprite</I> is now a pointer to the array of unsigned long integers which defines the sprite.
So, to define a sprite (or sprite mask), use something like</P>
<PRE>static const unsigned long sprite[] = {...};
</PRE>
<P><B>Note:</B> If you define a sprite mask and invert it with the '~' operator, you need to take
care of the possibility of the first two bytes being zero in one constant. In this case, the constant will
be assumed to be a 16 bit value, so only 16 bits will be inverted. Then the constant is promoted to an
unsigned long integer, and the first 16 bits are still zero as if they actually belonged to the mask.
To take care of this problem, add the <B>'L'</B> (long) suffix to the end of the value.
<BR><BR>
If you want to use sprites wider than 32 pixels (which is not very likely), one solution is to
use a "kernel"-based program and <CODE>graphlib::put_sprite</CODE> (see <A HREF="faq.html">Frequently Asked Questions</A>
for more info about how to do it). If you don't want to use kernel-based programs, the proposed method depends
on what the use of the sprite will be:</P>
<UL>
<LI><P>If you don't need too fast action, the built-in TIOS function <A HREF="graph.html#BitmapPut">BitmapPut</A> may be good enough.</P></LI>
<LI><P>If you need a very fast sprite routine for very large sprites, then you must write it yourself, or use prewritten ones in
ExtGraph or Genlib.</P></LI>
</UL>
<P>
See <A HREF="#Sprite8">Sprite8</A> for more info about sprites, and
<A HREF="#ClipSprite32">ClipSprite32</A> for a version that handles out-of-screen sprites gracefully.</P>
<P>See also: <A HREF="#ClipSprite32">ClipSprite32</A></P>
<HR>
<H3><A NAME="SprtModes"><U>SprtModes</U></A></H3>
<P><TABLE BORDER="1" CELLPADDING="2"><TR><TD CLASS="CODE"><B><A HREF="keywords.html#enum">enum</A></B> SprtModes {SPRT_XOR, SPRT_OR, SPRT_AND, SPRT_RPLC};</TD></TR></TABLE></P>
<P><B>An enumeration to describe possible modes of sprite drawing.</B></P>
<P>This type is used by all sprite functions.</P>
<HR>
<H3><A HREF="index.html">Return to the main index</A></H3>
</BODY>
</HTML>