Next: , Previous: (dir), Up: (dir)

GENLIB



Next: , Previous: Top, Up: Top

Introduction to GENLIB

Description

GENLIB is an asm dynamic (kernel based) graph 4-gray tiles-oriented library for TI-92, TI-92+, Ti-89, V200 and Titanium compatible with C and ASM. It works on all known AMS and hardware (including PedroM). It is mainly for 2D-games which looks like the games on the famous snes and genesis. There are a lot of functions. Most of them are very fast. Of course, it is possible to do better functions (Don't hesitate to contribute ). You don't need to use graphlib, gray4lib or tigcclib for using the 4 levels of gray.

In order to work properly in C, two static libraries have been created (genlib.a and gennlib.a): they are designated to work in C, and not in ASM.

This library is free for use and distribution, but not open-source (It is not a free software). I do not accept responsibility for any effects, adverse or otherwise, that this code may have on you, your computer, your sanity, your dog, and anything else that you can think of. Use it at your own risk.

You will need at least TIGCC v0.94 beta 22 (http://tigcc.ticalc.org/ to compile a C program with GenLib.

What are the main features of GENLIB?

How to use this Manual

Everyone should read GENLIB Basics. If you need to install the library yourself, you need to read Installing GENLIB, too.

The rest of the manual can be used for later reference, although it is probably a good idea to glance through it.


Next: , Previous: Introduction to GENLIB, Up: Top

1 Installing GENLIB

1.1 Installing GENLIB on calculators.

GENLIB is a kernel based library so to use it you must place it in the SYSTEM folder of your kernel (See the documentation of the kernel extender for more information about it). By Kernel, we mean an extended Shared Linker, providing midleware abilities.

To install GENLIB in your calculator, you must send genlib.89z (for ti-89 or Titanium) or genlib.9xz (for ti-92+), genlib.92p (for ti-92) or genlib.v2z (for V200) to your calculator. Please see GraphLink or Ticonnect documentation for more information about sending files to your calculator. Then move GENLIB to your SYSTEM folder (In the VAR-LINK menu, open the FILE menu and select MOVE TO ANOTHER FOLDER). Usually the SYSTEM folder is the MAIN folder. Finally you should archive genlib too (In the VAR-LINK menu, open the FILE menu and select ARCHIVE VARIABLE).

Modern Kernels (like PreOS) already provide GENLIB, so you don't need to install it by yourself.

1.2 Installing GENLIB for asm programmers.

To use GENLIB in assembly programs, you have to copy 'include/asm/genlib.h' from the GENLIB archive to your include-assembly directory, which is $TIGCC$/include/asm if you use TIGCC. To use the GENLIB functions in your program, just add :

include genlib.h

in the include-section of your program.

You can't use GENLIB in assembler and in nostub directly.

1.3 Installing GENLIB for C programmers.

To use genlib in your C program in kernel or nostub mode, you have to copy 'include/c/genlib.h' from the GENLIB archive to the C-include directory ($TIGCC$/include/c) and 'tigcc/genlib.a', 'tigcc/gennlib.a' into the TIGCC lib directory ($TIGCC$/lib). To use GENLIB functions, just add the following line:

      #include <genlib.h>

to your source code.

Another change is that you can not define SAVE_SCREEN and NO_EXIT_SUPPORT (Even in nostub mode, Genlib will save the screen and in nostub mode, it needs the exit function so that it exists properly). You don't need to include tigcclib.h by yourself.

You can also copy the files genlib.a, gennlib.a and genlib.h into the directory where the rest of your sources are.

If you want a kernel program, if you are using the command line, compile your project (in this case gen_first.c):

      tigcc -O2 -fomit-frame-pointer -Wall -W gen_first.c genlib.a

If you are using the IDE add genlib.a to the archive file folder of your project.

If you want a nostub program, if you are using the command line, compile your project (in this case gen_first.c):

      tigcc -O2 -fomit-frame-pointer -Wall -W gen_first.c gennlib.a

If you are using the IDE add gennlib.a to the archive file folder of your project. Do not forget to add gennlib.a in your project! Even if you want to create a nostub version of your program, it needs the dynamic version of GENLIB.

Remember that Kernel Programs are more compatible to new calculator and new AMS: I don't recommend creating nostub programs with genlib. Do it at your own risk.

1.4 Getting the Latest Version of GENLIB

The latest version of GENLIB is available from http://www.timetoteam.fr.st/, or from http://www.ticalc.org/.


Next: , Previous: Installing GENLIB, Up: Top

2 Reporting Bugs

If you think you have found a bug in GENLIB, first have a look on the Time To Team web page http://www.timetoteam.fr.st/: perhaps this bug is already known, in which case you may find there a workaround for it. Otherwise, please investigate and report it. We have made this library available to you, and it is not to ask too much from you, to ask you to report the bugs that you find.

There are a few things you should think about when you put your bug report together.

You have to send us a test case that makes it possible for us to reproduce the bug. Include instructions on how to run the test case.

You also have to explain what is wrong; if you get a crash, or if the results printed are incorrect and in that case, in what way.

Please include compiler version information in your bug report.

If your bug report is good, we will do our best to help you to get a corrected version of the library; if the bug report is poor, we won't do anything about it (aside of chiding you to send better bug reports).

Send your bug report to: `ppelissi@caramail.com'.

If you think something in this manual is unclear, or downright incorrect, or if the language needs to be improved, please send a note to the same address.


Next: , Previous: Reporting Bugs, Up: Top

3 GENLIB Basics

All declarations needed to use GENLIB are collected in the include file genlib.h. It is the same name between both C and ASM, but it is not the same file. See the installation section for more information. You should include that file in any program using the GENLIB library.

3.1 Types and structures

3.1.1 Screen

A Screen is one Black & White screen of 240x128 pixels. The standard LCD_MEM is one Screen. It can be seen as the Video Memory. Technically, a Screen is an array of SCREEN_SIZE unsigned char.

3.1.2 DScreen

A DScreen is one GRAY4 screen of 240x128 pixels. It is the main target of the graph functions of GENLIB. It can display up to 4 levels of gray, which is the optimum number of level of grays you can display on theses calculators. Technically, a DScreen is an array of DSCREEN_SIZE unsigned char.

In asm, if A0 is the address of the DScreen, 0(A0) is the dark screen and SCREEN_SIZE(a0) is the light one.

In C you can use the macros DARK_SCREEN(dscr) and LIGHT_SCREEN(dscr) to get a SCREEN reference.

See other documentation about how to display in level of grays on TI-calculators for more information (http://tigcc.ticalc.org/doc/gray.html#GrayOn).

In GENLIB, there are at least two DScreen:

3.1.3 SPRITE_16 (or Spr16)

It is a sprite 16x16 in 4 levels of gray. It is a format of sprites compatible with 'SprMaker' by Jimmy Mardell. The C description is typedef unsigned short SPRITE_16[16][2]. Here is an 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 1, 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

3.1.4 Spr8

It is the same format for 8x8 sprites: 8 rows of two bitplanes of one byte only.

3.1.5 Bgs (or Big Sprites)

A BGS, or Big Sprite, is a sprite of variable size (from 16 columns x 1 rows to 240 columns x 128 rows pixels) in 4 level of gray. The mask is calculated at real-time by enlarging a few the sprite so that it can be drawn on a complicated background without losing its visibility. It is just like if a white line encapsulated the sprite. The white color is transparent.

The format is like this:

     dc.b ROW_NUMBER, WORD_COL_NUMBER
     dc.w DATA1_DARK_GRAY, DATA1_LIGHT_GRAY   ; 16 pixels in gray
     dc.w DATA2_DARK_GRAY, DATA2_LIGHT_GRAY   ; 16 pixels in gray
     dc.w DATA3_DARK_GRAY, DATA3_LIGHT_GRAY   ; 16 pixels in gray
     dc.w ...

or in C:

     typedef struct {
     	char	Height; 		// In pixel
     	char	Weight; 		// In pixel /16 (in word)
     	short	Data[];                 // Data
     } BGS;

The first byte defines the number of rows of the BGS, the second byte defines the number of columns (divides by 16 pixel). Then it is a matrix of 2 words (the first word is the dark gray data, and the second one is the light gray data).

In assembly language, to print a ship of 32 x 8 pixels, you will do

     spr_0_0:
     	dc.b 8,2 ; 8 row and 16*2=32 columns
     	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, you will do:

     gl_put_big_sprite (100, -2, spr_0_0);

assuming that spr_0_0 has been defined elsewhere. See gl_put_big_sprite for more details.

3.1.6 MBgs (or Masked Big Sprites)

A MBGS, or masked big sprite, is a sprite of variable size (from 16 columns x 1 rows to 240 columns x 128 rows pixels) in 4 level of gray with an explicit mask.

The format is like this:

     dc.b ROW_NUMBER, WORD_COL_NUMBER
     dc.w DATA1_MASK,DATA1_DARK_GRAY, DATA1_LIGHT_GRAY   ; 16 pixels in gray
     dc.w DATA2_MASK,DATA2_DARK_GRAY, DATA2_LIGHT_GRAY   ; 16 pixels in gray
     dc.w DATA3_MASK,DATA3_DARK_GRAY, DATA3_LIGHT_GRAY   ; 16 pixels in gray
     dc.w ...

or in C:

     typedef struct {
     	char	Height; 		// In pixel
     	char	Weight; 		// In pixel /16 (in word)
     	short	Data[];                 // Data
     } MBGS;

The first byte defines the number of rows of the MBGS, the second byte defines the number of columns (divides by 16 pixel). Then it is a matrix of 3 words:

3.1.7 Plane

A plane is an association between an array of tiles and a matrix of index. It is the only solution to print very large images (4096x1024 pixels for example). It is useful for games which need a large background, larger than the screen size, in which the screen can be scrolled by down to one pixel. It is defined as:

     typedef struct {
      HANDLE		handle; 	// Handle of the plane (Useless, ok).
      unsigned short	size;		// Size of a line in the matrix
      void  	        *table;		// Matrix of index
      void		*tile;		// Tile-Array
      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;

The TILE array could be an array of Spr16 or Spr8. Most of the games use an array of Spr16.

The matrix of index could be:

GENLIB doesn't know the real type of a Plane. It is your responsibility to call the right functions.

3.1.8 VScreen

It is the Virtual screen of a Plane. It is used internally to go faster for putting the Plane on the current DScreen. The VScreen won't be updated if the position of the Plane hasn't moved too much. It you want to update the VScreen anyway, you must call the gl_refresh_plane function (For tiles animation, for example). You mustn't use it by yourself even if you can.

3.1.9 DHZ Table

It is an array of 128 signed char (= size of the screen ). Each byte represents an horizontal (individual) shift, in respect to the current Plane coordinates. So each line of the plane can have a different horizontal position. Very useful to do wonderful special effects. It is only used with gl_put_dhz_plane functions. The valid range for each element is from -8 to 8.

3.1.10 HDZ Table

It is an array of 128 signed short. Each word represents a vertical shift, even if it is not exact. When you call gl_put_dhz_plane function, GENLIB adds, after the drawing of a horizontal line, this offset to the current VScreen pointer.. If this offset equals the size of a VScreen line, you can display many times the same horizontal line, or skip one (making a Vertical scaling). But it is not so limited. You can do even better (and harder) effects.

It must be 2x aligned, otherwise you get an address error.

The way theses tables work is not really easy to understand, that's why I strongly recommend you to look at the given examples.

3.1.11 Palette

It is the Genlib palette, used by the TILE_INDEX Plane index. It allows you to filter your spr16 before it is drawn, by transforming, at real time, your sprite. The palette is (B: Black, D: Dark gray, L: Light Gray, W: White gray):

Default B D L W
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

3.1.12 Joypad

It is a virtual joypad. It is used to avoid the problems of different key mapping between Ti-89, Ti-92 and V200. To test if Left is pressed, you will just tested the value of left_key:

     // Extract from genlib.h
     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;
     
      JOYPAD j = gl_read_joypad();
      if (j.left_key == 0) {
     	// Move to left
     	//...
      }

In asm, you will do:

     ; Extract from genlib.h
     ;         Joypad structure :		TI92 | TI89 | V200
     ;			exit_key	ESC  | ESC  | ESC
     ;			mode_key	APPS | APPS | APPS
     ;			plus_key	+    |  +   |  +
     ;			minus_key	-    |  -   |  -
     ;			left_key
     ;			up_key
     ;			right_key
     ;			down_key
     ;			ka_key		 F1 |  2nd  |   Q
     ;			kb_key		 F2 | Diamd |   A
     ;			kc_key		 F3 | Home  |   Z
     ;			kd_key		 F4 |   X   | Diamond
     ;			ke_key		 F5 | Shift |   W
     ;			kf_key		 F6 | Alpha |   S
     ;			kg_key		 F7 | Mode  |   X
     ;			kh_key		 F8 |   Y   |  2nd
     
     	jsr	genlib::read_joypad
     	btst.l	#left_key,d0
     	bne.s	\no_left
     	...
     	\no_left

3.1.13 Keyboard

It is the matrix of the keys of the calculators. You should know what calculator is before reading the bit matrix.

Here are the key matrix of the Ti-92/V200:

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
Row 0 down right up left hand shift diamond 2nd
Row 1 3 2 1 F8 W S Z unused
Row 2 6 5 4 F3 E D X unused
Row 3 9 8 7 F7 R F C STO
Row 4 , ) ( F2 T G V space
Row 5 TAN COS SIN F6 Y H B /
Row 6 P ENTER2 LN F1 U J N ^
Row 7 * APPS CLEAR F5 I K M =
Row 8 unused ESC MODE + O L theta backspc
Row 9 (-) . 0 F4 Q A ENTER1 -

Here are the key matrix of the Ti-89/Titanium:

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
Row 0 Alpha Diam Shift 2nd Right Down Left Up
Row 1 F5 Clear ^ / * - + Enter
Row 2 F4 Backspc T , 9 6 3 (-)
Row 3 F3 Catalog Z ) 8 5 2 .
Row 4 F2 Mode ( ( 7 4 1 0
Row 5 F1 Home X = | EE STO Apps
Row 6 ESC

To test a key in assembly, you should do (assuming a0 is a pointer to a KEYBOARD):

     btst.b #col,row(a0)
     bne.s \no_pressed

In C, assuming Tab is a pointer to a KEYBOARD):

     if (Tab[row] & ~(1<<col) == 0)

3.1.14 Link data

It is the structure to control the genlib link. You should never write to it. If you want to update this structure, you should call set_link instead.

     typedef struct {
     	 unsigned short	link_flag;            // Master of Slave
     	 unsigned char	*buffer_recpt;        // Ptr to received buffer
     	 unsigned char	*buffer_send;         // Ptr to sent buffer
     	 unsigned short	buffer_recpt_size;    // Size of recieved buffer
     	 unsigned short	buffer_send_size;     // Size of send buffer
     	 unsigned char	buffer_recpt_flag;    // Status of received buffer
     	 unsigned char	buffer_send_flag;     // Status of send buffer
     	 unsigned short	buffer_recpt_offset;  // Internal
     	 unsigned short	buffer_send_offset;   // Internal
     } LINK_DATA;

Here is an example:

     	if (gl_synchronize())
     		printf("There is a problem of connection...\n" ;
     	else	if (gl_link_data.link_flag == MASTER)
     		printf("I am the master.\n");
     	else	printf("I am the slave.\n");

The corresponding EQU and example for asm programmers is:

     	; From GENLIB.h
     	;link_flag		:  = MASTER or SLAVE
     	;buffer_recpt_adr	: Address of the receiev buffer
     	;buffer_send_adr	: Address 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.
     	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

3.1.15 Point

It is a 2D point:

     typedef struct {
      short x;
      short y;
     } POINT;

You can use xe and ye in asm to access the sub arguments of a point.

3.2 Global variables

— Global C Variable: unsigned long gl_timer
— Global ASM Variable: long: genlib::timer

It is the internal timer of genlib (a volatile unsigned long). You can read and write this variable. It is incremented each time the Genlib interruption (AI5) has finished to display one screen. This timer is around 90 Hz. It is independent of the hardware of the calculators (or overclocked calculator). It is useful to synchronize your code so that you have a constant frame rate in your program. It is also useful 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 consuming...

To do a 30 Hz waiting, you could do:

          while (gl_timer <= 2);
          gl_timer = 0;
     
— Global C Variable: unsigned short gl_frame_timer
— Global ASM Variable: word: genlib::frame_timer

It is the 2nd internal timer of genlib. It is incremented each time Genlib interruption (AI5) has finished to display one complete DScreen. This timer is around 30 Hz and it is independent of the hardware of the calculators (or overclocked calculator). It is useful to synchronize your code so that you have a constant frame rate in your program. It is better than gl_timer because you synchronize your code with the DScreen and not the Screen swapping.

To do a 30 Hz waiting, you could do:

                  while (!gl_frame_timer);
                  gl_frame_timer = 0;
     
— Global ASM Variable: long genlib::sprite_tile_adr
— Global ASM Variable: word: genlib::sprite_scr_x
— Global ASM Variable: word: genlib::sprite_scr_y

sprite_tile_adr is the address of the SPRITE_16 array used by gl_put_sprite_16 functions. sprite_scr_x and sprite_scr_y are the coordinates X,Y of the virtual sprite-plane. It is used by all sprite functions except fast-sprite ones.

You cannot access theses variables in C, so you should use instead the functions gl_set_spr_xy and gl_set_spr_tile.

— Global C Constant: SCREEN * gl_window
— Global ASM Constant: long: genlib::window

It is the address of the genlib window. What it is the window? It is a screen that you could use for what you want. For Hardware 1 calculators or the Ti-92 I/II, it is in fact the LCD_MEM. But on Hardware 2, the LCD_MEM is used for swapping the screens. So GENLIB allocates a handle to replace the used 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 enough memory to work). It is the only difference between the 2 calculators, and it explains some differences between the 2 calculators when you swap from gray4 mode to gray2 mode. It may change. It is useful to print extra-information like score, life, coins, and them copy quickly to the DScreen without spending a lot of time using DrawStrXY.

— Global C Variable: LINK_DATA gl_link_data
— Global ASM Variable: LINK_DATA: genlib::link_data

It is the internal link_data structure of genlib. There is only one available. You could not create another one. But under kernels like Prosit which provides multi-tasking, each genlib program should have a different link_data structures (This feature is currently not available).

See LINK_DATA for more information.

— Global C Constant: short gl_hardware
— Global ASM Constant: word: genlib::hardware

It is the number of the current hardware. The different values are:

There could be another values when new hardware come out.

— Global C Constant: const char [256] gl_flipping_tab
— Global ASM Constant: char tab: genlib::flipping_tab

It is the internal flipping tab of genlib. It will reverse the order of the bits of the byte (that's why its size is 256). It is also called 'Horizontal Mirror'. For example:

          gl_flipping_tab[%01110001] = %10001110
     

(% is a Tigcc extension)

— Global C Constant: const signed char [256] gl_sin
— Global C Constant: const signed char [256] gl_cos
— Global ASM Constant: char tab: genlib::sin
— Global ASM Constant: char tab: genlib::cos

Theses tables are precomputed sinus / cosines 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.

If you want to calculate B = A * sin(i), you will do in C:

          B = (A * gl_sin[i]) >> 7
     

And in 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
     
— Global C Constant: const char [] gl_version
— Global ASM Constant: string genlib::version

It is the internal version string of Genlib. It looks like : "GenLib v" + VERSION +"."+ SUB_VERSION such as "Genlib v0.99.20b".


Next: , Previous: GENLIB Basics, Up: Top

4 GENLIB Example

The best way to understand how to use GenLib is to look at the examples. You can have a look at all the examples included in the archive. They are in general well commented. But let's see the initialization of a genlib program. It could be complicated since you have to do more stuff than with other graph libraries. You have to initialize genlib, allocate DScreens and set the Working and Displayed DScreen.

4.1 ASM

An assembly (a68k) genlib program looks like:

     	include tios.h		; Ti-os header file
     
     	xdef	_main           ; Export Entry Point
     	xdef	_comment        ; Export Comment
     
     	xdef	_ti92plus       ; Target TI-92+
     	xdef	_ti89           ; Target TI-89
     	xdef	_v200           ; Target V200
     	xdef    _ti89ti         ; Target Titanium
     
     	include "genlib.h" 	; Genlib Header files.
     
     _main:				; Program entry point
     	jsr	genlib::init   	; Initialization of genlib
     
     	; Allocate a DScreen on the stack
     	genlib::PUSH_DSCREEN d0                 ;
     	move.l	d0,DScr1			; Save it.
     	jsr	genlib::set_dscreen_function	; D0.l = DScreen's addr
     	jsr	genlib::set_dscreen_int		; D0.l = DScreen's addr
     	jsr	genlib::cls			; Clear current DScreen
     
     	; Alloc another DScreen (Heap)
     	jsr	genlib::init_dscreen
     	tst.w	d0
     	beq.s	\quit
     	jsr	genlib::push_hd		; Push the handle
     	move.l	a0,DScr2		; Save the other DScreen
     
     	bsr	lets_start		; Main Function
     
     	jsr	genlib::free_hd		; Free all the allocated handles
     
     \quit	genlib::POP_DSCREEN		; Pop DScreen
     	jsr	tios::PortRestore	; If we have called PortSet (Ti-92+ / Ti-89 only !)
     	jmp	genlib::quit		; End of program
     
     	; This function will exchange the buffer.
     SwapBuffer:
     	move.w	ts(pc),d1		; Read ts
     	move.l	DScr1(pc,d1.w),d0	; Read a screen
     	jsr	genlib::set_dscreen_int	; Set the interrupt to this DScreen
     	eor.w	#4,d1			; Next screen
     	move.w	d1,ts			; Save ts
     	clr.l	genlib::timer		; Clear gl_timer
     	move.l	DScr2(PC,d1.w),d0	; Read the other screen
     	jmp	genlib::set_dscreen_function	; Set the functions to this DScreen
     
     DScr1	dc.l	0		; DScreen 1
     DScr2	dc.l	0		; DScreen 2
     ts	dc.w	0		; Temps
     
     	; This function will allow a constant Fps to the program (15Hz)
     Wait15:
     	cmp.w	#1,genlib::frame_timer
     	bls.s	Wait15
     	clr.w	genlib::frame_timer
     	rts
     
     	; This function will allow a constant Fps to the program (30Hz)
     Wait30:
     	tst.w	genlib::frame_timer
     	beq.s	Wait30
     	clr.w	genlib::frame_timer
     	rts
     
     	; This function waits until you cannot draw without problems.
     	; You should add it before your first graphic function.
     Ready:	tst.l	genlib::timer
     	beq.s	Ready
     	rts
     
     lets_start:
     	; Main program
     	; ....
     
     	rts
     
     _comment	dc.b "GenLib example",0
     	end

It is the basic example. All the other assembly examples will have only a different 'lets_start' function.

4.2 C

A C example is even shorter:

     #include <genlib.h>
     // The entry point is gl_main.
     void	gl_main()
     {
     	...
     }

That's all! It is far easier in C since you have the ability to use gl_main, instead of doing the job yourself! You can define USE_KERNEL to compile in kernel format (shorter and more compatible with newer calculator since all the hacks are concentrated in the kernel). If you don't define the target, genlib will compile for all the calculators. You mustn't define SAVE_SCREEN of NO_EXIT_SUPPORT! And you don't need to include tigcclib since genlib.h do it for you.


Next: , Previous: GENLIB Example, Up: Top

5 GENLIB Interface

The C programmers shoudn't care about registers, ie section 'Input', 'Output' and 'Destroy'. They are provided only for ASM programmers. You should read all the interface of a section, since the functions are often inter-dependent.


Next: , Previous: GENLIB Interface, Up: GENLIB Interface

5.1 Initialization Functions

— Function C: void gl_init (void)
— Function ASM: - genlib::init
`Input'
nothing
`Output'
nothing
`Destroy'
nothing
`Description'
It initializes GENLIB by setting some auto-ints and global variables. It sets the processor timer and synchronizes the auto-ints with the screen. You must call this function before any other GENLIB's functions. It sets the priority level to 2 in order to disable auto-int 1 and 2. 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.
`Example'
See GENLIB Example.

— Function C: void gl_quit (void)
— Function ASM: - genlib::quit
`Input'
nothing
`Output'
nothing
`Destroy'
nothing
`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 if needed.
`Example'
See GENLIB Example.


Next: , Previous: Initialization Functions, Up: GENLIB Interface

5.2 Handle Functions

— Function C: void gl_push_hd (HANDLE Hd)
— Function ASM: - genlib::push_hd
`Input'
d0.w = handle to push
`Output'
d1.b = 0 if no error else there is a stack overflow.
`Destroy'
d1
`Description'
Push the handle Hd on the Handle Stack. The current maximum is currently 20 Handles. If you think it is too few, mail us. Under Tigcc, you can't test an overflow but it doesn't matter a lot.

— Function C: HANDLE gl_pop_hd (void)
— Function ASM: - genlib::pop_hd
`Input'
nothing
`Output'
  • d0.w = the returned handle.
  • d1.b = 0 if no error else there is a stack underflow.

`Destroy'
d0-d1
`Description'
Returns and pops the current handle on the Handle Stack. You could have an error if there is no Handle on the stack.
`Example'
               void	toto() {
               	HANDLE h;
               	DSCREEN *d;
               	gl_init_dscreen(&d, &h);
               	gl_push_hd(h);
               	// ... Do some stuff
               	gl_pop_hd(h);
               	HeapFree(h);
               }
          

— Function C: void gl_free_hd (void)
— Function ASM: - genlib::free_hd
`Input'
nothing
`Output'
nothing
`Destroy'
nothing
`Description'
Free all handles which are on the Handle Stack in reverse order (First In, Last Out). In general, you have to call it just before gl_quit.
`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();  // Free the handles of DScreen d1, d2 and the plane p
               }
          


Next: , Previous: Handle Functions, Up: GENLIB Interface

5.3 Screen Functions

After calling to gl_init, no DScreen are available yet. You have to create them (NOTE: gl_main does it for you).


Next: , Previous: (dir), Up: Screen Functions

5.3.1 Alloc Screen

— Function C: void gl_init_screen (SCREEN **Scr, HANDLE *Hd)
— Function ASM: - genlib::init_screen
`Input'
nothing
`Output'
  • d0.w = Handle of the allocated Screen (or H_NULL).
  • a0.l = Address of the screen (aligned to a 8x address).

`Destroy'
d0-d2/a0-a1
`Description'
Init and allocate a new Screen on the heap. It is a buffer of 3848 bytes, and it is 8x aligned (Its address is divisible by 8). It saves in Hd the handle of the allocated block and in Scr the aligned pointer.
`Example'
See gl_init_dscreen example.

— Function C: void gl_init_dscreen (DSCREEN **DScr, HANDLE *Hd)
— Function ASM: - genlib::init_dscreen
`Input'
nothing
`Output'
  • d0.w = Handle of the allocated DScreen (or H_NULL).
  • a0.l = Address of the dscreen (aligned to a 8x address).

`Destroy'
d0-d2/a0-a1
`Description'
Init and allocate a new DScreen on the heap. It is a buffer of 7688 bytes, and it is 8x aligned (Its address is divisible by 8). It saves in Hd the handle of the allocated block and in DScr the aligned pointer.
`Example'
See GENLIB Example.

— Macro: ALLOC_DSCREEN (dscr)
`Input'
The DScreen address
`Description'
It allocs a DScreen on the stack. It looks like PUSH_DSCREEN but you can not use it with global variables. You can define it everywhere in your program.
`Example'
               void	_main() {
               	unsigned int i,j,k;
               	gl_init();
               	ALLOC_DSCREEN(dscr);
               	gl_set_dscreen_int(dscr);
               	gl_set_dscreen_function(dscr);
               	...
               	gl_quit();
               }
          

— Macro: PUSH_DSCREEN (dscr)
`Input'
The DScreen address
`Description'
It allocs a DScreen on the stack. You must use in only 2 ways:
  • If you use with a global variable, this macro should be the last instruction of the initialization part of your program, since it is a mix between a declaration and a calcul.
  • If you use it with a local variable, you could define is anywhere in the initialization part, but you should define the DScreen variable inside the macro. Look at the examples (or its definition in genlib.h).

`Example'
Global var:
               DSCREEN *dscr = NULL;
               void	_main()	{
               	unsigned int i,j,k;
               	HANDLE h;
               	PUSH_DSCREEN(dscr);
               
               	gl_init();
               	...
               	gl_quit();
               }
          

Local var:

               void	_main() {
               	unsigned int i,j,k;
               	HANDLE h;
               	PUSH_DSCREEN(DSCREEN *dscr);
               
               	gl_init();
               	...
               	gl_quit();
               }
          

— ASM Macro: genlib::PUSH_DSCREEN ds
`Input'
nothing
`Output'
ds = The address of the pushed DScreen.
`Destroy'
ds and SP
`Description'
It allocs a DScreen on the stack. You must use it like a PUSH instruction!
`Example'
See GENLIB Example.

— ASM Macro: genlib::POP_DSCREEN
`Input'
nothing
`Output'
nothing
`Destroy'
SP
`Description'
It pops the DScreen from the stack. You must use it like a POP instruction!
`Warning'
YOU CAN'T ALLOCATE MORE THAN ONE DScreen ON THE STACK!
`Example'
See GENLIB Example.

— ASM Macro: genlib::PUSH_SCREEN ds
`Input'
nothing
`Output'
ds = The address of the pushed Screen.
`Destroy'
ds and SP
`Description'
It allocs a Screen on the stack. You must use it like a PUSH instruction!
`Example'
See genlib::PUSH_DSCREEN example.

— ASM Macro: genlib::POP_SCREEN
`Input'
nothing
`Output'
nothing
`Destroy'
SP
`Description'
It pops the Screen from the stack. You must use it like a POP instruction!
`Warning'
YOU CAN'T ALLOCATE MORE THAN TWO Screen ON THE STACK!
`Example'
See genlib::POP_DSCREEN example.


Next: , Previous: Alloc Screen, Up: Screen Functions

5.3.2 Set Screen

— Function C: void gl_set_dscreen_int (DSCREEN *DScr)
— Function ASM: - genlib::set_dscreen_int
`Input'
d0.l = DScr = Address of the DScreen to print.
`Output'
nothing
`Destroy'
nothing
`Description'
Set the current Displayed DScreen. You should call this function at least one so that you can see something. Note that it doesn't displayed it directly, but instead it sets some global variables to tell GENLIB to display it when it could be done. That's why you need to call glaux_ready() to check if it has been done.
`Example'
See GENLIB Example.

— Function C: void gl_set_dscreen_function (DSCREEN *DScr)
— Function ASM: - genlib::set_dscreen_function
`Input'
d0.l = DScr = Address of the DScreen to set.
`Output'
nothing
`Destroy'
nothing
`Description'
Set the current Working DScreen (ie the current output for most graph functions). You must call this function before calling any Graph-functions.
`Warning'
If you forget to call this function, YOU WILL HAVE A CRASH WHEN YOU CALL ANY GRAPHS FUNCTIONS since they will write in an area they shouldn't.
`Example'
See GENLIB Example.

— Function C: void gl_set_screen_int (SCREEN *Scr1, SCREEN *Scr2, SCREEN *Scr3)
— Function ASM: - genlib::set_screen_int
`Input'
  • d0.l = Scr1 = Address of the first screen (The dark one)
  • d1.l = Scr2 = Address of the second screen (The invisible one)
  • d2.l = Scr3 = Address of the third screen (The light one)

`Output'
nothing
`Destroy'
nothing
`Description'
With this function, you can set what are the third screens of the grayscale interruption. To be compatible with the standard grayscale, you should have Scr1 == Scr2. On Hardware 2, the 2nd screen won't be displayed. The 2nd screen works only on Hardware 1, and its effect is quite strange (for more details, see the grayscale routine). This function works like gl_set_dscreen_int, and it sets only what the interruption have to display. LCD_MEM isn't a valid screen since it is used by the gray driver on HW2. gl_window is a valid Screen.
`Example'
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));
               }
          

— Function C: void gl_set_LCD_MEM (void)
— Function ASM: - genlib::set_LCD_MEM
`Input'
nothing
`Output'
nothing
`Destroy'
nothing
`Description'
It sets the interruptions so that it displays the LCD_MEM (Gray 2). The functions still work with the current Working DScreen! It is the real screen LCD_MEM, not the window. So you can have some differences between HW1 and HW2 (The screen may not be cleared on HW2).
`Example'
                     gl_set_LCD_MEM();
                     ScreenClear();
                     DrawStrXY(20,30,"Hello world !", 4);
          

`See also'
The tigcclib graph functions!

— Function C: void gl_set_window (void)
— Function ASM: - genlib::set_window
`Input'
nothing
`Output'
nothing
`Destroy'
nothing
`Description'
It sets the interruptions so that it displays the window (Gray 2). The functions still work with the current Working DScreen!
`Example'
                       gl_set_window();
                       gl_clear_window();
                       gl_put_medium_string(gl_window, 20, 30, "Hello word !");
          

`See also'
gl_window, gl_clear_window and PortSet.


Next: , Previous: Set Screen, Up: Screen Functions

5.3.3 Misc Functions about Screen

— Function C: DSCREEN *gl_get_dscreen (void)
— Function ASM: - genlib::get_dscreen
`Input'
nothing
`Output'
a0.l = The current working DScreen
`Destroy'
a0
`Description'
Get the current Working DScreen. It is the last value passed to set_dscreen_function.
`Example'
See gl_fill_screen one.
`See also'
gl_dscreen_function.

— Function C: void gl_cls (void)
— Function ASM: - genlib::cls
`Input'
nothing
`Output'
nothing
`Destroy'
nothing
`Description'
Clear the Working DScreen.
`Example'
See gl_fill_screen one.
`See also'
gl_dscreen_function.

— Function C: void gl_clear_window (void)
— Function ASM: - genlib::clear_window
`Input'
nothing
`Output'
nothing
`Destroy'
nothing
`Description'
Clear the Window.
`Example'
See gl_copy_window one.
`See also'
gl_window.

— Function C: void gl_copy_window (void)
— Function ASM: - genlib::copy_window
`Input'
nothing
`Output'
nothing
`Destroy'
nothing
`Description'
It copies the Window to the current Working DScreen. The Window is copied in the two Screens of the Working DScreen so that it appears in black. You can use this function after updating information (Score, life, items, ...) on the window with tios::DrawStrXY or gl_put_large_string. It may be more powerful, if you have only a few rectangle of information in the window, to copy them by yourself. Even this function is fast, it is faster to copy only what you need!
`Example'
This program will display a triangle and moves it. It will copy each frame the window to display the information:
               INT 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();
                glaux_swap ();
                glaux_synchro (1);
               }
          

`See also'
gl_window and all window functions.

— Function C: void gl_fill_screen (SCREEN *scr, long pattern)
— Function ASM: - genlib::fill_screen
`Input'
  • a0.l = scr = The screen to fill.
  • d0.l = pattern = The pattern

`Output'
nothing
`Destroy'
nothing
`Description'
Fill the screen with the pattern. The pattern could be '0' (White) or '-1' (Black) or something more complex.
`Example'
               gl_fill_screen(DARK_SCREEN(gl_get_dscreen()), 0xBBBBBBBB);
               gl_fill_screen(LIGHT_SCREEN(gl_get_dscreen()), 0x55555555);
          

`See also'
gl_cls.


Next: , Previous: Screen Functions, Up: GENLIB Interface

5.4 String Functions

— Function C: void gl_put_small_string (SCREEN *Screen, short x, short y, const char *String)
— Function ASM: - genlib::put_small_string
`Input'
  • a1.l = Screen = The output
  • d0.w = x
  • d1.w = y
  • a0.l = String = String to print.

`Output'
nothing
`Destroy'
nothing
`Description'
It draws all the characters of String at the specified absolute coordinates (x, y) with the small font. No clipping is done! It prints the string without erasing the background.
`Example'
               gl_put_small_string(gl_window, 20, 50, "Genlib is Good !");
          

— Function C: void gl_put_medium_string (SCREEN *Screen, short x, short y, const char *String)
— Function ASM: - genlib::put_medium_string
`Input'
  • a1.l = Screen = The output
  • d0.w = x
  • d1.w = y
  • a0.l = String = String to print.

`Output'
nothing
`Destroy'
nothing
`Description'
It draws all the characters of String at the specified absolute coordinates (x, y) with the medium font. No clipping is done! It prints the string without erasing the background.
`Example'
               gl_put_medium_string(gl_window, 20, 50, "Hello world!");
          

— Function C: void gl_put_large_string (SCREEN *Screen, short x, short y, const char *String)
— Function ASM: - genlib::put_large_string
`Input'
  • a1.l = Screen = The output
  • d0.w = x
  • d1.w = y
  • a0.l = String = String to print.

`Output'
nothing
`Destroy'
nothing
`Description'
It draws all the characters of String at the specified absolute coordinates (x, y) with the large font. No clipping is done! It works in a quite different way from the last 2 functions. It is because the length of a char in this font is exactly 8 pixels. So it could be 8x aligned to gain more speed, 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.
`Example'
               gl_put_large_string(gl_window, 20, 50, "Dummy world!");
          

— Function C: void gl_create_bgs_string (const char *string, BGS *bgs)
— Function ASM: - genlib::create_bgs_string
`Input'
  • a0.l = String = String to convert.
  • a1.l = Bgs = The BGS output

`Output'
nothing
`Destroy'
nothing
`Description'
It creates a big sprite which looks like the string using the Huge Font (It may change). It is quite useful 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 (floor function is not needed in C).
`Example'
               void	print_string(char *str, short x, short y) {
                char	buffer[2+(strlen(str)+1)/2)*8*4];
                gl_create_bgs_string(str, (BGS *) buffer);
                gl_put_big_sprite(x, y, (BGS *) buffer);
               }
          

`See also'
gl_put_big_sprite


Next: , Previous: String Functions, Up: GENLIB Interface

5.5 Sprite Functions

This library offers very powerful sprites routines for different formats. It is hard to slow down your program with theses functions but I think, with courage and loyalty, you will. Each format has been carefully studied to offer the best ratio speed/flexibility possible (Indeed, most TI graph libraries just copy GENLIB formats and ideas).

The origins (xorg, yorg) of the relative coordinates (x, y) are defined using gl_set_spr_xy or genlib::sprite_tile_x, genlib::sprite_tile_y. The absolute coordinates (xabs, yabs) of a sprite are defined as: xabs = x - xorg and yabs = y - yorg.


Next: , Previous: (dir), Up: Sprite Functions

5.5.1 Sprite 16x16 Functions

For the Sprite16 format, the White color is the transparent color (it isn't be displayed). The size of the sprite is 64 bytes: 16 columns * 16 rows in 4 colors (/8).

You should set before the address of the array of SPRITE_16 using gl_set_spr_tile or genlib::sprite_tile_adr.

— Function C: void gl_put_sprite_16 (short x, short y, unsigned short num)
— Function ASM: - genlib::put_sprite_16
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • d2.w = num = Index of sprite16 in SPRITE_16 array( 0<= num < 512).

`Output'
nothing
`Destroy'
nothing
`Description'
It puts the sprite in SPRITE_16 format, number num at x, y on the Working DScreen.
`Example'
               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() {
                unsigned long count;
                short	x,y;
                char	tmpstr[500];
               
                // Init Spr16 Functions
                gl_set_spr_xy(0,0);
                gl_set_spr_tile(&Sprite);
               
                // 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();
               }
          

`See also'
gl_set_spr_tile and gl_set_spr_xy.

— Function C: void gl_put_sprite_16_flip_h (short x, short y, unsigned short num)
— Function ASM: - genlib::put_sprite_16_flip_h
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • d2.w = num = Index of sprite16 in SPRITE_16 array ( 0<= num < 512).

`Output'
nothing
`Destroy'
nothing
`Description'
It works just like gl_put_sprite_16 function but with a horizontal flipping. It means that it is the horizontal mirror of the sprite which is printed.
`Example'
See gl_put_sprite_16 example.
`See also'
gl_set_spr_tile and gl_set_spr_xy.

— Function C: void gl_put_sprite_16_flip_v (short x, short y, unsigned short num)
— Function ASM: - genlib::put_sprite_16_flip_v
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • d2.w = num = Index of sprite16 in SPRITE_16 array ( 0<= num < 512).

`Output'
nothing
`Destroy'
nothing
`Description'
It works just like gl_put_sprite_16 function but with a vertical flipping. It means that it is the vertical mirror of the sprite which is printed.
`Example'
See gl_put_sprite_16 example.
`See also'
gl_set_spr_tile and gl_set_spr_xy.

— Function C: void gl_put_sprite_16_flip_hv (short x, short y, unsigned short num)
— Function ASM: - genlib::put_sprite_16_flip_hv
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • d2.w = num = Index of sprite16 in SPRITE_16 array ( 0<= num < 512).

`Output'
nothing
`Destroy'
nothing
`Description'
It works just like gl_put_sprite_16 function but with both horizontal and vertical flipping. It means that it is the horizontal-vertical mirror of the sprite which is printed.
`Example'
See gl_put_sprite_16 example.
`See also'
gl_set_spr_tile and gl_set_spr_xy.

— Function C: void gl_put_sprite_16_zoom (short x, short y, unsigned short num, FIXED Hscale, FIXED Vscale)
— Function ASM: - genlib::put_sprite_16_zoom
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • d2.w = num = Index of sprite16 in SPRITE_16 array ( 0<= num < 512).
  • d4.l = Hscale = 1.0 / Horizontal Scale Factor - fixed 16:16.
  • d5.l = Vscale = Vertical Scale Factor - fixed 16:16.

`Output'
nothing
`Destroy'
nothing
`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, Hscale = (65536 / n) and Vscale = (65536 * n).
`Example'
               	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'
gl_set_spr_tile and gl_set_spr_xy.


Next: , Previous: Spr16 Functions, Up: Sprite Functions

5.5.2 Tile 16x16 Functions

For the Tiles16 Functions, no color is transparent.

— Function C: void gl_put_tile_16 (short x, short y, unsigned short num)
— Function ASM: - genlib::put_tile_16
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • d2.w = num = Index of sprite16 in SPRITE_16 array( 0<= num < 512).

`Output'
nothing
`Destroy'
nothing
`Description'
It puts the sprite in SPRITE_16 format, number num at x, y on the Working DScreen as a tile (ie no transparency).
`Example'
See gl_put_sprite_16 example.
`See also'
gl_set_spr_tile, gl_set_spr_xy and gl_put_sprite_16.

— Function C: void gl_put_tile_16_flip_h (short x, short y, unsigned short num)
— Function ASM: - genlib::put_tile_16_flip_h
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • d2.w = num = Index of sprite16 in SPRITE_16 array ( 0<= num < 512).

`Output'
nothing
`Destroy'
nothing
`Description'
It works just like gl_put_tile_16 function but with a horizontal flipping. It means that it is the horizontal mirror of the sprite which is printed.
`Example'
See gl_put_sprite_16 example.
`See also'
gl_set_spr_tile, gl_set_spr_xy and gl_put_sprite_16.

— Function C: void gl_put_tile_16_flip_v (short x, short y, unsigned short num)
— Function ASM: - genlib::put_tile_16_flip_v
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • d2.w = num = Index of sprite16 in SPRITE_16 array ( 0<= num < 512).

`Output'
nothing
`Destroy'
nothing
`Description'
It works just like gl_put_tile_16 function but with a vertical flipping. It means that it is the vertical mirror of the sprite which is printed.
`Example'
See gl_put_tile_16 example.
`See also'
gl_set_spr_tile, gl_set_spr_xy and gl_put_sprite_16.

— Function C: void gl_put_tile_16_flip_hv (short x, short y, unsigned short num)
— Function ASM: - genlib::put_tile_16_flip_hv
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • d2.w = num = Index of sprite16 in SPRITE_16 array ( 0<= num < 512).

`Output'
nothing
`Destroy'
nothing
`Description'
It works just like gl_put_tile_16 function but with both horizontal and vertical flipping. It means that it is the horizontal-vertical mirror of the sprite which is printed.
`Example'
See gl_put_sprite_16 example.
`See also'
gl_set_spr_tile, gl_set_spr_xy and gl_put_sprite_16.

— Function C: void gl_pal_sprite_16 (unsigned short pal, unsigned short src, unsigned short dest)
— Function ASM: - genlib::pal_sprite_16
`Input'
  • d0.w = pal = Palette number (0..7)
  • d1.w = src = Index of source sprite in SPRITE_16 array ( 0<= num < 512).
  • d2.w = num = Index of destination sprite in SPRITE_16 array ( 0<= num < 512).

`Output'
nothing
`Destroy'
nothing
`Description'
It copies and transforms the SPRITE_16 from src to dest according to palette pal.
`Example'
               	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_update_vscreen_max16


Next: , Previous: Tiles16 Functions, Up: Sprite Functions

5.5.3 Sprite GB 16x16 Functions

For the Gb16 Functions, the Light Gray is the transparent color. Since it is the less visible color, it is a good idea to use it. By the way, it is the default color used for transparency on GAME BOY device ((c) Nintendo).

— Function C: void gl_put_gb_sprite_16 (short x, short y, unsigned short num)
— Function ASM: - genlib::put_gb_sprite_16
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • d2.w = num = Index of sprite16 in SPRITE_16 array( 0<= num < 512).

`Output'
nothing
`Destroy'
nothing
`Description'
It puts the sprite in SPRITE_16 format, number num at x, y on the Working DScreen as a Gb16 (ie Light Gray is transparent).
`Example'
See gl_put_sprite_16 example.
`See also'
gl_set_spr_tile, gl_set_spr_xy and gl_put_sprite_16.

— Function C: void gl_put_gb_sprite_16_flip_h (short x, short y, unsigned short num)
— Function ASM: - genlib::put_gb_sprite_16_flip_h
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • d2.w = num = Index of sprite16 in SPRITE_16 array ( 0<= num < 512).

`Output'
nothing
`Destroy'
nothing
`Description'
It works just like gl_put_gb_sprite_16 function but with a horizontal flipping. It means that it is the horizontal mirror of the sprite which is printed.
`Example'
See gl_put_sprite_16 example.
`See also'
gl_set_spr_tile, gl_set_spr_xy and gl_put_sprite_16.

— Function C: void gl_put_gb_sprite_16_flip_v (short x, short y, unsigned short num)
— Function ASM: - genlib::put_gb_sprite_16_flip_v
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • d2.w = num = Index of sprite16 in SPRITE_16 array ( 0<= num < 512).

`Output'
nothing
`Destroy'
nothing
`Description'
It works just like gl_put_gb_sprite_16 function but with a vertical flipping. It means that it is the vertical mirror of the sprite which is printed.
`Example'
See gl_put_tile_16 example.
`See also'
gl_set_spr_tile, gl_set_spr_xy and gl_put_sprite_16.

— Function C: void gl_put_gb_sprite_16_flip_hv (short x, short y, unsigned short num)
— Function ASM: - genlib::put_gb_sprite_16_flip_hv
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • d2.w = num = Index of sprite16 in SPRITE_16 array ( 0<= num < 512).

`Output'
nothing
`Destroy'
nothing
`Description'
It works just like gl_put_gb_sprite_16 function but with both horizontal and vertical flipping. It means that it is the horizontal-vertical mirror of the sprite which is printed.
`Example'
See gl_put_sprite_16 example.
`See also'
gl_set_spr_tile, gl_set_spr_xy and gl_put_sprite_16.


Next: , Previous: Gb16 Functions, Up: Sprite Functions

5.5.4 Big Sprite Functions (Bgs)

The Big Sprite Functions are designed to put a sprite of any size between 16x1 to 240x128 with Halo. The weight is a multiple of 16. It is between 16 and 240 by step of 16 pixels. The height is between 1 to 128. The white is also the transparent color. The calculus of the mask is a bit complicated: the sprite is surrounded with a white halo, which allows it to be putted on complicated background.

The big sprites routines are slower than Spr16 for two reasons:

  1. Size is variable.
  2. 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).
— Function C: void gl_put_big_sprite (short x, short y, const BGS *bgs)
— Function ASM: - genlib::put_big_sprite
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • a0.l = bgs = Address of the Bgs sprite.

`Output'
nothing
`Destroy'
nothing
`Description'
It puts a big sprite on the Working DScreen with halo. The render is very nice, without the need of a mask (which would increase the size by 50%). It clips the sprite.
`Example'
               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_set_spr_xy and gl_put_masked_big_sprite.

— Function C: void gl_put_big_sprite_flip_h (short x, short y, const BGS *bgs, BGS *temp)
— Function ASM: - genlib::put_big_sprite_flip_h
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • a1.l = bgs = Address of the Bgs sprite.
  • a0.l = temp = Address of the temporary flipping sprite.

`Output'
The temporary buffer will be filled with the flipped-sprite.
`Destroy'
nothing
`Description'
It puts a Bgs on the Working DScreen with halo and with horizontal flipping. It clips the sprite if it is outside the screen. You must provide a buffer big enough for the flipped sprite. The size of this buffer is the size of the displayed sprite. Usually, you have a maximum for all the sprites you displayed (typically 64x64) and you create a buffer of size 2+64*64*(4/16).
`Example'
               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_set_spr_xy.

— Function C: void gl_put_big_sprite_flip_v (short x, short y, const BGS *bgs, BGS *temp)
— Function ASM: - genlib::put_big_sprite_flip_v
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • a1.l = bgs = Address of the Bgs sprite.
  • a0.l = temp = Address of the temporary flipping sprite.

`Output'
The temporary buffer will be filled with the flipped-sprite.
`Destroy'
nothing
`Description'
It puts a Bgs on the Working DScreen with halo and with vertical flipping. It clips the sprite if it is outside the screen. You must provide a buffer big enough for the flipped sprite. The size of this buffer is the size of the displayed sprite. Usually, you have a maximum for all the sprites you displayed (typically 64x64) and you create a buffer of size 2+64*64*(4/16).
`Example'
See gl_put_big_sprite_flip_h.
`See also'
gl_set_spr_xy.

— Function C: void gl_put_big_sprite_flip_hv (short x, short y, const BGS *bgs, BGS *temp)
— Function ASM: - genlib::put_big_sprite_flip_hv
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • a1.l = bgs = Address of the Bgs sprite.
  • a0.l = temp = Address of the temporary flipping sprite.

`Output'
The temporary buffer will be filled with the flipped-sprite.
`Destroy'
nothing
`Description'
It puts a Bgs on the Working DScreen with halo and with Horizontal and vertical flipping. It clips the sprite if it is outside the screen. You must provide a buffer big enough for the flipped sprite. The size of this buffer is the size of the displayed sprite. Usually, you have a maximum for all the sprites you displayed (typically 64x64) and you create a buffer of size 2+64*64*(4/16).
`Example'
See gl_put_big_sprite_flip_h.
`See also'
gl_set_spr_xy.

— Function C: void gl_put_big_sprite_zoom (short x, short y, const BGS *bgs, FIXED Hscale, FIXED Vscale)
— Function ASM: - genlib::put_big_sprite_zoom
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • a1.l = bgs = Address of the Bgs sprite.
  • d4.l = Hscale = 65536 / Horizontal Scale Factor.
  • d5.l = Vscale = Vertical Scale Factor.

`Output'
The temporary buffer will be filled with the flipped-sprite.
`Destroy'
nothing
`Description'
It scales a Bgs on the Working DScreen without halo. It doesn't clip the sprite if it is outside the screen.
`Example'
               	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'
gl_put_sprite_16_zoom.


Next: , Previous: Bgs Functions, Up: Sprite Functions

5.5.5 Masked Big Sprite Functions (MBgs)

The Masked Big Sprite Functions are designed to put a sprite of any size between 16x1 to 240x128 with Mask. The weight is a multiple of 16. It is between 16 and 240 by step of 16 pixels. The height is between 1 to 128.

— Function C: void gl_put_masked_big_sprite (short x, short y, const MBGS *mbgs)
— Function ASM: - genlib::put_masked_big_sprite
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • a0.l = mbgs = Address of the MBgs sprite.

`Output'
nothing
`Destroy'
nothing
`Description'
It puts a masked big sprite on the Working DScreen with mask. It clips the sprite.
`Example'
               extern	MBGS	ship2;
               void lets_start() {
                gl_set_spr_xy(0,0);
                gl_cls();
                gl_put_masked_big_sprite(10, 50, &ship2);
                gl_wait_a_key();
               }
          

`See also'
gl_set_spr_xy and gl_put_big_sprite.

— Function C: void gl_put_masked_big_sprite_flip_h (short x, short y, const MBGS *mbgs, MBGS *temp)
— Function ASM: - genlib::put_masked_big_sprite_flip_h
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • a1.l = bgs = Address of the MBgs sprite.
  • a0.l = temp = Address of the temporary flipping sprite.

`Output'
The temporary buffer will be filled with the flipped-sprite.
`Destroy'
nothing
`Description'
It puts a MBgs on the Working DScreen with mask and with horizontal flipping. It clips the sprite if it is outside the screen. You must provide a buffer big enough for the flipped sprite. The size of this buffer is the size of the displayed sprite. Usually, you have a maximum for all the sprites you displayed (typically 64x64) and you create a buffer of size 2+64*64*(6/16).
`Example'
               extern	MBGS	ship2;
               void lets_start() {
                char Temp[3000];
                gl_cls();
                gl_put_masked_big_sprite_flip_h(10, 50, &ship2, (MBGS *) Temp);
                gl_wait_a_key();
               }
          

`See also'
gl_set_spr_xy.

— Function C: void gl_put_masked_big_sprite_flip_v (short x, short y, const MBGS *mbgs, MBGS *temp)
— Function ASM: - genlib::put_masked_big_sprite_flip_v
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • a1.l = bgs = Address of the MBgs sprite.
  • a0.l = temp = Address of the temporary flipping sprite.

`Output'
The temporary buffer will be filled with the flipped-sprite.
`Destroy'
nothing
`Description'
It puts a MBgs on the Working DScreen with mask and with vertical flipping. It clips the sprite if it is outside the screen. You must provide a buffer big enough for the flipped sprite. The size of this buffer is the size of the displayed sprite. Usually, you have a maximum for all the sprites you displayed (typically 64x64) and you create a buffer of size 2+64*64*(6/16).
`Example'
See gl_put_masked_big_sprite_flip_h.
`See also'
gl_set_spr_xy.

— Function C: void gl_put_masked_big_sprite_flip_hv (short x, short y, const MBGS *bgs, MBGS *temp)
— Function ASM: - genlib::put_masked_put_big_sprite_flip_hv
`Input'
  • d0.w = x = X relative coordinate.
  • d1.w = y = Y relative coordinate.
  • a1.l = bgs = Address of the MBgs sprite.
  • a0.l = temp = Address of the temporary flipping sprite.

`Output'
The temporary buffer will be filled with the flipped-sprite.
`Destroy'
nothing
`Description'
It puts a MBgs on the Working DScreen with mask and with Horizontal and vertical flipping. It clips the sprite if it is outside the screen. You must provide a buffer big enough for the flipped sprite. The size of this buffer is the size of the displayed sprite. Usually, you have a maximum for all the sprites you displayed (typically 64x64) and you create a buffer of size 2+64*64*(6/16).
`Example'
See gl_put_masked_big_sprite_flip_h.
`See also'
gl_set_spr_xy.


Next: , Previous: MBgs Functions, Up: Sprite Functions

5.5.6 Fast Sprite Functions

Theses routines may be the fastest sprites routines available on ti-68k. But the sprite format is very huge. So in most games, they are never used. The White color is transparent, and they work in monochrome. So you need to call them twice to work in gray. They are only available to ASM programmers since, in my opinion, if you need such routines, you won't do your program in C.

— Function C: void gl_make_fast_sprite (SPRITE_BW16 spr, FAST_SPRITE fspr)
— Function ASM: - genlib::make_fast_sprite
`Input'
  • a0.l = spr = Address of the sprite 16x16 (Monochrome).
  • a1.l = fspr = Address of the output (1024 bytes).

`Output'
The temporary buffer will be filled with the Fast Sprite.
`Destroy'
nothing
`Description'
It creates a Fast Sprite from a '16x16 black and white' spr sprite to the given buffer fspr.
`Example'
char fspr[1024]; unsigned short Sprite[16] = {125,145,165,185, 205,225,245,265, 285,305,325,345, 365,385,405,425, 445,465,485,505 }; gl_make_fast_sprite(Sprite, fspr);

— ASM Macro: 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'
nothing
`Destroy'
d0-d7/a0-a1
`Description'
It puts the Fast Sprite into the given Screen. Warning: NO CLIPPING is done.
`Example'
               	jsr	genlib::get_dscreen
               	move.l	a0,a1
               	moveq	#100,d0
               	moveq	#50,d1
               	lea	fspr(Pc),a0
               	genlib::put_fast_sprite
               	...
               fspr	ds.b	1024
          

— ASM Macro: 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'
nothing
`Destroy'
d0-d7/a0-a1
`Description'
It does a logical operation from the Fast Sprite to the given Screen. Warning: NO CLIPPING is done.
`Example'
genlib::put_fast_sprite is defined like this:
               genlib::put_fast_sprite	MACRO
                genlib::do_fast_sprite or
                ENDM
          

— ASM Macro: 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'
nothing
`Destroy'
d0-d7/a0-a1
`Description'
It puts the Fast Sprite into the given DScreen. Warning: NO CLIPPING is done. It appears as black.
`Example'
               	jsr	genlib::get_dscreen
               	move.l	a0,a1
               	moveq	#100,d0
               	moveq	#50,d1
               	lea	fspr(Pc),a0
               	genlib::put_fast_sprite_ds
               	...
               fspr	ds.b	1024
          

— ASM Macro: 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'
nothing
`Destroy'
d0-d7/a0-a1
`Description'
It does a logical operation from the Fast Sprite to the given DScreen. Warning: NO CLIPPING is done. It appears as black.
`Example'
genlib::put_fast_sprite_ds is defined like this:
               genlib::put_fast_sprite_ds	MACRO
                genlib::do_fast_sprite_ds or
                ENDM
          


Next: , Previous: Sprite Functions, Up: GENLIB Interface

5.6 Plane Functions

The Plane Functions of Genlib are the most interesting feature of this library. They provided an easy and fast way of implementing huge maps (typically several times larger than the screen - For example, 1024x512 pixels). In fact, it works like if you draw a very big sprites of size 4096x1024 into the Working DScreen. As the size of the sprite is enormous, you won't define it like a typical sprite. You will define both things: a matrix of index and an array of tiles. Each element of the matrix represents a tile in the array of tiles. As a consequence, you cut your map in tiles, and then fill the matrix with the position of each tile.

As you have seen, a matrix could be a matrix of bytes (standard, 256 tiles max) or a matrix of short (for maximum performance, 1024 tiles max, Horizontal, Vertical flipping and Palette).

The association of a matrix of index and an array of tiles is called a Plane. The way of working is similar with the way of the console 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 initialize it:


Next: , Previous: (dir), Up: Plane Functions

5.6.1 Misc Plane Functions

— Function C: PLANE *gl_init_plane (const void *map, const SPRITE_16 *tile, unsigned short sizeX)
— Function ASM: - genlib::init_plane
`Input'
  • a3.l = map = Address of the matrix of index.
  • a4.l = tile = Address of the array of tile.
  • a5.l = 0 (must be equal to 0).
  • d3.w = sizeX = The number of columns (real or its log2).

`Output'
a0.l = Address of the allocated Plane.
`Destroy'
d0/a0
`Description'
It allocates a new plane in the heap with its VScreen and initializes it. Before using any plane functions, you should call this function. The SizeX argument could be the real X size (ie the number of columns of the matrix) or the log2 of the real X size (if it is possible, ie for 2^8=256 it is possible). The default is set to the log2 of the real size.
`Example'
               	PLANE	*P;
               	unsigned 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,
               	}
               
               	unsigned 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, (SPRITE_16 *) tiles, 32);
          

