*  Assembler demo on how to use SpriteWiz created data  -  By D. Visage
*
*  Message Software
*  James Messa and David A. Visage
*  GET THE MESSAGE!
*
*  Note : This code will not assemble with the MetaComco assembler.
*         It will only assemble with the Manx 3.4 assembler.
*         You can, however, use the generated sprite data with both.
*
*  Note : To assemble and link (Two drives hopefully) -
*
*         as SW_AsmDemo.asm
*         ln SW_AsmDemo.o -lc32
*
              include   "exec/types.i"
              include   "intuition/intuition.i"
              include   "graphics/sprite.i"
              include   "DV.i"
*
*  A few standard equates
*
AbsExecBase   equ       $0004             ; The famous AbsExecBase
*
DELAY_VAL     equ       25                ; Alas, it is hard coded!
MAX_WIDTH     equ       640
MAX_HEIGHT    equ       200
WINDOW_FLAGS  equ       WINDOWCLOSE | SMART_REFRESH | ACTIVATE
*
COLOR00       equ       00
COLOR01       equ       01
COLOR02       equ       02
COLOR21       equ       21
COLOR22       equ       22
COLOR23       equ       23
*
SPRITE02      equ       02
SPR_HEIGHT    equ       16
SPRITE_X      equ       320
SPRITE_Y      equ       100
*
*  Macros for declaring and calling Amiga routines
*
XLIB          macro
              public    _LVO\1
              endm
*
EXECALL       macro
              move.l    AbsExecBase,a6
              jsr       _LVO\1(a6)
              endm
*
GFXCALL       macro
              move.l    GfxBase,a6
              jsr       _LVO\1(a6)
              endm
*
INTCALL       macro
              move.l    IntuiBase,a6
              jsr       _LVO\1(a6)
              endm
*
DOSCALL       macro
              move.l    DosBase,a6
              jsr       _LVO\1(a6)
              endm
*
*  You must not remove references to _main or .begin
*
              public    _main
              public    .begin
              XLIB      OpenLibrary
              XLIB      CloseLibrary
              XLIB      GetMsg
              XLIB      ReplyMsg
              XLIB      OpenWindow
              XLIB      CloseWindow
              XLIB      ViewPortAddress
              XLIB      SetRGB4
              XLIB      LoadRGB4
              XLIB      GetSprite
              XLIB      ChangeSprite
              XLIB      FreeSprite
              XLIB      Delay
*
              cseg
_main:
              jsr       OpenLibs               ; Open all needed libraries
              jsr       InitAll                ; Init display and sprite
              move.l    #NUM_SPRITES,d0        ; Get number of sprites
              lea       SPR00COL,a0            ; Get first sprite pointer
Loop:
              move.l    d0,SaveSprNum          ; Number of sprites
              move.l    a0,SaveSprPtr          ; Current sprite pointer
              jsr       ChangeImage            ; Change sprite image
              jsr       CheckClose             ; Close gadget hit?
              beq.s     EndProg                ; Yep!
*
              moveq     #DELAY_VAL,d1          ; Timeout value in d1
              DOSCALL   Delay                  ; Call delay function
*
              move.l    SaveSprPtr,a0          ; Get current sprite pointer
              adda.l    #si_SizeOf,a0          ; Get next sprite image
              move.l    SaveSprNum,d0          ; Get Sprite number counter
              subq      #$01,d0                ; Decrement counter
              bne.s     Loop                   ; Keep looping
*
              move.l    #NUM_SPRITES,d0        ; Re-initialize counter
              lea       SPR00COL,a0            ; Point back to first sprite
              bra.s     Loop                   ; Keep looping
EndProg:
              jsr       FreeAll                ; Free display and sprite
              jsr       CloseLibs              ; Close all used libraries
              rts
*
*  Open all needed libraries  --> intuition, graphics, and dos
*
OpenLibs:
              clr.l     d0                     ; Any version of dos
              lea       DosName,a1             ; Points to library name
              EXECALL   OpenLibrary            ; Call OpenLibrary
              move.l    d0,DosBase             ; Save library base pointer
*
              clr.l     d0                     ; Any version of intuition
              lea       IntuiName,a1           ; Points to library name
              EXECALL   OpenLibrary            ; Call OpenLibrary
              move.l    d0,IntuiBase           ; Save library base pointer
