kumbach@nro.cs.athabascau.ca (Kevin Umbach) (12/06/90)
I'm writing a video game for the Amiga that has 6 small men (12 by 11 pixels, 2 planes) running around on the screen. I currently have them defined as animation objects and I'm using the Animate function to move them. Even though I'm only using a 320X200 2plane screen, the anim objects move very slowly. So here's my question: Is it faster to use blitter directly and keep track of all positional information manually, or do I have to be an expert programmer to get things moving faster than Animate? I currently have the program coded using Lattice C. Any hints and tips for speeding up animation would be greatly appreciated.
ken@cbmvax.commodore.com (Ken Farinsky - CATS) (12/08/90)
In article <BZLRT1w163w@ersys.uucp> ersys!kumbach@nro.cs.athabascau.ca (Kevin Umbach) writes: >I'm writing a video game for the Amiga that has 6 small men (12 by 11 >pixels, 2 planes) running around on the screen. I currently have them >defined as animation objects and I'm using the Animate function to >move them. Even though I'm only using a 320X200 2plane screen, the >anim objects move very slowly. Why don't you use sprites or vsprites? The objects are small enough, and you are running on a lores screen, so sprites would work. They should be a lot faster. -- -- Ken Farinsky - CATS - (215) 431-9421 - Commodore Business Machines uucp: ken@cbmvax.commodore.com or ...{uunet,rutgers}!cbmvax!ken bix: kfarinsky
ckp@grebyn.com (Checkpoint Technologies) (12/08/90)
In article <BZLRT1w163w@ersys.uucp> ersys!kumbach@nro.cs.athabascau.ca (Kevin Umbach) writes: >I'm writing a video game for the Amiga that has 6 small men (12 by 11 >pixels, 2 planes) running around on the screen. I currently have them >defined as animation objects and I'm using the Animate function to >move them. Even though I'm only using a 320X200 2plane screen, the >anim objects move very slowly. It seems your objects are small enough, few enough, and shallow enough that you could be using sprites. Is there some basic reason why you aren't? If you switch from Bobs to VSprites, your code won't change much, and you can get perfectly smooth and flicker-free animation without double buffering. You will also be able to use different colors for them than your playfield, though I don't know if that's an issue for you. -- First comes the logo: C H E C K P O I N T T E C H N O L O G I E S / / \\ / / Then, the disclaimer: All expressed opinions are, indeed, opinions. \ / o Now for the witty part: I'm pink, therefore, I'm spam! \/
jnmoyne@lbl.gov (Jean-Noel MOYNE) (12/08/90)
If your objects can be only 8 points wide, and 3 colors (you can use different colors from the backgroud), then go for sprites ... You'll be able to animate 8 objects very quickly (and that means in sync with the display, which is your goal for a game). Otherwise, you can quite easilly boost the blitter's perfs by programming it yourself. Remeber the graphics.lib routines where made for general purposes, you can allways make a specific routine for your needs, and it'll be a lot faster. The only problem is that the blitter is not really easy to program by hand, and that you'll have to access it relatively to _custombase (don't do it otherwise than this way), it's a little dirty but if you need to modify it for a specific Amiga it can be do easilly. If you choose this solution, I strongly recomand you to get the program blitlab (Radical Eye software, it's PD), and it's documentation. Next buy some patience too (for the debuging) (-: JNM -- These are my own ideas (not LBL's) " Just make it!", BO in 'BO knows Unix'
farren@well.sf.ca.us (Mike Farren) (12/11/90)
ersys!kumbach@nro.cs.athabascau.ca (Kevin Umbach) writes: >I'm writing a video game for the Amiga that has 6 small men (12 by 11 >pixels, 2 planes) running around on the screen. I currently have them >defined as animation objects and I'm using the Animate function to >move them. Even though I'm only using a 320X200 2plane screen, the >anim objects move very slowly. > >So here's my question: > Is it faster to use blitter directly and keep track of all positional > information manually, or do I have to be an expert programmer to > get things moving faster than Animate? My experience with Animate, back when I was doing the port of Crystal Quest to the Amy, was that it was just too slow to do an arcade-game type movement for any significant number of objects (where significant == 3 or more). I whipped up a quick blitter routine in assembly which moved an object as desired (16 X 16 pixels), and it blazed - I could have nearly 50 objects moving around before a noticable speed degradation happened. Of course, I wasn't doing background saves or anything like that, but that would have been easy to add, and wouldn't have hurt the performance all THAT much - six men, 12 X 11, should be a piece of cake. Or, since you're only using 2 planes, how about setting 'em up as sprites, which would take essentially nothing in the way of resources? -- Mike Farren farren@well.sf.ca.us
pashdown@javelin.es.com (Pete Ashdown) (12/12/90)
farren@well.sf.ca.us (Mike Farren) writes: >I whipped up a quick blitter routine in assembly which >moved an object as desired (16 X 16 pixels), and it blazed - I could >have nearly 50 objects moving around before a noticable speed degradation >happened. Of course, I wasn't doing background saves or anything like >that, but that would have been easy to add, and wouldn't have hurt the >performance all THAT much - six men, 12 X 11, should be a piece of cake. Hey Mike, how about a post of that routine? >Mike Farren farren@well.sf.ca.us -- "While you are here, your wives and girlfriends are dating handsome American movie and TV stars. Stars like Tom Selleck, Bruce Willis, and Bart Simpson." -- Baghdad Betty Pete Ashdown pashdown%javelin@dsd.es.com ...dsd.es.com!javelin!pashdown
farren@well.sf.ca.us (Mike Farren) (12/19/90)
pashdown@javelin.es.com (Pete Ashdown) writes: >farren@well.sf.ca.us (Mike Farren) writes: >>I whipped up a quick blitter routine in assembly >Hey Mike, how about a post of that routine? Sure thing. Here you are: ; This routine draws an object directly to the bitplanes. ; ; The shape data is organized as one large block, for ease of loading via ; a standard "fread" statement. In this case, there are 73 shapes possible, ; and the shape number and location onscreen are passed to the drawshape ; routines. ; There are five arrays, plus the actual shape data. The first two arrays ; are held in the area pointed to by the "shape" pointer, and are ; a series of pointers to the shape and mask data, respectively. The ; next three are held in the area pointed to by the "shapeinfo" pointer, ; and are the width of the shape (in pixels), the height of the ; shape (in lines), and the modulo of the shape (the number of bytes per ; line - with this data being constrained to either two or three bytes). ; ; The shape data is simply the bit patterns of the shape, plane by plane. ; The mask data is used to "cookie-cut" the shape onto the screen, and ; is the bit pattern of the shape, with a set bit whenever the same ; bit in the final shape is not transparent. The first longword in ; the shape data is a length word, indicating the total length of the ; data area - this is for simplicity in loading. ; The basic coordinates are held in a Mac-like "rect" array, which holds ; four words: the leftmost x coordinate, the topmost y coordinate, the ; rightmost x coordinate, and the bottommost y coordinate. This arrangement ; makes it easy to compute collisons between rectangles. LEFT EQU 0 TOP EQU 2 ; The offsets into the big array are precomputed for ease of access SHOFF EQU 0 ;The offset of the shape data pointers MOFF EQU 292 ;The offset of the mask data pointers HEIGHT EQU 584 ;The offset of the height values WIDTH EQU 146 ;The offset of the width values MODULO EQU 292 ;The offset of the modulo values include 'types.i' include 'custom.i' include 'blit.i' include 'dmabits.i' CSECT data,1 ; these are the externals. Mostly self-explanatory, except for "bp", ; which is an array of pointers to the individual bitplanes which make ; up the playfield. In this example, four planes are hardwired in. XREF _Screen ; The screen structure (playfield) XREF _custom ; To point to blitter XREF _shapes ; The shape and mask data XREF _bp ; a pointer to the bitplane pointers XREF _shapeinfo ; The shape height, width, and modulo ; these are defined here for debugging purposes only. XDEF fbltcon0 XDEF fbltcon1 XDEF fbltafwm XDEF fbltalwm XDEF fbltcpth XDEF fbltcptl XDEF fbltbpth XDEF fbltbptl XDEF fbltapth XDEF fbltaptl XDEF fbltdpth XDEF fbltdptl XDEF fbltsize XDEF fbltcmod XDEF fbltbmod XDEF fbltamod XDEF fbltdmod ; these are the blitter shadow registers. For some reason, direct writes ; to the blitter register did not work correctly, while indirect writes ; did not. I haven't the slightest idea why - but this works, at the ; cost of one additional set of accesses. fbltcon0: DC.W 0 fbltcon1: DC.W 0 fbltafwm: DC.W 0 fbltalwm: DC.W 0 fbltcpth: DC.W 0 fbltcptl: DC.W 0 fbltbpth: DC.W 0 fbltbptl: DC.W 0 fbltapth: DC.W 0 fbltaptl: DC.W 0 fbltdpth: DC.W 0 fbltdptl: DC.W 0 fbltsize: DC.W 0 fbltcmod: DC.W 0 fbltbmod: DC.W 0 fbltamod: DC.W 0 fbltdmod: DC.W 0 CSECT text ; drawshape(number, where) ; short number; ; struct Rect *where; ; ; (using Lattice register parameter passing, number is passed in d0, ; the pointer to where in a0.) ; ; eraseshape(number, where) ; parameters as above. XDEF _drawshape XDEF _eraseshape ; outside routines used, using Lattice's bindings instead of "OVF" styles. XREF _OwnBlitter XREF _DisownBlitter XREF _WaitBlit _drawshape: movem.l d2-d7/a2-a6,-(a7) lea _custom,a5 ;point to the custom address ;Calculate the bitplane offset for this X,Y value - place into D2, with ;D3 the number of pixels offset from the word boundary move (a0)+,d2 ;get the Y value ext.l d2 ;make it a long asl.l #3,d2 ;d2 = Y*8 move.l d2,d1 ;save it for now asl.l #2,d2 ;d2 = Y*32 add.l d1,d2 ;d2 = Y*40 move (a0),d3 ;d3 = X ext.l d3 ;make it long move.l d3,d1 ;temp save x in d0 andi.l #15,d3 ;d3 = bit shift ror.w #4,d3 ;move to high order nibble asr.l #3,d1 ;d0 = words of x andi #$fffffffe,d1 ;convert to word address add.l d1,d2 ;d2 = y*40+x ;Extract addresses and dimensions from shapeinfo. Figure address ends up ;in A2, mask address in A3. Height in d4, modulo in d5. Setup some of ;the blitter shadow registers as appropriate. ext.l d0 ;make the number a fake long movea.l _shapeinfo,a0 ;point to the shape information adda.l #4,a0 ;a0 points to shape data offset movea.l a0,a4 ;save it here, too... adda.l #HEIGHT,a4 ;a4 points to height data offset asl.l #1,d0 ;times two (for WORD) adda.l d0,a4 ;calculate height offset asl.l #1,d0 ;calculate the offset for data adda.l d0,a0 ;a0 points to figure data offset movea.l _shapes,a2 ;get the shape data pointer movea.l a2,a3 ;into both registers adda.l (a0),a2 ;a2 now points to figure data adda.l MOFF(a0),a3 ;a3 now points to mask data move.w (a4),d4 ;d4 now has the height move.w MODULO(a4),d6 ;and d6 the modulo ;Setup the blitter shadow registers. Most of these will not change ;from plane to plane, so can be set up now. move.l a3,fbltbpth ;address of mask data in "B" move.w #0,fbltamod ;no modulo for figure move.w #0,fbltbmod ;or mask move.l #-1,fbltafwm ;setup masks move.l #$0fe20000,d0 ;save bltcons temporarily or.l d3,d0 ;or in the "b" shift value swap d3 ;swap words in shift or.l d3,d0 ;"or" in the "a" shift value move.l d0,fbltcon0 ;setup controller move.w d4,d5 ;calculate the modulo for figure cmpi.w #3,d6 ;if modulo == 3, setup differs bne.s notthree ; asl.w #1,d4 ;height * 4 words asl.w #2,d5 ;d5 = height * 4 add.w d4,d5 ;d4 = height * 6 asl.w #5,d4 ;d4 = vertical size or.w #3,d4 ;horizontal size = 3 move.w d4,fbltsize move.w #34,fbltcmod ;34 byte modulo for this one move.w #34,fbltdmod ;and this, too. bra.s domod ;finish it off notthree: asl.w #6,d4 ;size = height * 64 asl.w #2,d5 ;size of this bit plane mod. or.w #2,d4 ;or in the width move.w d4,fbltsize ;and save it move.w #36,fbltcmod ;36 byte modulo for screen move.w #36,fbltdmod ;in both registers domod: ;Setup the pointer to the bitplanes in a4, and the bitplane counter in ;d7. ext.l d5 ;make sure d5 is long lea _bp,a4 ;get pointer to first plane moveq #4,d7 ;do four planes PlaneLoop: movea.l (a4)+,a0 ;a0 = bitplane to do adda.l d2,a0 ;add in offset to first word move.l a2,fbltapth ;address of data in "A" move.l a0,fbltcpth ;address of screen in "C" move.l a0,fbltdpth ;and in "D" jsr DoRealBlit adda.l d5,a2 ;point to next line of shape subq.w #1,d7 ; bne PlaneLoop ;and the planes movem.l (a7)+,d2-d7/a2-a6 ;restore registers rts ;and return _eraseshape: movem.l d2-d7/a2-a6,-(a7) lea _custom,a5 ;point to the custom address ;Calculate the bitplane offset for this X,Y value - place into D2, with ;D3 the number of pixels offset from the word boundary move (a0)+,d2 ;get the Y value ext.l d2 ;make it a word asl.l #3,d2 ;d2 = Y*8 move.l d2,d1 ;save it for now asl.l #2,d2 ;d2 = Y*32 add.l d1,d2 ;d2 = Y*40 move (a0),d3 ;d3 = X ext.l d3 ;make it a word move.l d3,d1 ;temp save x in d0 andi.l #15,d3 ;d3 = bit shift ror.w #4,d3 ;move to high order nibble asr.l #3,d1 ;d0 = words of x andi #$fffffffe,d1 ;convert to word address add.l d1,d2 ;d2 = y*40+x ;Extract addresses and dimensions from shapeinfo. Mask address ends up ;in A2, height in d4, modulo in d5. Setup some of the blitter shadow ;registers as appropriate. ext.l d0 ;extend the pointer to a long movea.l _shapeinfo,a0 ;point to the shape information adda.l #4,a0 ;a0 points to shape data offset movea.l a0,a4 ;save it here, too... adda.l #HEIGHT,a4 ;a4 points to height data offset asl.l #1,d0 ;times two (for WORD) adda.l d0,a4 ;calculate height offset asl.l #1,d0 ;calculate the offset for data adda.l d0,a0 ;a0 points to figure data offset movea.l _shapes,a3 ;get the shape data pointer adda.l MOFF(a0),a3 ;a3 now points to mask data move.w (a4),d4 ;d4 now has the height move.w MODULO(a4),d6 ;and d6 the modulo ;Setup the blitter shadow registers. Most of these will not change ;from plane to plane, so can be set up now. move.l a3,fbltapth ;address of mask data in "A" move.w #0,fbltamod ;no modulo for figure move.l #-1,fbltafwm ;setup masks move.l #$0b0a0000,d0 ;save bltcons temporarily swap d3 ;swap words in shift or.l d3,d0 ;"or" in the "a" shift value move.l d0,fbltcon0 ;setup controller cmpi #3,d6 ;if modulo == 3, setup differs bne.s notthreea ; asl.w #1,d4 ;height * 4 words asl.w #2,d5 ;d5 = height * 4 add.w d4,d5 ;d4 = height * 6 asl.w #5,d4 ;d4 = vertical size or.w #3,d4 ;horizontal size = 3 move.w d4,fbltsize move.w #34,fbltcmod ;34 byte modulo for this one move.w #34,fbltdmod ;and this, too. bra.s domoda ;finish it off notthreea: asl.w #6,d4 ;size = height * 64 or.w #2,d4 ;or in the width move.w d4,fbltsize ;and save it move.w #36,fbltcmod ;36 byte modulo for screen move.w #36,fbltdmod ;in both registers domoda: ;Setup the pointer to the bitplanes in a4, and the bitplane counter in ;d7. ext.l d5 ;make sure d5 is long lea _bp,a4 ;get pointer to first plane moveq #4,d7 ;do four planes PlaneLoopa: movea.l (a4)+,a0 ;a0 = bitplane to do adda.l d2,a0 ;add in offset to first word move.l a0,fbltcpth ;address of screen in "C" move.l a0,fbltdpth ;and in "D" jsr DoRealBlit subq.w #1,d7 ; bne PlaneLoopa ;and the planes movem.l (a7)+,d2-d7/a2-a6 ;restore registers rts ;and return DoRealBlit: jsr _OwnBlitter jsr _WaitBlit move #$8400,dmacon(a5) ;nasty blitter move fbltcon0,bltcon0(a5) move fbltcon1,bltcon1(a5) move fbltafwm,bltafwm(a5) move fbltalwm,bltalwm(a5) move.l fbltcpth,bltcpt(a5) move.l fbltbpth,bltbpt(a5) move.l fbltapth,bltapt(a5) move.l fbltdpth,bltdpt(a5) move fbltcmod,bltcmod(a5) move fbltbmod,bltbmod(a5) move fbltamod,bltamod(a5) move fbltdmod,bltdmod(a5) move fbltsize,bltsize(a5) w1: btst #DMAB_BLTDONE-8,dmaconr(a5) ;check it bne.s w1 ;loop 'til done jsr _DisownBlitter rts end -- Mike Farren farren@well.sf.ca.us