`See also'
gl_change_update

— Function C: void gl_free_plane (PLANE *P)
— Function ASM: - genlib::free_plane
`Input'
a0.l = P = Address of the Plane.
`Output'
nothing
`Destroy'
d0-d2/a0-a1
`Description'
It frees the plane (Equivalent at HeapFree(P->handle)).
`Example'
gl_free_plane(P);
`See also'
HeapFree

— Function C: void gl_refresh_plane (PLANE *P)
— Function ASM: - genlib::refresh_plane
`Input'
a0.l = P = Address of the Plane.
`Output'
nothing
`Destroy'
nothing
`Description'
It refreshs the plane. After calling this function, when you call an update_vscreen Function, the VScreen of the plane will always be updated! Otherwise, it will be updated if needed. It is useful if you update the matrix of index or the array of tiles, after initializing the Plane.
`Example'
               P->xs = 201;
               P->ys = 305;
               gl_refresh_plane(P);
               gl_update_vscreen_16(P);
               gl_put_plane(P);
          

`See also'
gl_update_vcreen_16

— Function C: void gl_copy_xyplane_xysprite (PLANE *P)
— Function ASM: - genlib::copy_xyplane_xysprite
`Input'
a0.l = P = Address of the Plane.
`Output'
nothing
`Destroy'
nothing
`Description'
It copies the coordinates of the given Plane into the coordinates of the Sprite Origin. It is useful if you want that your sprites were drawn according to the position of the Plane which is usually the case.
`Example'
It is equivalent to: gl_set_spr_xy(P->xs, P->ys);
`See also'
gl_set_spr_xy

— Function C: void gl_copy_dscreen_vscreen (PLANE *P, DSCREEN *DScr);
— Function ASM: - genlib::copy_dscreen_vscreen
`Input'
  • a0.l = P = Address of the Plane.
  • a1.l = DScr = Address of the DScreen.

