File: bug.txt - Tab length: 1 2 4 8 - Lines: on off - No wrap: on off

[img]http://www.mirari.fr/Y5X0[/img]

Bon j'ai un peu optimis� le code et ajout� de quoi calculer les d�g�ts. �a finira peut �tre par faire un vrai jeu :p

Ah et les ennemis sont moins agressifs maintenant.
[box=test.c]
[code=c]
#pragma string name C TEST

#include "..\dev\ti83p.h"
#include "..\dev\tilib.c"
#include "..\dev\gbalib2.c"

// Sprites
#include "..\dev\sprites\title.h"
#include "..\dev\sprites\map.h"
#include "..\dev\sprites\map_player.h"
#include "..\dev\sprites\tiles.h"
#include "..\dev\sprites\battle_player_up.h"
#include "..\dev\sprites\battle_player_up_attack.h"
#include "..\dev\sprites\battle_player_right.h"
#include "..\dev\sprites\battle_player_right_attack.h"
#include "..\dev\sprites\battle_player_down.h"
#include "..\dev\sprites\battle_player_down_attack.h"
#include "..\dev\sprites\battle_player_left.h"
#include "..\dev\sprites\battle_player_left_attack.h"
#include "..\dev\sprites\battle_enemy.h"
#include "..\dev\sprites\battle_enemy_attack.h"

// Map
extern char battle_map[];
#asm
._battle_map
        defb 4,4,4,4,4,4,4,3,3,3,3,3,4,4,4,4,4,4,4,4
        defb 4,0,0,0,0,0,0,1,3,3,3,4,4,0,1,1,1,0,0,4
        defb 4,0,0,0,0,0,0,2,1,3,3,1,1,0,2,2,2,0,0,4
        defb 4,0,0,4,4,4,0,0,2,3,0,2,2,0,0,0,0,0,0,4
        defb 4,0,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,4
        defb 4,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4
        defb 4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4
        defb 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4
        defb 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4
        defb 4,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4
        defb 4,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4
        defb 4,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,4
        defb 4,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,4
        defb 4,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,4
        defb 4,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,4
        defb 4,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,4
        defb 4,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,4
        defb 4,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,4
        defb 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4
        defb 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
#endasm

// Constants
#define START   0
#define LOAD    1
#define QUIT    2
#define BATTLE_MAP_WIDTH        20
#define BATTLE_MAP_HEIGHT       20
#define ATTACK_ANIM_DELAY       45

// Global variables
unsigned char i, j, key, player_x = 80, player_y = 59, player_hp = 10, battle_player_x = 10, battle_player_y = 18, *battle_player_direction = 0, camera_x, camera_y, x_temp, y_temp, x_temp2, y_temp2;

typedef struct {
  unsigned char x;
  unsigned char y;
  unsigned char *sprite;
  unsigned char hp;
} enemy_struct;

enemy_struct enemy[4];

extern char text_menu[];
#asm
._text_menu
        defm "Nouveau"&TL_NEWL&"Continuer"&TL_NEWL&"Quitter"&0
#endasm

extern char text_intro[];
#asm
._text_intro
        defm "Vous viviez tranquillement"&TL_NEWL&"en dehors de la soci"&0x96&"t"&0x96&TL_NEWL&"jusqu'au jour o"&0xaf&" vous"&TL_NEWL&"d"&0x96&"couvrez qu'on vous a"&TL_NEWL&"vol"&0x96&"..."&TL_BRK&TL_NEWL&"Vous d"&0x96&"cidez alors de"&TL_NEWL&"partir "&0x8f&" la recherche"&TL_NEWL&"des voleurs."&TL_BRK&0
#endasm

extern char text_castle[];
#asm
._text_castle
        defm "Garde :"&TL_NEWL&"Passez votre chemin sale"&TL_NEWL&"manant !"&TL_BRK&0
#endasm

extern char text_hp[];
#asm
._text_hp
        defm "PV :"&0
#endasm

