Page 1 sur 2

fonctions de sprite gcc4ti

Message non luPosté: 22 Fév 2021, 22:38
de Michael0x18
Apologies in advance: my French is terrible. School French really doesn't teach you enough.

When using GCC4TI, is there some way to redirect the sprite functions to a buffer of non-standard size, say, 256x256 instead of 240x128?

Quand on utilise le SDK GCC4TI, puis-je le fonctions sprite faire écrire à un buffer qui a les dimensions 256x256 a lieu de 140x128?

Re: fonctions de sprite gcc4ti

Message non luPosté: 22 Fév 2021, 22:59
de Lionel Debroux
Don't worry, unless you want to hone your French skills, you can save time by posting in English :)

Like all "fast" graphics libraries (faster than AMS, that is), GCC4TI's sprite functions hard-code the plane byte width to 30 bytes = 240 pixels. Only AMS's graphics functions can deal with different (and variable) plane size, and that's partially why the whole AMS graphics stack is so slow.

I can see two ways forward for you:
* use AMS (PortSet, BitmapPut, etc.), if the slowness doesn't kill your program's purpose - it often does;
* copy GCC4TI's sprite routine to your project, rename it, and modify the code. For a 256-pixel-wide buffer, i.e. 32-byte-wide buffer,
Code: Tout sélectionner
mulu.w #30,%d1
becomes
Code: Tout sélectionner
lsl.w #5,%d1
, and
Code: Tout sélectionner
lea 30(%a1),%a1
becomes
Code: Tout sélectionner
lea 32(%a1),%a1
.
Clearly, my preference goes to the latter.

Re: fonctions de sprite gcc4ti

Message non luPosté: 23 Fév 2021, 02:09
de Michael0x18
Thank you! I have made the suggested modifications.
The file I modified was taken straight from the GCC4TI Github page. I modified /gcc4ti/trunk/tigcc/archive/sprite16.s, and it now looks like this:
Code: Tout sélectionner
.globl Sprite16
.text
.even
Sprite16:
| Compute offset from beginning of plane.
   lsl.w #5,%d1    | modification 1
   adda.l %d1,%a1 | 2
   move.w %d0,%d1 | 2
   lsr.w #4,%d1 | 2
   add.w %d1,%d1 | 2
   adda.w %d1,%a1 | 2
| d0: shift count.
   not.w %d0 | 2
   and.w #15,%d0 | 4
   addq.w #1,%d0 | 2

   move.l %d4,-(%a7) | 2
| d3: drawing mode.
   subq.w #1,%d3 | 2
| d4: mask used by AND and RPLC.
   moveq #-1,%d4 | 2
   clr.w %d4 | 2
   rol.l %d0,%d4 | 2
| Jump to loop entry.
   bra.s .L__s16_loopentry | 2

| AND.
.L__s16_Am:
   or.l %d4,%d1 | 2
   and.l %d1,(%a1) | 2

| Next line.
.L__s16_loop:
   lea 32(%a1),%a1 | 4     modification 2

.L__s16_loopentry:
| Have we finished ?
   subq.w #1,%d2 | 2
   blt.s .L__s16_rts | 2

   moveq #0,%d1 | 2
   move.w (%a0)+,%d1 | 2
   lsl.l %d0,%d1 | 2
   cmp.w #1,%d3 | 4
   beq.s .L__s16_Am | 2
   tst.w %d3 | 2
   blt.s .L__s16_Xm | 2
   beq.s .L__s16_Om | 2
| RPLC.
   and.l %d4,(%a1) | 2

| OR.
.L__s16_Om:
   or.l %d1,(%a1) | 2
   bra.s .L__s16_loop | 2

| XOR
.L__s16_Xm:
   eor.l %d1,(%a1) | 2
   bra.s .L__s16_loop | 2

| Return
.L__s16_rts:
   addq.w #1,%d3 | 2
   move.l (%a7)+,%d4 | 2
   rts | 2


Now that I have this, how would I go about linking it with my project (in the IDE) such that I can call both functions?

Re: fonctions de sprite gcc4ti

Message non luPosté: 23 Fév 2021, 07:51
de Lionel Debroux
* rename the occurrences of Sprite16 to e.g. Sprite16_32bytesplane;
* add the new file to your project in the IDE;
* copy the prototype of Sprite16 from sprites.h to your source code, and rename the function according to your previous rename in the assembly file.

