ORG 100H
USE16

include 'CONSTS.ASM'
include 'OBJTYPES.ASM'

; Unholy hack to reduce the amount of memory we get for the program because DOS is a big dum-dum and allocates the entire
; free memory space, despite the fact that the program can only be up to 64K in size
MOV BX, 0x800 ; 32K (in paragraphs) NOTE: If this is not enough, the program will eventually crash when it gets bigger
              ; Take great care to synchronize that with the .COM executable size!!!!!!!!!!!!!!
MOV AH, 4Ah   ; MODIFY MEMORY BLOCK
INT 21h       ; Me when Interrupt 21H (Disk Operating System Kernel Interrupt) [Real]
JC ERROR_GeneralDOSError ; Balls

MOV DX, Filename
CALL DOS_OpenReadonly
JC ERROR_FileError ; Carry set means an error
; If the branch was not taken, AX has the file handle.
; We just store it in RAM for later since it's going to be useful for pretty much the entire runtime of the program
MOV [GameFileHandle], AX

; 1 Para = 16B

MOV BX, 1024 ; 16K
CALL DOS_AllocateMemory ; Allocate scratch RAM
JC ERROR_GeneralDOSError
MOV [RAM_Scratch], AX

MOV BX, 256 ; 4K again
CALL DOS_AllocateMemory ; Allocate persistent RAM
JC ERROR_GeneralDOSError
MOV [RAM_Persistent], AX

MOV BX, 4096 ; Full 64K segment
CALL DOS_AllocateMemory ; Allocate object RAM
JC ERROR_GeneralDOSError
MOV [RAM_Object], AX

MOV BX, 4096 ; Full 64K segment
CALL DOS_AllocateMemory ; Allocate the frame buffer
JC ERROR_GeneralDOSError
MOV [RAM_Framebuffer], AX

MOV ES, [RAM_Scratch]

; Allocated segment in ES

MOV BX, [GameFileHandle] ; File handle
MOV CX, 4                ; Number of bytes to read
MOV DX, 0                ; Offset into the buffer
CALL DOS_ReadFileIntoES  ; Does the PUSH DS POP DS shenanigans
JC ERROR_GeneralDOSError       ; If CF then error

; Does not mess with BX, and we still need BX for the handle.
CALL BASE_VerifyGameFileMagic

MOV CX, 2
XOR DX, DX
CALL DOS_ReadFileIntoES ; Read a single byte indicating the version, and then one about how much memory to allocate, 0 is 16K, 1 is 32K, 2 is 64K
JC ERROR_GeneralDOSError

; Check the file version. Valid values are 1 and... well, just 1.
A_CheckVer:
    MOV AL, [ES:0]
    CMP AL, 1
    JE .goodver
    MOV DX, STR_ErrInvalidVersion
    CALL DOS_PrintString
    JMP Exit
    .goodver:

; Read how much memory we want to allocate (0, 1, or 2 for 16, 32, and 64K respectively), allocate it, and store the segment
MOV AL, [ES:1]
CALL BASE_AllocFileMem
MOV [RAM_OpFile], AX

MOV BX, [GameFileHandle] ; We probably lost BX long ago
MOV CX, 0xFFFF           ; Read everything to end
MOV ES, [RAM_OpFile]     ; Store the entire file in its alloc'd memory
XOR DX, DX               ; Starting at offset 0 in ES:DX
CALL DOS_ReadFileIntoES
JC ERROR_GeneralDOSError

MOV [FilePtr], 0 ; Reset the file pointer to 0, this is our "program counter"

MOV CX, 3600 ; Object count, 3600 JUST fits, any more and we're out of memory
MOV ES, [RAM_Object]
CALL TABLE_InitializeBitmap

CALL BIOS_SetVideoMode13H

MOV DX, MyBmpFn
CALL BASE_AllocLoadFile ; ES:0 = Loaded file
MOV [BitmapSeg], ES

MOV DX, MyBmpFn1
CALL BASE_AllocLoadFile ; ES:0 = Loaded file
MOV [BitmapSeg1], ES


MOV ES, [RAM_Object]

MOV CX, 1
CALL TABLE_ObjAlloc

; AX Has obj h
CALL TABLE_ObjFree

MOV CX, 1
CALL TABLE_ObjAlloc
PUSH AX
MOV CX, 1
CALL TABLE_ObjAlloc
CALL TABLE_GetObjectAddr
MOV WORD [ES:DI], 0xEFBE

;POP AX
;MOV SI, TestStr
;CALL OBJ_STRING_FillString

;JMP $

;TestStr db 'According to all known laws of aviation, there is no way a bee should be able to fly.', 0

;JMP $

NewTestDrwLoop:
    MOV AL, 0x01 ; Blue
    CALL BASE_ClearScreen
    
    MOV ES, [BitmapSeg]
    XOR SI, SI
    MOV CX, [XPos] ; X
    MOV DX, [YPos] ; Y
    CALL BASE_DrawBitmapFromFile
    ADD [XPos], 1

    ;MOV ES, [BitmapSeg1]
    ;XOR SI, SI
    ;MOV CX, [XPos1] ; X
    ;MOV DX, [YPos1] ; Y
    ;CALL BASE_DrawBitmapFromFile
    ;SUB [XPos1], 1

    CALL BASE_Present
    JMP NewTestDrwLoop

BitmapSeg dw ?
BitmapSeg1 dw ?
MyBmpFn db 'WIDE.BMA', 0x00
MyBmpFn1 db 'BMPMOON.BMA', 0x00
XPos dw 0
YPos dw 0
XPos1 dw 0
YPos1 dw 0

JMP $
CALL BIOS_SetVideoMode03H ; If Exit is called, the mode is likely already 03H, and we don't want to clear the framebuffer, which this does
Exit:

    MOV BX, [GameFileHandle]
    CALL DOS_CloseFile
    JC FileCloseError

    ; Free all memory blocks
    ; We use CX to see whether the carry has been set within one or more calls, since we want to continue even if there was an error
    ; So we just use ADC CX, 0 to add the carry to CX, if CF = 0, CX = 0
    CLC
    XOR CX, CX

    MOV ES, [RAM_Scratch]
    CALL DOS_FreeMemory
    ADC CX, 0

    MOV ES, [RAM_Persistent]
    CALL DOS_FreeMemory
    ADC CX, 0

    MOV ES, [RAM_Object]
    CALL DOS_FreeMemory
    ADC CX, 0

    MOV ES, [RAM_OpFile]
    CALL DOS_FreeMemory
    ADC CX, 0

    CMP CX, 0
    JE .noerror

    MOV DX, STR_ErrFree
    CALL DOS_PrintString
    .noerror:

    MOV DX, STR_Bye
    CALL DOS_PrintString

    ; CALL BIOS_SetVideoMode03H ; Fix the video mode
    INT 20H ; ENDOF Program

include 'ERRORS.ASM'
include 'DOSFUNC.ASM'
include 'BIOSFUNC.ASM'
include 'BASEFUNC.ASM'
include 'HEAPUTIL.ASM'
include 'OBJUTILS.ASM'
include 'STATVAR.ASM'