//Functions prototypes
void main_menu(void);
char draw_cursor(unsigned char x, unsigned char y);
void handle_map(void);
void update_map(void);
char draw_player(unsigned char old_player_x, unsigned char old_player_y, unsigned char player_x, unsigned char player_y);
char check_place(unsigned char player_x, unsigned char player_y);
void battle(void);
void update_battle_screen(void);
char is_location_empty(unsigned char x, unsigned char y);
char hit(unsigned char damage, unsigned char x, unsigned char y);

//Functions
char main(){
        switch(main_menu()){
                case START:
                        TL_rectangle_filled(0, 0, 96, 64, TL_RECT_FILL_BLACK);
                        TL_rectangle_filled(1, 1, 94, 62, TL_RECT_FILL_WHITE);
                        TL_text(2, 1, text_intro, TL_TEXT_TYPE, 5);
                        handle_map();
                        break;
                case LOAD:
                        break;
        }
}

void main_menu(void){
        unsigned char cursor_y = 0;
        TL_large_sprite(5, 0, 11, 26, title);
        TL_rectangle_filled(28, 33, 40, 21, TL_RECT_FILL_BLACK);
        TL_rectangle_filled(29, 34, 38, 19, TL_RECT_FILL_WHITE);
        TL_text(34, 34, text_menu, TL_TEXT_NOTYPE, 0);
        TL_gbuf_to_lcd();
        key = 0;
        while(key != skey_2nd){
                draw_cursor(30, 34+cursor_y*6);
                key = TL_get_key();
                switch(key){
                        case skey_up:
                                if(cursor_y > START){
                                        TL_gbuf_to_lcd();
                                        cursor_y-=1;
                                }
                                break;
                        case skey_down:
                                if(cursor_y < QUIT){
                                        TL_gbuf_to_lcd();
                                        cursor_y+=1;
                                }
                                break;
                }
        }
        return cursor_y;
}

char draw_cursor(unsigned char x, unsigned char y){
#asm
        res textwrite,(iy+sgrflags)     ; reset some flag to write only to the screen (not the graph buffer)
        ld hl,2
        add hl,sp
        ld b,(hl)       ; get y from the parameters (stack)
        inc hl
        inc hl
        ld c,(hl)       ; get x
        ld (pencol),bc
        ld a,5
        rst rbr_call
        defw _vputmap   ; write the cursor character
        set textwrite,(iy+sgrflags)     ; set the flag to write on the gbuf
#endasm
}

void handle_map(void){
        int move;
        update_map();
        key = 0;
        while(key != dkey_clear){
                key = TL_direct_input(dkey_group_1);
                switch(key){
                        case dkey_up:
                                if((TL_get_pixel(player_x, player_y-1) == TL_PIXEL_ON) || (TL_get_pixel(player_x+1, player_y-1) == TL_PIXEL_ON) || (TL_get_pixel(player_x+2, player_y-1) == TL_PIXEL_ON)){
                                        check_place(player_x+1, player_y-1);
                                        update_map();
                                }else
                                        move = 1;
                                break;
                        case dkey_right:
                                if((TL_get_pixel(player_x+3, player_y) == TL_PIXEL_ON) || (TL_get_pixel(player_x+3, player_y+1) == TL_PIXEL_ON) || (TL_get_pixel(player_x+3, player_y+2) == TL_PIXEL_ON)){
                                        check_place(player_x+3, player_y+1);
                                        update_map();
                                }else
                                        move = 1;
                                break;
                        case dkey_left:
                                if((TL_get_pixel(player_x-1, player_y) == TL_PIXEL_ON) || (TL_get_pixel(player_x-1, player_y+1) == TL_PIXEL_ON) || (TL_get_pixel(player_x-1, player_y+2) == TL_PIXEL_ON)){
                                        check_place(player_x-1, player_y+1);
                                        update_map();
                                }else
                                        move = 1;
                                break;
                        case dkey_down:
                                if((TL_get_pixel(player_x, player_y+3) == TL_PIXEL_ON) || (TL_get_pixel(player_x+1, player_y+3) == TL_PIXEL_ON) || (TL_get_pixel(player_x+2, player_y+3) == TL_PIXEL_ON)){
                                        check_place(player_x+1, player_y+3);
                                        update_map();
                                }else
                                        move = 1;
                                break;
                }
                if(move){
                        draw_player(player_x, player_y, player_x += (key == dkey_right)-(key == dkey_left), player_y += (key == dkey_down)-(key == dkey_up));
                        move = 0;
                }
                key = TL_direct_input(dkey_group_2);
        }
}