`Output'
nothing
`Destroy'
nothing
`Description'
It copies the given DScreen into the VScreen of the Plane P. It doesn't clean the VScreen so you may get some artefact at the border of the VScreen.
`Example'
               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);
                             glaux_swap ();
                             glaux_synchro (1);
               	}
               }
          


Next: , Previous: Misc Plane Functions, Up: Plane Functions

5.6.2 Customize Plane Functions

All the functions in this section should be only for advanced GENLIB users.

— Function C: void gl_change_update (void)
— Function ASM: - genlib::change_update
`Input'
Nothing
`Output'
nothing
`Destroy'
nothing
`Description'
It modifies the code of the three functions gl_update_vscreen_8, update_vscreen_16 and update_vscreen_max16 so that you define the real size of a row. It is useful for working with matrix which horizontal size is not a power of two. You should call it before calling the update_function, in the initialization section of your program for example.
`Example'
See gl_init_plane.

— Function C: void gl_restore_update (void)
— Function ASM: - genlib::restore_update
`Input'
Nothing
`Output'
nothing
`Destroy'
nothing
`Description'
It modifies the code of the three functions gl_update_vscreen_8, update_vscreen_16 and update_vscreen_max16 so that you define the logarithm in base two of the size of a row. It is useful for working with matrix which horizontal size is a power of two. You should call it before calling the update_function, in the initialization section of your program for example.
`Example'
See gl_init_plane.

