cpcrslib v.2       

(Only English version of this text will be maintained)

Español. Ojo. La ayuda en español está obsoleta.

 

Amstrad CPC Library for z88dk.

 

Download last version (03/30/2009): cpcrslib

 

 

Introduction.

 

cpcrslib is a C library containing routines and functions that allow to the handling of sprites and tile-mapping in Amstrad CPC. The library is written to be used with z88dk compiler. cpcrslib also incorporates keyboard routines to redefine and to detect keys, as well as general routines to change to the screen mode or the colours.

So far, next games have been coded using cpcrslib:

 

Small Games for Smart Minds by ESP Soft.

Mariano The Dragon by ESP Soft.

Sort'em by LuBlu Entertainment.

Phantomas Thales #1: Marsport by The Mojon Twins.

Nanako Descens to Hell by The Mojon Twins.

 

 

News.

 

03/30/2009

cpc_ClrScr: Fills screen with ink 0 (similar to CLG)

cpc_DisableFirmware: Disables interruption jump from &0038

cpc_EnableFirmware: Restores interruption jump previously removed with cpc_DisableFirmware

cpc_PrintGphStrStd: New mode 1 8x8 pixel writing routine, memory address

cpc_PrintGphStrStdXY: New mode 1 8x8 pixel writing routine, (x,y) for positioning text

cpc_ShowTileMap: Modified. Removed EI/DI instructions to avoid music/sound delays while showing tile Map.

cpc_RRI, cpc_RLI: Modified. There was a bug when using IX.

cpc_ScanKeyboard: New routine for scanning whole keyboard (from cpcwiki keyboard programming).

cpc_TestKeyF: New routine to test if a key has been pressed but it must be used after cpc_ScanKeyboard. This way is faster than previous one if 3 or more keys have to be tested.

cpc_WyzPlayer: Modified interruption backup because previously it assumed it was a JP XXXX jump and sometimes is not correct.

Example disc included: All the code examples compiled and ready to run in a single disk.

 

03/23/2009

cpc_RRI: Moves a screen rectangle one byte to the left (<-), most left byte goes to the right side (no byte info lost)

cpc_RLI: Moves a screen rectangle one byte to the right (->), most left byte goes to the left side (no byte info lost)

 

03/20/2009

cpc_TouchTiles: New routine to set a tile rectangle as touched in order to be shown in the next cpc_ShowTouchedTiles call.

 

02/23/2009

cpc_GetTiles, cpc_PutTiles: New routines to capture into a buffer a tile map area and to copy from buffer to tile map.

 

02/22/2009

cpc_UpdScr: Routine has been modified in order to get faster code.

cpc_PutCpTileMapo2b:  New routine to draw compiled sprites into the map tile.

 

02/20/2009

Multiplication routine almost always can be substituted by a specific faster one. Routines were generic multiplication is used can be fast changed modifying code in multiplication1.asm and multiplication2.asm before compiling the library. Using optimized multiplication routines gets better performance in the program so it’s recommended to use them. 

 

02/19/2009

cpc_PutSpTileMap: Code optimized, smaller and faster. Now tiles touched by a sprite are found faster.

 

02/16/2009

cpc_PutTrSpriteTileMap2b: New routine similar to cpc_PutTrSpTileMap2b but without the internal buffer address calculation, it requires use of cpc_SpUpdX and cpc_SpUpdY to update the sprite position or by the normal way but using cpc_SuperbufferAddress() after x,y update.

cpc_UpdateTileMap: Update to include cpc_PutTrSpTileMap2 and cpc_PutTrSpriteTileMap2 routines.

 

02/11/2009

cpc_ScrollLeft0, cpc_ScrollLeft, cpc_ScrollRight0, cpc_ScrollRight: New routines for software scroll using tile map. (See example included in file)

 

02/09/2009

cpc_PutTrSpTileMap2b: Draws a sprite using one of the colours as transparent. It requires selecting transparent colour during compilation. (See example included in file)

 

01/16/2009

cpc_TestKey : Code optimized, smaller and faster.

cpc_RedefineKey: Code optimized, smaller and faster.

cpc_AnyKeyPressed: Rewritten, smaller and faster.... previous version doesn't work.

cpc_SetBorder: Changed caller function, now it's smaller and faster routine.

cpc_InitTileMap: Changed caller function, now it's smaller and faster routine.

 

05/21/2008

New uncruch routine: Exomizer. Z80 code by Metalbrain, compression algorithm by Magnus Lind. Exomizer crunch files more than pucrunch does.

 

03/12/2008

Minor changes in tile map sprite drawing: The superbuffer address is updated during the drawing.

 

02/28/2008

New function added: it make all the steps in the sprite drawing when drawing in a tile map. cpc_UpdateTileMap(spriteList). Small sprite demo sample modified to support this new function.

 

02/21/2008

Touched tiles code modified, now it’s only required to modify the table in TileMapConf.asm file.

 

02/16/2008

New functions added

cpc_SetInkGphStr(char colour, char value)        Set text char colours in mode 0. It replaces cpc_SetColorGphStr.

cpc_SetInkGphStrM1(char colour, char value)    Set text char colours in mode 1.

cpc_PutMaskSpriteTileMap2b(sprite)                 Previously this routine was cpc_PutSpTileMap2b, renamed.

cpc_PutSpTileMap2b(   sprite)                          Draws an unmasked sprite in a tile map.

 

02/13/2008

New functions added

cpc_PutTile4x16(int *tile, char *x, char *y)          Draw 4x16 tiles directly in the screen

cpc_AnyKeyPressed()                                      If a key is pressed it returns 1 else returns 0.

cpc_SetColorGphStr(char colour, char value)     Set text char colours in mode 0.

 

And some bugs corrected in mode 0 text routines.

 