void update_map(void){
        C_bcall(_cleargbuf);
        TL_large_sprite(0, 0, 12, 64, map);
        TL_small_sprite(player_x, player_y, 3, map_player);
        TL_gbuf_to_lcd();
}

char draw_player(unsigned char old_player_x, unsigned char old_player_y, unsigned char player_x, unsigned char player_y){
        TL_small_sprite(old_player_x, old_player_y, 3, map_player);     // clear the player's sprite
        TL_small_sprite(player_x, player_y, 3, map_player);     // and re-draw it to its new place
        TL_gbuf_to_lcd();
}

char check_place(unsigned char player_x, unsigned char player_y){
        if(player_x > 5 && player_x < 19 && player_y > 4 && player_y < 31){
                // TOWER
        }else if(player_x > 25 && player_x < 58 && player_y > 3 && player_y < 36){
                // CASTLE
                TL_rectangle_filled(0, 37, 96, 27, TL_RECT_FILL_BLACK);
                TL_rectangle_filled(1, 38, 94, 25, TL_RECT_FILL_WHITE);
                TL_text(2, 38, text_castle, TL_TEXT_TYPE, 5);
        }else if(player_x > 57 && player_x < 95 && player_y > 0 && player_y < 25){
                // VOLCANO
        }else if(player_x > 29 && player_x < 49 && player_y > 39 && player_y < 54){
                // TOWN
        }else if(player_x > 59 && player_x < 95 && player_y > 32 && player_y < 63){
                if(player_x > 83 && player_x < 94 && player_y > 52 && player_y < 62){
                        // HOUSE
                }else{
                        // FOREST
                        battle();
                }
        }
}