— Function C: void gl_set_filter (unsigned short filter)
— Function ASM: - genlib::set_filter
`Input'
d0.w = filter = The way of filtering.
`Output'
nothing
`Destroy'
nothing
`Description'
It sets the transparent color for gl_put_frgd_plane, gl_put_frgd_plane_89, gl_put_dhz_frgd_plane, put_dhz_frgd_plane_89 by modifying the code of theses functions. You should call this function before them.

filter can be :

  • 0: White is transparent (Default).
  • 1: Black is transparent.
  • 2: Light Gray is transparent.
  • 3: All colors are translucent.

`Example'
See 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


Next: , Previous: Customize Plane Functions, Up: Plane Functions

5.6.3 Update VScreen Plane Functions

— Function C: void gl_update_vscreen_8 (PLANE *P)
— Function ASM: - genlib::update_vscreen_8
`Input'
a0.l = P = Address of the PLANE struct.
`Output'
nothing
`Destroy'
nothing
`Description'
It updates the VScreen of the given Plane with tiles 8x8 if necessary, assuming the matrix of index is a matrix of bytes.
`Example'
See gl_update_vscreen_16 example.

— Function C: void gl_update_vscreen_16 (PLANE *P)
— Function ASM: - genlib::update_vscreen_16
`Input'
a0.l = P = Address of the PLANE struct.
`Output'
nothing
`Destroy'
nothing
`Description'
It updates the VScreen of the given Plane with tiles 16x16 if necessary, assuming the matrix of index is a matrix of bytes.
`Example'
                JOYPAD	j;
               
                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);
                 glaux_swap ();
                 glaux_synchro (1);
               }
           

— Function C: void gl_update_roll_vscreen_16 (PLANE *P)
— Function ASM: - genlib::update_roll_vscreen_16
`Input'
a0.l = P = Address of the PLANE struct.
`Output'
nothing
`Destroy'
nothing
`Description'
It updates the VScreen of the given Plane with tiles 16x16 if necessary, assuming the matrix of index is a matrix of bytes. Contrary to gl_update_vscreen_16, if there is a horizontal overflow, it uses the same row. The horizontal size of the matrix of index must be a power of 2, since it uses a mask to compute the real x coordinate of the tile to print in the VScreen.
`Example'
See gl_update_vscreen_16 example.

