AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)

Started by kevin, March 17, 2012, 08:34:43 PM

Previous topic - Next topic

Kev G

Hello Kevin.

Just registered to say that I (and many other amos users) have been following your progress on this for a couple of weeks now.
I must say that it is looking promising. I use a real Amiga for AMOS programming and there are many others like me who still
design programs for the Amiga.

I really hope that you can knock up an AGA Dual Playfield mode at some point. I've tried it myself
using a modified copper list but its not a workable solution. I have however, managed to get a 'Sliced-HAM' screen working
using the copper list from a 4 bit display. It displays 16 unique colours on each scan line so on a PAL display you have 4096 colours
without the dithering that you get on a standard HAM display. If you want the code for AGE then I would be more than happy
to give you it so that you can include it in AGE.

Keep up the good work.

Kev G.

kevin

 Hi Kev,

Quote
Just registered to say that I (and many other amos users) have been following your progress on this for a couple of weeks now.
I must say that it is looking promising. I use a real Amiga for AMOS programming and there are many others like me who still
design programs for the Amiga.

    Well,  it's nice to know that somebody noticed, had assumed so from the view count.   I really can't stress enough that while AGE works, its far from a tried and true polished solution,  so people should keep their expectations well and truly in check.   I hope it works OK on real hardware, but it might not also !

    The clean up has taken a bit longer than expected, but will not doubt reuse bits of the lib in other projects.. so all is not lost.

Quote
I really hope that you can knock up an AGA Dual Playfield mode at some point. I've tried it myself
using a modified copper list but its not a workable solution. I have however, managed to get a 'Sliced-HAM' screen working
using the copper list from a 4 bit display. It displays 16 unique colours on each scan line so on a PAL display you have 4096 colours
without the dithering that you get on a standard HAM display. If you want the code for AGE then I would be more than happy
to give you it so that you can include it in AGE.

   yeah..   Dual playfield & dyanmic had crossed my mind, the copper support in the library isn't like AMOS's native management, in fact there's barely any copper related functions at all.  The standard view, just sets the display mode, bitplane pointers, 24bit palette  and that's about it.  You can roll your own copper list,  which is not unlike how the original AmosAGA hack works. 
     
   Setting a dual playfield screen, will mean creating two 4bit AGE screens, then building a copper view with dual mode enabled.   One of the issues with the AGA chipset,  is that running all 8 bitplanes chews up a loads of DMA during our video refresh. Much, like turning hires modes on.   We can reduce this some what, by enabling 32bit or 64bit fetch modes for the video hardware, but this some negative side affects, in that it means everything must be alligned to either 32 or 64 bits.   This is not really issue if you want to scroll the screen vertically, but horizontally it can be rather painful, since we have to over side the buffers to accommodate hardware scrolling, which kills most of the hardware sprites.   

   Anyway, we'll see how we go.



kevin


  AGE - 8Bit Planar Line Rendering / Line Queues

      There's still a few odds and ends that i'm cleaning up.  The replacement line clipper and chunky line render are in and work pretty well. But the older line render was blitter based and choked badly, very badly.   It didn't really fit with design of library, which was originally written to favor CPU rendering over blitter, as mid range systems 020/030 with fast memory can easy beat it.       
     
      Anyway, so now the line function can draw to chunky or planar surfaces, if your going to be drawing to planar, then I'd really recommend going easy on it, in particular when rendering directly to chip/video memory.    Speed wise, it's ok given its a generic routine after all.   Moreover, while looking through the functions there was line queue stub, but no actual routine.   I dunno if that was in the older release version  or not, I think this based on the final source(s), but ya never know..   But it's added now. 

      The Line queue has two functions the render function AGE_LINE_QUEUE[Ptr,Xoffset,YOffset,FLAGS,ITEMCOUNT]  and the queue builder function.  AGE_SET_LINE_QUEUE[Ptr,QueueIndex,X1,Y1,X2,y2,ColorINdex] ,  each queye item is 10 bytes  in memory (X1.w,Y1.w,X2.w,y2.w,Colour.w) .  When you render, you can uses the flags parameter to select if you want the output to be clipped or not.  Warning,  if you turn clipping off and render outside the viewport, it will crash !