void battle(void){
        C_bcall(_cleargbuf);
        for(i = 0; i<4; i++){
generate_enemy_coordinates:
                x_temp = TL_random(BATTLE_MAP_WIDTH-2)+1;
                y_temp = TL_random(BATTLE_MAP_HEIGHT/2)+1;
                if(GBA_collision((x_temp-GBA_scroll_x)*8, (y_temp-GBA_scroll_y)*8) > 0)
                        goto generate_enemy_coordinates;
                enemy[i].x = x_temp;
                enemy[i].y = y_temp;
                enemy[i].sprite = battle_enemy;
                enemy[i].hp = 3;
        }
        battle_player_direction = battle_player_up;
        key = 0;
        while(key != skey_clear){
                if(battle_player_x < screen_w/16){
                        camera_x = 0;
                }else if(battle_player_x > BATTLE_MAP_WIDTH-screen_w/16){
                        camera_x = BATTLE_MAP_WIDTH-screen_w/8;
                }else{
                        camera_x = battle_player_x-screen_w/16;
                }
                if(battle_player_y < screen_h/16){
                        camera_y = 0;
                }else if(battle_player_y > BATTLE_MAP_HEIGHT-screen_h/18){
                        camera_y = BATTLE_MAP_HEIGHT-screen_h/9;
                }else{
                        camera_y = battle_player_y-screen_h/16;
                }
                update_battle_screen();
                key = TL_get_key();
                x_temp = battle_player_x-(key == skey_left)+(key == skey_right);
                y_temp = battle_player_y-(key == skey_up)+(key == skey_down);
                if(is_location_empty(x_temp, y_temp) && GBA_collision((x_temp-GBA_scroll_x)*8, (y_temp-GBA_scroll_y)*8) == 0){
                        battle_player_x = x_temp;
                        battle_player_y = y_temp;
                }
                switch(key){
                        case skey_up:
                                battle_player_direction = battle_player_up;
                                x_temp2 = battle_player_x;
                                y_temp2 = battle_player_y-1;
                                break;
                        case skey_right:
                                battle_player_direction = battle_player_right;
                                x_temp2 = battle_player_x+1;
                                y_temp2 = battle_player_y;
                                break;
                        case skey_left:
                                battle_player_direction = battle_player_left;
                                x_temp2 = battle_player_x-1;
                                y_temp2 = battle_player_y;
                                break;
                        case skey_down:
                                battle_player_direction = battle_player_down;
                                x_temp2 = battle_player_x;
                                y_temp2 = battle_player_y+1;
                                break;
                }
                if(key == skey_2nd){
                        battle_player_direction += 2*8; // go to the attack sprite
                        if(is_location_empty(x_temp2, y_temp2)){
                                update_battle_screen();
                                TL_delay(ATTACK_ANIM_DELAY);
                        }else
                                enemy[j].hp -= hit(TL_random(2), (enemy[j].x-GBA_scroll_x)*8, (enemy[j].y-GBA_scroll_y)*8);
                        battle_player_direction -= 2*8; // go back to the normal sprite
                }
                // IA
                for(i = 0; i<4; i++){
                        if(enemy[i].hp > 0){
                                if(TL_random(3)){       // 1 in 3 chance that the enemy goes anywhere
                                        if(TL_random(2))
                                                x_temp = TL_random(2)+enemy[i].x;
                                        else
                                                x_temp = -TL_random(2)+enemy[i].x;
                                        if(TL_random(2))
                                                y_temp = TL_random(2)+enemy[i].y;
                                        else
                                                y_temp = -TL_random(2)+enemy[i].y;
                                }else{  // 2 in 3 chance that the enemy follow the player
                                        x_temp = enemy[i].x+(enemy[i].x < battle_player_x)-(enemy[i].x > battle_player_x);
                                        y_temp = enemy[i].y+(enemy[i].y < battle_player_y)-(enemy[i].y > battle_player_y);
                                }
                                if(TL_random(2))        // to prevent the enemy from moving two tiles at a time
                                        x_temp = enemy[i].x;
                                else
                                        y_temp = enemy[i].y;
                                if(is_location_empty(x_temp, y_temp) && GBA_collision((x_temp-GBA_scroll_x)*8, (y_temp-GBA_scroll_y)*8) == 0){
                                        if(x_temp == battle_player_x && y_temp == battle_player_y){
                                                enemy[i].sprite = battle_enemy_attack;
                                                player_hp -= hit(TL_random(2), (battle_player_x-GBA_scroll_x)*8, (battle_player_y-GBA_scroll_y)*8);
                                                enemy[i].sprite = battle_enemy;
                                        }else{
                                                enemy[i].x = x_temp;
                                                enemy[i].y = y_temp;
                                        }
                                }
                        }
                }
        }
}

void update_battle_screen(void){
        C_bcall(_cleargbuf);
        GBA_init_map(camera_x, camera_y, 20, 20, tiles, battle_map);
        GBA_restore_map();
        GBA_draw_mask_sprite((battle_player_x-GBA_scroll_x)*8, (battle_player_y-GBA_scroll_y)*8, 1, 8, battle_player_direction, GBA_CLIP_SPRITE);
        for(j = 0; j<4; j++){
                if(enemy[j].hp > 0)
                        GBA_draw_mask_sprite((enemy[j].x-GBA_scroll_x)*8, (enemy[j].y-GBA_scroll_y)*8, 1, 8, enemy[j].sprite, GBA_CLIP_SPRITE);
        }
#asm
        ld hl,gbuf+57*(96/8)
        ld de,gbuf+57*(96/8)+1
        ld (hl),@11111111
        ld bc,96/8
        ldir    ; draw a horizontal line (x = 0, y = 57, w = 96, h = 1)
#endasm
        TL_text(0, 58, text_hp, TL_TEXT_NOTYPE, 0);
        TL_put_val(12, 58, player_hp);
        TL_gbuf_to_lcd();
}

char is_location_empty(unsigned char x, unsigned char y){       // return 1 (TRUE) if there's no enemy at the location, otherwise return 0 (FALSE)
        for(j = 0; j<4; j++){
                if(enemy[j].x == x && enemy[j].y == y && enemy[j].hp > 0){
                        return 0;
                }
        }
        return 1;
}

