.
Extract from 'Sprmaker.doc' :
The sprite format is kind of simple. The way it's done is to make putting
the sprite fast and easy. Since greyscale graphics are stored in two
layers, each row (0-15) in the sprite will have two (0-1) bitplanes of
16 (0-15) bits, each bit one pixel. If you have a black pixel, both
planes at that location will be set. A darkgray pixel is stored with
a set bit on bitplane 0 and a cleared bit on bitplane 0, a lightgray pixel
has a cleared bit on bitplane 0 and a set bit on bitplane 1, and a white
pixel has both pixels cleared on both bitplanes.
Here's an example of the three first rows in a sprite, an ugly one. The
colors are 3=black, 2=dark gray, 1=light gray, 0=white:
Row 0: 3231203231200231
Row 1: 1202211033021220
Row 2: 0113220102332123
Those rows are first translated into two bitplanes:
Row 0: 1110101110100110 1011001011000011
Row 1: 0101100011010110 1000011011001000
Row 2: 0001110001111011 0111000100110101
Then the bitplanes are translated into a word in ordinary binary -> word
way:
Row 0: 60326 45763
Row 1: 22742 34504
Row 2: 7291 28981
These words are stored in the file (60326, 45763, 22742, ...). The words
are stored in the bigindian way, ie the most significant byte is stored
first. Thus, the first 12 bytes in the file will be (in hex):
EB A6 B2 C3 58 D6 86 C8 1C 7B 71 35
To use this in your own Fargo program, this routine will put a sprite
at D0,D1 (x,y). The label sprites should be put before the INCBIN
row (see below) and D2 is the sprite number of the sprite (the first sprite=0,
second=1 and so on). The address to the grayscale plane is stored in a
longword, greyplane.
S08: "Sprites 8x8" (Or tiles 8x8)
typedef char TILE_8[8][2];
- Description:
It is the same format, execpt with 8 rows of two bitplanes of one byte only.
Plane
typedef struct
{
HANDLE handle; // Handle of the plane (Useless, ok).
unsigned short size; // Size of a line in the matrix
unsigned char *table; // Matrix of tiles
void *tile; // Tiles (either 16x16 or 8x8)
unsigned char *ind_tab; // Internally used
unsigned short xs_old; // Internally used
unsigned short ys_old; // Internally used
unsigned short xs; // X position of the plane
unsigned short ys; // Y position of the plane
unsigned char VScreen[VSCREEN_SIZE]; // VScreen
} PLANE;
ASM:
PLANE_HDL ; Handle of the plane
PLANE_SIZE ; Size of a line in the matrix.
PLANE_TABLE_ADR ; Addr of the matrix
PLANE_TILE_ADR ; Addr of the tiles
PLANE_IND_T_ADR ; Internally used
PLANE_XS_OLD ; Internally used
PLANE_YS_OLD ; Internally used
PLANE_XS ; Position X of the plane
PLANE_YS ; Position Y of the plane
PLANE_V_SCREEN ; VScreen
Description:
A plane is the assoctiation between an array of tiles and a matrix of index.
The array of tiles could be an array of SPRITE16 or SPRITE8.
The matrix of index could be a matrix of bytes: each byte is the number of a tile in the array of tiles.
Either, it could be a word. If so, the 10 highest bits are the index in the tile array, the bit 1 if the Horizontal flipping bit, the bit 2 is the Vertical flipping bit, the bits 5-4-3 are the bits of the palette to use (Default 0) and finally the bit 0 isn't used.
typedef struct
{
unsigned int tile : 10;
unsigned int pal : 3;
unsigned int flipv : 1;
unsigned int fliph : 1;
unsigned int nothing : 1;
} WORD_INDEX;
Examples:
Look at the example for the plane functions.
Point
typedef struct
{
short x;
short y;
} POINT;
ASM:
xe equ 0 ; x coordinate (16-bits Integer)
ye equ 2 ; y coordinate (16-bits Integer)
Description:
It is a point. I have nothing more to say.
Examples:
POINT P = {125, 100};
DHZ: DHZ Table
typedef char DHZ_TAB[SCREEN_Y];
ASM:
Dhz ds.b SCREEN_Y
Description:
It is an array of 128 bytes (SCREEN_Y = 128 ).
Each byte is the individual shifting of one line when the plane is put on the DScreen.
It is only used with put_plane_dhz functions. The valid range is from -8 to 8.
Examples:
Look at the put_plane examples.
DHZ_TAB dhz = {
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
}
HDZ: HDZ Table
typedef short HDZ_TAB[SCREEN_Y];
ASM:
Ddz ds.w SCREEN_Y
Description:
It is an array of SCREEN_Y words (= 256 bytes).
Each word is the value the function add to the adress registers which points
the VScreen after one line in put_plane functions.
If you add the size of the line of the VSscreen, you can change the VScreen pointer so that it derefs what you want,
the line you want. It is very usefull for zoom (You draw the same line many times, just including times to times, a -VIRTUAL_X in
the array. It must be 2x aligned, either you will get an address error.
Examples:
Look at the put_plane examples.
HDZ_TAB dhz = {
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,+VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,+VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,+VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,+VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,+VIRTUAL_X,0,0,0,
}
Sprite_Plane
- C:
The variables cannot be used. Use the extra-c functions instead.
- ASM:
genlib::sprite_tile_table = adress of the 16x16 tiles.
genlib::sprite_scr_x = x of the sprite_plane.
genlib::sprite_scr_y = y of the sprite_plane.
Description:
It isn't a real plane. It is a virtual plane. You just have 3 variables.
The address of the array of tiles (SPRITE_16). And the 2 coordinates x
and y of this virtual plane. When you call a sprite function, it first removes
this coordinates from the values you have passed to this function.
Examples:
In assembly language :
lea Tiles(Pc),a0
move.l a0,genlib::sprite_tile_table
move.w #10,genlib::sprite_scr_x
move.w #20,genlib::sprite_scr_y
...
Tiles: incbin "tiles.bin"
In C :
gl_set_spr_xy(10, 20);
gl_set_spr_tile(Tiles);
Joypad
typedef struct
{
unsigned int kh_key : 1;
unsigned int kg_key : 1;
unsigned int kf_key : 1;
unsigned int ke_key : 1;
unsigned int kd_key : 1;
unsigned int kc_key : 1;
unsigned int kb_key : 1;
unsigned int ka_key : 1;
unsigned int down_key : 1;
unsigned int right_key : 1;
unsigned int up_key : 1;
unsigned int left_key : 1;
unsigned int minus_key : 1;
unsigned int plus_key : 1;
unsigned int mode_key : 1;
unsigned int exit_key : 1;
} JOYPAD;
ASM:
Joypad structure : TI92 | TI89
exit_key ESC | ESC
mode_key APPS | APPS
plus_key + | +
minus_key - | -
left_key
up_key
right_key
down_key
ka_key F1 | 2nd
kb_key F2 | Diamond
kc_key F3 | Home
kd_key F4 | X
ke_key F5 | Shift
kf_key F6 | Alpha
kg_key F7 | Mode
kh_key F8 | Y
Description:
It is a virtual joypad. It is used to avoid the problems of different key mapping on
Ti-89 and Ti-92. On the both calcs, the values will be equal.
To test if Left is pressed, you will just tested the value of left_key.
Examples:
In assembly language :
jsr genlib::read_joypad
move.l d0,joypad
btst.l #left_key,d0
bne.s \no_left
...
\no_left
In C :
JOYPAD j;
//...
j = gl_read_joypad();
if (j.left_key == 0)
{
// Move to left
//...
}
Link data
typedef struct
{
unsigned short link_flag;
unsigned char *buffer_recpt;
unsigned char *buffer_send;
unsigned short buffer_recpt_size;
unsigned short buffer_send_size;
unsigned char buffer_recpt_flag;
unsigned char buffer_send_flag;
unsigned short buffer_recpt_offset;
unsigned short buffer_send_offset;
} LINK_DATA;
ASM:
link_flag : = MASTER or SLAVE
buffer_recpt_adr : Adress of the receiev buffer
buffer_send_adr : Adress of the send buffer
buffer_recpt_size : Size of r-buffer
buffer_send_size : Size of s-buffer
buffer_recpt_flag : = IN_PROGRESS or DONE (r-buffer)
buffer_send_flag : = IN_PROGRESS or DONE (s-buffer)
buffer_recpt_offset : don't use it.
buffer_send_offset : don't use it.
Description:
It is the structure to control the genlib link auto-int.
You should never write to it. If you want to update structure that the calcs
exchange, you should call set_link.
Examples:
In assembly language :
jsr genlib::synchronize
tst.w d0
beq link_error
move.l genlib::link_data,a4
cmp.w #MASTER,link_flag(a4)
beq.s \master
lea Slave(Pc),a0
bsr Print
bra.s \done
\master:
lea Master(Pc),a0
bsr Print
\done:
...
Slave: dc.b "I am the slave !",0
Master: dc.b "I am the master!",0
In C :
if (gl_synchronize())
printf("There is a problem of connection...\n" ;
else if (gl_link_data.link_flag == MASTER)
printf("I am the master of the universe !\n");
else printf("I am the slave !!!\n");
Keyboard
- C:
typedef char KEYBOARD[10];
- ASM:
A buffer of 10 bytes.
- Description:
It is the matrix of the keys of the calcs.
You should know what calculator is before testing the matrix.
Here are the key matrix of the Ti-92
Row +-------+-------+-------+-------+-------+-------+-------+-------+
V Col>| Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Bit 0 | down | right | up | left | hand | shift |diamond| 2nd |
| Bit 1 | 3 | 2 | 1 | F8 | W | S | Z | unused|
| Bit 2 | 6 | 5 | 4 | F3 | E | D | X | unused|
| Bit 3 | 9 | 8 | 7 | F7 | R | F | C | STO |
| Bit 4 | , | ) | ( | F2 | T | G | V | space |
| Bit 5 | TAN | COS | SIN | F6 | Y | H | B | / |
| Bit 6 | P | ENTER2| LN | F1 | U | J | N | ^ |
| Bit 7 | * | APPS | CLEAR | F5 | I | K | M | = |
| Bit 8 | unused| ESC | MODE | + | O | L | theta |backspc|
| Bit 9 | (-) | . | 0 | F4 | Q | A | ENTER1| - |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+
and of the Ti-89
Row +-------+-------+-------+-------+-------+-------+-------+-------+
V Col>| Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Bit 0 | Alpha | Diam. | Shift | 2nd | Right | Down | Left | Up |
| Bit 1 | F5 | Clear | ^ | / | * | - | + | Enter |
| Bit 2 | F4 |Backspc| T | , | 9 | 6 | 3 | (-) |
| Bit 3 | F3 |Catalog| Z | ) | 8 | 5 | 2 | . |
| Bit 4 | F2 | Mode | ( | ( | 7 | 4 | 1 | 0 |
| Bit 5 | F1 | Home | X | = | | | EE | STO | Apps |
| Bit 6 | | | | | | | | Esc |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+
To test a key, you should do like this in asm:
btst.b #col,row(a0)
bne.s \no_pressed
In C, like this
if (Tab[row] & ~col == 0)
...
Examples:
In assembly language :
jsr genlib::read_key_matrix
btst.l #5,4(a0) // F4 on Ti-92, '(' on Ti-89
bne.s \no_pressed
...
\no_pressed:
In C :
KEYBOARD *Tab;
Tab = gl_read_key_matrix();
if (Tab[4] & ~5 == 0)
...
Big sprites
typedef struct
{
char Height; // In pixel
char Weight; // In pixel /16 (in word)
short Data[1]; // Should be []
} BGS;
ASM:
?+0.b : Height (1..128)
?+1.b : Weight (1..15)
?+2.w : Interleaved data. (Each word is interleaved)
Description:
It is the description of a Bgs sprite. It could be a sprite of 240x128 max.
It is a grayscale sprite, and the mask is calculated at the real-time,
so you don't need it. It is enlarged to add a white line all around the sprite.
The White color is transparent.
The format is like this :
dc.b ROW_NUMBER, WORD_COL_NUMBER
dc.w DATA1_GRAPH_SCREEN_1, DATA1_GRAPH_SCREEN_2 ; 16 pixels in gray
dc.w DATA2_GRAPH_SCREEN_1, DATA2_GRAPH_SCREEN_2 ; 16 pixels in gray
dc.w DATA3_GRAPH_SCREEN_1, DATA3_GRAPH_SCREEN_2 ; 16 pixels in gray
dc.w ...
Examples:
In assembly language :
To print a ship of 32 x 8 pixels
spr_0_0:
dc.b 8,2
dc.w %0000000000000001,%0000000000000001,%1000000000000000,%1000000000000000
dc.w %0000000000000011,%0000000000000010,%1100000000000000,%0100000000000000
dc.w %0000000000001110,%0000000000001001,%0111000000000000,%1001000000000000
dc.w %0000000001111100,%0000000001000011,%0011111000000000,%1100001000000000
dc.w %0000111111011100,%0000100000000011,%0011101111110000,%1100000000010000
dc.w %0000011111111110,%0000011111111111,%0111111111100000,%1111111111100000
dc.w %0000000000000011,%0000000000000010,%1100000000000000,%0100000000000000
dc.w %0000000000001110,%0000000000001001,%0111000000000000,%1001000000000000
lea spr_0_0(Pc),a0
moveq #100,d0 ; x
moveq #-2,d1 ; y
jsr genlib::put_big_sprite
In C :
gl_put_big_sprite(100, -2, spr_0_0);
Palette
Description:
It is the Genlib palette. It allows you to filter your sprite16 before you print it. The palette is (B: Black, D: Dark gray, L: Light Gray, W: White gray) :
- Pal 0: B D L W
- Pal 1: B L L W
- Pal 2: B D W W
- Pal 3: B W W W
- Pal 4: B B B B
- Pal 5: B B D D
- Pal 6: B D D L
- Pal 7: B D L L
Examples:
See gl_update_vscreen_max16 and gl_pal_sprite_16.
There are internal variables of genlib you could access and modify. When you could read the variable, it is set with R. When you could write it, it is set with W.
unsigned long gl_timer;
genlib::timer
TYPE:
An unsigned long integer.
ACCESS:
DESCRIPTION:
It is the internal timer of genlib. It is incremented each time the Genlib interruption (Auto-int 5) has finished to display one screen. This timer is around 90 Hz and it is independant of the hardware of the calculators (or overclocked calc).
It is usefull to synchronize your code so that you have a constant frame rate in your program. It is usefull for benching a grayscale-graph routine. Why only grayscale-graph routines ? Because the interruption used the CPU to exchanged the screens, to emulating a gray screen. But on Hardware v2.00, it is quite consumming...
EXAMPLES:
To do a 30 Hz waiting, you could do :
In assembly language :
\Lili
cmp.l #2,genlib::timer
bls.s \Lili
clr.l genlib::timer
In C :
while (gl_timer <= 2);
gl_timer = 0;
unsigned short gl_frame_timer;
genlib::frame_timer
TYPE:
An unsigned short integer.
ACCESS:
DESCRIPTION:
It is the 2nd internal timer of genlib. It is incremented each time the Genlib interruption (Auto-int 5) has finished to display one DScreen. This timer is around 30 Hz and it is independant of the hardware of the calculators (or overclocked calc).
It is usefull to synchronize your code so that you have a constant frame rate in your program.
EXAMPLES:
To do a 30 Hz waiting, you could do :
In assembly language :
\Lili
tst.w genlib::frame_timer
beq.s \Lili
clr.w genlib::frame_timer
In C :
while (!gl_frame_timer);
gl_frame_timer = 0;
SCREEN *gl_window;
genlib::window
TYPE:
ACCESS:
DESCRIPTION:
It is the adress of the genlib window. What it is the window ? It is a screen that you could use for what you want. For Hard 1.00 calcs or the Ti-92 I/II, it is in fact the LCD_MEM. But on HW2, the LCD_MEM is used for swapping the screens. So it allocates a handle to replace the LCD_MEM. If gl_init could not allocate a SCREEN on Hardware 2, genlib::window will be equal to LCD_MEM. There will be a lots of bugs, but since you cannot allocate anything, I think your program will stop (Not enought memory to work). It is the only difference between the 2 calcs, and it explains some differences between the 2 calcs when you swap from gray4 mode to gray2 mode. It may change. It is usefull to print extra-informations like score, lifes, coins, and them copy quickly to the DScreen without spending a lot of time using DrawStrXY...
EXAMPLES:
genlib::sprite_tile_adr
genlib::sprite_scr_x
genlib::sprite_scr_y
TYPE:
A ptr to a SPRITE16 array.
A word.
A word.
ACCESS:
DESCRIPTION:
It is the address of the SPRITE16 array used but PUT_SPRITE16 functions.
It is the base address.
sprite_scr_x and sprite_scr_y are the coordinates X,Y of the sprite-plane. It is used by all sprite functions exept fast-sprite.
You cannot access theses variables in C, so you should instead the functions :
void gl_set_spr_xy(short x, short y);
void gl_set_spr_tile(SPRITE_16 *adr);
EXAMPLES:
See Put_sprite16 examples.
LINK_DATA gl_link_data;
genlib::link_data
TYPE:
It is the only Link_data structure.
ACCESS:
DESCRIPTION:
It is the internal link_data structure of genlib. There is only one available. You couldnot create another one. But under kernels like Prosit which provides multi-tasking, each genlib program will have a different link_data structures (Not available).
EXAMPLES:
char gl_internal_timer;
genlib::internal_timer
TYPE:
ACCESS:
DESCRIPTION:
It is the internal timer of genlib. You should never use it.
EXAMPLES:
unsigned short gl_hardware;
genlib::hardware
TYPE:
ACCESS:
DESCRIPTION:
It is the number of the current hardware. The different values are 0 for TI-92I/II, 1 for Hardware 1.00 and 2 for Hard 2.0. There could be another values with new hardwares.
EXAMPLES:
move.w genlib::hardware,d0
beq.s \Fargo
cmp.w #1,d0
beq.s \hard1
; Hard 2
...
C:
switch (gl_hardware)
{
case 0: gl_put_large_string(gl_window,0,0,"Ti-92 I/II\n");
break;
case 1: gl_put_large_string(gl_window,0,0,"Hardware 1.00\n");
break;
case 2: gl_put_large_string(gl_window,0,0,"Hardware 2.00\n");
break;
default: gl_put_large_string(gl_window,0,0,"Hardware not recognized\n");
}
gl_copy_window();
char gl_flipping_tab[256];
genlib::flipping_tab
TYPE:
ACCESS:
DESCRIPTION:
It is the internal flipping tab of genlib. It will reverse the order of the bits of the byte. It is also called 'Horizontal Mirror'.
EXAMPLES:
gl_flipping_tab[%01110001] = %10001110
(signed char) gl_sin[256];
(signed char) gl_cos[256];
genlib::sin
genlib::cos
TYPE:
It is an array of 256 signed chars.
ACCESS:
DESCRIPTION:
Theses tables are precalculated sinus / cosinus tables.
gl_sin[i] = 128 * sin(2*PI*i/256)
gl_cos[i] = 128 * cos(2*PI*i/256)
It means that a complete lap is an angle of 256. It is quite different from degrees (360°) or radian (2*PI). But in computer science, it is the best choice.
EXAMPLES:
If you want to calculate B = A * sin(i)
C: B = (A * gl_sin[i]) >> 7
Asm:
move.w A,d0 ; Read A
move.w i,d1 ; Read i
lea genlib::sin,a0 ; Read sinus table
move.b 0(a0,d1.w),d1 ; d1.b = 128 * sinus(i)
ext.w d1 ; d1.w = 128 * sinus(i)
muls.w d1,d0 ; d0.l = 128 * sinus(i) * A
asr.l #7,d0 ; d0.l = sinus(i) * A
move.w d0,B ; If there are no overflow
char gl_version[];
genlib::version
TYPE:
ACCESS:
DESCRIPTION:
It is the version string of Genlib. It looks like :
"GenLib v" + VERSION +"."+ SUB_VERSION
such as "Genlib v0.99.20b"
EXAMPLES:
PortSet(gl_window, 239, 127);
clrscr();
printf("Start program (%s)", gl_version);
gl_copy_window();
gl_wait_a_key();
Here are the specifications of the functions. Under Ti-gcc, you don't care about the registers destroyed by the functions. It will be always d0-d2/a0-a1.
There are two main functions : init and quit. It inits Genlib and quits genlib. Simple, no ?
void gl_init(void);
genlib::init
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It inits the auto-ints of the genlib library (4, 5 & 6) and the internal variables of genlib. It sets the processor timer and synchronize with the vertical signal.
You must call this function before any other genlib's functions.
It sets the priority level to 3 in order to disable auto-int 1, 2 & 3.
You can, of course, change the priority level if you want, but keep in mind that the standard auto-int 1 interfere with genlib key-scanning routines.
EXAMPLES:
See the standard example of Genlib
SEE ALSO:
void gl_quit(void);
genlib::quit
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It quits the genlib library and restore all the interruptions, ports, ... It won't call the function gl_free_hd. So you should call it before.
EXAMPLES:
See the standard example of Genlib
SEE ALSO:
Theses functions are VERY usefull when you alloc memory with HeapAlloc
and you don't want to save the handles by yourself.
void gl_push_hd(HANDLE hd);
genlib::push_hd
INPUT:
Hd = d0.w = Handle to push.
OUTPUT:
Nohing under TiGcc
d1.b = 0 if no error else there is a stack overflow.
DESTROYED REGISTERS:DESCRIPTION:
Push the handle on the genlib handle stack. The current maximun is 20 Handles. If you think it is to few, call me. If you are sure that you can't have an overflow, you can no test the flag. Under Tigcc, you can't test it, but it isn't very important since, in general, you will never test it.
EXAMPLES:
See the standard example of Genlib. It allocates two DScreen and pushes their handles on the HANDLE stack.
SEE ALSO:
HANDLE gl_pop_hd(void);
genlib::pop_hd
INPUT:OUTPUT:
d0.w = The handle
d1.b = 0 if no error else there is a void stack .
DESTROYED REGISTERS:DESCRIPTION:
Pop the current handle on the genlib handle stack. The current maximun is 20 Handles. If you think it is to few, call me. You could have an error if there is no HANDLE on the HANDLE stack.
EXAMPLES:
void toto(){
HANDLE h;
DSCREEN *d;
gl_init_dscreen(&d, &h);
gl_push_hd(h);
// ... Do som stuff
gl_pop_hd(h);
HeapFree(h);}
SEE ALSO:
void gl_free_hd(void);
genlib::free_hd
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
Free all handles which are pushed on the stack in reverse order (FILO or LIFO, First In Last Out or Last In First Out). In general, it is just before you call gl_quit.
EXAMPLES:
You could have a look on the standard example.
void toto(){
HANDLE h;
DSCREEN *d1, *d2;
PLANE *p;
gl_init_dscreen(&d1, &h); // A new DScreen
gl_push_hd(h); // Push the handle on the Genlib HANDLE stack
gl_init_dscreen(&d2, &h); // A new DScreen
gl_push_hd(h); // ...
p = gl_init_plane(map, tile, 32); // map and tile are defined elsewhere.
gl_push_hd(p->handle);
// ... Do some stuff
gl_free_hd(h);} // Free the handles of DScreen d1, d2 and the plane p
SEE ALSO:
When you call gl_init, it won't alloc any DScreen to do grayscale. You should alloc by yourself a Dscreen, on the heap or on the stack.
void gl_init_screen(SCREEN **Scr, HANDLE *Hd);
genlib::init_screen
INPUT:OUTPUT:
Scr: A ptr to the ptr of the allocated Screen.
Hd: A ptr to the Handle of the allocated Screen (or H_NULL).
d0.w = Handle of the allocated Screen (or H_NULL).
a0.l = Address of the screen (aligned with a 8x address)
DESTROYED REGISTERS:DESCRIPTION:
Init and allocate a new Screen on the heap. It is a buffer of (1 * $F00 + 8) bytes, and it is 8x aligned (Its address is divisible by 8).
EXAMPLES:
Look at the example of gl_init_dscreen.
SEE ALSO:
void gl_init_dscreen(DSCREEN **DScr, HANDLE *Hd);
genlib::init_dscreen
INPUT:OUTPUT:
DScr: A ptr to the ptr of the allocated DScreen.
Hd: A ptr to the Handle of the allocated DScreen (or H_NULL).
d0.w = Handle of the allocated DScreen (or H_NULL).
a0.l = Address of the Dscreen (aligned with a 8x address)
DESTROYED REGISTERS:DESCRIPTION:
Init and allocate a new DScreen on the heap. It is a buffer of (2 * $F00 + 8) bytes, and it is 8x aligned (Its address is divisible by 8).
EXAMPLES:
Look at the standard example. It alloates 2 dscreens to do double-buffering.
SEE ALSO:
void gl_set_dscreen_int(DSCREEN *DScr);
genlib::set_dscreen_int
INPUT:
Dscr = d0.l = Address of the DScreen to print.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
Set the DScreen for the auto-int. It is an interruption that will display the DScreen. and you should call this function at least one so that you can see something.
EXAMPLES:
Look at the standard example.
SEE ALSO:
void gl_set_dscreen_function(DSCREEN *Scr);
genlib::set_dscreen_function
INPUT:
Dscr = d0.l = Address of the working DScreen.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
Set the DScreen for the genlib functions.
You must call this function before calling any Graph-functions.
If you forget to init it at least one time, YOU WILL HAVE A CRASH WHEN
YOU CALL ANY GRAPHS FUNCTIONS OF GENLIB since they will write in an area
they shouldn't.
The alternative is that you have to pass the DScreen as an argument only once. You don't have to pass the current DScreen for most of the graph functions.
EXAMPLES:
Look at the standard example.
SEE ALSO:
DSCREEN *gl_get_dscreen(void);
genlib::get_dscreen
INPUT:OUTPUT:
a0 = Th current working DScreen
DESTROYED REGISTERS:DESCRIPTION:
Get the current working dscreen. It is the last value passed to set_dscreen_function.
EXAMPLES:SEE ALSO:
void gl_set_screen_int(SCREEN *Scr1, SCREEN *Scr2, SCREEN *Scr3);
genlib::set_screen_int
INPUT:
Scr1 = d0.l = Adress of the first screen (The dark One)
Scr2 = d1.l = Adress of the second screen (The invisible one)
Scr3 = d2.l = Adress of the third screen (The light one)
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
With this function, you can set what are the third screens of the greyscale interruption. To be compatible with the standard grayscale, you should have Scr1 = Scr2. On Hardware 2.00, the 2nd screen won't be displayed. The 2nd screen works only on Hardware 1 !
This function works like gl_set_dscreen_int, and it sets only what the interruption have to display. The Genlib functions still need a DScreen ! LCD_MEM isn't a valid screen since it is used by the grey driver on HW2. gl_window is a valid screen.
EXAMPLES:
A way to implement gl_set_dscreen_int is :
void gl_set_dscreen_int(DSCREEN *dscr)
{gl_set_screen_int(DARK_SCREEN(dscr), DARK_SCREEN(dscr), LIGHT_SCREEN(dscr));}
gl_set_dscreen_int:
movem.l d0-d2,-(a7)
move.l d0,d1
move.l d0,d2
add.l #SCREEN_SIZE,d2
jsr genlib::set_screen_int
movem.l (a7)+,d0-d2
rts
SEE ALSO:
void gl_copy_window(void);
genlib::copy_window
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It copies the genlib window to the current working DScreen. The window wil be copied in the 2 screens of the Dscreen so that it will be dark. You can use after updating informations (Score, life, items, ...) on the window with tios::DrawStrXY or gl_put_large_string.
You must call 'set_dscreen_function' before calling this function !
It may be more powerfull, if you have only a few data, to copy them by yourself. Even this function is fast, it will be faster to copy only what you need !
EXAMPLES:
This program will display a triangle and moves it.
It will copy each frame the window to display the information.
POINT P1 = {10, 20}, P2 = {100,0}, P3 = {200,100};
int i;
gl_clear_window();
gl_put_small_string(gl_window, 10, 15, "SCORE: 1000120 pts");
gl_put_large_string(gl_window, 20, 0, "FORTINE INVADERS");
gl_put_medium_string(gl_window, 10, 90, "Life: 3");
for( i = 0 ; i < 100 ; i++)
{
gl_cls();
P1.x++;
P1.y++;
P2.x--;
P2.y++;
P3.x-=2;
P3.y--;
gl_draw_c_face(&P1, &P2, &P3, 2);
gl_copy_window();
SwapBuffer();
Wait30();
}
SEE ALSO:
gl_window, gl_clear_window, gl_set_dscreen_function
void gl_cls(void);
genlib::cls
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
Clear the current working DScreen - Quite fast-.
EXAMPLES:
Look at the example of gl_copy_window.
SEE ALSO:
gl_clear_window, gl_set_dscreen_function
void gl_clear_window(void);
genlib::clear_window
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
Clear the window - Quite fast-.
EXAMPLES:
Look at the example of gl_copy_window.
SEE ALSO:
void gl_fill_screen(SCREEN *scr, long pattern);
genlib::fill_screen
INPUT:
scr = a0 = The screen to fill with the pattern.
pattern = d0.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
Fill the screen with the pattern.
The pattern could be '0' (White) or '-1' (Black) or something more complex.
EXAMPLES:
gl_fill_screen(DARK_SCREEN(gl_get_dscreen()), 0xBBBBBBBB);
gl_fill_screen(LIGHT_SCREEN(gl_get_dscreen()), 0x55555555);
SEE ALSO:
void gl_set_LCD_MEM(void);
genlib::set_LCD_MEM
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It sets the interrruptions so that it displays the LCD_MEM (Gray 2).
The functions still work with the current working DScreen !
Note: It is the real screen LCD_MEM, not the window screen.
So you can have some difference between HW1 and HW2. The screen could not be cleared on HW2.
EXAMPLES:
gl_set_LCD_MEM();
ScreenClear();
DrawStrXY(20,30,"Hello world !", 4);
SEE ALSO:
The tigcclib graph functions !
genlib::PUSH_DSCREEN ds
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It allocs a DScreen on the stack.
You must use it as a PUSH instruction !
EXAMPLES:
See the standard example.
SEE ALSO:
genlib::POP_DSCREEN
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It pops the DScreen from the stack.
You must use it as a POP instruction !
WARNING : YOU CAN'T ALLOCATE MORE THAN ONE DSCREEN ON THE STACK !
EXAMPLES:
See the standard example.
SEE ALSO:
genlib::PUSH_SCREEN ds
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It allocs a Screen on the stack.
You must use it as a PUSH instruction !
WARNING : YOU CAN'T ALLOCATE MORE THAN TWO SCREENS ON THE STACK !
EXAMPLES:
See the PUSH_DSCREEN example.
SEE ALSO:
genlib::POP_SCREEN
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It pops the Screen from the stack.
You must use it as a POP instruction !
EXAMPLES:
See the POP_DSCREEN example.
SEE ALSO:
Theses functions are very faster than the ROM function DrawStrXY (and when I say very, ...). But of course, you can't select all the options of such a function (The mode format).
void gl_put_small_string(SCREEN *Scr, short x, short y, char *Str);
genlib::put_small_string
INPUT:
Str = A0 = String to print
Scr = A1 = Address of the screen (LCD_MEM or window, or ??)
x = D0.w = X coordinate (0...239)
y = D1.W = Y coordinate (0...127)
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws all the characters of the string at the specified coordinates with the small font (Of the boot code, so it doesn't work on Vti with 9xu or Tib roms, but only with real dump). No clipping is done !
It isn't perfect, since the ti-os small font is quite strange. I know that the first byte of each character of the small font is the weight of the character, but I didn't realize a routine which works perfectly.
It prints the string without erasing the background.
EXAMPLES:
gl_put_small_string(gl_window, 20, 50, "Genlib is Good !");
move.l genlib::window,a1
lea \String(Pc),a0
moveq #20,d0
moveq #50,d1
jsr genlib::put_small_string
bra.s \done
\String dc.b "Genlib is too good !",0
even
\done:
SEE ALSO:
gl_put_large_string, gl_put_medium_string.
void gl_put_medium_string(SCREEN *Scr, short x, short y, char *Str);
genlib::put_medium_string
INPUT:
Str = A0 = String to print
Scr = A1 = Address of the screen (LCD_MEM or window, or ??)
x = D0.w = X coordinate (0...239)
y = D1.W = Y coordinate (0...127)
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws all the characters of the string at the specified coordinates with the medium font (Of the boot code, so it doesn't work on Vti with 9xu or Tib roms, but only with real dump). No clipping is done !
It prints the string without erasing the background.
EXAMPLES:
gl_put_medium_string(gl_window, 20, 50, "MMMMMmmmmrrrrrroups ?");
move.l genlib::window,a1
lea \String(Pc),a0
moveq #20,d0
moveq #50,d1
jsr genlib::put_small_string
bra.s \done
\String dc.b "Mroupsy is good !",0
even
\done:
SEE ALSO:
gl_put_large_string, gl_put_small_string.
void gl_put_large_string(SCREEN *Scr, short x, short y, char *Str);
genlib::put_large_string
INPUT:
Str = A0 = String to print
Scr = A1 = Address of the screen (LCD_MEM or window, or ??)
x = D0.w = X coordinate (0...239)
y = D1.W = Y coordinate (0...127)
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws all the characters of the string at the specified coordinates with the large font (Of the boot code, so it doesn't work on Vti with 9xu or Tib roms, but only with real dump). No clipping is done !
It works in a very different way than the last 2 functions.
It is because the len of a char, in this font, is exactly 8 pixels.
So it could be 8x aligned, and it is 8x aligned. It increases a lot
the speed. So the real coordinate x is in fact floor(x/8)*8.
It prints the string, erasing the background.
EXAMPLES:
gl_put_large_string(gl_window, 20, 50, "Scoobydoo ?");
move.l genlib::window,a1
lea \String(Pc),a0
moveq #20,d0
moveq #50,d1
jsr genlib::put_small_string
bra.s \done
\String dc.b "Scoobydoo is really good !",0
even
\done:
SEE ALSO:
gl_put_medium_string, gl_put_small_string.
void gl_create_bgs_string(char *str, BGS *bgs);
genlib::create_bgs_string
INPUT:
str = A0 = Address of the string
bgs = A1 = Address of the Big sprite buffer (must be large enought)
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It creates a big sprite which looks like the string.
It is quite usefull if you want to print a string with clipping or using the halo.
The size of the buffer should be equal at 2+floor((strlen(str)+1)/2)*8*4.
EXAMPLES:
void print_string(char *str, short x, short y){
char buffer[2+floor((strlen(str)+1)/2)*8*4]; // I think it works.
gl_create_bgs_string(str, (BGS *) buffer);
gl_put_big_sprite(x, y, (BGS *) buffer);}
SEE ALSO:
Here there are ! The sprite routines of genlib !
This library offers very powerfull sprites routines for very different formats.
It is hard to slow down your program with theses routines but I think, with courage and loyalty, you will. There are designed to put "a litle more" than one or two sprites ;)
First, we will see the SPRITE16 (or TILE16, it is the same) format.
The color White is the transparent color. It won't be displayed.
The size of the sprite is 64 bytes : 16 Colonnes * 16 Lignes in 4 colors (/8).
(Sprmaker format -Interleave).
You should set before the address of the array of TILE16 using gl_set_spr_tile or genlib::sprite_tile_adr.
void gl_put_sprite_16(short x, short y, short no);
genlib::put_sprite_16
INPUT:
x = d0.w = x coordinate in the sprite plane
y = d1.w = y coordinate in the sprite plane
no = d2.w = Number of tile in the array of TILE16 (0 <=no < 512).
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It puts the sprite in SPRITE16 format, number no at x, y on the current working DScreen.
EXAMPLES:
SPRITE_16 Sprite =
{
{0xaaaa, 1195},
{1045, 1195},
{1045, 1195},
{1045, 1195},
{1045, 1195},
{1045, 1195},
{1045, 1195},
{1045, 1195},
{1045, 1195},
{1045, 1195},
{1045, 1195},
{1045, 1195},
{1045, 1195},
{1045, 1195},
{1045, 1195},
{1045, 1195},
};
void lets_start() {
SPRITE_16 *spr = &Sprite;
unsigned long count;
short x,y;
char tmpstr[500];
// Init sprite_16
gl_set_spr_xy(0,0);
gl_set_spr_tile(spr);
// Put sprite...
gl_cls();
count = 0;
gl_timer = 0;
for (y=0;y<100-8;y++)
for (x=0;x<160-16;x++)
{
count++;
gl_put_sprite_16(x, y, 0);
}
sprintf(tmpstr,"Genlib %lu tics for %ld sprites",gl_timer,count);
gl_set_LCD_MEM();
gl_put_small_string((SCREEN *) LCD_MEM, 14, 30, tmpstr);
gl_wait_a_key();
// Genlib put sprite with macros
SwapBuffer();
gl_cls();
count = 0;
gl_timer = 0;
for (y=0;y<100-8;y++)
for (x=0;x<160-16;x++)
{
count++;
_gl_put_sprite_16(x, y, 0);
}
sprintf(tmpstr,"GenlibMacro %lu tics for %ld sprites",gl_timer,count);
gl_set_LCD_MEM();
gl_put_small_string((SCREEN *) LCD_MEM,14,40,tmpstr);
gl_wait_a_key();
}
SEE ALSO:
gl_put_sprite_16_flip_h, gl_put_sprite_16_flip_v, gl_put_sprite_16_flip_hv
void gl_put_sprite_16_flip_h(short x, short y, short no);
genlib::put_sprite_16_flip_h
INPUT:
x = d0.w = x coordinate in the sprite plane
y = d1.w = y coordinate in the sprite plane
no = d2.w = Number of tile in the array of TILE16 (0 <=no < 512).
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It works just like put_sprite_16 function but with a horizontal flipping. It means that it is the horizontal mirror of the sprite which is printed.
EXAMPLES:
See the put_sprite16 example.
SEE ALSO:
gl_put_sprite_16, gl_put_sprite_16_flip_v, gl_put_sprite_16_flip_hv
void gl_put_sprite_16_flip_v(short x, short y, short no);
genlib::put_sprite_16_flip_v
INPUT:
x = d0.w = x coordinate in the sprite plane
y = d1.w = y coordinate in the sprite plane
no = d2.w = Number of tile in the array of TILE16 (0 <=no < 512).
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It works just like put_sprite_16 function but with a vertical flipping. It means that it is the vertical mirror of the sprite which is printed.
EXAMPLES:
See the put_sprite16 example.
SEE ALSO:
gl_put_sprite_16_flip_h, gl_put_sprite_16, gl_put_sprite_16_flip_hv
void gl_put_sprite_16_flip_hv(short x, short y, short no);
genlib::put_sprite_16_flip_hv
INPUT:
x = d0.w = x coordinate in the sprite plane
y = d1.w = y coordinate in the sprite plane
no = d2.w = Number of tile in the array of TILE16 (0 <=no < 512).
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It works just like put_sprite_16 function but with a vertical flipping and a horizontal flipping. It means that it is the horizontal-vertical mirror of the sprite which is printed.
EXAMPLES:
See the put_sprite16 example.
SEE ALSO:
gl_put_sprite_16_flip_h, gl_put_sprite_16, gl_put_sprite_16
void gl_put_sprite_16_zoom(short x, short y, short no, FIXED H_fact, FIXED V_fact);
genlib::put_sprite_16_zoom
INPUT:
x = d0.w = X (real coordinate !)
y = d1.w = Y (real coordinate !)
no = d2.w = index in the sprite array
H_fact = d4.l = 1.00 / (hor_zoom_factor) (Fixed)
V_fact = d5.l = ver_zoom_factor (Fixed)
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It scales a sprite_16 but without any clipping.
It isn't slow, but you can't (in my opinion) use it for real time function except for special effects.
It will display it without erasing the background, but it may change.
To do a square-zoom of factor n, H_fact = (65536 / n) and V_fact = d5.l=(65536 * n)
EXAMPLES:
jsr genlib::cls
clr.w genlib::sprite_scr_x ; Clear Sprite_Scroll_X coordinate
clr.w genlib::sprite_scr_y ; Clear "_"_Y "
lea Sprite_Tile(PC),a0 ; Set sprite tile (16x16)
move.l a0,genlib::sprite_tile_adr
moveq #10,d0
moveq #15,d1
moveq #0,d2
move.l #(65536/4),d4
move.l #(65536*4),d5
jsr genlib::put_sprite_16_zoom
jsr genlib::wait_a_key ; Wait a key (direct acces)
; ...
rts
Sprite_Tile
INCBIN "fernand.bin"
SEE ALSO:
void gl_pal_sprite_16(short pal, short src, short dest);
genlib::pal_sprite16
INPUT:
pal = d0.w = Palette number (0..7)
src = d1.w = Number of source sprite in sprite16 array.
dest = d2.w = Number of Dest sprite in sprite16 array.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It copies the sprite 16 according to the palette.
EXAMPLES:
jsr genlib::cls
clr.w genlib::sprite_scr_x ; Clear Sprite_Scroll_X coordinate
clr.w genlib::sprite_scr_y ; Clear "_"_Y "
lea Sprite_Tile(PC),a0 ; Set sprite tile (16x16)
move.l a0,genlib::sprite_tile_adr
moveq #0,d0
moveq #0,d1
moveq #1,d2
jsr genlib::pal_sprite_16
moveq #10,d0
moveq #10,d1
moveq #1,d2
jsr genlib::put_sprite_16 ; Put sprite d2.w at (d0.w, d1.w)
; on the current dscreen !
jsr genlib::wait_a_key ; Wait a key (direct acces)
; ...
rts
Sprite_Tile
INCBIN "fernand.bin"
SEE ALSO:
gl_put_sprite_16, palette
void gl_put_mask_spr16(short x, short y, short no);
genlib::put_mask_spr16
INPUT:
x = d0.w = x coordinate in the sprite plane
y = d1.w = y coordinate in the sprite plane
no = d2.w = Number of tile in the array of TILE16 (0 <=no < 512).
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It puts the sprite in SPRITE16 format, number no at x, y on the current working DScreen without any transparency.
EXAMPLES:
See the PutSprite16 examples.
SEE ALSO:
gl_put_mask_spr16_flip_h, gl_put_mask_spr16_flip_v, gl_put_mask_spr16_flip_hv
void gl_put_mask_spr16_flip_h(short x, short y, short no);
genlib::put_mask_spr16_flip_h
INPUT:
x = d0.w = x coordinate in the sprite plane
y = d1.w = y coordinate in the sprite plane
no = d2.w = Number of tile in the array of TILE16 (0 <=no < 512).
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It works just like put_sprite_16 function but with a horizontal flipping, without transparency.
It means that it is the horizontal mirror of the sprite which is printed.
EXAMPLES:
See the put_sprite16 example.
SEE ALSO:
gl_put_mask_spr16, gl_put_mask_spr16_flip_v, gl_put_mask_spr16_flip_hv
void gl_put_mask_spr16_flip_v(short x, short y, short no);
genlib::put_mask_spr16_flip_v
INPUT:
x = d0.w = x coordinate in the sprite plane
y = d1.w = y coordinate in the sprite plane
no = d2.w = Number of tile in the array of TILE16 (0 <=no < 512).
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It works just like put_sprite_16 function but with a vertical flipping without transparency.
It means that it is the vertical mirror of the sprite which is printed.
EXAMPLES:
See the put_sprite16 example.
SEE ALSO:
gl_put_mask_spr16, gl_put_mask_spr16_flip_h, gl_put_mask_spr16_flip_hv
void gl_put_mask_spr16_flip_hv(short x, short y, short no);
genlib::put_mask_spr16_flip_hv
INPUT:
x = d0.w = x coordinate in the sprite plane
y = d1.w = y coordinate in the sprite plane
no = d2.w = Number of tile in the array of TILE16 (0 <=no < 512).
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It works just like put_sprite_16 function but with a vertical flipping and a horizontal flipping without transparency.
It means that it is the horizontal-vertical mirror of the sprite which is printed.
EXAMPLES:
See the put_sprite16 example.
SEE ALSO:
gl_put_mask_spr16, gl_put_mask_spr16_flip_h, gl_put_mask_spr16_flip_v
The 'Big' sprite functions are designed to put a sprite of any size between 16x1 to 240x128.
The weight is a multiple of 16. It is between 16..240. The height is between 1 to 128.
The white is also the transparent color. The calcul of the mask is a bit complicated. The sprite is surrounded with a white halo, which allows it to be putted on dark, or complicated background.
It is also an interleave format. The sprite format is :
dc.b ROW_NUMBER, WORD_COL_NUMBER
dc.w ROW_1_COL_1_SCREEN_1,ROW_1_COL_1_SCREEN_2,ROW_1_COL_2_SCREEN_1,ROW_1_COL_2_SCREEN_2,...
dc.w ROW_2_COL_1_SCREEN_1,ROW_2_COL_1_SCREEN_2,ROW_2_COL_2_SCREEN_1,ROW_2_COL_2_SCREEN_2,...
dc.w ...
Or in C:
typedef struct
{
char Height; // In pixel
char Weight; // In pixel /16
GRAY_16_PIXEL Data[]; // It isn't defined like this
} BGS;
and GRAY_16_PIXEL is defined as :
typedef struct
{
short DARK_PLANE; // 16 pixels for dark plane
short LIGHT_PLANE; // 16 pixels for light plane
} GRAY_16_PIXEL;
As an example, here is a ship of size 32 x 8
ship: dc.b 8,2
dc.w %0000000000000001,%0000000000000001,%1000000000000000,%1000000000000000
dc.w %0000000000000011,%0000000000000010,%1100000000000000,%0100000000000000
dc.w %0000000000001110,%0000000000001001,%0111000000000000,%1001000000000000
dc.w %0000000001111100,%0000000001000011,%0011111000000000,%1100001000000000
dc.w %0000111111011100,%0000100000000011,%0011101111110000,%1100000000010000
dc.w %0000011111111110,%0000011111111111,%0111111111100000,%1111111111100000
dc.w %0000000000000011,%0000000000000010,%1100000000000000,%0100000000000000
dc.w %0000000000001110,%0000000000001001,%0111000000000000,%1001000000000000
The big sprites routines are slower than sprite16 for two reasons :
- Size is variable :)
- A halo will be generated all around your sprites so that you can see them
in your complex background (without the need of extra memory for the mask).
void gl_put_big_sprite(short x, short y, BGS *bgs);
genlib::put_big_sprite
INPUT:
x = d0.w = X coordinate in the sprite plane
y = d1.w = Y coordinate in the sprite plane
bgs = a0 = address of the sprite.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It puts a big sprite on the current DScreen with halo. It renders the sprite very nice, without the need of a mask (which would increase the size by 50%).
It clips the sprite if it is outside the screen.
The original routine was made by Olivier Certner.
EXAMPLES:
clr.w genlib::sprite_scr_x ; Clear Sprite_Scroll_X coordinate
clr.w genlib::sprite_scr_y ; Clear "_"_Y "
jsr genlib::cls
moveq #10,d0
moveq #50?D1
lea ship,a0
jsr genlib::put_big_sprite
jsr genlib::wait_a_key
In C :
extern BGS ship;
void lets_start() {
gl_set_spr_xy(0,0);
gl_cls();
gl_put_big_sprite(10, 50, &ship);
gl_wait_a_key();
}
SEE ALSO:
gl_put_big_sprite_flip_h, gl_put_big_sprite_flip_v, gl_put_big_sprite_flip_hv
void gl_put_big_sprite_flip_h(short x, short y, BGS *bgs, BGS *bgs_flip);
genlib::put_big_sprite_flip_h
INPUT:
x = d0.w = X coordinate in the sprite plane
y = d1.w = Y coordinate in the sprite plane
bgs = a1 = address of the sprite.
bgs_flip = a0 = address of a temporary buffer whose size must be at least equal to the sprite.
OUTPUT:
In the temporary buffer, you have the flipped-sprite.
DESTROYED REGISTERS:DESCRIPTION:
It puts a big sprite on the current DScreen with halo and with horizontal flipping.
It clips the sprite if it is outside the screen.
You need to have a temporary buffer for computing the flipping sprite.
EXAMPLES:
clr.w genlib::sprite_scr_x ; Clear Sprite_Scroll_X coordinate
clr.w genlib::sprite_scr_y ; Clear "_"_Y "
jsr genlib::cls
moveq #10,d0
moveq #50?D1
lea ship,a1
lea Temp,a0
jsr genlib::put_big_sprite
jsr genlib::wait_a_key
rts
BSS
Temp ds.b 3800
In C :
extern BGS ship;
void lets_start() {
char Temp[3000];
gl_cls();
gl_put_big_sprite_flip_h(10, 50, &ship, (BGS *) Temp);
gl_wait_a_key();
}
SEE ALSO:
gl_put_big_sprite, gl_put_big_sprite_flip_v, gl_put_big_sprite_flip_hv
void gl_put_big_sprite_flip_v(short x, short y, BGS *bgs, BGS *bgs_flip);
genlib::put_big_sprite_flip_v
INPUT:
x = d0.w = X coordinate in the sprite plane
y = d1.w = Y coordinate in the sprite plane
bgs = a1 = address of the sprite.
bgs_flip = a0 = address of a temporary buffer whose size must be at least equal to the sprite.
OUTPUT:
In the temporary buffer, you have the flipped-sprite.
DESTROYED REGISTERS:DESCRIPTION:
It puts a big sprite on the current DScreen with halo and with vertical flipping.
It clips the sprite if it is outside the screen.
You need to have a temporary buffer for computing the flipping sprite.
EXAMPLES:
See the example of gl_put_big_sprite_flip_h
SEE ALSO:
gl_put_big_sprite_flip_h, gl_put_big_sprite, gl_put_big_sprite_flip_hv
void gl_put_big_sprite_flip_hv(short x, short y, BGS *bgs, BGS *bgs_flip);
genlib::put_big_sprite_flip_hv
INPUT:
x = d0.w = X coordinate in the sprite plane
y = d1.w = Y coordinate in the sprite plane
bgs = a1 = address of the sprite.
bgs_flip = a0 = address of a temporary buffer whose size must be at least equal to the sprite.
OUTPUT:
In the temporary buffer, you have the flipped-sprite.
DESTROYED REGISTERS:DESCRIPTION:
It puts a big sprite on the current DScreen with halo and with horizontal and vertical flipping.
It clips the sprite if it is outside the screen.
You need to have a temporary buffer for computing the flipping sprite.
EXAMPLES:
See the example of gl_put_big_sprite_flip_h
SEE ALSO:
gl_put_big_sprite_flip_h, gl_put_big_sprite, gl_put_big_sprite_flip_v
void gl_put_big_sprite_zoom(short x, short y, BGS *bgs, FIXED H_fact, FIXED V_fact);
genlib::put_big_sprite_zoom
INPUT:
x = d0.w = X coordinate in the DSceen
y = d1.w = Y coordinate in the DScreen
bgs = a1 = address of the sprite.
H_fact = d4.l = 1.0 / (hor_zoom_factor) (Fixed)
V_fact = d5.l = ver_zoom_factor (Fixed)
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It scales a big sprite on the current DScreen without halo.
It doesn't clip the sprite if it is outside the screen.
If you want a square scale factor n, H_fact = 65536 / n abnd V_fact = 65536 * n.
EXAMPLES:
clr.w genlib::sprite_scr_x ; Clear Sprite_Scroll_X coordinate
clr.w genlib::sprite_scr_y ; Clear "_"_Y "
jsr genlib::cls
lea ship(PC),a1 ; Address
moveq #10,d0 ; x (real !)
moveq #20,d1 ; y (real !)
move.l #(65536/4),d4 ; Factor x
move.l #(65536*4),d5 ; Factor y
jsr genlib::put_big_sprite_zoom
jsr genlib::wait_a_key
rts
SEE ALSO:
Your game is really too slow ? put_sprite_16 isn't enought fast for you ? big_sprite are too too too too too too slow ? (NDLR: PpHd please stops destroying you !)
Do you really need to put more than 200 sprites each frame at 60 Fps ?
If you do, here is the solution ! Theses routines are, maybe, the fastest sprites routines possible on ti-68k ! But of course, there are some bad news... The sprite format is huge !
Now, try to slow down your program with theses routines. Ok, you will. :(
The White color is transparent, and they work in monochrome. So you need to call them twice to work in gray.
I haven't converted the macros for ti-gcc since, in my opinion, if you need such routines, you won't do your program in C.
void gl_make_fast_sprite(SPRITE_BW16 Spr, FAST_SPRITE fspr);
genlib::make_fast_sprite
INPUT:
Spr = a0 = 16BW sprite.
fspr = a1 = buffer of 1024 bytes (size of a FAST_SPRITE)
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It creates a fast sprite from a '16x16 black and white' (16BW) sprite in the given buffer.
EXAMPLES:
extern char fspr[1024];
short Sprite[16] =
{125,145,165,185,
205,225,245,265,
285,305,325,345,
365,385,405,425,
445,465,485,505
};
void create_fspr() {
gl_make_fast_sprite(Sprite, fspr); }
SEE ALSO:
All the functions of fast sprites.
genlib::put_fast_sprite
INPUT:
d0.w = X coordinate in the SCREEN
d1.w = Y coordinate in the SCREEN
a0 -> Fast_sprite
a1 -> Screen
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It puts the fast sprite in the given screen.
It must be used like a macro (It is a macro ).
Warning : NO CLIPPING is done.
EXAMPLES:
jsr genlib::get_dscreen
move.l a0,a1
moveq #100,d0
moveq #50,d1
lea fspr(Pc),a0
genlib::put_fast_sprite
...
xdef fspr
fspr ds.b 1024
SEE ALSO:
All the functions of fast sprites.
genlib::do_fast_sprite
INPUT:
d0.w = X coordinate in the SCREEN
d1.w = Y coordinate in the SCREEN
a0 -> Fast_sprite
a1 -> Screen
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It does a logical operation from the fast sprite to the given screen.
It must be used like a macro (It is a macro ).
Warning : NO CLIPPING is done.
EXAMPLES:
put_fast_sprite is defined like that :
genlib::put_fast_sprite MACRO
genlib::do_fast_sprite
ENDM
SEE ALSO:
All the functions of fast sprites.
genlib::put_fast_sprite_ds
INPUT:
d0.w = X coordinate in the SCREEN
d1.w = Y coordinate in the SCREEN
a0 -> Fast_sprite
a1 -> DScreen
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It puts the fast sprite to the given DScreen.
It is copies in the two sub-screens.
It must be used like a macro (It is a macro ).
Warning : NO CLIPPING is done.
EXAMPLES:
jsr genlib::get_dscreen
move.l a0,a1
moveq #100,d0
moveq #50,d1
lea fspr(Pc),a0
genlib::put_fast_sprite_ds
...
xdef fspr
fspr ds.b 1024
SEE ALSO:
All the functions of fast sprites.
genlib::do_fast_sprite_ds
INPUT:
d0.w = X coordinate in the SCREEN
d1.w = Y coordinate in the SCREEN
a0 -> Fast_sprite
a1 -> DScreen
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It does a logical operation from the fast sprite to the given DScreen.
It is copies in the two sub-screens.
It must be used like a macro (It is a macro ).
Warning : NO CLIPPING is done.
EXAMPLES:
genlib::put_fast_sprite_ds MACRO
genlib::do_fast_sprite_ds
ENDM
SEE ALSO:
All the functions of fast sprites.
You like doing scrolling ?
Well, you may think you will do scrolling... But, in fact, it is quite different. You don't have the standard routines (ScrollLeft, ScrollRight, ScrollUp, ScrollDown) which provides a scrolling of one pixel per one pixel. In this conception, you will reach the limits very early. You won't be able to increase the speed.
So I have implemented a very different way of scrolling. Scrolling ? Not exactly. I can't really call it scrolling. In fact, it works like you draw a very big sprites of size 4096x1024 (for example) into the current DScreen. As the size of the sprite is enormous, you won't define it like a sprite. You will define both things : a matrix and an array of tiles. Each element of the matrix will be an equivalent of the corresponding tile in the array.
As you have seen in the structure part, a matrix could be a matrix of bytes (Standard, 256 tiles max) or a matrix of short (Maximun performance, 1024 tiles max, Horizontal, Vertical flipping, Palette).
The association of the matrix and the array of tiles is called a Plane.
The way of working is similar with the way of working of the console video chip of SNES, Genesis, Game Boy, GBA, ...
In fact, it is easier to use than standard scrolling functions, but they could be less flexible. To draw a plane, you should do after init it :
- Call an update function to update its VScreen. Choose the function according to the matrix and tiles format.
- Call a put_plane function according to the special effects you want./li>
void _gl_init_plane(char *map, void *tile, short sizeX, PLANE **plan);
PLANE *gl_init_plane(char *map, void *tile, short sizeX);
genlib::init_plane
INPUT:
map = a3 = Adress of the matrix.
tile = a4 = Adress of the tile (8x8 or 16x16) array.
A5 = 0
sizeX = d3 = Weight of the matrix.
-> N when 2^N is the real numbers of colomns (Default - faster)
-> or the real number of colomns (See 'change_update)
plan (Macro only) : address of the address of the plane.
OUTPUT:
a0 = The allocated plane (except for macro) or NULL if no enought memory.
DESTROYED REGISTERS:DESCRIPTION:
It allocates a new plane in the heap with its VScreen and inits it.
Before using any plane functions, you should call this function.
EXAMPLES:
PLANE *P;
char map[] = { // A matrix of 32x32
0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x24,0x24,0x24,
0x24,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,
0x24,0x24,0x01,0x24,0x01,0x01,0x01,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x22,0x01,0x01,0x24,0x24,0x24,0x01,0x0f,0x00,
0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x22,0x00,0x01,0x01,0x01,0x24,0x01,
0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x0c,
0x0c,0x0c,0x00,0x00,0x00,0x22,0x00,0x00,0x01,0x01,
0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x0c,0x0c,
0x0c,0x0c,0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,
0x0c,0x0c,0x0c,0x0c,0x11,0x00,0x00,0x22,0x00,0x00,
0x22,0x00,0x00,0x00,0x01,0x00,0x11,0x08,0x00,0x0c,
0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x00,0x00,0x00,
0x00,0x00,0x0c,0x0c,0x0c,0x0c,0x10,0x00,0x11,0x22,
0x00,0x00,0x22,0x00,0x00,0x00,0x01,0x00,0x10,0x00,
0x00,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0b,
0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x00,0x10,0x00,
0x10,0x22,0x00,0x00,0x22,0x00,0x00,0x00,0x22,0x00,
0x10,0x00,0x00,0x00,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
0x00,0x02,0x07,0x07,0x07,0x07,0x1a,0x1a,0x10,0x1a,
0x10,0x25,0x10,0x22,0x12,0x12,0x22,0x00,0x00,0x00,
0x22,0x02,0x10,0x14,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x02,0x01,0x00,0x00,0x00,0x00,0x02,0x02,
0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x07,
0x07,0x07,0x02,0x01,0x02,0x02,0x19,0x19,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,
0x01,0x01,0x01,0x24,0x24,0x24,0x01,0x01,0x01,0x01,
0x01,0x22,0x22,0x22,0x01,0x01,0x01,0x01,0x02,0x02,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x24,0x24,0x24,
0x01,0x01,0x01,0x22,0x22,0x22,0x01,0x20,0x1f,0x01,
0x01,0x01,0x02,0x19,0x19,0x19,0x19,0x02,0x01,0x00,
0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x22,0x22,0x22,0x01,0x00,
0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x02,0x02,0x01,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,
0x20,0x00,0x00,0x00,0x18,0x18,0x18,0x22,0x22,0x22,
0x00,0x00,0x00,0x00,0x01,0x20,0x01,0x01,0x01,0x01,
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,
0x20,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x22,
0x22,0x22,0x00,0x1a,0x1a,0x00,0x01,0x00,0x00,0x00,
0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x01,0x01,0x00,0x0c,0x0c,0x0c,0x0c,0x00,0x00,0x00,
0x00,0x22,0x22,0x22,0x00,0x01,0x01,0x01,0x20,0x00,
0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x01,0x20,0x00,0x0c,0x0c,0x0c,0x0c,0x00,
0x00,0x00,0x00,0x22,0x22,0x01,0x01,0x20,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0x00,0x11,0x00,0x00,0x00,
0x00,0x00,0x09,0x09,0x01,0x01,0x01,0x01,0x20,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x22,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x10,0x00,
0x00,0x11,0x00,0x01,0x01,0x01,0x01,0x22,0x22,0x22,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x22,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
0x10,0x17,0x00,0x10,0x00,0x01,0x20,0x00,0x00,0x22,
0x22,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x01,0x01,0x02,0x02,0x2b,0x10,0x0e,0x00,0x00,0x00,
0x00,0x22,0x22,0x22,0x11,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x22,0x00,0x00,0x11,0x00,0x11,0x00,
0x00,0x00,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x00,
0x00,0x00,0x00,0x22,0x22,0x22,0x10,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x22,0x00,0x00,0x10,0x00,
0x10,0x00,0x00,0x00,0x01,0x01,0x03,0x01,0x01,0x01,
0x01,0x02,0x17,0x1a,0x1a,0x22,0x22,0x22,0x10,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x22,0x00,0x00,
0x10,0x11,0x10,0x00,0x00,0x00,0x01,0x01,0x01,0x01,
0x03,0x03,0x01,0x01,0x02,0x02,0x02,0x02,0x22,0x22,
0x10,0x17,0x1a,0x1a,0x12,0x00,0x00,0x00,0x00,0x22,
0x00,0x00,0x10,0x10,0x10,0x00,0x00,0x00,0x01,0x01,
0x01,0x01,0x01,0x01,0x03,0x03,0x01,0x01,0x03,0x01,
0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x2b,0x2b,0x25,
0x2b,0x22,0x2b,0x2b,0x10,0x10,0x10,0x2b,0x23,0x2b,
0x01,0x03,0x03,0x03,0x03,0x03,0x01,0x01,0x03,0x03,
0x03,0x22,0x22,0x22,0x01,0x01,0x01,0x01,0x01,0x2c,
0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,
0x2c,0x2c,0x01,0x01,0x03,0x03,0x03,0x03,0x01,0x01,
0x01,0x01,0x03,0x22,0x22,0x22,0x01,0x01,0x01,0x01,
0x01,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,
0x2c,0x2c,0x2c,0x2c,0x01,0x01,0x01,0x03,0x03,0x03,
0x03,0x01,0x01,0x01,0x03,0x22,0x22,0x22,0x01,0x01,
0x01,0x01,0x01,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,
0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x01,0x01,0x01,0x01,
0x01,0x01,0x03,0x03,0x03,0x03,0x01,0x22,0x22,0x22,
0x01,0x01,0x01,0x01,0x01,0x2c,0x2c,0x2c,0x2c,0x2c,
0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x03,0x03,0x03,0x01,0x22,
0x22,0x22,0x01,0x01,0x01,0x01,0x01,0x2c,0x2c,0x2c,
0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x03,0x03,0x03,
0x01,0x22,0x22,0x22,0x01,0x01,0x01,0x01,0x01,0x2c,
0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,
0x2c,0x2c,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x03,0x03,0x01,0x22,0x22,0x22,0x01,0x01,0x01,0x01,
0x01,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,
}
char tiles[] = { // Thanks to ttbin2hex.
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xcc,0xcd,
0xff,0xff,0xb3,0x33,0xff,0xff,0xb3,0x33,0xff,0xff,
0xcc,0xcd,0xff,0xff,0xcc,0xcd,0xff,0xff,0xb3,0x33,
0xff,0xff,0xb3,0x33,0xff,0xff,0xcc,0xcd,0xff,0xff,
0xcc,0xcd,0xff,0xff,0xb3,0x33,0xff,0xff,0xb3,0x33,
0xff,0xff,0xcc,0xcd,0xff,0xff,0xcc,0xcd,0xff,0xff,
0xb3,0x33,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,0x00,0x00,0xff,0xff,0xdb,0x6d,0x24,0x92,
0xb6,0xdb,0x49,0x24,0x00,0x00,0xff,0xff,0xff,0xff,
0x00,0x00,0xff,0xff,0xff,0xff,0xb3,0x33,0xff,0xff,
0xcc,0xcd,0xff,0xff,0xcc,0xcd,0xff,0xff,0xb3,0x33,
0xff,0xff,0xb3,0x33,0xff,0xff,0xcc,0xcd,0xff,0xff,
0xcc,0xcd,0xff,0xff,0xb3,0x33,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x3f,0xfc,0xf0,0x0f,0x1f,0xf8,0xf8,0x1f,0x0f,0xf0,
0xfc,0x3f,0x07,0xe0,0xfe,0x7f,0x03,0xc0,0xff,0xff,
0x01,0x80,0xff,0xff,0x03,0xc0,0xff,0xff,0x07,0xe0,
0xfe,0x7f,0x0f,0xf0,0xfc,0x3f,0x1f,0xf8,0xf8,0x1f,
0x3f,0xfc,0xf0,0x0f,0x7f,0xfe,0xe0,0x07,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x03,0xff,0xff,
0xe0,0x03,0xff,0xff,0xf0,0x07,0xff,0xff,0xf8,0x0f,
0xdf,0xff,0xfc,0x1f,0xcf,0xfb,0xfe,0x3f,0xc7,0xf3,
0xff,0x7f,0xc3,0xe3,0xff,0xff,0xc1,0xc3,0xff,0xff,
0xc1,0xc3,0xff,0x7f,0xc3,0xe3,0xfe,0x3f,0xc7,0xf3,
0xfc,0x1f,0xcf,0xfb,0xf8,0x0f,0xdf,0xff,0xf0,0x07,
0xff,0xff,0xe0,0x03,0xff,0xff,0xc0,0x03,0xff,0xff,
0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff,0x55,0x55,
0xff,0xff,0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff,
0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff,0x55,0x55,
0xff,0xff,0xaa,0xaa,0xff,0xff,0xaa,0xaa,0xff,0xff,
0xaa,0xaa,0xff,0xff,0xaa,0xaa,0xff,0xff,0xaa,0xaa,
0xff,0xff,0xaa,0xaa,0xff,0xff,0xaa,0xaa,0xff,0xff,
0xaa,0xaa,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x01,
0xff,0xff,0x80,0x01,0xff,0xff,0x9c,0x39,0xe3,0xc7,
0x9c,0x39,0xe3,0xc7,0x80,0x01,0xff,0xff,0x80,0x01,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x01,0x80,0xff,0xff,0x01,0x80,0xff,0xff,0x39,0x9c,
0xc7,0xe3,0x39,0x9c,0xc7,0xe3,0x01,0x80,0xff,0xff,
0x01,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0x3c,0x3c,
0x3c,0x3c,0x42,0x42,0x7e,0x7e,0x99,0x99,0xe7,0xe7,
0x42,0x42,0x7e,0x7e,0x3c,0x3c,0x3c,0x3c,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xff,0xff,0xff,0xff,0x40,0x02,0x7f,0xfe,
0x7f,0xfe,0x7f,0xfe,0x40,0x02,0x7f,0xfe,0xff,0xff,
0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x08,0x10,0x08,0x10,0x08,0x10,
0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x10,
0x1c,0x38,0x1c,0x38,0x3e,0x7c,0x36,0x6c,0x7f,0xfe,
0x77,0xee,0x7f,0xfe,0x63,0xc6,0x7f,0xfe,0x41,0x82,
0x00,0x00,0x00,0x00,0x0c,0x30,0x0c,0x30,0x1c,0x38,
0x1c,0x38,0x36,0x6c,0x36,0x6c,0x63,0xc6,0x63,0xc6,
0xc3,0xc3,0xc3,0xc3,0x07,0xe0,0x07,0xe0,0x0d,0xb0,
0x0d,0xb0,0x19,0x98,0x1b,0xd8,0x30,0x0c,0x31,0x8c,
0x20,0x04,0x20,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x04,0x20,0x04,
0x30,0x0c,0x30,0x0c,0x19,0x98,0x19,0x98,0x0d,0xb0,
0x0d,0xb0,0x07,0xe0,0x07,0xe0,0x23,0xc4,0x03,0xc0,
0x33,0xcc,0x03,0xc0,0x1b,0xd8,0x03,0xc0,0x0f,0xf0,
0x03,0xc0,0x07,0xe0,0x03,0xc0,0x03,0xc0,0x03,0xc0,
0x03,0xc0,0x03,0xc0,0x03,0xc0,0x03,0xc0,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xc0,0x03,0xc0,
0x0f,0xf0,0x0c,0x30,0x1f,0xf8,0x13,0xc8,0x1c,0x38,
0x14,0x28,0x38,0x1c,0x28,0x14,0x38,0x1c,0x28,0x14,
0x38,0x1c,0x28,0x14,0x38,0x1c,0x28,0x14,0x1c,0x38,
0x14,0x28,0x1f,0xf8,0x13,0xc8,0x0f,0xf0,0x0c,0x30,
0x03,0xc0,0x03,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x90,
0x0c,0x90,0x0c,0x90,0x1c,0x90,0x1c,0x90,0x34,0x60,
0x34,0x60,0x24,0x1e,0x24,0x1e,0x04,0x12,0x04,0x12,
0x04,0x16,0x04,0x16,0x04,0x1c,0x04,0x1c,0x04,0x10,
0x04,0x10,0x3f,0x90,0x3f,0x90,0x07,0xe0,0x07,0xe0,
0x1f,0xf8,0x18,0x18,0x3c,0x3c,0x23,0xc4,0x70,0x0e,
0x4f,0xf2,0x60,0x06,0x5f,0xfa,0xe0,0x07,0x9f,0xf9,
0xc0,0x03,0xbf,0xfd,0xc0,0x03,0xbf,0xfd,0xc0,0x03,
0xbf,0xfd,0xc0,0xf3,0xbf,0xfd,0xc0,0x33,0xbf,0xfd,
0xc0,0x03,0xbf,0xfd,0xc0,0x03,0xbf,0xfd,0xc0,0x03,
0xbf,0xfd,0xff,0xff,0x80,0x01,0xff,0xff,0xff,0xff,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x9f,0xff,
0xff,0xff,0x90,0x0a,0xf0,0x0f,0x60,0x0a,0x60,0x0f,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0xc0,0x01,0xc0,0x03,0x80,
0x03,0x80,0x03,0x80,0x03,0x80,0x01,0xc0,0x01,0xc0,
0x01,0xc0,0x01,0xc0,0x03,0x80,0x03,0x80,0x03,0x80,
0x03,0x80,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,
0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x01,0xc0,
0x01,0xc0,0x01,0xc0,0x01,0xc0,0x03,0x80,0x03,0x80,
0x03,0x80,0x03,0x80,0x01,0xc0,0x01,0xc0,0x00,0x00,
0x00,0x00,0x0c,0x30,0x0c,0x30,0x1c,0x38,0x1c,0x38,
0x36,0x6c,0x36,0x6c,0x63,0xc6,0x63,0xc6,0xc3,0xc3,
0xc3,0xc3,0x87,0xe1,0x83,0xc1,0x0d,0xb0,0x03,0x80,
0x19,0x98,0x01,0xc0,0x33,0x8c,0x03,0x80,0x23,0x84,
0x03,0x80,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,
0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x01,0xc0,
0x01,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x50,0x0a,0xa0,
0x0a,0xa8,0x15,0x50,0x15,0x54,0x2a,0xa8,0x2a,0xaa,
0x55,0x54,0x55,0x54,0x2a,0xaa,0x2a,0xaa,0x55,0x54,
0x15,0x54,0x2a,0xa8,0x0a,0xa8,0x15,0x50,0x05,0x50,
0x0a,0xa0,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x03,0xc0,0x00,0x00,0x04,0x20,0x03,0xc0,0x05,0xa0,
0x02,0x40,0x05,0xa0,0x02,0x40,0x04,0x20,0x03,0xc0,
0x03,0xc0,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,
0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x3f,0xfc,0x1f,0xf8,0x00,0x00,0x07,0xe0,0x07,0xe0,
0x07,0xe0,0x07,0xe0,0x92,0x49,0x6d,0xb6,0x24,0x92,
0xdb,0x6d,0x49,0x24,0xb6,0xdb,0x92,0x49,0x6d,0xb6,
0x24,0x92,0xdb,0x6d,0x49,0x24,0xb6,0xdb,0x92,0x49,
0x6d,0xb6,0x24,0x92,0xdb,0x6d,0x49,0x24,0xb6,0xdb,
0x92,0x49,0x6d,0xb6,0x24,0x92,0xdb,0x6d,0x49,0x24,
0xb6,0xdb,0x92,0x49,0x6d,0xb6,0x24,0x92,0xdb,0x6d,
0x49,0x24,0xb6,0xdb,0x92,0x49,0x6d,0xb6,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x3c,0x3c,0x3c,0x00,0x7e,0x7e,0x7e,0x00,0xc3,0xc3,
0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,
0xc3,0xc3,0xff,0x00,0x7e,0x7e,0x7e,0x00,0x3c,0x3c,
0x3c,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,
0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x1f,0xf8,
0x1f,0xf8,0x1f,0xf8,0x1f,0xf8,0x01,0x80,0x01,0x80,
0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,
0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,
0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,
0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x08,0x10,0x00,0x00,0x1c,0x38,
0x00,0x00,0x3c,0x3c,0x03,0xc0,0x18,0x18,0x07,0xe0,
0x02,0x40,0x0d,0xb0,0x01,0x80,0x0e,0x70,0x01,0x80,
0x0e,0x70,0x02,0x40,0x0d,0xb0,0x18,0x18,0x07,0xe0,
0x3c,0x3c,0x03,0xc0,0x1c,0x38,0x00,0x00,0x08,0x10,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x48,0x41,0x41,
0x48,0x48,0xf7,0xf7,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x07,0xe0,0x07,0xe0,0x0f,0xf0,
0x08,0x10,0x1f,0xf8,0x18,0x18,0x1f,0xe8,0x14,0x38,
0x1f,0xc8,0x13,0xf8,0x1f,0xc8,0x13,0xf8,0x1f,0xc8,
0x13,0xf8,0x1f,0xc8,0x13,0xf8,0x1f,0xc8,0x13,0xf8,
0x1c,0x28,0x17,0xf8,0x18,0x18,0x1f,0xf8,0xe3,0x8e,
0x55,0x55,0xe3,0x8e,0x55,0x55,0xe3,0x8e,0x55,0x55,
0xe3,0x8e,0x55,0x55,0xe3,0x8e,0x55,0x55,0xe3,0x8e,
0x55,0x55,0xe3,0x8e,0x55,0x55,0xe3,0x8e,0x55,0x55,
0xe3,0x8e,0x55,0x55,0xe3,0x8e,0x55,0x55,0xe3,0x8e,
0x55,0x55,0xe3,0x8e,0x55,0x55,0xe3,0x8e,0x55,0x55,
0xe3,0x8e,0x55,0x55,0xe3,0x8e,0x55,0x55,0xe3,0x8e,
0x55,0x55,0x00,0x00,0x00,0x00,0x03,0xc0,0x00,0x00,
0x04,0x20,0x03,0xc0,0x04,0x20,0x03,0xc0,0x04,0x20,
0x03,0xc0,0x3e,0x7c,0x01,0x80,0x43,0xc2,0x3c,0x3c,
0x42,0x42,0x3d,0xbc,0x42,0x42,0x3d,0xbc,0x43,0xc2,
0x3c,0x3c,0x3e,0x7c,0x01,0x80,0x04,0x20,0x03,0xc0,
0x04,0x20,0x03,0xc0,0x04,0x20,0x03,0xc0,0x03,0xc0,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x0f,
0x00,0x7f,0x00,0x70,0x01,0xf8,0x01,0x87,0x03,0xc0,
0x02,0x3c,0x07,0x00,0x04,0xe1,0x0e,0x00,0x09,0x8f,
0x1c,0x07,0x13,0x38,0x38,0x1f,0x26,0x63,0x38,0x3e,
0x24,0xce,0x70,0x78,0x4d,0x98,0x60,0xf0,0x59,0x30,
0x60,0xe0,0x53,0x60,0xe1,0xc0,0x96,0x40,0xc3,0xc0,
0xb4,0xc0,0xc3,0x80,0xa5,0x80,0xc3,0x00,0xad,0x00,
0xf0,0x00,0xf0,0x00,0xfe,0x00,0x0e,0x00,0x1f,0x80,
0xe1,0x80,0x03,0xc0,0x3c,0x40,0x01,0xe0,0x86,0x20,
0x00,0x70,0xf3,0x90,0xe0,0x38,0x18,0xc8,0xf0,0x1c,
0xce,0x64,0x7c,0x0c,0x63,0x34,0x3e,0x0e,0x39,0x92,
0x0f,0x06,0x0c,0xda,0x07,0x86,0x06,0x4a,0x03,0x87,
0x03,0x69,0x01,0xc3,0x01,0x2d,0x01,0xc3,0x01,0xa5,
0x00,0xc3,0x00,0xb5,0xc3,0x00,0xad,0x00,0xc3,0x80,
0xa5,0x80,0xc3,0x80,0xb4,0x80,0xe1,0xc0,0x96,0xc0,
0x61,0xe0,0x52,0x60,0x60,0xf0,0x5b,0x30,0x70,0x7c,
0x49,0x9c,0x30,0x3e,0x2c,0xc6,0x38,0x0f,0x26,0x73,
0x1c,0x07,0x13,0x18,0x0e,0x00,0x09,0xcf,0x07,0x80,
0x04,0x61,0x03,0xc0,0x02,0x3c,0x01,0xf8,0x01,0x87,
0x00,0x7f,0x00,0x70,0x00,0x0f,0x00,0x0f,0x00,0xc3,
0x00,0xb5,0x01,0xc3,0x01,0xa5,0x03,0xc3,0x03,0x2d,
0x03,0x87,0x02,0x69,0x07,0x06,0x06,0xca,0x0f,0x06,
0x0c,0x9a,0x1e,0x0e,0x19,0xb2,0x7c,0x1c,0x73,0x24,
0xf8,0x1c,0xc6,0x64,0xe0,0x38,0x1c,0xc8,0x00,0x70,
0xf1,0x90,0x00,0xe0,0x87,0x20,0x03,0xc0,0x3c,0x40,
0x1f,0x80,0xe1,0x80,0xfe,0x00,0x0e,0x00,0xf0,0x00,
0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x01,0x00,0x00,0x00,0x02,0x80,0x00,0x00,0x04,0x40,
0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0xa0,0x00,0x00,
0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x1e,0x42,0x00,
0x42,0x00,0x81,0xc0,0x81,0xc0,0x00,0x21,0x00,0x21,
0x3c,0x1e,0x3c,0x1e,0x42,0x00,0x42,0x00,0x81,0xc0,
0x81,0xc0,0x00,0x20,0x00,0x21,0x3c,0x1e,0x3c,0x1e,
0x42,0x00,0x42,0x00,0x81,0xc0,0x81,0xc0,0x00,0x21,
0x00,0x21,0x3c,0x1e,0x3c,0x1e,0x42,0x00,0x42,0x00,
0x81,0xc0,0x81,0xc0,0x00,0x21,0x00,0x21,0x3c,0x1e,
0x78,0x1e,0x00,0x00,0xfc,0x3f,0x30,0x0c,0xfe,0x7f,
0x78,0x1e,0xf0,0x0f,0x33,0xcc,0x60,0x06,0x11,0x88,
0x07,0xe0,0x1f,0xf8,0x61,0x86,0x11,0x88,0xf1,0x8f,
0x31,0x8c,0xff,0xff,0x78,0x1e,0xfd,0xbf,0x31,0x8c,
0x79,0x9e,0x01,0x80,0x03,0xc0,0x03,0xc0,0x06,0x60,
0x07,0xe0,0x0e,0x70,0x09,0x90,0x38,0x1c,0x37,0xec,
0x78,0x1e,0x67,0xe6,0xe7,0xe7,0x99,0x99,0xcf,0xcf,
0x33,0x33,0x9f,0x9f,0x66,0x66,0x3f,0x3f,0xcc,0xcc,
0x7f,0xfe,0x99,0x99,0xfd,0xfc,0x32,0x33,0xf9,0xf9,
0x66,0x66,0xfe,0x73,0xc9,0x9c,0xee,0x77,0x99,0x99,
0xcf,0xcf,0x32,0x33,0x9f,0x9f,0x66,0x66,0x3f,0xbf,
0xcd,0xcc,0x7e,0x7e,0x99,0x99,0xfc,0xfc,0x33,0x33,
0xf9,0xf9,0x66,0x66,0xf3,0xf3,0xcc,0xcc,0x0e,0x70,
0x00,0x00,0x13,0xc8,0x00,0x00,0x13,0xc8,0x03,0xc0,
0x32,0x4c,0x33,0xcc,0x23,0xc4,0x23,0xc4,0x2d,0xb4,
0x2d,0xb4,0x3f,0xfc,0x3f,0xfc,0x03,0xc0,0x03,0xc0,
0x03,0xc0,0x03,0xc0,0x00,0x00,0x01,0x80,0x01,0x80,
0x01,0x80,0x03,0xc0,0x03,0xc0,0x03,0xc0,0x03,0xc0,
0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x0e,0x70,
0x00,0x00,0xff,0xff,0xc1,0x01,0xff,0xff,0xfd,0x83,
0xff,0xfe,0x3d,0x8f,0xff,0xf8,0x0d,0xff,0xff,0xc0,
0x07,0xff,0xff,0x80,0x01,0xff,0xff,0x83,0xc1,0xff,
0xff,0x0f,0xe3,0xff,0xfc,0x1b,0xff,0xff,0xf0,0xf1,
0xbf,0xff,0xfb,0xb0,0x1f,0xff,0xfe,0x18,0x3f,0xff,
0xfc,0x08,0x27,0xff,0xfe,0x04,0x67,0xff,0xff,0x07,
0x47,0xff,0xff,0x03,0xc1,0xff,0xc0,0xff,0xff,0x83,
0xe0,0xff,0xff,0xe2,0x20,0x7f,0xff,0xe6,0x10,0x3f,
0xff,0xe4,0x18,0x7f,0xff,0xfc,0x0d,0xdf,0xff,0xf8,
0x8f,0x0f,0xff,0xfd,0xd8,0x3f,0xff,0xff,0xf0,0xff,
0xff,0xc7,0xc1,0xff,0xff,0x83,0x01,0xff,0xff,0x80,
0x03,0xff,0xff,0xe0,0x1f,0xff,0xff,0xb0,0x7f,0xff,
0xf1,0xbc,0xff,0xff,0xc1,0xbf,0xff,0xff,0x80,0x83,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x03,0xc0,0x00,0x00,0x0f,0x30,0x03,0xc0,
0x13,0x38,0x0f,0xf0,0x2c,0xcc,0x1f,0xf8,0x2c,0xcc,
0x1f,0xf8,0x53,0x32,0x3f,0xfc,0x57,0xf2,0x38,0x1c,
0x6c,0x3e,0x31,0x8c,0x38,0x1c,0x01,0x80,0x00,0x00,
0x01,0x80,0x00,0x00,0x03,0xc0,0x03,0xc0,0x0c,0x30,
0x07,0xe0,0x18,0x18,0x79,0xee,0xff,0xff,0xff,0xff,
0x86,0x11,0xff,0xff,0x86,0x11,0x79,0xee,0xff,0xff,
0x77,0x7a,0xff,0xff,0xff,0xff,0x88,0x85,0xff,0xff,
0x88,0x85,0x77,0x7a,0xff,0xff,0xff,0xff,0x88,0x05,
0xff,0xff,0x88,0x05,0x77,0xdb,0xf8,0x3d,0xff,0xff,
0x88,0x21,0xf6,0xde,0x8f,0xff,0xff,0xff,0x89,0x21,
0xff,0xff,0x89,0x21,0x76,0xde,0xff,0xff,0xff,0xff,
0xff,0xff,0xc0,0x03,0xff,0xff,0xa0,0x07,0xff,0xfd,
0x9f,0xff,0xff,0xf9,0x90,0x0f,0xff,0xf9,0x91,0xcf,
0xff,0xf9,0x90,0x8f,0xff,0xf9,0x93,0xef,0xff,0xf9,
0x90,0x8f,0xff,0xf9,0x91,0x4f,0xff,0xf9,0x92,0x2f,
0xff,0xf9,0x90,0x0f,0xff,0xf9,0x9f,0xff,0xff,0xf9,
0xbf,0xff,0xe0,0x05,0xff,0xff,0xc0,0x03,0xff,0xff,
0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x18,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x18,
0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x3c,0x02,0x00,
0x00,0x3c,0x04,0x00,0x00,0x7e,0x08,0x00,0x00,0x7e,
0x08,0x00,0x00,0xff,0x10,0x00,0x00,0xff,0x90,0x00,
0x00,0x7e,0xd0,0x00,0x00,0x00,0x56,0x18,0x00,0x00,
0x68,0x18,0x00,0x7e,0x30,0x7e,0x81,0xf0,0x7f,0x88,
0x7f,0xf0,0x81,0x77,0x7f,0xf0,0x81,0x77,0x7f,0xf0,
0x81,0x77,0x7f,0xf0,0x81,0x77,0x7e,0xef,0x7e,0xef,
0x01,0x01,0x81,0x81,0x01,0x01,0x7f,0x7f,0x01,0x01,
0x7f,0x7f,0xf9,0x7f,0x87,0x81,0xf7,0x81,0x79,0x7f,
0xf7,0x81,0x79,0x7f,0xf7,0x81,0x79,0x7f,0xf7,0x81,
0x79,0x7f,0xf7,0x81,0x79,0x7f,0xf6,0xfe,0x78,0xfe
};
gl_change_update(); // Real size.
P = gl_init_plane(map, tiles, 32);
SEE ALSO:
All the functions about planes !
void gl_free_plane(PLANE *P);
genlib::free_plane
INPUT:
P = A0 = Address of the plane.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It frees the plane (Equivalent at HeapFree(P->handle);)
EXAMPLES:
gl_free_plane(P);
SEE ALSO:
void gl_refresh_plane(PLANE *P);
genlib::refresh_plane
INPUT:
P = A0 = Address of the plane.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
After calling this function, when you call an 'update_vscreen' function, the VScreen (Virtual-Screen) of the plane will always be updated ! Otherwise, it won't be (always) updated.
It is usefull for tile animation or if you update the matrix.
EXAMPLES:
P->xs = 201;
P->ys = 305;
gl_refresh_plane(P);
gl_update_vscreen_16(P);
gl_put_plane(P);
SEE ALSO:
void gl_copy_xyplane_xysprite(PLANE *P);
genlib::copy_xyplane_xysprite
INPUT:
P = A0 = Address of the plane.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It copies the coordinates of the given plane to the coordinates of the sprite_plane. It is usefull, if you want that your sprites were drawn according to the position of the plane.
EXAMPLES:
It is equivalent to do : gl_set_spr_xy(P->xs, P->ys);
// Set tiles
gl_set_spr_tile(tiles);
// Set the coordinates of the plane
P->xs = 201;
P->ys = 305;
// Set the coordinates of the sprite plane
gl_copy_xyplane_xysprite(P);
// Draw the plane
gl_update_vscreen_16(P);
gl_put_plane(P);
// Put the sprite.
gl_put_sprite_16(253,365, 8);
SEE ALSO:
void gl_copy_dscreen_vscreen(PLANE *P, DSCREEN *DScr);
genlib::copy_dscreen_vscreen
INPUT:
P = A0 = Address of the plane.
DScr = A1 = address of the DScreen.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It copies the DScreen to the VScreen of the plane. It won't clean the VScreen.
EXAMPLES:
void lets_start()
{
int i;
POINT P1 = {32,15}, P2 = {150,60}, P3 = {200, 5};
POINT P4 = {100,5}, P5 = {15,60}, P6 = {200, 50};
PLANE *P = gl_init_plane(NULL, NULL, 16);
gl_cls();
gl_draw_clipped_c_face(P1, P2, P3, 2);
gl_draw_clipped_c_face(P5, P6, P7, 1);
gl_copy_dscreen_vscreen();
for(i = 0 ; i < 30 ; i++)
{
gl_cls();
P->xs = i;
P->ys = i/2;
gl_put_plane(P);
SwapBuffer();
Wait30();
}
}
SEE ALSO:
void gl_change_update(void);
genlib::change_update
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It is an advance function of genlib.
It modifies the code of the three functions 'update_vscreen_8', 'update_vscreen_16' and 'update_vscreen_max16' so that you define the real size of a row in the matrix. It is usefull for working with matrix of size 20 or 30 for example.
You should call it before the update_function. (In the inialisation part of your program for example).
EXAMPLES:SEE ALSO:
void gl_restore_update(void);
genlib::restore_update
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It is an advance function of genlib.
It modifies the code of the three functions 'update_vscreen_8', 'update_vscreen_16' and 'update_vscreen_max16' so that you define the logarithmic size of a row in the matrix. It is usefull for working with matrix of size 2^N for example. It is the default.
You should call it before the update_function. (In the inialisation part of your program for example).
EXAMPLES:SEE ALSO:
void gl_set_filter(short filt);
genlib::set_filter
INPUT:
filt = d0 = The way of filtering.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It is an advance function of genlib.
It sets the transparent color for put_frgd_plane, put_frgd_plane_89, put_dhz_frgd_plane, put_dhz_frgd_plane_89 by changing the code of theses functions. You should call this function before them.
The filter could be :
- 0: The white is transparent (Default).
- 1: The black is transparent. The other colors are ok.
- 2: The Black and White mode : white is white, black and dark grey are black. Light grey is fully transparent.
- 3: All colors are transparent.
EXAMPLES:
See the examples of gl_put_fgrd_plane.
SEE ALSO:
gl_put_frgd_plane, gl_put_frgd_plane_89, gl_put_dhz_frgd_plane, gl_put_dhz_frgd_plane_89
void gl_set_callback_update(void)
genlib::set_callback_update
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It is an advance function of genlib.
It modifies the code of 'update_vscreen_8', 'update_vscreen_16', 'update_vscreen_roll_16' and 'update_vscreen_max16' (As usual) so that you can use a call-back function. But it works only in asm, since you have an extra-argument in a register.
After the function has complete a line of tiles in the VScreen, you can change the address in the table. It could be very usefull if you combine it with Dhz/Hdz table.
The registers you can use for the callbacks function but which are destroyed are : d1.l,
d2.w (But you CAN'T use d2.l !), a1. All the other registers are reserved.
The arguments of the call-backs functions are d3.w = (Table_size-VIRTUAL_X) (The standard incrementaion rate), a4 (The current case in the matrix).
The only global register you can use is : a3.l
When you call the update functions, THERE IS AN EXTRA ARGUMENT :
the address of the callback function is in a2 !!!
Forget this extra-argument, and it will crash !
The call-back function could be only in assembly language.
EXAMPLES:
A basic function which does nothing more than the standart update vscreen is :
MyCallBack adda.w d3,a4
rts
...
jsr genlib::set_callback_update
...
lea MyCallBack(Pc),a2
move.l Plane(Pc),a0
jsr genlib::update_vscreen_16
jsr genlib::put_plane
And a more advance function could be :
MySuperCallBack adda.w (a3)+,a4 ; Add something dependant...
rts
But you need to create a good table in a3 !
SEE ALSO:
gl_update_vscreen_????; gl_free_callback_update
void gl_free_callback_update(void)
genlib::free_callback_update
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It is an advance function of genlib.
It restores the default after a set_callback_update call.
EXAMPLES:
I don't have any example, since it is the default...
SEE ALSO:
gl_update_vscreen_????; gl_set_callback_update
void gl_update_vscreen_8(PLANE *P);
genlib::update_vscreen_8
INPUT:
P = a0 = address of the plane.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It updates the Vscreen of the plane with tiles 8x8 if necessary.
The matrix is a matrix of bytes.
EXAMPLES:SEE ALSO:
void gl_update_vscreen_16(PLANE *P);
genlib::update_vscreen_16
INPUT:
P = a0 = address of the plane.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It updates the Vscreen of the plane with tiles 16x16 if necessary.
The matrix is a matrix of bytes.
EXAMPLES:
JOYPAD j;
// Copies the Init part from gl_init_plane
P->xs = 10;
P->ys = 10;
j = gl_read_joypad();
while (j.exit_key) {
j = gl_read_joypad();
if (!j.left_key) P->xs --;
if (!j.right_key) P->xs ++;
if (!j.up_key) P->ys --;
if (!j.down_key) P->ys ++;
gl_update_vscreen_16(P);
gl_put_plane(P);
SwapBuffer();
Wait30();
}
SEE ALSO:
void gl_update_roll_vscreen_16(PLANE *P);
genlib::update_roll_vscreen_16
INPUT:
P = a0 = address of the plane.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It works like gl_update_vscreen_16. But it is a roll plane matrix. That is to say, if you go outside a row in the matrix during the updating of the Vscreen, instead of going in the new row, you will return to the same row.
It updates the Vscreen of the plane with tiles 16x16 if necessary.
The matrix is a matrix of bytes.
EXAMPLES:SEE ALSO:
void gl_update_vscreen_max16(PLANE *P)
genlib::update_vscreen_max16
INPUT:
P = a0 = address of the plane.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It update the virtual screen of a plane with tiles 16x16.
But the matrix is in the word format, i.e. each tile is indexed by a word instead of a byte. The meaning of the word is :
dc.w %xxxx xxxx xx PPP VH 0
x: Number of the tile to display (Max: 1024 tiles)
V: vertical flipping (1: On, 0:off)
H: Horizontal flipping (1: On, 0:off)
P: Number of the palette (0 -> 7).
You will need this function if you want to do hight and beautiful graphisms (more than 500 tiles).
EXAMPLES:SEE ALSO:
The '_89' means 'Ti89 optimisation.
void gl_put_plane(PLANE *P);
genlib::put_plane
void gl_put_plane_89(PLANE *P);
genlib::put_plane_89
INPUT:
P = a0 = address of the plane.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It puts the VScreen of the plane on the current DSCreen as background.
All is erased.
EXAMPLES:SEE ALSO:
gl_update_vscreen_????, gl_put_plane_???
void gl_put_fgrd_plane(PLANE *P);
genlib::put_fgrd_plane
void gl_put_fgrd_plane_89(PLANE *P);
genlib::put_fgrd_plane_89
INPUT:
P = a0 = address of the plane.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It puts the VScreen of the plane on the current DSCreen as foreground.
You can define the transparent color with gl_set_filter.
EXAMPLES:
JOYPAD j;
PLANE *P1, *P2;
gl_change_update(); // Real size.
P1 = gl_init_plane(map, tiles, 32);
P2 = gl_init_plane(map, tiles, 32); // Same map but you can change
P1->xs = 10;
P1->ys = 10;
P2->xs = 20;
P2->ys = 20;
j = gl_read_joypad();
while (j.exit_key) {
j = gl_read_joypad();
if (!j.left_key) P1->xs --, P2->xs ++;
if (!j.right_key) P1->xs ++, P2->xs --;
if (!j.up_key) P1->ys --, P2->ys ++;
if (!j.down_key) P1->ys ++, P2->ys --;
gl_update_vscreen_16(P1);
gl_update_vscreen_16(P2);
gl_put_plane(P1);
gl_put_fgrd_plane(P2);
SwapBuffer();
Wait15();
}
SEE ALSO:
gl_update_vscreen_????, gl_put_plane_???
void gl_put_dhz_plane(PLANE *P, DHZ_TAB D, HDZ_TAB H);
genlib::put_dhz_plane
void gl_put_dhz_plane_89(PLANE *P, DHZ_TAB D, HDZ_TAB H);
genlib::put_dhz_plane_89
INPUT:
P = a0 = address of the plane.
D = a4 = address of the Dhz table.
H = a5 = address of the Hdz table.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It puts the VScreen of the plane on the current DSCreen as background with Dhz/Hdz tables.
EXAMPLES:
DHZ_TAB dhz = {
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
}
HDZ_TAB hdz = {
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,+VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,+VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,+VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,+VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,+VIRTUAL_X,0,0,0,
}
JOYPAD j;
PLANE *P1;
gl_change_update(); // Real size.
P1 = gl_init_plane(map, tiles, 32);
P1->xs = 10;
P1->ys = 10;
j = gl_read_joypad();
while (j.exit_key) {
j = gl_read_joypad();
if (!j.left_key) P1->xs --, P2->xs ++;
if (!j.right_key) P1->xs ++, P2->xs --;
if (!j.up_key) P1->ys --, P2->ys ++;
if (!j.down_key) P1->ys ++, P2->ys --;
gl_update_vscreen_16(P1);
gl_put_dhz_plane(P1, dhz, hdz);
SwapBuffer();
Wait30();
}
SEE ALSO:
gl_update_vscreen_????, gl_put_plane_???
void gl_put_dhz_fgrd_plane(PLANE *P, DHZ_TAB D, HDZ_TAB H);
genlib::put_dhz_fgrd_plane
void gl_put_dhz_fgrd_plane_89(PLANE *P, DHZ_TAB D, HDZ_TAB H);
genlib::put_dhz_fgrd_plane_89
INPUT:
P = a0 = address of the plane.
D = a6 = address of the Dhz table.
H = d7 = address of the Hdz table.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It puts the VScreen of the plane on the current DSCreen as foreground with Dhz/Hdz table.
You can define the transparent color with gl_set_filter.
EXAMPLES:
JOYPAD j;
PLANE *P1, *P2;
gl_change_update(); // Real size.
P1 = gl_init_plane(map, tiles, 32);
P2 = gl_init_plane(map, tiles, 32); // Same map but you can change
P1->xs = 10;
P1->ys = 10;
P2->xs = 20;
P2->ys = 20;
j = gl_read_joypad();
while (j.exit_key) {
j = gl_read_joypad();
if (!j.left_key) P1->xs --, P2->xs ++;
if (!j.right_key) P1->xs ++, P2->xs --;
if (!j.up_key) P1->ys --, P2->ys ++;
if (!j.down_key) P1->ys ++, P2->ys --;
gl_update_vscreen_16(P1);
gl_update_vscreen_16(P2);
gl_put_plane(P1);
gl_put_dhz_fgrd_plane(P2, dhz, hdz);
SwapBuffer();
Wait15();
}
SEE ALSO:
gl_update_vscreen_????, gl_put_plane_???
void gl_put_dhz_trpt_plane(PLANE *P, DHZ_TAB D, HDZ_TAB H, long Dhz_offset, long Hdz_offset);
genlib::put_dhz_trpt_plane
void gl_put_dhz_trpt_plane_89(PLANE *P, DHZ_TAB D, HDZ_TAB H, long Dhz_offset, long Hdz_offset);
genlib::put_dhz_trpt_plane_89
INPUT:
P = a0 = address of the plane.
D = a3 = address of the Dhz table.
H = a4 = address of the Hdz table.
Dhz_offset = a5 = offset to get the next dhz table (For the light screen) from the end of the last dhz table
Hdz_offset = a6 = offset to get the next hdz table (For the light screen) from the end of the last hdz table
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It puts the VScreen of the plane on the current DSCreen as transparent with individual Dhz/Hdz table.
EXAMPLES:
DHZ_TAB dhz = {
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
}
DHZ_TAB dhz2 = {
-1,1,-2,2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,1,
-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,0,1,-1,2,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,2,-2,3,-3,4,-4,5,-7,8,-8,0,-5,6,-6,7,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
0,1,-1,-4,5,-5,6,-6,7,-7,8,-8,0,2,-2,3,-3,4,
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,0,
-5,6,-6,7,-7,8,-8,0,0,1,-1,2,-2,3,-3,4,-4,5,
}
HDZ_TAB hdz = {
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,+VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,+VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,+VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,+VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,+VIRTUAL_X,0,0,0,
}
HDZ_TAB hdz2 = {
0,0,0,0,0,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,+VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,+VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,+VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,+VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
0,0,0,0,-VIRTUAL_X,0,0,0,
}
JOYPAD j;
PLANE *P1, *P2;
gl_change_update(); // Real size.
P1 = gl_init_plane(map, tiles, 32);
P2 = gl_init_plane(map, tiles, 32); // Same map but you can change
P1->xs = 10;
P1->ys = 10;
P2->xs = 20;
P2->ys = 20;
j = gl_read_joypad();
while (j.exit_key) {
j = gl_read_joypad();
if (!j.left_key) P1->xs --, P2->xs ++;
if (!j.right_key) P1->xs ++, P2->xs --;
if (!j.up_key) P1->ys --, P2->ys ++;
if (!j.down_key) P1->ys ++, P2->ys --;
gl_update_vscreen_16(P1);
gl_update_vscreen_16(P2);
gl_put_plane(P1);
gl_put_dhz_trpt_plane(P2, dhz, hdz, dhz2-dhz+sizeof(dhz), hdz2-hdz+sizeof(hdz));
// Should be 0 and 0...
SwapBuffer();
Wait15();
}
SEE ALSO:
gl_update_vscreen_????, gl_put_plane_???
You don't need to do keyscanning by yourself !
There are very usefull functions which do it for you.
All the keyscanning routines do direct hardware acces. So the standard Ti-Os auto-int 1 should be disable. It should be the case except you do it by yourself.
void gl_wait_no_key(void);
genlib::wait_no_key
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It stops the program until all the keys aren't pressed.
EXAMPLES:SEE ALSO:
void gl_wait_a_key(void);
genlib::wait_a_key
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It stops the program until a key is pressed.
EXAMPLES:SEE ALSO:
char gl_key_pressed(void);
genlib::keypressed
INPUT:OUTPUT:
d0 <> 0 if a key pressed otherwise 0
DESTROYED REGISTERS:DESCRIPTION:
It answers the question : Is a key pressed ?
EXAMPLES:SEE ALSO:
gl_wait_no_key, gl_wait_a_key
KEYBOARD *gl_read_key_matrix(void);
genlib::read_key_matrix
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It update the key-matrix (See above).
The Key-matrix is calc dependant (Ti-89 / Ti-92)
EXAMPLES:
KEYBOARD *keys = gl_read_key_matrix();
SEE ALSO:
gl_wait_no_key, gl_wait_a_key
JOYPAD gl_read_joypad(void);
genlib::read_joypad
INPUT:OUTPUT:
d0 = Current Joypad.
a0 -> New key's matrix.
DESTROYED REGISTERS:DESCRIPTION:
It updates the virtual joypad and the key's matrix.
The joypad ISN'T calc dependant.
Joypad structure : TI92 | TI89
exit_key ESC | ESC
mode_key APPS | APPS
plus_key + | +
minus_key - | -
left_key
up_key
right_key
down_key
ka_key F1 | 2nd
kb_key F2 | Diamond
kc_key F3 | Home
kd_key F4 | X
ke_key F5 | Shift
kf_key F6 | Alpha
kg_key F7 | Mode
kh_key F8 | Y
EXAMPLES:
Of course you don't need to call read_joypad every time.
You can call it once, and then test many keys.
JOYPAD j = gl_read_joypad();
To test 'ke' (F5 or Shift), use :
jsr genlib::read_joypad
btst.l #ke_key,d0
bne \no
[...] ; Code to use if presssed
\no:
SEE ALSO:
gl_wait_no_key, gl_wait_a_key
Genlib has also link functions. It doesn't use the tios routine. It uses a direct access so that you can specify your buffer.
How it works ?
The way of working of the link of genlib is quite different, in theory, with the way of working of the functions of the Ti-Os. The principle is not genious. It works with symetrical buffers. (I dond't know the offical name). On both calcs, we define two buffers. The content of theses two zones are identical (without any propagated time).One calc can only modify one zone. The other one is modified by the other calc.
+-------+ +-------+
| | | |
| | | |
| | | |
| | | |
| | | |
+-------+ +-------+
|Reciev | | Send |
|Buffer | <==================== |Buffer |
+-------+ +-------+
| | | |
| | | |
| | | |
+-------+ +-------+
|Send | ===================> |Receiv |
|Buffer | |Buffer |
+-------+ +-------+
| | | |
| | | |
| | | |
| | | |
| | | |
+-------+ +-------+
Calc A Calc B
I love ASCII art.
The size between the two zones (Send Buffer and Receiv buffer) can be different. The size between a Receiv Buffer of one calc and the size of the Send Buffer of the other calc must be equal.
In order to know if the Receiv Buffer has been received, you have to test if genlib::link_data+buffer_recpt_flag (gl_link_data.buffer_recpt_flag) is DONE. To receive another one, we set it at IN_PROGRESS.
In order to know if the Send Buffer has been received, you have to test if genlib::link_data+buffer_send_flag (gl_link_data.buffer_send_flag) is DONE. To send another one, we call gl_send_data.
To put into practise
- Synchronise : Use gl_synchronize
- Test Master/Slave flag : gl_link_data.link_flag
- Define the mapped memories areas : gl_set_link
- In the infinite loop of your game, add a function which tests the link, and create a new buffer and copy the received buffer. See send_data
void gl_set_byte_link(void);
genlib::set_byte_link
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It sets the auto-link parameters to use a byte structure. You must call it before using 'send_byte' and 'receive_byte'. It works like gl_set_link
EXAMPLES:SEE ALSO:
void _gl_send_byte(char byte);
genlib::send_byte
INPUT:
byte = d0 = The byte to send.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:EXAMPLES:
move.b #...,d0
jsr genlib::send_byte
lea genlib::link_data,a0
\wait: cmp.b #DONE,buffer_send_flag(a0)
bne.s \wait
<-ASM/C->
send_byte(...);
while (gl_link_data.buffer_send_flag != DONE );
SEE ALSO:
gl_set_byte_link, gl_receive_byte
char gl_receive_byte(void);
genlib::receive_byte
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:EXAMPLES:
lea genlib::link_data,a0
move.b #IN_PROGRESS,buffer_recpt_flag(a0)
\wait:
cmp.b #DONE,buffer_recpt_flag(a0)
bne.s \wait
jsr genlib::receive_byte
<-ASM/C->
gl_link_data.buffer_recieve_flag = IN_PROGRESS;
while (gl_link_data.buffer_receive_flag != DONE );
byte = receive_byte();
SEE ALSO:
void gl_send_data(void);
genlib::send_data
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It send the Send buffer to ther other calc. It doesn't wait until it was send. It will be send using the interruptions.
EXAMPLES:
; Test
lea genlib::link_data,a0
cmp.b #DONE,buffer_recpt_flag(a0)
bne.s \no_new
cmp.b #DONE,buffer_send_flag(a0)
bne.s \no_new
; Copies the Receiv Buffer to avoid some problem.
move.w buffer_r(PC),coor_2
; Creates the new Send Buffer
move.b d4,buffer_s ; x
move.b d5,buffer_s+1 ; y
move.b #IN_PROGRESS,buffer_recpt_flag(a0) ; I want a new receive buffer !
jsr genlib::send_data ; Send it (not really)
\no_new
<-ASM/C->
if (gl_link_data.buffer_recpt_flag == DONE && gl_link_data.buffer_send_flag == DONE)
{
tempo.x = buffer_r.x;
tempo.y = buffer_r.y;
buffer_s.x = courant.x;
buffer_s.y = courant.y;
gl_link_data.buffer_recpt_flag = IN_PROGRESS;
gl_send_data();
}
SEE ALSO:
gl_link_data, gl_set_link
void gl_send_data(void);
genlib::send_data
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It send the Send buffer to ther other calc. It doesn't wait until it was send. It will be send using the interruptions.
EXAMPLES:
; Test
lea genlib::link_data,a0
cmp.b #DONE,buffer_recpt_flag(a0)
bne.s \no_new
cmp.b #DONE,buffer_send_flag(a0)
bne.s \no_new
; Copies the Receiv Buffer to avoid some problem.
move.w buffer_r(PC),coor_2
; Creates the new Send Buffer
move.b d4,buffer_s ; x
move.b d5,buffer_s+1 ; y
move.b #IN_PROGRESS,buffer_recpt_flag(a0) ; I want a new receive buffer !
jsr genlib::send_data ; Send it (not really)
\no_new
<-ASM/C->
if (gl_link_data.buffer_recpt_flag == DONE && gl_link_data.buffer_send_flag == DONE)
{
tempo.x = buffer_r.x;
tempo.y = buffer_r.y;
buffer_s.x = courant.x;
buffer_s.y = courant.y;
gl_link_data.buffer_recpt_flag = IN_PROGRESS;
gl_send_data();
}
SEE ALSO:
gl_link_data, gl_set_link
char gl_synchronize(void);
genlib::synchronize
INPUT:OUTPUT:
d0 = 0 if synchro is ok, otherwise the user has pressed a key.
DESTROYED REGISTERS:DESCRIPTION:
It synchronizes the 2 calcs.
It updates the master / slave flag.
Genlib must be installed into the two calcs before calling this function (genlib::init already called).
EXAMPLES:
jsr genlib::synchronize ; Synchro ...
tst.w d0
beq.s \ok
WriteStr #1,#1,#4,bad_str
bra fin
\ok: WriteStr #1,#1,#4,ok_str
Or
if (gl_synchronise())
{
printf("The user press a key !\n");
exit(0);
}
SEE ALSO:
void gl_set_link(char *buf_rcpt, char *buf_send, short buf_rept_len, short buf_send_len);
genlib::set_link
INPUT:
buf_rcpt = a1 = address of the receive-buffer.
buf_send = a2 = address of the send-buffer.
buf_rept_len = d1.w = size of the receive-buffer.
buf_send_len = d2.w = size of the send-buffer.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It sets the current mapped memory areas to use for the link.
Warning : the buffers aren't cleared !
EXAMPLES:
lea buffer_r(PC),a1
lea buffer_s(PC),a2
moveq #2,d1
moveq #2,d2
jsr genlib::set_link
OR gl_set_link(buffer_r, buffer_s, 2, 2);
SEE ALSO:
Some functions which may do some good special effects.
void gl_do_zoom(short x, short y, FIXED H_fact, FIXED V_Fact, short hor_words, short vert_rows, SCREEN *scr, unsigned short *texture, short texture_inc);
genlib::do_zoom
INPUT:
x = d0.w = X coordinate on the DScreen.
y = d1.w = Y coordinate on the DScreen.
H_Fact = d4.l = 1 / (factor of the horizontal Zoom)
V_Fact = d5.l = factor of the vertical Zoom
vert_rows = d6.w = Number of vertical lines for the texture
hor_words = d6.uw= Number of horizontal words for the texture
scr = a0 = The destination Screen.
texture = a1 = texture.
texture_inc = a4 = It is added to the current adress of the texture to get the next texture. It is the interleaved factor (2-Non interleave or 4-Interleave). It should be 2.
a3 = Screen X size. Warning : if a3<>30, then you must have y = 0.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It scales a B&W texture of vertical size vert_rows and of horizontal size 16x hor_words. There is no clipping. H_Fact and V_Fact are fixed reals. The speed is 38 fps for a full-screen zoom on Ti-89. This function isn't enought speed for real time games. You should only use it for special effects.
EXAMPLES:
gl_put_big_sprite_zoom is defined as :
genlib::put_big_sprite_zoom:
movem.l d6/a0-a4,-(a7)
moveq #0,d6
move.b (a1)+,d6 ; Read the number of rows
swap d6
move.b (a1)+,d6 ; Read the number of words
swap d6
lea (30).w,a3 ; Size of a screen line.
lea (4).w,a4 ; Interleaved fact !
move.l DarkScreen,a0 ; Get DarkScreen
bsr genlib::do_zoom ; Zoom
move.l LightScreen,a0 ; Get LightScreen
addq.l #2,a1 ; Texture ;Get the other bit-plane.
bsr genlib::do_zoom ; Zoom
movem.l (a7)+,d6/a0-a4
rts
SEE ALSO:
gl_put_sprite_16_zoom, gl_put_big_sprite_zoom
There are lots of triangle drawing functions. There are quite efficient.
void gl_draw_clipped_face(POINT *Pt1, POINT *Pt2, POINT *Pt3, SCREEN *scr);
genlib::draw_clipped_face
INPUT:
Pt1 = a1 = First Point.
Pt2 = a2 = Second Point
Pt3 = a3 = Third Point
scr = a4 = Destination Screen.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws a face (a triangle in fact). This routine is inspired by Patrick Davidson's one (In Project 12). It clips the triangle. But don't use points which are too far from the screen since it uses a 16-bits division. The coordinates are defined respectively from the Screen.
EXAMPLES:
POINT P1 = {12,13}, P2 = {250,-20}, P3 = {100,150};
gl_draw_clipped_face(&P1, &P2, &P3, DARK_SCREEN(gl_get_dscreen()));
SEE ALSO:
void gl_draw_clipped_c_face(POINT *Pt1, POINT *Pt2, POINT *Pt3, short color);
genlib::draw_clipped_c_face
INPUT:
Pt1 = a1 = First Point.
Pt2 = a2 = Second Point
Pt3 = a3 = Third Point
color = d0 = 0 (White), 1(light gray), 2(Dark Gray) or 3(Black)
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws a face (a triangle in fact) in the specified color. This routine is inspired by Patrick Davidson's one (In Project 12). It clips the triangle. But don't use points which are too far from the screen since it uses a 16-bits division. The coordinates are defined respectively from the Screen.
EXAMPLES:
POINT P1 = {12,13}, P2 = {250,-20}, P3 = {100,150};
gl_draw_clipped_c_face(&P1, &P2, &P3, 2);
SEE ALSO:
void gl_draw_face(POINT *Pt1, POINT *Pt2, POINT *Pt3, SCREEN *scr);
genlib::draw_face
INPUT:
Pt1 = a1 = First Point.
Pt2 = a2 = Second Point
Pt3 = a3 = Third Point
scr = a4 = Destination Screen.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws a face (a triangle in fact). This routine is inspired by Patrick Davidson's one (In Project 12).The coordinates are defined respectively from the Screen. There is no clipping.
EXAMPLES:
POINT P1 = {12,13}, P2 = {220,20}, P3 = {100,100};
gl_draw_face(&P1, &P2, &P3, DARK_SCREEN(gl_get_dscreen()));
SEE ALSO:
void gl_draw_c_face(POINT *Pt1, POINT *Pt2, POINT *Pt3, short color);
genlib::draw_c_face
INPUT:
Pt1 = a1 = First Point.
Pt2 = a2 = Second Point
Pt3 = a3 = Third Point
color = d0 = 0 (White), 1(light gray), 2(Dark Gray) or 3(Black)
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws a face (a triangle in fact) in the specified color. This routine is inspired by Patrick Davidson's one (In Project 12). The coordinates are defined respectively from the Screen. There is no clipping.
EXAMPLES:
POINT P1 = {12,13}, P2 = {200,20}, P3 = {100,100};
gl_draw_c_face(&P1, &P2, &P3, 2);
SEE ALSO:
void gl_render_triangle(POINT *P1, POINT *P2, POINT *P3, void (*draw_hline)(short x1, short x2, short y));
genlib::render_triangle.
INPUT:
P1 = a1 = First Point.
P2 = a2 = Second Point.
P3 = a3 = Third Point.
draw_hline = a6 = Horizontal Line drawing function
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It "Draws" a triangle. In fact, it will call the callback with the different values needed to draw the triangle. It could, of course, doesn't draw a triangle but memorize the coordinates.
The Horizontal Line drawing function, in assembly, should have a prototype like:
INPUT:
d0.w = x1
d1.w = x2
d3.w = y
OUTPUT:DESTROYED REGISTERS:
EXAMPLES:
POINT P1 = {12,13}, P2 = {200,20}, P3 = {100,100};
gl_render_triangle(&P1, &P2, &P3, gl_draw_hline_light);
SEE ALSO:
The drawing of a horizontal line is a good primitive !
void gl_draw_bwhline_b(short x1, short x2, short y);
genlib::draw_bwhline_b
INPUT:
x1 = d0.w = First X coordinate.
x2 = d1.w = Second Y coordinate.
y = d3.w = Y coordinate.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws an horizontal clipped line in Black (in the DARK_SCREEN of the current DSCREEN).
EXAMPLES:
gl_draw_bwline_b(152,12,10);
SEE ALSO:
gl_render_triangle, gl_render_disk
void gl_draw_bwhline_w(short x1, short x2, short y);
genlib::draw_bwhline_w
INPUT:
x1 = d0.w = First X coordinate.
x2 = d1.w = Second Y coordinate.
y = d3.w = Y coordinate.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws an horizontal clipped line in White (in the DARK_SCREEN of the current DSCREEN).
EXAMPLES:
gl_draw_bwline_w(152,12,10);
SEE ALSO:
gl_render_triangle, gl_render_disk
void gl_draw_hline_w(short x1, short x2, short y);
genlib::draw_hline_w
INPUT:
x1 = d0.w = First X coordinate.
x2 = d1.w = Second Y coordinate.
y = d3.w = Y coordinate.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws an horizontal clipped line in white (in the current DSCREEN).
EXAMPLES:
gl_draw_hline_w(152,12,10);
SEE ALSO:
gl_render_triangle, gl_render_disk
void gl_draw_hline_lg(short x1, short x2, short y);
genlib::draw_hline_lg
INPUT:
x1 = d0.w = First X coordinate.
x2 = d1.w = Second Y coordinate.
y = d3.w = Y coordinate.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws an horizontal clipped line in Light Gray (in the current DSCREEN).
EXAMPLES:
gl_draw_hline_lg(152,12,10);
SEE ALSO:
gl_render_triangle, gl_render_disk
void gl_draw_hline_dg(short x1, short x2, short y);
genlib::draw_hline_dg
INPUT:
x1 = d0.w = First X coordinate.
x2 = d1.w = Second Y coordinate.
y = d3.w = Y coordinate.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws an horizontal clipped line in Dark Gray (in the current DSCREEN).
EXAMPLES:
gl_draw_hline_dg(152,12,10);
SEE ALSO:
gl_render_triangle, gl_render_disk
void gl_draw_hline_b(short x1, short x2, short y);
genlib::draw_hline_b
INPUT:
x1 = d0.w = First X coordinate.
x2 = d1.w = Second Y coordinate.
y = d3.w = Y coordinate.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws an horizontal clipped line in Black (in the current DSCREEN).
EXAMPLES:
gl_draw_hline_b(152,12,10);
SEE ALSO:
gl_render_triangle, gl_render_disk
void gl_draw_hline_light(short x1, short x2, short y);
genlib::draw_hline_light
INPUT:
x1 = d0.w = First X coordinate.
x2 = d1.w = Second Y coordinate.
y = d3.w = Y coordinate.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws an horizontal clipped line (in the current DSCREEN).
It will transform the background such like there is a ray of light.
It is very powerfull if you combine it with render_triangle or render_disk !
EXAMPLES:
gl_draw_hline_light(152,12,10);
SEE ALSO:
gl_render_triangle, gl_render_disk
void gl_draw_hline_shadow(short x1, short x2, short y);
genlib::draw_hline_shadow
INPUT:
x1 = d0.w = First X coordinate.
x2 = d1.w = Second Y coordinate.
y = d3.w = Y coordinate.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws an horizontal clipped line (in the current DSCREEN).
It will transform the background such like there is a ray of shadow.
It is very powerfull if you combine it with render_triangle or render_disk !
EXAMPLES:
gl_draw_hline_shadow(152,12,10);
SEE ALSO:
gl_render_triangle, gl_render_disk
void gl_put_pixel(short x, short y, short color);
genlib::put_pixel
INPUT:
x = d0.w = x coordinate on the DScreen
y = d1.w = y coordinate on the DScreen
color = d3.w = 0 (White), 1(Light gray), 2(Dark Gray) or 3(Black)
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It puts a pixel on the current Dscreen. (Clipping)
EXAMPLES:
gl_put_pixel(152,12,2);
SEE ALSO:
void gl_draw_circle(short x, short y, short radius, short color);
_gl_draw_circle(POINT center, short radius, short color);
genlib::draw_circle
INPUT:
x = d4.w = x_center of the circle
y = d5.w = y_center of the circle
radius = d2.w = Radius of the circle
color = d3.w = 0(Black), 1(Light gray), 2(Dark gray) or 3(Black)
For the macro version, you should use a point rather than coordinates (To avoid some bugs).
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws a non-clipped circle on the current Dscreen at the specified color.
EXAMPLES:
gl_draw_circle(152,12,30,2);
SEE ALSO:
void gl_draw_clipped_circle(short x, short y, short radius, short color);
_gl_draw_clipped_circle(POINT center, short radius, short color);
genlib::draw_clipped_circle
INPUT:
x = d4.w = x_center of the circle
y = d5.w = y_center of the circle
radius = d2.w = Radius of the circle
color = d3.w = 0(Black), 1(Light gray), 2(Dark gray) or 3(Black)
For the macro version, you should use a point rather than coordinates (To avoid some bugs).
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws a clipped circle on the current Dscreen at the specified color.
EXAMPLES:
gl_draw_clipped_circle(152,12,30,2);
SEE ALSO:
int gl_clip_line(short *x1, short *y1, short *x2, short *y2);
genlib::clip_line
INPUT:
x1 = d0.w = x coordinate of Point 1
y1 = d1.w = y coordinate of Point 1
x2 = d2.w = x coordinate of Point 2
y2 = d3.w = y coordinate of Point 2
NOTE: In C, you pass as arguments the adress of the arguments. In Asm, you pass the arguments. It is because, in C, you cannot return more than one argument.
OUTPUT:
d4 = 0 if the line is outside the screen (No draw).
Otherwise the coordinates are updated (In Asm, d0,d1,d2,d3 are modified).
DESTROYED REGISTERS:DESCRIPTION:EXAMPLES:
See gl_draw_clipped_line example.
SEE ALSO:
void gl_draw_line(short x1, short y1, short x2, short y2, short color);
genlib::draw_line
INPUT:
x1 = d0.w = x coordinate of Point 1
y1 = d1.w = y coordinate of Point 1
x2 = d2.w = x coordinate of Point 2
y2 = d3.w = y coordinate of Point 2
color = d5.w = 0(White), 1(light), 2(Dark), 3(Black).
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws a line without clipping.
EXAMPLES:
gl_draw_line(10,20,100,100,1);
SEE ALSO:
void gl_draw_clipped_line(short x1, short y1, short x2, short y2, short color);
genlib::draw_clipped_line
INPUT:
x1 = d0.w = x coordinate of Point 1
y1 = d1.w = y coordinate of Point 1
x2 = d2.w = x coordinate of Point 2
y2 = d3.w = y coordinate of Point 2
color = d5.w = 0(White), 1(light), 2(Dark), 3(Black).
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws a line with clipping.
EXAMPLES:
gl_draw_clipped_line(-10,-20,100,100,1);
SEE ALSO:
void gl_draw_disk(short x, short y, short radius, short color);
genlib::draw_disk
INPUT:
x = d4.w = x_center of the disk
y = d5.w = y_center of the disk
radius = d2.w = Radius of the disk
color = d3.w = 0(Black), 1(Light gray), 2(Dark gray) or 3(Black)
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws a disk without clipping.
EXAMPLES:
gl_draw_disk(10,20,10,1);
SEE ALSO:
void gl_draw_clipped_disk(short x, short y, short radius, short color);
genlib::draw_clipped_disk
INPUT:
x = d4.w = x_center of the disk
y = d5.w = y_center of the disk
radius = d2.w = Radius of the disk
color = d3.w = 0(Black), 1(Light gray), 2(Dark gray) or 3(Black)
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It draws a disk with clipping.
EXAMPLES:
gl_draw_clipped_disk(10,20,10,1);
SEE ALSO:
void gl_render_disk(short x, short y, short radius, void (*draw_hline)(short x1, short x2, short y));
genlib::render_disk
INPUT:
x = d4.w = x_center of the disk
y = d5.w = y_center of the disk
radius = d2.w = Radius of the disk
draw_hline = a2 = Horizontal line drawing function
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It renders a disk.
In fact, it will call the callback with the different values needed to draw the disk. It could, of course, doesn't draw a disk but memorize the coordinates. For example, all the previous functions call this function with a different hline function !
The Horizontal Line drawing function, in assembly, should have a prototype like:
INPUT:
d0.w = x1
d1.w = x2
d3.w = y
OUTPUT:DESTROYED REGISTERS:
EXAMPLES:
gl_render_disk(10,20,10,gl_draw_hline_light);
SEE ALSO:
void gl_set_spr_xy(short x, short y);
INPUT:
x = x coordinate of the sprite plane
y = y coordinate of the sprite plane
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It sets the coordinates of the sprite plane.
In asm, you can use instead :
move.w x,genlib::sprite_scr_x
move.w y,genlib::sprite_scr_y
EXAMPLES:
See gl_put_sprite_16 example
SEE ALSO:
void gl_set_spr_tile(SPRITE_16 *adr);
INPUT:
adr = address of the array of tiles.
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It sets the address of the tiles table.
In asm, you can use instead :
move.l adr,genlib::sprite_tile_adr
EXAMPLES:
See gl_put_sprite_16 example
SEE ALSO:
There are some additionnal MACROS which are defined in genlib.h.
divu32 A,B,ds1,ds2
(divs32 A,B,ds1,ds2)
INPUT:
ds1 = Temporary register (Destroyed)
ds2 = Temporary register (Destroyed)
A = a data register (32 bits)
B = a data register or an immediate value (16 bits)
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It divides a 32 bits unsigned (signed) number by 16 bits unsigned (signed) number with a 32 bits unsigned (signed) quotient.
A = A / B
EXAMPLES:
move.l #$Fe120019,d0
divu32 d0,#80,d2,d3 ; d0.l = d0.l / d1.w
SEE ALSO:
fload : Load a fraction.
fadd : Add two fixed numbers
fsub : Sub two fixed numbers
fmulu ; Mul two unsigned fixed numbers
fmuls : Mul two signed fixed numbers
fdivu : Div two unsigned fixed numbers
fdivs : Div two signed fixed numbers
INPUT:
f??? src,dest
src = Source 1 data register
dest = Source 2 and destination data register
fdivu src,dest,tmp1,tmp2
tmp1 = Temporary register (Destroyed)
tmp2 = Temporary register (Destroyed)
fload A,B,ds => ds = A / B
OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
They are usefull fixed functions.
Warning : mul & div assume that the number are 0.b | ?.b | ?.b | 0.b
since divu & mulu accept only word operandes
EXAMPLES:
fload 2,3,d1
fload 1584,145,d2
fload 1584,14547,d3
fadd d2,d1
fmuls d3,d1
fadd d2,d1
fdivs d2,d1
SEE ALSO:
Theses functions aren't very usefull... I let them only for compatibility reasons.
void gl_exg_gray(void);
genlib::exg_gray
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
Exchange dark-grey and bright-grey.
Warning : Calling set_dscreen_int disable it.
EXAMPLES:SEE ALSO:
genlib::use_int1
INPUT:
A6 -> Adresse of the function
D0-D7/A0-A5 : same as the called function.
Stack : same as the called function.
OUTPUT:
same as function (even a6 !)
DESTROYED REGISTERS:DESCRIPTION:
Call a function and restore the auto-int 1 during this call.
I don't know how to declare for Ti-gcc so you can't use this
function. But you can use instead :
asm("move.w #$000,%d0 \n trap #1");
idle_loop();
asm("move.w #$300,%d0 \n trap #1");
Even in asm you can do like it...
EXAMPLES:SEE ALSO:
genlib::put_sprite_16_last_flip
INPUT:OUTPUT:DESTROYED REGISTERS:DESCRIPTION:
It puts the last flipped sprite at D0.w,D1.w of Sprite-Tile-Table on the sprite_plane.
EXAMPLES:SEE ALSO:
Genlib extensions
There are several extensions of Genlib. The first one and the more important one is GenClib. It is an asm library which provides an efficiency interface between your C program and genlib. Since Genlib uses the register convention for passsing the arguments and the C uses the stack convention for that, I need a library to call Genlib under Tigcc. Nevertheless you could call Genlib without GenClib using the macros (With prefix '_gl_' instead of 'gl_'). But it could create some strange bugs. So don't use the macros in the developement part of your program !
The other one is GenAlib. It is a library which provides efficiency functions for allocating /freeing memory without using Ti-Os functions. It is really perfect for creating lists or trees.
There are two other extensions in developement : GenNlib and GenBlib. The first one is an interface for using Genlib under nostub programs. The second one is an interface for using genlib under Ti-Basic programs. Both of them are still under developement.
Bench
All the tests have been done on a Ti-92+ HW1 with new batteries (alcaline), and with the version 0.99.10 of genlib.
Function | Freq
put_sprite_16 : 3018 (if x%16 = 08)
: 3126 (if x%16 = 10)
: 3290 (if x%16 = 01)
: 5333 (if x%16 = 00)
put_big_sprite : 2500 (16x16)
: 800 (32x32)
: 35 (240x128)
update_vscreen_16 : 105
put_plane : 60
put_plane_89 : 115
put_fgrd_plane : 41
put_fgrd_plane_89 : 77
draw_line : 1648 (20x10 2x100
: 563 (0x0 240x128)
draw_clipped_line : 545 (0x0 240x128)
: 543 (-240,-128,480,256)
: 733 (-100,-20,300,200)
draw_circle : 300 (R=30)
put_pixel : 31603
cls : 535
put_large_string : 3184 (14 chars)
put_medium_string : 1192 (14 chars)
put_small_string : 1545 (14 chars)
copy_window : 190
History
v0.99.00 (20 July 1999)
1st public release.
v0.99.09 (23 November 1999)
Hardware v2.00 compatible: use the file 'genlibh2' instead of 'genlib' !
Add Put string routines
Optimisation
Fix some bugs.
Add update_roll_plane_v16
????
v0.99.10 (15 december 1999)
Optimisation of the hardware 2 version.
Add the Ti-92 + HW2 version
Add the genlib::internal_timer
Add gentimer
Port to DoorsII (But you need to recompile the examples).
Optimize a lot put_big_sprite when there is clipping !!!!
Fix a bug in genface & Optimize this routine.
Optimize the cls routine.
Add 'genlib::set_screen_int' function.
Fix a very bad bug ! (VICTORY !)
Merge 'genlibh2' and 'genlib' to 'genlib'
Add genlib::hardware
v0.99.15 (13 may 2000)
Optimize the logique of the code.
Add 'genlib::change_update'
Add 'genlib::restore_update'
Add 'genlib::put_plane_dhz_trpt_plane'
Add 'genlib::put_plane_dhz_trpt_plane_89'
Add 'genlib::init_screen'
Start to work about porting some routines to black and white.
Optimize and fix bugs in 'genlib::draw_face' : Clipping now !
CHANGE THE PARAMETERS OF GENLIB::DRAW_FACE !!!!
Optimisation of genlib::internal_timer in case of Hardware 2
(Auto-choose the best value (?) for your calc)
Fix a stupid big in put_pixel ! :(
Optimize 'update_vscreens' functions.
Fix a stupid but crash bug in put_big_sprite when left clipping.
Optimize 'put_big_sprite'
Improve grayscale quality on Hardware 1 & 2 !!!! Thanks, Olivier :)
Create the include files for Ti-Gcc :) but still bugged :(
Add 'genlib::clear_window'
Optimize "Put_plane_???" routines.
Fix a bug.
Add 'genlib::draw_circle'
Add 'genlib::draw_clipped_circle'
Change 'genlib::put_small_string' and 'genlib::put_medium_string'
so that you shouldn't use a 8x x coordinate.
Fix bugs in 'put_dhz_plane(_89)' & 'put_dhz_trpt_planz(_89)'.
Add 'genlib::clip_line'
Add 'genlib::draw_line'
Add 'genlib::draw_clipped_line'
v0.99.17 (30 october 2000)
Correct some errors in the doc (init_plane & draw_circle)
Fix a bug in draw_c_face
Add set_filter function (Try it, it is quite amazing !)
Fix a bug : If you use your cable during a game which doesn't use this feature, it crashes...
Add sinus/cosinus tables !!!
Fix a bug in line clipping !
Optimize genlib::copy_window (+15%)
Optimize genlib::put_large_string (+01%)
Optimize genlib::put_sprite_16 (+07%)
Fix a bug in genlib::put_sprite_16 :(((
Optimize genlib::put_sprite_16_flip_v (+06%)
Optimize genlib::put_sprite_16_flip_hv (+05%)
Optimize genlib::put_sprite_16_flip_h (+06%)
Optimize genlib::put_big_sprite_flip_v (+05%)
Optimize genlib::put_big_sprite_flip_hv (+05%)
Optimize genlib::put_big_sprite_flip_h (+05%)
Add set_callback_update & free_callback_update !!!!!!
Add update_max_vscreen ! You can use now 1024 tiles for a plane with H/V flipping !
Change put_big_sprite so that you have a white area all around the sprite !
Even it is slower, I think it is really better.
v0.99.19:
Fix the As92 Header file.
Create GenClib, the C Genlib lib
Update the gray routines for HW2
Add draw_bwhline_b
Add draw_bwhline_w
Add draw_hline_w
Add draw_hline_lg
Add draw_hline_dg
Add draw_hline_b
Add render_triangle
Note: Render means that the function needs a call-back function !
Optimize a lot draw_c_face and draw_c_clipped_face
Fix some bugs in the gray routines.
Add fill_screen
Add draw_disk
Add draw_clipped_disk
Add render_disk
Optimize (size + speed) clip_a_line
Add draw_hline_light
Add the link section in gentut.txt
Fix a bug in read_joypad on ti-92 (Thx to Dark Angel & Squale92)
Add create_bgs_string
Fix the bug of small/medium string (x < 6)
Update the doc.
Add Palette routine in update_max_vscreen
Add pal_sprite_16
Fix a bug in cosinus table
Add genlib::frame_timer
Add genlib::draw_hline_shadow
Add genlib::version
Rewrite the documentation in HTML.
Change the black mask in set_filter. It works fine, now.
Update the Bigsprites routine :
+ The mask is a little smaller.
+ When clipping, there is the mask.
Add genlib::put_mask_spr16
Add genlib::put_mask_spr16_flip_h
Add genlib::put_mask_spr16_flip_v
Add genlib::put_mask_spr16_flip_hv
ToDo: + Rotation routines (40% completed)
+ Fast zoom routines (80% completed)
+ Mode 7 routine (10% completed)
Staff
This documentation was written by Patrick Pelissier
(a.k.a. PpHd).
Genlib for Ti-89, Ti-92 and Ti-92+ is (c) 1999-2000-2001 Time To Team. Don't mix with Genlib for microship.
If you want to mail us, please prefer French, then English and finally Spanish. We don't understand any other languages.
Main code : Patrick Pélissier
Additionnal code:Olivier Certner
If you need help, please use the TIGCC Programming Message Board (English speakers)
or the TI-Fr Programming Message Board. (French speakers).
To get the latest release of Genlib, please go to Time To Team home page
Thanks
David Ellsworth
Patrick Davidson
Julien Muchembled
Jimmy Mardell
Johan Eilert
FlashZ & Dark Angel for having done all the tests on HW2