| www.retrosoftware.co.uk http://www.retrosoftware.co.uk/forum/ |
|
| C64 Sprites to BBC convertion http://www.retrosoftware.co.uk/forum/viewtopic.php?f=73&t=343 |
Page 4 of 6 |
| Author: | TomW [ Sat Oct 10, 2009 10:41 am ] |
| Post subject: | Re: C64 Sprites to BBC convertion |
Yeah - whoops! That'll teach me to _test_ code I post here... |
|
| Author: | MartinB [ Sat Oct 10, 2009 10:46 am ] |
| Post subject: | Re: C64 Sprites to BBC convertion |
Rich wrote: If you like, I can post code to do this, or perhaps you'd prefer to have a go at implementing it yourself first? If the 'you' is me then yes please Rich, that would be great. If the 'you' is Colin then yes please anyway - Col can look the other way if he wants to do it himself (I do have a well-on-the-way project btw and these basic but effective tricks are really helpful Martin |
|
| Author: | RichTW [ Sat Oct 10, 2009 12:06 pm ] | ||
| Post subject: | Re: C64 Sprites to BBC convertion | ||
OK, here it is. I guess this is a spoiler, so if you don't want to know how it's done, look away now! Here is some skeleton code (and a disc image) presented in BeebAsm format. Essentially, it's more a tutorial in setting up the hardware and handling the interrupts than anything else. You'll notice that the configuration of the video hardware is very important, in particular explicitly setting the screen line where VSync should be generated, and setting the interlace mode. You can't necessarily guarantee either of these when selecting Mode 2 (because it depends on the *TV setting). Anyway, this code shows you how to set a timer to trigger just before the scanline of your choice starts to be rasterised. Code: vsynccount = 0 ; zero page address of the vsync counter DEBUG_RASTERS = TRUE ; conditionally assemble debug code screenLine = 32 ; screen line (in pixels) on which timer should interrupt vsyncPosition = 34 ; screen character row at which VSync is generated vsyncWidth = 2 ; pulse width in scanlines of VSync signal (default is 2) ; number of screen lines (in pixels) between Vsync and line 0 numLinesAfterVsync = (39 - vsyncPosition) * 8 - vsyncWidth ; time spent rendering the border prior to our chosen line, in usecs borderTime = (128 - 80) / 2 ; time in usecs between the irq occurring and the service routine being reached irqServiceLatency = 51 ; calculate the timer value required to interrupt at the right place timerLength = 64 * (screenLine + numLinesAfterVsync) - irqServiceLatency - borderTime ORG &1900 \\----------------------------------------------------------------- \\ The entry point of the code \\----------------------------------------------------------------- .start SEI LDX #&FF:TXS ; reset stack \\ Configure VIAs STX &FE44:STX &FE45 LDA #&7F:STA &FE4E ; disable all System VIA interrupts STA &FE6E ; disable all User VIA interrupts STA &FE43 ; set keyboard data direction LDA #&C2:STA &FE4E ; enable VSync and timer interrupt LDA #&0F:STA &FE42 ; set addressable latch for writing LDA #3:STA &FE40 ; keyboard write enable LDA #0:STA &FE4B ; timer 1 one shot mode \\ Configure CRTC LDA #8:STA &FE00 LDA #0:STA &FE01 ; turn off interlace LDA #10:STA &FE00 LDA #32:STA &FE01 ; turn off cursor LDA #7:STA &FE00 LDA #vsyncPosition:STA &FE01 ; explicitly set vsync position LDA #3:STA &FE00 LDA #vsyncWidth * 16 + 8 STA &FE01 ; explicitly set vsync pulse width \\ Set interrupt handler LDA #LO(irq):STA &204 LDA #HI(irq):STA &205 ; set interrupt handler CLI \\----------------------------------------------------------------- \\ This is the main loop - totally empty at the moment! \\----------------------------------------------------------------- .mainloop LDA #1:STA vsynccount \\ Do main loop here .waitforvsync LDA vsynccount:BNE waitforvsync JMP mainloop \\----------------------------------------------------------------- \\ The IRQ handler \\----------------------------------------------------------------- .irq LDA &FE4D AND #2 ; test if it's a Vsync interrupt BNE irqvsync \\ If we got here, it's definitely a timer interrupt .irqtimer IF DEBUG_RASTERS LDA #4:STA &FE21 ; debug change background to blue ENDIF LDA #&40:STA &FE4D ; acknowledge timer interrupt LDA vsynccount BEQ skipdec DEC vsynccount ; decrement vsync count if not already zero .skipdec LDA &FC ; restore A RTI ; and exit \\ If we got here, it's a vsync .irqvsync STA &FE4D ; acknowledge vsync interrupt LDA #LO(timerLength):STA &FE44 ; set timer interrupt period LDA #HI(timerLength):STA &FE45 IF DEBUG_RASTERS LDA #7:STA &FE21 ; debug change background to black ENDIF LDA &FC ; restore A RTI ; and exit .end SAVE "Code", start, end For some reason, the irqServiceLatency value seems to be rather large, but it has to be this big in order that the timer interrupts as soon as the right border begins on the line previous to the target line (in order to maximise our time as much as possible). Tom, you got any ideas where I've gone wrong here?
|
|||
| Author: | ColinD [ Sat Oct 10, 2009 2:01 pm ] |
| Post subject: | Re: C64 Sprites to BBC convertion |
Thats done the trick.. thanks guys... I can now see whats going on, when, and how fast too Think I'll look at trying to optimise some of the code to try to speed things up... Cheers, Colin |
|
| Author: | RichTW [ Sat Oct 10, 2009 6:47 pm ] |
| Post subject: | Re: C64 Sprites to BBC convertion |
RichTW wrote: For some reason, the irqServiceLatency value seems to be rather large, but it has to be this big in order that the timer interrupts as soon as the right border begins on the line previous to the target line (in order to maximise our time as much as possible). OK, I understand why it's that big now - it breaks down like this: Upon VSync: Code: (jump to IRQ) 7 STA &FC 3 PLA 4 PHA 3 AND #&10 2 BNE (not taken) 2 JMP (&204) 5 ... LDA &FE4D 6 (worst case) AND #2 2 BNE (taken) 3 STA &FE4D 5 LDA # 2 STA &FE44 6 LDA # 2 STA &FE45 5 Upon timer interrupt: Code: (jump to IRQ) 7 STA &FC 3 PLA 4 PHA 3 AND #&10 2 BNE (not taken) 2 JMP (&204) 5 ... LDA &FE4D 6 (worst case) AND #2 2 BNE (not taken) 2 ------------------- total 93 Of course, we have to take into account the IRQ handling overheads twice. On the VSync, we have to go through the whole process before we even get to set the timer, so we're already behind. And then when the timer interrupts, we repeat the whole preamble a second time, which gives us an additional delay of 47us. The additional few microseconds used by my code take into account the extra time it takes to load a value and store it to the palette (which are the first 'visible' moments of the interrupt), plus also to account for the latency if the IRQ happens in the middle of executing an instruction (could be as much as 3us more if a slow instruction is interrupted, e.g. a LDA (ind, X)). |
|
| Author: | MartinB [ Sat Oct 10, 2009 7:18 pm ] |
| Post subject: | Re: C64 Sprites to BBC convertion |
That's brilliant Rich - explains it all very nicely One question - When you explicitly set the point where the vsync interrupt occurs, does this affect the actual physical behaviour of the raster or literally only the line at which the interrupt occurs? If the latter, why is it necessary to set the vsync position and then use that to set a timer to interrupt at a point before vsync - can you not just set vsync to occur at this earlier point? (I strongly suspect I'm missing something obvious Martin |
|
| Author: | RichTW [ Sun Oct 11, 2009 11:22 am ] |
| Post subject: | Re: C64 Sprites to BBC convertion |
When you set the VSync position, it is literally specifying the screen line at which the VSync pulse is sent to the VDU. At this point an interrupt is also generated. Since VSync triggers flyback, it will always denote which line will be the last one in the bottom border, so if you were to set it to the last line in your visible playing area, the whole screen would be moved physically downwards so that there was no bottom border at all (which would of course be far too low). That's why we need the timer to interrupt at the end of the displayed screen, before the bottom border is rasterised. The VSync pulse width doesn't affect the display position at all, but it does delay the interrupt by the number of scanlines it specifies. It always defaults to 2 scanlines in Beeb modes, but I just set it explicitly to make a point. |
|
| Author: | MartinB [ Sun Oct 11, 2009 12:56 pm ] |
| Post subject: | Re: C64 Sprites to BBC convertion |
Got it. I thought perhaps we could signal a virtual vsync IRQ separate from the actual raster pulse but since not, that explains the need for a timer. Thanks very much for all that Rich (and Tom), I now fully understand the techniques and can see all the benefits so I'll be adding this to my project forthwith Martin |
|
| Author: | ColinD [ Mon Oct 12, 2009 8:44 pm ] | ||
| Post subject: | Re: C64 Sprites to BBC convertion | ||
OK.... I've been trying to muck about optimising code..... I did manage to roll all the convert/colour/plot code into one loop.... But its not saved as much cpu time as I would have liked.... (Its nice neat code though, lol)... So.. forget that for now..... OK.. I've done a screen sync.... and a delay to move stuff down the screen a litlle.... Green is converting the sprite from 64 bytes to BBC 128 bytes (and changing colour tables) Blue is clearing old plot, Yellow is plotting new sprite..... I've tried optimising (and it shaves a few cycles off) , but at the end of the day the code still has to shift a LOT of bytes around, so its not saving that much overall !!! There are a couple of ways to shuffle memory round, so its faster to access in loops (or in mutiple byte numbers) - but it gets messy !! - So all the code is unoptimised for now.... So.... I've now got a fairly good idea, how fast stuff runs, and I'm unlikely to double the speed of the code, however much optimising I do.... (and I will try to optimise as fast as I can....eventually) Dropped down to 4 sprites... so everthing runs at 50 FPS (inc conversion - which may well be off line - or a MIX - some online convertions but mostly offline !!) Cheers, Colin Ps... Here is a version of the new c64>beeb disply plot Code (that I'm not using.. but works, just to demonstrate how it works - I don't think it can be optimised very much !!! - I moved the tables down into zeropage, and it speeded up a little, but not that much overall !!) - I will probably use a variant of it to do the graphics convertion 'off line'.... ITS VERY BRUTE FORCE !!! .alias SCREEN $70 .alias TEMP $72 .alias TEMP2 $73 LDA #$30 STA SCREEN+1 LDA #$00 STA SCREEN Ldx #$00 STX TEMP2 LOOP1: LDY #$00 LOOP2: LDX TEMP2 INC TEMP2 lda $2000,x ; sprite starts here c64 format - 63 bytes of data... EACH BYTE is 4 PIXELS !! Unlike BBC mode 2 !! sta TEMP LDA #$00 ASL TEMP ROL ASL TEMP ROL TAX LDA COLPALLET,X ; ( 0>3 - 0 = Background 1-3 = the 3 colours to use) TAX LDA BYTEPATTERN,X ASL STA FRIG1+1 LDA #$00 ASL TEMP ROL ASL TEMP ROL TAX LDA COLPALLET,X TAX LDA BYTEPATTERN,X FRIG1: ORA #$00 STA (SCREEN),Y ; 1ST BYTE SCREEN LOCATION TYA CLC ADC #$08 TAY LDA #$00 ASL TEMP ROL ASL TEMP ROL TAX LDA COLPALLET,X ; ( 0>3 - 0 = Background 1-3 = the 3 colours to use) TAX LDA BYTEPATTERN,X ASL STA FRIG2+1 LDA #$00 ASL TEMP ROL ASL TEMP ROL TAX LDA COLPALLET,X TAX LDA BYTEPATTERN,X FRIG2: ORA #$00 STA (SCREEN),Y ; 2nd BYTE SCREEN LOCATION TYA CLC ADC #$08 TAY CPY #$30 BNE LOOP2 INC SCREEN LDA SCREEN AND #$07 BNE SKIP1 LDA SCREEN SEC SBC #$08 CLC ADC #$80 STA SCREEN LDA SCREEN+1 ADC #$02 STA SCREEN+1 SKIP1: LDA TEMP2 CMP #63 BNE LOOP1 RTS
|
|||
| Author: | ColinD [ Tue Oct 13, 2009 7:25 pm ] |
| Post subject: | Re: C64 Sprites to BBC convertion |
OK..... Heres a post to go a little 'off topic' but still kind of keep on track.... Having a quick muck about with PuCrunch ( I've used this before briefly on the c64). Saved all my sprite data out... Its 8k worth... and crunches down to 3k... (mates game uses 12.5k of sprites and goes down to 4.6K) Level data (50 game screens -256 bytes each) is 12.5K and crunches down to 4.25K... so.. quick sums.. looks like its easily coming in under 40%.... If say I managed to optimise all my graphics/levels down to a 20K chunk (or a lot less with some optimising).... Say I end up with 4K of data packed.... I could then uncrunch this to the screen memory (as a scratch pad) - Pick out what I needed and copy it to a work area (say 2K ?) - So use 6K for whatever I have left overall...less a little for zero page, stack, etc. .....then things could start to become quite intersting..(will be very tight though).. Either that or Multiload (which I want to try and avoid) !! I'm going to be taking a break soon from this Scene for a short while (need to sort some c64 coding out for a music player - and other real life issues) - and then hopefully return one I have a game plan... I'll be experimenting with some other c64 graphics formats too... Like Character sets/fonts (2k) and expanded xy c64 sprites (slow and messy, but might be fun !!) Cheers, Colin |
|
| Author: | ColinD [ Wed Oct 14, 2009 10:28 pm ] |
| Post subject: | Re: C64 Sprites to BBC convertion |
Optimised my code above a little to ignore when the data is zero, so that it skips some of the indexing.... slows things though for very graphicy sprites... Should also work with the other code I've done (which plots pre-converted 128 byte sprites)... I'm quite happy with my progress..... I'm going to start another thread about memory useage on the bbc !! Cheers, Colin |
|
| Author: | ColinD [ Fri Oct 16, 2009 8:41 pm ] |
| Post subject: | Re: C64 Sprites to BBC convertion |
I'm now looking at c64 character font plotting..... Heres a bbc screen shot, compared to the c64 version... You can ignore the colours for now... Very rough and ready code to copy the 'font' to the screen... The font is a Banner kind of thing.... Same kind of format as the sprites, so lots and lots of bit shifting of the 2k font to display on the beeb as 4k..... !! At the moment the c64 version runs a hi-light through the banner, and changes colours from time to time..... But the bbc one just plots.... Got some spinning sprites below to test, but the memory is garbage for now..... On the c64 version I have some bubble sprites multiplexed floating up around the banner...(with more re-cycled hardware sprites below for the fishies etc) . Early days.... Looks good to me !! Attachment:
|
|
| Author: | SteveO [ Fri Oct 16, 2009 8:54 pm ] |
| Post subject: | Re: C64 Sprites to BBC convertion |
ColinD wrote: Looks good to me !! and me to ! |
|
| Author: | ColinD [ Fri Oct 16, 2009 9:18 pm ] |
| Post subject: | Re: C64 Sprites to BBC convertion |
SteveO wrote: ColinD wrote: Looks good to me !! and me to ! Ta very much The font graphics 'slab' is very memory inefficeint though.... its basically a 2k bitmap in 4 colours...(not sure how bitmaps are stored, but probably similar'ish) and there are lots of zero bytes scattered..... could probably be optimised to 1K but would be a LOT of HARD work !!! - Remember the c64 had much more memory to waste for trivial things like this..... There is another 2k font used in my c64 game too... some for the font (in mono colour mode), and some for the character graphics in multicolour mode.... I'll have to bin the font and use native bbc fonts maybe if I can suss out how they are stored in the rom, and optimise the rest of the font too (and try to optimise level storage !!)..... Grrrr !!!! ##edit## As another 'test' next, I'll probably try to plot one of my game levels up on screen (minus the sprites of course) - I think things will need to be simplified, so that the sprites don't overlap the game screen graphics (or very little) - will be a bit of a shame and things will have to be redesigned somewhat, but otherwise things will run very slow compared to a c64.... |
|
| Author: | ColinD [ Fri Oct 16, 2009 9:49 pm ] |
| Post subject: | Re: C64 Sprites to BBC convertion |
Here's the C64 'unfinished' game screen shot of one of the 50 levels (not all finished)... as seen at the Lass a few months ago at Console-Combat.. Sprite Priorities are mucked up (sprites should be infront of the background graphics).... Attachment: Its a shame that the beeb only has the 8 colours to play with, so won't be able to do brown shades / grey shades etc.... so won't be able to show it all off in its intended glory !! (could possibly flicker the pallet of the 8-16 colours ? every screen under the sync interupt - would that work ??) Not sure what to do yet... either make the enemy sprites 16(8)x16 instead of 24(12)x21... and make the screens native c64 sixe, or enlarge the screens a bit (to give the sprites free space to move around)... (multicolour halves the horizontal res) The crab will be a bugger, as he likes to scurry about on the same level as the pearls/bubbles to collect (ovelapping)..... I could make all the other enemys move in free space... You can see looking at the sprites that I've used the 2nd 'definable' colour to change the sprite main colour.. and used the 3rd and 4th 'fixed' multi-colours on the sprites as basic black and white... 1st colour is transparent.. I'm going to chill out now... too many 'bows'... Cheers, Col |
|
| Author: | SteveO [ Sat Oct 17, 2009 9:26 am ] |
| Post subject: | Re: C64 Sprites to BBC convertion |
I was at the Lass, missed this |
|
| Author: | ColinD [ Sun Oct 18, 2009 2:09 am ] |
| Post subject: | Re: C64 Sprites to BBC convertion |
A little more progress... code is REALLY brute force, with lots of plotting sections repeated till I start breaking stuff into subroutines.... Attachment: Attachment:
|
|
| Author: | DaveJ [ Sun Oct 18, 2009 6:10 am ] |
| Post subject: | Re: C64 Sprites to BBC convertion |
This is looking fantastic. If you want to see a good example of how get the most of the 8 colour palette you have to play with, then you may like to take a look at the Beeb version of Jamie Woodhouse's game "Qwak!". He uses several nifty tricks in his sprite designs to get around the limitations of the palette. If getting good brown shades is important, I would suggest putting some of the C64 sprites through Francis Loch's BBC Image convertor and seeing what you can come up with. Hope you don't mind my suggestions. The game is looking fabulous and I can't wait to play it. |
|
| Author: | SteveO [ Sun Oct 18, 2009 7:47 am ] |
| Post subject: | Re: C64 Sprites to BBC convertion |
Yep, looking really good, are you re-using some of your C64 code ? or are you just really quick at knocking all this stuff up |
|
| Author: | ColinD [ Sun Oct 18, 2009 2:48 pm ] |
| Post subject: | Re: C64 Sprites to BBC convertion |
SteveO wrote: Yep, looking really good, are you re-using some of your C64 code ? or are you just really quick at knocking all this stuff up All the code is new, I'm just using the re-using graphics and the 1st levsls data - the c64 code is unsuitable due to the way it deals with character plotting. Code is pretty clunky and oversized, and I'll have to optimise it - Knocked the level display up in a couple of hours after working out the format again... 19 x 10 Tiles (Each Tile is 4 characters from the font in increments of 4) - Think I've got 32 Tiles and the Hi-Res font below that. Cheers, Colin |
|
| Page 4 of 6 | All times are UTC [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|