kevin

  AGE - Interleaved Planar + Porting Colour Functions

    The original AGE lib had provision for both standard PLANAR and INTERLEAVED planar, but the interleaved mode didn't seem to work in the latest versions.   Turned out to be just the pre mult table wasn't being set up correctly in that mode.  The premult's is a look up table of Y values, that library routines use when working out the address of particular scan line when reading or writing a screen buffer,  it's just quicker fetching pre-computed values than multing the Y coordinate by the surface pitch every time.    

     In early versions of the update the Colour functions were written in AMOS, but unfortunately doing things like blending RGB values is a lot of work for AMOS to actually do.  Wasn't going to bother, but if you try and fade the palette IN/OUT then just calling the blend function 256 times can eat most of a complete frame on it's own.  Which is a bit scary really,  so those functions have been ported to assembly and dropped into the library.

     For the sake of a comparison,   the native version the RGB_ALPHA_BLEND function is about 25 FRAMES (that's about 25*20 milliseconds) faster than interpreted AMOS implementation when blending 2000 colours.   While not exactly a fair comparison, it does demostrate just how important data management seems to be in AMOS.  

     Another subtle change has been to the initialize function for AGE, it appears that I can use variable pointers to help with the function pointer initializations.   While I haven't rolled this completely out, it'd not doubt save some code bloat in the library, with minimal fuss.  The down side of such a change is the having to be a bit more careful with the order of declaration in the start up.    
   

     Sample Colour Functions Test Code (Requires Dev Version Of AGE).



Set Buffer 50

' *=-------------------------------------------------------------------=*
'  
'                            AGE - Colour Functions  
'
'                                      By  
'
'                                By Kevin Picone
'
'                         Last Updated - 13th, Apr, 2012                  
'
'                (c) Copyright 1997/98/1999/2000- 2012, Kevin Picone
'
'                             www.UnderwareDesign.com        
'
' *=-------------------------------------------------------------------=*
'

   ' Sorry but AMOSPRO seems to require absolute include paths ??  
   '  SO,  YOU'LL HAVE TO TWEAK THE PATHS IN ORDER TO RUN
   '  THE DEMOS FROM AMOS/AMOSPRO correctly on your machine    


   ' To make the pathing less annoying, here we store the 'root path'  
   '  in a variable APPPATH$ .. Then use this through our program.  


     APPPATH$="Dh0:/AGE_V102/"



    ' Set the location of the AGE lib..  
      AGE_LIBRARY_PATH$=APPPATH$+"Includes/Asm/Age.lib"

    ' Include the AGE wrapper into your AMOS project
      Include "Dh0:/AGE_V102/INCLUDES/AMOS/AGE_V076.AMOS"


'   *=-----------------------------------------------------------------=*    '
'
'                        >> TEST COLOUR FUNCTIONS <<
'
'   *=-----------------------------------------------------------------=*    


 RGB[255,16,$A0]

 C=Param
 Print Hex$(C)

 RGBR[C]
 Print "R:"+Hex$(Param)

 RGBG[C]
 Print "G:"+Hex$(Param)

 RGBB[C]
 Print "B:"+Hex$(Param)


'-----------------------------------------------

Print ""



 RGB_24TO12[C]
 C12=Param
 Print "RGB12to12:"+Hex$(C12)



 RGB_12TO24[C12]
 C24=Param

 Print "RGB12to24:"+Hex$(C24)




'-----------------------------------------------


 RGB1=$8090A0
 RGB2=$10203

 RGB_ADD[RGB1,RGB2]

 C=Param
Print ""
 Print "RGB  Alpha Add"
 Print Hex$(RGB1)
 Print Hex$(RGB2)
 Print Hex$(C)


 RGB_SUB[RGB1,RGB2]

 C=Param
 Print "RGB  Alpha Add"
 Print Hex$(RGB1)
 Print Hex$(RGB2)
 Print Hex$(C)



'-----------------------------------------------


Print ""

Print "FADE RGB"

 RGB_FADE[RGB1,0.5]

 C=Param
 Print Hex$(RGB1)

 Print Hex$(C)





'-----------------------------------------------
Print "Press Space"
Wait Key

Cls


  Print ""

  Print "FADE ALPHA BLEND"

  RGB1=$AABBCC
  RGB2=$334455


  RGB_ALPHA_BLEND[RGB1,RGB2,0]
  Print Hex$(Param)



  RGB_ALPHA_BLEND[RGB1,RGB2,1]
  Print Hex$(Param)

  RGB_ALPHA_BLEND2[RGB1,RGB2,1]
  Print Hex$(Param)



  RGB_ALPHA_BLEND[RGB1,RGB2,0.5]
  Print Hex$(Param)

  RGB_ALPHA_BLEND2[RGB1,RGB2,0.5]
  Print Hex$(Param)



  Print "Speed Test Start"

   M=10000

  ST=Timer()

   For LP=0 To M
      RGB_ALPHA_BLEND[RGB1,RGB2,0.5]
   Next

   T=Timer()

      Print(T-ST)



  ST=Timer()

    For LP=0 To M
       RGB_INT_ALPHA_BLEND[RGB1,RGB2,128]
    Next

   T=Timer()

      Print(T-ST)



  ST=Timer()

     For LP=0 To M
        RGB_ALPHA_BLEND2[RGB1,RGB2,0.5]
     Next

   T=Timer()

   Print(T-ST)

  Wait Key


        ' -----------------------------------  
        ' Clean Up/Close Down AGE  
        ' -----------------------------------  
           AGE_CLEAN_UP






 

kevin

  AGE - Convex Polygon Rendering (Flat / Gouraud / Texture Mapped)

   Dropped a bit more time into this update yesterday afternoon,  the new code is a replacement of poylgon edge conversion routines.   The code was basically drag and dropped in from PlayBASIC,  while the library already contained triangle based rendering routines, which apart from being a big mess, they're limited to only triangles.    So of you want to render a textured quad, you had to draw it in at least two halves.  When you do this, we're doubling a number operations not to mention that one edge is converted twice.

   So a better solution is to use a polygon filler than can render sets of 3 or more vertex, which is how the replacement  routine works.  It's limited to the 32 vertex,  but can potentially draw any set as long as the vertex form a convex polygon shape.  It'll fail on the concave or complex polygons.

   In the picture bellow we're looking at a flat filled quad drawn over the star field example, the colours per scan line is just random junk in this example.  Porting the code was pretty painless,  a few syntax issues with comments in VBCC, but you get that.   Typically when things are moving quickly something pops up to hinder that progress and this time was no exception.   So the routine was ported, but of course when I called it from the library, nothing happened..

   Long story short,  the ported code isn't identical to the version in PB, this version is styled to use the AGE screen structure.  In AGE the viewport structure is 16bit, it's 32bit in PB.  Which turned out to the problem.  The caller was passing a 32bit structure in where it expected a 16 bit.  Making it reject virtually anything.  Pretty novel issue, but annoying none the less.  
   
   The polygon fillers, don't actually draw pixels.  It just calcs the visible spans.  In the example bellow, i'm just running through the resulting span buffer can drawing LINES between them for test purposes.    What i plan to do in this session,  is set up the filler to use the built in SPAN routines (which are used in Circles/Boxes) to render the strips out.   At least then the flat shaded filler work on chunky or planar/interleaved screens.   Texture Mapping and Gouraud will be CHUNKY only i'm afraid.

   

AGE - Filled TRI + QUADS

     Dropped in the some commands into the Amos wrapper (Second picture), they're basically the same as the PB commands, so we've AGE_TRI[x1,y1,x2,y2,x3,y3] and it's sister function AGE_TRIC[x1,y1,x2,y2,x3,y3,Colour] as well as AGE_QUADC[x1,y1,x2,y2,x3,y3],x4,y4,Colour.  It's nice being able to project some points and and just draw quad out of the edge verts.

     The Texture mapped and gouraud version of the span buffering as in, but there's no AMOS wrapping code at the moment.  There's a lot of Amos function overhead passing all the required fields into the function.  Might end up having  Textured TRI + Textured Quad functions, with some type of user generated vertex buffer.   A vert buffer would prolly be best.   

   

kevin

  AGE - FIXED POINT MATH / TRIG FUNCTIONS

    From messing with AMOS, you can't help but notice floating point performance isn't pretty.  It's not really AMOS's fault, given it's just using the Amiga floating point math libraries underneath, which need to emulate FPU when one's not present.   You can improve the performance on real hardware, if you have FPU in your system, by replacing the math lib with an FPU optimized version (Check Aminet there some on there).     Even so, Fixed Point should still be better. 
   
     While most of the examples shown here are using fixed point, there is some floating poijnt usage still in them, namely COS/SIN functions.  So i've knocked up a couple of Fixed point replacement functions for the native routines.   The routines use a 16:16 formatted fixed point values, so there's 16 bits one whole part and 16 bit fractional part.    This limits the numeric range, but we can perform floating point styled using Integer operations without same the Floating Point overhead.  

     The functions i've included focus around cos/sine,  where functions like AGE_COS[ANGLE]  / AGE_SIN[ANGLE]   are the COS/SIN equivalents.  Internally the lib uses a sinus TABLE, so it should be pretty efficient.  I often use polar coordinates when mapping character paths in games (Angle and Speed), so i've added a couple of functions that bundle up some processing into a single function.   While i suspect this will be slower from the AMOS interpreter,  compiled it should work really well, if not... You could actually inline some of those function if push came to shove.  

     Anyway,  in the example we're plotting some circles using the functions.  



Set Buffer 50

' *=-------------------------------------------------------------------=*
'  
'                   AGE - FIXED POINT MATH/ TRIG FUNCTIONS  
'
'                                      By  
'
'                                By Kevin Picone
'
'                         Last Updated - 18th, Apr, 2012                  
'
'                (c) Copyright 1997/98/1999/2000- 2012, Kevin Picone
'
'                             www.UnderwareDesign.com        
'
' *=-------------------------------------------------------------------=*
'

   ' Sorry but AMOSPRO seems to require absolute include paths ??  
   '  SO,  YOU'LL HAVE TO TWEAK THE PATHS IN ORDER TO RUN
   '  THE DEMOS FROM AMOS/AMOSPRO correctly on your machine    


   ' To make the pathing less annoying, here we store the 'root path'  
   '  in a variable APPPATH$ .. Then use this through our program.  


     APPPATH$="Dh0:/AGE_V102/"



    ' Set the location of the AGE lib..  
      AGE_LIBRARY_PATH$=APPPATH$+"Includes/Asm/Age.lib"

    ' Include the AGE wrapper into your AMOS project
      Include "Dh0:/AGE_V102/INCLUDES/AMOS/AGE_V081.AMOS"


'   *=-----------------------------------------------------------------=*    '
'
'                        >> TEST FIXED POINT MATH FUNCTIONS <<
'
'   *=-----------------------------------------------------------------=*    

'    


' Step Fixde point accuracy (16 bits if fraction part)
ACC=$10000

' Size of the circles we'll be drawing

RADIUS=100



' Testing the FIXED POINT COS + SIN  
'  These function return a cos/sin value in fixed point 16:16 format
' the function returns results in fixed point 16:16 format


For LP=-360 To 720 Step 2

  AGE_COS[LP]
  X=Param*RADIUS

  AGE_SIN[LP]
  Y=Param*RADIUS

 Plot 160+X/ACC,100+Y/ACC

Next


Print "AGE FIXED POINT COS & SIN"
Print "Ppess Space"
Wait Key

Cls

' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------




' Testing the FIXED POINT COSRADIUS + SINRADIUS  
'  This function Mults the Cos/Sin value by radius as part of it
' the function returns results in fixed point 16:16 format


For LP=-360 To 720 Step 2

  AGE_COSRADIUS[LP,RADIUS]
  X=Param

  AGE_SINRADIUS[LP,RADIUS]
  Y=Param

 Plot 160+X/ACC,100+Y/ACC

Next

Print "AGE FIXED POINT COSRADIUS & SINRADIUS"
Print "Press Space"
Wait Key

Cls



' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------

' Testing the FIXED POINT POLAR
'  This function returns movement along X / Y cord
' from an angle and Radius/speed
' the results are in fixed point 16:16 format  


For LP=-360 To 720 Step 2

  AGE_POLAR[LP,RADIUS]
  X=Dreg(0)
  Y=Dreg(1)

  Plot 160+X/ACC,100+Y/ACC

Next

Print "AGE POLAR"
Print "Press Space"
Wait Key

Cls



' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------

' Testing the FIXED POINT POLAR STEP
'  This function returns movement along X / Y cord
' from an angle and Radius/speed
' the results are in fixed point 16:16 format  


' calc the screen center in Fixed point  
 CX=160*ACC
 CY=100*ACC


For LP=-360 To 720 Step 2

  AGE_POLARSTEP[LP,RADIUS,CX,CY]
  X=Dreg(0)
  Y=Dreg(1)

  Plot X/ACC,Y/ACC

Next

Print "AGE POLAR STEP (FIXED POINT)"
Print "Press Space"
Wait Key

Cls




' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------

' Testing the FIXED POINT POLAR STEP (INTEGER)
'  This function returns movement along X / Y cord
' from an angle and Radius/speed
' the results are as signed integers



' calc the screen center in Fixed point  
 CX=160*ACC
 CY=100*ACC


For LP=-360 To 720 Step 2

  AGE_INTPOLARSTEP[LP,RADIUS,CX,CY]
  X=Dreg(0)
  Y=Dreg(1)

  Plot X,Y

Next

Print "AGE POLAR STEP (INTEGER)"
Print "Press Space"
Wait Key

Cls

        ' -----------------------------------  
        ' Clean Up/Close Down AGE  
        ' -----------------------------------  
           AGE_CLEAN_UP







kevin

  AGE - FIXED POINT MATH / ROTATE2D and ROTATE2D BATCH

     Did a little more tinkering with the math functions last night, adding a 2D ROTATE vertex function, along with a Batch version of the function.    The rotated 2d function, takes an individual 2D vector and rotates this by the required number of degrees   AGE_ROTATE2D[ANGLE,X,Y], the function returns the rotated vector in registers D0 and D1.

    So to rotate the point at 100x,200y by 50 degrees  we'd go



    AGE_ROTATE2D[50,100,200]

    NewX = Dreg(0)
    NewY = Dreg(1)



    Input and returns coordinates are in 32bit Integers.  Internally the rotation is all fixed point though and is faster than manually rotating the point in pure AMOS code.     The trouble is with calling AMOS functions heavily in our programs,  is that it add overhead to the procedure.   So a faster method, is to rotate a BATCH of vertex in one hit.  So the function call has very little (none really) impact upon performance.  To do this, we've added the AGE_ROTATE2D_BATCH function.    

   AGE_ROTATE2D_BATCH is a little more complex to set up, but will give us much better through put for the more verts you want to rotate.   The function expects the user  to set up two buffers of suitable size. (  if they're not it'll die !).    These are the SOURCE and DESTINATION vertex buffers.    It's not recommended to use the same buffer for both source and destination, since this will only give you compounded precision errors, over successive rotations.      

   AGE_ROTATE2D_BATCH[SRCPTR,SRCVERTEXMODULO,DESTPTR,DESTVERTEXMODULO,METHOD,ANGLE,VERTEXCOUNT]

   SrcPTR  = The address of the original (none rotated) vertex

   SrcVertexModulo  = The distance (in bytes) between each vertex

   DESTPTR  = The address where the rotated vertex will be stored.  

   DestVertexModulo  = The distance (in bytes) between each vertex

   METHOD =  1= 32bit Vertex ,  - = 16bit vertex

   ANGLE = To rotate this set i degrees

   VERTEXCOUNT = Number of verts in this batch


  When calling the function, we can choose the size of the vertex data using the METHOD field.  There's only 2 options, 16bit or 32bit.   In 16bit mode, the routine expects the X data to be located at SRCPTR, and Y data to be located at SRCPTR+2, same for Destination data.   In 32bit mode, they're 4 bytes apart in source and destination.    The modulo allows you to access structures of different width.    

  Ideally what this allows us to do, is create queues of dots / lines then batch rotate the ordinates prior to rendering the queue.  This bypasses a huge amount of AMOS overhead and will give us near assembly results.    


  Math Test Example



' *=-------------------------------------------------------------------=*
'  
'                   AGE - FIXED POINT MATH/ TRIG FUNCTIONS  
'
'                                      By  
'
'                                By Kevin Picone
'
'                         Last Updated - 19th, Apr, 2012                  
'
'                (c) Copyright 1997/98/1999/2000- 2012, Kevin Picone
'
'                             www.UnderwareDesign.com        
'
' *=-------------------------------------------------------------------=*
'

   ' Sorry but AMOSPRO seems to require absolute include paths ??  
   '  SO,  YOU'LL HAVE TO TWEAK THE PATHS IN ORDER TO RUN
   '  THE DEMOS FROM AMOS/AMOSPRO correctly on your machine    


   ' To make the pathing less annoying, here we store the 'root path'  
   '  in a variable APPPATH$ .. Then use this through our program.  


     APPPATH$="Dh0:/AGE_V102/"



    ' Set the location of the AGE lib..  
      AGE_LIBRARY_PATH$=APPPATH$+"Includes/Asm/Age.lib"

    ' Include the AGE wrapper into your AMOS project
      Include "Dh0:/AGE_V102/INCLUDES/AMOS/AGE_V082.AMOS"


'   *=-----------------------------------------------------------------=*  
'
'                        >> TEST FIXED POINT MATH FUNCTIONS <<
'
'   *=-----------------------------------------------------------------=*    
'    
 Curs Off


' Step Fixed point accuracy (16 bits if fraction part)
  ACC=$10000


' Size of the circles we'll be drawing
  RADIUS=100

'  Testing the FIXED POINT COS + SIN  
' These function return a cos/sin value in fixed point 16:16 format  
' the function returns results in fixed point 16:16 format


For LP=-360 To 720 Step 2

  AGE_COS[LP]
  X=Param*RADIUS

  AGE_SIN[LP]
  Y=Param*RADIUS

  Plot 160+X/ACC,100+Y/ACC

Next


  Print "AGE FIXED POINT COS & SIN"
  Print "Ppess Space"
  Wait Key

  Cls

' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------




' Testing the FIXED POINT COSRADIUS + SINRADIUS  
'  This function Mults the Cos/Sin value by radius as part of it
' the function returns results in fixed point 16:16 format


For LP=-360 To 720 Step 2

  AGE_COSRADIUS[LP,RADIUS]
  X=Param

  AGE_SINRADIUS[LP,RADIUS]
  Y=Param

 Plot 160+X/ACC,100+Y/ACC

Next

Print "AGE FIXED POINT COSRADIUS & SINRADIUS"
Print "Press Space"
Wait Key

Cls



' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------

' Testing the FIXED POINT POLAR
'  This function returns movement along X / Y cord
' from an angle and Radius/speed
' the results are in fixed point 16:16 format  


For LP=-360 To 720 Step 2

  AGE_POLAR[LP,RADIUS]
  X=Dreg(0)
  Y=Dreg(1)

  Plot 160+X/ACC,100+Y/ACC

Next

Print "AGE POLAR"
Print "Press Space"
Wait Key

Cls



' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------

' Testing the FIXED POINT POLAR STEP
'  This function returns movement along X / Y cord
' from an angle and Radius/speed
' the results are in fixed point 16:16 format  


' calc the screen center in Fixed point  
 CX=160*ACC
 CY=100*ACC


For LP=-360 To 720 Step 2

  AGE_POLARSTEP[LP,RADIUS,CX,CY]
  X=Dreg(0)
  Y=Dreg(1)

  Plot X/ACC,Y/ACC

Next

Print "AGE POLAR STEP (FIXED POINT)"
Print "Press Space"
Wait Key

Cls




' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------

' Testing the FIXED POINT POLAR STEP (INTEGER)
'  This function returns movement along X / Y cord
' from an angle and Radius/speed
' the results are as signed integers



' calc the screen center in Fixed point  
 CX=160*ACC
 CY=100*ACC


For LP=-360 To 720 Step 2

  AGE_INTPOLARSTEP[LP,RADIUS,CX,CY]
  X=Dreg(0)
  Y=Dreg(1)

  Plot X,Y

Next

Print "AGE POLAR STEP (INTEGER)"
Print "Press Space"
Wait Key

Cls



  Screen Open 0,320,200,16,Lowres
  Screen Open 1,320,200,16,Lowres




' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------

' Testing the FIXED POINT POLAR STEP (INTEGER)
'  This function returns movement along X / Y cord
' from an angle and Radius/speed
' the results are as signed integers



' calc the screen center

 CX=160
 CY=100


NUMBEROFLOOPS=50
For LP=0 To NUMBEROFLOOPS

   CURRENTBUFFER=1-CURRENTBUFFER
   Screen 1-CURRENTBUFFER
   Screen Show CURRENTBUFFER


   If LP+1=NUMBEROFLOOPS
     Print "Press Space"
    End If



  Cls
   Print "AGE ROTATE 2D"

   ANGLE=ANGLE+5 mod 360

   AGE_ROTATE2D[ANGLE,0,0]
   X1=CX+Dreg(0)
   Y1=CY+Dreg(1)

   AGE_ROTATE2D[ANGLE,100,0]
   X2=CX+Dreg(0)
   Y2=CY+Dreg(1)

   AGE_ROTATE2D[ANGLE,100,100]
   X3=CX+Dreg(0)
   Y3=CY+Dreg(1)

   AGE_ROTATE2D[ANGLE,0,100]
   X4=CX+Dreg(0)
   Y4=CY+Dreg(1)


   Polyline X1,Y1 To X2,Y2 To X2,Y2 To X3,Y3
   Polyline X3,Y3 To X4,Y4 To X4,Y4 To X1,Y1

Next

Print "Press Space"
Wait Key






' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------

'  Testing BATCH ROTATE Function on  array of 32bit integers
' the function has two data type methods built in.  It can
' rotate batches of 16bit vertexs or 32bit..  First we'll test
' 32bits

'  I'm using two arrays here. One as the source Vertex buffer
' and the other is the ROTATED vertex buffer. SO we create our
'  vertex set.   Then we just rotate them during the game, thus
' avoiding the need to recreate the source vertex each time.
'      
'  You should be able to use this function with the various queue
' functions in the library.  

  VERTEXCOUNT=100


' The number of bytes between each vertex in the source structure  
  SRCVERTEXMODULO=8

' The number of bytes between each vertex in the source structure  
  DESTVERTEXMODULO=8


  Dim VERTBUFFER(VERTEXCOUNT*(SRCVERTEXMODULO/4))
  Dim ROTATED_VERTBUFFER(VERTEXCOUNT*(DESTVERTEXMODULO/4))

 INDEX=0


 For LP=0 To(VERTEXCOUNT-1)
     X1=Rnd(320)-160
     Y1=Rnd(200)-100
     VERTBUFFER(INDEX)=X1
     VERTBUFFER(INDEX+1)=Y1
     Add INDEX,2
 Next




' calc the screen center

 CX=160
 CY=100


SRCPTR=Varptr(VERTBUFFER(0))
DESTPTR=Varptr(ROTATED_VERTBUFFER(0))


NUMBEROFLOOPS=25




For LP=0 To NUMBEROFLOOPS

   Screen Show CURRENTBUFFER
   CURRENTBUFFER=1-CURRENTBUFFER
   Screen CURRENTBUFFER


  Cls
   Print "AGE ROTATE 2D BATCHES"
   If LP+1=NUMBEROFLOOPS
     Print "Press Space"
    End If

   ANGLE=ANGLE+1 mod 360

   AGE_ROTATE2D_BATCH[SRCPTR,SRCVERTEXMODULO,DESTPTR,DESTVERTEXMODULO,1,ANGLE,VERTEXCOUNT]

   INDEX=0

   X1=CX+ROTATED_VERTBUFFER(INDEX)
   Y1=CY+ROTATED_VERTBUFFER(INDEX+1)


  For EDGELP=1 To VERTEXCOUNT-1

       X2=CX+ROTATED_VERTBUFFER(INDEX)
       Y2=CY+ROTATED_VERTBUFFER(INDEX+1)
       Add INDEX,2

       Polyline X1,Y1 To X2,Y2

       X1=X2
       Y1=Y2

  Next




Next

Print "Press Space"
Wait Key






' -------------------------------------------------------------
' -------------------------------------------------------------
' ------------------>> BRUTE FORCE TEST <<---------------------
' -------------------------------------------------------------
' -------------------------------------------------------------

 Screen CURRENTBUFFER
 Screen To Front CURRENTBUFFER


Cls

Print "Brute Force Math Test"


COUNT=10000



_STARTTIME=Timer

 For LP=0 To COUNT
     X=Cos(ANGLE)
 Next

 Print "Floating Point COS:"+Str$(Timer-_STARTTIME)




_STARTTIME=Timer

 For LP=0 To COUNT
     AGE_COS[ANGLE]
     X=Param
 Next

 Print "Fixed Point COS:"+Str$(Timer-_STARTTIME)




_STARTTIME=Timer

 For LP=0 To COUNT
     X=Cos(ANGLE)*RADIUS
 Next

 Print "Floating Point COS* RADIUS:"+Str$(Timer-_STARTTIME)


_STARTTIME=Timer

 For LP=0 To COUNT
     AGE_COSRADIUS[ANGLE,RADIUS]
     X=Param
 Next

 Print "Fixed Point COSRADIUS:"+Str$(Timer-_STARTTIME)



_STARTTIME=Timer

 For LP=0 To COUNT
     Dreg(0)=ANGLE
     Dreg(1)=RADIUS
     Call LIBAGE_COSRADIUS
     X=Dreg(0)
 Next

 Print "Unrolled Fixed Point COSRADIUS:"+Str$(Timer-_STARTTIME)


Wait Key



        ' -----------------------------------  
        ' Clean Up/Close Down AGE  
        ' -----------------------------------  
           AGE_CLEAN_UP




  At the bottom of the test is a loop that runs some brute force performance comparisons on the AGE_COS/SIN functions compared to the native floating point functions.    From the emulator I get some interesting, but not that unexpected results.   If we compare COS() with AGE_COS[], over 10,000 calls, the AGE function is quicker, but not dramatically so.  A lot benefit is lost wrapping the function as a Procedure.    Which is demonstrated nicely when comparing the Cos(Angle)*Radius  equivalents, in that they're about the same speed here.  That is, until you get rid of the procedure, then it's twice as fast.  


Compiling Amos Issues

   So far i'm just running the demos from the AmosPRO IDE / runtime interpreter, so we should be able to strip out a lot of runtime overhead when compiled to EXE, but the compiler doesn't want to play nice.   Not too sure what it's problem is, but it appears that the AGE Wrapper might need to be modded in order to be able to compile the final game/demos to EXE's.   Which is really NOT what i was hoping.    The library does actually run really well from the WinAUE 2.3.3 / with JIT enabled.  In fact we're seeing demo's approach 50fps under emulation,  chunky or planar doesn't seem to matter.    Which is neat for those running under emulation, but compiling to exe would be a huge benefit on real hardware.




kevin

  AGE - DRAW POLY  / DRAW TEXTURED POLY

        These touch back to triangle / quad routines mentioned previously.   In the original library, it seems that AMOS would spit out an integer overflow if it felt the result exceeds the range of 32bit value in some operations, which i'd never noticed before.   Anyway this would cause issues if which the polygon routines try and bundles up the coordinates into packed registers.  

        For example, the in triangle function there's enough registers to happily just send them as is,  but if you want gouraud or texture mapping you need to send more information than just the vertexs.  So the function would pack pairs  X1,Y1 / X2,Y2 / X3,Y3 into three 32bit registers.

        A bit like this.

        PackedX1Y1 = (X1 * $10000) + Y1

        But there's a few obvious problems with this, but mainly since the X1/Y1 are 32 bit integers,  what happens if X1 or Y1's negative ? .. Yeah it overflows...    To Get around this we need to mask the fields before ,merging the bits.    

        Something like this,

        PackedX1Y1 = ((X1 and $ffff) * $10000) + (Y1 and $ffff)

        But you'll still get overflows in AMOS, not too sure how MULT is implemented in AMOS actually, since the 68000 cpu doesn't have a native 32bit integer multiply, which makes you wonder ? hmmm.   Of course shifting is a much better option, but it seems the shifters are a type of custom operator in Amos.

        So to pack a pair of fields, we've effectively forced to do this.
 
        X1 = X1 and $ffff
        Rol.l 16,X1
        PackedX1Y1 = X1  or  (Y1 and $ffff)

           
        Now i only bring it up, as that's a lot of overhead on the AMOS side of the library to batch up the data every time to send it.   Obviously, it'd be a much better idea to stream line the data setup into a more Amos friendly format like an array or memory bank.  

        So the DRAWPOLY functions come at the same problem from that perspective, basically we fill in a list of Vertex data, pass this list to the polygon rendering function and it draws it for us (if possible).   There's a few limitations,  such as the shape must be convex and less than 32 vertex in the list, but that's about it.    You can draw filled shapes and texture mapped shapes also.  

        The DrawPoly functions expect user to lay the vertex data out in the following 20 byte structure,  X,Y, U,V, Col.  So each field is a 32bit integer



  0   X
  4   Y
  8   U
 12  V
 16  Col
 Size = 20 bytes


             

        So if you wanted to create a vertex buffer in an array,  what you'd is dimension the array so there's 5 times the number vertex you need.    Why 5 times ?, well each cell in the array is 4 bytes (one 32bit integer) so each cell is a field in our vertex structure above,  since the structure is 20 bytes, we'll need 5 slots per vertex in our array .  

       Ie.

       VertexCount = 10

       Dim Vertex_Buffer(VertexCount * 5)
       

    Then to render a textured 10 sided poylgon disc thing..  We can do that like this.


      ' Array index into Vertex_Buffer()
      INDEX=0

      ' Step in degrees for this number of vertex
       ANGLESTEP=360/VERTEXCOUNT

      ' Bump rotation angle each refresh
       SPIN=SPIN+2 mod 360

      ' Set starting angle to the current rotation angle
      ANGLE=SPIN

      ' Angle Texture coordinates.  These aren't rotating
        ANGLE2=0

           For LP=0 To VERTEXCOUNT-1
                ' bump the current angle
                ANGLE=ANGLE+ANGLESTEP mod 360

               '  project a polar cord at 150 units same as X=Cos(Angle)*Radius   / Y=Sin(angle)*RAdius
                 AGE_POLAR[ANGLE,150]

               ' set the X + Y cords of the Vertex
                VERTEX_BUFFER(INDEX)=160+Dreg(0)/$10000
                VERTEX_BUFFER(INDEX+1)=128+Dreg(1)/$10000

                ' set the U/V cord
                ANGLE2=ANGLE2+ANGLESTEP
                AGE_POLAR[ANGLE2,124]

                VERTEX_BUFFER(INDEX+2)=128+Dreg(0)/$10000
                VERTEX_BUFFER(INDEX+3)=128+Dreg(1)/$10000

                ' bump the array index to the next vertex in buffer
                Add INDEX,5

           Next

           ' Get the address of the first byte in this array
           PTR=Varptr(VERTEX_BUFFER(0))

          ' draw this shape as textured polygon using the dragon texture  
           AGE_DRAWTEXTUREDPOLY[PTR,VERTEXCOUNT,DRAGON_TEXTURE]



        Bellow you can see the result of the code, which is it's drawing a spining textured circle shape thing using the dragons texture map for something to look at.    You can draw the same thing as triangles, which is not a lot of extra programming, but it's lot of extra work on the AMOS and ultimately AGE.  




 AGE - GOURAUD TORUS (AGAIN)

        Hadn't updated all the polygon filler routines to the N-sided versions,  so bellow (Second shot) we see the gouraud torus demo, using the new filler with a object pushed right up in the viewers face.   It's running in the low 30fps mark under emulation (with jit).    To be honest, the fill quality isn't great, but it works.    

 

  AGE - GOURAUD QUAD

         Dropped a AGE_GouraudQUAD[x1,y1,c1,x2,y2,c2,x3,y3,c3,x4,y4,c4]  function into the wrapper.   Pictured bellow drawing a quad between some random palette data. 



 

kevin




A.G.E  V1.02 BETA #1  is Now Available (21st, Apr, 2012)



  This release contains an 'as is' snap shot of the AGE package at this time. Those familiar with the original package will notice a lot has changed since the previous release some 12 years ago, way too much to paraphrase now.  So to get up to speed please make sure you read this thread and the examples carefully.
   
   The package includes revision 85 of AGE AMOS wrapper and binary library, as well as various examples.

   What's AGE ?  it's a replacement / plug in graphics engine for AMOSPRO that enables AMOS programmers to use the AGA chipset.

   You can find out more information about AGE at AGE HOME PAGE



Download

  Download AGE V1.02 BETA #1  



Installation

  Download the package to your computer and unzip the folder.    The examples are hard coded to expect a path of DH0:AGE-V102-Beta-01,  so you'll need to mod the paths if you place it anywhere else.    You don't need to the copy the AGE.LIB file into your libraries folder, it's not a general purpose library.




History

   Changes since last release



---------------------------------------------------------------------------------------------------------------
         ------------------------------------>> Release V1.02 - BETA #1 << -------------------------------------------------
---------------------------------------------------------------------------------------------------------------

      Too many to mention





Amiten

Hi all,

First to all I want to say CONGRATULATIONS!! Kevin Picone for make this AGE extension Amazing Work!

I Coding in Amos/Amos pro from early 90 until 2003 and now in 2012 I working again with Amos in some own projects   an example :  http://youtu.be/qv8IK6aXV8k  or http://youtu.be/v-0_gJQAHDM this only some examples about ideas I want to do in future visit my web site in www.amiten.webatu.com for more info.

The thing is I would like to use your Extension to Have AGA support in AMOS ( just a Dream if I can Do it)

At the moment I only play i little bit with your extension AGE , but cant do work.

Y download the last Beta calls Download AGE V1.02 BETA #1  I extract on Dh0:  go in Amos pro and allways in winuae and in A1200 REAL say me the same this Screen:



So Really I dont know now What I Can Do with This...  hope some body can help me to start use AGE.

Thanks for all in advance,

Keep with the good Work!
And Amiga 4Ever!
Amiten.

kevin


Quote
At the moment I only play i little bit with your extension AGE , but cant do work.
I extract on Dh0:  go in Amos pro and allways in winuae and in A1200 REAL say me the same this Screen:

  It's not actually an extension, it's more a generic library.   The library comes with an AMOS wrapper and the raw machine code bundled up with it.     The wrapper is just a chunk of Amos code laid out as a set of procedures  that call the machine code library functions. 

  Setting it like this was meant to make it easier, but unfortunately AmosPro only seems to be support absolute include paths.  Meaning that if folder structure is extracted differently/moved etc,  than the code examples are setup to expect, Amos won't be able to locate the wrapper and you'll get that error from Amos. 

  So the package should be extracted to Dh0:AGE-V102-Beta-01/  inside this folder, there should  be the example files and the folders "includes", "Manual", GFxFiles and Tools. 


  ie. so  directory of the folder structure would look a bit like this. 



  Dh0:AGE-V102-Beta-01/includes
  Dh0:AGE-V102-Beta-01/includes/Amos
  Dh0:AGE-V102-Beta-01/includes/Amos/AGE_V085.AMOS
  Dh0:AGE-V102-Beta-01/includes/Asm/Age.lib
  Dh0:AGE-V102-Beta-01/includes/Manual
  Dh0:AGE-V102-Beta-01/includes/Tools
 
  Dh0:AGE-V102-Beta-01/Example_V001_Show_Picture.AMOS
  Dh0:AGE-V102-Beta-01/Example_V002_Palette.AMOS

  etc
  etc
  etc
  etc
  etc

  Dh0:AGE-V102-Beta-01/Example_V120_Dragon3.AMOS






Amiten


Hi Kevin  , Thanks for your quick Response ;)