*
              clr.l     d0                     ; Any version of graphics
              lea       GfxName,a1             ; Points to library name
              EXECALL   OpenLibrary            ; Call OpenLibrary
              move.l    d0,GfxBase             ; Save library base pointer
              rts                              ; Back to caller
*
*  Open initial display and allocate sprite to play with
*
InitAll:
              lea       MyWindow,a0            ; Pointer to NewWindow
              INTCALL   OpenWindow             ; Call OpenWindow
              move.l    d0,WindowPtr           ; Save window pointer
*
              move.l    d0,a0                  ; Window pointer in a0
              INTCALL   ViewPortAddress        ; Call ViewPortAddress
              move.l    d0,VPortPtr            ; Save ViewPort pointer
*
              move.l    d0,a0                  ; ViewPort pointer in a0
              lea       ColorTable,a1          ; Table pointer in a1
              moveq     #$03,d0                ; Number of colors
              GFXCALL   LoadRGB4               ; Set screen colors
*
*  Initialize a sprite to play with
*
              lea       MySprite,a0            ; SimpleSprite pointer in a0
              moveq     #SPRITE02,d0           ; Sprite number in d0
              GFXCALL   GetSprite              ; Call GetSprite
*
              lea       MySprite,a0            ; Get SimpleSprite pointer
              move.w    d0,ss_num(a0)          ; Store sprite number
              move.w    #SPR_HEIGHT,d0         ; Get Sprite Height
              move.w    d0,ss_height(a0)       ; Store Height
              move.w    #SPRITE_X,d0           ; Get Sprite X
              move.w    d0,ss_x(a0)            ; Store X Coordinate
              move.w    #SPRITE_Y,d0           ; Get Sprite Y
              move.w    d0,ss_y(a0)            ; Store Y Coordinate
              rts                              ; Back to caller
*
*  Change sprite image to next in sequence
*
ChangeImage:
              move.l    SaveSprPtr,a0          ; Get current sprite in a0
*
              move.w    si_SprColor1(a0),d1    ; Packed UWORD color in d1
              moveq     #COLOR21,d0            ; Register to set in d0
              jsr       SetColor               ; Set sprite color
*
              move.w    si_SprColor2(a0),d1    ; Packed UWORD color in d1
              moveq     #COLOR22,d0            ; Register to set in d1
              jsr       SetColor               ; Set sprite color
*
              move.w    si_SprColor3(a0),d1    ; Packed UWORD color in d1
              moveq     #COLOR23,d0            ; Register to set in d0
              jsr       SetColor               ; Set sprite color
*
              lea       si_SprData(a0),a2      ; Pointer to sprite image
              move.l    VPortPtr,a0            ; ViewPort pointer in a0
              lea       MySprite,a1            ; SimpleSprite pointer in a1
              GFXCALL   ChangeSprite           ; Call ChangeSprite
              rts                              ; Back to caller              
*
*  Set indicated color register (d0) to desired color (d1)
*
SetColor:
              movem.l   d0-d3/a0-a3,SaveReg    ; Save used registers
              andi.l    #$0fff,d1              ; Clear high nybble of d1
              move.l    d1,SaveColor           ; Save color value
              moveq     #$08,d2                ; Initial shift value
              lea       RedBits,a0             ; Start of RGB color table
ColorLoop:
              move.l    SaveColor,d1           ; Get color in d1
              lsr.l     d2,d1                  ; Shift d1 right by (8,4,0)
              andi.l    #$0f,d1                ; Mask off low nybble
              move.l    d1,(a0)                ; Save d1 in current color
              adda.l    #$04,a0                ; Point to next color
              subq      #$04,d2                ; Get next shift value
              bpl.s     ColorLoop              ; Loop till mask is negative
*
              move.l    VPortPtr,a0            ; ViewPort pointer in a0
              move.l    RedBits,d1             ; Amount of red in d1
              move.l    GreenBits,d2           ; Amount of green in d2
              move.l    BlueBits,d3            ; Amount of blue in d3
              GFXCALL   SetRGB4                ; Call SetRGB4 function
              movem.l   SaveReg,d0-d3/a0-a3    ; Restore used registers
              rts                              ; Back to caller