char hit(unsigned char damage, unsigned char x, unsigned char y){
        update_battle_screen();
        TL_rectangle_filled(x+2, y-7, 5, 7, TL_RECT_FILL_WHITE);
        TL_put_val(x+3, y-7, damage);
        TL_gbuf_to_lcd();
        TL_delay(ATTACK_ANIM_DELAY);
        return damage;
}
[/code]
[/box]
[box=tilib.c]
[code=c]
#include "..\dev\tilib.h"       // � MODIFIER EN : #include "tilib.h"

#if defined TL_ALL
#define TL_RANDOM
#define TL_DELAY
#define TL_SMALL_SPRITE
#define TL_LARGE_SPRITE
#define TL_GBUF_TO_LCD
#define TL_DIRECT_INPUT
#define TL_GET_KEY
#define TL_GET_PIXEL
#define TL_RECTANGLE_FILLED
#define TL_TEXT
#define TL_PUT_VAL
#endif

#if defined TL_RANDOM
#asm
TL_random_data:
        defw $0000
#endasm
char __FASTCALL__ TL_random(unsigned char max){
#asm
; Random routine by Joe Wingbermuehle
        ld b,l

TL_random:
        push hl
        push de
        ld hl,(TL_random_data)
        ld a,r
        ld d,a
        ld e,(hl)
        add hl,de
        add a,l
        xor h
        ld (TL_random_data),hl
        sbc hl,hl
        ld e,a
        ld d,h
TL_random_loop:
        add hl,de
        djnz TL_random_loop
        ld a,h
        pop de
        pop hl
        ld h,0
        ld l,a
#endasm
}
#endif

#if defined TL_DELAY
char __FASTCALL__ TL_delay(unsigned char delay){
#asm
        ld b,l
        ei

delay_loop:
        halt
        djnz delay_loop
        di
#endasm
}
#endif

#if defined TL_SMALL_SPRITE
char TL_small_sprite(unsigned char x, unsigned char y, unsigned char height, unsigned char *sprite){
#asm
; Sprite routine by Joe Wingbermuehle
        ld hl,2
        add hl,sp
        ld e,(hl)
        inc hl
        ld d,(hl)
        push de
        pop ix
        inc hl
        ld b,(hl)
        inc hl
        inc hl
        ld c,(hl)
        inc hl
        inc hl
        ld a,(hl)
        ld l,c

TL_small_sprite:
        ld e,l
        ld h,$00
        ld d,h
        add hl,de
        add hl,de
        add hl,hl
        add hl,hl
        ld e,a
        and $07
        ld c,a
        srl e
        srl e
        srl e
        add hl,de
        ld de,gbuf
        add hl,de

TL_small_sprite_loop_1:
        ld d,(ix)
        ld e,$00
        ld a,c
        or a
        jr z,TL_small_sprite_skip_1

TL_small_sprite_loop_2:
        srl d
        rr e
        dec a
        jr nz,TL_small_sprite_loop_2

TL_small_sprite_skip_1:
        ld a,(hl)
        xor d
        ld (hl),a
        inc hl
        ld a,(hl)
        xor e
        ld (hl),a
        ld de,$0b
        add hl,de
        inc ix
        djnz TL_small_sprite_loop_1
#endasm
}
#endif

#if defined TL_LARGE_SPRITE
char TL_large_sprite(unsigned char x, unsigned char y, unsigned char width, unsigned char height, unsigned char *sprite){
#asm
; Sprite routine by Joe Wingbermuehle
        ld hl,2
        add hl,sp
        ld e,(hl)
        inc hl
        ld d,(hl)
        push de
        pop ix
        inc hl
        ld b,(hl)
        inc hl
        inc hl
        ld c,(hl)
        inc hl
        inc hl
        push hl
        inc hl
        inc hl
        ld a,(hl)
        pop hl
        ld l,(hl)

TL_large_sprite:
        di
        ex af,af
        ld a,c
        push af
        ex af,af
        ld e,l
        ld h,0
        ld d,h
        add hl,de
        add hl,de
        add hl,hl
        add hl,hl
        ld e,a
        and $07
        ld c,a
        srl e
        srl e
        srl e
        add hl,de
        ld de,gbuf
        add hl,de

TL_large_sprite_loop_1:
        push hl

TL_large_sprite_loop_2:
        ld d,(ix)
        ld e,0
        ld a,c
        or a
        jr z,TL_large_sprite_skip_1

TL_large_sprite_loop_3:
        srl d
        rr e
        dec a
        jr nz,TL_large_sprite_loop_3

TL_large_sprite_skip_1:
        ld a,(hl)
        xor d
        ld (hl),a
        inc hl
        ld a,(hl)
        xor e
        ld (hl),a
        inc ix
        ex af,af
        dec a
        push af
        ex af,af
        pop af
        jr nz,TL_large_sprite_loop_2
        pop hl
        pop af
        push af
        ex af,af
        ld de,$0c
        add hl,de
        djnz TL_large_sprite_loop_1
        pop af
#endasm
}
#endif