Specs.

 

Sprite Managing.

Tile-Mapping.

Keyboard.

Uncompressing pucrunch files.

Printing text graphically.

Screen routines.

Sound & music.

 

 

 

Routines and functions.

 

 Sprite Managing routines.

 

A sprite is a two-dimensional image that can be drawn everywhere in the screen as many times as wanted.  The next routines put sprites in the screen by several drawing methods.

 

This is the sprite data used in the examples:

 

extern char sprite[];

extern char sprite_sd[];

extern char sprite_mask0[];

extern char sprite_mask[];

 

#asm

._sprite

defb 2,2         // width, height

._sprite_sd

defb $ff,$ff      //sprite data

defb $ff,$ff

._sprite_mask0

defb 2,2

._sprite_mask

defb &ff,0,&ff,0

defb &ff,0,&ff,0

#endasm

 

 

And this is the sprite structure used in the routines: 

 

struct st_sprite {         // minimun sprite structure to be used in sprite functions.

        int sp0;            //2 bytes: sprite data    0-1

        int sp1;            //2 bytes: previos sprite data   2-3

        int coord0;         //2 bytes: superbuffer address   4-5   

        int coord1;         //2 bytes: previouse superbuffer address      6-7

        unsigned char cx, cy;     //2 bytes: sprite cordinates     8-9

        unsigned char ox, oy;     //2 bytes: previous sprite cordinates  10-11

        unsigned char pm;   //1 byte: sprite printing method.      12

        unsigned char move; // 13 

} ;

 

 

 

 

 

The sprite data is divided in two parts: The first one is two bytes representing the sprite dimension in bytes (if it is a masked sprite, the dimensions are the same as if it were an unmasked sprite).

The second one is the sprite data; it is a serial of bytes that represent the sprite in the way the CPC screen understands.

 

 

cpc_PutSp

 

void cpc_PutSp(int *sprite, char *height, char *width, int *address)

 

Puts the sprite in the specified address. The sprite dimensions are in the call parameters, not in the sprite data.

 

Parameters:

sprite: Sprite data (without dimensions)

height : sprite height

width: sprite width

address: screen address where the sprite will be drawn

 

Returns:

Draws the sprite in the specified address.

 

See also:

cpc_PutSpTr, cpc_PutMaskSp, cpc_PutSpXOR

 

 

Example:

 

// puts a 2x2 sprite in 0xc000 (start of standard screen address)

cpc_PutSp(sprite_sd,2,2,0xc000);    

 

 

 

 

 

 

 

 

cpc_PutSpXOR

 

void cpc_PutSpXOR(int *sprite, char *height, char *width, int *address)

 

Puts the sprite in the specified address, using XOR method with the screen byte. The sprite dimensions are in the call parameters, not in the sprite data.

 

Parameters:

sprite: Sprite data (without dimensions)

height : sprite height

width: sprite width

address: screen address where the sprite will be drawn

 

Returns:

Draws the sprite in the specified address.

 

See also:

cpc_PutSpTr, cpc_PutMaskSp, cpc_PutSp

 

 

Example:

 

// puts a 2x2 sprite in 0xc000 (start of standard screen address)

cpc_PutSpXOR(sprite_sd,2,2,0xc000); 

 

 

 

 

 

 

 

cpc_PutMaskSp

 

void cpc_PutMaskSp(int *sprite, char *height, char *width, int *address)

 

Puts a masked sprite in the screen, the first byte is the mask data, the second the sprite data. The sprite dimensions are in the call parameters, not in the sprite data.

 

Parameters:

sprite: Sprite data (without dimensions)

height : sprite height

width: sprite width

address: screen address where the sprite will be drawn

 

Returns:

Draws the sprite in the specified address.

 

See also:

cpc_PutSpTr, cpc_PutSpXor, cpc_PutSp

 

Example:

 

// puts a 2x2 sprite in 0xc000 (start of standard screen address)

cpc_PutMaskSp(sprite_mask,2,2,0xc000);     

 

 

 

 

 

 

 

cpc_PutSpTr

 

void cpc_PutSpTr(int *sprite, char *height, char *width, int *address)

 

Puts mode 0 sprite taking into account that colour number 0 is transparent so the background is shown.

 

Parameters:

sprite: Sprite data (without dimensions)

height : sprite height

width: sprite width

address: screen address where the sprite will be drawn

 

Returns:

Draws the sprite in the specified address.

 

See also:

cpc_PutMaskSp, cpc_PutSpXOR, cpc_PutSp

 

Example:

 

// puts a 2x2 sprite in 0xc000 (start of standard screen address)

cpc_PutSpTr(sprite_sd,2,2,0xc000);  

 

 

 

 

 

 

 

cpc_PutSprite

 

void cpc_PutSpTr(int *sprite, int *address)

 

Puts the sprite in the specified address. The sprite dimensions are in the sprite data.

 

Parameters:

sprite: Sprite data including width and height.

address: screen address where the sprite will be drawn

 

Returns:

Draws the sprite in the specified address.

 

See also:

cpc_PutMaskSprite, cpc_PutSpriteXOR

 

Example:

 

// puts a 2x2 sprite in 0xc000 (start of standard screen address)

cpc_PutSprite(sprite,0xc000); 

 

 

 

 

 

 

cpc_PutMaskSprite

 

void cpc_PutMaskSprite(int *sprite, int *address)

 

Puts a masked sprite in the specified address. The sprite dimensions are in the first and second sprite bytes. Next bytes are the mask and the sprite bytes alternatively.

 

Parameters:

sprite: Sprite data including width and height.

address: screen address where the sprite will be drawn

 

Returns:

Draws the sprite in the specified address.

 

See also:

cpc_PutSprite, cpc_PutSpriteXOR

 