— Function C: void gl_update_max16 (PLANE *P)
— Function ASM: - genlib::update_max16
`Input'
a0.l = P = Address of the PLANE struct.
`Output'
nothing
`Destroy'
nothing
`Description'
It updates the VScreen of the given Plane with tiles 16x16 if necessary, assuming the matrix of index is a matrix of word. See Plane section for more details.
`Example'
See gl_update_vscreen_16 example.


Next: , Previous: Update VScreen Plane Functions, Up: Plane Functions

5.6.4 Put Plane Functions

The '_89' suffix means that the function draw only the portion of the screen visible on the TI-89 or compatible device.

— Function C: void gl_put_plane (PLANE *P)
— Function C: void gl_put_plane_89 (PLANE *P)
— Function ASM: - genlib::put_plane
— Function ASM: - genlib::put_plane_89
`Input'
a0.l = P = Address of the PLANE struct.
`Output'
nothing
`Destroy'
d0-d2/a0-a1
`Description'
It puts the VScreen of the given Plane on the Working DScreen as a background (ie everything is erased).
`Example'
See gl_update_vscreen_16 example.

— Function C: void gl_put_fgrd_plane (PLANE *P)
— Function C: void gl_put_fgrd_plane_89 (PLANE *P)
— Function ASM: - genlib::put_fgrd_plane
— Function ASM: - genlib::put_fgrd_plane_89
`Input'
a0.l = P = Address of the PLANE struct.
`Output'
nothing
`Destroy'
d0-d2/a0-a1
`Description'
It puts the VScreen of the given Plane on the Working DScreen as a foreground: by default, White is transparent, but you can redefine it using gl_set_filter.
`Example'
                JOYPAD	j;
                PLANE	*P1, *P2;
               
                gl_change_update ();
                P1 = gl_init_plane (map, tiles, 32);
                P2 = gl_init_plane (map, tiles, 32);
               
                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);
                 glaux_swap ();
                 glaux_synchro (2);
                }
           

`See also'
gl_set_filter, gl_update_ functions

