; ------------------------------------------------------
; Sprites Animations
; Copyright (c) 2005-2016, Franck Charlet
; All rights reserved.
; ------------------------------------------------------
; buildblock RELEASE
;       CAPT %5\Release.bat
; buildblockend
; buildblock DEBUG
;       CAPT %5\Debug.bat
; buildblockend

; ------------------------------------------------------
; Constants
SCREEN_WIDTH            equ     800
SCREEN_HEIGHT           equ     600
SCREEN_BPP              equ     32

MAX_SIZE_SPRITE1        equ     64                      ; Size of the textures holding the sprites
MAX_SIZE_SPRITE2        equ     64

SPRITE1_UP              equ     0
SPRITE1_DOWN            equ     1
SPRITE1_RIGHT           equ     2
SPRITE1_LEFT            equ     3

SPRITE2_DOWN            equ     0       

; ------------------------------------------------------
; Includes
                        include ..\Common_Src\FrameWork.asm
                        include ..\Common_Src\Bmp.asm
                        include ..\Common_Src\Textures.asm
                        include ..\Common_Src\Sprites.asm
                        include ..\Common_Src\Fonts.asm

; ------------------------------------------------------
; Variables
lFont                   dd      0

Picture1                BMP     <>
Picture1_Id             dd      0

Picture2                BMP     <>
Picture2_Id             dd      0

; - Number of sprites in the group
; - Size of the texture
; - Color key
; - X
; - Y
; - Width
; - Height
Sprite1_Down_Table      dd      6
                        dd      MAX_SIZE_SPRITE1, 0ff00ffh
                        dd        0,   0, 32, 64
                        dd       34,   0, 32, 64
                        dd       68,   0, 32, 64
                        dd      102,   0, 32, 64
                        dd      136,   0, 32, 64
                        dd      170,   0, 32, 64

Sprite1_Up_Table        dd      6
                        dd      MAX_SIZE_SPRITE1, 0ff00ffh
                        dd        0,  66, 32, 64
                        dd       34,  66, 32, 64
                        dd       68,  66, 32, 64
                        dd      102,  66, 32, 64
                        dd      136,  66, 32, 64
                        dd      170,  66, 32, 64

Sprite1_Right_Table     dd      6
                        dd      MAX_SIZE_SPRITE1, 0ff00ffh
                        dd        0, 132, 32, 64
                        dd       34, 132, 32, 64
                        dd       68, 132, 32, 64
                        dd      102, 132, 32, 64
                        dd      136, 132, 32, 64
                        dd      170, 132, 32, 64

Sprite1_Left_Table      dd      6
                        dd      MAX_SIZE_SPRITE1, 0ff00ffh
                        dd        0, 198, 32, 64
                        dd       34, 198, 32, 64
                        dd       68, 198, 32, 64
                        dd      102, 198, 32, 64
                        dd      136, 198, 32, 64
                        dd      170, 198, 32, 64

; ----
Sprite2_Down_Table      dd      3
                        dd      MAX_SIZE_SPRITE2, 0ff00ffh
                        dd        0,  0, 38, 40
                        dd       38,  0, 38, 40
                        dd       76,  0, 38, 40
                        
; - Number of entries
; - Index of the still position
; - Min position
; - Max position
; - Type of animation (SPRITE_ANIM_FORWARD/SPRITE_ANIM_PINGPONG/SPRITE_ANIM_ONCE)
; - Address of the group to use
; - Address of the picture to use
Sprite1_Anim_Datas      dd      4
                        dd      0, 1, 5, SPRITE_ANIM_PINGPONG, offset Sprite1_Up_Table, offset Picture1
                        dd      0, 1, 5, SPRITE_ANIM_PINGPONG, offset Sprite1_Down_Table, offset Picture1
                        dd      0, 1, 5, SPRITE_ANIM_PINGPONG, offset Sprite1_Right_Table, offset Picture1
                        dd      0, 1, 5, SPRITE_ANIM_PINGPONG, offset Sprite1_Left_Table, offset Picture1