Example:

 

// puts a 2x2 sprite in 0xc000 (start of standard screen address)

cpc_PutMaskSprite(sprite_mask0,0xc000);    

 

 

 

 

 

 

cpc_PutSpriteXOR

 

void cpc_PutSpriteXOR(int *sprite, int *address)

 

Puts the sprite in the specified address, using XOR method with the screen byte, sprite dimensions are in the sprite data.

 

Parameters:

sprite: Sprite data including width and height.

address: screen address where the sprite will be drawn

 

Returns:

Draws the sprite in the specified address.

 

See also:

cpc_PutSprite, cpc_PutMaskSprite

 

Example:

 

// puts a 2x2 sprite in 0xc000 (start of standard screen address)

cpc_PutMaskSprite(sprite,0xc000);   

 

 

 

 

 

 

cpc_PutMaskSp2x8

 

void cpc_PutMaskSp2x8(int *sprite, int *address)

 

Puts a 2x8 bytes masked sprite in the specified address. The sprite has not the dimensions in its data definition. The porpoise of this routine in provide a faster method for drawing 2x8 sprites.

 

Parameters:

sprite: Sprite data including width and height.

address: screen address where the sprite will be drawn

 

Returns:

Draws the sprite in the specified address.

 

See also:

cpc_PutMaskSp4x16

 

Example:

 

 

 

 

 

 

cpc_PutMaskSp4x16

 

void cpc_PutMaskSp4x16(int *sprite, int *address)

 

Puts a 4x16 bytes masked sprite in the specified address. The sprite has not the dimensions in its data definition. The porpoise of this routine in provide a faster method for drawing 4x16 sprites.

 

Parameters:

sprite: Sprite data including width and height.

address: screen address where the sprite will be drawn

 

Returns:

Draws the sprite in the specified address.

 

See also:

cpc_PutMaskSp2x8

 

Example:

 

 

 

 

 

 

cpc_GetSP

 

void cpc_GetSp(int *buffer, char height, char width, int *origin)

 

Captures a screen area starting from origin and sized by width and height and copy it to buffer.

 

Parameters:

buffer: captured data destination.

height: capture height.

width:  capture width.

origin: capture starting address.

 

Returns:

 

See also:

 

Example:

See sprites example code.

 

 

 

 

cpc_CollSp

 

char cpc_CollSp(struct sprite0, struct sprite1)

 

Test if two sprites are colliding. Parameters include the position of the sprites and the sprites.

 

Parameters:

sprite0: sprite structure

sprite1: sprite structure

 

Returns:

Return 1 if both sprites are colliding, 0 if not colliding.

 

See also:

 

Example:

See small sprite demo.

 

 

 

 

 

cpc_SpRRM1

 

void cpc_SpRRM1(int *sprite)

 

Rotate to the right a mode 1 sprite.

 

Parameters:

sprite: sprite data with dimensions.

 

Returns:

 

See also:

cpc_SPRLM1

 

Example:

cpc_SpRRM1(sprite_mask0);

 

For a full example, see sprite rotation mode 1 code.

 

 

 

 

cpc_SpRLM1

 

void cpc_SpRLM1(int *sprite)

 

Rotate to the left a mode 1 sprite.

 

Parameters:

sprite: sprite data with dimensions.

 

Returns:

 

See also:

cpc_SPRLM1

 

Example:

cpc_SpRLM1(sprite_mask0);

 

For a full example, see sprite rotation mode 1 code.

 

 

 

 

 

 

 

 

Tiles

 

Tiles are fixed elements in the screen, usually for map drawing. There are some specific routines for tiles, but the sprite routines can be used in the same way for drawing tiles.

 

cpc_PutTile2x8

 

void cpc_PutTile2x8(int *tile, char x, char y)

 

Puts the 2x8 bytes tile in the specified address given in x,y coordinates.

 

Parameters:

tile: Tile data without dimensions.

x: screen coordinate

y: screen coordinate

 

Returns:

Draws the sprite in the specified address.

 

See also:

cpc_PutTile4x16

 

Example:

 

 

 

 

cpc_PutTile4x16

 

void cpc_PutTile4x16(int *tile, char x, char y)

 

Puts the 4x16 bytes tile in the specified address given in x,y coordinates.

 

Parameters:

tile: Tile data without dimensions.

x: screen coordinate

y: screen coordinate

 

Returns:

Draws the sprite in the specified address.

 

See also:

cpc_PutTile2x8

 

Example:

 

 

 

 

 

General example about sprites (from masked sprite sample)

#include "cpcrslib.h"

 

extern unsigned char sp_8x8[];

extern unsigned char sp_16x16[];

extern unsigned char tile_8x8[];

extern unsigned char buffer[];

 

#asm

._sp_8x8

defb $88,$70,$11,$E0             //MASK, SPRITE, MASK, SPRITE...  Mask is drawn using highest ink number

defb $11,$E0,$88,$70            

defb $00,$96,$00,$96

defb $00,$F0,$00,$F0

defb $00,$F7,$00,$FE

defb $00,$C7,$00,$3E

defb $00,$F3,$00,$FC

defb $88,$70,$11,$E0

 

._sp_16x16

defb $88,$70,$11,$E0,$88,$70,$11,$E0   //MASK, SPRITE, MASK, SPRITE...

defb $11,$E0,$88,$70,$11,$E0,$88,$70  

defb $00,$96,$00,$96,$00,$96,$00,$96

defb $00,$F0,$00,$F0,$00,$F0,$00,$F0

defb $00,$F7,$00,$FE,$00,$F7,$00,$FE

defb $00,$C7,$00,$3E,$00,$C7,$00,$3E

defb $00,$F3,$00,$FC,$00,$F3,$00,$FC