#if defined TL_GBUF_TO_LCD || defined TL_TEXT
void TL_gbuf_to_lcd(void){
#asm
; Fast copy routine by Joe Wingbermuehle
TL_gbuf_to_lcd:
        di
        ld a,$80
        out (plcdcmd),a
        ld hl,gbuf-12-(-(12*64)+1)
        ld a,$20
        ld c,a
        inc hl
        dec hl

TL_gbuf_to_lcd_again:
        ld b,64
        inc c
        ld de,-(12*64)+1
        out (plcdcmd),a
        add hl,de
        ld de,10

TL_gbuf_to_lcd_loop:
        add hl,de
        inc hl
        inc hl
        inc de
        ld a,(hl)
        out (plcddata),a
        dec de
        djnz TL_gbuf_to_lcd_loop
        ld a,c
        cp $2b+1
        jr nz,TL_gbuf_to_lcd_again
#endasm
}
#endif

#if defined TL_DIRECT_INPUT
char __FASTCALL__ TL_direct_input(unsigned char keygroup){
#asm
        ld a,l  ; a = keygroup
        out (pkey),a
        in a,(pkey)
        ld h,0
        ld l,a          ; hl is the return parameter
#endasm
}
#endif

#if defined TL_GET_KEY
void TL_get_key(void){
#asm
TL_get_key_loop:
        rst rbr_call
        defw _getcsc
        or a
        jr z,TL_get_key_loop
        ld h,0
        ld l,a
#endasm
}
#endif

#if defined TL_GET_PIXEL
char TL_get_pixel(unsigned char x, unsigned char y){
#asm
        ld hl,2
        add hl,sp
        ld e,(hl)       ; e=y
        inc hl
        inc hl
        ld a,(hl)       ; a=x
        ld l,e

TL_get_pixel:
        ld h,0
        ld d,h
        ld e,l
        add hl,hl
        add hl,de
        add hl,hl
        add hl,hl
        ld e,a
        srl e
        srl e
        srl e
        add hl,de
        ld de,plotsscreen
        add hl,de
        and 7
        ld b,a
        ld a,$80
        jr z,TL_test_pixel

TL_get_pixel_loop:
        rrca
        djnz TL_get_pixel_loop

TL_test_pixel:
        and (hl)
        or a
        ld hl,TL_PIXEL_ON
        jr nz,TL_get_pixel_quit
        ld hl,TL_PIXEL_OFF

TL_get_pixel_quit:
#endasm
}
#endif