Sprite2_Anim_Datas      dd      1
                        dd      0, 0, 2, SPRITE_ANIM_PINGPONG, offset Sprite2_Down_Table, offset Picture2

hSprite1                dd      0
hSprite2                dd      0

Pos_Sprite_X            real4   0.0
Pos_Sprite_Y            real4   0.0

Sprite1_Speed           real4   100.0
mSprite1_Speed          real4   -100.0
Sprite1_Walk_speed      real4   15.0
Sprite2_Walk_speed      real4   5.0

; ------------------------------------------------------
; Name: Initialize()
; Desc: Perform the various initializations
Initialize              proc

                        invoke  glClearDepth, CDBL(1.0)
                        invoke  glHint, GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST
                        invoke  glClearColor, CFLT(0.2), CFLT(0.25), CFLT(0.3), CFLT(1.0)
                        invoke  glEnable, GL_NORMALIZE
                        invoke  glEnable, GL_CULL_FACE

                        invoke  Load_BMP, CSTR("..\..\Media\sprite3.bmp"), addr Picture1, -1
                        .if     eax == FALSE
                                invoke  Set_Error_Msg, CSTR("Can't load texture file")
                                mov     eax, FALSE
                                ret
                        .endif
                        
                        invoke  Load_BMP, CSTR("..\..\Media\sprite4.bmp"), addr Picture2, -1
                        .if     eax == FALSE
                                invoke  Set_Error_Msg, CSTR("Can't load texture file")
                                mov     eax, FALSE
                                ret
                        .endif
                        
                        invoke  Init_Textures_Context

                        invoke  Create_Anim_Sprite, addr Sprite1_Anim_Datas, SPRITE1_DOWN
                        mov     hSprite1, eax
                        .if     eax == NULL
                                invoke  Set_Error_Msg, CSTR("Can't create sprite")
                                mov     eax, FALSE
                                ret
                        .endif

                        fld     INT2FLT(50)
                        fstp    Pos_Sprite_X
                        fld     INT2FLT(50)
                        fstp    Pos_Sprite_Y

                        invoke  Create_Anim_Sprite, addr Sprite2_Anim_Datas, SPRITE2_DOWN
                        mov     hSprite2, eax
                        .if     eax == NULL
                                invoke  Set_Error_Msg, CSTR("Can't create sprite")
                                mov     eax, FALSE
                                ret
                        .endif

                        ; Create the fonts
                        invoke  Create_Font_Bitmap, CSTR("Courier New"), 12, FW_NORMAL
                        mov     lFont, eax
                        .if     eax == 0
                                invoke  Set_Error_Msg, CSTR("Can't create font")
                                xor     eax, eax
                                ret
                        .endif

                        mov     eax, TRUE
                        ret
Initialize              endp

; ------------------------------------------------------
; Name: Deinitialize()
; Desc: Free allocated resources
Deinitialize            proc
                        invoke  Destroy_Font, lFont

                        invoke  Destroy_Anim_Sprite, hSprite2
                        invoke  Destroy_Anim_Sprite, hSprite1

                        invoke  Unload_BMP, addr Picture1
                        invoke  Unload_BMP, addr Picture2
                        ret
Deinitialize            endp

; ------------------------------------------------------
; Name: Update()
; Desc: Update the scene
Update                  proc    FrameRate:real4

                        ; Update scene here
                        invoke  DInput_Get_Key, DIK_LEFT
                        test    eax, eax
                        jz      Sprite_Left
                        invoke  Sprite_Move, addr Pos_Sprite_X, mSprite1_Speed, FrameRate, 0, SCREEN_WIDTH - 32
                        mov     ecx, SPRITE1_LEFT

Sprite_Left:            invoke  DInput_Get_Key, DIK_RIGHT
                        test    eax, eax
                        jz      Sprite_Right
                        invoke  Sprite_Move, addr Pos_Sprite_X, Sprite1_Speed, FrameRate, 0, SCREEN_WIDTH - 32
                        mov     ecx, SPRITE1_RIGHT