defb $88,$70,$11,$E0,$88,$70,$11,$E0

defb $88,$70,$11,$E0,$88,$70,$11,$E0

defb $11,$E0,$88,$70,$11,$E0,$88,$70

defb $00,$96,$00,$96,$00,$96,$00,$96

defb $00,$F0,$00,$F0,$00,$F0,$00,$F0

defb $00,$F7,$00,$FE,$00,$F7,$00,$FE

defb $00,$C7,$00,$3E,$00,$C7,$00,$3E

defb $00,$F3,$00,$FC,$00,$F3,$00,$FC

defb $88,$70,$11,$E0,$88,$70,$11,$E0

._tile_8x8

defb $07,$0E        //Unmasked

defb $2D,$C3       

defb $0F,$2D

defb $0F,$2D

defb $0F,$0F

defb $0F,$2D

defb $0F,$0F

defb $07,$0E

._buffer defs 64

#endasm

 

main(){

      

       cpc_SetMode(1);       //mode change. The interrupt standard jump must be disabled.

       cpc_SetModo(1);       //Firmware routine for mode changing.

                           

       cpc_SetColour(17,11);   //Ink change using hardware. The interrupt standard jump must be disabled.  

       cpc_SetInk(17,11); //Ink change using firmware.                          

 

       // Put a 2x8 bytes sprite in specified coordinates

       cpc_PutTile2x8(tile_8x8,10,90);

      

       // Put a 2x8 bytes masked sprite into the specified screen address (&C00B)

       cpc_PutMaskSp2x8(sp_8x8,0xc00b);

      

       // Same but using a 4x16 bytes sprite

       cpc_PutMaskSp4x16(sp_16x16,0xc190);

      

       // This routine is for using in mode 0 due to it uses ink 0 as transparent.

       cpc_PutSpTr(tile_8x8,8,2,0xc19b);

 

       // Put a sprite of specified dimensions into screen.

       cpc_PutSp(tile_8x8,8,2,0xc19b);

      

       // Captures a screen box of the specified dimensions and stores it onto memory

       cpc_GetSp(buffer,8,8,0xc054);

 

       // In this example, prints the captured area in &c190

       cpc_PutSp(buffer,8,8,0xc190);

 

       while (1){}  //Repeat until the end of the world

}

 

 

 

Arriba

 

Keyboard.

 

The library has been compiled in order to have 12 different keys available. If more keys are needed, modifying it is quite simple only space for key assignation is required in cpc_KeysData.

 

cpc_RedefineKey

 

void cpc_RedefineKey(char number)

                 

Waits until a key is pressed and assigns it to the key number specified

 

Parameters:

number: Key number to be assigned

 

Returns:

 

See also:

cpc_AssignKey

 

Example:

cpc_Redefinekey(0);      //assign next key pressed to number 0

 

 

 

 

cpc_AssignKey

 

void cpc_AssignKey(char number, int value)

                 

Assign  a key to the specified key number.

 

Parameters:

number: Key number to be assigned

value: Represents a key so must be selected from  correct values in order to work correctly. Values must be taken from the keyboard table.

 

Returns:

 

See also:

cpc_RedefineKey

 

Example:

cpc_AssignKey(0,0x4002) Assing the cursor right to key 0.

 

 

 

cpc_TestKey

 

char cpc_TestKey(char number)

 

Tests if the key assigned to selected number has been pressed.

 

Parameters:

number: Key number to be checked

 

Returns:

Returns 1 if key assigned to number is pressed else return 0.

 

See also:

cpc_AnyKeyPressed, cpc_TestKeyF

 

Example:

cpc_TestKey(0);      //test if key assigned to number 0 has been pressed

 

 

 

cpc_AnyKeyPressed

 

char cpc_AnyKeyPressed(void)

 

Tests if any key has been pressed.

 

Parameters:

 

Returns:

Returns 1 if any key has been pressed else return 0.

 

See also:

cpc_TestKey, cpc_TestKeyF

 

Example:

While (!cpc_AnyKeyPressed()){};      //wait until any key pressed.

 

 

 

cpc_ScanKeyboard

 

void cpc_ScanKeyboard(void)

 

Scan entire keyboard and stores all keys pressed.

 

Parameters:

 

Returns:

 

See also:

cpc_TestKeyF

 

Example:

cpc_ScanKeyboard();      //Scan entire keyboard

 

 

 

cpc_TestKeyF

 

char cpc_TestKeyF(char number)

 

Tests if the key assigned to selected number has been pressed. Use it after cpc_ScanKeyboard. This pair of routines is recommended when 3 or more keys must be checked. It’s recommended in order to decrease the execution time.

 

Parameters:

number: Key number to be checked

 

Returns:

Returns 1 if key assigned to number is pressed else return 0.

 

See also:

cpc_AnyKeyPressed, cpc_ScanKeyboard, cpc_TestKey

 

Example:

cpc_ScanKeyboard();

cpc_TestKeyF(0);      //test if key assigned to number 0 has been pressed

cpc_TestKeyF(1);      //test if key assigned to number 1 has been pressed

 

 

 

 

 

Keyboard table (source: cpcwiki)

 

Byte:
Line

&80

&40

&20

&10

&08

&04

&02

&01

&40

F Dot

ENTER

F3

F6

F9

CURDOWN

CURRIGHT

CURUP

&41

F0

F2

F1

F5

F8

F7

COPY

CURLEFT

&42

CONTROL

\

SHIFT

F4

]

RETURN