— Function C: void gl_put_dhz_plane (PLANE *P, DHZ_TAB D, HDZ_TAB H)
— Function C: void gl_put_dhz_plane_89 (PLANE *P, DHZ_TAB D, HDZ_TAB H)
— Function ASM: - genlib::put_dhz_plane
— Function ASM: - genlib::put_dhz_plane_89
`Input'
  • a0.l = P = Address of the PLANE struct.
  • a4.l = D = Address of the DHZ Table.
  • a5.l = H = Address of the Hdz Table.

`Output'
nothing
`Destroy'
nothing
`Description'
It puts the VScreen of the given Plane on the Working DScreen as a background, with Dhz and Hdz tables.
`Example'
                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 ();
                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);
                 glaux_swap ();
                 glaux_synchro (1);
                }
           

`See also'
gl_update_ functions

— Function C: void gl_put_dhz_fgrd_plane (PLANE *P, DHZ_TAB D, HDZ_TAB H)
— Function C: void gl_put_dhz_fgrd_plane_89 (PLANE *P, DHZ_TAB D, HDZ_TAB H)
— Function ASM: - genlib::put_dhz_fgrd_plane
— Function ASM: - genlib::put_dhz_fgrd_plane_89
`Input'
  • a0.l = P = Address of the PLANE struct.
  • a6.l = D = Address of the DHZ Table.
  • d7.l = H = Address of the Hdz Table.

`Output'
nothing
`Destroy'
nothing
`Description'
It puts the VScreen of the given Plane on the Working DScreen as a foreground, with Dhz and Hdz tables. You can redefine the transparent color with gl_set_filter.
`Example'
Mix example from gl_put_dhz_plane and gl_put_fgrd_plane.
`See also'
gl_update_ functions.


Next: , Previous: Plane Functions, Up: GENLIB Interface

5.7 Key Functions

All the key scanning routines do a direct hardware access. So the standard Ti-Os auto-int 1 should be disable so that it works properly (which is the default).

— Function C: void gl_wait_no_key (void)
— Function ASM: - genlib::wait_no_key
`Input'
nothing
`Output'
nothing
`Destroy'
nothing
`Description'
It stops the program until all keys are not pressed.

— Function C: void gl_wait_a_key (void)
— Function ASM: - genlib::wait_a_key
`Input'
nothing
`Output'
nothing
`Destroy'
nothing
`Description'
It stops the program until a key is pressed.

— Function C: char gl_key_pressed (void)
— Function ASM: - genlib::key_pressed
`Input'
nothing
`Output'
d0 != 0 if a key is pressed.
`Destroy'
d0
`Description'
It returns a non-null value iff a key is pressed.

— Function C: const KEYBOARD *const gl_read_key_matrix (void)
— Function ASM: - genlib::read_key_matrix
`Input'
nothing
`Output'
a0: a pointer to the internal updated key matrix.
`Destroy'
a0
`Description'
It updates the key-matrix (See KEYBOARD). The Key-matrix depends on the calculator (ti89, ti92+, v200). You should use read_joypad instead (if you could).

— Function C: JOYPAD gl_read_joypad (void)
— Function ASM: - genlib::read_joypad
`Input'
nothing
`Output'
  • d0.l: Current Joypad Value.
  • a0.l: Updated key matrix.

`Destroy'
a0 d0
`Description'
It updates the virtual joypad and the key's matrix. The joypad is calculator independent. Of course you need to call it once per frame (even if some games call it twice per frame to increase the maniability, but it is quite difficult to handle it).
`Example'
                     jsr	genlib::read_joypad
                     btst.l	#ke_key,d0
                     bne	\no_ke
               	; Code to use if ke (Shift or F5 or W) is pressed.
               \no_ke:
                     btst.l	#ka_key,d0
                     bne	\no_ka
               	; Code to use if ka (2nd or F1 or Q) is pressed.
               \no_ke:
                


Next: , Previous: Key Functions, Up: GENLIB Interface

5.8 Link Functions

Genlib has also special link functions. It doesn't use the tios routine. It uses a direct access to the I/O hardware so that you can specify your destination buffer.


Next: , Previous: Link Functions, Up: Link Functions

5.8.1 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 AMS. The principle is not genious. It works with symmetrical buffers. (I don't know the official name). On both calculators, we define two buffers. The content of theses two zones are identical (without considering the propagating time). One calc can only modify one area. The other one is modified by the other calc. In fact, it maps an area of RAM of one calculator (in read/write access) into the other calculator (in read access), and vice-versa.

The size between the two areas (Send Buffer and Receive buffer) can be different. The size between a Receiv Buffer of one calculator and the size of the Send Buffer of the other calculator must be equal.

In order to know if the Receiv Buffer has been updated, you have to test if genlib::link_data+buffer_recpt_flag (gl_link_data.buffer_recpt_flag) is set to 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.

Ok it is quite complex. It is due to a bad conception. When I rewrite theses functions, I will use a more academic protocol (like TCP).


Next: , Previous: Link Functions(1), Up: Link Functions

5.8.2 To put into practice


Previous: Link Functions(2), Up: Link Functions

5.8.3 Interface

— Function C: void gl_set_byte_link (void)
— Function ASM: - genlib::set_byte_link
`Input'
nothing
`Output'
nothing
`Destroy'
nothing
`Description'
It sets the link parameters to use a byte structure. You must call it before using gl_send_byte and gl_receive_byte. It works like gl_set_link and does a similar job.

— Function C: void gl_send_byte (unsigned char byte)
— Function ASM: - genlib::send_byte
`Input'
d0.b = byte = Byte to send
`Output'
nothing
`Destroy'
nothing
`Description'
It sends byte. gl_set_byte must have been called to set the BYTE interface.
`Example'
                     move.b #...,d0
                     jsr	genlib::send_byte
                     lea	genlib::link_data,a0
               \w:   cmp.b	#DONE,buffer_send_flag(a0)
                     bne.s	\w
                
                     gl_send_byte(...);
                     while (gl_link_data.buffer_send_flag != DONE );
                

