spacegamex64/space.s
2025-10-03 19:12:59 +08:00

4435 lines
103 KiB
ArmAsm

;SPACE GAME FOR x64 SYSTEMS
.DATA
PAUSEGAME DQ 00H
UPSCALE_MODE DQ 00H ;0 FOR MULTI-CORE HARDWARE UPSCALED IMAGE OUTPUT, 1 FOR NO UPSCALING
SHOW_HITBOX DQ 00H ;1 TO SHOW HIT BOXES
imageHandle DQ ? ;pointer to image handle
systemTable DQ ? ;pointer to system table
helloMessage DW 'S', 'T', 'A', 'R', 'T', 'I', 'N', 'G', ' ', 'U', 'E', 'F', 'I', ' ', 'P', 'R', 'G', 13, 10
DW 'W', 'R', 'I', 'T', 'T', 'E', 'N', ' ', 'B', 'Y', ' '
DW 'I', 'N', 'K', 'B', 'O', 'X', 13, 10, 0
endMessage DW 'O', 'K', 13, 10, 0
monthMessage DW '-', '>', ' ', 'M', 13, 10, 0
fpsMessage DW 'F', 'P', 'S', ':', ' ', 0
timeCapMessage DW 'N', 'A', 'N', 'O', ' ', 'O', 'U', 'T', ':', ' '
timeCapVal DW 0, 0
cyclesMessage DW 'C', 'A', 'L', 'C', 'U', 'L', 'A', 'T', 'I', 'N', 'G'
DW ' ', 'C', 'P', 'U', ' ', 'S', 'P', 'E', 'E', 'D', 0
controlMessage DW 'U', 'D', 'L', 'R', 'F', 13, 10, 0
PRESSEDLEFTMessage DW 'A', ' ', 'P', 'R', 'E', 'S', 'S', 'E', 'D', ':', ' ', 0
videoMessage1 DW 'M', 'A', 'X', ' ', 'V', 'I', 'D', 'E', 'O', ' ', 'M', 'O', 'D', 'E', 'S', ':', ' ', 0
videoMessage2 DW 'M', ':', ' ', 0
videoMessage3 DW 'F', 'O', 'R', 'M', 'A', 'T', ':', ' ', 0
videoMessage4 DW 'V', 'I', 'D', 'E', 'O', ' ', 'M', 'O', 'D', 'E', ' ', 'S', 'E', 'L', ':', ' ', 0
mouseMessage DW 'M', 'O', 'U', 'S', 'E', ':', ' ', 10, 13, 0
columnMessage DW 'C', 'O', 'L', 'U', 'M', 'N', ' ', 'C', 'O', 'U', 'N', 'T', ':', ' ', 10, 13, 0
returnLineMes DW 0DH, 0
spaceMessage DW ' ', 0
xMessage DW 'x', 0
bMessage DW 64 DUP (?)
BUFFER DB 64 DUP (?)
modeInfoBuffer DQ ?
sizeOfInfo DQ ?
curMode DQ ?
VIDEOX DD ?
VIDEOY DD ?
selectedMode DQ ?
TITLECARD DW 0612H, 060FH, 0600H, 0602H, 0604H, 05EDH, 0606H, 0600H, 060CH, 0604H
DW 05EDH, 0605H, 060EH, 0611H, 05EDH, 0617H, 0620H, 061EH
;KEY RELATED
index DQ ?
key DQ ?
;EFI_INPUT_KEY
WkeyDescriptor DW 0, 'W', 00H, 00H ;SCANCODE, UNICODE CHAR, KeyShiftState + KeyToggleState
WkeyNotifyHandle DQ ?
littleWkeyDescriptor DW 0, 'w', 00H, 00H ;SCANCODE, UNICODE CHAR, KeyShiftState + KeyToggleState
littleWkeyNotifyHandle DQ ?
upkeyDescriptor DW 01H, 0, 00H, 00H ;SCANCODE, UNICODE CHAR, KeyShiftState + KeyToggleState
upkeyNotifyHandle DQ ?
SkeyDescriptor DW 0, 'S', 00H, 00H ;SCANCODE, UNICODE CHAR, KeyShiftState + KeyToggleState
SkeyNotifyHandle DQ ?
littleSkeyDescriptor DW 0, 's', 00H, 00H ;SCANCODE, UNICODE CHAR, KeyShiftState + KeyToggleState
littleSkeyNotifyHandle DQ ?
downkeyDescriptor DW 02H, 0, 00H, 00H ;SCANCODE, UNICODE CHAR, KeyShiftState + KeyToggleState
downkeyNotifyHandle DQ ?
AkeyDescriptor DW 0, 'A', 00H, 00H ;SCANCODE, UNICODE CHAR, KeyShiftState + KeyToggleState
AkeyNotifyHandle DQ ?
littleAkeyDescriptor DW 0, 'a', 00H, 00H ;SCANCODE, UNICODE CHAR, KeyShiftState + KeyToggleState
littleAkeyNotifyHandle DQ ?
leftkeyDescriptor DW 04H, 0, 00H, 00H ;SCANCODE, UNICODE CHAR, KeyShiftState + KeyToggleState
leftkeyNotifyHandle DQ ?
DkeyDescriptor DW 0, 'D', 00H, 00H ;SCANCODE, UNICODE CHAR, KeyShiftState + KeyToggleState
DkeyNotifyHandle DQ ?
littleDkeyDescriptor DW 0, 'd', 00H, 00H ;SCANCODE, UNICODE CHAR, KeyShiftState + KeyToggleState
littleDkeyNotifyHandle DQ ?
rightkeyDescriptor DW 03H, 0, 00H, 00H ;SCANCODE, UNICODE CHAR, KeyShiftState + KeyToggleState
rightkeyNotifyHandle DQ ?
ZkeyDescriptor DW 0, 'Z', 00H, 00H ;SCANCODE, UNICODE CHAR, KeyShiftState + KeyToggleState
ZkeyNotifyHandle DQ ?
littleZkeyDescriptor DW 0, 'z', 00H, 00H ;SCANCODE, UNICODE CHAR, KeyShiftState + KeyToggleState
littleZkeyNotifyHandle DQ ?
QkeyDescriptor DW 0, '?', 00H, 00H ;SCANCODE, UNICODE CHAR, KeyShiftState + KeyToggleState
QkeyNotifyHandle DQ ?
littleQkeyDescriptor DW 0, '/', 00H, 00H ;SCANCODE, UNICODE CHAR, KeyShiftState + KeyToggleState
littleQkeyNotifyHandle DQ ?
spacekeyDescriptor DW 00H, ' ', 00H, 00H ;SCANCODE, UNICODE CHAR, KeyShiftState + KeyToggleState
spacekeyNotifyHandle DQ ?
PRESSEDLEFT DB 0
KEYTIMERLEFT DB 0
PRESSEDRIGHT DB 0
KEYTIMERRIGHT DB 0
PRESSEDUP DB 0
KEYTIMERUP DB 0
PRESSEDDOWN DB 0
KEYTIMERDOWN DB 0
PRESSEDFIRE DB 0
KEYTIMERFIRE DB 0
POINTERSTATE DD 0, 0, 0, 0, 0, 0 ;X, Y, Z, AND BUTTONS
POINTERLOC DQ 600, 600
POINTERBUTTON DQ 0, 0
POINTERLEFT DB 0
POINTERRIGHT DB 0
POINTERUP DB 0
POINTERDOWN DB 0
POINTERFIRE DB 0
COMBLEFT DB 0
COMBRIGHT DB 0
COMBUP DB 0
COMBDOWN DB 0
COMBFIRE DB 0
;GRAPHICS:
SPRITEVERSION DQ 0
TILEMAP0 DW 0400H DUP (?)
TILEMAP1 DW 0400H DUP (?)
TM0XOFFSET DB 0
TM0YOFFSET DB 0
TM1XOFFSET DB 0
TM1YOFFSET DB 0
OUTPUTFBUFFER DD 010000H DUP (?) ;262KB 256x256px FRAME BUFFER
OUTPUTFBUFFER_2 DD 010000H DUP (?) ;262KB 64x256px SPARE FRAME BUFFER FOR MEMORY SPILLAGE
UPSCALEDBUFFER DQ ? ;4MB UPSCALED 1024x1024px FRAME BUFFER (POINTER)
UPSCALEDROW DB 256 DUP (?)
UPSCALEDCOUNT DQ 0
FAILEDCPULIST DQ ?
SUCESSCPUS DQ ?
NUMBERAP DQ ?
ENABLEDAP DQ ?
SPRITEOBJ STRUCT
MODE DW ? ;0 IF INACTIVE
SPRITETILENUM DW ?
X DW ?
Y DW ?
SPRITEOBJ ENDS
SPRITES SPRITEOBJ 080H DUP(<>) ;128 SPRITE OBJECTS
ENEMYOBJ STRUCT
MODE DW ? ;0 IF INACTIVE
SPRITE DW ?
X DW ?
Y DW ?
HITBOXX DB ? ;X & Y ARE OFFSET FROM TOP LEFT CORNER
HITBOXY DB ?
HITBOXW DB ?
HITBOXH DB ?
ALT DB ? ;ALTITUDE
TIMER DB ? ;INTERNAL TIMER FOR SPRITE ANIMATIONS
ENEMYOBJ ENDS
ENEMYOBJSIZE = 0EH
ENEMY ENEMYOBJ 040H DUP(<>) ;64 ENEMIES
NUMBEROFENEMY EQU 040
BOLTOBJ STRUCT
MODE DW ? ;0 IF INACTIVE
SPRITE DW ?
X DW ?
Y DW ?
HITBOXX DB ? ;X & Y ARE OFFSET FROM TOP LEFT CORNER
HITBOXY DB ?
HITBOXW DB ?
HITBOXH DB ?
ALT DB ? ;ALTITUDE
TIMER DB ? ;INTERNAL TIMER FOR SPRITE ANIMATIONS
BOLTOBJ ENDS
BOLTOBJSIZE = 0EH
BOLTS BOLTOBJ 08H DUP(<>) ;8 BOLTS
BOLTCOOLDOWN DQ 0
BOLTCOOLDOWNFRAMES EQU 24
COLORRED DD 000FF0000H
COLORORANGE DD 000FF8000H
COLORYELLOW DD 000FFFF00H
COLORGREENN DD 00039FF14H
COLORBLUE DD 0000000FFH
COLORGREEN DD 00000FF00H
COLORBLACK DD 000000000H
;GAME VARIABLES
TITLEON DQ 1 ;START WITH TITLE ON
STAGE DQ 0
SHIPX DQ 0
SHIPY DQ 0
SHIPTILTY DQ 0
SHIPHITBOX DB 0, 0, 0, 0 ;X, Y, W, H
SHIPALT DB 0
SHIPFUEL DB 0
SCROLLTIMER DQ 0
SCROLLX DQ 0
SCROLLY DQ 0
LASTSCROLLX DQ 0
LASTSCROOLY DQ 0
GAMEMAPOFFSET DQ 258H
COLUMNTICK DQ 0
HIDESHADOW DQ 0
HIT DQ 0
NOFUEL DQ 0
BONUSFUEL EQU 020H ;AMOUNT OF BONUS FUEL FROM HITTING TANKS
PAUSESCROLL DQ 0
EXPLODETIMER DQ 0
EXPLODEDELAYTIMER DQ 0
RESET DQ 0
WINTIMER DQ 0
;FRAMERULES:
MOVEMENTFRAMERULE EQU 2
MOVEMENTFRAMERULEC DQ 0
SCROLLFRAMERULE EQU 3 ;HOW FAST THE GAME BACKGROUND SCROLLS
SCROLLFRAMERULEC DQ 0
FUELFRAMERULE EQU 20 ;HOW QUICK FUEL IS DEPLETED
FUELFRAMERULEC DQ 0
ELOGICFRAMERULE EQU 2
ELOGICFRAMERULEC DQ 0
EXPLODEFRAMERULE EQU 8
EXPLODEFRAMERULEC DQ 0
BOSSMOVEFRAMERULE EQU 4
BOSSMOVEFRAMERULEC DQ 0
TITLECOUNTER DQ 0
TITLESWAPCOUNTER DQ 0
;GAME CONSTANTS
SHIPORGINX EQU 12
SHIPORGINY EQU 70
SHIPMAXX EQU 112
SHIPMAXY EQU 112
;TIME RELATED
time DQ 4 DUP(?)
;UINT16 Year;
;UINT8 Month;
;UINT8 Day;
;UINT8 Hour;
;UINT8 Minute;
;UINT8 Second;
;UINT8 Pad1;
;UINT32 Nanosecond;
;INT16 TimeZone;
;UINT8 Daylight;
;UINT8 PAD2;
EFI_TIME_CAPABILITIES DQ ?, ? ;9 bytes used
SECONDS DB ?
TSC_PS DQ ?
TSC_PS2 DQ ?
CYCLESPERFRAME DQ ?
NEXTFRAME@ DQ ?
FRAMERATE DQ ?
FRAMECOUNT DQ ?
S1 DQ ?
S2 DQ ?
;FRAME COUNTERS
MOVEMENTFC DB ?
;PROTOCOL Globally Unique IDs:
TextInputExGUID DD 0DD9E7534H ;Data1
DW 07762H ;Data2
DW 04698H ;Data3
DB 08CH, 014H, 0F5H, 085H, 017H, 0A6H, 025H, 0AAH ;Data4
GraphicsOutputGUID DD 09042A9DEH ;Data1
DW 23DCH ;Data2
DW 4A38H ;Data3
DB 096H, 0FBH, 07AH, 0DEH, 0D0H, 080H, 051H, 06AH ;Data4
MPServicesGUID DD 03FDDA605H ;Data1
DW 0A76EH ;Data2
DW 04F46H ;Data3
DB 0ADH, 029H, 012H, 0F4H, 053H, 01BH, 03DH, 008H ;Data4
ABSOLUTEPOINTERGUID DD 08D59D32BH ;Data1
DW 0C655H ;Data2
DW 04AE9H ;Data3
DB 09BH, 015H, 0F2H, 059H, 004H, 099H, 02AH, 043H ;Data4
SIMPLEPOINTERGUID DD 031878C87H ;Data1
DW 00B75H ;Data2
DW 011D5H ;Data3
DB 09AH, 04FH, 000H, 090H, 027H, 03FH, 0C1H, 04DH ;Data4
INCLUDE graphics/loadImg.inc
INCLUDE graphics/loadImgShip.inc
INCLUDE graphics/bgTiles.inc
INCLUDE graphics/tilemap.inc
INCLUDE graphics/spriteTiles.inc
INCLUDE graphics/spriteTiles2.inc
;FUNCTION POINTERS
conIn DQ ?
conOut DQ ?
RuntimeServices DQ ?
BootServices DQ ?
AllocatePages DQ ?
OutputString DQ ?
WaitForEvent DQ ?
ReadKeyStroke DQ ?
WaitForKey DQ ?
SetCursorPosition DQ ?
LocateProtocol DQ ?
TextInputEX DQ ?
RegisterKeyNotify DQ ?
MPServices DQ ?
StartupThisAP DQ ?
StartupAllAPs DQ ?
GetNumberOfAP DQ ?
EnableDisableAP DQ ?
LocateHandleBuffer DQ ?
ABSOLUTEPOINTER DQ ?
SIMPLEPOINTER DQ ?
POINTERGETSTATEABS DQ ?
POINTERGETSTATESMP DQ ?
POINTERMODE DQ ?
getTime DQ ?
GOP DQ ?
queryMode DQ ?
setMode DQ ?
BLT DQ ?
mode DQ ?
maxMode DD ?
.CODE ;MACRO-LAND
;FOR SOME REASON MY HARDWARE DOESN'T LIKE CALLS OF MY HOMEMADE PROCEDURES
;I TRIED GIVING IT STACK SPACE, THAT WASN'T IT. FEEL FREE TO FIGURE IT OUT YOURSELF
;SO IT'S MACRO-CITY FROM HERE ON OUT
RNG MACRO
LOCAL GETRND
LOCAL RETRYRNG
LOCAL EXITRNG
;ASSUMING RDRAND IS SUPPORTED
;ATTEMPT TO GET A 64-BIT RANDOM VALUE IN RAX
MOV RCX, 010H
GETRND:
RDRAND RAX
JNC RETRYRNG
JMP EXITRNG
RETRYRNG:
LOOP GETRND
EXITRNG:
ENDM
GETUEFIFUNCTIONS MACRO
;RDX = SystemTable
;system table header is 24B long
;all pointers should be 8 bytes in x64 systems
;FIND POINTERS TO RELEVANT FUNCTIONS FROM SYSTEM TABLE:
MOV RAX, QWORD PTR [RDX + 30H] ;RAX = SystemTable->ConIn
MOV conIn, RAX
MOV RAX, QWORD PTR [RDX + 40H] ;RAX = SystemTable->ConOut
MOV conOut, RAX
MOV RAX, QWORD PTR [RDX + 58H] ;RAX = SystemTable->RuntimeServices
MOV RuntimeServices, RAX
MOV RAX, QWORD PTR [RDX + 60H] ;RAX = SystemTable->BootServices
MOV BootServices, RAX
MOV RAX, conOut
MOV R8, QWORD PTR [RAX + 08H] ;R8 = ConOut->OutputString
MOV OutputString, R8
MOV R8, QWORD PTR [RAX + 38H] ;R8 = ConOut->SetCursorPosition
MOV SetCursorPosition, R8
MOV RAX, BootServices
MOV R8, QWORD PTR [RAX + 28H] ;R8 = BootServices->AllocatePages
MOV AllocatePages, R8
MOV R8, QWORD PTR [RAX + 60H] ;R8 = BootServices->WaitForEvent
MOV WaitForEvent, R8
MOV R8, QWORD PTR [RAX + 138H] ;R8 = BootServices->LocateHandleBuffer
MOV LocateHandleBuffer, R8
MOV R8, QWORD PTR [RAX + 140H] ;R8 = BootServices->LocateProtocol
MOV LocateProtocol, R8
MOV RAX, conIn
MOV R8, QWORD PTR [RAX + 08H] ;R8 = conIn->ReadKeyStroke
MOV ReadKeyStroke, R8
MOV R8, QWORD PTR [RAX + 10H] ;R8 = conIn->WaitForKey
MOV WaitForKey, R8
MOV RAX, RuntimeServices
MOV R8, QWORD PTR [RAX + 18H] ;R8 = RuntimeServices->EFI_GET_TIME
MOV getTime, R8
;LOCATE TextInputEX
LEA RCX, [TextInputExGUID] ;RCX = &GUID (globally unique identifier
XOR RDX, RDX ;RDX = Registration (NULL)
LEA R8, QWORD PTR [TextInputEX]
CALL LocateProtocol
OUTPUT64BITNUMBER 00H ;OUTPUT STATUS OF LOCATE PROTOCOL, 0 = EFI_SUCESS
;GET RegisterKeyNotify
MOV RAX, TextInputEX
MOV R8, QWORD PTR [RAX + 20H] ;R8 = SIMPLE_TEXT_INPUT_EX_PROTOCOL->RegisterKeyNotify
MOV RegisterKeyNotify, R8
;LOCATE GraphicsOutputProtocol
LEA RCX, [GraphicsOutputGUID]
XOR RDX, RDX
LEA R8, QWORD PTR [GOP]
CALL LocateProtocol
OUTPUT64BITNUMBER 00H ;OUTPUT STATUS OF LOCATE PROTOCOL, 0 = EFI_SUCESS
;GET FUNCTIONS:
MOV RAX, GOP
MOV R8, QWORD PTR [RAX] ;GRAPHICS_OUTPUT_PROTOCOL->QueryMode
MOV queryMode, R8
MOV R8, QWORD PTR [RAX + 08H] ;GRAPHICS_OUTPUT_PROTOCOL->SetMode
MOV setMode, R8
MOV R8, QWORD PTR [RAX + 10H] ;GRAPHICS_OUTPUT_PROTOCOL->Blt
MOV BLT, R8
MOV R8, QWORD PTR [RAX + 18H] ;GRAPHICS_OUTPUT_PROTOCOL->Mode*
MOV mode, R8
LEA RAX, QWORD PTR [mode]
MOV RBX, [RAX]
MOV RAX, [RBX]
MOV DWORD PTR [maxMode], EAX
;LOCATE MPServicesProtocol
LEA RCX, [MPServicesGUID]
XOR RDX, RDX
LEA R8, QWORD PTR [MPServices]
CALL LocateProtocol
OUTPUT64BITNUMBER 00H ;OUTPUT STATUS OF LOCATE PROTOCOL, 0 = EFI_SUCESS
;GET FUNCTIONS
MOV RAX, MPServices
MOV R8, QWORD PTR [RAX] ;EFI_MP_SERVICES_PROTOCOL->GET_NUMBER_OF_PROCESSORS
MOV GetNumberOfAP, R8
MOV R8, QWORD PTR [RAX + 10H] ;EFI_MP_SERVICES_PROTOCOL->STARTUP_ALL_APS
MOV StartupAllAPs, R8
MOV R8, QWORD PTR [RAX + 18H] ;EFI_MP_SERVICES_PROTOCOL->STARTUP_THIS_AP
MOV StartupThisAP, R8
MOV R8, QWORD PTR [RAX + 28H] ;EFI_MP_SERVICES_PROTOCOL->ENABLEDISABLEAP
MOV EnableDisableAP, R8
MOV RCX, conOut ;pointer to conOut
LEA RDX, [mouseMessage]
CALL OutputString
;LOCATE ABSOLUTEPOINTER PROTOCOL:
LEA RCX, [ABSOLUTEPOINTERGUID]
XOR RDX, RDX
LEA R8, QWORD PTR [ABSOLUTEPOINTER]
CALL LocateProtocol
OUTPUT64BITNUMBER 00H
;GET FUNCTIONS:
MOV RAX, ABSOLUTEPOINTER
MOV R8, QWORD PTR [RAX + 08H] ;ABSOLUTEPOINTER->GETSTATE
MOV POINTERGETSTATEABS, R8
;LOCATE SIMPLEPOINTER PROTOCOL:
LEA RCX, [SIMPLEPOINTERGUID]
XOR RDX, RDX
LEA R8, QWORD PTR [SIMPLEPOINTER]
CALL LocateProtocol
OUTPUT64BITNUMBER 00H
;GET FUNCTIONS:
MOV RAX, SIMPLEPOINTER
MOV R8, QWORD PTR [RAX + 08H] ;SIMPLEPOINTER->GETSTATE
MOV POINTERGETSTATESMP, R8
MOV R8, QWORD PTR [RAX + 18H] ;SIMPLEPOINTER->MODE*
MOV POINTERMODE, R8
ENDM
OUTPUT64BITNUMBER MACRO newline ;64b UNSIGNED NUMBER IN RAX newline ? 0 \r\n : skip.
LOCAL CONVERTTODIGITLOOP
LOCAL REVERSELOOP
LOCAL CLEARLOOP
LOCAL WRITE64
; RCX = digit count
MOV RCX, 3FH
LEA RBX, [BUFFER] ; pointer to buffer
LEA RDX, [bMessage]
CLEARLOOP:
MOV BYTE PTR [RBX + RCX], 00H
MOV BYTE PTR [RDX + RCX], 00H
LOOP CLEARLOOP
XOR RCX, RCX ;DIGIT COUNT ZERO OUT
MOV RSI, 10
CONVERTTODIGITLOOP:
XOR RDX, RDX ;CLEAR REMAINDER
DIV RSI ;RAX /= 10, RDX = REMAINDER
ADD DL, 30H ;CONVERT DIGIT TO ASCII
MOV [RBX + RCX], DL ;STORE DIGIT
INC RCX
TEST RAX, RAX ;IS THE REMAINING VALUE 0?
JNZ CONVERTTODIGITLOOP
;REVERSE ORDER INTO MESSAGE OUTPUT BUFFER
LEA RDI, [bMessage]
REVERSELOOP:
DEC RCX
MOV AL, [RBX + RCX]
MOV BYTE PTR [RDI], AL
INC RDI
INC RDI ;TWO SINCE USES WIDE STRING
TEST RCX, RCX
JNZ REVERSELOOP
;ADD RETURN LINE
MOV AL, newline
CMP AL, 00H
JNZ WRITE64
MOV BYTE PTR [RDI], 13
MOV BYTE PTR [RDI + 2], 10
WRITE64: ;OUTPUT TEXT TO CONSOLE:
MOV RCX, conOut
LEA RDX, [bMessage]
CALL OutputString
ENDM
ESTIMATECYCLESFORFPS MACRO ;2 SECONDS TO COMPLETE
LOCAL WAITFORNEXTSECOND
LOCAL WAITFORNEXTSECOND2
;GET INITIAL SECOND:
;READ TIME:
LEA RCX, [time]
LEA RDX, [EFI_TIME_CAPABILITIES]
CALL getTime
MOV AL, BYTE PTR [time + 06H]
MOV BYTE PTR [SECONDS], AL
WAITFORNEXTSECOND:
LEA RCX, [time]
LEA RDX, [EFI_TIME_CAPABILITIES]
CALL getTime
MOV AL, BYTE PTR [time + 06H]
CMP AL, BYTE PTR [SECONDS]
JZ WAITFORNEXTSECOND ;WAIT UNTIL SECOND IS DIFFERENT
MOV BYTE PTR [SECONDS], AL ;STORE NEW VAL IN SECONDS
MOV BYTE PTR [S1], AL
;ESTIMATECYCLES
RDTSC ;READ TIME STAMP COUNTER -> LOW 32b IN EAX, HIGH 32b IN EDX
MOV DWORD PTR [TSC_PS], EAX
MOV DWORD PTR [TSC_PS + 04H], EDX
WAITFORNEXTSECOND2:
LEA RCX, [time]
LEA RDX, [EFI_TIME_CAPABILITIES]
CALL getTime
MOV AL, BYTE PTR [time + 06H]
CMP AL, BYTE PTR [SECONDS]
JZ WAITFORNEXTSECOND2 ;WAIT UNTIL SECOND IS DIFFERENT
MOV BYTE PTR [S2], AL
;REREADTSC
RDTSC
SHL RDX, 20H ;MOVE BOTTOM 32 BITS INTO TOP 32 BITS
OR RAX, RDX ;NOW ENTIRE 64 BIT VALUE IS IN RAX
SUB RAX, TSC_PS ;CALCULATE EXACT NUMBER OF CYCLES PER SECOND
MOV QWORD PTR [TSC_PS2], RAX ;STORE VALUE IN TSC_PS
;DIV64
SHR RAX, 07H ;DIVIDE BY 128
MOV QWORD PTR [CYCLESPERFRAME], RAX ;STORE IN CYCLESPERFRAME
;THIS REPRESENTS HOW MANY CPU CYCLES OCCUR IN 1/128 OF A SECOND
ENDM
SETUPKEYNOTIFICATIONS MACRO
;(EFIAPI *EFI_REGISTER_KEYSTROKE_NOTIFY) (
;IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
;IN EFI_KEY_DATA *KeyData,
;IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
;OUT VOID **NotifyHandle
;);
;UP CONTROL:
MOV RCX, TextInputEX ;POINTS TO THE PROTOCOL
LEA RDX, QWORD PTR [WkeyDescriptor]
LEA R8, [KeyNotificationCallbackFunctionUp] ;CALL BACK FUNCTION
LEA R9, QWORD PTR [WkeyNotifyHandle]
CALL RegisterKeyNotify
MOV RCX, TextInputEX ;POINTS TO THE PROTOCOL
LEA RDX, QWORD PTR [littleWkeyDescriptor]
LEA R8, [KeyNotificationCallbackFunctionUp] ;CALL BACK FUNCTION
LEA R9, QWORD PTR [littleWkeyNotifyHandle]
CALL RegisterKeyNotify
MOV RCX, TextInputEX ;POINTS TO THE PROTOCOL
LEA RDX, QWORD PTR [upkeyDescriptor]
LEA R8, [KeyNotificationCallbackFunctionUp] ;CALL BACK FUNCTION
LEA R9, QWORD PTR [upkeyNotifyHandle]
CALL RegisterKeyNotify
;DOWN CONTROL:
MOV RCX, TextInputEX ;POINTS TO THE PROTOCOL
LEA RDX, QWORD PTR [SkeyDescriptor]
LEA R8, [KeyNotificationCallbackFunctionDown] ;CALL BACK FUNCTION
LEA R9, QWORD PTR [SkeyNotifyHandle]
CALL RegisterKeyNotify
MOV RCX, TextInputEX ;POINTS TO THE PROTOCOL
LEA RDX, QWORD PTR [littleSkeyDescriptor]
LEA R8, [KeyNotificationCallbackFunctionDown] ;CALL BACK FUNCTION
LEA R9, QWORD PTR [littleSkeyNotifyHandle]
CALL RegisterKeyNotify
MOV RCX, TextInputEX ;POINTS TO THE PROTOCOL
LEA RDX, QWORD PTR [downkeyDescriptor]
LEA R8, [KeyNotificationCallbackFunctionDown] ;CALL BACK FUNCTION
LEA R9, QWORD PTR [downkeyNotifyHandle]
CALL RegisterKeyNotify
;LEFT CONTROL:
MOV RCX, TextInputEX ;POINTS TO THE PROTOCOL
LEA RDX, QWORD PTR [AkeyDescriptor]
LEA R8, [KeyNotificationCallbackFunctionLeft] ;CALL BACK FUNCTION
LEA R9, QWORD PTR [AkeyNotifyHandle]
CALL RegisterKeyNotify
MOV RCX, TextInputEX ;POINTS TO THE PROTOCOL
LEA RDX, QWORD PTR [littleAkeyDescriptor]
LEA R8, [KeyNotificationCallbackFunctionLeft] ;CALL BACK FUNCTION
LEA R9, QWORD PTR [littleAkeyNotifyHandle]
CALL RegisterKeyNotify
MOV RCX, TextInputEX ;POINTS TO THE PROTOCOL
LEA RDX, QWORD PTR [leftkeyDescriptor]
LEA R8, [KeyNotificationCallbackFunctionLeft] ;CALL BACK FUNCTION
LEA R9, QWORD PTR [leftkeyNotifyHandle]
CALL RegisterKeyNotify
;RIGHT CONTROL:
MOV RCX, TextInputEX ;POINTS TO THE PROTOCOL
LEA RDX, QWORD PTR [DkeyDescriptor]
LEA R8, [KeyNotificationCallbackFunctionRight] ;CALL BACK FUNCTION
LEA R9, QWORD PTR [DkeyNotifyHandle]
CALL RegisterKeyNotify
MOV RCX, TextInputEX ;POINTS TO THE PROTOCOL
LEA RDX, QWORD PTR [littleDkeyDescriptor]
LEA R8, [KeyNotificationCallbackFunctionRight] ;CALL BACK FUNCTION
LEA R9, QWORD PTR [littleDkeyNotifyHandle]
CALL RegisterKeyNotify
MOV RCX, TextInputEX ;POINTS TO THE PROTOCOL
LEA RDX, QWORD PTR [rightkeyDescriptor]
LEA R8, [KeyNotificationCallbackFunctionRight] ;CALL BACK FUNCTION
LEA R9, QWORD PTR [rightkeyNotifyHandle]
CALL RegisterKeyNotify
;FIRE CONTROL:
MOV RCX, TextInputEX ;POINTS TO THE PROTOCOL
LEA RDX, QWORD PTR [ZkeyDescriptor]
LEA R8, [KeyNotificationCallbackFunctionFire] ;CALL BACK FUNCTION
LEA R9, QWORD PTR [ZkeyNotifyHandle]
CALL RegisterKeyNotify
MOV RCX, TextInputEX ;POINTS TO THE PROTOCOL
LEA RDX, QWORD PTR [littleZkeyDescriptor]
LEA R8, [KeyNotificationCallbackFunctionFire] ;CALL BACK FUNCTION
LEA R9, QWORD PTR [littleZkeyNotifyHandle]
CALL RegisterKeyNotify
MOV RCX, TextInputEX ;POINTS TO THE PROTOCOL
LEA RDX, QWORD PTR [QkeyDescriptor]
LEA R8, [KeyNotificationCallbackFunctionFire] ;CALL BACK FUNCTION
LEA R9, QWORD PTR [QkeyNotifyHandle]
CALL RegisterKeyNotify
MOV RCX, TextInputEX ;POINTS TO THE PROTOCOL
LEA RDX, QWORD PTR [littleQkeyDescriptor]
LEA R8, [KeyNotificationCallbackFunctionFire] ;CALL BACK FUNCTION
LEA R9, QWORD PTR [littleQkeyNotifyHandle]
CALL RegisterKeyNotify
MOV RCX, TextInputEX ;POINTS TO THE PROTOCOL
LEA RDX, QWORD PTR [spacekeyDescriptor]
LEA R8, [KeyNotificationCallbackFunctionFire] ;CALL BACK FUNCTION
LEA R9, QWORD PTR [spacekeyNotifyHandle]
CALL RegisterKeyNotify
ENDM
MINX EQU 500
MINY EQU 500
MAXX EQU 700
MAXY EQU 700
TRIGGERLOW EQU 596
TRIGGERHIGH EQU 604
POINTERLOGIC MACRO
LOCAL ENDPOINTERLOGIC
LOCAL SETPOINTERX
LOCAL SETPOINTERY
LOCAL SETPLEFT
LOCAL SETPRIGHT
LOCAL SETPUP
LOCAL SETPDOWN
LOCAL CHECKPOINTERUPDOWN
LOCAL AFTERPOINTERSET
MOV RCX, SIMPLEPOINTER
LEA RDX, QWORD PTR [POINTERSTATE]
CALL POINTERGETSTATESMP
CMP RAX, 00H
JNZ ENDPOINTERLOGIC ;IF NOT 0, NO REASON TO CALCULATE IT
;GET BUTTON STATUS:
XOR RAX, RAX
MOV AL, BYTE PTR [POINTERSTATE + 0CH]
MOV BYTE PTR [POINTERBUTTON], AL
XOR RAX, RAX
MOV AL, BYTE PTR [POINTERSTATE + 0DH]
MOV BYTE PTR [POINTERBUTTON + 08H], AL
;CHECK BUTTON STATUS:
MOV AL, BYTE PTR [POINTERBUTTON]
CMP AL, 01H
JZ SETPOINTERX
;ELSE RESET TO 600, 600
MOV RAX, 600
MOV QWORD PTR [POINTERLOC], RAX
MOV QWORD PTR [POINTERLOC + 08H], RAX
JMP ENDPOINTERLOGIC
SETPOINTERX:
MOV R8, POINTERMODE
;PIXELS X = RelativeMovementX / ResolutionX
XOR RAX, RAX
XOR RDX, RDX
MOV EAX, DWORD PTR [POINTERSTATE] ;RELATIVEMOVEMENTX
MOVSXD RAX, EAX ;SIGN-EXTEND TO 64-BIT
MOV RBX, [R8] ;RESOLUTION X
CQO ;SIGN-EXTEND RAX INTO RDX:RAX
IDIV RBX ;RAX = RAX / RBX (SIGNED)
;ADD TO CURRENT X LOCATION
MOV RBX, QWORD PTR [POINTERLOC]
ADD RAX, RBX
CMP RAX, MAXX
JA SETPOINTERY
CMP RAX, MINX
JB SETPOINTERY
MOV QWORD PTR [POINTERLOC], RAX
SETPOINTERY:
XOR RAX, RAX
XOR RDX, RDX
MOV EAX, DWORD PTR [POINTERSTATE + 04H] ;RELATIVEMOVEMENTY
MOVSXD RAX, EAX ;SIGN-EXTEND TO 64-BIT
MOV RBX, [R8 + 08H] ;RESOLUTION Y
CQO ;SIGN-EXTEND RAX INTO RDX:RAX
IDIV RBX ;RAX = RAX / RBX (SIGNED)
;ADD TO CURRENT X LOCATION
MOV RBX, QWORD PTR [POINTERLOC + 08H]
ADD RAX, RBX
CMP RAX, MAXY
JA ENDPOINTERLOGIC
CMP RAX, MINY
JB ENDPOINTERLOGIC
MOV QWORD PTR [POINTERLOC + 08H], RAX
ENDPOINTERLOGIC:
;SET POINTER DIRECTIONS
MOV AL, BYTE PTR [POINTERBUTTON + 08H]
MOV BYTE PTR [POINTERFIRE], AL
;RESET ALL THE REST
XOR RAX, RAX
MOV DWORD PTR [POINTERLEFT], EAX ;CLEAR ALL FOUR BYTES
;LEFT
MOV RAX, QWORD PTR [POINTERLOC] ;X
CMP RAX, TRIGGERLOW
JB SETPLEFT
CMP RAX, TRIGGERHIGH
JB CHECKPOINTERUPDOWN
SETPRIGHT:
INC BYTE PTR [POINTERRIGHT]
JMP CHECKPOINTERUPDOWN
SETPLEFT:
INC BYTE PTR [POINTERLEFT]
CHECKPOINTERUPDOWN:
MOV RAX, QWORD PTR [POINTERLOC + 08H] ;Y
CMP RAX, TRIGGERLOW
JB SETPUP
CMP RAX, TRIGGERHIGH
JB AFTERPOINTERSET
SETPDOWN:
INC BYTE PTR [POINTERDOWN]
JMP AFTERPOINTERSET
SETPUP:
INC BYTE PTR [POINTERUP]
AFTERPOINTERSET:
ENDM
KEYLOGIC MACRO
LOCAL AFTERUPCOUNT
LOCAL AFTERDOWNCOUNT
LOCAL AFTERLEFTCOUNT
LOCAL AFTERRIGHTCOUNT
LOCAL AFTERFIRECOUNT
;UP COUNT:
XOR RAX, RAX
MOV AL, BYTE PTR [KEYTIMERUP]
CMP AL, 00H
JZ AFTERUPCOUNT ;NOTHING TO COUNT DOWN
DEC BYTE PTR [KEYTIMERUP]
JNZ AFTERUPCOUNT
;@0, SET PRESSED TO FALSE
MOV BYTE PTR [PRESSEDUP], 00H
AFTERUPCOUNT:
;DOWN COUNT:
XOR RAX, RAX
MOV AL, BYTE PTR [KEYTIMERDOWN]
CMP AL, 00H
JZ AFTERDOWNCOUNT ;NOTHING TO COUNT DOWN
DEC BYTE PTR [KEYTIMERDOWN]
JNZ AFTERDOWNCOUNT
;@0, SET PRESSED TO FALSE
MOV BYTE PTR [PRESSEDDOWN], 00H
AFTERDOWNCOUNT:
;LEFT COUNT
XOR RAX, RAX
MOV AL, BYTE PTR [KEYTIMERLEFT]
CMP AL, 00H
JZ AFTERLEFTCOUNT ;NOTHING TO COUNT DOWN
DEC BYTE PTR [KEYTIMERLEFT]
JNZ AFTERLEFTCOUNT
;@0, SET PRESSED TO FALSE
MOV BYTE PTR [PRESSEDLEFT], 00H
AFTERLEFTCOUNT:
;RIGHT COUNT:
XOR RAX, RAX
MOV AL, BYTE PTR [KEYTIMERRIGHT]
CMP AL, 00H
JZ AFTERRIGHTCOUNT ;NOTHING TO COUNT DOWN
DEC BYTE PTR [KEYTIMERRIGHT]
JNZ AFTERRIGHTCOUNT
;@0, SET PRESSED TO FALSE
MOV BYTE PTR [PRESSEDRIGHT], 00H
AFTERRIGHTCOUNT:
;FIRE COUNT:
XOR RAX, RAX
MOV AL, BYTE PTR [KEYTIMERFIRE]
CMP AL, 00H
JZ AFTERFIRECOUNT ;NOTHING TO COUNT DOWN
DEC BYTE PTR [KEYTIMERFIRE]
JNZ AFTERFIRECOUNT
;@0, SET PRESSED TO FALSE
MOV BYTE PTR [PRESSEDFIRE], 00H
AFTERFIRECOUNT:
ENDM
FIRSTKEYTIMELIMIT EQU 50H ;80
SECONDKEYTIMELIMIT EQU 0CH ;12
KeyNotificationCallbackFunctionUp PROC
;RCX = EFI_KEY_DATA*
XOR RAX, RAX
MOV AL, BYTE PTR [KEYTIMERUP]
CMP AL, 00H ;IS ZERO?
JZ SETFIRSTTIMERA
;ELSE RESET TIMER TO 32
MOV BYTE PTR [KEYTIMERUP], SECONDKEYTIMELIMIT
JMP EXITA
SETFIRSTTIMERA:
MOV BYTE PTR [KEYTIMERUP], FIRSTKEYTIMELIMIT
;ALSO SET PRESSED:
MOV BYTE PTR [PRESSEDUP], 01H
EXITA:
RET
KeyNotificationCallbackFunctionUp ENDP
KeyNotificationCallbackFunctionDown PROC
;RCX = EFI_KEY_DATA*
XOR RAX, RAX
MOV AL, BYTE PTR [KEYTIMERDOWN]
CMP AL, 00H ;IS ZERO?
JZ SETFIRSTTIMERA
;ELSE RESET TIMER TO 32
MOV BYTE PTR [KEYTIMERDOWN], SECONDKEYTIMELIMIT
JMP EXITA
SETFIRSTTIMERA:
MOV BYTE PTR [KEYTIMERDOWN], FIRSTKEYTIMELIMIT
;ALSO SET PRESSED:
MOV BYTE PTR [PRESSEDDOWN], 01H
EXITA:
RET
KeyNotificationCallbackFunctionDown ENDP
KeyNotificationCallbackFunctionLeft PROC
;RCX = EFI_KEY_DATA*
XOR RAX, RAX
MOV AL, BYTE PTR [KEYTIMERLEFT]
CMP AL, 00H ;IS ZERO?
JZ SETFIRSTTIMERA
;ELSE RESET TIMER TO 32
MOV BYTE PTR [KEYTIMERLEFT], SECONDKEYTIMELIMIT
JMP EXITA
SETFIRSTTIMERA:
MOV BYTE PTR [KEYTIMERLEFT], FIRSTKEYTIMELIMIT
;ALSO SET PRESSED:
MOV BYTE PTR [PRESSEDLEFT], 01H
EXITA:
RET
KeyNotificationCallbackFunctionLeft ENDP
KeyNotificationCallbackFunctionRight PROC
;RCX = EFI_KEY_DATA*
XOR RAX, RAX
MOV AL, BYTE PTR [KEYTIMERRIGHT]
CMP AL, 00H ;IS ZERO?
JZ SETFIRSTTIMERA
;ELSE RESET TIMER TO 32
MOV BYTE PTR [KEYTIMERRIGHT], SECONDKEYTIMELIMIT
JMP EXITA
SETFIRSTTIMERA:
MOV BYTE PTR [KEYTIMERRIGHT], FIRSTKEYTIMELIMIT
;ALSO SET PRESSED:
MOV BYTE PTR [PRESSEDRIGHT], 01H
EXITA:
RET
KeyNotificationCallbackFunctionRight ENDP
KeyNotificationCallbackFunctionFire PROC
;RCX = EFI_KEY_DATA*
;XOR PAUSEGAME, 01H
XOR RAX, RAX
MOV AL, BYTE PTR [KEYTIMERFIRE]
CMP AL, 00H ;IS ZERO?
JZ SETFIRSTTIMERA
;ELSE RESET TIMER TO 32
MOV BYTE PTR [KEYTIMERFIRE], SECONDKEYTIMELIMIT
JMP EXITA
SETFIRSTTIMERA:
MOV BYTE PTR [KEYTIMERFIRE], FIRSTKEYTIMELIMIT
;ALSO SET PRESSED:
MOV BYTE PTR [PRESSEDFIRE], 01H
EXITA:
RET
KeyNotificationCallbackFunctionFire ENDP
RESETCONSOLEPOSITION MACRO
MOV RCX, conOut
MOV RDX, 00H
MOV R8, 00H
CALL SetCursorPosition
ENDM
RESETAPS MACRO
;RESET ALL APS (ALL PROCESSORS BESIDES THE BSP)
;BUT ENABLEDISABLEAP SHOULD IGNORE THE BSP (PROBABLY), SO THAT'S WHY I DON'T EXPLICITY EXCLUDE IT
XOR R10, R10
DISABLEALLAPS:
MOV RCX, MPServices
MOV RDX, R10 ;PROCESSOR NUMBER
MOV R8, 00H ;DISABLED
MOV R9, 00H ;NULL
CALL EnableDisableAP
;OUTPUT64BITNUMBER 00H ;OUTPUT RESULT
INC R10
CMP R10, NUMBERAP
JNZ DISABLEALLAPS
XOR R10, R10
ENABLEALLAPS:
MOV RCX, MPServices
MOV RDX, R10 ;PROCESSOR NUMBER
MOV R8, 01H ;ENABLED
MOV R9, 00H ;NULL
CALL EnableDisableAP
;OUTPUT64BITNUMBER 00H ;OUTPUT RESULT
INC R10
CMP R10, NUMBERAP
JNZ ENABLEALLAPS
ENDM
RUNGOPINIT MACRO
;GET DETAILS OF graphics output process on this device
LOCAL CALLQUERY
LOCAL CHECKNEXTMODE
LOCAL MODESELECTED
;CPU DETAILS:
MOV RCX, MPServices
LEA RDX, QWORD PTR [NUMBERAP]
LEA R8, QWORD PTR [ENABLEDAP]
CALL GetNumberOfAP
OUTPUT64BITNUMBER 00H
MOV RAX, QWORD PTR [NUMBERAP]
OUTPUT64BITNUMBER 00H
MOV RAX, QWORD PTR [ENABLEDAP]
OUTPUT64BITNUMBER 00H
;PRINT MAX VIDEO MODES:
MOV RCX, conOut ;pointer to conOut
LEA RDX, [videoMessage1]
CALL OutputString
XOR RAX, RAX
MOV EAX, DWORD PTR [maxMode]
OUTPUT64BITNUMBER 00H
;GET MODE DETAILS:
CALLQUERY:
MOV R10, QWORD PTR [curMode]
MOV RCX, GOP
MOV RDX, R10
LEA R8, QWORD PTR [sizeOfInfo]
LEA R9, QWORD PTR [modeInfoBuffer]
CALL queryMode
;PRINT INFO:
MOV RCX, conOut ;pointer to conOut
LEA RDX, [videoMessage2]
CALL OutputString
MOV RAX, QWORD PTR [curMode]
OUTPUT64BITNUMBER 01H ;NO NEWLINE
MOV RCX, conOut ;pointer to conOut
LEA RDX, [spaceMessage]
CALL OutputString
MOV RBX, QWORD PTR [modeInfoBuffer]
XOR RAX, RAX
MOV EAX, DWORD PTR [RBX + 04H] ;HORIZONTAL RESOLUTION
MOV DWORD PTR [VIDEOX], EAX
OUTPUT64BITNUMBER 01H
MOV RCX, conOut ;pointer to conOut
LEA RDX, [xMessage]
CALL OutputString
MOV RBX, QWORD PTR [modeInfoBuffer]
XOR RAX, RAX
MOV EAX, DWORD PTR [RBX + 08H] ;VERTICAL RESOLUTION
MOV DWORD PTR [VIDEOY], EAX
OUTPUT64BITNUMBER 01H
MOV RCX, conOut ;pointer to conOut
LEA RDX, [spaceMessage]
CALL OutputString
MOV RCX, conOut ;pointer to conOut
LEA RDX, [videoMessage3]
CALL OutputString
MOV RBX, QWORD PTR [modeInfoBuffer]
XOR RAX, RAX
MOV EAX, DWORD PTR [RBX + 0CH] ;PIXEL FORMAT
OUTPUT64BITNUMBER 00H
;DETERMINE IF THIS MODE IS SUITABLE:
;GOAL: 1280x1024, ELSE IT'LL JUST SELECT THE FIRST MODE
CMP DWORD PTR [VIDEOX], 0500H ;1280
JNE CHECKNEXTMODE
CMP DWORD PTR [VIDEOY], 0400H ;1024
JNE CHECKNEXTMODE
;PERFECT VIDEO MODE FOUND, MAKE SELECTION
XOR RAX, RAX
MOV EAX, DWORD PTR [curMode]
MOV QWORD PTR [selectedMode], RAX
JMP MODESELECTED
CHECKNEXTMODE:
INC DWORD PTR [curMode]
XOR EAX, EAX
MOV EAX, DWORD PTR [maxMode]
CMP EAX, DWORD PTR [curMode]
JNE CALLQUERY
MODESELECTED:
MOV RCX, conOut ;pointer to conOut
LEA RDX, [videoMessage4]
CALL OutputString
MOV RAX, selectedMode
OUTPUT64BITNUMBER 00H
;SET NEW VIDEO MODE:
MOV RCX, GOP
MOV RDX, QWORD PTR [selectedMode]
CALL setMode
;ALLOCATE UPSCALEDBUFFER PAGES
MOV RCX, 00H ;ALLOCATE PAGES, ANY
MOV RDX, 04H ;EfiBootServicesData MEMORY
MOV R8, 0800H ;1024 PAGES * 4KB = 4MB
LEA R9, UPSCALEDBUFFER
CALL AllocatePages
ENDM
BLTRECT MACRO sourceX, sourceY, destX, destY, W, H ;RDX LOADED WITH PIXEL BEFOREHAND
MOV RCX, GOP
MOV R8, 00H ;function: Efibltvideofill
MOV R9, sourceX
PUSH 0 ;delta
PUSH H
PUSH W
PUSH destY
PUSH destX
PUSH sourceY
SUB RSP, 20h
CALL BLT
ADD RSP, 20h
ADD RSP, 30h ; Clean up 6 pushes (6 * 8 = 48 = 30h)
ENDM
BLTBUFF MACRO sourceX, sourceY, destX, destY, W, H
MOV RCX, GOP
;RDX LOADED WITH POINTER TO BUFFER
MOV R8, 02H ;FUNCTION: Efibltbuffertovideo
MOV R9, sourceX
PUSH 0
PUSH H
PUSH W
PUSH destY
PUSH destX
PUSH sourceY
SUB RSP, 20h
CALL BLT
ADD RSP, 20h
ADD RSP, 30h
ENDM
GRAPHICSINIT MACRO
LOCAL TILEMAPLOOP1
LOCAL TILEMAPLOOP2
LOCAL TITLECARDLOOP
LOCAL TILEMAPTOPLOOP
;(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT) (
;IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
;IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
;IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
;IN UINTN SourceX,
;IN UINTN SourceY,
;IN UINTN DestinationX,
;IN UINTN DestinationY,
;IN UINTN Width,
;IN UINTN Height,
;IN UINTN Delta OPTIONAL );
;PRIMARILY USE: EfiBltBufferToVideo
;CLEAR THE VIDEO BUFFER:
LEA RDX, QWORD PTR [COLORBLACK]
BLTRECT 0, 0, 0, 0, 1280, 1024
;TILEMAP INITIALIZATION
LEA RBX, QWORD PTR [TILEMAP0]
ADD RBX, 05EH
LEA RDX, QWORD PTR [tilemap]
XOR R8, R8
MOV RCX, 014H
;COPY 15x20 INITIALTILE MAP TO TOP RIGHT OF GAME AREA
;X: 14, Y:0
TILEMAPLOOP1:
MOV AX, WORD PTR [RDX] ;TAKE FROM DATA TILE MAP
MOV WORD PTR [RBX], AX ;PLACE IN VRAM TILE MAP
INC RBX
INC RBX
INC RDX
INC RDX
INC R8
CMP R8, 0FH ;IS IT EQUAL TO 15?
JNZ TILEMAPLOOP1
XOR R8, R8
;INCREASE BY 17 TILES
ADD RBX, 022H
LOOP TILEMAPLOOP1
;COVER 2 TILES ON EDGES WITH BLACK:
LEA RBX, QWORD PTR [TILEMAP1]
MOV RCX, 020H
MOV RAX, 05EDH ;EDGE OVERLAY
XOR R8, R8
TILEMAPTOPLOOP:
MOV WORD PTR [RBX + R8], AX
INC R8
INC R8
LOOP TILEMAPTOPLOOP
MOV RDX, RBX
ADD RDX, 03CH
XOR R8, R8
MOV RCX, 00H
MOV RAX, 05EDH ;EDGE OVERLAY
TILEMAPLOOP2:
MOV WORD PTR [RBX + R8], AX
MOV WORD PTR [RDX + R8], AX
INC R8
INC R8
INC RCX
TEST RCX, 01H
JNZ TILEMAPLOOP2
;ELSE INCREASE R8 BY 30*2
ADD R8, 03CH
CMP RCX, 040H
JNZ TILEMAPLOOP2
LOADINNEXTSECTIONOFMAP
MOV RCX, 12H
LEA RDX, QWORD PTR [TITLECARD]
LEA RBX, QWORD PTR [TILEMAP1]
ADD RBX, 018H
TITLECARDLOOP:
MOV AX, WORD PTR [RDX]
MOV WORD PTR [RBX], AX
INC RBX
INC RBX
INC RDX
INC RDX
LOOP TITLECARDLOOP
;HEIGHT GAUGE:
LEA RBX, QWORD PTR [TILEMAP1]
ADD RBX, 0204H
MOV RAX, 064DH
MOV WORD PTR [RBX], AX
ADD RBX, 0140H
MOV RAX, 0643H
MOV WORD PTR [RBX], AX
;SPRITE INIT:
;SHIP SPRITE:
LEA RBX, QWORD PTR [SPRITES]
MOV RAX, 046000C00000001H ;SHIP
MOV QWORD PTR [RBX], RAX
;BALL SPRITE:
LEA RBX, QWORD PTR [SPRITES + 08H]
MOV RAX, 0DC00B0003B0001H
MOV QWORD PTR [RBX], RAX
;PLATE SPRITE:
LEA RBX, QWORD PTR [SPRITES + 10H]
MOV RAX, 0E000B0003A0001H
MOV QWORD PTR [RBX], RAX
;BUTTON SPRITE:
LEA RBX, QWORD PTR [SPRITES + 18H]
MOV RAX, 0E000D0003C0001H
MOV QWORD PTR [RBX], RAX
;SHADOW SPRITE (LAST SPRITE)
LEA RBX, QWORD PTR [SPRITES + 03F8H]
MOV RAX, 0000000000C0001H
MOV QWORD PTR [RBX], RAX
;ADD SHIP FUEL:
MOV AL, 0FFH
MOV BYTE PTR [SHIPFUEL], AL
ENDM
RENDERTILE MACRO TRANSPARENCY ;ONTO OUTPUTBUFFER (TRANS = 0: NO TRANSPARENCY IN TILES)
LOCAL RENDER8x8LOOP
LOCAL PUSHPIXELTOTILE
LOCAL PUSHPIXELNOOFFSET
LOCAL AFTERPUSHPTT
LOCAL AFTERRENDER8x8
;TILE NUMBER IN AX, INDEX OF PLACE IN OUTPUTFBUFFER IN BL
;DETERMINE DESTINATION LOCATION IN OUTPUTFBUFFER
MOV R9, RAX
MOV RAX, RBX
XOR RDX, RDX
MOV R10, 020H
DIV R10 ;RESULT IN RAX, REMAINDER IN RDX
MOV RBX, RDX ;SAVE REMAINDER
MOV R10, 02000H
MUL R10 ;NUMBER OF BYTES PER TILE ROW IN BUFFER
SHL RBX, 05 ; * 32 ;NUMBER OF BYTES IN ROW OFFSET
ADD RAX, RBX ;FINAL OFFSET
LEA R12, QWORD PTR [OUTPUTFBUFFER]
;GET TILE LOCATION
SHL R9, 08H ;*256, 256BYTES PER TILE IN bgTiles
LEA R10, QWORD PTR [bgTiles]
ADD R9, R10
;COPY 8x8 TILE TO OUTPUTFBUFFER
MOV RCX, 00H
MOV R11, RAX
MOV RAX, (TRANSPARENCY)
RENDER8x8LOOP:
MOV EBX, DWORD PTR [R9]
CMP AL, 00H
JZ PUSHPIXELTOTILE ;DOESN'T MATTER JUST PUSH
TEST EBX, 0FFFFFFH
JZ AFTERPUSHPTT ;PIXEL IS '0', I.E. TRANSPARENT
PUSHPIXELTOTILE:
CMP AL, 00H
JNZ PUSHPIXELNOOFFSET
;OFFSET X:
PUSH RAX
;MOV RAX, R11
;AND RAX, 0FFFFFFFFFFFFFC00H
;MOV R13, RAX
XOR RAX, RAX
MOV R14, R11
SHR R14, 02H
MOV AL, BYTE PTR [TM0XOFFSET]
ADD RAX, R14
AND RAX, 0FFH
SHL RAX, 02H
MOV R13, RAX
;OFFSET Y
XOR RAX, RAX
MOV R14, R11
SHR R14, 0AH ;Y OFFSET
MOV AL, BYTE PTR [TM0YOFFSET]
ADD RAX, R14
AND RAX, 0FFH
SHL RAX, 0AH
ADD R13, RAX
POP RAX
MOV DWORD PTR [R12 + R13], EBX
JMP AFTERPUSHPTT
PUSHPIXELNOOFFSET:
MOV DWORD PTR [R12 + R11], EBX
AFTERPUSHPTT:
ADD R11, 04H
ADD R9, 04H
INC RCX
TEST RCX, 07H
JNZ RENDER8x8LOOP
;ELSE HITS 8 ROWS, CHECK IF FINISHED
CMP RCX, 040H ;64px
JZ AFTERRENDER8x8
;ELSE INCREASE TO NEXT ROW
ADD R11, 03E0H ;NUMBER OF BYTES PER ROW - ONE TILE'S ROW
JMP RENDER8x8LOOP
AFTERRENDER8x8:
ENDM
RENDERSPRITE MACRO
;RAX = 16b-MODE, 16b-TILE, 16b-X, 16b-Y
;MODE ALREADY CHECKED IF 0 TO SKIP
;LOCAL SPRITEPIXELLOOP
;LOCATE LOCATION OF SPRITE TILE DATA
LOCAL AFTERPLOTSPRITEPIXEL
SHR RAX, 10H
XOR RBX, RBX
MOV BX, AX ;MOVED INTO BX
SHL RBX, 0CH ;*4096 (BYTES PER 32x32 SPRITE)
LEA RDX, QWORD PTR [spriteTiles]
CMP SPRITEVERSION, 00H
JZ POSTTILESSELECTED
LEA RDX, QWORD PTR [spriteTiles2] ;SECOND VERSION
POSTTILESSELECTED:
ADD RBX, RDX ;LOCATION OF TILE NOW LOCATED IN RBX
;SET DESTINATION LOCATION
LEA RDX, QWORD PTR [OUTPUTFBUFFER]
SHR RAX, 10H ;RAX = 0YYYYXXXX
XOR R8, R8
XOR R9, R9
MOV R8, RAX ;X
AND R8, 0FFH ;CLAMP TO WITHIN 255
SHL R8, 02H ;*4 (4 BYTES PER PIXEL)
MOV R9, RAX
SHR R9, 06H ;Y * 1024 (BYTES PER ROW)
AND R9, 03FC00H ;CLAMP TO WITHIN 255
ADD RDX, R8
ADD RDX, R9 ;DEST LOCATION NOW IN RDX
MOV RCX, 20H
XOR R8, R8
SPRITEPIXELLOOP:
MOV EAX, DWORD PTR [RBX]
CMP EAX, 00H
JZ AFTERPLOTSPRITEPIXEL
MOV DWORD PTR [RDX], EAX
AFTERPLOTSPRITEPIXEL:
ADD RBX, 04H
ADD RDX, 04H
INC R8
TEST R8, 01FH
JNZ SPRITEPIXELLOOP
;INCREASE RDX BY ONE ROW
ADD RDX, 0380H
XOR R8, R8
LOOP SPRITEPIXELLOOP
ENDM
RENDERGRAPHICS MACRO ;RENDER TILE MAPS TO FINAL OUTPUT BUFFER & OUTPUT TO SCREEN
LOCAL ENEMIESTOSPRITES
LOCAL NEXTENEMYSPRITE
LOCAL BOLTTOSPRITES
LOCAL NEXTBOLTSPRITE
LOCAL RENDERTILEMAP0
LOCAL RENDERTILEMAP1
LOCAL AFTERTM1TILE
LOCAL RESETUPSCALEVALLOOP
LOCAL SENDTOSCREEN
LOCAL AMPLIFYLOOP
LOCAL AFTERSENDTOSCREEN
LOCAL HARDWAREACCEl
LOCAL RENDERSPRITELOOP
LOCAL SPRITELOOPTAIL
;RENDER BOLTS TO SPRITES
LEA RBX, QWORD PTR [BOLTS]
LEA RDX, QWORD PTR [SPRITES]
ADD RDX, 080H ;FIRST 16 RESERVED FOR STUFF
MOV RCX, 08H
BOLTTOSPRITES:
;CLEAR INITIALLY
XOR RAX, RAX
MOV [RDX], RAX
;CHECK FOR BOLT SPRITE PLACEMENT
MOV AL, BYTE PTR [RBX]
CMP AL, 00H
JZ NEXTBOLTSPRITE
;COPY TO SPRITES
MOV RAX, [RBX] ;FIRST 8 BYTES ARE THE SAME BETWEEN BOLTS AND SPRITES
MOV [RDX], RAX
NEXTBOLTSPRITE:
ADD RBX, BOLTOBJSIZE
ADD RDX, 08H
LOOP BOLTTOSPRITES
;RENDER ENEMIES TO SPRITES
LEA RBX, QWORD PTR [ENEMY]
;RDX ALREADY IN CORRECT POSITION
MOV RCX, NUMBEROFENEMY
ENEMIESTOSPRITES:
;CLEAR IT INITIALLY
XOR RAX, RAX
MOV [RDX], RAX
;CHECK FOR ENEMY SPRITE PLACEMENT
MOV AL, BYTE PTR [RBX]
CMP AL, 00H
JZ NEXTENEMYSPRITE
TEST AL, 04H ;INIVISIBLE BIT
JNZ NEXTENEMYSPRITE
;COPY TO SPRITES
MOV RAX, [RBX] ;FIRST 8 BYTES ARE THE SAME BETWEEN ENEMIES AND SPRITES
MOV [RDX], RAX
NEXTENEMYSPRITE:
ADD RBX, ENEMYOBJSIZE
ADD RDX, 08H
LOOP ENEMIESTOSPRITES
;RENDER TILE MAP 0:
XOR RBX, RBX
LEA RDX, TILEMAP0
RENDERTILEMAP0:
;MOVE TILE IN TILE MAP 0 ONTO FINAL OUTPUT BUFFER
XOR RAX, RAX
MOV AX, WORD PTR [RDX + RBX]
PUSH RBX
PUSH RDX
SHR RBX, 01H ;DIVIDE BY TWO TO GET INDEX
RENDERTILE 00H ;WITHOUT TRANSPARENCY
POP RDX
POP RBX
INC RBX
INC RBX ;TWICE FOR WORD VALUE
CMP RBX, 0800H
JNZ RENDERTILEMAP0
;RENDER SPRITES BACK TO FRONT
LEA RBX, QWORD PTR [SPRITES]
ADD RBX, 03F8H
MOV RCX, 00H
RENDERSPRITELOOP:
MOV RAX, QWORD PTR [RBX] ;GET TOTAL VALUE FOR SPRITE
;16b-MODE, 32b-TILE, 16b-X, 16b-Y
CMP AL, 00H
JZ SPRITELOOPTAIL ;IF MODE = 0, DO NOT RENDER
;ELSE RENDER THIS SPRITE:
PUSH RBX
PUSH RCX
RENDERSPRITE
POP RCX
POP RBX
SPRITELOOPTAIL:
SUB RBX, 08H
INC RCX
CMP RCX, 080H
JNZ RENDERSPRITELOOP
;RENDER TILE MAP 1:
XOR RBX, RBX
LEA R8, TILEMAP1
RENDERTILEMAP1:
XOR RAX, RAX
;MOVE TILE IN TILE MAP 1 ONTO FINAL OUTPUT BUFFER
MOV AX, WORD PTR [R8 + RBX]
CMP AX, 00H
JZ AFTERTM1TILE
PUSH RBX
PUSH R8
SHR RBX, 01H ;DIVIDE BY TWO TO GET INDEX
RENDERTILE 01H ;WITH TRANSPARENCY
POP R8
POP RBX
AFTERTM1TILE:
INC RBX
INC RBX ;TWICE FOR WORD VALUE
CMP RBX, 0800H
JNZ RENDERTILEMAP1
;OUTPUT GRAPHICS TO SCREEN:
MOV RAX, UPSCALE_MODE
CMP RAX, 00H
JZ HARDWAREACCEl
;ELSE IS RUNNING ON SLOW EMULATOR, OUT SMALL SCREEN BUFFER
LEA RDX, QWORD PTR [OUTPUTFBUFFER]
BLTBUFF 0, 0, 512, 384, 256, 256
JMP AFTERSENDTOSCREEN
HARDWAREACCEl:
;LEA RDX, QWORD PTR [OUTPUTFBUFFER]
;BLTBUFF 0, 0, 0, 500, 256, 256
;INITIALIZE VALUES FOR PARALLEL BUFFER UPSCALING
MOV RCX, 020H
MOV RAX, 00H
LEA RBX, QWORD PTR [UPSCALEDROW]
RESETUPSCALEVALLOOP:
MOV QWORD PTR [RBX], RAX
ADD RBX, 08H
LOOP RESETUPSCALEVALLOOP ;8 * 32 = 256 BYTES
MOV QWORD PTR [UPSCALEDCOUNT], RAX
;STARTUP_ALL_APS
MOV RCX, MPServices ;IN EFI_MP_SERVICES_PROTOCOL *This,
LEA RDX, [PARALLELRENDERTOSCREEN] ;IN EFI_AP_PROCEDURE Procedure,
MOV R8, 00H ;IN BOOLEAN SingleThread,
MOV R9, 00H ;IN EFI_EVENT WaitEvent OPTIONAL,
;REVERES ORDER ONTO STACK
SUB RSP, 8 ; Pre-align the stack (now RSP % 16 == 0)
PUSH QWORD PTR [FAILEDCPULIST] ;OUT UINTN **FailedCpuList OPTIONAL
PUSH 00H ;IN VOID *ProcedureArgument OPTIONAL,
PUSH 00H ;IN UINTN TimeoutInMicroSeconds,
;SUB RSP, 20H
CALL StartupAllAPs
;ADD RSP, 20H
;ADD RSP, 18h ; Clean up stack
;ABOVE IS EXECUTED IN BLOCKING MODE,
;MEANING THAT ALL APs MUST FINISHED BEFORE THIS NEXT LINE CONTINUES
MOV RAX, QWORD PTR [UPSCALEDCOUNT]
OUTPUT64BITNUMBER 00H ;OUTPUT NUMBER OF UPSCALED LINES TO CONSOLE
MOV RAX, QWORD PTR [UPSCALEDCOUNT]
CMP RAX, 00H
JNZ SKIPRESET
;RESETAPS
INC UPSCALE_MODE
RESETTITLE
SKIPRESET:
;OUTPUT BUFFER TO SCREEN:
MOV RDX, UPSCALEDBUFFER
BLTBUFF 0, 0, 128, 0, 1024, 1024
AFTERSENDTOSCREEN:
ENDM
PARALLELRENDERTOSCREEN PROC
;'WORK' TO RENDER SCREEN SPLIT INTO EACH ROW
;AP FINDS A YET UNRENDERED ROW (UPSCALEDROW)
;CALCULATES IT ONCE TO THE BUFFER,
;THEN COPIES THAT DATA 3 MORE TIMES TO ENLARGE IT TO x4
;AT END, INCREASES COUNT OF COMPLETED ROWS BY 1 (UPSCALEDCOUNT)
;RETURNS TO TOP TO FIND NEXT ROW TO RENDER
;IF NO ROWS FOUND LEFT, RETURNS
;BACK IN MAIN THREAD, CAN DETECT WHEN PROCESS HAS BEEN COMPLETED WHEN COMPLETED ROWS = 256
;FIND UNRENDERED ROW
XOR RCX, RCX
LEA R11, UPSCALEDROW
ROWRENDERLOOP:
MOV AL, BYTE PTR [R11 + RCX]
CMP AL, 00H
JNZ NEXTRENDERROWCHECK
;MARK AS RENDERED:
INC BYTE PTR [R11 + RCX]
;FIND LOCATION OF THIS ROW IN UPSCALEDBUFFER:
MOV RDX, RCX
SHL RDX, 0EH ;* 16384
ADD RDX, [UPSCALEDBUFFER]
;FIND LOCATION OF THIS ROW IN OUTPUTFBUFFER
MOV R9, RCX
SHL R9, 0AH ;* 1024
LEA R10, OUTPUTFBUFFER
ADD R9, R10
;COPY FOUR PIXELS AT A TIME
XOR R8, R8
XOR R10, R10
XOR RAX, RAX
RENDERFIRSTROW:
MOV EAX, DWORD PTR [R9]
MOV DWORD PTR [RDX + R10], EAX
ADD R10, 04H
TEST R8, 03H
JNZ NOTNEXTPIXELYET
ADD R9, 04H ;INCREASE PIXEL IN OUTPUTFBUFFER AFTER COPIED 4 TIMES
NOTNEXTPIXELYET:
INC R8
CMP R8, 0400H
JNZ RENDERFIRSTROW
XOR R8, R8
XOR R9, R9
XOR RAX, RAX
COPYFIRSTROWTOTHREEOTHERS:
MOV RAX, QWORD PTR [RDX + R8]
MOV QWORD PTR [RDX + R8 + 1000H], RAX
MOV QWORD PTR [RDX + R8 + 2000H], RAX
MOV QWORD PTR [RDX + R8 + 3000H], RAX
ADD R8, 08H
INC R9
CMP R9, 0200H
JNZ COPYFIRSTROWTOTHREEOTHERS
;MARK AS ANOTHER ROW COMPLETED
COMPLETED:
INC UPSCALEDCOUNT
NEXTRENDERROWCHECK:
INC RCX
CMP RCX, 0100H
JNZ ROWRENDERLOOP ;STILL MORE WORK TO DO
RET
PARALLELRENDERTOSCREEN ENDP
RENDERHITBOXES MACRO
;RENDER ALL HITBOXES FOR MAIN SHIP AND ENEMIES
;COLOR DETERMINED BY ALTITUDE:
;LOW -> HIGH: RED, ORANGE, YELLOW, GREEN
LOCAL ENEMYRENDERHBLOOP
LOCAL NEXTEHB
LOCAL BOLTRENDERHBLOOP
LOCAL NEXTBHB
;SHOW SHIP HITBOX:
XOR RAX, RAX
MOV AL, BYTE PTR [SHIPHITBOX]
MOV R10, RAX
SHL R10, 02H
ADD R10, 080H
MOV AL, BYTE PTR [SHIPHITBOX + 01H]
MOV R11, RAX
SHL R11, 02H
MOV AL, BYTE PTR [SHIPHITBOX + 02H]
MOV R12, RAX
SHL R12, 02H
MOV AL, BYTE PTR [SHIPHITBOX + 03H]
MOV R13, RAX
SHL R13, 02H
LEA RDX, QWORD PTR [COLORRED]
XOR RAX, RAX
MOV AL, BYTE PTR [SHIPALT]
SHL RAX, 02H
ADD RDX, RAX
BLTRECT 0, 0, R10, R11, R12, R13
;ENEMY HITBOXES:
MOV RCX, NUMBEROFENEMY ;UP TO THIS MANY ENEMIES
LEA RBX, QWORD PTR [ENEMY]
ENEMYRENDERHBLOOP:
MOV AL, BYTE PTR [RBX] ;VALID BIT
CMP AL, 00H
JZ NEXTEHB
XOR RAX, RAX
MOV AL, BYTE PTR [RBX + 04H] ;X
ADD AL, BYTE PTR [RBX + 08H] ;X OFFSET
MOV R10, RAX
SHL R10, 02H
ADD R10, 080H
MOV AL, BYTE PTR [RBX + 06H] ;Y
ADD AL, BYTE PTR [RBX + 09H] ;Y OFFSET
MOV R11, RAX
SHL R11, 02H
MOV AL, BYTE PTR [RBX + 0AH] ;WIDTH
MOV R12, RAX
SHL R12, 02H
MOV AL, BYTE PTR [RBX + 0BH] ;HEIGHT
MOV R13, RAX
SHL R13, 02H
LEA RDX, QWORD PTR [COLORRED]
XOR RAX, RAX
MOV AL, BYTE PTR [RBX + 0CH] ;ENEMY ALTITUDE
SHL RAX, 02H
ADD RDX, RAX
PUSH RBX
PUSH RCX
BLTRECT 0, 0, R10, R11, R12, R13
POP RCX
POP RBX
NEXTEHB:
ADD RBX, ENEMYOBJSIZE
;WITH MACROS TOO FAR FOR LOOP
DEC RCX
CMP RCX, 00H
JNZ ENEMYRENDERHBLOOP
;BOLT HITBOXES
MOV RCX, 08H ;UP TO 32 BOLTS
LEA RBX, QWORD PTR [BOLTS]
BOLTRENDERHBLOOP:
MOV AL, BYTE PTR [RBX] ;VALID BIT
CMP AL, 00H
JZ NEXTBHB
XOR RAX, RAX
MOV AL, BYTE PTR [RBX + 04H] ;X
ADD AL, BYTE PTR [RBX + 08H] ;X OFFSET
MOV R10, RAX
SHL R10, 02H
ADD R10, 080H
MOV AL, BYTE PTR [RBX + 06H] ;Y
ADD AL, BYTE PTR [RBX + 09H] ;Y OFFSET
MOV R11, RAX
SHL R11, 02H
MOV AL, BYTE PTR [RBX + 0AH] ;WIDTH
MOV R12, RAX
SHL R12, 02H
MOV AL, BYTE PTR [RBX + 0BH] ;HEIGHT
MOV R13, RAX
SHL R13, 02H
LEA RDX, QWORD PTR [COLORRED]
XOR RAX, RAX
MOV AL, BYTE PTR [RBX + 0CH] ;BOLT ALTITUDE
SHL RAX, 02H
ADD RDX, RAX
PUSH RBX
PUSH RCX
BLTRECT 0, 0, R10, R11, R12, R13
POP RCX
POP RBX
NEXTBHB:
ADD RBX, BOLTOBJSIZE
;WITH MACROS TOO FAR FOR LOOP
DEC RCX
CMP RCX, 00H
JNZ BOLTRENDERHBLOOP
ENDM
;GAME LOGIC MACROS
RESETGAME MACRO
LOCAL CLEARTILEMAPS
LOCAL CLEARBUFF
LOCAL CLEARBOLTS
LOCAL CLEARENEMIES
;RESET ALL VARIABLES
MOV STAGE, 00H
MOV SHIPX, 00H
MOV SHIPY, 00H
MOV SHIPTILTY, 00H
XOR RAX, RAX
MOV BYTE PTR [SHIPHITBOX], AL
MOV BYTE PTR [SHIPHITBOX + 01H], AL
MOV BYTE PTR [SHIPHITBOX + 02H], AL
MOV BYTE PTR [SHIPHITBOX + 03H], AL
MOV BYTE PTR [SHIPALT], AL
MOV BYTE PTR [SHIPFUEL], AL
MOV SCROLLTIMER, 00H
MOV SCROLLX, 00H
MOV SCROLLY, 00H
MOV LASTSCROLLX, 00H
MOV LASTSCROOLY, 00H
MOV GAMEMAPOFFSET, 0258H
MOV COLUMNTICK, 00H
MOV HIDESHADOW, 00H
MOV HIT, 00H
MOV NOFUEL, 00H
MOV PAUSESCROLL, 00H
MOV EXPLODETIMER, 00H
MOV RESET, 00H
MOV EXPLODEDELAYTIMER, 00H
MOV WINTIMER, 00H
MOV BYTE PTR [TM0XOFFSET], 00H
MOV BYTE PTR [TM0YOFFSET], 00H
MOV BYTE PTR [TM1XOFFSET], 00H
MOV BYTE PTR [TM1YOFFSET], 00H
;CLEAR TILEMAPS
XOR RAX, RAX
MOV RCX, 0400H
LEA RDX, QWORD PTR [TILEMAP0]
LEA RBX, QWORD PTR [TILEMAP1]
CLEARTILEMAPS:
MOV WORD PTR [RDX], AX
MOV WORD PTR [RBX], AX
ADD RDX, 02H
ADD RBX, 02H
LOOP CLEARTILEMAPS
;FRAMERULES:
MOV MOVEMENTFRAMERULEC, 00H
MOV SCROLLFRAMERULEC, 00H
MOV FUELFRAMERULEC, 00H
MOV ELOGICFRAMERULEC, 00H
MOV EXPLODEFRAMERULEC, 00H
;CLEAR BUFFER
MOV RCX, 010000H
LEA RDX, QWORD PTR [OUTPUTFBUFFER]
XOR RAX, RAX
CLEARBUFF:
MOV DWORD PTR [RDX], EAX
ADD RDX, 04H
LOOP CLEARBUFF
;CLEAR BOLTS:
MOV RCX, 08H
LEA RDX, QWORD PTR [BOLTS]
CLEARBOLTS:
MOV [RDX], RAX
ADD RDX, BOLTOBJSIZE
LOOP CLEARBOLTS
;CLEAR ENEMIES:
MOV RCX, NUMBEROFENEMY
LEA RDX, QWORD PTR [ENEMY]
CLEARENEMIES:
MOV [RDX], RAX
ADD RDX, ENEMYOBJSIZE
LOOP CLEARENEMIES
;INIT GRAPHICS
GRAPHICSINIT
;UNPAUSE
MOV PAUSEGAME, 00H
ENDM
FIREBOLT MACRO
LOCAL ENDFIREBOLT
LOCAL CHECKBOLT
LOCAL NEXTBOLTCHECK
LOCAL FIREINTHEHOLE
;LOCATE EMPTY BOLT SLOT
LEA RBX, QWORD PTR [BOLTS]
MOV RCX, 00H
CHECKBOLT:
MOV AL, BYTE PTR [RBX]
CMP AL, 00H
JZ FIREINTHEHOLE
NEXTBOLTCHECK:
ADD RBX, BOLTOBJSIZE
LOOP CHECKBOLT
JMP ENDFIREBOLT ;NO BOLT SLOTS AVAILABLE
FIREINTHEHOLE: ;BOLT SLOT FOUND, FIRE AWAY
INC BYTE PTR [RBX] ;TURN ON
MOV AL, 0DH
MOV BYTE PTR [RBX + 02H], AL ;SPRITE
MOV RAX, SHIPX
ADD RAX, SHIPORGINX
ADD RAX, 010H
MOV BYTE PTR [RBX + 04H], AL ;X
MOV RAX, SHIPY
SHR RAX, 01H
ADD RAX, SHIPORGINY
ADD RAX, SHIPTILTY
SUB RAX, 07H
MOV BYTE PTR [RBX + 06H], AL ;Y
MOV BYTE PTR [RBX + 08H], 08H ;X
MOV BYTE PTR [RBX + 09H], 0BH ;Y
MOV BYTE PTR [RBX + 0AH], 010H ;WIDTH
MOV BYTE PTR [RBX + 0BH], 08H ;HEIGHT
MOV AL, SHIPALT
MOV BYTE PTR [RBX + 0CH], AL ;ALTITUDE
MOV BYTE PTR [RBX + 0DH], 00H ;TIMER
MOV BOLTCOOLDOWN, BOLTCOOLDOWNFRAMES
ENDFIREBOLT:
ENDM
BOLTLOGIC MACRO
;MOVE BOLTS AROUND, SET HIT BOXES
;BOLTOBJ STRUCT
; MODE DW ? ;0 IF INACTIVE
; SPRITE DW ?
; X DW ?
; Y DW ?
; HITBOXX DB ? ;X & Y ARE OFFSET FROM TOP LEFT CORNER
; HITBOXY DB ?
; HITBOXW DB ?
; HITBOXH DB ?
; ALT DB ? ;ALTITUDE
;BOLTOBJ ENDS
LOCAL DEADBOLT
LOCAL MOVEBOLT
;LOCATE EMPTY BOLT SLOT
LEA RBX, QWORD PTR [BOLTS]
MOV RCX, 08H
CHECKBOLT:
MOV AL, BYTE PTR [RBX]
CMP AL, 00H
JZ NEXTBOLTCHECK
;BOLT IS ACTIVE MODE 1, MOVE
CMP AL, 01H
JZ MOVEBOLT
;ELSE IS MODE 2, INCREASE SPRITES ACCORDING TO TIMER
MOV AL, BYTE PTR [RBX + 0DH] ;TIMER
INC AL
CMP AL, 010 ;MAX TIME
JA DEADBOLT
SHR AL, 03H ;/8
ADD AL, 031H
MOV BYTE PTR [RBX + 02H], AL ;SPRITE
;INCREASE TIMER
INC BYTE PTR [RBX + 0DH] ;TIMER
JMP NEXTBOLTCHECK
MOVEBOLT:
MOV AL, BYTE PTR [RBX + 06H] ;Y
DEC AL
CMP AL, 0FFH ;DON'T WRAP AROUND SCREEN
JZ DEADBOLT
MOV BYTE PTR [RBX + 06H], AL
MOV AL, BYTE PTR [RBX + 04H] ;X
INC AL
INC AL
MOV BYTE PTR [RBX + 04H], AL
CMP AL, 0F0H
JB NEXTBOLTCHECK
DEADBOLT: ;HIT THE EDGE OF THE SCREEN, DISABLE
XOR RAX, RAX
MOV BYTE PTR [RBX], AL
NEXTBOLTCHECK:
ADD RBX, BOLTOBJSIZE
LOOP CHECKBOLT
ENDM
MOVESHIP MACRO
LOCAL STARTMOVESHIP
LOCAL AFTERSHIPLEFT
LOCAL AFTERSHIPRIGHT
LOCAL AFTERSHIPUP
LOCAL AFTERSHIPDOWN
LOCAL AFTERBOLTCHECK
LOCAL AFTERBOLTS
LOCAL COMPASS1
LOCAL COMPASS2
LOCAL COMPASS3
LOCAL COMPASS4
LOCAL COMPASS5
LOCAL COMPASS6
LOCAL COMPASS7
LOCAL COMPASS8
LOCAL SETSPRITEBUTTON
LOCAL CALCALTITUDESPRITE
LOCAL FULLALTSPRITE
LOCAL DRAWFUELSPRITES
LOCAL DEADSHIPFROMNOFUEL
LOCAL SETFUELSPRITES
LOCAL NEXTFUELSPRITE
LOCAL SETALTSPRITE
LOCAL ENDMOVESHIP
;CHECK STAGE
MOV RAX, STAGE
CMP RAX, 02H
JBE STARTMOVESHIP
;CHANGE SPRITE TO RED SHIP:
MOV AL, 03FH
MOV BYTE PTR [SPRITES + 02H], AL
JMP ENDMOVESHIP
;COMBINE KEYBOARD AND MOUSE MOVEMENT INTO ONE BYTE:
STARTMOVESHIP:
MOV AL, BYTE PTR [PRESSEDLEFT]
OR AL, BYTE PTR [POINTERLEFT]
MOV BYTE PTR [COMBLEFT], AL
MOV AL, BYTE PTR [PRESSEDRIGHT]
OR AL, BYTE PTR [POINTERRIGHT]
MOV BYTE PTR [COMBRIGHT], AL
MOV AL, BYTE PTR [PRESSEDUP]
OR AL, BYTE PTR [POINTERUP]
MOV BYTE PTR [COMBUP], AL
MOV AL, BYTE PTR [PRESSEDDOWN]
OR AL, BYTE PTR [POINTERDOWN]
MOV BYTE PTR [COMBDOWN], AL
MOV AL, BYTE PTR [PRESSEDFIRE]
OR AL, BYTE PTR [POINTERFIRE]
MOV BYTE PTR [COMBFIRE], AL
;CHECK MOVEMENTFRAMERULE
INC MOVEMENTFRAMERULEC
MOV RAX, MOVEMENTFRAMERULEC
CMP RAX, MOVEMENTFRAMERULE
JNZ ENDMOVESHIP
;HIT FRAMERULE, RESET COUNTER
XOR RAX, RAX
MOV MOVEMENTFRAMERULEC, RAX
MOV RBX, SHIPX
MOV RDX, SHIPY
XOR R8, R8
;MOVE LEFT
MOV AL, BYTE PTR [COMBLEFT]
CMP AL, 01H
JNZ AFTERSHIPLEFT
CMP RBX, 00H
JZ AFTERSHIPLEFT
DEC RBX
TEST RBX, 01H
JZ AFTERSHIPLEFT
;DECREASE Y BY 2
DEC SHIPTILTY
AFTERSHIPLEFT: ;MOVE RIGHT
MOV AL, BYTE PTR [COMBRIGHT]
CMP AL, 01H
JNZ AFTERSHIPRIGHT
CMP RBX, SHIPMAXX
JZ AFTERSHIPRIGHT
INC RBX
TEST RBX, 01H
JNZ AFTERSHIPRIGHT
;INCREASE Y BY 2
INC SHIPTILTY
AFTERSHIPRIGHT: ;MOVE UP
MOV AL, BYTE PTR [COMBUP]
CMP AL, 01H
JNZ AFTERSHIPUP
CMP RDX, 00H
JZ AFTERSHIPUP
MOV R8, 04H ;GOING UP
DEC RDX
DEC RDX
AFTERSHIPUP: ;MOVE DOWN
MOV AL, BYTE PTR [COMBDOWN]
CMP AL, 01H
JNZ AFTERSHIPDOWN
CMP RDX, SHIPMAXY
JZ AFTERSHIPDOWN
MOV R8, 08H ;GOING UP
INC RDX
INC RDX
AFTERSHIPDOWN:
MOV SHIPX, RBX
MOV SHIPY, RDX
;SET SHIP LOCATION IN SPRITES:
MOV RAX, SHIPY
SHR RAX, 01H ;DIVIDE BY TWO
ADD RAX, SHIPORGINY
MOV RDX, SHIPTILTY
ADD RAX, RDX
SHL RAX, 010H
MOV RBX, SHIPX
ADD RBX, SHIPORGINX
OR RAX, RBX
MOV DWORD PTR [SPRITES + 04H], EAX
;SET SPRITE:
MOV RAX, R8
MOV BYTE PTR [SPRITES + 02H], AL
;SET SHADOW SPRITE:
MOV RAX, SHIPORGINY
ADD RAX, SHIPTILTY
ADD RAX, 03H
MOV RDX, SHIPMAXY
SHR RDX, 01H
ADD RAX, RDX
SHL RAX, 010H
ADD RAX, SHIPX
ADD RAX, 0FH
MOV DWORD PTR [SPRITES + 03FCH], EAX
MOV RAX, HIDESHADOW
XOR RAX, 01H
MOV BYTE PTR [SPRITES + 03F8H], AL
;SET ALTITUDE SPRITES:
MOV R8, 28
MOV R9, 7
MOV R10, SHIPMAXY
SUB R10, SHIPY
MOV RCX, 04H
LEA RBX, QWORD PTR [TILEMAP1]
ADD RBX, 0304H
XOR R11, R11
CALCALTITUDESPRITE:
CMP R10, R8 ;COMPARE TO 28, IF GREATER OR EQUAL, IT'S A FULL SPRITE
JAE FULLALTSPRITE
;ELSE FIND PERCENTAGE FULL
MOV RAX, R10
SHL RAX, 01H
XOR RDX, RDX
DIV R9
ADD RAX, 0644H
;MOVE 28 INTO R10
MOV R10, R8
JMP SETALTSPRITE
FULLALTSPRITE:
MOV AX, 064CH
CMP R11, 03H
JAE SETALTSPRITE
INC R11
SETALTSPRITE:
MOV WORD PTR [RBX], AX
SUB R10, R8
SUB RBX, 040H
LOOP CALCALTITUDESPRITE
MOV RAX, R11
MOV BYTE PTR [SHIPALT], AL
;FUEL FRAMERULE:
XOR RAX, RAX
MOV AL, BYTE PTR [SHIPFUEL]
INC FUELFRAMERULEC
MOV RBX, FUELFRAMERULEC
CMP RBX, FUELFRAMERULE
JNZ SETFUELSPRITES
XOR RBX, RBX
MOV FUELFRAMERULEC, RBX
CMP AL, 00H
JZ DEADSHIPFROMNOFUEL
;DECREASE FUEL
DEC AL
MOV BYTE PTR [SHIPFUEL], AL
JMP SETFUELSPRITES
DEADSHIPFROMNOFUEL:
INC NOFUEL
MOV RBX, 0FFH ;DEATH MODE
MOV STAGE, RBX
SETFUELSPRITES:
SHR RAX, 02H ;/4
MOV R8, RAX
MOV RCX, 08H
LEA RBX, QWORD PTR [TILEMAP1]
ADD RBX, 0798H
MOV RDX, 08H ;COMPARISON GUAGE
DRAWFUELSPRITES:
MOV AX, 05E0H
CMP R8, RDX ;CURRENT FUEL AGAINST INCREASING GAUGE
JAE FULLFUELCELL
;ELSE IS LESS THAN FULL CELL
AND R8, 07H
ADD RAX, R8
MOV R8, 00H ;CLEAR FUEL FOR REST OF CELLS
JMP NEXTFUELSPRITE
FULLFUELCELL:
ADD AX, 07H ;FULL CELL
NEXTFUELSPRITE:
MOV WORD PTR [RBX], AX ;STORE SPRITE
ADD RDX, 08H ;INCREASE TO NEXT GUAGE
INC RBX
INC RBX
LOOP DRAWFUELSPRITES
;CHECK BOLT FIRE
MOV RAX, BOLTCOOLDOWN
CMP RAX, 00H
JNZ AFTERBOLTCHECK
;CHECK FIRE
MOV AL, BYTE PTR [COMBFIRE]
CMP AL, 01H
JNZ AFTERBOLTCHECK
;ELSE TRY TO FIRE BOLT:
FIREBOLT
AFTERBOLTCHECK:
BOLTLOGIC
MOV RAX, BOLTCOOLDOWN
CMP RAX, 00H
JZ AFTERBOLTS
DEC BOLTCOOLDOWN
AFTERBOLTS:
;SHOW MOVEMENT IN ARCADE JOYSTICK AND BUTTON
;EIGHT POSSIBLE LOCATIONS IF R8 = UDLR:
;U000, U00R, 000R, 0D0R, 0D00, 0DL0, 00L0, U0L0
;OTHER MODES ARE POSSIBLE SINCE KEYBOARD | MOUSE INPUT, BUT THOSE RESULT IN ONLY STANDARD POSITION
XOR RAX, RAX
MOV AL, BYTE PTR [COMBUP]
SHL AL, 01H
OR AL, BYTE PTR [COMBDOWN]
SHL AL, 01H
OR AL, BYTE PTR [COMBLEFT]
SHL AL, 01H
OR AL, BYTE PTR [COMBRIGHT]
MOV R8, RAX ;R8 LOWEST NIBBLE = UDLR
CMP R8, 08H
JNZ COMPASS1
MOV EAX, 0D600B0H ;Y-6
JMP SETSPRITEBUTTON
COMPASS1:
CMP R8, 09H
JNZ COMPASS2
MOV EAX, 0D800B4H ;Y-4, X+4
JMP SETSPRITEBUTTON
COMPASS2:
CMP R8, 01H
JNZ COMPASS3
MOV EAX, 0DC00B6H ;X+6
JMP SETSPRITEBUTTON
COMPASS3:
CMP R8, 05H
JNZ COMPASS4
MOV EAX, 0E000B4H ;Y+4, X+4
JMP SETSPRITEBUTTON
COMPASS4:
CMP R8, 04H
JNZ COMPASS5
MOV EAX, 0E200B0H ;Y+6
JMP SETSPRITEBUTTON
COMPASS5:
CMP R8, 06H
JNZ COMPASS6
MOV EAX, 0E000ACH ;Y+4, X-4
JMP SETSPRITEBUTTON
COMPASS6:
CMP R8, 02H
JNZ COMPASS7
MOV EAX, 0DC00AAH ;X-6
JMP SETSPRITEBUTTON
COMPASS7:
CMP R8, 0AH
JNZ COMPASS8
MOV EAX, 0D800ACH ;Y-4, X-4
JMP SETSPRITEBUTTON
COMPASS8:
MOV EAX, 0DC00B0H ;STANDARD X-Y
SETSPRITEBUTTON:
MOV DWORD PTR [SPRITES + 0CH], EAX ;STORE BALL LOCATION
MOV AL, BYTE PTR [COMBFIRE]
ADD AL, 03CH
MOV BYTE PTR [SPRITES + 01AH], AL
ENDMOVESHIP:
ENDM
SPAWNENEMY MACRO X, Y, Z ;2D X AND Y [0-255], Z ALTITUDE [0-3]
;ENEMY TYPE LOADED INTO R8
;ENEMYOBJ STRUCT
; MODE DW ? ;0 IF INACTIVE
; SPRITE DW ?
; X DW ?
; Y DW ?
; HITBOXX DB ? ;X & Y ARE OFFSET FROM TOP LEFT CORNER
; HITBOXY DB ?
; HITBOXW DB ?
; HITBOXH DB ?
; ALT DB ? ;ALTITUDE
;ENEMYOBJ ENDS
;ENEMYOBJSIZE = 0DH
;ENEMY ENEMYOBJ 040H DUP(<>) ;64 ENEMIES
LOCAL ENDSPAWNENEMY
LOCAL SLOTSEARCHLOOP
LOCAL DETECTINGENEMYTYPE
LOCAL SPAWNENTRYWALL
LOCAL NEXTENEMYCLEAN1
LOCAL NEXTENEMYCLEAN2
LOCAL WALLLOOP
LOCAL WALLLOOP2
LOCAL WALLLOOP3
LOCAL SPAWNDISH
LOCAL SPAWNFRONTTURRENT
LOCAL SPAWNSIDETURRENT
LOCAL SPAWNTANKER
LOCAL SPAWNMISSLEUP
LOCAL SPAWNEBOLT
LOCAL SPAWNSPRAY
LOCAL SPAWNWALL
LOCAL SPAWNWALL2
LOCAL SPAWNGROUNDPLANE
LOCAL SPAWNSPACEPLANE
LOCAL DISTANCELOOP
LOCAL SPAWNENTRYWALLMEDIUM
LOCAL SPAWNENTRYWALLLOW
LOCAL SPAWNMISSLE
LOCAL SPAWNBOSS
;FIND OPEN ENEMY SLOT
LEA RDX, QWORD PTR [ENEMY]
MOV RCX, NUMBEROFENEMY ;MAX NUMBER OF OPEN SLOTS
XOR R15, R15
SLOTSEARCHLOOP:
MOV AL, BYTE PTR [RDX]
CMP AL, 00H
JZ DETECTINGENEMYTYPE ;THIS SLOT IS OPEN
INC R15
ADD RDX, ENEMYOBJSIZE
LOOP SLOTSEARCHLOOP
;IF EMPTY SLOT NOT FOUND, SKIP SPAWN
JMP ENDSPAWNENEMY
DETECTINGENEMYTYPE:
CMP R8, 01H
JZ SPAWNENTRYWALL
CMP R8, 02H
JZ SPAWNENTRYWALLMEDIUM
CMP R8, 03H
JZ SPAWNENTRYWALLLOW
CMP R8, 04H
JZ SPAWNBOSS
CMP R8, 01CH
JZ SPAWNMISSLEUP
CMP R8, 023H
JZ SPAWNFRONTTURRENT
CMP R8, 024H
JZ SPAWNSIDETURRENT
CMP R8, 025H
JZ SPAWNTANKER
CMP R8, 026H
JZ SPAWNDISH
CMP R8, 027H
JZ SPAWNEBOLT
CMP R8, 029H
JZ SPAWNSPRAY
CMP R8, 021H
JZ SPAWNWALL
CMP R8, 022H
JZ SPAWNWALL2
CMP R8, 019H
JZ SPAWNGROUNDPLANE
CMP R8, 011H
JZ SPAWNSPACEPLANE
CMP R8, 01BH
JZ SPAWNMISSLE
;IF ENEMY TYPE NOT FOUND, SKIP SPAWN
JMP ENDSPAWNENEMY
SPAWNENTRYWALL:
;SINCE THIS IS THE FIRST EVENT, I KNOW THAT ALL THE ENEMIES ARE CLEAR
;SO I'M GOING TO SPAWN MULTIPLE AT ONCE, DON'T DO THAT OTHERWISE
MOV RAX, 101
MOV RBX, 50
MOV RCX, 0DH
WALLLOOP:
MOV BYTE PTR [RDX], 0DH ;MODE 1 + LONG SPRITE + INVISIBLE
MOV BYTE PTR [RDX + 01H], 00H
MOV BYTE PTR [RDX + 02H], 011H ;SPRITE
MOV BYTE PTR [RDX + 04H], AL
MOV BYTE PTR [RDX + 06H], BL
MOV BYTE PTR [RDX + 0CH], 02H ;ALT
MOV BYTE PTR [RDX + 0DH], 00H ;TIMER
;HIT BOX:
PUSH RAX
MOV EAX, 03A140000H ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
POP RAX
ADD AL, 08H
ADD BL, 04H
ADD RDX, ENEMYOBJSIZE
LOOP WALLLOOP
;FINAL WALL ON RIGHT SIDE:
MOV BYTE PTR [RDX], 0DH ;MODE 1 + LONG SPRITE + INVISIBLE
MOV BYTE PTR [RDX + 01H], 00H
MOV BYTE PTR [RDX + 02H], 011H ;SPRITE
MOV BYTE PTR [RDX + 04H], 221
MOV BYTE PTR [RDX + 06H], 97
MOV BYTE PTR [RDX + 0CH], 03H ;ALT
;HIT BOX:
MOV EAX, 042140000H ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
JMP ENDSPAWNENEMY
SPAWNENTRYWALLMEDIUM:
;SINCE THIS IS THE FIRST EVENT, I KNOW THAT ALL THE ENEMIES ARE CLEAR
;SO I'M GOING TO SPAWN MULTIPLE AT ONCE, DON'T DO THAT OTHERWISE
MOV RAX, 101
MOV RBX, 66
MOV RCX, 0DH
WALLLOOP2:
MOV BYTE PTR [RDX], 0DH ;MODE 1 + LONG SPRITE + INVISIBLE
MOV BYTE PTR [RDX + 01H], 00H
MOV BYTE PTR [RDX + 02H], 011H ;SPRITE
MOV BYTE PTR [RDX + 04H], AL
MOV BYTE PTR [RDX + 06H], BL
MOV BYTE PTR [RDX + 0CH], 01H ;ALT
MOV BYTE PTR [RDX + 0DH], 00H ;TIMER
;HIT BOX:
PUSH RAX
MOV EAX, 02A140000H ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
POP RAX
ADD AL, 08H
ADD BL, 04H
NEXTENEMYCLEAN1:
INC R15
CMP R15, NUMBEROFENEMY
JAE ENDSPAWNENEMY ;MAXXED OUT
ADD RDX, ENEMYOBJSIZE
CMP BYTE PTR [RDX], 00H
JNZ NEXTENEMYCLEAN1
LOOP WALLLOOP2
;FINAL WALL ON RIGHT SIDE:
MOV BYTE PTR [RDX], 0DH ;MODE 1 + LONG SPRITE + INVISIBLE
MOV BYTE PTR [RDX + 01H], 00H
MOV BYTE PTR [RDX + 02H], 011H ;SPRITE
MOV BYTE PTR [RDX + 04H], 221
MOV BYTE PTR [RDX + 06H], 97
MOV BYTE PTR [RDX + 0CH], 03H ;ALT
;HIT BOX:
MOV EAX, 042140000H ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
JMP ENDSPAWNENEMY
SPAWNENTRYWALLLOW:
;SINCE THIS IS THE FIRST EVENT, I KNOW THAT ALL THE ENEMIES ARE CLEAR
;SO I'M GOING TO SPAWN MULTIPLE AT ONCE, DON'T DO THAT OTHERWISE
MOV RAX, 101
MOV RBX, 82
MOV RCX, 0DH
WALLLOOP3:
MOV BYTE PTR [RDX], 0DH ;MODE 1 + LONG SPRITE + INVISIBLE
MOV BYTE PTR [RDX + 01H], 00H
MOV BYTE PTR [RDX + 02H], 011H ;SPRITE
MOV BYTE PTR [RDX + 04H], AL
MOV BYTE PTR [RDX + 06H], BL
MOV BYTE PTR [RDX + 0CH], 00H ;ALT
MOV BYTE PTR [RDX + 0DH], 00H ;TIMER
;HIT BOX:
PUSH RAX
MOV EAX, 01A140000H ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
POP RAX
ADD AL, 08H
ADD BL, 04H
NEXTENEMYCLEAN2:
INC R15
CMP R15, NUMBEROFENEMY
JAE ENDSPAWNENEMY ;MAXXED OUT
ADD RDX, ENEMYOBJSIZE
CMP BYTE PTR [RDX], 00H
JNZ NEXTENEMYCLEAN2
LOOP WALLLOOP3
JMP ENDSPAWNENEMY
SPAWNFRONTTURRENT:
;SET UP INITIAL VALUES
INC BYTE PTR [RDX] ;SET TO MODE 1
MOV BYTE PTR [RDX + 01H], 00H
MOV BYTE PTR [RDX + 02H], 023H ;SPRITE
MOV RAX, X
MOV BYTE PTR [RDX + 04H], AL
MOV RAX, Y
MOV BYTE PTR [RDX + 06H], AL
MOV RAX, Z
MOV BYTE PTR [RDX + 0CH], AL
MOV BYTE PTR [RDX + 0DH], 00H ;TIMER
;HIT BOX:
MOV EAX, 00C13060BH ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
JMP ENDSPAWNENEMY
SPAWNSIDETURRENT:
;SET UP INITIAL VALUES
INC BYTE PTR [RDX] ;SET TO MODE 1
MOV BYTE PTR [RDX + 01H], 00H
MOV BYTE PTR [RDX + 02H], 024H ;SPRITE
MOV RAX, X
MOV BYTE PTR [RDX + 04H], AL
MOV RAX, Y
MOV BYTE PTR [RDX + 06H], AL
MOV RAX, Z
MOV BYTE PTR [RDX + 0CH], AL
MOV BYTE PTR [RDX + 0DH], 00H ;TIMER
;HIT BOX:
MOV EAX, 0111D0701H ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
JMP ENDSPAWNENEMY
SPAWNTANKER:
;SET UP INITIAL VALUES
INC BYTE PTR [RDX] ;SET TO MODE 1
MOV BYTE PTR [RDX + 01H], 00H
MOV BYTE PTR [RDX + 02H], 025H ;SPRITE
MOV RAX, X
MOV BYTE PTR [RDX + 04H], AL
MOV RAX, Y
MOV BYTE PTR [RDX + 06H], AL
MOV RAX, Z
MOV BYTE PTR [RDX + 0CH], AL
MOV BYTE PTR [RDX + 0DH], 00H ;TIMER
;HIT BOX:
MOV EAX, 01C1C0002H ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
JMP ENDSPAWNENEMY
SPAWNDISH:
;SET UP INITIAL VALUES
INC BYTE PTR [RDX] ;SET TO MODE 1
MOV BYTE PTR [RDX + 01H], 00H
MOV BYTE PTR [RDX + 02H], 026H ;SPRITE
MOV RAX, X
MOV BYTE PTR [RDX + 04H], AL
MOV RAX, Y
MOV BYTE PTR [RDX + 06H], AL
MOV RAX, Z
MOV BYTE PTR [RDX + 0CH], AL
MOV BYTE PTR [RDX + 0DH], 00H ;TIMER
;HIT BOX:
MOV EAX, 01A1A0202H ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
JMP ENDSPAWNENEMY
SPAWNMISSLEUP:
;SET UP INITIAL VALUES
MOV BYTE PTR [RDX], 075H ;DELAY, INVISIBLE, NO HIT, GO UP
MOV BYTE PTR [RDX + 01H], 00H
MOV BYTE PTR [RDX + 02H], 01CH ;SPRITE
MOV RAX, X
MOV BYTE PTR [RDX + 04H], AL
MOV RAX, Y
MOV BYTE PTR [RDX + 06H], AL
MOV RAX, Z
MOV BYTE PTR [RDX + 0CH], AL
MOV BYTE PTR [RDX + 0DH], 00H ;TIMER
;HIT BOX:
MOV EAX, 00A05030DH ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
JMP ENDSPAWNENEMY
SPAWNEBOLT:
;SET UP INITIAL VALUES
MOV BYTE PTR [RDX], 081H ;SET TO MODE 1 + FLY DOWN TRACK
MOV BYTE PTR [RDX + 01H], 00H
MOV BYTE PTR [RDX + 02H], 027H ;SPRITE
MOV RAX, X
MOV BYTE PTR [RDX + 04H], AL
MOV RAX, Y
MOV BYTE PTR [RDX + 06H], AL
MOV RAX, Z
MOV BYTE PTR [RDX + 0CH], AL
MOV BYTE PTR [RDX + 0DH], 00H ;TIMER
;HIT BOX:
MOV EAX, 004070F0BH ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
JMP ENDSPAWNENEMY
SPAWNMISSLE:
;SET UP INITIAL VALUES
MOV BYTE PTR [RDX], 081H ;SET TO MODE 1 + FLY DOWN TRACK
MOV BYTE PTR [RDX + 01H], 00H
MOV BYTE PTR [RDX + 02H], 01BH ;SPRITE
MOV RAX, X
MOV BYTE PTR [RDX + 04H], AL
MOV RAX, Y
MOV BYTE PTR [RDX + 06H], AL
MOV RAX, Z
MOV BYTE PTR [RDX + 0CH], AL
MOV BYTE PTR [RDX + 0DH], 00H ;TIMER
;HIT BOX:
MOV EAX, 008091201H ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
JMP ENDSPAWNENEMY
SPAWNSPRAY:
;SET UP INITIAL VALUES
MOV WORD PTR [RDX], 0241H ;SET TO MODE 1 + SKIP HITBOX CHECK + SHORT TIMER
MOV BYTE PTR [RDX + 02H], 029H ;SPRITE
MOV RAX, X
MOV BYTE PTR [RDX + 04H], AL
MOV RAX, Y
MOV BYTE PTR [RDX + 06H], AL
MOV RAX, Z
MOV BYTE PTR [RDX + 0CH], AL
MOV BYTE PTR [RDX + 0DH], 00H ;TIMER
;HIT BOX:
MOV EAX, 000000000H ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
JMP ENDSPAWNENEMY
SPAWNWALL:
;SET UP INITIAL VALUES
MOV WORD PTR [RDX], 01H ;SET TO MODE 1
MOV BYTE PTR [RDX + 02H], 021H ;SPRITE
MOV RAX, X
MOV BYTE PTR [RDX + 04H], AL
MOV RAX, Y
MOV BYTE PTR [RDX + 06H], AL
MOV RAX, Z
MOV BYTE PTR [RDX + 0CH], AL
MOV BYTE PTR [RDX + 0DH], 00H ;TIMER
;HIT BOX:
MOV EAX, 01A200300H ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
JMP ENDSPAWNENEMY
SPAWNWALL2:
;SET UP INITIAL VALUES
MOV WORD PTR [RDX], 01H ;SET TO MODE 1
MOV BYTE PTR [RDX + 02H], 022H ;SPRITE
MOV RAX, X
MOV BYTE PTR [RDX + 04H], AL
MOV RAX, Y
MOV BYTE PTR [RDX + 06H], AL
MOV RAX, Z
MOV BYTE PTR [RDX + 0CH], AL
MOV BYTE PTR [RDX + 0DH], 00H ;TIMER
;HIT BOX:
MOV EAX, 01A200300H ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
JMP ENDSPAWNENEMY
SPAWNGROUNDPLANE:
;SET UP INITIAL VALUES
INC BYTE PTR [RDX] ;SET TO MODE 1
MOV BYTE PTR [RDX + 01H], 00H
MOV BYTE PTR [RDX + 02H], 019H ;SPRITE
MOV RAX, X
MOV BYTE PTR [RDX + 04H], AL
MOV RAX, Y
MOV BYTE PTR [RDX + 06H], AL
MOV RAX, Z
MOV BYTE PTR [RDX + 0CH], AL
MOV BYTE PTR [RDX + 0DH], 00H ;TIMER
;HIT BOX:
MOV EAX, 00E190804H ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
JMP ENDSPAWNENEMY
SPAWNSPACEPLANE: ;THESE ARE SPAWNED TO AIM AT THE PLAYER
;SET UP INITIAL VALUES
MOV BYTE PTR [RDX], 081H ;SET TO MODE 1 + FLY DOWN
MOV BYTE PTR [RDX + 01H], 00H
MOV AL, 03H
SUB AL, BYTE PTR [SHIPALT] ;REVERSE ORDER
ADD AL, 011H ;BASE SPRITE
MOV BYTE PTR [RDX + 02H], AL ;SPRITE
LEA RBX, [SPRITES] ;FIRST SPRITE IS SHIP SPRITE
MOV AL, BYTE PTR [RBX + 04H] ;X
MOV BL, BYTE PTR [RBX + 06H] ;Y
DISTANCELOOP:
INC AL
INC AL
DEC BL
CMP AL, 0EDH
JB DISTANCELOOP
MOV BYTE PTR [RDX + 04H], AL
MOV BYTE PTR [RDX + 06H], BL
MOV AL, BYTE PTR [SHIPALT]
MOV BYTE PTR [RDX + 0CH], AL
MOV BYTE PTR [RDX + 0DH], 00H ;TIMER
;HIT BOX:
MOV EAX, 00E190804H ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
JMP ENDSPAWNENEMY
SPAWNBOSS:
;FOUR HIT BOXES
LEA RDX, QWORD PTR [ENEMY]
MOV WORD PTR [RDX], 01803H ;SET TO MODE 1 + 6 HIT POINTS
MOV BYTE PTR [RDX + 02H], 034H ;SPRITE
MOV RAX, X
MOV BYTE PTR [RDX + 04H], AL
MOV RAX, Y
MOV BYTE PTR [RDX + 06H], AL
MOV RAX, 0 ;0 ALTITUDE
MOV BYTE PTR [RDX + 0CH], AL
MOV BYTE PTR [RDX + 0DH], 00H ;TIMER
;HIT BOX:
MOV EAX, 032320707H ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
ADD RDX, ENEMYOBJSIZE
MOV BYTE PTR [RDX], 043H ;SET TO MODE + NO HITBOX CHECK
MOV BYTE PTR [RDX + 01H], 00H
MOV BYTE PTR [RDX + 02H], 035H ;SPRITE
MOV RAX, X
ADD RAX, 020H
MOV BYTE PTR [RDX + 04H], AL
MOV RAX, Y
MOV BYTE PTR [RDX + 06H], AL
MOV RAX, Z
MOV BYTE PTR [RDX + 0CH], AL
MOV BYTE PTR [RDX + 0DH], 00H ;TIMER
;HIT BOX:
MOV EAX, 000000000H ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
ADD RDX, ENEMYOBJSIZE
MOV BYTE PTR [RDX], 043H ;SET TO MODE + NO HITBOX CHECK
MOV BYTE PTR [RDX + 01H], 00H
MOV BYTE PTR [RDX + 02H], 036H ;SPRITE
MOV RAX, X
MOV BYTE PTR [RDX + 04H], AL
MOV RAX, Y
ADD RAX, 020H
MOV BYTE PTR [RDX + 06H], AL
MOV RAX, Z
DEC RAX
MOV BYTE PTR [RDX + 0CH], AL
MOV BYTE PTR [RDX + 0DH], 00H ;TIMER
;HIT BOX:
MOV EAX, 000000000H ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
ADD RDX, ENEMYOBJSIZE
MOV BYTE PTR [RDX], 043H ;SET TO MODE + NO HITBOX CHECK
MOV BYTE PTR [RDX + 01H], 00H
MOV BYTE PTR [RDX + 02H], 037H ;SPRITE
MOV RAX, X
ADD RAX, 020H
MOV BYTE PTR [RDX + 04H], AL
MOV RAX, Y
ADD RAX, 020H
MOV BYTE PTR [RDX + 06H], AL
MOV RAX, Z
DEC RAX
MOV BYTE PTR [RDX + 0CH], AL
MOV BYTE PTR [RDX + 0DH], 00H ;TIMER
;HIT BOX:
MOV EAX, 000000000H ;HWYX
MOV DWORD PTR [RDX + 08H], EAX ;HITBOX
JMP ENDSPAWNENEMY
ENDSPAWNENEMY:
ENDM
LOADINNEXTSECTIONOFMAP MACRO
;SCREEN READJUSTED ALREADY, CLEAN TO STORE AT TOP AND SIDE OF SCREEN
;GAMEMAPOFFSET ALREADY AT PROPER GAMEMAP OFFSET
LOCAL TILESTOPLOOP
LOCAL TILESSIDELOOP
LEA RBX, QWORD PTR [TILEMAP0]
ADD RBX, 022H
LEA RDX, QWORD PTR [tilemap]
ADD RDX, GAMEMAPOFFSET
XOR R8, R8
MOV RCX, 0FH
;COPY 15 TILES TO TOP RIGHT OF GAME AREA
;X: 14, Y:0
TILESTOPLOOP:
MOV AX, WORD PTR [RDX + R8] ;TAKE FROM DATA TILE MAP
MOV WORD PTR [RBX], AX ;PLACE IN VRAM TILE MAP
INC RBX
INC RBX
INC R8
INC R8
LOOP TILESTOPLOOP
;ADD 38 MORE TILES TO SIDE (2 PER ROW)
ADD RBX, 03CH
MOV RCX, 00H
TILESSIDELOOP:
MOV AX, WORD PTR [RDX + R8] ;TAKE FROM DATA TILE MAP
MOV WORD PTR [RBX], AX ;PLACE IN VRAM TILE MAP
INC RBX
INC RBX
INC R8
INC R8
INC RCX
TEST RCX, 01H
JNZ TILESSIDELOOP
;INCREASE DESTINATION BY 30 TILES
ADD RBX, 03CH
CMP RCX, 026H
JNZ TILESSIDELOOP
ADD R8, GAMEMAPOFFSET
MOV GAMEMAPOFFSET, R8
ENDM
COLUMNTICKEVENTS MACRO
;EVENTS RELATED TO SCROLLING MAP TRIGGERED AT CERTAIN COLUMNS
;INCLUDING: SHIP SHADOW ON/OFF, SPAWN ENEMIES, &C.
;EVENTS BROKEN UP BY STAGE
LOCAL STAGE1EVENTS
LOCAL STAGE2EVENTS
LOCAL STAGE3EVENTS
LOCAL ENDCOLUMNTICKEVENTS
MOV RAX, COLUMNTICK
MOV RBX, STAGE
CMP RBX, 02H
JZ STAGE3EVENTS
CMP RBX, 01H
JZ STAGE2EVENTS
JMP STAGE1EVENTS
;COULD BE REDESIGNED INTO A JUMP TABLE FOR QUICKER ACCESS
;FROM SIDE TO NEW TILES IS 128px
STAGE3EVENTS: ;2ND FLYOVER AREA
S3E1:
CMP RAX, 0A8H
JNZ S3E2
MOV R8, 01H ;SPAWN ENTRY WALLS
SPAWNENEMY 50, 0, 0
JMP ENDCOLUMNTICKEVENTS
S3E2:
CMP RAX, 0ACH
JNZ S3E3
MOV HIDESHADOW, 01H ;HIDE SHADOW
JMP ENDCOLUMNTICKEVENTS
S3E3:
CMP RAX, 0B2H
JNZ S3E4
MOV HIDESHADOW, 00H ;UNHIDE SHADOW
MOV R8, 026H ;SPAWN DISH
SPAWNENEMY 229, 104, 0
JMP ENDCOLUMNTICKEVENTS
S3E4:
CMP RAX, 0AAH
JNZ S3E5
MOV R8, 025H ;TANKER
SPAWNENEMY 221, 56, 0
JMP ENDCOLUMNTICKEVENTS
S3E5:
CMP RAX, 0A4H
JNZ S3E6
MOV R8, 022H ;WALL
SPAWNENEMY 229, 32, 3
JMP ENDCOLUMNTICKEVENTS
S3E6:
CMP RAX, 0A5H
JNZ S3E7
MOV R8, 022H ;WALL
SPAWNENEMY 237, 51, 3
JMP ENDCOLUMNTICKEVENTS
S3E7:
CMP RAX, 0AFH
JNZ S3E8
MOV R8, 024H ;SIDE TURRENT
SPAWNENEMY 226, 110, 0
JMP ENDCOLUMNTICKEVENTS
S3E8:
CMP RAX, 0ADH
JNZ S3E9
MOV R8, 023H ;FRONT TURRENT
SPAWNENEMY 222, 25, 0
JMP ENDCOLUMNTICKEVENTS
S3E9:
CMP RAX, 0B0H
JNZ S3E10
MOV R8, 025H ;TANKER
SPAWNENEMY 229, 72, 0
JMP ENDCOLUMNTICKEVENTS
S3E10:
CMP RAX, 0B1H
JNZ S3E12
MOV R8, 021H ;WALL
SPAWNENEMY 205, 4, 1
JMP ENDCOLUMNTICKEVENTS
S3E12:
CMP RAX, 0B5H
JNZ S3E13_25
MOV R8, 022H ;WALL
SPAWNENEMY 237, 83, 1
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 221, 52, 0
JMP ENDCOLUMNTICKEVENTS
S3E13_25:
CMP RAX, 0B8H
JNZ S3E13_5
MOV R8, 03H ;LOW WALLS
SPAWNENEMY 0, 0, 0
JMP ENDCOLUMNTICKEVENTS
S3E13_5:
CMP RAX, 0BCH
JNZ S3E13
MOV HIDESHADOW, 01H ;HIDE SHADOW
JMP ENDCOLUMNTICKEVENTS
S3E13:
CMP RAX, 0BDH
JNZ S3E14
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 229, 95, 0
JMP ENDCOLUMNTICKEVENTS
S3E14:
CMP RAX, 0BBH
JNZ S3E15
MOV R8, 025H ;TANKER
SPAWNENEMY 238, 51, 0
JMP ENDCOLUMNTICKEVENTS
S3E15:
CMP RAX, 0BEH
JNZ S3E16
MOV R8, 025H ;TANKER
SPAWNENEMY 225, 57, 0
MOV R8, 023H ;FRONT TURRENT
SPAWNENEMY 228, 26, 0
JMP ENDCOLUMNTICKEVENTS
S3E16:
CMP RAX, 0C0H
JNZ S3E17
MOV R8, 025H ;TANKER
SPAWNENEMY 229, 55, 0
JMP ENDCOLUMNTICKEVENTS
S3E17:
CMP RAX, 0C2H
JNZ S3E18
MOV R8, 023H ;FRONT TURRENT
SPAWNENEMY 226, 91, 0
MOV HIDESHADOW, 00H ;UNHIDE SHADOW
JMP ENDCOLUMNTICKEVENTS
S3E18:
CMP RAX, 0C5H
JNZ S3E19
MOV R8, 022H ;WALL
SPAWNENEMY 229, 48, 2
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 213, 16, 0
JMP ENDCOLUMNTICKEVENTS
S3E19:
CMP RAX, 0C7H
JNZ S3E20
MOV R8, 022H ;WALL
SPAWNENEMY 223, 76, 2
JMP ENDCOLUMNTICKEVENTS
S3E20:
CMP RAX, 0C9H
JNZ S3E21
MOV R8, 02H ;MEDIUM WALLS
SPAWNENEMY 0, 0, 0
MOV R8, 025H ;TANKER
SPAWNENEMY 233, 29, 0
JMP ENDCOLUMNTICKEVENTS
S3E21:
CMP RAX, 0CDH
JNZ S3E22
MOV HIDESHADOW, 01H ;HIDE SHADOW
JMP ENDCOLUMNTICKEVENTS
S3E22:
CMP RAX, 0D3H
JNZ S3E23
MOV HIDESHADOW, 00H ;UNHIDE SHADOW
JMP ENDCOLUMNTICKEVENTS
S3E23:
CMP RAX, 0CBH
JNZ S3E24
MOV R8, 025H ;TANKER
SPAWNENEMY 237, 59, 0
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 229, 80, 0
JMP ENDCOLUMNTICKEVENTS
S3E24:
CMP RAX, 0CEH
JNZ S3E25
MOV R8, 025H ;TANKER
SPAWNENEMY 229, 87, 0
JMP ENDCOLUMNTICKEVENTS
S3E25:
CMP RAX, 0CCH
JNZ S3E26
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 238, 28, 0
JMP ENDCOLUMNTICKEVENTS
S3E26:
CMP RAX, 0D1H
JNZ S3E27
MOV R8, 024H ;SIDE TURRENT
SPAWNENEMY 226, 110, 0
JMP ENDCOLUMNTICKEVENTS
S3E27:
CMP RAX, 0CFH
JNZ S3E28
MOV R8, 022H ;WALL
SPAWNENEMY 229, 8, 0
JMP ENDCOLUMNTICKEVENTS
S3E28:
CMP RAX, 0D0H
JNZ S3E29
MOV R8, 021H ;WALL
SPAWNENEMY 237, 28, 0
JMP ENDCOLUMNTICKEVENTS
S3E29:
CMP RAX, 0D5H
JNZ S3E30
MOV R8, 022H ;WALL
SPAWNENEMY 229, 104, 0
MOV R8, 023H ;FRONT TURRENT
SPAWNENEMY 232, 24, 0
JMP ENDCOLUMNTICKEVENTS
S3E30:
CMP RAX, 0D2H
JNZ S3E31
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 237, 12, 0
JMP ENDCOLUMNTICKEVENTS
S3E31:
CMP RAX, 0D8H
JNZ S3E32
MOV R8, 025H ;TANKER
SPAWNENEMY 233, 17, 0
JMP ENDCOLUMNTICKEVENTS
S3E32:
CMP RAX, 0DBH
JNZ S3E33_5
MOV R8, 023H ;FRONT TURRENT
SPAWNENEMY 236, 100, 0
MOV HIDESHADOW, 01H ;HIDE SHADOW
JMP ENDCOLUMNTICKEVENTS
S3E33_5:
CMP RAX, 0DCH
JNZ S3E33
JMP ENDCOLUMNTICKEVENTS
S3E33:
CMP RAX, 0DDH
JNZ S3E34
MOV R8, 025H ;TANKER
SPAWNENEMY 229, 47, 0
JMP ENDCOLUMNTICKEVENTS
S3E34:
CMP RAX, 0DFH
JNZ S3E35
MOV R8, 026H ;SPAWN DISH
SPAWNENEMY 238, 108, 0
MOV HIDESHADOW, 00H ;UNHIDE SHADOW
JMP ENDCOLUMNTICKEVENTS
S3E35:
CMP RAX, 0E0H
JNZ S3E36
MOV R8, 023H ;FRONT TURRENT
SPAWNENEMY 234, 75, 0
JMP ENDCOLUMNTICKEVENTS
S3E36:
CMP RAX, 0E1H
JNZ S3E37
MOV R8, 021H ;WALL
SPAWNENEMY 205, 4, 1
JMP ENDCOLUMNTICKEVENTS
S3E37:
CMP RAX, 0E4H
JNZ S3E38
MOV R8, 022H ;WALL
SPAWNENEMY 229, 64, 1
JMP ENDCOLUMNTICKEVENTS
S3E38:
CMP RAX, 0E5H
JNZ S3E39
MOV R8, 022H ;WALL
SPAWNENEMY 238, 84, 1
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 222, 51, 0
MOV R8, 025H ;TANKER
SPAWNENEMY 237, 15, 0
JMP ENDCOLUMNTICKEVENTS
S3E39:
CMP RAX, 0E8H
JNZ S3E48
MOV R8, 03H ;LOW WALLS
SPAWNENEMY 0, 0, 0
JMP ENDCOLUMNTICKEVENTS
S3E48:
CMP RAX, 0EBH
JNZ S3E49
MOV HIDESHADOW, 01H ;HIDE SHADOW
JMP ENDCOLUMNTICKEVENTS
S3E49:
CMP RAX, 0F8H
JNZ S3E50
MOV PAUSESCROLL, 01H ;PAUSE SCROLL
MOV R8, 04H ;BOSS
SPAWNENEMY 172, 66, 2
JMP ENDCOLUMNTICKEVENTS
S3E50:
CMP RAX, 0F2H
JNZ S3E51
MOV HIDESHADOW, 00H ;UNHIDE SHADOW
JMP ENDCOLUMNTICKEVENTS
S3E51:
JMP ENDCOLUMNTICKEVENTS
STAGE2EVENTS: ;SPACE EVENTS
S2E1:
CMP RAX, 072H
JNZ S2E2
MOV HIDESHADOW, 01H ;TURN SHADOW OFF
JMP ENDCOLUMNTICKEVENTS
S2E2:
CMP RAX, 070H
JNZ S2E3
MOV R8, 011H ;TARGETED SPACE PLANE
SPAWNENEMY 0, 0, 0
JMP ENDCOLUMNTICKEVENTS
S2E3:
CMP RAX, 070H
JNZ S2E4
MOV R8, 011H ;TARGETED SPACE PLANE
SPAWNENEMY 0, 0, 0
JMP ENDCOLUMNTICKEVENTS
S2E4:
CMP RAX, 074H
JNZ S2E5
MOV R8, 011H ;TARGETED SPACE PLANE
SPAWNENEMY 0, 0, 0
JMP ENDCOLUMNTICKEVENTS
S2E5:
CMP RAX, 078H
JNZ S2E6
MOV R8, 011H ;TARGETED SPACE PLANE
SPAWNENEMY 0, 0, 0
JMP ENDCOLUMNTICKEVENTS
S2E6:
CMP RAX, 07CH
JNZ S2E7
MOV R8, 011H ;TARGETED SPACE PLANE
SPAWNENEMY 0, 0, 0
JMP ENDCOLUMNTICKEVENTS
S2E7:
CMP RAX, 080H
JNZ S2E8
MOV R8, 011H ;TARGETED SPACE PLANE
SPAWNENEMY 0, 0, 0
JMP ENDCOLUMNTICKEVENTS
S2E8:
CMP RAX, 084H
JNZ S2E9
MOV R8, 011H ;TARGETED SPACE PLANE
SPAWNENEMY 0, 0, 0
JMP ENDCOLUMNTICKEVENTS
S2E9:
CMP RAX, 088H
JNZ S2E10
MOV R8, 011H ;TARGETED SPACE PLANE
SPAWNENEMY 0, 0, 0
JMP ENDCOLUMNTICKEVENTS
S2E10:
CMP RAX, 08CH
JNZ S2E11
MOV R8, 011H ;TARGETED SPACE PLANE
SPAWNENEMY 0, 0, 0
JMP ENDCOLUMNTICKEVENTS
S2E11:
CMP RAX, 090H
JNZ S2E12
MOV R8, 011H ;TARGETED SPACE PLANE
SPAWNENEMY 0, 0, 0
JMP ENDCOLUMNTICKEVENTS
S2E12:
CMP RAX, 094H
JNZ S2E13
MOV R8, 011H ;TARGETED SPACE PLANE
SPAWNENEMY 0, 0, 0
JMP ENDCOLUMNTICKEVENTS
S2E13:
CMP RAX, 09CH
JNZ ENDCOLUMNTICKEVENTS
MOV HIDESHADOW, 00H ;TURN SHADOW BACK ON
INC STAGE ;MOVE TO NEXT STAGE
JMP ENDCOLUMNTICKEVENTS
JMP ENDCOLUMNTICKEVENTS
STAGE1EVENTS: ;1ST FLYOVER AREA
S1E0: ;TURN SHADOW OFF FOR WALL FLYOVER + FRONT TURRENT
CMP RAX, 09H
JNZ S1E1
MOV HIDESHADOW, 01H
MOV R8, 023H ;SPAWN FRONT FACING TURRENT
SPAWNENEMY 239, 40, 0
JMP ENDCOLUMNTICKEVENTS
S1E1: ;TURN ON SHADOW AFTER WALL FLYOVER
CMP RAX, 0FH
JNZ S1E2
MOV HIDESHADOW, 00H
JMP ENDCOLUMNTICKEVENTS
S1E2:
CMP RAX, 0BH
JNZ S1E3
MOV R8, 026H ;SPAWN DISH
SPAWNENEMY 218, 112, 0
JMP ENDCOLUMNTICKEVENTS
S1E3: ;SPAWNING WALL OF ENEMIES IN FRONT
CMP RAX, 05H
JNZ S1E4
MOV R8, 01H ;SPAWN ENTRY WALLS
SPAWNENEMY 50, 0, 0
JMP ENDCOLUMNTICKEVENTS
S1E4: ;SPAWNING SIDE TURRENT
CMP RAX, 0EH
JNZ S1E5
MOV R8, 024H ;SIDE TURRENT
SPAWNENEMY 216, 116, 0
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 230, 25, 0
JMP ENDCOLUMNTICKEVENTS
S1E5: ;SPAWN TANKER
CMP RAX, 011H
JNZ S1E6
MOV R8, 025H ;TANKER
SPAWNENEMY 217, 30, 0
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 197, 86, 0
JMP ENDCOLUMNTICKEVENTS
S1E6: ;SPAWN UP MISSLE
CMP RAX, 07H
JNZ S1E7
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 229, 60, 0
JMP ENDCOLUMNTICKEVENTS
S1E7: ;SPAWN UP MISSLE
CMP RAX, 0DH
JNZ S1E8
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 221, 30, 0
JMP ENDCOLUMNTICKEVENTS
S1E8:
CMP RAX, 012H
JNZ S1E9
MOV R8, 025H ;TANKER
SPAWNENEMY 217, 70, 0
JMP ENDCOLUMNTICKEVENTS
S1E9:
CMP RAX, 015H
JNZ S1E10
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 200, 128, 0
JMP ENDCOLUMNTICKEVENTS
S1E10:
CMP RAX, 017H
JNZ S1E11
MOV R8, 025H ;TANKER
SPAWNENEMY 225, 114, 0
MOV R8, 022H ;WALL
SPAWNENEMY 229, 61, 0
JMP ENDCOLUMNTICKEVENTS
S1E11:
CMP RAX, 018H
JNZ S1E12
MOV R8, 022H ;WALL
SPAWNENEMY 237, 81, 0
JMP ENDCOLUMNTICKEVENTS
S1E12:
CMP RAX, 01AH
JNZ S1E13
MOV R8, 024H ;SIDE TURRENT
SPAWNENEMY 226, 66, 0
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 198, 28, 0
MOV R8, 022H ;LAST WALL
SPAWNENEMY 229, 108, 0
S1E13:
CMP RAX, 01DH
JNZ S1E14
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 214, 94, 0
JMP ENDCOLUMNTICKEVENTS
S1E14:
CMP RAX, 01EH
JNZ S1E15
MOV R8, 025H ;TANKER
SPAWNENEMY 220, 26, 0
JMP ENDCOLUMNTICKEVENTS
S1E15:
CMP RAX, 01FH
JNZ S1E16
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 230, 74, 0
JMP ENDCOLUMNTICKEVENTS
S1E16:
CMP RAX, 020H
JNZ S1E17
MOV R8, 025H ;TANKER
SPAWNENEMY 232, 110, 0
JMP ENDCOLUMNTICKEVENTS
S1E17:
CMP RAX, 021H
JNZ S1E18
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 230, 52, 0
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 238, 80, 0
JMP ENDCOLUMNTICKEVENTS
S1E18:
CMP RAX, 022H
JNZ S1E19
MOV R8, 024H ;SIDE TURRENT
SPAWNENEMY 236, 112, 0
JMP ENDCOLUMNTICKEVENTS
S1E19:
CMP RAX, 023H
JNZ S1E20
MOV R8, 025H ;TANKER
SPAWNENEMY 229, 48, 0
JMP ENDCOLUMNTICKEVENTS
S1E20:
CMP RAX, 026H
JNZ S1E21
MOV R8, 023H ;SPAWN FRONT FACING TURRENT
SPAWNENEMY 231, 86, 0
JMP ENDCOLUMNTICKEVENTS
S1E21:
CMP RAX, 027H
JNZ S1E22
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 230, 22, 0
JMP ENDCOLUMNTICKEVENTS
S1E22:
CMP RAX, 028H
JNZ S1E23
MOV R8, 023H ;SPAWN FRONT FACING TURRENT
SPAWNENEMY 235, 115, 0
JMP ENDCOLUMNTICKEVENTS
S1E23:
CMP RAX, 029H
JNZ S1E24
MOV R8, 025H ;TANKER
SPAWNENEMY 229, 20, 0
JMP ENDCOLUMNTICKEVENTS
S1E24:
CMP RAX, 02BH
JNZ S1E25
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 230, 115, 0
JMP ENDCOLUMNTICKEVENTS
S1E25:
CMP RAX, 02DH
JNZ S1E26
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 222, 79, 0
MOV R8, 022H ;WALL
SPAWNENEMY 229, 11, 0
JMP ENDCOLUMNTICKEVENTS
S1E26:
CMP RAX, 02EH
JNZ S1E27
MOV R8, 022H ;WALL
SPAWNENEMY 237, 31, 0
JMP ENDCOLUMNTICKEVENTS
S1E27:
CMP RAX, 030H
JNZ S1E28
MOV R8, 021H ;LAST WALL
SPAWNENEMY 229, 60, 0
JMP ENDCOLUMNTICKEVENTS
S1E28:
CMP RAX, 032H
JNZ S1E29
MOV R8, 023H ;SPAWN FRONT FACING TURRENT
SPAWNENEMY 227, 107, 0
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 221, 80, 0
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 221, 40, 0
JMP ENDCOLUMNTICKEVENTS
S1E29:
CMP RAX, 035H
JNZ S1E30
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 230, 123, 0
JMP ENDCOLUMNTICKEVENTS
S1E30:
CMP RAX, 037H
JNZ S1E31
MOV R8, 023H ;SPAWN FRONT FACING TURRENT
SPAWNENEMY 218, 25, 0
JMP ENDCOLUMNTICKEVENTS
S1E31:
CMP RAX, 03AH
JNZ S1E32
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 237, 97, 0
JMP ENDCOLUMNTICKEVENTS
S1E32:
CMP RAX, 03CH
JNZ S1E33
MOV R8, 019H ;GROUND PLANE
SPAWNENEMY 233, 105, 0
MOV R8, 019H ;GROUND PLANE
SPAWNENEMY 224, 55, 0
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 238, 69, 0
JMP ENDCOLUMNTICKEVENTS
S1E33:
CMP RAX, 03DH
JNZ S1E34
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 237, 70, 0
JMP ENDCOLUMNTICKEVENTS
S1E34:
CMP RAX, 040H
JNZ S1E35
MOV R8, 025H ;TANKER
SPAWNENEMY 229, 100, 0
JMP ENDCOLUMNTICKEVENTS
S1E35:
CMP RAX, 042H
JNZ S1E36
MOV R8, 025H ;TANKER
SPAWNENEMY 237, 68, 0
JMP ENDCOLUMNTICKEVENTS
S1E36:
CMP RAX, 045H
JNZ S1E37
MOV R8, 023H ;SPAWN FRONT FACING TURRENT
SPAWNENEMY 217, 130, 0
JMP ENDCOLUMNTICKEVENTS
S1E37:
CMP RAX, 046H
JNZ S1E38
MOV R8, 026H ;SPAWN DISH
SPAWNENEMY 229, 45, 0
MOV R8, 023H ;SPAWN FRONT FACING TURRENT
SPAWNENEMY 225, 21, 0
JMP ENDCOLUMNTICKEVENTS
S1E38:
CMP RAX, 048H
JNZ S1E39
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 238, 20, 0
JMP ENDCOLUMNTICKEVENTS
S1E39:
CMP RAX, 049H
JNZ S1E40
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 230, 73, 0
JMP ENDCOLUMNTICKEVENTS
S1E40:
CMP RAX, 04AH
JNZ S1E41
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 238, 70, 0
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 238, 100, 0
JMP ENDCOLUMNTICKEVENTS
S1E41:
CMP RAX, 04CH
JNZ S1E42
MOV R8, 025H ;TANKER
SPAWNENEMY 238, 68, 0
MOV R8, 023H ;SPAWN FRONT FACING TURRENT
SPAWNENEMY 233, 20, 0
JMP ENDCOLUMNTICKEVENTS
S1E42:
CMP RAX, 04EH
JNZ S1E43
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 237, 43, 0
JMP ENDCOLUMNTICKEVENTS
S1E43:
CMP RAX, 050H
JNZ S1E44
MOV R8, 019H ;GROUND PLANE
SPAWNENEMY 231, 51, 0
JMP ENDCOLUMNTICKEVENTS
S1E44:
CMP RAX, 051H
JNZ S1E45
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 237, 70, 0
JMP ENDCOLUMNTICKEVENTS
S1E45:
CMP RAX, 052H
JNZ S1E46
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 228, 102, 0
JMP ENDCOLUMNTICKEVENTS
S1E46:
CMP RAX, 053H
JNZ S1E47
MOV R8, 019H ;GROUND PLANE
SPAWNENEMY 235, 25, 0
JMP ENDCOLUMNTICKEVENTS
S1E47:
CMP RAX, 055H
JNZ S1E48
MOV R8, 023H ;SPAWN FRONT FACING TURRENT
SPAWNENEMY 233, 112, 0
MOV R8, 019H ;GROUND PLANE
SPAWNENEMY 228, 52, 0
JMP ENDCOLUMNTICKEVENTS
S1E48:
S1E49:
CMP RAX, 05AH
JNZ S1E50
MOV R8, 025H ;TANKER
SPAWNENEMY 229, 92, 0
JMP ENDCOLUMNTICKEVENTS
S1E50:
CMP RAX, 05BH
JNZ S1E51
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 230, 38, 0
JMP ENDCOLUMNTICKEVENTS
S1E51:
CMP RAX, 05DH
JNZ S1E52
MOV R8, 01CH ;UP MISSLE
SPAWNENEMY 229, 92, 0
JMP ENDCOLUMNTICKEVENTS
S1E52:
CMP RAX, 05FH
JNZ S1E53
MOV R8, 025H ;TANKER
SPAWNENEMY 225, 82, 0
JMP ENDCOLUMNTICKEVENTS
S1E53:
CMP RAX, 061H
JNZ S1E54
MOV R8, 026H ;SPAWN DISH
SPAWNENEMY 221, 113, 0
JMP ENDCOLUMNTICKEVENTS
S1E54:
CMP RAX, 065H
JNZ S1E55
MOV R8, 01H ;SPAWN ENTRY WALLS
SPAWNENEMY 50, 0, 0
JMP ENDCOLUMNTICKEVENTS
S1E55:
CMP RAX, 069H
JNZ S1E56
MOV HIDESHADOW, 01H ;TURN SHADOW OFF
JMP ENDCOLUMNTICKEVENTS
S1E56:
CMP RAX, 06FH
JNZ ENDCOLUMNTICKEVENTS
MOV HIDESHADOW, 00H ;TURN SHADOW BACK ON
INC STAGE ;MOVE TO NEXT STAGE
JMP ENDCOLUMNTICKEVENTS
ENDCOLUMNTICKEVENTS:
ENDM
MOVEBACKGROUND MACRO
;MOVE BACKGROUND LAYER 0 OVER 16, DOWN 8
;SHIFT LAYER ROWS TO DO SO
;THEN AFTER THE SHIFT IS FINISHED:
;COPY ALL ROWS DOWN 1, AND OVER 2 TILES
;RESET SHIFTS
;LOAD IN NEW EDGE TILES
LOCAL JUSTXSCROLL
LOCAL MOVEDOWN1SIDE2
LOCAL PUSHSCROLL
LOCAL ENEMIESBACKGROUNDSCROLL
LOCAL NEXTEBGSCROLL
LOCAL ENDMOVEBACKGROUND
;CHECK STAGE
MOV RAX, STAGE
CMP RAX, 02H
JA ENDMOVEBACKGROUND
MOV RAX, PAUSESCROLL
CMP RAX, 00H
JNZ ENDMOVEBACKGROUND
;CHECK FRAMERULE
INC SCROLLFRAMERULEC
MOV RAX, SCROLLFRAMERULEC
CMP RAX, SCROLLFRAMERULE
JNZ ENDMOVEBACKGROUND
XOR RAX, RAX
MOV SCROLLFRAMERULEC, RAX
;TESTING TO SHOW OFF:
INC SCROLLTIMER
MOV RAX, SCROLLTIMER
TEST RAX, 01H
JNZ JUSTXSCROLL
INC SCROLLY
JUSTXSCROLL:
INC SCROLLX
MOV RAX, SCROLLX
CMP RAX, 010H
JNZ PUSHSCROLL
;INCREASE COLUMN TICK COUNT
INC COLUMNTICK
COLUMNTICKEVENTS
;RETILE TILE MAP 0
LEA RBX, QWORD PTR [TILEMAP0]
MOV R8, 07BEH ;SOURCE OFFSET FROM RBX
MOV RDX, 07FAH ;DESTINATION OFFSET FROM RBX
XOR R9, R9
MOV RCX, 01FH
MOVEDOWN1SIDE2:
MOV AX, WORD PTR [RBX + R8]
MOV WORD PTR [RBX + RDX], AX
DEC R8
DEC R8
DEC RDX
DEC RDX
INC R9
CMP R9, 01EH
JNZ MOVEDOWN1SIDE2
;ELSE DECREASE R8 & RDX BY FOUR
SUB R8, 04H
SUB RDX, 04H
XOR R9, R9
LOOP MOVEDOWN1SIDE2
;RESET SCROLL
XOR RAX, RAX
MOV SCROLLX, RAX
MOV SCROLLY, RAX
;LOAD NEW SECTION:
LOADINNEXTSECTIONOFMAP
PUSHSCROLL:
MOV RAX, 0100H
SUB RAX, SCROLLX
MOV BYTE PTR [TM0XOFFSET], AL
MOV RAX, SCROLLY
MOV BYTE PTR [TM0YOFFSET], AL
;COMPARE TO LAST SCROLL:
MOV RAX, SCROLLX
CMP RAX, LASTSCROLLX
JZ ENDMOVEBACKGROUND ;IF SAME, NO NEED TO UPDATE ENEMIES
;ELSE MOVE ENEMIES ALONG WITH THE BACKGROUND
MOV RCX, SCROLLY
XOR RCX, LASTSCROOLY
AND RCX, 01H ;INCREASE Y IF NOT THE SAME
MOV RDX, 01H
SHL RDX, CL ;2 IF MOVED Y, 1 IF DIDN'T MOVE Y (USED FOR FASTER SPEED OBJECTS)
MOV R8, RDX
MOV R9, 01H ;ALWAYS DECREASE X
MOV RCX, NUMBEROFENEMY
LEA RBX, QWORD PTR [ENEMY]
ENEMIESBACKGROUNDSCROLL:
PUSH RCX
MOV AL, BYTE PTR [RBX]
CMP AL, 00H
JZ NEXTEBGSCROLL ;NOT ACTIVE
TEST AL, 02H ;NON-SCROLL EFFECT BIT
JNZ NEXTEBGSCROLL
;FOR FASTER SCROLL:
MOV R10, QWORD PTR [RBX] ;MODE
AND R10, 080H ;EXTRA SPEED BIT
SHR R10, 06H
;SCROLL X AND Y
MOV RDX, R8
MOV RCX, R10
SHL RDX, CL ;MULTIPLY NUMBER OF TIMES IN R10 FOR SPEED (DEFUALT IS 0)
SHR RDX, 01H ;DIVIDE BY TWO
MOV AL, BYTE PTR [RBX + 06H] ;Y
ADD AL, DL
MOV BYTE PTR [RBX + 06H], AL
MOV AL, BYTE PTR [RBX + 04H] ;X
MOV RDX, R9
SHL RDX, CL
SUB AL, DL ;ALWAYS DECREASE
MOV BYTE PTR [RBX + 04H], AL
;DESPAWN WHEN X = 240
CMP AL, 0F0H
JB NEXTEBGSCROLL
;DESPAWN
XOR RAX, RAX
MOV WORD PTR [RBX], AX
NEXTEBGSCROLL:
POP RCX
ADD RBX, ENEMYOBJSIZE
LOOP ENEMIESBACKGROUNDSCROLL
;AND MOVE MODE 2 BOLTS
MOV RDX, SCROLLY
XOR RDX, LASTSCROOLY
AND RDX, 01H ;INCREASE Y IF NOT THE SAME
MOV RCX, 08H
LEA RBX, QWORD PTR [BOLTS]
BOLTSBACKGROUNDSCROLL:
MOV AL, BYTE PTR [RBX]
CMP AL, 02H
JNZ NEXTBBGSCROLL ;ONLY MODE 2 BOLTS
;SCROLL X AND Y
MOV AL, BYTE PTR [RBX + 06H] ;Y
ADD AL, DL
MOV BYTE PTR [RBX + 06H], AL
MOV AL, BYTE PTR [RBX + 04H] ;X
DEC AL ;ALWAYS DECREASE
MOV BYTE PTR [RBX + 04H], AL
;DESPAWN WHEN X = 240
CMP AL, 0F0H
JNZ NEXTBBGSCROLL
;DESPAWN
XOR AL, AL
MOV BYTE PTR [RBX], AL
NEXTBBGSCROLL:
ADD RBX, ENEMYOBJSIZE
LOOP BOLTSBACKGROUNDSCROLL
ENDMOVEBACKGROUND:
;STORE LAST SCROLL
MOV RAX, SCROLLX
MOV LASTSCROLLX, RAX
MOV RAX, SCROLLY
MOV LASTSCROOLY, RAX
ENDM
ENEMYLOGIC MACRO
LOCAL ENEMYLOGICLOOP
LOCAL NEXTENEMYLOGIC
LOCAL EXPLODEENEMYANIMATION
LOCAL DEADENEMY
LOCAL ENDENEMYLOGIC
INC ELOGICFRAMERULEC
MOV RAX, ELOGICFRAMERULEC
CMP RAX, ELOGICFRAMERULE
JNZ ENDENEMYLOGIC
XOR RAX, RAX
MOV ELOGICFRAMERULEC, RAX
MOV RCX, 00H
LEA RBX, QWORD PTR [ENEMY]
ENEMYLOGICLOOP:
XOR RAX, RAX
MOV AL, BYTE PTR [RBX] ;MODE
CMP AL, 00H
JZ NEXTENEMYLOGIC
;CHECK FOR EXPLOSION TIMER
MOV AL, BYTE PTR [RBX + 01H] ;MODE HIGH BYTE
TEST AL, 01H ;EXPLOSION TIMER
JZ CHECKFORLANDTANKS
;CHECK FUEL TANKS:
MOV AL, BYTE PTR [RBX + 02H] ;SPRITE
CMP AL, 025H
JNZ EXPLODEENEMYANIMATION
;THIS WILL ONLY OCCUR ONCE SINCE THE SPRITE IS ABOUT TO BE CHANGED
;INCREASE SHIP'S FUEL
MOV AL, BYTE PTR [SHIPFUEL]
ADD AX, BONUSFUEL
CMP AX, 0100H
JA FULLFUEL
MOV BYTE PTR [SHIPFUEL], AL
JMP EXPLODEENEMYANIMATION
FULLFUEL:
MOV BYTE PTR [SHIPFUEL], 0FFH
EXPLODEENEMYANIMATION:
;INCREASE SPRITES ACCORDING TO TIMER
MOV AL, BYTE PTR [RBX + 0DH] ;TIMER
INC AL
CMP AL, 030 ;MAX TIME
JA DEADENEMY
SHR AL, 03H ;/8
AND AL, 01H
ADD AL, 02FH
MOV BYTE PTR [RBX + 02H], AL ;SPRITE
;INCREASE TIMER
INC BYTE PTR [RBX + 0DH] ;TIMER
JMP NEXTENEMYLOGIC
CHECKFORLANDTANKS:
MOV AL, BYTE PTR [RBX + 02H] ;SPRITE
CMP AL, 023H ;LAND TANK SPRITE
JNZ CHECKENEMYDELAY
;RANDOM FIRE ENEMY MISSLES (027H) AT PLAYER
RNG ;FILL RAX WITH RANDOM VARIABLE
AND RAX, 03FH
CMP RAX, 03FH
JNZ NEXTENEMYLOGIC
;SPAWN MISSLE
PUSH RBX
PUSH RCX
XOR RAX, RAX
MOV AL, BYTE PTR [RBX + 04H] ;X
SUB AL, 018H
MOV R10, RAX ;DEST X
MOV AL, BYTE PTR [RBX + 06H] ;Y
ADD AL, 09H
MOV R11, RAX ;DEST Y
MOV R8, 027H ;SPAWN MISSLE
SPAWNENEMY R10, R11, 0
POP RCX
POP RBX
JMP NEXTENEMYLOGIC
CHECKENEMYDELAY:
MOV AL, BYTE PTR [RBX] ;MODE
TEST AL, 20H ;DELAY BIT
JZ ENEMYGOUP
;MUST BE BELOW THE MINIMUM Y VALUE OF SHIP
MOV AL, BYTE PTR [RBX + 06H] ;Y
ADD AL, 40H
CMP AL, SHIPORGINY
JBE ENEMYGOUP
;CHECK TO END DELAY
RNG ;FILL RAX WITH RANDOM VARIABLE
AND RAX, 07FH
CMP RAX, 07FH
JNZ NEXTENEMYLOGIC
;TURN OFF DELAY, INVISIBLE, AND NO HITBOX
MOV AL, BYTE PTR [RBX] ;MODE
AND AL, 093H
MOV BYTE PTR [RBX], AL
;SPAWN ENEMY FIRE UNDERNEATH (029H)
;SPAWN MISSLE
PUSH RBX
PUSH RCX
XOR RAX, RAX
MOV AL, BYTE PTR [RBX + 04H] ;X
MOV R10, RAX ;DEST X
MOV AL, BYTE PTR [RBX + 06H] ;Y
ADD AL, 04H
MOV R11, RAX ;DEST Y
MOV R8, 029H ;SPAWN SPRAY
SPAWNENEMY R10, R11, 0
POP RCX
POP RBX
JMP NEXTENEMYLOGIC
ENEMYGOUP:
MOV AL, BYTE PTR [RBX] ;MODE
XOR AL, 04H
AND AL, 14H
CMP AL, 14H ;GO UP BIT + NO INVISIBLE BIT
JNZ CHECKMISSLELAUNCH
;DECREASE Y BY SPEED
ENEMYFLYSPEED EQU 01
MOV AL, BYTE PTR [RBX + 06H] ;Y
SUB AL, ENEMYFLYSPEED
MOV BYTE PTR [RBX + 06H], AL ;Y
CMP AL, 020H
JB DEADENEMY ;TOO HIGH, KILL IT OFF
;MAINTAIN PROPER ALTITUDE (10px EACH)
MOV AL, BYTE PTR [RBX + 0DH] ;TIMER
INC AL
CMP AL, 0CH
JB STOREALTTIMER
;ELSE INCREASE ALTITUDE AND RESET TIMER
MOV AL, BYTE PTR [RBX + 0CH]
CMP AL, 03H
JAE STOREALTTIMER
INC BYTE PTR [RBX + 0CH]
STOREALTTIMER:
MOV BYTE PTR [RBX + 0DH], AL ;TIMER
JMP NEXTENEMYLOGIC
CHECKMISSLELAUNCH:
MOV AL, BYTE PTR [RBX + 01H] ;MODE HIGH BYTE
TEST AL, 02H ;SHORT TIMER BIT
JZ CHECKBOSS
;COUNT TO 32, DELETE
INC BYTE PTR [RBX + 0DH]
MOV AL, BYTE PTR [RBX + 0DH] ;TIMER
CMP AL, 010H
JAE DEADENEMY
;SET SPRITE:
SHR AL, 02H
ADD AL, 029H
MOV BYTE PTR [RBX + 02H], AL ;SPRITE
JMP NEXTENEMYLOGIC
CHECKBOSS:
MOV AL, BYTE PTR [RBX + 02H] ;SPRITE
CMP AL, 034H ;BOSS + 3 OTHER SPRITES
JNZ CHECKFLYMISSLE
;CHECK HEALTH:
MOV AL, BYTE PTR [RBX + 01H]
SHR AL, 02H ;HP
CMP AL, 00H
JNZ MOVEBOSS
;ALREADY DEAD, DESTROY SELF
XOR RAX, RAX
MOV WORD PTR [RBX], AX
MOV WORD PTR [RBX + ENEMYOBJSIZE], AX
MOV WORD PTR [RBX + ENEMYOBJSIZE*2], AX
MOV WORD PTR [RBX + ENEMYOBJSIZE*3], AX
;SPAWN EXPLOSION:
MOV AL, BYTE PTR [RBX + 04H] ;X
ADD AL, 10H
MOV R10, RAX
MOV AL, BYTE PTR [RBX + 06H] ;Y
ADD AL, 10H
MOV R11, RAX
MOV R8, 029H ;SPAWN SPRAY
PUSH RBX
PUSH RCX
SPAWNENEMY R10, R11, 0
POP RCX
POP RBX
;SET WIN TIME OUT
INC WINTIMER
JMP NEXTENEMYLOGIC
MOVEBOSS:
;RANDOMLY LAUNCH MISSLE
RNG ;FILL RAX WITH RANDOM VARIABLE
AND RAX, 07FH
CMP RAX, 07FH
JNZ MOVETHEBOSS
;SPAWN MISSLE
PUSH RBX
PUSH RCX
XOR RAX, RAX
MOV AL, BYTE PTR [RBX + 04H] ;X
ADD AL, 0FH
MOV R10, RAX ;DEST X
MOV AL, BYTE PTR [RBX + 06H] ;Y
ADD AL, 0EH
MOV R11, RAX ;DEST Y
MOV R8, 01BH ;SPAWN MISSLE
SPAWNENEMY R10, R11, 0
POP RCX
POP RBX
MOVETHEBOSS:
INC BOSSMOVEFRAMERULEC
MOV RAX, BOSSMOVEFRAMERULEC
CMP RAX, BOSSMOVEFRAMERULE
JNZ NEXTENEMYLOGIC
MOV BOSSMOVEFRAMERULEC, 00H
;IF TIMER == 0 GO LEFT, IF TIMER == 1 GO RIGHT
MOV AL, BYTE PTR [RBX + 0DH] ;TIMER
CMP AL, 00H
JZ MOVEBOSSLEFT
MOVEBOSSRIGHT:
MOV AL, BYTE PTR [RBX + 06H] ;Y
ADD AL, 01H
MOV BYTE PTR [RBX + 06H], AL
MOV BYTE PTR [RBX + 06H + ENEMYOBJSIZE], AL
ADD AL, 020H
MOV BYTE PTR [RBX + 06H + ENEMYOBJSIZE*2], AL
MOV BYTE PTR [RBX + 06H + ENEMYOBJSIZE*3], AL
MOV AL, BYTE PTR [RBX + 04H] ;X
ADD AL, 02H
MOV BYTE PTR [RBX + 04H], AL
MOV BYTE PTR [RBX + 04H + ENEMYOBJSIZE*2], AL
ADD AL, 020H
MOV BYTE PTR [RBX + 04H + ENEMYOBJSIZE], AL
MOV BYTE PTR [RBX + 04H + ENEMYOBJSIZE*3], AL
CMP AL, 0E6H
JBE NEXTENEMYLOGIC
;ELSE RESET TO MOVE LEFT
MOV BYTE PTR [RBX + 0DH], 00H ;TIMER
MOVEBOSSLEFT:
MOV AL, BYTE PTR [RBX + 06H] ;Y
SUB AL, 01H
MOV BYTE PTR [RBX + 06H], AL
MOV BYTE PTR [RBX + 06H + ENEMYOBJSIZE], AL
ADD AL, 020H
MOV BYTE PTR [RBX + 06H + ENEMYOBJSIZE*2], AL
MOV BYTE PTR [RBX + 06H + ENEMYOBJSIZE*3], AL
MOV AL, BYTE PTR [RBX + 04H] ;X
SUB AL, 02H
MOV BYTE PTR [RBX + 04H], AL
MOV BYTE PTR [RBX + 04H + ENEMYOBJSIZE*2], AL
ADD AL, 020H
MOV BYTE PTR [RBX + 04H + ENEMYOBJSIZE], AL
MOV BYTE PTR [RBX + 04H + ENEMYOBJSIZE*3], AL
CMP AL, 08CH
JA NEXTENEMYLOGIC
;ELSE RESET TO MOVE RIGHT
MOV BYTE PTR [RBX + 0DH], 01H ;TIMER
JMP NEXTENEMYLOGIC
CHECKFLYMISSLE:
MOV AL, BYTE PTR [RBX]
TEST AL, 080H ;FLY BIT
JZ NEXTENEMYLOGIC
MOV RAX, PAUSESCROLL
CMP AL, 00H
JZ NEXTENEMYLOGIC
;FLY MISSLES (BECAUSE THE SCREEN IS PAUSED WHEN BOSS IS LAUNCHED
MOV AL, BYTE PTR [RBX + 06H] ;Y
ADD AL, 01H
MOV BYTE PTR [RBX + 06H], AL ;Y
MOV AL, BYTE PTR [RBX + 04H] ;X
SUB AL, 02H
MOV BYTE PTR [RBX + 04H], AL ;X
CMP AL, 0F0H
JA DEADENEMY
JMP NEXTENEMYLOGIC
DEADENEMY:
XOR RAX, RAX
MOV WORD PTR [RBX], AX
NEXTENEMYLOGIC:
ADD RBX, ENEMYOBJSIZE
INC RCX
CMP RCX, NUMBEROFENEMY
JNZ ENEMYLOGICLOOP
ENDENEMYLOGIC:
ENDM
CHECKHITBOXES MACRO
;CALCULATING AND CHECKING ALL HITBOXES:
;CALCULATING MAIN SHIP HITBOX:
LOCAL ENEMYHITCHECK
LOCAL STANDARDALTCHECK
LOCAL EXTENSIVEALTCHECK
LOCAL COMPAREHITBOX
LOCAL NEXTENEMYHITCHECK
LOCAL CALCBOLTBOX
LOCAL ENEMYHITCHECK2
LOCAL NEXTENEMYHITCHECK2
LOCAL COMPAREHITBOX2
LOCAL EXTENSIVEALTCHECK2
LOCAL NEXTBOLTBOX
LOCAL NORMALENEMYHIT
;SET SHIP LOCATION IN SPRITES:
;DEPENDING ON SIZE OF SHIP:
;DEFAULT SIZE:
MOV AL, 12 ;WIDTH
MOV BYTE PTR [SHIPHITBOX + 02H], AL
MOV AL, 8 ;HEIGHT
MOV BYTE PTR [SHIPHITBOX + 03H], AL
MOV R8, 0BH ;X-OFFSET
MOV R9, 0CH ;Y-OFFSET
;LOCATION X
MOV RAX, SHIPORGINX
ADD RAX, SHIPX
ADD RAX, R8
MOV BYTE PTR [SHIPHITBOX], AL
MOV RAX, SHIPORGINY
MOV RBX, SHIPY
SHR RBX, 01H
ADD RAX, RBX
ADD RAX, SHIPTILTY
ADD RAX, R9
MOV BYTE PTR [SHIPHITBOX + 01H], AL
;CHECKING SHIP AND ENEMY COLLISIONS:
;MUST BE ON SAME ALTITUDE UNLESS 4TH BIT IN ENEMY MODE IS SET (IN WHICH CASE ONLY ALTITUDE AND LOWER WILL HIT)
LEA RDX, QWORD PTR [ENEMY]
XOR RAX, RAX
MOV HIT, RAX
XOR R8, R8
XOR RCX, RCX
ENEMYHITCHECK:
;CHECK IF ACTIVE
MOV AL, BYTE PTR [RDX]
CMP AL, 00H
JZ NEXTENEMYHITCHECK
MOV AL, BYTE PTR [RDX + 0DH]
CMP AL, 00H
JNZ NEXTENEMYHITCHECK
;IS ACTIVE, CHECK HITBOX, ESCPAE ONCE CONDITION FALSE
;COMPARE ALTITUDES:
MOV AL, BYTE PTR [RDX]
TEST AL, 08H ;SPECIAL TALL HITBOX
JNZ EXTENSIVEALTCHECK
TEST AL, 040H ;NO CHECK HITBOX BIT
JNZ NEXTENEMYHITCHECK
STANDARDALTCHECK:
MOV AL, BYTE PTR [SHIPALT]
CMP AL, BYTE PTR [RDX + 0CH]
JNZ NEXTENEMYHITCHECK ;DIFFERENT ALTITUDES, SHIPS IN THE NIGHT
JMP COMPAREHITBOX
EXTENSIVEALTCHECK:
MOV AL, BYTE PTR [HIDESHADOW]
CMP AL, 00H
JZ NEXTENEMYHITCHECK ;HIDE SHADOW MUST ALSO BE TURNED ON
MOV AL, BYTE PTR [SHIPALT]
CMP AL, BYTE PTR [RDX + 0CH]
JA NEXTENEMYHITCHECK ;ONLY ESCAPE IF ALTITUDE IS GREATER
;JMP COMPAREHITBOX
COMPAREHITBOX:
;X PREP
MOV BL, BYTE PTR [RDX + 04H] ;EX
ADD BL, BYTE PTR [RDX + 08H] ;EX OFFSET
;X1+W1 >= X2 && X2+W2 >= X1
MOV AL, BYTE PTR [SHIPHITBOX] ;X
ADD AL, BYTE PTR [SHIPHITBOX + 02H] ;+W
CMP AL, BYTE PTR BL
JB NEXTENEMYHITCHECK
ADD BL, BYTE PTR [RDX + 0AH] ;EW
CMP BL, BYTE PTR [SHIPHITBOX]
JB NEXTENEMYHITCHECK
;Y PREP
MOV BL, BYTE PTR [RDX + 06H] ;EY
ADD BL, BYTE PTR [RDX + 09H] ;EY OFFSET
;Y1+H1 >= Y2 && Y2+H2 >= Y2
MOV AL, BYTE PTR [SHIPHITBOX + 01H] ;Y
ADD AL, BYTE PTR [SHIPHITBOX + 03H] ;+H
CMP AL, BYTE PTR BL
JB NEXTENEMYHITCHECK
ADD BL, BYTE PTR [RDX + 0BH] ;EH
CMP BL, BYTE PTR [SHIPHITBOX + 01H]
JB NEXTENEMYHITCHECK
;CONNECTED
INC R8
NEXTENEMYHITCHECK:
ADD RDX, ENEMYOBJSIZE
INC RCX
CMP RCX, NUMBEROFENEMY
JNZ ENEMYHITCHECK
MOV HIT, R8
;COMPARE PLAYER BOLTS AGAINST ENEMY HIT BOXES
MOV RCX, 00H ;NUMBER OF BOLTS COUNTER
LEA RBX, QWORD PTR [BOLTS]
CALCBOLTBOX: ;STORE BOLT VALUES IN R8(X), R9(Y), R10(X+W), R11(Y+H)
MOV AL, BYTE PTR [RBX] ;MODE
CMP AL, 01H ;ONLY ALLOW FLYING BOLTS TO COLLIDE
JNZ NEXTBOLTBOX
XOR RAX, RAX
MOV AL, BYTE PTR [RBX + 04H] ;X
ADD AL, BYTE PTR [RBX + 08H] ;X OFFSET
MOV R8, RAX
ADD AL, BYTE PTR [RBX + 0AH] ;WIDTH
MOV R10, RAX
MOV AL, BYTE PTR [RBX + 06H] ;Y
ADD AL, BYTE PTR [RBX + 09H] ;Y OFFSET
MOV R9, RAX
ADD AL, BYTE PTR [RBX + 0BH] ;HEIGHT
MOV R11, RAX
MOV R12, RBX
PUSH RCX
;PREPARE ENEMY DATA:
LEA RDX, QWORD PTR [ENEMY]
XOR RCX, RCX
ENEMYHITCHECK2:
;CHECK IF ACTIVE
MOV AL, BYTE PTR [RDX]
CMP AL, 00H
JZ NEXTENEMYHITCHECK2
MOV AL, BYTE PTR [RDX + 0DH]
CMP AL, 00H
JNZ NEXTENEMYHITCHECK2
;IS ACTIVE, CHECK HITBOX, ESCPAE ONCE CONDITION FALSE
;COMPARE ALTITUDES:
MOV AL, BYTE PTR [RDX]
TEST AL, 08H ;SPECIAL TALL HITBOX
JNZ EXTENSIVEALTCHECK2
TEST AL, 040H ;NO CHECK HITBOX BIT
JNZ NEXTENEMYHITCHECK2
;STANDARD ALTITUDE CHECK:
MOV AL, BYTE PTR [R12 + 0CH] ;BOLT ALTITUDE
CMP AL, BYTE PTR [RDX + 0CH] ;ENEMY ALTITUDE
JNZ NEXTENEMYHITCHECK2 ;DIFFERENT ALTITUDES, SHIPS IN THE NIGHT
JMP COMPAREHITBOX2
EXTENSIVEALTCHECK2:
MOV AL, BYTE PTR [R12 + 0CH] ;BOLT ALTITUDE
CMP AL, BYTE PTR [RDX + 0CH]
JA NEXTENEMYHITCHECK2 ;ONLY ESCAPE IF ALTITUDE IS GREATER
COMPAREHITBOX2:
;X PREP
MOV BL, BYTE PTR [RDX + 04H] ;EX
ADD BL, BYTE PTR [RDX + 08H] ;EX OFFSET
;X1+W1 >= X2 && X2+W2 >= X1
MOV RAX, R10 ;BOLT X+W
CMP AL, BL
JB NEXTENEMYHITCHECK2
ADD BL, BYTE PTR [RDX + 0AH] ;EW
MOV RAX, R8 ;BOLT X
CMP BL, AL
JB NEXTENEMYHITCHECK2
;Y PREP
MOV BL, BYTE PTR [RDX + 06H] ;EY
ADD BL, BYTE PTR [RDX + 09H] ;EY OFFSET
;Y1+H1 >= Y2 && Y2+H2 >= Y2
MOV RAX, R9
CMP AL, BL
JB NEXTENEMYHITCHECK2
ADD BL, BYTE PTR [RDX + 0BH] ;EH
MOV RAX, R11
CMP BL, AL
JB NEXTENEMYHITCHECK2
;CONNECTED, SET EACH MODE TO 2 TO EXPLODE THEM
MOV AL, 02H
MOV BYTE PTR [R12], AL
MOV BL, BYTE PTR [RDX] ;MODE FOR ENEMY
TEST BL, 08H ;SPECIAL TALL HITBOX
JNZ NEXTENEMYHITCHECK2 ;IF TALL, DON'T DELETE IT
;CHECK IF BOSS
MOV AL, BYTE PTR [RDX + 02H] ;SPRITE
CMP AL, 034H
JNZ NORMALENEMYHIT ;NOT THE BOSS
;DECREASE HP BY 1
MOV AL, BYTE PTR [RDX + 01H] ;CHECK FOR HIT POINTS
SUB AL, 04H
MOV BYTE PTR [RDX + 01H], AL ;NORMALLY THIS WOULD ERASE OTHER BITS, BUT I KNOW THEY'RE NOT SET
JMP NEXTENEMYHITCHECK2
NORMALENEMYHIT:
MOV BYTE PTR [RDX + 01H], 01H ;START THE DEATH TIMER
MOV BYTE PTR [RDX + 0DH], 00H ;RESET INTERNAL TIMER
NEXTENEMYHITCHECK2:
ADD RDX, ENEMYOBJSIZE
INC RCX
CMP RCX, NUMBEROFENEMY
JNZ ENEMYHITCHECK2
POP RCX
MOV RBX, R12
NEXTBOLTBOX:
ADD RBX, BOLTOBJSIZE
INC RCX
CMP RCX, 08H
JNZ CALCBOLTBOX
ENDM
SHIPEXPLODE MACRO
;EXPLODE THE SHIP:
INC EXPLODEFRAMERULEC
MOV RAX, EXPLODEFRAMERULEC
CMP RAX, EXPLODEFRAMERULE
JNZ ENDSHIPEXPLODE
XOR RAX, RAX
MOV EXPLODEFRAMERULEC, RAX
;INCREASE EXPLOSION:
LEA RDX, QWORD PTR [SPRITES]
MOV RAX, EXPLODETIMER
ADD AL, 029H
MOV BYTE PTR [RDX + 02H], AL ;SPRITES
INC EXPLODETIMER
MOV RAX, EXPLODETIMER
CMP AL, 06H
JNZ ENDSHIPEXPLODE
;END GAME
INC RESET
ENDSHIPEXPLODE:
ENDM
GAMELOGIC MACRO
MOV RAX, HIT
CMP RAX, 00H
JZ NOTHIT
MOV AL, BYTE PTR [SPRITES + 02H]
CMP AL, 020H
JA AFTERSETREDSPRITE
MOV BYTE PTR [SPRITES + 02H], 03FH
AFTERSETREDSPRITE:
;SET MODE TO HIT
MOV RAX, 0FFH ;DEATH MODE
MOV STAGE, RAX
INC EXPLODEDELAYTIMER
MOV RAX, EXPLODEDELAYTIMER
CMP RAX, 040H
JB AFTERLOGIC
SHIPEXPLODE
JMP AFTERLOGIC
NOTHIT:
MOVESHIP
MOVEBACKGROUND
ENEMYLOGIC
CHECKHITBOXES
AFTERLOGIC:
MOV RAX, WINTIMER
CMP RAX, 00H
JZ AFTERWT
INC WINTIMER
MOV RAX, WINTIMER
CMP RAX, 0C0H
JNZ AFTERWT
RESETTITLE
AFTERWT:
MOV RAX, RESET
CMP RAX, 00H
JZ NORESET
RESETGAME
NORESET:
ENDM
INITTITLE MACRO
;CLEAR SCREEN TO TITLE
LEA RDX, QWORD PTR [loadTitleImgBin]
BLTBUFF 0, 0, 0, 0, 1280, 1024 ;RDX LOADED WITH POINTER TO BUFFER
MOV RAX, SPRITEVERSION
MOV RBX, 01F720H
MUL RBX
LEA RDX, QWORD PTR [shipImg]
ADD RDX, RAX
BLTBUFF 0, 0, 534, 477, 230, 140 ;RDX LOADED WITH POINTER TO BUFFER
MOV TITLECOUNTER, 080H
ENDM
RESETTITLE MACRO
MOV TITLEON, 01H
INITTITLE
ENDM
TITLELOGIC MACRO
;CHECK FOR SPRITE SWAP:
CMP TITLESWAPCOUNTER, 00H
JNZ DECREASESWAPCOUNTER
;CHECK LEFT AND RIGHT
MOV AL, BYTE PTR [PRESSEDLEFT]
OR AL, BYTE PTR [POINTERLEFT]
OR AL, BYTE PTR [PRESSEDRIGHT]
OR AL, BYTE PTR [POINTERRIGHT]
CMP AL, 00H
JZ CHECKFIREPRESS
;SWAP GRAPHICS USED
XOR SPRITEVERSION, 01H
MOV TITLESWAPCOUNTER, 80H
;OUTPUT TO SCREEN
MOV RAX, SPRITEVERSION
MOV RBX, 01F720H
MUL RBX
LEA RDX, QWORD PTR [shipImg]
ADD RDX, RAX
BLTBUFF 0, 0, 534, 477, 230, 140 ;RDX LOADED WITH POINTER TO BUFFER
DECREASESWAPCOUNTER:
DEC TITLESWAPCOUNTER
CHECKFIREPRESS:
;WAIT FOR FIRE TO PRESS
MOV RAX, TITLECOUNTER
CMP RAX, 00H
JZ CHECKTITLEPRESS
DEC TITLECOUNTER
JMP ENDTITLELOGIC
CHECKTITLEPRESS:
MOV AL, BYTE PTR [PRESSEDFIRE]
OR AL, BYTE PTR [POINTERFIRE]
CMP AL, 00H
JZ ENDTITLELOGIC
MOV TITLEON, 00H ;TITLE OFF, START GAME
RESETGAME
ENDTITLELOGIC:
ENDM
.CODE
EFI_MAIN PROC
;RCX = ImageHandle
MOV imageHandle, RCX
MOV systemTable, RDX
GETUEFIFUNCTIONS ;GET ALL FUNCTIONS NEEDED FROM EFI TABLE AND PROTOCOLS
RUNGOPINIT ;SET IDEAL VIDEO MODE
RESETCONSOLEPOSITION
;Output to EFI console:
MOV RCX, conOut ;pointer to conOut
LEA RDX, [helloMessage]
CALL OutputString
;READ TIME:
LEA RCX, [time]
LEA RDX, [EFI_TIME_CAPABILITIES]
CALL getTime
MOV RCX, conOut
LEA RDX, [cyclesMessage]
CALL OutputString
;ESTIMATING TIME TO GET CYCLES FOR TARGET FPS:
ESTIMATECYCLESFORFPS
MOV RAX, QWORD PTR [CYCLESPERFRAME]
OUTPUT64BITNUMBER 00H
;STORE INITIAL SECONDS
MOV AL, BYTE PTR [time + 06H]
MOV BYTE PTR [SECONDS], AL
;INITIAL SETUP:
SETUPKEYNOTIFICATIONS
INITTITLE
;SET INITIAL FRAME TIME
RDTSC
SHL RDX, 20H
OR RAX, RDX
ADD RAX, CYCLESPERFRAME
MOV NEXTFRAME@, RAX ;SET TIME TO NEXT FRAME
WAITNEXTFRAME:
RDTSC
SHL RDX, 20H
OR RAX, RDX
CMP NEXTFRAME@, RAX
JA WAITNEXTFRAME ;IF NOT AT NEXT FRAME TIME, KEEP WAITING
ADD RAX, CYCLESPERFRAME
MOV NEXTFRAME@, RAX ;SET TIME TO NEXT FRAME
RUNFRAME:
MOV RAX, TITLEON
CMP AL, 00H
JZ AFTERTITLE
KEYLOGIC
POINTERLOGIC
TITLELOGIC
JMP WAITNEXTFRAME
AFTERTITLE: ;TITLE IS OFF
RESETCONSOLEPOSITION ;BACK TO TOP LEFT
;RUN GAME LOGIC
KEYLOGIC
POINTERLOGIC
MOV RAX, PAUSEGAME
CMP RAX, 00H
JNZ AFTERGAMELOGIC
GAMELOGIC
AFTERGAMELOGIC:
MOV RAX, TITLEON ;IF WAS JUST TURNED ON:
CMP RAX, 01H
JZ AFTERHITBOX
;GRAPHICS TO OUTPUT
RENDERGRAPHICS
MOV RAX, SHOW_HITBOX
CMP RAX, 01H
JNZ AFTERHITBOX
RENDERHITBOXES
AFTERHITBOX:
;CHECK FPS
INC FRAMECOUNT
;CHECK IF NEW SECOND
LEA RCX, [time]
LEA RDX, [EFI_TIME_CAPABILITIES]
CALL getTime
MOV AL, BYTE PTR [time + 06H]
CMP AL, BYTE PTR [SECONDS]
JZ OUTPUTFPS
;UPDATE NEW FPS FROM FRAMERATE OF LAST SECOND
MOV RAX, QWORD PTR [FRAMECOUNT]
MOV FRAMERATE, RAX ;STORE FOR NEW OUTPUT
MOV FRAMECOUNT, 00H
OUTPUTFPS: ;PRINT OUT NEW FPS
MOV RCX, conOut
LEA RDX, [fpsMessage] ;FPS:
CALL OutputString
MOV RAX, FRAMERATE
OUTPUT64BITNUMBER 00H
MOV RAX, PAUSEGAME
OUTPUT64BITNUMBER 00H
JMP DEBUGSKIP
;OUTPUT CONTROL MESSAGE
MOV RCX, conOut
LEA RDX, [controlMessage] ;UDLRF
CALL OutputString
;OUTPUT CURRENT KEY STATUS
XOR RAX, RAX
MOV AL, BYTE PTR [PRESSEDUP]
OUTPUT64BITNUMBER 01H ;NO RETURN LINE
XOR RAX, RAX
MOV AL, BYTE PTR [PRESSEDDOWN]
OUTPUT64BITNUMBER 01H ;NO RETURN LINE
XOR RAX, RAX
MOV AL, BYTE PTR [PRESSEDLEFT]
OUTPUT64BITNUMBER 01H ;NO RETURN LINE
XOR RAX, RAX
MOV AL, BYTE PTR [PRESSEDRIGHT]
OUTPUT64BITNUMBER 01H ;NO RETURN LINE
XOR RAX, RAX
MOV AL, BYTE PTR [PRESSEDFIRE]
OUTPUT64BITNUMBER 00H ;NO RETURN LINE
;MOUSE:
XOR RAX, RAX
MOV AL, BYTE PTR [COMBUP]
OUTPUT64BITNUMBER 01H ;NO RETURN LINE
XOR RAX, RAX
MOV AL, BYTE PTR [COMBDOWN]
OUTPUT64BITNUMBER 01H ;NO RETURN LINE
XOR RAX, RAX
MOV AL, BYTE PTR [COMBLEFT]
OUTPUT64BITNUMBER 01H ;NO RETURN LINE
XOR RAX, RAX
MOV AL, BYTE PTR [COMBRIGHT]
OUTPUT64BITNUMBER 01H ;NO RETURN LINE
XOR RAX, RAX
MOV AL, BYTE PTR [COMBFIRE]
OUTPUT64BITNUMBER 00H ;RETURN LINE
;COLUMN COUNTR:
MOV RCX, conOut
LEA RDX, [columnMessage]
CALL OutputString
MOV RAX, COLUMNTICK
OUTPUT64BITNUMBER 00H
DEBUGSKIP:
;END FRAME LOGIC, WAIT FOR NEXT FRAME
JMP WAITNEXTFRAME
WAITEVENT:
; WaitForEvent
MOV RCX, 01H
LEA RDX, [WaitForKey] ;POINTER TO WaitForKey
LEA R8, [index] ;POINTER TO INDEX
CALL WaitForEvent
;READ KEY
MOV RCX, conIn
LEA RDX, [key]
CALL ReadKeyStroke
;RETURNED IN KEY:
;UINT16 ScanCode;
;CHAR16 UnicodeChar;
MOV RCX, conOut ;pointer to conOut
LEA RDX, [endMessage]
CALL OutputString
; WaitForEvent
MOV RCX, 01H
LEA RDX, [WaitForKey] ;POINTER TO WaitForKey
LEA R8, [index] ;POINTER TO INDEX
CALL WaitForEvent
;END PROGRAM
MOV RAX, 00H ;EFI_SUCESS
RET
EFI_MAIN ENDP
END