Which functions are you using to draw the relevant part of the 32-byte-wide plane to the real screen ?

Less than a month after the release of GCC4TI 0.96 Beta 10, I integrated clipped sprite functions to the library - another long-standing feature request for and unprocessed contribution to GCC4TI's dead ancestor.

Re: fonctions de sprite gcc4ti

Message non luPosté: 23 Fév 2021, 09:47
de Lionel Debroux
Your post on Omnimaga mentions a post on Cemetech, which is certainly https://www.cemetech.net/forum/viewtopic.php?t=17448 . The twin topics' titles do not mention that this is for the TI-68k series, which further increases the chances that I miss topics, but you couldn't have known :)

Re: fonctions de sprite gcc4ti

Message non luPosté: 23 Fév 2021, 17:54
de Michael0x18
Yeah sorry.

I originally considered writing my own function, which would have applied broadly to C as a whole, but you're right. It would probably have been better to put 68K in the titles - the 84 + CE also has a C SDK, and that's what Cemetech focuses on.

But hey, modifying the library function is a much better choice. It was written by a good assembly programmer, so its basically guaranteed to be faster than anything I could write in C. (I suck at ASM, so that's not even an option.)

Thank you for the tips!

Re: fonctions de sprite gcc4ti

Message non luPosté: 23 Fév 2021, 19:37
de Michael0x18
Okay. One more quick thing. It's no longer about the sprite functions, but it's a follow up. I modified the sprites function and linked it with extern, and now it works (I think, it doesn't crash, at least, like my old code did.)
If I now wish to test a pixel within this buffer, is this sufficient?
Code: Tout sélectionner
short isBit(void* buffer, short x, short y){
   //              32 wide     start block * 2 size
   void* base = buffer+32*y + (x/16)*2;
   unsigned short offset = ((unsigned)x)%16;//Offset from start of base block
   
   unsigned short val = *((unsigned short*)base);
   
   //Number that gets ANDed with the block to test.
   unsigned short test = 1<<offset;
   return ((val&test)>0)?1:0;
}

Re: fonctions de sprite gcc4ti

Message non luPosté: 23 Fév 2021, 21:07
de Lionel Debroux
I haven't tested it, but looks correct at first glance.

I'd write it slightly differently, to:
1) try to force the compiler to do the right thing - we don't want it to optimize (x/16)*2 to (x/8);
2) eliminate usage of the non-portable GCC extension known as "void pointer arithmetics" (it's not your fault for unwittingly using it, it's the compiler designers' and implementers' fault for making it possible...);
3) to simplify the way the last test is written. In fact, the 3 last statements could be combined.
Also, I took the liberty to make x and y unsigned.

Code: Tout sélectionner
short isBit(void* buffer, unsigned short x, unsigned short y){
   //              32 wide     start block * 2 size
   unsigned char * base = (unsigned char *)buffer + (y<<5) + ((x>>4) +(x>>4));
   unsigned short offset = x&15;//Offset from start of base block
   
   unsigned short val = *((unsigned short*)base);
   
   //Number that gets ANDed with the block to test.
   unsigned short test = 1<<offset;
   return (val&test);
}


EDIT: thinking about it again... given that the btst instruction works with byte-sized memory operands, maybe the whole function could attempt to perform bit tests on bytes, which would yield something along the lines of (untested):

Code: Tout sélectionner
short isBit(void* buffer, unsigned short x, unsigned short y){
   //              32 wide     start block * 2 size
   unsigned char * base = (unsigned char *)buffer + (y<<5) + (x>>3);
   
   return (*base & (1 << (x&7)));
}


EDIT2: wrapped y<<5 into parentheses, per your later post.

Re: fonctions de sprite gcc4ti

Message non luPosté: 23 Fév 2021, 22:08
de Michael0x18
Thank you, yet again. When I used your code, it worked - after wrapping the y<<5 in parentheses. I think the main reason why mine didn't work was because of the 2*(x/16)=x/8 thing. It works now.

Re: fonctions de sprite gcc4ti

Message non luPosté: 23 Fév 2021, 22:10
de Lionel Debroux
Oops, cross-edit. See the second part I've just added to my post :)