#if defined TL_RECTANGLE_FILLED
char TL_rectangle_filled(unsigned char x, unsigned char y, unsigned char width, unsigned char height, unsigned char color){
#asm
; Rectangle filled routine by chickendude
#define GBUF_LSB        $40
#define GBUF_MSB        $93
        ld hl,2
        add hl,sp
        push hl
        inc hl
        inc hl
        ld b,(hl)
        inc hl
        inc hl
        ld c,(hl)
        inc hl
        inc hl
        ld e,(hl)
        inc hl
        inc hl
        ld d,(hl)
        pop hl
        ld a,(hl)
        cp 2
        jr z,TL_rectangle_filled_xor
        or a
        jr nz,TL_rectangle_filled_solid

;b = height
;c = width
;d = starting x
;e = starting y

TL_rectangle_filled_white:
        call TL_rectangle_filled_solid

TL_rectangle_filled_xor:
        ld a,$ae                ;xor (hl)
        jr TL_rectangle_filled_2

TL_rectangle_filled_solid:
        ld a,$b6                ;or (hl)

TL_rectangle_filled_2:
        push de
        push bc
        ld (TL_rectangle_filled_or_xor),a       ;use smc for xor/solid fill
        ld a,d                  ;starting x
        and $7                  ;what bit do we start on?
        ex af,af
        ld a,d                  ;starting x
        ld l,e                  ;ld hl,e
        ld h,0                  ; ..
        ld d,h                  ;set d = 0
        add hl,de               ;starting y * 12
        add hl,de               ;x3
        add hl,hl               ;x6
        add hl,hl               ;x12
        rra                             ;a = x coord / 8
        rra                             ;
        rra                             ;
        and @00011111   ;starting x/8 (starting byte in gbuf)
        add a,GBUF_LSB
        ld e,a                  ;
        ld d,GBUF_MSB   ;
        add hl,de               ;hl = offset in gbuf
        ex af,af
        ld d,a
        ld a,@10000000
        jr z,TL_rectangle_filled_4

TL_rectangle_filled_3:
        rra
        dec d
        jr nz,TL_rectangle_filled_3

TL_rectangle_filled_4:
        ld e,12

TL_rectangle_filled_loop_x:
        push af
        push bc
        push hl
        ld c,a

TL_rectangle_filled_loop_y:
TL_rectangle_filled_or_xor:
        or (hl)                 ;smc will modify this to or/xor
        ld (hl),a
        ld a,c
        add hl,de
        djnz TL_rectangle_filled_loop_y
        pop hl
        pop bc
        pop af
        rrca
        jr nc,TL_rectangle_filled_5
        inc hl

TL_rectangle_filled_5:
        dec c
        jr nz,TL_rectangle_filled_loop_x

TL_rectangle_filled_end:
        pop bc
        pop de
#endasm
}
#endif

#if defined TL_TEXT
#asm
TL_text_wait:
        defb 0
TL_text_typing_speed:
        defb 0
TL_text_default_col:
        defb 0
#endasm
char TL_text(unsigned char x, unsigned char y, unsigned char *text, unsigned char is_typed, unsigned char typing_speed){
#asm
; Text routine by chickendude
;0              ($00)   = end of a dialogue or end of a menu option
;NEWX   ($ff)   = new X coordinate
;NEWY   ($fe)   = new Y coordinate
;NEWXY  ($fd)   = new XY coordinates
;NEWL   ($fc)   = new line
;BRK    ($fb)   = pause
        ld hl,2
        add hl,sp
        set textwrite,(iy+sgrflags)
        ld a,(hl)
        ld (TL_text_typing_speed),a
        inc hl
        inc hl
        ld a,(hl)
        ld (TL_text_wait),a
        inc hl
        inc hl
        push hl
        inc hl
        inc hl
        ld d,(hl)
        inc hl
        inc hl
        ld e,(hl)
        pop hl
        ld a,(hl)
        inc hl
        ld h,(hl)
        ld l,a

TL_text_start:
        ld (pencol),de
        ld a,e
        ld (TL_text_default_col),a

TL_text_loop:
        ld de,(pencol)
        ld a,(hl)
        or a
        jp z,TL_gbuf_to_lcd
        cp TL_BRK
        jr c,TL_text_not_special
        ld bc,TL_text_loop
        push bc
        push hl
        ld hl,TL_text_routine_table
        cpl
        add a,a
        ld c,a
        ld b,0
        add hl,bc
        ld c,(hl)
        inc hl
        ld b,(hl)
        pop hl                  ;hl = adress in the string
        push bc                 ;bc = routine adress where we want to jump
        ret

TL_text_not_special:
        push de
        push ix
        rst rbr_call
        defw _vputmap
        pop ix
        pop de
        ld a,(TL_text_wait)     ;= 0 if no delay, != 0 else
        or a
        call nz,TL_text_delay
        inc hl
        jr TL_text_loop

TL_text_delay:
        di
        exx
        ld a,dkey_group_6       ;check ALPHA to skip text typing
        out (pkey),a
        in a,(pkey)
        bit 7,a
        jr nz,TL_text_delay_skip
        xor a
        ld (TL_text_wait),a

TL_text_delay_skip:
        ld a,(TL_text_typing_speed)
        ld b,a

TL_text_delay_loop:
        push bc
        call nc,TL_gbuf_to_lcd
        pop bc
        djnz TL_text_delay_loop
        exx
        ret

TL_text_routine_table:
        defw TL_text_new_x
        defw TL_text_new_y
        defw TL_text_new_x_y
        defw TL_text_new_line
        defw TL_text_pause

TL_text_new_x:
        inc hl
        ld e,(hl)
        ld (pencol),de
        inc hl
        ret

TL_text_new_x_y:
        call TL_text_new_x

TL_text_new_y:
        inc hl
        ld d,(hl)
        ld (pencol),de
        inc hl
        ret

TL_text_new_line:
        ld a,d
        add a,6 ;penrow+6
        ld d,a
        ld a,(TL_text_default_col)
        ld e,a
        ld (pencol),de
        inc hl
        ld a,(hl)
        ret

TL_text_pause:
        push hl
        call TL_gbuf_to_lcd

TL_text_pause_loop:
        ei
        halt
        di
        ld a,dkey_group_7       ;check 2nd
        out (pkey),a
        in a,(pkey)
        bit 5,a
        jr nz,TL_text_pause_loop

TL_text_load_next:
        ld hl,TL_text_wait
        inc (hl)
        in a,(pkey)
        inc a
        jr nz,TL_text_load_next
        pop hl
        inc hl                                  ;skip BRK
        ret
#endasm
}
#endif