[

CLR

&43

.

/

 :

 ;

P

@

-

^

&44

,

M

K

L

I

O

9

0

&45

SPACE

N

J

H

Y

U

7

8

&46

V

B

F

G (Joy2 Fire)

T (Joy2 Right)

R (Joy2 Left)

5 (Joy2 Down)

6 (Joy2 Up)

&47

X

C

D

S

W

E

3

4

&48

Z

CAPSLOCK

A

TAB

Q

ESC

2

1

&49

DEL

-

-

Joy1 Fire

Joy1 Right

Joy1 Left

Joy1 Down

Joy1 Up

 

 

Example about keyboard managing (from keyboard sample)

#include "cpcrslib.h"

 

main(){

       cpc_SetModo(1);                              //Set mode using firmware

       cpc_PrintStr("Press key to redefine"); //Show text using firmware

       cpc_RedefineKey(0);                   //redefine key.

       cpc_PrintStr("Press key to test it");

       while (1) {

             if (cpc_TestKey(0)==1) {  //test if the key has been pressed.

                    cpc_PrintStr("ok");

             }

       }

}

 

Another example using alternative testing routines

#include "cpcrslib.h"

 

main(){

       cpc_SetModo(1);                              //Set mode using firmware

       cpc_PrintStr("Press key to redefine"); //Show text using firmware

       cpc_RedefineKey(0);                   //redefine key.

       cpc_PrintStr("Press key to test it");

       while (1) {

             cpc_ScanKeyboard();

             if (cpc_TestKeyF(0)==1) { //test if the key has been pressed.

                    cpc_PrintStr("ok");

             }

       }

}

 

 

 

 

Arriba

 

 

Uncompressing.

 

Two routines have been included in order to support compressed files by Pucrunch and Exomizer compressors.

 

cpc_Uncrunch

 

void cpc_Uncrunch(int origin, int destination)

 

Uncompress a pucrunch compressed file.

 

Parameters:

origin: address of the compressed data.

destination: address where the data will be uncompressed

 

Returns:

 

See also:

cpc_UnExo

 

Example:

See example below

 

 

 

cpc_UnExo

 

void cpc_UnExo(int origin, int destination)

 

Uncompress a exomizer compressed file

 

Parameters:

origin: address of the compressed data.

destination: address where the data will be uncompressed

 

Returns:

 

See also:

cpc_Uncrunch

 

Example:

See example below

 

 

 

 

Example about uncrunching file (from pucrunch sample)

#include "cpcrslib.h"

extern unsigned char binary_data[];

#asm

._binary_data

   BINARY "tonteria.pu"   //includes a pucrunch file

#endasm

 

main(){

       cpc_SetModo(1);

       cpc_Uncrunch(binary_data,0xc000);

       while (1) {}

}

 

 

 

Note: In the cpcrslib pack  windows executable files to compress from a DOS box are included. Syntax:

 

pucruch -d -c0 filein fileout

 

exo filein fileout

 

Fileout is the file to incluye in the C program to be uncompressed by cpcrslib.

 

Arriba

 

Writting text grapically.

 

These routines allow text writing in a screen position (in mode 0 or mode 1)

 

Mode 0:

cpc_PrintGphStr("HI;BOY<",0xc190);                         // specifying screen address

cpc_PrintGphStrXY("BYE;GUY<",20,100);                 //screen coordinates x,y

cpc_SetInkGphStr(char colour, char value);              // Set text char colour in mode 0. Each char is defined up to 4 colours (0..3), values for a nice result are:

0

2

8

10

32

34

40

42

128

130

136

138

160

162

168

170

                                                                                  

Mode 1:

cpc_PrintGphStrM1("HI;BOY <",0xc190);                   //specifying screen address

cpc_PrintGphStrXYM1("BYE;GUY <",20,100);                        //screen coordinates x,y

cpc_SetInkGphStM1r(char colour, char value);                      // Set text char colour in mode 1. Each char is defined up to 4 colours (0..3). ), values for a nice result are:

0, 8, 128, 136

 

Each character is 4x8 pixels and can be modified in cpc_Chars.asm file and compiling the library.

 

Arriba

 

 

Screen

 

Mode Selection

cpc_SetMode(mode)               //Hardware routine. It requires disabling the Standard jump of the interruption.     

cpc_SetModo(mode)               // firmware routine

 

Ink change:

cpc_SetColour(ink number,  hardware colour)           //Hardware routine. It requires disabling the Standard jump of the interruption.         

                                  

 

//firmware:

cpc_SetBorder(colour)

cpc_SetInk(ink number, colour)         

 

 

cpc_GetScrAddress(x,y)                     //returns the x,y coordinates screen address. For example:  cpc_ScrAdress(0,0) -> &C000

 

 

//Rotation routines

cpc_RLI(screen rectangle origin, width, height)

cpc_RRI(screen rectangle origin, width, height)

 

#include "cpcrslib.h"

 

void main (void) {

       while (1){

             cpc_RRI(0xc050+8,10,50);

             cpc_RLI(0xc050+50,10,50);

       }

}

 

 

 

Almost all the library routines are in the included examples.

 

Arriba

 

Sound & music

 

 

This library cpcwyzlib includes a sound player coded by WYZ.  Don’t forget compiling with –lcpcwyzlib.

Tracker available at: WYZTracker in CPCWiki There are threads about it in a Spanish forum: Amstrad.es Forum WYZTracker thread and in CPCWiki forum: CPCWiki thread

 

cpc_WyzInitPlayer(SOUND_TABLE  RULE_TABLE,  EFFECT_TABLE, SONG_TABLE);  //Configure the placer with required data

cpc_WyzSetBuffer(int buffer);            //Set music buffer. Must be done before loading and playing any song.

cpc_WyzLoadSong(0);                       //select song number

cpc_WyzSetPlayerOff();                     //stop music and sound

cpc_WyzSetPlayerOn();                     //activate music and sound

cpc_WyzStartEffect(2,1);                    //play a sound effect #1 in channel 2

 

Tracker can be used to make music for the WYZPlayer but not to make sound effects (SFX), however SFX format is quite simple:

 

defb byte1,byte2

defb byte1,byte2

...

defb &ff

 

Where byte 1 and bits 7, 6, 5 & 4 from byte2 are the sound frequency and bits 3, 2, 1 & 0 of byte2 is the amplitude. Effect finishes when &ff is found.

 

 

Arriba

 

Tile Map

 

List of functions and routines:

 

cpc_UpdScr()

cpc_UpdScrAddresses()

cpc_ShowTileMap(z)

cpc_SetTile(tx,ty,tile)

cpc_SetTouchTile(tx,ty,tile)

cpc_ReadTile(tx,ty)

cpc_TouchTileXY(x,y)

cpc_ShowTouchedTiles()

cpc_PutSpTileMap(struct sprite)

cpc_PutTrSpTileMap2b(sprite)

cpc_PutTrSpriteTileMap2b(sprite)

cpc_PutMaskSpTileMap2b(sprite)

cpc_PutMaskSpriteTileMap2b(sprite)

cpc_PutORSpTileMap2b(sprite)

cpc_PutCpTileMapo2b(sprite)

cpc_SuperbufferAddress(x,y)

cpc_ResetTouchedTiles()

cpc_SpUpdX(struct sprite, value)

cpc_SpUpdY(struct sprite, value)

 

cpc_ScrollRight0();

cpc_ScrollLeft0();

cpc_ScrollRight();

cpc_ScrollLeft();

 

cpc_GetTiles(x,y,w,h,buffer);

cpc_PutTiles(x,y,w,h,buffer);

cpc_TouchTiles(x,y,w,h);

 

 

 

How to use the tile map routines.

 

A little bit of theory.

 

This routines allow to draw and to move sprites in the screen without blinking and regenerating the background.  Sprites can be of whatever dimensions, and can be whatever number of them, but is necessary to consider that the capacities of the CPC are limited and the bigger and the more sprites in the screen, the CPC will require more time to draw them.

 

Tile are of 2x8 bytes (width x height). The maximum definable are is 40x20 tile, depending on the screen mode this will be 320x160 pixels ( mode 1) or 160x160 pixels (mode 0).

 

The tiles and the sprites are drawn in a buffer area call superbuffer. The visible screen is updated from this superbuffer.

 

The superbuffer, in used memory would be 40x2x160 bytes=12800 bytes (&3200) at the most. By default, the beginning of the superbuffer is located at &100 and would arrive at the most until &3300 (&3200+&100). It is important to have this into account to put the beginning of the program code over the superbuffer, if no, when using it, it will crash giving unexpected results in the execution.

 

 

Steps drawing a tile map in the screen:

 

1. Set the map tiles. The map is a matrix (10x5 tile example):

{  1, 1, 1, 1, 1, 1, 1, 1, 1, 1

   0, 0, 0, 0, 0, 0, 0, 0, 0, 0

   0, 0, 0, 0, 0, 0, 0, 0, 0, 0

   0, 0, 0, 0, 0, 0, 0, 0, 0, 0

   2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }

 

2. Send whole superbuffer to the visible screen.

 

Representing a sprite requiere next steps:

1. Look up the tiles touched by the sprite in its present position and in its previous one (phase 1). These tiles are the touched tiles.

2. Supperbuffer touched tiles are updated to clear its last state.

3. The sprites are drawn in superbuffer (phase 2)

4. Touched tiles are sent to the visible screen. The sprite is shown in its new position.

 

There are two kinds of coordinates: Tile coordinates (tx.ty) and screen coordinates(x,y). The first ones refer to the tile map (see example above) and the screen coordinates refer to the pixel (better, the byte) of the sprite in superbuffer.

For example, (x,y)=(10,10) points somewhere in the red tile of the sample map.

(tx,ty)=(2,3) is the blue tile of the sample map.

 

 

 

Now, a little bit of practise:

 

Defining screen:

 

Set each map tile:

cpc_SetTile(x,y,tile);

 

This code defines the example map:

 

void draw_tilemap(void) {

      unsigned char x,y;

      y=0;

      for(x=0; x<10;x++) {

            cpc_SetTile(x,y,1);

      }

      for(y=1;y<4;y++) {

            for (x=0; x<10;x++) {

            cpc_SetTile(x,y,0);

            }

      }

      y=4;

      for (x=0; x<10;x++) {

            cpc_SetTile(x,y,2);

      }

}

 

 

2º. Show entire map screen:

cpc_ShowTileMap(0);

 

 

Having defined the screen, we can put sprites on it.

The next structure is mandatory to define the sprites:

 

struct sprites{  

      int sp0;          //2 bytes   Current Sprite

      int sp1;          //2 bytes   Previous Sprite

      int coord0;       //2 bytes   superbuffer address

      int coord1;       //2 bytes   Previous superbuffer address

      unsigned char cx, cy;   //2 bytes   Current coordinates

      unsigned char ox, oy;   //2 bytes   Previous coordinates

      unsigned char move;     //Not yet implemented.

}

 

If new fields are required, they will be added at the end of the structure.

 

To initialise a sprite, these are the fields to be filled:

           sp0 (current sprite data)

           sp1 (current sprite data the first time)

           ox

           oy

           cx

           cy

 

Now the sprites can be drawn maintaining the background.

 

En un ciclo de movimiento, lo primero que hay que hacer es resetear la tabla de tiles tocados (los últimos que se han traladado a la pantalla visible):

cpc_ResetTouchedTiles();

 

Draw and move sprites is a 4 steps cycle:

 

1. All the sprites to superbuffer (phase 1)

cpc_PutSpTileMap(sprite00);

cpc_PutSpTileMap(sprite01);

...

(This update the touched tile table to be restablished later)

 

To update a tile during the sprite movement cycle:

cpc_SetTile(tx,ty,tile);

cpc_TouchTileXY(tx,ty);   //mete el tile en la tabla de tiles tocados para restaurarlos

 

Or making the previous two functions in just one call:

cpc_SetTouchTile_xy(tx,ty,tile)

 

2. Clear superbuffer (where the sprites are):

cpc_UpdScr();

 

3. Drawing the sprites in superbuffer (Phase 2)

cpc_PutMaskSpTileMap2b(sprite00);

cpc_PutORSpTileMap2b(sprite01);

...

 

4.  Finally, all the touch tiles are sent to the visible screen:

cpc_ShowTouchedTiles();

 

 

That all!

There is several options to draw sprites in superbuffer:

cpc_PutMaskSpTileMap2b(): draw a masked sprite

cpc_PutTrSpTileMap2b(): draw an sprite using one o its colours as transparent. It requires two parameters to be included in compilation time: mascara1 & mascara2. See TileMapConf.asm

cpc_PutORSpTileMap2b  draw an unmasked sprite doing OR operation.

cpc_PutSpTileMap2b(): draw a unmasked sprite

 

cpc_ReadTile(tx,ty) return the tile number of the tile map spicified by (tx,ty)

 

Other way of moving sprites is with the following routines:

cpc_SpUpdX(struct sprite, value)       // move sprite left (<0) or right (>0) in the value quantity 

cpc_SpUpdY(struct sprite, value)       // move sprite up (<0) or down (>0) in the value quantity 

cpc_PutMaskSpriteTileMap2b(struct sprite)   // puts the masked sprite in the tile map, it’s faster than cpc_PutMaskSpTileMap2b but requires to move sprite with the functions cpc_SpUpdX or cpc_SpUpdX, there is an example in small_sprite_demo.c file.

cpc_PutTrSpriteTileMap2b(struct sprite): // puts the masked sprite in the tile map, it’s faster than cpc_PutTrSpTileMap2b but requires to move sprite with the functions cpc_SpUpdX or cpc_SpUpdX,

 

cpc_UpdateTileMap(listaSprites)         // it includes all the functions to draw sprites in the screen in a single function. This function makes previously defined steps without

cpc_SetTile(tx,ty,tile), cpc_TouchTileXY(tx,ty) y cpc_SetTouchTileXY(tx,ty,tile) functions that will be called before cpc_UpdateTileMap() and after cpc_ResetTouchedTiles().

 

The parameter is a list of the sprites that are going to be drawn. Last element of the list must be 0xffff.

int spriteList[10];
spriteList[0]=sprite00;
...
sprite[n]=0xffff; //last element


On the other hand, the control of if sprite draws or recovers its background does with the value move of the structure of sprites. So that is made first stage the program pays attention to bit 0 of move. If it is 0 is not executed, if it is 1, is executed.


In order to see if sprite is drawn in the map of tiles, code pays attention to bits 1, 2 and 3 of move. If they are 000 not  draws sprite. The remaining values are:
001 -> cpc_PutMaskSpriteTileMap2b
010 -> cpc_PutMaskSpTileMap2b
011 -> cpc_PutORSpTileMap2b
100 -> cpc_PutSpTileMap2b

101 -> cpc_PutTrSpTileMap2

110 -> cpc_PutTrSpriteTileMap2

For example, I want to draw sprite00 with the last function all the short while, and that always recovers its bottom: the value move would be 00001001 in binary.... as not how a binary number in z88dk goes, I put it in decimal:
sprite00.move=9;
If sprite does not move of its site, it is enough drawing it without recovering its background:

sprite00.move=8; //00001000
If I want to recover the background but that sprite is not drawn (for example, to make disappear sprite that before was drawn):
sprite00.move=1; //00000001
And so on.

 

Scrolling routines

4 new functions have been added to have horizontal software scroll. These are not enhanced scrolling routines and maybe are not very usefull but they can be used to make some kind of effects. Each step scrolls a tile to the left or to th right. Scrolling consists in two steps:

1.     Moving background tile map with cpc_ScrollLeft0() or cpcScrollRight0(). Before doing this step, tile map updating is mandatory because the left or the right column has been moved (or deleted) and it’s time to update it with new screen information.

2.     Scrolling visible area with cpc_ScrollLeft() or cpcScrollRight(). This step get the new left or right tile column and draw it on visible screen before scrolling.

It has been included a new example using scroll: see scroll_transparent folder.

 

For scrolling is needed the left column of the screen to be defined in TileMapConf.asm file.

 

Tile Map Capturing

 

cpc_GetTiles(unsigned char x, unsigned char y, unsigned char w, unsigned char h, int buffer)

Captures tiles in area defined by x,y,w,h and stores them into buffer

For example:

Int buffer[6];

cpc_GetTiles(1,4,2,3,buffer);

 

Captures and stores into buffer a rectangle defined by x=1, y=4 and width=2 and height=3. Capture next tiles (1,4),(1,5), (2,4),(2,5), (3,4),(3,5)

 

cpc_PutTiles(unsigned char x, unsigned char y, unsigned char w, unsigned char h, int buffer)

Read buffer for tiles and set tile map from them:

For example:

Int buffer[6];

cpc_PutTiles(1,4,2,3,buffer);

 

Sets next tiles (1,4),(1,5), (2,4),(2,5), (3,4),(3,5) from buffer.

 

 

 

TileMapConf.asm

This file is the configuration file of the tile map:

Buffer address

Visible screen address

Tile data

Tile map dimension…

It has to be linked during the compilation (take a look at the tile examples make.bat file)

 

XLIB TileMapConf

 

XDEF tiles

XDEF pantalla_juego

XDEF tiles_tocados

XDEF posiciones_pantalla

XDEF posiciones_super_buffer

 

XDEF posicion_inicial_area_visible

XDEF posicion_inicial_superbuffer

XDEF ancho_pantalla_bytes

XDEF alto_pantalla_bytes

XDEF ancho_pantalla_bytes_visible

 

; ***************************************************

; Transparent colour for cpc_PutTrSpTileMap2b/ cpc_PutTrSpriteTileMap2b routine

XDEF mascara1

XDEF mascara2

; ***************************************************

 

 

;XDEF tile

; ***************************************************

; Scroll Left Addresses column

; not requiered if scroll not used

XDEF ColumnScr

; ***************************************************

 

 

; ***************************************************

; Transparent colour for cpc_PutTrSpTileMap2b routine

; For printing sprites using transparent color (mode 0) transparent color selection is requiered.

; Selección color transparente. Escribir las 2 máscaras que correspondan al color elegido.

;Example colour number 7:

defc mascara1 = $54   

defc mascara2 = $a8

;0: $00, $00

;1: $80, $40

;2: $04, $08

;3: $44, $88

;4: $10, $20

;5: $50, $A0

;6: $14, $28

;7: $54, $A8

;8: $01, $02

;9: $41, $82

;10: $05, $0A

;11: $45, $8A

;12: $11, $22

;13: $51, $A2

;14: $15, $2A

;15: $55, $AA

; ***************************************************

 

 

 

;------------------------------------------------------------------------------------

; SCREEN AND BUFFER ADDRESSES

;------------------------------------------------------------------------------------

defc posicion_inicial_area_visible = $c050         ;Begin of the screen area

defc posicion_inicial_superbuffer = $100           ;Begin of the superbuufer (2x8xT_WIDTHxT_HEIGHT  bytes)

;------------------------------------------------------------------------------------

 

;------------------------------------------------------------------------------------

; TILE MAP DIMENSIONS

;------------------------------------------------------------------------------------

defc T_WIDTH = 32                  ;max=40 tiles                           

defc T_HEIGHT = 16                 ;max=20 tiles

;------------------------------------------------------------------------------------

 

 

 

;------------------------------------------------------------------------------------

; Other parameters (internal use)

;------------------------------------------------------------------------------------

;------------------------------------------------------------------------------------

; El ancho de pantalla influye determinantemente en numerosas rutinas que hay que actualizar si se cambia.

defc ancho_pantalla_bytes = 2*T_WIDTH          ;Cada tile es de 2 bytes de ancho.

defc alto_pantalla_bytes = 8*T_HEIGHT             ;Cada tile es de 8 bytes de alto.

defc ancho_pantalla_bytes_visible = 2*T_WIDTH  ;dentro del area definida, cuánto se debe mostrar.

 

.TileMapConf

;------------------------------------------------------------------------------------

.posiciones_pantalla                                         ;Posiciones en las que se dibujan los tiles

defw posicion_inicial_area_visible+$50*0

defw posicion_inicial_area_visible+$50*1 

defw posicion_inicial_area_visible+$50*2

defw posicion_inicial_area_visible+$50*3

defw posicion_inicial_area_visible+$50*4

defw posicion_inicial_area_visible+$50*5

defw posicion_inicial_area_visible+$50*6

defw posicion_inicial_area_visible+$50*7

defw posicion_inicial_area_visible+$50*8

defw posicion_inicial_area_visible+$50*9

defw posicion_inicial_area_visible+$50*10

defw posicion_inicial_area_visible+$50*11

defw posicion_inicial_area_visible+$50*12

defw posicion_inicial_area_visible+$50*13

defw posicion_inicial_area_visible+$50*14

defw posicion_inicial_area_visible+$50*15

defw posicion_inicial_area_visible+$50*16

defw posicion_inicial_area_visible+$50*17

defw posicion_inicial_area_visible+$50*18

defw posicion_inicial_area_visible+$50*19

 

.posiciones_super_buffer                                              ;muestra el inicio de cada línea

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*0

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*1

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*2

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*3

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*4

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*5

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*6

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*7

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*8

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*9

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*10

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*11

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*12

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*13

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*14

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*15

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*16

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*17

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*18

defw posicion_inicial_superbuffer+8*ancho_pantalla_bytes*19

 

.pantalla_actual defw 0             

 

.pantalla_juego  defs T_WIDTH*T_HEIGHT         ;En tiles, es el mapa donde cada byte dice el tile que tiene.

defb $FF                                                          ;Este byte es importante, marca el fin de la pantalla.

 

.tiles_tocados defs 150  ;touch tile table

;cuando un tile es tocado, se marca en esta tabla para luego restaurarlo.

                                               ;Es una tabla sin duplicados. Cada tile tocado se representa por 2 bytes. Se pueden

                                               ;tocar hasta 75 tiles.

;------------------------------------------------------------------------------------

 

 

 

 

 

; ***************************************************

; Scroll Left Addresses column

; not requiered if scroll not used comment it ;)

; one word for each scrollable line

.ColumnScr

defw $C0AA

defw $C8AA

defw $D0AA

defw $D8AA

defw $E0AA

defw $E8AA

defw $F0AA

defw $F8AA

; ***************************************************

 

 

 

 

           

 

;------------------------------------------------------------------------------------

; TILE DATA. TILES MUST BE DEFINED HERE

;------------------------------------------------------------------------------------

.tiles                             ;Each tile is 2x8 bytes.

 

;defb 2,8

;defb $70,$c0

;defb $f0,$68

;defb $f0,$84

;defb $f0,$e0

;defb $f0,$a4

;defb $e0,$c0

;defb $50,$60

;defb $00,$00

 

Arriba

 

 

 

 

 

 

(c) Raúl Simarro 2007-09 Contact, doubts, suggestions, ...