— Function C: unsigned char gl_receive_byte (void)
— Function ASM: - genlib::receive_byte
`Input'
nothing
`Output'
d0.b = The received byte.
`Destroy'
d0
`Description'
It receives the byte by the other calculator. gl_set_byte must have been called to set the BYTE interface.
`Example'
                     lea	genlib::link_data,a0
                     move.b    #IN_PROGRESS,buffer_recpt_flag(a0)
               \w:   cmp.b	#DONE,buffer_recpt_flag(a0)
                     bne.s	\w
                     jsr	genlib::receive_byte
                
                     gl_link_data.buffer_recieve_flag = IN_PROGRESS;
                     while (gl_link_data.buffer_receive_flag != DONE );
                     byte = gl_receive_byte();
                

— Function C: void gl_set_link (char *buf_rcpt, char *buf_send, short buf_rept_len, short buf_send_len)
— Function ASM: - genlib::set_link
`Input'
  • a1.l = buf_rcpt = address of the Receiv Buffer.
  • a2.l = buf_send = address of the Send Buffer.
  • d1.w = buf_rept_len = size of the Receiv Buffer.
  • d2.w = buf_send_len = size of the Send Buffer.

`Output'
nothing
`Destroy'
nothing
`Description'
It sets the current mapped memory areas to use for the link interface.

— Function C: void gl_send_data (void)
— Function ASM: - genlib::send_data
`Input'
nothing
`Output'
nothing
`Destroy'
nothing
`Description'
It sends the already-defined Send buffer to the other calculator. It is sent using the auto-link 4, so when this function returns the data hasn't been sent already, but are being sent. You must check the status of the link interface to see if the data has been sent.
`Example'
                     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 potential problem.
               		move.w	buffer_r,my_own_copy
               		; 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)      ; Receive a new one
               		jsr	genlib::send_data			; Send a new one
               \no_new
                
                     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();
                     }
                

— Function C: int gl_synchronize (void)
— Function ASM: - genlib::synchronize
`Input'
nothing
`Output'
d0 == 0 if synchro is ok, otherwise the user has pressed a key.
`Destroy'
d0
`Description'
It synchronizes the 2 calculators and updates the master / slave flag. GENLIB must have be installed into the two calculators before calling this function (i.e. genlib::init has been called).
`Example'
                     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
                
               if (gl_synchronise()) {
                  printf ("The user press a key !\n");
                  exit (1);
               }
                


Next: , Previous: Link Functions, Up: GENLIB Interface

5.9 Special Functions

Some functions which may do some good special effects.


Next: , Up: Special Functions

5.9.1 Horizontal Line Functions

— Function C: void gl_draw_bwhline_b (short x1, short x2, short y)
— Function ASM: - genlib::draw_bwhline_b
— Function C: void gl_draw_bwhline_w (short x1, short x2, short y)
— Function ASM: - genlib::draw_bwhline_w
`Input'
  • d0.w = x1
  • d1.w = x2
  • d3.w = y

`Output'
nothing
`Destroy'
d0-d2/a0-a1
`Description'
It draws an horizontal clipped Black (with _b suffix) or white (with _w suffix) line in the DARK_SCREEN of the Working DSscreen from x1 to x2 at row y.
`See also'
gl_render_triangle, gl_render_disk

— Function C: void gl_draw_line_w (short x1, short x2, short y)
— Function ASM: - genlib::draw_hline_w
— Function C: void gl_draw_line_lg (short x1, short x2, short y)
— Function ASM: - genlib::draw_hline_lg
— Function C: void gl_draw_line_dg (short x1, short x2, short y)
— Function ASM: - genlib::draw_hline_dg
— Function C: void gl_draw_line_b (short x1, short x2, short y)
— Function ASM: - genlib::draw_hline_b
`Input'
  • d0.w = x1
  • d1.w = x2
  • d3.w = y

`Output'
nothing
`Destroy'
d0-d2/a0-a1
`Description'
It draws an horizontal clipped White(_w)/LighGray(_lg)/DarkGray(_dg)/Black(_b) line in the Working DSreen from x1 to x2 at row y.
`See also'
gl_render_triangle, gl_render_disk

— Function C: void gl_draw_hline_light (short x1, short x2, short y)
— Function ASM: - genlib::draw_hline_light
— Function C: void gl_draw_hline_shadow (short x1, short x2, short y)
— Function ASM: - genlib::draw_hline_shadow
`Input'
  • d0.w = x1
  • d1.w = x2
  • d3.w = y

`Output'
nothing
`Destroy'
d0-d2/a0-a1
`Description'
It draws an alpha horizontal clipped line in the Working DScreen from x1 to x2 at row y. Alpha color is white for _light function and black for _shadow function. It transforms the background such like there is a ray of light, or a lack of a ray of light, which lights it.
`See also'
gl_render_triangle, gl_render_disk


Next: , Previous: Horizontal Line Functions, Up: Special Functions

5.9.2 Triangle Functions

— Function C: void gl_draw_clipped_face (POINT *Pt1, POINT *Pt2, POINT *Pt3, SCREEN *scr)
— Function ASM: - genlib::draw_clipped_face
— Function C: void gl_draw_face (POINT *Pt1, POINT *Pt2, POINT *Pt3, SCREEN *scr)
— Function ASM: - genlib::draw_face
`Input'
  • a0.l = Pt1 = First point.
  • a1.l = Pt2 = Second point.
  • a2.l = Pt3 = Third point.
  • a4.l = scr = Destination Screen

`Output'
nothing
`Destroy'
nothing
`Description'
It draws a triangle in the specified scr with or without clipping. This routine is inspired by Patrick Davidson's one. Even for clipped version, don't use points too far from screen space since it may overflow. The coordinates are defined respectively from the Screen space.
`Example'
                     POINT	P1 = {12, 13}, P2 = {250, -20}, P3 = {100, 150};
                     gl_draw_clipped_face (&P1, &P2, &P3, DARK_SCREEN (gl_get_dscreen ()));
          

`See also'
gl_render_triangle

— Function C: void gl_draw_clipped_c_face (POINT *Pt1, POINT *Pt2, POINT *Pt3, short color)
— Function ASM: - genlib::draw_clipped_c_face
— Function C: void gl_draw_c_face (POINT *Pt1, POINT *Pt2, POINT *Pt3, short color)
— Function ASM: - genlib::draw_c_face
`Input'
  • a0.l = Pt1 = First point.
  • a1.l = Pt2 = Second point.
  • a2.l = Pt3 = Third point.
  • d0.w = color = 0 (White), 1(light gray), 2(Dark Gray) or 3(Black)

`Output'
nothing
`Destroy'
nothing
`Description'
It draws a triangle in the Working DScreen with or without clipping in the specified color. This routine is inspired by Patrick Davidson's one. Even for clipped version, don't use points too far from screen space since it may overflow. The coordinates are defined respectively from the DScreen space.
`Example'
                     POINT	P1 = {12, 13}, P2 = {250, -20}, P3 = {100, 150};
                     gl_draw_clipped_c_face (&P1, &P2, &P3, 1);
          

`See also'
gl_render_triangle

— Function C: void gl_render_triangle (POINT *P1, POINT *P2, POINT *P3, void (*draw_hline)(short, short, short))
— Function ASM: - genlib::render_triangle
`Input'
  • a0.l = Pt1 = First point.
  • a1.l = Pt2 = Second point.
  • a2.l = Pt3 = Third point.
  • a6.l = draw_hline = Horizontal Line drawing function (GENLIB compatible).

`Output'
nothing
`Destroy'
d0-d7/a0-a6
`Description'
It renders a triangle in the Working DScreen using the specified callback. Don't use points too far from screen space since it may overflow. The coordinates are defined respectively from the DScreen space. The Horizontal Line drawing function, in assembly, should have a prototype like those from GENLIB Horizontal Line Functions.
`Example'
                     POINT	P1 = {12, 13}, P2 = {250, -20}, P3 = {100, 150};
                     gl_render_triangle (&P1, &P2, &P3, gl_draw_hline_light);
          

`See also'
gl_render_triangle


Next: , Previous: Triangle Functions, Up: Special Functions

5.9.3 Circle Functions

— Function C: void gl_draw_circle (short x, short y, short radius, short color)
— Function ASM: - genlib::draw_circle
— Function C: void gl_draw_clipped_circle (short x, short y, short radius, short color)
— Function ASM: - genlib::draw_clipped_circle
`Input'
  • d4.w = x = X absolute coordinate.
  • d5.w = y = Y absolute coordinate.
  • d2.w = radius = Radius of the circle.
  • d3.w = color = 0(Black), 1(Light gray), 2(Dark gray) or 3(Black).

`Output'
nothing
`Destroy'
nothing
`Description'
It draws a circle on the Working DScreen with the specified color, with or without clipping.
`Example'
               gl_draw_clipped_circle (152, 12, 30, 2);
          

— Function C: void gl_draw_disk (short x, short y, short radius, short color)
— Function ASM: - genlib::draw_disk
— Function C: void gl_draw_clipped_disk (short x, short y, short radius, short color)
— Function ASM: - genlib::draw_clipped_disk
`Input'
  • d4.w = x = X absolute coordinate.
  • d5.w = y = Y absolute coordinate.
  • d2.w = radius = Radius of the disk.
  • d3.w = color = 0(Black), 1(Light gray), 2(Dark gray) or 3(Black).

`Output'
nothing
`Destroy'
nothing
`Description'
It draws a disk on the Working DScreen with the specified color, with or without clipping.
`Example'
               gl_draw_clipped_disk (152, 12, 30, 2);
          

— Function C: void gl_render_disk (short x, short y, short radius, void (*draw_hline)(short, short, short))
— Function ASM: - genlib::render_disk
`Input'
  • d4.w = x = X absolute coordinate.
  • d5.w = y = Y absolute coordinate.
  • d2.w = radius = Radius of the disk.
  • a2.l = draw_hline = GENLIB compatible horizontal line drawing function.

`Output'
nothing
`Destroy'
nothing
`Description'
It renders a disk on the Working DScreen using the specified callback. The Horizontal Line drawing function, in assembly, should have a prototype like those from GENLIB Horizontal Line Functions.
`Example'
                gl_render_disk(10,20,10,gl_draw_hline_light);
          


Previous: Circle Functions, Up: Special Functions

5.9.4 Misc Functions

— Function C: 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);
— Function ASM: - genlib::do_zoom
`Input'
  • d0.w = x = X coordinate on the Screen.
  • d1.w = y = Y coordinate on the Screen.
  • d4.l = H_Fact = 1 / (factor of the horizontal Zoom) - fixed 16:16.
  • d5.l = V_Fact = factor of the vertical Zoom - fixed 16:16.
  • d6.w = vert_rows = Number of vertical lines for the texture.
  • d6.uw = hor_words = Number of horizontal words for the texture.
  • a0.l = scr = The destination Screen.
  • a1.l = texture = The input texture.
  • a4.l = texture_inc = Interleave factor (4 for BGS like texture format, otherwise 2).
  • a3.l = Screen X size (if a3<>30, then you must have y = 0).

