
Je viens de porter la routine de rectangle de chickendude et j'ai un peu adapté sa routine de texte lettre par lettre multiligne et qui gère les pauses avec 2nd

Bientôt j'aurais de quoi faire des petits jeux facilement en C sans que ça prenne trop de place. Par contre je n'ai pas encore réussis à résoudre ce bug de clipping vertical.
tiroutines.h
#define include_ionPutSprite 0
#define include_ionFastCopy 1
#define include_direct_input 1
#define include_rectangle_filled 1
#define include_text 1
#if include_ionPutSprite == 1
char ionPutSprite(unsigned char x, unsigned char y, unsigned char height, unsigned char *sprite_pointer);
char ionPutSprite(unsigned char x, unsigned char y, unsigned char height, unsigned char *sprite_pointer){
#asm
; parameters are puts on the sp
ld hl,2
add hl,sp ; skip over return address on stack
ld e,(hl)
inc hl
ld d,(hl)
push de
pop ix ; ix = *sprite_pointer
inc hl
ld b,(hl) ; height occupies 16 bits on stack but only the LSB is relevant
inc hl ; skip MSB
inc hl
ld c,(hl) ; c = y
inc hl ; skip MSB
inc hl
ld a,(hl) ; a = x
ld l,c
;-----> Draw a sprite
; b=size of sprite
; l=y
; a=x
; ix holds pointer
ionPutSprite:
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
ionPutSpriteLoop1:
ld d,(ix)
ld e,$00
ld a,c
or a
jr z,ionPutSpriteSkip1
ionPutSpriteLoop2:
srl d
rr e
dec a
jr nz,ionPutSpriteLoop2
ionPutSpriteSkip1:
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 ionPutSpriteLoop1
#endasm
}
#endif
#if include_ionFastCopy == 1 || include_text == 1
void ionFastCopy(void);
void ionFastCopy(void){
#asm
;-----> Copy the gbuf to the screen (fast)
;Input: nothing
;Output:graph buffer is copied to the screen
ionFastCopy:
di
ld a,$80
out (plcdcmd),a
ld hl,gbuf-12-(-(12*64)+1)
ld a,$20
ld c,a
inc hl
dec hl
ionFastCopyAgain:
ld b,64
inc c
ld de,-(12*64)+1
out (plcdcmd),a
add hl,de
ld de,10
ionFastCopyLoop:
add hl,de
inc hl
inc hl
inc de
ld a,(hl)
out (plcddata),a
dec de
djnz ionFastCopyLoop
ld a,c
cp $2b+1
jr nz,ionFastCopyAgain
#endasm
}
#endif
#if include_direct_input == 1
char __FASTCALL__ direct_input(unsigned char keygroup);
char __FASTCALL__ 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 include_rectangle_filled == 1
#define RECT_FILL_WHITE 0
#define RECT_FILL_BLACK 1
#define RECT_FILL_XOR 2
char rectangle_filled(unsigned char x, unsigned char y, unsigned char width, unsigned char height, unsigned char color);
char rectangle_filled(unsigned char x, unsigned char y, unsigned char width, unsigned char height, unsigned char color){
#asm
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,rectangle_filled_xor
or a
jr nz,rectangle_filled_solid
; Rectangle filled routine by chickendude
;b = height
;c = width
;d = starting x
;e = starting y
#define GBUF_LSB $40
#define GBUF_MSB $93
rectangle_filled_white:
call rectangle_filled_solid
rectangle_filled_xor:
ld a,$ae ;xor (hl)
jr rectangle_filled2
rectangle_filled_solid:
ld a,$b6 ;or (hl)
rectangle_filled2:
push de
push bc
ld (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,rectangle_filled4
rra
rectangle_filled3:
dec d
jr nz,rectangle_filled3
rectangle_filled4:
ld e,12
rectangle_loop_x:
push af
push bc
push hl
ld c,a
rectangle_loop_y:
or_xor:
or (hl) ;smc will modify this to or/xor
ld (hl),a
ld a,c
add hl,de
djnz rectangle_loop_y
pop hl
pop bc
pop af
rrca
jr nc,rectangle_filled5
inc hl
rectangle_filled5:
dec c
jr nz,rectangle_loop_x
rectangle_end:
pop bc
pop de
#endasm
}
#endif
#if include_text == 1
#asm
#define TEXT_NOTYPE 0
#define TEXT_TYPE 1
#define NEWX $ff
#define NEWY $fe
#define NEWXY $fd
#define NEWL $fc
#define BRK $fb
text_wait:
defb 0
text_typing_speed:
defb 0
default_col:
defb 0
#endasm
char text(unsigned char x, unsigned char y, unsigned char *text, unsigned char is_typed, unsigned char typing_speed);
char text(unsigned char x, unsigned char y, unsigned char *text, unsigned char is_typed, unsigned char typing_speed){
#asm
ld hl,2
add hl,sp
set textwrite,(iy+sgrflags)
ld a,(hl)
ld (text_typing_speed),a
inc hl
inc hl
ld a,(hl)
ld (text_wait),a
inc hl
inc hl
push hl
inc hl
inc hl
ld e,(hl)
inc hl
inc hl
ld d,(hl)
pop hl
ld a,(hl)
inc hl
ld h,(hl)
ld l,a
; Text routine by chickendude
text_start:
ld (pencol),de
ld a,e
ld (default_col),a
text_loop:
ld de,(pencol)
ld a,(hl)
or a
jp z,ionFastCopy
cp BRK
jr c,not_special
ld bc,text_loop
push bc
push hl
ld hl,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
not_special:
push de
push ix
rst rbr_call
defw _vputmap
pop ix
pop de
ld a,(text_wait) ;= 0 if no delay, != 0 else
or a
call nz,text_delay
inc hl
jr text_loop
text_delay:
di
exx
ld a,key_group_6 ;check ALPHA to skip text typing
out (pkey),a
in a,(pkey)
bit 7,a
jr nz,text_delay_skip
xor a
ld (text_wait),a
text_delay_skip:
ld a,(text_typing_speed)
ld b,a
text_delay_loop:
push bc
call nc,ionFastCopy
pop bc
djnz text_delay_loop
exx
ret
; $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
text_routine_table:
defw text_new_x
defw text_new_y
defw text_new_x_y
defw text_new_line
defw text_pause
text_new_x:
inc hl
ld e,(hl)
ld (pencol),de
inc hl
ret
text_new_x_y:
call text_new_x
text_new_y:
inc hl
ld d,(hl)
ld (pencol),de
inc hl
ret
text_new_line:
ld a,d
add a,6 ;penrow+6
ld d,a
ld a,(default_col)
ld e,a
ld (pencol),de
inc hl
ld a,(hl)
ret
text_pause:
pop bc ;clear stack
push hl
call ionFastCopy
text_pause_loop:
ei
halt
di
ld a,key_group_7 ;check 2nd
out (pkey),a
in a,(pkey)
bit 5,a
jr nz,text_pause_loop
load_next_text:
ld hl,text_wait
inc (hl)
in a,(pkey)
inc a
jr nz,load_next_text
pop hl
inc hl ;skip BRK
ret
#endasm
}
#endif
#pragma string name C TEST
#include <..\dev\ti83p.h>
#include <..\dev\tiroutines.h>
#include <..\dev\gbalib2.h>
// #define bcall(romcall) asm("rst $28");\
// asm("defw romcall");
extern char map[];
#asm
._map
defb 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,0
defb 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,1,1,1
defb 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
defb 3,3,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1
defb 3,3,0,0,0,0,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0
defb 3,3,0,0,0,0,0,0,2,2,2,2,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0
defb 3,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0
defb 3,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,1,1,0,0,0,2
defb 0,0,0,0,0,0,0,0,4,4,4,4,1,1,1,4,4,4,4,0,0,0,0,0,1,1,0,0,0,2,2
defb 0,0,0,0,0,0,0,0,4,4,4,4,1,5,1,1,1,1,1,1,1,1,1,1,1,0,0,0,2,2,2
defb 3,3,0,0,0,0,0,0,4,4,4,4,1,1,1,4,4,4,4,0,0,0,0,0,0,0,0,0,2,2,2
defb 3,3,3,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,2,2,2,2
defb 3,3,3,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,2,2,2,2,2
defb 3,3,3,3,0,0,0,0,0,0,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,3
defb 3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,0,0,0,0,0,0,2,3,3,3,3,3
defb 3,3,3,3,3,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,0,0,0,3,3,3,3,3,3,3
#endasm
extern char tiles[];
#asm
._tiles
defb @10000000 ; tile #0 (field)
defb @10000100
defb @00010000
defb @01000001
defb @00000000
defb @00100000
defb @00000010
defb @00000000
defb @00000000 ; tile #1 (road)
defb @00000000
defb @00000000
defb @00000000
defb @00000000
defb @00000000
defb @00000000
defb @00000000
defb @00010000 ; tile #2 (forest)
defb @00110000
defb @00101000
defb @01100000
defb @01010100
defb @11000000
defb @11111110
defb @00010000
defb @00000000 ; tile #3 (mountain)
defb @00000000
defb @00001000
defb @00010100
defb @00100110
defb @01010010
defb @11011001
defb @10001000
defb @11111010 ; tile #4 (water)
defb @11011111
defb @10101101
defb @11111010
defb @11101111
defb @11010111
defb @11111111
defb @11111101
defb @11111111 ; tile #5 (temple)
defb @01011110
defb @00101100
defb @00101100
defb @00101100
defb @00101100
defb @01111110
defb @10011111
#endasm
char sprite[]={
0xC3,0x3C,
0x81,0x42,
0x00,0xA5,
0x00,0xA5,
0x00,0x81,
0x00,0xBD,
0x81,0x42,
0xC3,0x3C
};
extern char text01[];
#asm
._text01
defb 'T','E','S','T',BRK,0
#endasm
int main(){
char x=0, y=0;
// bcall(_cleargbuf);
gbaInitMap(0, 0, 31, 16, tiles, map);
gbaRestoreMap();
text(6, 30, text01, TEXT_TYPE, 5);
rectangle_filled(0, 0, screen_w, screen_h, RECT_FILL_XOR);
ionFastCopy();
while(1){
switch(direct_input(key_group_1)){
case key_up:
if(gbaScrollUp()){
gbaRestoreMap();
}
y-=1;
gbaDrawMaskSprite(x, y, 1, 8, sprite, GBA_CLIP_SPRITE);
ionFastCopy();
break;
case key_right:
if(gbaScrollRight()){
gbaRestoreMap();
}
x+=1;
gbaDrawMaskSprite(x, y, 1, 8, sprite, GBA_CLIP_SPRITE);
ionFastCopy();
break;
case key_left:
if(gbaScrollLeft()){
gbaRestoreMap();
}
x-=1;
gbaDrawMaskSprite(x, y, 1, 8, sprite, GBA_CLIP_SPRITE);
ionFastCopy();
break;
case key_down:
if(gbaScrollDown()){
gbaRestoreMap();
}
y+=1;
gbaDrawMaskSprite(x, y, 1, 8, sprite, GBA_CLIP_SPRITE);
ionFastCopy();
break;
}
}
}
Par contre ça n'est pas possible de définir un texte en entier après un defb, on est vraiment obligé de le faire lettre par lettre ?! Je crois que j'ai un tas de trucs à réclamer sur le forum officiel.