; ------------------------------------------------------
; Move origin
; 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

NBR_CUBES               equ     10

; ------------------------------------------------------
; Includes
                        include ..\Common_Src\FrameWork.asm
                        include ..\Common_Src\Misc.asm

; ------------------------------------------------------
; Functions
Display_Cube            proto

; ------------------------------------------------------
; Variables
RotX                    real4   NBR_CUBES dup (0.0)
RotY                    real4   NBR_CUBES dup (0.0)
RotZ                    real4   NBR_CUBES dup (0.0)
RotXSpeed               real4   NBR_CUBES dup (0.0)
RotYSpeed               real4   NBR_CUBES dup (0.0)
RotZSpeed               real4   NBR_CUBES dup (0.0)
PosX                    dd      NBR_CUBES dup (0.0)
PosY                    dd      NBR_CUBES dup (0.0)
PosXSpeed               real4   NBR_CUBES dup (0.0)
PosYSpeed               real4   NBR_CUBES dup (0.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, 0, 0, 0, CFLT(1.0)
                        invoke  glEnable, GL_NORMALIZE
                        invoke  glEnable, GL_CULL_FACE

                        invoke  GetTickCount
                        invoke  Init_Random_Seed, eax

                        xor     ebx, ebx
                        .while  ebx < NBR_CUBES
                                invoke  Get_Random_Number, CFLT(0.0), CFLT(360.0)
                                mov     [RotX + ebx * 4], eax
                                invoke  Get_Random_Number, CFLT(0.0), CFLT(360.0)
                                mov     [RotY + ebx * 4], eax
                                invoke  Get_Random_Number, CFLT(0.0), CFLT(360.0)
                                mov     [RotZ + ebx * 4], eax

                                invoke  Get_Random_Number, CFLT(-50.0), CFLT(50.0)
                                mov     [RotXSpeed + ebx * 4], eax
                                invoke  Get_Random_Number, CFLT(-50.0), CFLT(50.0)
                                mov     [RotYSpeed + ebx * 4], eax
                                invoke  Get_Random_Number, CFLT(-50.0), CFLT(50.0)
                                mov     [RotZSpeed + ebx * 4], eax

                                push    ebx
                                fild    dword ptr [esp]
                                pop     eax
                                fmul    CFLT(0.1)
                                fsin
                                fmul    CFLT(5.0)
                                fstp    dword ptr [PosXSpeed + ebx * 4]

                                push    ebx
                                fild    dword ptr [esp]
                                pop     eax
                                fmul    CFLT(0.1)
                                fsin
                                fmul    CFLT(5.0)
                                fstp    dword ptr [PosYSpeed + ebx * 4]

                                inc     ebx
                        .endw
                        mov     eax, TRUE
                        ret
Initialize              endp

; ------------------------------------------------------
; Name: Deinitialize()
; Desc: Free allocated resources
Deinitialize            proc

                        ret
Deinitialize            endp

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

                        ; Update scene here
                        xor     ebx, ebx
                        .while  ebx < NBR_CUBES
                                fld     [RotXSpeed + ebx * 4]
                                fmul    FrameRate
                                fadd    [RotX + ebx * 4]
                                fstp    [RotX + ebx * 4]
        
                                fld     [RotYSpeed + ebx * 4]
                                fmul    FrameRate
                                fadd    [RotY + ebx * 4]
                                fstp    [RotY + ebx * 4]
        
                                fld     [RotZSpeed + ebx * 4]
                                fmul    FrameRate
                                fadd    [RotZ + ebx * 4]
                                fstp    [RotZ + ebx * 4]

                                fld     CFLT(1.5)
                                fmul    FrameRate
                                fadd    [PosXSpeed + ebx * 4]
                                fst     [PosXSpeed + ebx * 4]
                                fsin
                                fmul    INT2FLT(SCREEN_WIDTH / 3)
                                fistp   [PosX + ebx * 4]

                                fld     CFLT(2.0)
                                fmul    FrameRate
                                fadd    [PosYSpeed + ebx * 4]
                                fst     [PosYSpeed + ebx * 4]
                                fsin
                                fmul    INT2FLT(SCREEN_HEIGHT / 3)
                                fistp   [PosY + ebx * 4]

                                inc     ebx
                        .endw

                        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
                        invoke  glClear, GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT

                        ; Draw scene here
                        invoke  glPushMatrix
                                invoke  glTranslatef, CFLT(0.0), CFLT(0.0), CFLT(-12.0)
                                xor     ebx, ebx
                                .while  ebx < NBR_CUBES
                                        invoke  glViewport, [PosX + ebx * 4], [PosY + ebx * 4], SCREEN_WIDTH, SCREEN_HEIGHT
                                        invoke  glRotatef, RotX, CFLT(0.0), CFLT(1.0), CFLT(0.0)
                                        invoke  glRotatef, RotY, CFLT(1.0), CFLT(0.0), CFLT(0.0)
                                        invoke  glRotatef, RotZ, CFLT(0.0), CFLT(0.0), CFLT(1.0)
                                        invoke  Display_Cube
                                        inc     ebx
                                .endw
                        invoke  glPopMatrix
                        invoke  glViewport, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT

                        ret
Draw                    endp

; ------------------------------------------------------
; Name: Display_Cube()
; Desc: Display a simple cube
Display_Cube            proc
                        invoke  glBegin, GL_QUADS
                                invoke  glColor3f, CFLT(0.0), CFLT(0.2), CFLT(0.3)
                                invoke  glVertex3f, CFLT(1.0), CFLT(1.0), CFLT(-1.0)
                                invoke  glVertex3f,CFLT(-1.0), CFLT(1.0), CFLT(-1.0)
                                invoke  glVertex3f,CFLT(-1.0), CFLT(1.0), CFLT(1.0)
                                invoke  glVertex3f, CFLT(1.0), CFLT(1.0), CFLT(1.0)

                                invoke  glVertex3f, CFLT(1.0),CFLT(-1.0), CFLT(1.0)
                                invoke  glVertex3f,CFLT(-1.0),CFLT(-1.0), CFLT(1.0)
                                invoke  glVertex3f,CFLT(-1.0),CFLT(-1.0),CFLT(-1.0)
                                invoke  glVertex3f, CFLT(1.0),CFLT(-1.0),CFLT(-1.0)

                                invoke  glColor3f, CFLT(0.2), CFLT(0.4), CFLT(0.5)
                                invoke  glVertex3f, CFLT(1.0), CFLT(1.0), CFLT(1.0)
                                invoke  glVertex3f,CFLT(-1.0), CFLT(1.0), CFLT(1.0)
                                invoke  glVertex3f,CFLT(-1.0),CFLT(-1.0), CFLT(1.0)
                                invoke  glVertex3f, CFLT(1.0),CFLT(-1.0), CFLT(1.0)

                                invoke  glVertex3f, CFLT(1.0),CFLT(-1.0),CFLT(-1.0)
                                invoke  glVertex3f,CFLT(-1.0),CFLT(-1.0),CFLT(-1.0)
                                invoke  glVertex3f,CFLT(-1.0), CFLT(1.0),CFLT(-1.0)
                                invoke  glVertex3f, CFLT(1.0), CFLT(1.0),CFLT(-1.0)

                                invoke  glColor3f, CFLT(0.4), CFLT(0.6), CFLT(0.7)
                                invoke  glVertex3f, CFLT(-1.0), CFLT(1.0), CFLT(1.0)
                                invoke  glVertex3f, CFLT(-1.0), CFLT(1.0),CFLT(-1.0)
                                invoke  glVertex3f, CFLT(-1.0),CFLT(-1.0),CFLT(-1.0)
                                invoke  glVertex3f, CFLT(-1.0),CFLT(-1.0), CFLT(1.0)

                                invoke  glVertex3f, CFLT(1.0), CFLT(1.0),CFLT(-1.0)
                                invoke  glVertex3f, CFLT(1.0),CFLT(1.0), CFLT(1.0)
                                invoke  glVertex3f, CFLT(1.0),CFLT(-1.0), CFLT(1.0)
                                invoke  glVertex3f, CFLT(1.0),CFLT(-1.0),CFLT(-1.0)
                        invoke  glEnd
                        ret
Display_Cube            endp

end start