`Output'
nothing
`Destroy'
nothing
`Description'
It scales a Black-and-White texture of vertical size vert_rows and of horizontal size 16 x hor_words. There is no clipping. H_Fact and V_Fact are fixed 16:16 reals. The speed is 38 fps for a full-screen zoom on Ti-89. This function isn't fast enough for real time games yet. You should only use it for special effects.
`Example'
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 and gl_put_big_sprite_zoom

— Function C: void gl_put_pixel (short x, short y, short color)
— Function ASM: - genlib::put_pixel
`Input'
  • d0.w = x = X real coordinate on the DScreen.
  • d1.w = y = Y real coordinate on the DScreen.
  • d3.w = color = 0 (White), 1(Light gray), 2(Dark Gray) or 3(Black)

`Output'
nothing
`Destroy'
nothing
`Description'
It puts a pixel on the Working DScreen with Clipping.
`Example'
                     gl_put_pixel(152,12,2);
                

— Function C: int gl_clip_line (short *x1, short *y1, short *x2, short *y2)
— Function ASM: - genlib::clip_line
`Input'
  • d0.w = x1 = X real coordinate of Point 1.
  • d1.w = y1 = Y real coordinate of Point 1.
  • d2.w = x2 = X real coordinate of Point 2.
  • d3.w = y2 = Y real coordinate of Point 2.

`Output'
  • d0.w = New X coordinate of Point 1
  • d1.w = New Y coordinate of Point 1
  • d2.w = New X coordinate of Point 2
  • d3.w = New Y coordinate of Point 2
  • d4.w == 0 iff the line is outside the screen (can't draw it).

`Destroy'
d0-d4
`Description'
It clips the line from Point 1 to Point 2. In asm, you pass directly the coordinates, whereas in C, you pass the address of the coordinates (It is due to the fact that C can't return more than one argument).
`See also'
gl_draw_clipped_line.

— Function C: void gl_draw_line (short x1, short y1, short x2, short y2, short color)
— Function ASM: - genlib::draw_line
— Function C: void gl_draw_clipped_line (short x1, short y1, short x2, short y2, short color)
— Function ASM: - genlib::draw_clipped_line
`Input'
  • d0.w = x1 = X real coordinate of Point 1.
  • d1.w = y1 = Y real coordinate of Point 1.
  • d2.w = x2 = X real coordinate of Point 2.
  • d3.w = y2 = Y real coordinate of Point 2.
  • d5.w = color = 0 (White), 1(Light gray), 2(Dark Gray) or 3(Black)

`Output'
nothing
`Destroy'
nothing
`Description'
It draws a line with or without clipping in the specified color on the Working DScreen.
`Example'
                      gl_draw_line(10,20,100,100,1);
                


Next: , Previous: Special Functions, Up: GENLIB Interface

5.10 C only Functions

Theses functions are useful for C programmers.

— Function C: void gl_set_spr_xy (short x, short y)
`Description'
It sets the coordinates of the sprite plane. In asm, you use instead:
               move.w x,genlib::sprite_scr_x
               move.w y,genlib::sprite_scr_y
          

— Function C: void gl_set_spr_tile (SPRITE_16 *adr)
`Description'
It sets the address of the tiles table. In asm, you use instead:
               move.l adr,genlib::sprite_tile_adr
          


Next: , Previous: C Only Functions, Up: GENLIB Interface

5.11 ASM only Functions

There are some additional MACROS which are defined in genlib.h and may be useful for you.

— Macro ASM: - divu32 A,B,ds1,ds2
— Macro ASM: - 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'
A
`Destroy'
A, ds1, ds2
`Description'
It divides a 32 bits unsigned (or signed) number by 16 bits unsigned (or signed) number. The result is a 32 bits unsigned (signed) quotient, i.e. A = A / B.
`Example'
                     move.l	#$Fe120019,d0
                     divu32	d0,#80,d2,d3		; d0.l = d0.l / d1.w
          

— Macro ASM: - fload A,B,dest
— Macro ASM: - fadd A,dest
— Macro ASM: - fsub A,dest
— Macro ASM: - fmulu A,dest
— Macro ASM: - fmuls A,dest
— Macro ASM: - fdivu A,dest,tmp1,tmp2
— Macro ASM: - fdivs A,dest,tmp1,tmp2
`Input'
  • tmp1 = Temporary register (Destroyed)
  • tmp2 = Temporary register (Destroyed)
  • A = ea
  • B = ea
  • dest = destination data register

`Output'
dest
`Destroy'
dest, ds1, ds2
`Description'
It loads A/B in dest. It adds A to dest. It subtracts A from dest. It multiplies A to dest, or it divides A from dest. Warning: mul & div assume that the number have the lowest 8 bits and the highest 8 bits null since divu & mulu accept only word operands.
`Example'
                     fload	2,3,d1
                     fload	1584,145,d2
                     fload	1584,14547,d3
                     fadd	d2,d1
                     fmuls	d3,d1
                     fadd	d2,d1
                     fdivs	d2,d1
          


Next: , Previous: ASM Only Functions, Up: GENLIB Interface

5.12 GLAUX Functions

Theses functions aren't in the dynamic library of GENLIB but in the static one (genlib.a or gennlib.a). You can use still use theses functions in nostub or kernel mode. Since they are pure C functions, I just do a preview of them. Some extra structures are defined too:

     /* colors */
     enum { C_WHITE, C_LGRAY, C_DGRAY, C_BLACK, C_SHADOW=-3, C_LIGHT, C_NONE };
     /* text mode */
     enum { T_SMALL, T_MEDIUM, T_LARGE };

Their meanings are obvious, no ?

They work on the Working DScreen.

— Function: void glaux_rect (int x1, int y1, int x2, int y2, int fcolor, int bsize, int bcolor)

Draw a clipped rect from (x1, y1) to (x2, y2). fcolor is the font color. bcolor is the border color. bsize is the border size.

— Function: void glaux_circle (int x, int y, int r, int fcolor, int bcolor)

Draw a clipped circle at (x, y) with radius r. fcolor is the font color. bcolor is the border color.

— Function: void glaux_triangle (int x1, int y1, int x2, int y2, int x3, int y3, int fcolor, int bcolor)

Draw a clipped triangle at (x1, y1), (x2, y2) and (x3, y3). fcolor is the font color. bcolor is the border color.

— Function: void glaux_text (int x, int y, int color, int textmode, const char *format, ...)

Draw a formatted string at (x, y). color is the color. textmode is the font. string is the formatted text to display.

— Function: int glaux_read_char (void)

Read a char from the standard Key Buffer (ie uses AMS ngetchx). Restore the interrupt level after finishing reading. Translate the TI-89 keys to TI-92+ keys (ie K_DIAMOND, K_LEFT, etc return the value for ti-92+.

— Function: void gl_main (void)

Well, this function isn't defined by genlib. You must define it yourself. If you want to use 'gl_main', you don't need to define another entry point (the standard _main function) and you don't need to initialize genlib: genlib is started, and two DScreens are allocated (one on the stack, the other on the heap) and cleared. So you can start directly!

See glaux functions to handle the allocated DScreen.

— Function: void glaux_synchro (unsigned short time)

This function synchronizes your program to 15 Hz (if time = 2) or 30Hz (if time = 1). This function must be used only with gl_main!

— Function: void glaux_ready (void)

This function waits until the swapping of the DScreen is really effective. It is very useful, if you want to avoid bad artefact: you swap your DScreens, you update the Working DScreen... but is is still displayed. As a consequence, you have artefact. In general, this function doesn't wait, if you know how to use it well. It must be used only with gl_main!

— Function: void glaux_swap (void)

This function swaps the 2 DScreens allocated by gl_main, ie the Working DScreen becomes the Displayed DScreen and the Displayed DScreen becomes the Working one. Must be used only with gl_main !

— Function: void glaux_no_double_buffer (void)

This function stops the Double Buffering system. The working DScreen and the displayed one become the same. It must be used with gl_main only. Use glaux_swap to restore the Double Buffering System.


Next: , Previous: GLAUX Functions, Up: GENLIB Interface

5.13 Outdated Functions

All the functions in this section are outdated, their usage is not recommended.

— Function C: void gl_set_callback_update (void)
— Function ASM: - genlib::set_callback_update
`Input'
nothing
`Output'
nothing
`Destroy'
nothing
`Description'
It modifies the code of update_vscreen_8, update_vscreen_16, update_vscreen_roll_16 and update_vscreen_max16 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 useful 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 incrementing 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.

`Example'
A basic function which does nothing more than the standard 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
           

A more advanced example looks like:

                 MySuperCallBack	adda.w	(a3)+,a4
               			rts
           

`See also:'
gl_update_xxx functions

— Function C: void gl_free_callback_update (void)
— Function ASM: - genlib::free_callback_update
`Input'
Nothing
`Output'
nothing
`Destroy'
nothing
`Description'
It disables the calling of the callback in the Update VScreen functions.
`Example'
See Update VScreen functions.

— Function C: void gl_put_dhz_trpt_plane (PLANE *P, DHZ_TAB D, HDZ_TAB H, long Dhz_offset, long Hdz_offset)
— Function C: void gl_put_dhz_trpt_plane_89 (PLANE *P, DHZ_TAB D, HDZ_TAB H, long Dhz_offset, long Hdz_offset)
— Function ASM: - genlib::put_dhz_trpt_plane
— Function ASM: - genlib::put_dhz_trpt_plane_89
`Input'
  • a0.l = P = Address of the plane.
  • a3.l = D = Address of the Dhz table.
  • a4.l = H = Address of the Hdz table.
  • a5.l = Dhz_offset = Offset between the two DHZ Tables
  • a6.l = Hdz_offset = Offset between the two HDZ Tables

`Output'
nothing
`Destroy'
nothing
`Description'
It puts the VScreen of the given Plane on the Working DScreen as transparent with individual Dhz/Hdz table. The offset between the two tables is defined as the offset between the end of the first one and the beginning of the second.
`Example'
                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 ();
                P1 = gl_init_plane (map, tiles, 32);
                P2 = gl_init_plane (map, tiles, 32);
               
                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));
                 glaux_swap ();
                 glaux_synchro (2);
                }
           

— Function C: void gl_exg_gray (void)
— Function ASM: - genlib::exg_gray
`Input'
nothing
`Output'
nothing
`Destroy'
nothing
`Description'
Exchange dark-grey and bright-grey. Warning: Calling set_dscreen_int disable it.

— Function ASM: - genlib::use_int1
`Input'
  • A6 = Address of the function
  • D0-D7/A0-A5 : same as the called function.
  • Stack : same as the called function.

`Output'
Same as called function
`Destroy'
Same as called function
`Description'
Call a function and restore the auto-int 1 during this call. You can use in C this code:
                     OSSetSR (0);
                     idle_loop();
                     OSSetSR (0x200);
                

Even in asm you can do like it...

— Function ASM: - genlib::put_sprite_16_last_flip
`Input'
  • d0.w = X
  • d1.w = Y

`Output'
nothing
`Destroy'
nothing
`Description'
It puts the last flipped sprite at D0.w,D1.w of Sprite-Tile-Table on the sprite_plane.


Next: , Previous: GENLIB Interface, Up: Top

6 Contributors

The main developers are:


Next: , Previous: Contributors, Up: Top

7 Bench

Here are the results (expressed in Hz) of GENLIB v1.00.00a on different systems:

92+HW1 89HW2 89HW3
Spr16 3211 4219 4139
Bgs16 2360 3101 3040
Bgs32 773 1020 1000
Bgs64 166 218 213
Mirror Spr16 1940 2592 2537
Spr32->64 105 140 137
Line 1930 2520 2485
Triangle 460 473 587
Circle 132 176 176
Random Pixel 6521 8256 8181
MediumString 460 599 587
Clear DScr 529 714 703
1 Plane (92) 79 103 101
1 Plane (89) 110 145 144
2 Planes(92) 31 41 40
2 Planes(89) 50 67 66
3 Planes(92) 19 26 25
3 Planes(89) 32 43 42

As you can see, performance on HW2 and HW3 are the same and are far greater than on HW1.


Next: , Previous: Bench, Up: Top

History


Next: , Previous: History, Up: Top

Concept Index


Previous: Concept Index, Up: Top

Function and Type Index