ifndef _CSprite_
_CSprite equ 1

; --=====================================================================================--
; #CLASS:    CSprite 
; #VERSION:  1.0
; --=====================================================================================--
; Built by NaN's Object Class Creator
; © Sept 19, 2001
;
; By Thomas Bleeker 
;
; --=====================================================================================--
; #AUTHOR: Thomas Bleeker 
; #DATE:   Sept. 20, 2001
;
; #DESCRIPTION:
;
;          This is the Sprite Object class.  It defines the basic attributes each
;          sprite object will have, and provides opperator methods to modify these
;          attributes in run time.<br><br>
;          This class has setup methods to get each sprite "orientated" to the
;
;          drawing DC (setScreenSize, setBitmap, setDrawingDC) and opperator methods
;          to change the attributes (move, setSpeed) and lastly a method to work with how
;          windows does GDI graphics (draw)..
;
; --=====================================================================================--
; CLASS METHOD PROTOS
; --=====================================================================================--

   CSprite_Init    PROTO :DWORD

; --=====================================================================================--
; FUNCTION POINTER PROTOS
; --=====================================================================================--
   CSprite_destructorPto    TYPEDEF  PROTO  :DWORD 
   CSprite_setBitmapPto	  TYPEDEF  PROTO  :DWORD, :DWORD
   CSprite_movePto		  TYPEDEF  PROTO  :DWORD 
   CSprite_drawPto		  TYPEDEF  PROTO  :DWORD 
   CSprite_setSpeedPto	  TYPEDEF  PROTO  :DWORD, :DWORD
   CSprite_setScreenSizePto TYPEDEF  PROTO  :DWORD, :DWORD, :DWORD
   CSprite_setDrawingDCPto TYPEDEF PROTO :DWORD, :DWORD
; --=====================================================================================--
; CLASS STRUCTURE
; --=====================================================================================--
   CLASS CSprite
      CMETHOD destructor 
      CMETHOD setBitmap				; sets bitmap for sprite
      CMETHOD move					; move sprite
      CMETHOD draw					; draw sprite on drawDC
      CMETHOD setSpeed
      CMETHOD setScreenSize
      CMETHOD setDrawingDC
      hBitmap		dd		?
      dcBitmap		dd		?
      drawDC		dd		?
      widthScreen	dd		?
      heightScreen	dd		?
      bmpWidth		dd		?
      bmpHeight		dd		?
      xPos			dd		?
      yPos			dd		?
      speed			dd		?
   CSprite ENDS

.data

   BEGIN_INIT 
      dd offset CSprite_destructor
      dd offset CSprite_setBitmap			;set bitmap of Spriteation
      dd offset CSprite_move
      dd offset CSprite_draw
      dd offset CSprite_setSpeed
      dd offset CSprite_setScreenSize
      dd offset CSprite_setDrawingDC
      dd 0 	 ; hBitmap
      dd 0   ; dcBitmap
      dd 0	 ; drawDC
      dd 0,0 ; width/height screen
      dd 0,0 ; width/height bitmap (set as soon as bitmap is loaded)
      dd 200 ; xPos (initial value)
      dd 150 ; yPos (initial value)
      dd 10  ; initial speed
   END_INIT


.code
; --=====================================================================================--
; #METHOD:      CONSTRUCTOR (NONE)
;
; #DESCRIPTION: Basic constructor setup, no extra procedures are included..
;
;
; #RETURN:      Nothing..
; --=====================================================================================--
CSprite_Init  PROC uses edi esi lpTHIS:DWORD
   SET_CLASS CSprite
   SetObject edi, CSprite

   ReleaseObject edi
   ret
CSprite_Init ENDP

; --=====================================================================================--
; #METHOD:      destructor (NONE)
;
; #DESCRIPTION: Will delete the object bimpate handle (if one is stored to this object), 
;               as well as delete the given DC (if one was stored to this object)..
;
; #RETURN:      Nothing..
; --=====================================================================================--
CSprite_destructor  PROC uses edi lpTHIS:DWORD 
   SetObject edi, CSprite

   mov eax, [edi].hBitmap
   .IF eax
   		invoke	DeleteObject, [edi].hBitmap
   .ENDIF
   
   mov eax, [edi].dcBitmap
   .IF eax
   		invoke	DeleteDC, eax
   .ENDIF
   
   ReleaseObject edi
   ret
CSprite_destructor  ENDP

; --=====================================================================================--
; #METHOD:      setBitmap (hBitMap)
;
; #DESCRIPTION: Creates a DC for this object and selects the passes hBitmap into it..
;
; #PARAM:       hBitmap    The handle of the bitmap to be used with this object..
;
; #RETURN:      Nothing..
; --=====================================================================================--
CSprite_setBitmap  PROC uses edi lpTHIS:DWORD, hBitmap:DWORD
LOCAL	tmpBITMAP:BITMAP
   SetObject edi, CSprite
   invoke	CreateCompatibleDC, NULL
   mov		[edi].dcBitmap, eax
   mov		eax, hBitmap
   mov		[edi].hBitmap, eax
   invoke	SelectObject, [edi].dcBitmap, [edi].hBitmap
  
   invoke	GetObject, hBitmap, SIZEOF BITMAP, ADDR tmpBITMAP
   mov		eax, tmpBITMAP.bmWidth
   mov		[edi].bmpWidth, eax
   mov		eax, tmpBITMAP.bmHeight
   mov		[edi].bmpHeight, eax
   

   ReleaseObject edi
   ret