Quote
  It's not actually an extension, it's more a generic library.   The library comes with an AMOS wrapper and the raw machine code bundled up with it.     The wrapper is just a chunk of Amos code laid out as a set of procedures  that call the machine code library functions. 

May be I´m a little crap jejeje, sorry   but Amos Wrapper?? dont know what is this, is a Extension for Amos??

Now I try again  download the AGE again in original Zip File. put in Winuae  extract with MirawizARC 1.1b  in DH0:   Rigth!   and  now I get diferent error:

   Variable´s Name buffer to small ???

I think now the Path is recognised rigth  but something  remain.

So if you know why I will very grateful .

Regards
Amiten
 
 

baggey

Hi, Just come across this thread  ;D

Ive browsed through and think.

I need Amos pro "Download" and the "Beta". Will google "AMOS PRO"

I never owned An amiga! But remember seeing a demo of "Walker" i think it was called. Which looked like cool game  :)

Baggey


Jesus was only famous because of his dad

colinmiland

There are a lot of engines and they do different things. Some are better in a smaller environment, some in a huge world. Some enable really complex water and visual effects, while others do great things with skelatal animation.

Epo

Hello Kevin,

Your AGE looks fantastic. I tried it couple of times in those past years. Also, did it today. However, I never succeeded in compiling any of your examples. Is it even possible? I'm experienced with Amos and I'd like to make use of your "extension" but if it can not be compiled then it misses the point. Can you help?