Sprite_Right:           invoke  DInput_Get_Key, DIK_UP
                        test    eax, eax
                        jz      Sprite_Up
                        invoke  Sprite_Move, addr Pos_Sprite_Y, mSprite1_Speed, FrameRate, 0, SCREEN_HEIGHT - 64
                        mov     ecx, SPRITE1_UP
Sprite_Up:              
                        invoke  DInput_Get_Key, DIK_DOWN
                        test    eax, eax
                        jz      No_Move
                        invoke  Sprite_Move, addr Pos_Sprite_Y, Sprite1_Speed, FrameRate, 0, SCREEN_HEIGHT - 64
                        mov     ecx, SPRITE1_DOWN
No_Move:
                        ; No keys pressed ?
                        invoke  DInput_Get_Key, DIK_LEFT
                        test    eax, eax
                        jnz     No_Key
                        invoke  DInput_Get_Key, DIK_RIGHT
                        test    eax, eax
                        jnz     No_Key
                        invoke  DInput_Get_Key, DIK_UP
                        test    eax, eax
                        jnz     No_Key
                        invoke  DInput_Get_Key, DIK_DOWN
                        test    eax, eax
                        jnz     No_Key
                        
                        ; Set in still position according to the (last set) current group
                        invoke  Stop_Anim_Sprite, hSprite1
                        jmp     No_Sprite_Move
No_Key:                 ; Set the group of animation
                        invoke  Set_Anim_Sprite_Group, hSprite1, ecx
                        ; Animate it
                        invoke  Animate_Sprite, hSprite1, Sprite1_Walk_speed, FrameRate
No_Sprite_Move:
                        ; Modify the position of the sprite
                        invoke  Set_Anim_Sprite_Pos, hSprite1, FLT2INT(Pos_Sprite_X), FLT2INT(Pos_Sprite_Y)

                        ; Second sprite just walks
                        invoke  Animate_Sprite, hSprite2, Sprite2_Walk_speed, FrameRate

                        invoke  DInput_Get_Key, DIK_ESCAPE
                        test    eax, eax
                        jz      Esc_Pressed
                        invoke  Terminate_Application
Esc_Pressed:            ret
Update                  endp

; ------------------------------------------------------
; Name: Draw()
; Desc: Draw the scene
Draw                    proc
                        local   Collide:dword

                        invoke  glClear, GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT

                        ; Draw scene here
                        invoke  Enter_2D_Mode, INT2FLT(SCREEN_WIDTH), INT2FLT(SCREEN_HEIGHT)
                                invoke  glEnable, GL_BLEND
                                invoke  glBlendFunc, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA
                                invoke  glColor3f, CFLT(1.0), CFLT(1.0), CFLT(1.0)
                                
                                invoke  Display_Anim_Sprite, hSprite1

                                invoke  Set_Anim_Sprite_Pos, hSprite2, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2
                                invoke  Display_Anim_Sprite, hSprite2

                                invoke  Get_Current_Anim_Sprite, hSprite1
                                push    eax
                                invoke  Get_Current_Anim_Sprite, hSprite2
                                pop     ebx
                                invoke  Check_Collision, eax, ebx
                                .if     eax == TRUE
                                        invoke  glTranslatef, CFLT(0.0), CFLT(0.0), CFLT(-1.0)
                                        invoke  glColor4f, CFLT(1.0), CFLT(0.4), CFLT(0.2), CFLT(0.0)
                                        invoke  Display_2D_Text, INT2FLT(10), INT2FLT(502), lFont, CSTR("*COLLISION*"), 11
                                .endif

                                invoke  glTranslatef, CFLT(0.0), CFLT(0.0), CFLT(-1.0)
                                invoke  glColor4f, CFLT(1.0), CFLT(0.8), CFLT(0.4), CFLT(0.0)
                                invoke  Display_2D_Text, INT2FLT(10), INT2FLT(532), lFont, CSTR("Use arrows keys to move sprite"), 30

                                invoke  glDisable, GL_BLEND
                        invoke  Leave_2d_Mode
                        ret
Draw                    endp


end start