CSprite_setBitmap ENDP
   
; --=====================================================================================--
; #METHOD:      move (VOID)
;
; #DESCRIPTION: Randomly moves this sprite object's x-y location, at a random speed.<br>
;               NOTE: The spite's location variable are only ajusted, and not redrawn..
;
; #RETURN:      Nothing..
; --=====================================================================================--
CSprite_move  PROC uses edi lpTHIS:DWORD 
   SetObject edi, CSprite
   
   invoke	RAND32, [edi].speed
   mov		ecx, [edi].speed
   shr		ecx, 1
   sub		eax, ecx
   add		[edi].xPos, eax
   
   neg		ecx
   add		ecx, [edi].widthScreen
   
   .IF		sdword ptr [edi].xPos < 0
   		mov		eax, [edi].widthScreen
   		mov		edx, [edi].bmpWidth
   		shr		edx, 1
   		sub		eax, edx
   		sub		eax, 40
   		mov		[edi].xPos, eax
   .ELSEIF sdword ptr [edi].xPos > sdword ptr ecx
   		mov		[edi].xPos, 0
   .ENDIF
   
   
   invoke	RAND32, [edi].speed
   mov		ecx, [edi].speed
   shr		ecx, 1
   sub		eax, ecx
   add		[edi].yPos, eax
   
   neg		ecx
   add		ecx, [edi].heightScreen
   
   .IF		sdword ptr [edi].yPos < 0
   		mov		eax, [edi].heightScreen
   		sub		eax, [edi].bmpHeight
   		;sub		eax, 40
   		mov		[edi].yPos, eax
   .ELSEIF sdword ptr [edi].yPos > sdword ptr ecx
   		mov		[edi].yPos, 0
   .ENDIF
 
   
   ReleaseObject edi
   ret
CSprite_move ENDP

; --=====================================================================================--
; #METHOD:      draw (VOID)
;
; #DESCRIPTION: Draws the sprite object onto the displayed DC according to its x-y location..
;
; #RETURN:      Nothing..
; --=====================================================================================--
CSprite_draw  PROC uses edi lpTHIS:DWORD 
   SetObject edi, CSprite
   
   mov		eax, [edi].bmpWidth
   shr		eax, 1
   invoke	BitBlt, [edi].drawDC, [edi].xPos, [edi].yPos,\
   				eax, [edi].bmpHeight, [edi].dcBitmap, eax, 0, SRCAND
   
   mov		eax, [edi].bmpWidth
   shr		eax, 1
   invoke	BitBlt, [edi].drawDC, [edi].xPos, [edi].yPos,\
   				eax, [edi].bmpHeight, [edi].dcBitmap, 0, 0, 	SRCINVERT 		 
   
   
   ReleaseObject edi
   ret
CSprite_draw ENDP

; --=====================================================================================--
; #METHOD:      setSpeed (dwSpeed)
;
; #DESCRIPTION: Used to adjust the sprinte objects speed of movement..
;
; #PARAM:       dwSpeed  The value to set the new speed to..
;
; #RETURN:      Nothing..
; --=====================================================================================--
CSprite_setSpeed  PROC uses edi lpTHIS:DWORD, dwSpeed:DWORD
   SetObject edi, CSprite
   
   mov		eax, dwSpeed 		;get speed parameter
   mov		[edi].speed, eax 	;put into class member
   
   
   ReleaseObject edi
   ret
CSprite_setSpeed ENDP

; --=====================================================================================--
; #METHOD:      setScreenSize (dwWidth, dwHeight)
;
; #DESCRIPTION: Used to specify the drawing area's sreen size..
;
; #PARAM:       dwWidth       The screen width (DWORD)..
; #PARAM:       dwHeight      The screen heigth (DWORD)..
;
; #RETURN:      Nothing..
; --=====================================================================================--
CSprite_setScreenSize  PROC uses edi lpTHIS:DWORD, dwWidth:DWORD, dwHeight:DWORD
   SetObject edi, CSprite

   mov eax, dwWidth
   mov ecx, dwHeight
   mov [edi].widthScreen, eax
   mov [edi].heightScreen, ecx      
      
      
      
   ReleaseObject edi
   ret
CSprite_setScreenSize  ENDP     


; --=====================================================================================--
; #METHOD:      setDrawingDC (hDC)
;
; #DESCRIPTION: Used to set the global DC that is to be displayed with the GUI.  Each
;               sprite needs this information such it can draw itself onto the same
;               DC and thus be shown..
;
; #PARAM:       hDC      A non volitile DC that this sprite can be drawn onto..
;
; #RETURN:      Nothing..
; --=====================================================================================--
CSprite_setDrawingDC  PROC uses edi lpTHIS:DWORD, hDC:DWORD
   SetObject edi, CSprite

   mov	eax, hDC
   mov  [edi].drawDC, eax
   
   ReleaseObject edi
   ret
CSprite_setDrawingDC  ENDP     
 
endif