#if defined TL_PUT_VAL
char TL_put_val(unsigned char x, unsigned char y, unsigned char val){
#asm
TL_put_val:
        ld hl,2
        add hl,sp
        ld e,(hl)
        inc hl
        ld d,(hl)
        push de
        inc hl
        ld b,(hl)
        inc hl
        inc hl
        ld c,(hl)
        ld (pencol),bc
        pop hl
        rst rbr_call
        defw _setxxxxop2
        rst rbr_call
        defw _op2toop1
        ld a,3
        rst rbr_call
        defw _dispop1a
#endasm
}
#endif
[/code]
[/box]
[box=tilib.h]
[code=c]
//****************************************************//
//** Uncomment #define of functions you want to use **//
//****************************************************//

//#define TL_ALL        //Auto define all functions
#define TL_RANDOM
#define TL_DELAY
#define TL_SMALL_SPRITE
#define TL_LARGE_SPRITE
#define TL_GBUF_TO_LCD
#define TL_DIRECT_INPUT
#define TL_GET_KEY
#define TL_GET_PIXEL
#define TL_RECTANGLE_FILLED
#define TL_TEXT
#define TL_PUT_VAL

//*********************//
//** TIlib constants **//
//*********************//

#define TL_PIXEL_ON     1
#define TL_PIXEL_OFF    0
#define TL_RECT_FILL_WHITE      0
#define TL_RECT_FILL_BLACK      1
#define TL_RECT_FILL_XOR        2
#define TL_TEXT_NOTYPE  0
#define TL_TEXT_TYPE    1
#define TL_NEWX $ff
#define TL_NEWY $fe
#define TL_NEWXY        $fd
#define TL_NEWL $fc
#define TL_BRK  $fb

//**************************//
//** Functions prototypes **//
//**************************//

char __FASTCALL__ TL_random(unsigned char max);
char __FASTCALL__ TL_delay(unsigned char delay);
char TL_small_sprite(unsigned char x, unsigned char y, unsigned char height, unsigned char *sprite);
char TL_large_sprite(unsigned char x, unsigned char y, unsigned char width, unsigned char height, unsigned char *sprite);
void TL_gbuf_to_lcd(void);
char __FASTCALL__ TL_direct_input(unsigned char keygroup);
void TL_get_key(void);
char TL_get_pixel(unsigned char x, unsigned char y);
char TL_rectangle_filled(unsigned char x, unsigned char y, unsigned char width, unsigned char height, unsigned char color);
char TL_text(unsigned char x, unsigned char y, unsigned char *text, unsigned char is_typed, unsigned char typing_speed);
char TL_put_val(unsigned char x, unsigned char y, unsigned char val);
[/code]
[/box]