*
*  Read close gadget and return 0 if depressed
*
CheckClose:
              move.l    WindowPtr,a1           ; Window pointer in a1
              move.l    wd_UserPort(a1),a0     ; Window reply port in a0
              EXECALL   GetMsg                 ; Call GetMsg
              cmpi.l    #$0,d0                 ; Is a message available?
              beq.s     NoMessage              ; Nope!
              move.l    d0,MessagePtr          ; Save MessagePtr
*
              move.l    d0,a1                  ; Message pointer in a1
              EXECALL   ReplyMsg               ; Reply to message
*
              move.l    MessagePtr,a0          ; Get message pointer
              move.l    im_Class(a0),d1        ; Get class of message
              cmpi.l    #CLOSEWINDOW,d1        ; Was close gadget hit?
              bne.s     NoMessage              ; Nope!
              moveq     #$0,d0                 ; Indicate gadget was hit
              rts                              ; Back to caller
*
NoMessage:    moveq     #$1,d0                 ; Something else happened
              rts                              ; Back to caller
*
*  Free display and sprite
*
FreeAll:
              moveq     #SPRITE02,d0           ; Sprite number in d0
              GFXCALL   FreeSprite             ; Call FreeSprite
*
              move.l    WindowPtr,a0           ; Pointer to window in a0
              INTCALL   CloseWindow            ; Call CloseWindow
              rts                              ; Back to caller
*
*  Close all used libraries
*
CloseLibs:
              move.l    DosBase,a1             ; Dos library base
              EXECALL   CloseLibrary           ; Call CloseLibrary
*
              move.l    IntuiBase,a1           ; Intuition library base
              EXECALL   CloseLibrary           ; Call CloseLibrary
*
              move.l    GfxBase,a1             ; Graphics library base
              EXECALL   CloseLibrary           ; Call CloseLibrary
              rts                              ; Back to caller
*
              dseg
*
*  Character strings used in program
*
DosName:      dc.b      'dos.library',0
              ds.w      0
*
IntuiName:    dc.b      'intuition.library',0
              ds.w      0
*
GfxName:      dc.b      'graphics.library',0
              ds.w      0
*
WindowTitle:  dc.b      ' SpriteWiz assembler demo  -  By D. Visage',0
              ds.w      0
*
*  Definition of default NewWindow structure
*
MyWindow:
              dc.w      0,0                    ; LeftEdge, TopEdge
              dc.w      MAX_WIDTH,MAX_HEIGHT   ; Width, Height
              dc.b      COLOR00,COLOR01        ; DetailPen, BlockPen
              dc.l      CLOSEWINDOW            ; IDCMPFlags
              dc.l      WINDOW_FLAGS           ; User defined flags
              dc.l      0                      ; struct Gadget *FirstGadget
              dc.l      0                      ; struct Image *Checkmark
              dc.l      WindowTitle            ; UBYTE *Title;
              dc.l      0                      ; struct Screen *Screen
              dc.l      0                      ; struct BitMap *BitMap
              dc.w      0,0                    ; MinWidth, MinHeight
              dc.w      0,0                    ; MaxWidth, MaxHeight
              dc.w      WBENCHSCREEN           ; Good old WorkBench
*
*  Initial colors - BackGround Black, Borders White, Everthing else Red
*
ColorTable    dc.w      $000,$fff,$f00
*
*  Storage for SimpleSprite structure
*
MySprite      ds.b      ss_SIZEOF              ; This is in bytes
*
*  Storage for converting packed UWORDS to RGB values
*
RedBits       ds.l      1
GreenBits     ds.l      1
BlueBits      ds.l      1
SaveColor     ds.l      1
*
*  Storage for global library base pointers
*
DosBase       ds.l      1
IntuiBase     ds.l      1
GfxBase       ds.l      1
*
*  Storage for pointers to Window,ViewPort, and IntuiMessages
*
WindowPtr     ds.l      1
VPortPtr      ds.l      1
MessagePtr    ds.l      1
*
*  These are used for the animation sequence
*
SaveSprNum    ds.l      1
SaveSprPtr    ds.l      1
*
*  Register storage
*
SaveReg       ds.l      8                    ; d0-d3/a0-a3
*
              end


