| www.retrosoftware.co.uk http://www.retrosoftware.co.uk/forum/ |
|
| Sprite plotting routine woes http://www.retrosoftware.co.uk/forum/viewtopic.php?f=73&t=881 |
Page 1 of 1 |
| Author: | jbnbeeb [ Tue Dec 24, 2013 3:54 pm ] | |||
| Post subject: | Sprite plotting routine woes | |||
HI, Merry Christmas to you all! Problem: I think my sprite routine is taking too long to complete and so I am getting sprite tearing at the top of the screen. First question: What is meant by RichTW and others when plotting sprites in "column major" order (per one of the options in Beebspriter) ..? Does it mean a column of bytes in the order specified in a screen mode? OR does it mean a character's worth of column - i.e. in mode 5 this would be a two byte column. Second Longer question: is there a simpler way I can speed up my sprite plotting as contrasted with http://www.retrosoftware.co.uk/wiki/index.php/Mode2_MaskedSprite_Plotter ?? BTW I have studied Steve's code extensively and think it is great re optimisation but it'd be nice if there was a simpler thing I could do in my existing code. Background: I am trying to write a 2 player plane dogfight game. I want to have smooth animation. However, I also predict I'll need a fair bit of RAM as I want to write a 1 player mode which will require AI code for the 2nd player; thus I am using MODE 5. To get smooth animation (moving by one pixel in X direction), I plot a sprite, then a further 3 copies of the sprite each frame, each of which is offset by one pixel in X dir. Every four frames, I increment X ord by one byte. I am using Steve O'Leary's routine as found here: http://www.retrosoftware.co.uk/wiki/index.php/Calculate_Screen_Address10KMode I need a lot of sprites to achieve this: 8 directions * 4 sprites per direction = 32 sprites per player. I also want bullets etc. Currently I still think this is a worthwhile trade off vs using Mode2 due to still having a fair amount of memory left. I think the reason it is slow is because I am using the screen addr calc routine throughout the plot routine (based on other threads I have been scanning through). BIG ASK: It would be appreciated if the code whizzes on the forum could take a look through the source in the zip file (BeebASM and sprites in BeebSpriter line-by line order) and suggest (simple-ish??) things I could do to speed up plot routine. The code has lots of comments. I attach two zip files. Using RichTW's plotting colour either side of plot routine idea.. one zip file shows the sprite plotting below the coloured line and no sprite tearing. The second zip file shows the same code except plotting at top of screen and the tearing. Any help or advice much appreciated. Thanks all, jbnbeeb
|
||||
| Author: | tricky [ Wed Dec 25, 2013 9:40 am ] |
| Post subject: | Re: Sprite plotting routine woes |
Hi jbnbeeb, I had a look at the sprite code and there are quite a few places where you could save a few cycles. I am planning a kind of game library for the beeb, including the various sprite routines that I have used over the years, so if you can wait, you can probably use one of them; be assured that the beeb can draw plenty without flickering/tearing, but it can take quite a bit of fiddling (see Jeltron - loads of sprites 25fps or carnival - special case sprites, but drawing all 13 (mode 1 so 2x data) for a row takes about 6/7 char lines; 5 vsync to top of screen and 1/2 rows on screen). If you fancy working out the sprite drawing yourself, you can simplify sprite drawing for mode 4/5 is to narrow the screen to 32 8 byte chars - 128/256x256 pixels. This reduces the screen size to 8K and means that each character row starts on a new page, making all screen address easy to calculate and meaning that going down a row is incrementing the high byte of the address. tricky |
|
| Author: | jbnbeeb [ Sat Dec 28, 2013 5:35 pm ] |
| Post subject: | Re: Sprite plotting routine woes |
Hi tricky, thanks for your response - on Christmas day ! I was intrigued by the 8k Mode 5 screen and i've had a look through the forum and found the appropriate code to set this up. ....but after considerable head scratching, I am still struggling to work out how much more efficient it would be than a regular Mode 5 screen. I understand that each char row on 8k screen can be a new page..BUT to work out a "pixel row".. I still have to do something like... [where X and Y ords are integers, X = 0..31 bytes/per 4 pixels , Y 0..255pixels] result=ScreenStartAddress+((((Y div 8)*256)+(Y and 7)) + X * 8) ..thus I'm just substituting 256 for the usual 320 of Mode 5.. It looks like I've got to do the "usual" formula.. thus I can't see how I could make calculating the screen addr much quicker. Please could you supply any further hints re above? Thanks, jbnbeeb |
|
| Author: | tricky [ Sat Dec 28, 2013 10:25 pm ] |
| Post subject: | Re: Sprite plotting routine woes |
The main thing is to calculate the screen address as infrequently as possible (once ever is a good start If you have 1 row = 1 page, you don't have to worry about crossing a page boundary as you draw the chars/columns of your sprite, so you can just use ,x/y I usually keep the fractional parts separate and the main parts in y (rows/pages), x (chars) for pixels (256x256 mode 4) addr = &4000 + (y/8)*256 + (x/8)*8 + y%8 in assembler, this simplifies to addr_hi = &40 | (y >> 3) addr_lo = (x & &F8) | y & 7 in asm (not tested, just typed in here): tya : lsr A : lsr A : lsr A : ora #&40 : sta &71 txa : and #&F8 : sta &70 tya : and #&07 : ora &70 : sta &70 NB this only trashes A, not X or Y and doesn't mess with the carry - think of it as "premature optimization" or "saving yourself work later" I wouldn't use the third line, as I would probably be using the vertical offset within a char to pick a custom drawing routine or to offset the src/dst. I probably wouldn't store the second line in &70 as I would keep that as 0 and just put the char offset in Y. You could save a byte and a couple of clocks by changing the first line to something like tya : lsr A : SEC : ror A : lsr A : ora #&40 : sta &71 PS changing mode yourself is quite easy and can be handy if you need to do some relocation and don't want to clear 10K, when you are using 8K and aren't sure which bytes will get overwritten if you do. |
|
| Author: | jbnbeeb [ Sun Dec 29, 2013 4:25 pm ] |
| Post subject: | Re: Sprite plotting routine woes |
tricky wrote: The main thing is to calculate the screen address as infrequently as possible (once ever is a good start Hi tricky, thanks for the further hints. The quote above is something that struck me shortly after I wrote the last message yesterday! And I can now see how this would be nice and quick. It's kinda clicked: I can easily work out a "pixel" row with in a char by just putting lo byte in Y register and ANDing it with 7. Should I need to plot on a char row above or below from current pos, I can just put hi byte in X register and dec or inc by 1. I am now going to write routines to do this and use an 8k mode 5 screen. I'll plot in "column major" order instead of plotting line by line and calling a screen addr calc routine every time I plot a byte further in a row! Hopefully this will result in much quicker routine and thus greatly reduce sprite tearing. Will post back when I've done this. |
|
| Author: | jbnbeeb [ Mon Mar 24, 2014 12:28 am ] |
| Post subject: | Re: Sprite plotting routine woes |
Hi, got my 8k mode 5 screen sprite plotting /moving routines running in January. After a hiatus with new job and creating a no-code-required load screen generator for RS Adventure games, I'm getting back to my Dogfight game. I discovered a problem whilst testing the sprite routines. I load the sprite data high in ram, just prior to screen memory. Or so I thought. The issue is: I've cribbed bits of code I found on this forum to create an 8k Mode 5 screen which should start at &6000. BUT by changing to Mode 5 and then poking the CRTC registers.. the screen memory is refreshed from &5800. So if I put data in 5800-6000 prior to changing to Mode 5, the data is wiped. Question: Is it possible to create an 8k MODE 5 screen and change to that custom mode (from Mode 7 say) and only refresh memory from &6000? If so, how would it be done? The routine I have cobbled together for the 8k mode 5 screen is below. I'd like to do this so I could change screen modes within the game without losing data between 5800-6000 ..say for a high score table in Mode 6 or 7. Code: ;Switch to mode 5 lda #$16 jsr oswrch lda #5 jsr oswrch ; now in mode 5 LDA #1 ;Display width STA $FE00 LDA #32 ;32 characters (256 pixels in mode 5) STA $FE01 LDA #6 ;Display height STA $FE00 LDA #32 ;32characters ( STA $FE01 LDA #12 ;Display address high STA $FE00 LDA #&0c ;Start at &6000 STA $FE01 ;lda #13 ;sta $FE00 ;lda #0 ;sta $FE01 jbnbeeb wrote: tricky wrote: The main thing is to calculate the screen address as infrequently as possible (once ever is a good start Hi tricky, thanks for the further hints. The quote above is something that struck me shortly after I wrote the last message yesterday! And I can now see how this would be nice and quick. It's kinda clicked: I can easily work out a "pixel" row with in a char by just putting lo byte in Y register and ANDing it with 7. Should I need to plot on a char row above or below from current pos, I can just put hi byte in X register and dec or inc by 1. I am now going to write routines to do this and use an 8k mode 5 screen. I'll plot in "column major" order instead of plotting line by line and calling a screen addr calc routine every time I plot a byte further in a row! Hopefully this will result in much quicker routine and thus greatly reduce sprite tearing. Will post back when I've done this. |
|
| Author: | tricky [ Mon Mar 24, 2014 8:14 pm ] |
| Post subject: | Re: Sprite plotting routine woes |
You can just start in mode 7 and set the rest yourself. If you are scrolling or using the joystick, you need to set up the addressable latch (so you can set the address that screen memory "wraps" to) sei lda #&0F : sta SysViaDDRB \\ enable write to addressable latch (b0-2 addr, b3 data) and read joystick buttons (b5,b6) and speech (b6 ready, b7 interrupt) lda #0+8 : sta SysViaRegB \\ write "disable" sound lda #3+8 : sta SysViaRegB \\ write "disable" keyboard ldx #4+8 : stx SysViaRegB \\ these two set the ldx #5+0 : stx SysViaRegB \\ screen size to 16K cli you will need to play with the +8/+0 in the last two lines to get 8k if scrolling |
|
| Page 1 of 1 | All times are UTC [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|