Nop90 Posted December 10, 2019 Share Posted December 10, 2019 Could someone explain me how and for what is used the skip sprite flag? Thanks Quote Link to comment Share on other sites More sharing options...
LordKraken Posted December 10, 2019 Share Posted December 10, 2019 (edited) ahah I knew you would be interested so here is my code, when I want to hide a sprite from a SCB linked list, instead of rebuilding the entire list, I just do: SCBCTL1(enemy->escb) = SCB_CTL1_SKIP_SPRITE; Where SCB_CTL1_SKIP_SPRITE is simply the flag 0x04 When I want to show this sprite again, then I generally use flag 0x10 for the first SCB (zoom and palette definition) or 0x18 for the others (zoom and reuse palette) So this is BLL-ish code so as far as I know with cc65, you need to set this flag in the SCB struct. Edited December 10, 2019 by LordKraken 1 1 Quote Link to comment Share on other sites More sharing options...
sage Posted December 10, 2019 Share Posted December 10, 2019 depending on what you want to set teh srpites, it might be easier to just set the hi byte of the sprite data address to zero ? Quote Link to comment Share on other sites More sharing options...
+bhall408 Posted December 10, 2019 Share Posted December 10, 2019 1 hour ago, Nop90 said: Could someone explain me how and for what is used the skip sprite flag? A few months back, I'd had a theory that Ms. Pac-Man used that flag to handle the dots. ie, when you ate a dot, it could simply set the skip flag. Turns out that wasn't the case, but I think that would be a very elegant solution for that sort of game. Quote Link to comment Share on other sites More sharing options...
enthusi Posted December 10, 2019 Share Posted December 10, 2019 I (can) make sense to disable sprites via that flag when you have large chains of sprites (rather than setting "empty" data). Not THAT much is gained by that however. We use it in Lacim's Legacy for that very reason. Quote Link to comment Share on other sites More sharing options...
Nop90 Posted December 10, 2019 Author Share Posted December 10, 2019 it's almost what I guessed. I know people that had trouble making it work. I don't think it can be useful for the game I already made, but have to experiment with it Quote Link to comment Share on other sites More sharing options...
LordKraken Posted December 10, 2019 Share Posted December 10, 2019 (edited) 18 minutes ago, sage said: depending on what you want to set teh srpites, it might be easier to just set the hi byte of the sprite data address to zero ? In nop90 case, I will have to (gently ) disagree since he wants to retain the grid data at a particular position without having to do an extra lookup later. (Now I realize the context was set in a pm discussion... so the idea is to avoid drawing all the tiles when most of them are off screen. So when you move the camera and you change your grid position, you simply set this flag on or off) Edited December 10, 2019 by LordKraken Quote Link to comment Share on other sites More sharing options...
LordKraken Posted December 10, 2019 Share Posted December 10, 2019 (edited) Also by doing that you avoid drawing at weird cordinate which I suspect is causing weird behaviour sometimes and slow down as well (but please feel free to tell me I'm just crazy :D) Edited December 10, 2019 by LordKraken Quote Link to comment Share on other sites More sharing options...
sage Posted December 12, 2019 Share Posted December 12, 2019 you mainly avoid reading the rest of the sprite SCB and data. weird corordinates is not the problem for the hardware. Quote Link to comment Share on other sites More sharing options...
Nop90 Posted December 15, 2019 Author Share Posted December 15, 2019 I'm going to use this thread for other questions since are all related to the optimization of lawnmower. I'm using SUZY offsets to speedup the drawing, this way I can reuse a lot o of the tiles chain, but I have problems at the borders. I supposed that the offsets affects the rendered window on the phisical framebuffer, that I once read can be larger of 160x102, but someone said me it isn't so and SUZY v and h offsets are only offsets applied when drawing sprites. I made a test setting 20 pixels of offsets, than in a while(1) loop I draw a sprite in the center and half outside all the 4 borders: everything works fine, so I thought that offset works without changing the phisical size of the buffer. But using the offsets in the games, where values changes at every frame, I can't draw sprites crossing two of the borders (depending the sliding direction obtained changing the SUZY offsets), just like suzy is expected to trim pixels out of the physical fb. What's happening? How do the offsets works? If I have to enlarge the framebuffer (+16 pixels on every side) how can I do it? Quote Link to comment Share on other sites More sharing options...
laoo Posted December 15, 2019 Share Posted December 15, 2019 (edited) @Nop90 What do you mean by "offset"? HOFF/VOFF registers ($fc04/$fc06)? HOFF/VOFF are only values subtracted from sprites coordinates and are used to move around virtual windows in sprites coordinate space. They don't affect framebuffer location and AFAIK there is no way to extend framebuffer dimensions. Other offsets are HSIZOFF / VSIZOFF ($fc28/$fc2a) but they're some exotic values used to initialize size accummulator. Edited December 15, 2019 by laoo Quote Link to comment Share on other sites More sharing options...
Nop90 Posted December 15, 2019 Author Share Posted December 15, 2019 ok, there is some other problem I can't find. Quote Link to comment Share on other sites More sharing options...
Nop90 Posted December 15, 2019 Author Share Posted December 15, 2019 Solved, found that if I set the position of a sprite using the value stored in an unsigned char, the implicit cast to signed int causes problems. The values I use are in the range 0-160, so it should work. Not the first weird behaviour of cc65 i found. Some month ago I found that sometime it doesn't respect ansi c priority of math operators. Quote Link to comment Share on other sites More sharing options...
+karri Posted December 16, 2019 Share Posted December 16, 2019 If you make an implicite cast of a one byte entity to a two byte entity then the second byte is taken from memory. Quote Link to comment Share on other sites More sharing options...
Nop90 Posted December 16, 2019 Author Share Posted December 16, 2019 4 hours ago, karri said: If you make an implicite cast of a one byte entity to a two byte entity then the second byte is taken from memory. Is this standard c behaviour. If yes probably I worked too much with 32 bit memory aligned architectures. Quote Link to comment Share on other sites More sharing options...
+karri Posted December 16, 2019 Share Posted December 16, 2019 5 hours ago, Nop90 said: Is this standard c behaviour. If yes probably I worked too much with 32 bit memory aligned architectures. Sure. I mean you can make silly casts. The compiler cannot know what kind of bits is where in memory. You may be surprised if you make some int casts on a 64 bit machine. Quote Link to comment Share on other sites More sharing options...
laoo Posted December 17, 2019 Share Posted December 17, 2019 wait a minute... could you post some example of such cast? Quote Link to comment Share on other sites More sharing options...
Nop90 Posted December 17, 2019 Author Share Posted December 17, 2019 5 hours ago, laoo said: wait a minute... could you post some example of such cast? ty = sy; for(j=offy-1;j<offy+7;j++) { tx = sx; for(i=offx-1;i<offx+12;i++) { if((i>=0) && (j>=0) && (i<mapx) && (j<mapy)) { mapij = map(i,j); if(mapij==42) ttile = tiles[1]; else if(mapij>2 && mapij<6) ttile = tiles[mapij + ((framecount&4)?10:0)]; else ttile = tiles[mapij]; } else ttile =tiles[0]; addTile( TILES_FIELD, ttile, scrollingx ? tx - xx - 32 : tx, scrollingy ? ty - yy - 16: ty ); tx += 16; } ty += 16; } This is the (unoptimized) main loop for drawing the tiles on the screen, defining tx and tx as unsigned char gives the problems, I solved defining them signed int. addTiles only sets the value of sprites position and image data pointer in a sprites array. Quote Link to comment Share on other sites More sharing options...
laoo Posted December 17, 2019 Share Posted December 17, 2019 Such casts should definitely be performed correctly under standard C behavior. You can RUN sample code with such cast: https://onlinegdb.com/BJy40U8Rr It must be (another) quirk of cc65. Quote Link to comment Share on other sites More sharing options...
+karri Posted December 17, 2019 Share Posted December 17, 2019 If we have a pointer to an array of chars char data[] = {1,2,3,4,5,6,7}; and then I claim it to be an int int a = *(int *)&data[1]; What do you expect a to be? #include <stdio.h> int main() { char data[] = {1,2,3,4,5,6,7}; int a = *(int *)&data[1]; printf("%d\n", a); return 1; } karri@swing:~$ gcc test.c karri@swing:~$ ./a.out 84148994 Any language that has a pointer is bound to have problems sooner or later. In C the "int" may have any number of bits depending on the architecture. I use signed chars a lot in cc65. They work well. Quote Link to comment Share on other sites More sharing options...
laoo Posted December 18, 2019 Share Posted December 18, 2019 @karri This is trivially true. That's why it's erroneous to perform such casts. But variables in Nop90's code are not accessed through pointers so it's not the case. Look at the sample code and initial problem assessment: On 12/15/2019 at 6:41 PM, Nop90 said: Solved, found that if I set the position of a sprite using the value stored in an unsigned char, the implicit cast to signed int causes problems. If casting unsigned char to int involves fetching garbage from memory then it's obviously a bug in the compiler. @Nop90 Could you perform similar test to my example on cc65? Maybe you've stumbled on different problem because it's hard to believe that cc65 has such grave bug in casting. Quote Link to comment Share on other sites More sharing options...
Nop90 Posted December 18, 2019 Author Share Posted December 18, 2019 In the next days (If i survive all this 'Xmas business lunches and parties) I'll post a simple rom + sources that shows this problem and the other one I found with operators precedence (that I solve using all the parentesis I can). @laoo,what is 'your example on cc65'? give me a link please. Quote Link to comment Share on other sites More sharing options...
Nop90 Posted December 18, 2019 Author Share Posted December 18, 2019 (edited) well, coded a test in 5 mins. Run the rom and check the code. Can you see the problem? Is it the compiler or a silly mistake by me? test.lnx testoffset.zip Edited December 18, 2019 by Nop90 Quote Link to comment Share on other sites More sharing options...
laoo Posted December 18, 2019 Share Posted December 18, 2019 (edited) @Nop90 It's a bug in sign extension. Here's the problem: lda #$B4 sec sbc (sp) sta _sp_img+7 txa stz _sp_img+7+1 Look how it's working in gcc: https://onlinegdb.com/H16IvuwRB Edited December 18, 2019 by laoo Quote Link to comment Share on other sites More sharing options...
+karri Posted December 18, 2019 Share Posted December 18, 2019 The reason is that off is defined as unsigned char. With signed char the math goes: ; ; sp_img.hpos=180-off; ; lda #$B4 jsr pusha0 ldy #$02 lda (sp),y bpl L0041 ldx #$FF L0041: jsr tossubax sta _sp_img+7 stx _sp_img+7+1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.