-
Notifications
You must be signed in to change notification settings - Fork 0
/
Main.asm
2369 lines (2238 loc) · 58.1 KB
/
Main.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
; ===============================================================================
; Copyright 2023 Ilya Lyakhovets
;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
; ===============================================================================
; Asteroids game written on x64 MASM assembly
option casemap:none
; Init & Kill
MessageBoxA proto
ExitProcess proto
GetModuleHandleA proto
LoadIconA proto
LoadCursorA proto
RegisterClassA proto
ChangeDisplaySettingsA proto
AdjustWindowRectEx proto
GetSystemMetrics proto
CreateWindowExA proto
GetDC proto
ChoosePixelFormat proto
SetPixelFormat proto
wglCreateContext proto
wglMakeCurrent proto
wglDeleteContext proto
ReleaseDC proto
DestroyWindow proto
UnregisterClassA proto
; Common
SetCursor proto
SetFocus proto
SetForegroundWindow proto
ShowWindow proto
UpdateWindow proto
PeekMessageA proto
TranslateMessage proto
DispatchMessageA proto
PostQuitMessage proto
ValidateRect proto
DefWindowProcA proto
SwapBuffers proto
memset proto
strcat proto
strrchr proto
sinf proto
cosf proto
srand proto
rand proto
time proto
PlaySound proto
fopen proto
fscanf proto
GetModuleFileNameA proto
timeGetTime proto
; OpenGL
glShadeModel proto
glDepthFunc proto
glHint proto
glEnable proto
glDisable proto
glTranslatef proto
glRotatef proto
glLoadIdentity proto
glMatrixMode proto
glPushMatrix proto
glPopMatrix proto
glOrtho proto
glScissor proto
glViewport proto
glClearColor proto
glClearDepth proto
glClear proto
glBegin proto
glEnd proto
glVertex2f proto
glVertex3f proto
glVertex2d proto
glColor3f proto
glPointSize proto
glLineWidth proto
includelib legacy_stdio_definitions.lib
includelib libcmtd.lib
includelib vcruntime.lib
includelib ucrt.lib
includelib gdi32.lib
includelib winmm.lib
includelib user32.lib
includelib kernel32.lib
includelib OpenGL32.lib
.data?
hRC qword ?
hDC qword ?
hWnd qword ?
hInstance qword ?
POINT struct 8
x dword ?
y dword ?
POINT ends
POINTF struct 8
x dd ?
y dd ?
POINTF ends
; Rectangle
RECT struct 8
left dword ?
top dword ?
right dword ?
bottom dword ?
RECT ends
DEVMODEA struct 8
dmDeviceName byte 32 DUP(?)
dmSpecVersion word ?
dmDriverVersion word ?
dmSize word ?
dmDriverExtra word ?
dmFields dword ?
union DUMMYUNIONNAME
struct DUMMYSTRUCTNAME
dmOrientation word ?
dmPaperSize word ?
dmPaperLength word ?
dmPaperWidth word ?
dmScale word ?
dmCopies word ?
dmDefaultSource word ?
dmPrintQuality word ?
ends
struct DUMMYSTRUCTNAME2
dmPosition POINT<>
dmDisplayOrientation DWORD ?
dmDisplayFixedOutput DWORD ?
ends
ends
dmColor word ?
dmDuplex word ?
dmYResolution word ?
dmTTOption word ?
dmCollate word ?
dmFormName byte 32 DUP(?)
dmLogPixels word ?
dmBitsPerPel DWORD ?
dmPelsWidth DWORD ?
dmPelsHeight DWORD ?
union DUMMYUNIONNAME2
dmDisplayFlags dword ?
dmNup dword ?
ends
dmDisplayFrequency dword ?
dmICMMethod dword ?
dmICMIntent dword ?
dmMediaType dword ?
dmDitherType dword ?
dmReserved1 dword ?
dmReserved2 dword ?
dmPanningWidth dword ?
dmPanningHeight dword ?
DEVMODEA ends
; Windows class
WNDCLASSA struct 8
style dword ?
lpfnWndProc qword ?
cbClsExtra dword ?
cbWndExtra dword ?
hInstance qword ?
hIcon qword ?
hCursor qword ?
hbrBackground qword ?
lpszMenuName qword ?
lpszClassName qword ?
WNDCLASSA ends
; Pixel format descriptor
PIXELFORMATDESCRIPTOR struct 8
nSize word ?
nVersion word ?
dwFlags dword ?
iPixelType byte ?
cColorBits byte ?
cRedBits byte ?
cRedShift byte ?
cGreenBits byte ?
cGreenShift byte ?
cBlueBits byte ?
cBlueShift byte ?
cAlphaBits byte ?
cAlphaShift byte ?
cAccumBits byte ?
cAccumRedBits byte ?
cAccumGreenBits byte ?
cAccumBlueBits byte ?
cAccumAlphaBits byte ?
cDepthBits byte ?
cStencilBits byte ?
cAuxBuffers byte ?
iLayerType byte ?
bReserved byte ?
dwLayerMask dword ?
dwVisibleMask dword ?
dwDamageMask dword ?
PIXELFORMATDESCRIPTOR ends
pixelFormat dword ?
MESSAGE struct 8
hwnd qword ?
message dword ?
wParam qword ?
lParam qword ?
time dword ?
pt POINT <>
MESSAGE ends
SHIP struct 8
accelerating byte ?
destroyed byte ?
rot dd ?
vel POINTF <0.0, 0.0>
pos POINTF <0.0, 0.0>
SHIP ends
ASTEROID struct 8
active byte ?
sizeType word ?
rot dd ?
rotSpeed dd ?
vel POINTF <0.0, 0.0>
pos POINTF <0.0, 0.0>
ASTEROID ends
BULLET struct 8
active byte ?
vel POINTF <0.0, 0.0>
pos POINTF <0.0, 0.0>
BULLET ends
MAX_PARTICLES equ 80
EFFECT struct 8
time dd ?
vel POINTF MAX_PARTICLES dup (<0.0, 0.0>)
pos POINTF MAX_PARTICLES dup (<0.0, 0.0>)
EFFECT ends
; Wrapper for EFFECT structure.
; It seems like MASM doesn't allow to allocate an array of EFFECT using DUP directive.
; So, this workaround solves the issue.
WRAPPER_EFFECT struct 8
data EFFECT <0>
WRAPPER_EFFECT ends
.data
; Main
WINDOW_WIDTH dword 1920
WINDOW_HEIGHT dword 1080
FULLSCREEN byte 1
; Register class
CS_HREDRAW equ 2h
CS_VREDRAW equ 1h
CS_OWNDC equ 20h
IDC_ARROW equ 7F00h
IDI_APPLICATION equ 7F00h
className db "Asteroids", 0
wc WNDCLASSA <0, 0, 0, 0, 0, 0, 0, 0, 0>
; Fullscreen
DM_PELSWIDTH equ 80000h
DM_PELSHEIGHT equ 100000h
DM_BITSPERPEL equ 40000h
CDS_FULLSCREEN equ 4h
devMode DEVMODEA <>
; Rectangle
SM_CXSCREEN equ 0
SM_CYSCREEN equ 1
windowRect RECT <0, 0, 0, 0>
; Pixel format descriptor
PFD_DRAW_TO_WINDOW equ 4h
PFD_SUPPORT_OPENGL equ 20h
PFD_DOUBLEBUFFER equ 1h
PFD_TYPE_RGBA equ 0
PFD_MAIN_PLANE equ 0
windowTitle db "Asteroids", 0
WS_OVERLAPPED equ 0C00000h
WS_SYSMENU equ 80000h
WS_CAPTION equ 0C00000h
WS_MINIMIZEBOX equ 20000h
WS_OVERLAPPEDWINDOW equ 0C00000h or 80000h or 40000h or 20000h or 10000h
WS_EX_APPWINDOW equ 40000h
WS_EX_WINDOWEDGE equ 100h
WS_POPUP equ 80000000h
WS_EX_APPWINDOW equ 40000h
dwStyle equ WS_OVERLAPPED or WS_SYSMENU or WS_CAPTION or WS_MINIMIZEBOX
dwExStyle equ WS_EX_APPWINDOW or WS_EX_WINDOWEDGE
dwFullscreenStyle equ WS_POPUP;
dwExFullscreenStyle equ WS_EX_APPWINDOW;
WS_CLIPSIBLINGS equ 4000000h
WS_CLIPCHILDREN equ 2000000h
pfd PIXELFORMATDESCRIPTOR <0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>
; Common
DEG2RAN dd 0.0174532925199433
FLOAT_SIGN_MASK equ 80000000h
RAND_FLOAT_RANGE equ 1000
SW_NORMAL equ 1
SW_MAXIMIZE equ 3
PM_REMOVE equ 1h
WM_QUIT equ 12h
WM_CLOSE equ 10h
WM_PAINT equ 0fh
WM_KEYDOWN equ 100h
WM_KEYUP equ 101h
msg MESSAGE <>
PATH_SIZE equ 512
absolutePath db PATH_SIZE dup (0)
randSeed dd 0
configName db "Settings.cfg", 0
readingMode db "r", 0
readConfig db "Fullscreen: %hhd Width: %hu Height: %hu Sound: %hhd", 0
MS2SEC dd 0.001
deltaTime dd 0
lastFrameTime dd 0
; Keys
KEY_ESCAPE equ 1Bh
KEY_SPACE equ 20h
KEY_LEFT equ 25h
KEY_UP equ 26h
KEY_RIGHT equ 27h
KEY_DOWN equ 28h
keys byte 256 dup (0)
keysPressed byte 256 dup (0)
; OpenGL
GL_DEPTH_TEST equ 0B71h
GL_LEQUAL equ 0203h
GL_PERSPECTIVE_CORRECTION_HINT equ 0C50h
GL_NICEST equ 1102h
GL_SMOOTH equ 1D01h
GL_SCISSOR_TEST equ 0c11h
GL_MODELVIEW equ 1700h
GL_PROJECTION equ 1701h
GL_COLOR_BUFFER_BIT equ 4000h
GL_DEPTH_BUFFER_BIT equ 100h
GL_CLEAR_DEPTH_BUFFER dd 1.0
GL_POINTS equ 0h
GL_LINES equ 1h
GL_LINE_STRIP equ 3h
GL_LINE_LOOP equ 2h
GL_NEAR dq 0.0
GL_FAR dq 1.0
BACKGROUND_COLOR_R dd 0.0
BACKGROUND_COLOR_G dd 0.0
BACKGROUND_COLOR_B dd 0.0
BACKGROUND_COLOR_A dd 1.0
; SHIP
SHIP_MOVE_SPEED dd 2.5
SHIP_ROTATION_SPEED dd 100.0
SHIP_FORWARD_SIZE dd 15
SHIP_BACK_SIZE dd 5
SHIP_BACKSIDE_SIZE dd 15
SHIP_SIDE_SIZE dd 10
SHIP_PLUME_SIZE dd 20
SHIP_PLUME_SIDE_SIZE dd 5
SHIP_THICKNESS dd 3
SHIP_BOUNDARY equ 15
SHIP_COLOR_R dd 1.0
SHIP_COLOR_G dd 1.0
SHIP_COLOR_B dd 1.0
SHIP_PLUME_COLOR_R dd 1.0
SHIP_PLUME_COLOR_G dd 0.75
SHIP_PLUME_COLOR_B dd 0.0
ship SHIP <0, 0>
; Asteroids
ASTEROID_MAX_SPEED dd 250
ASTEROID_MAX_ROTATION_SPEED dd 150.0
ASTEROID_THICKNESS dd 4
ASTEROID_COLOR_R dd 1.0
ASTEROID_COLOR_G dd 1.0
ASTEROID_COLOR_B dd 1.0
ASTEROID_BIG equ 0
ASTEROID_MIDDLE equ 1
ASTEROID_SMALL equ 2
ASTEROID_BIG_SIZE equ 40
ASTEROID_MIDDLE_SIZE equ 25
ASTEROID_SMALL_SIZE equ 12
ASTEROIDS_ON_START dd 3
MAX_BIG_ASTEROIDS equ 10
MAX_ASTEROIDS equ MAX_BIG_ASTEROIDS * 2 * 3
asteroids ASTEROID MAX_ASTEROIDS dup ({0, 0.0, 0.0})
; Bullets
BULLET_SPEED dd 500.0
BULLET_SIZE dd 3
MAX_BULLETS equ 30
bullets BULLET MAX_BULLETS dup ({0})
; Effects
EFFECT_MAX_SPEED dd 80.0
EFFECT_TIME dd 1.5
EFFECT_SIZE dd 2
EFFECT_COLOR_R dd 1.0
EFFECT_COLOR_G dd 1.0
EFFECT_COLOR_B dd 1.0
MAX_EFFECTS equ MAX_ASTEROIDS + 1
effects WRAPPER_EFFECT MAX_EFFECTS dup ({})
; Sound - Unfortunately, PlaySound doesn't support mixing sounds
SOUND_ENABLED byte 1
SND_FILENAME equ 20000h
SND_ASYNC equ 1h
SND_NODEFAULT equ 2h
SND_FLAGS equ SND_FILENAME or SND_ASYNC or SND_NODEFAULT
rocketEngine byte "Sounds\RocketEngine.wav", 0
blaster byte "Sounds\Blaster.wav", 0
shipExplosion byte "Sounds\ShipExplosion.wav", 0
asteroidExplosion byte "Sounds\AsteroidExplosion.wav", 0
rocketEnginePath byte PATH_SIZE dup (0)
blasterPath byte PATH_SIZE dup (0)
shipExplosionPath byte PATH_SIZE dup (0)
asteroidExplosionPath byte PATH_SIZE dup (0)
; Error messages
errorTitle db "An error occurred!", 0
registerClassError db "Could not register the window class!", 0
createWindowError db "Could not create a window!", 0
getDCError db "Could not get the device context!", 0
choosePFDError db "Could not choose the pixel format!", 0
setPFDError db "Could not set the pixel format context!", 0
createRCError db "Could not create a rendering context!", 0
makeCurrentRCError db "Could not make the current calling rendering context!", 0
initRendererError db "Could not initialize renderer!", 0
resetCurrentRCError db "Could not reset the current calling rendering context!", 0
deleteRCError db "Could not delete the rendering context!", 0
releaseDCError db "Could not release the device context!", 0
destroyWindowError db "Could not destroy the window!", 0
unregisterClassError db "Could not unregister the window class!", 0
.code
;================================================
; WinMainCRTStartup
;================================================
WinMainCRTStartup proc
local file:dq
sub rsp, 28h
; Gets the absolute path of sound files
mov rcx, 0
lea rdx, absolutePath
mov r8, PATH_SIZE
call GetModuleFileNameA
lea rcx, absolutePath
mov rdx, '\\'
call strrchr
mov cx, 0
mov [rax + 1], cx
lea rcx, rocketEnginePath
lea rdx, absolutePath
call strcat
lea rcx, rocketEnginePath
lea rdx, rocketEngine
call strcat
lea rcx, blasterPath
lea rdx, absolutePath
call strcat
lea rcx, blasterPath
lea rdx, blaster
call strcat
lea rcx, shipExplosionPath
lea rdx, absolutePath
call strcat
lea rcx, shipExplosionPath
lea rdx, shipExplosion
call strcat
lea rcx, asteroidExplosionPath
lea rdx, absolutePath
call strcat
lea rcx, asteroidExplosionPath
lea rdx, asteroidExplosion
call strcat
; Reads config from the disk
lea rcx, configName
lea rdx, readingMode
call fopen
mov file, rax
test rax, rax
jz configNotFound
lea rax, SOUND_ENABLED
push rax
lea rax, WINDOW_HEIGHT
push rax
lea r9, WINDOW_WIDTH
lea r8, FULLSCREEN
lea rdx, readConfig
mov rcx, file
sub rsp, 20h
call fscanf
add rsp, 30h
configNotFound:
; Initializes the game
call InitWindow
test rax, rax
jnz kill
mov al, FULLSCREEN
test al, al
mov rdx, SW_MAXIMIZE
jnz @f
mov rdx, SW_NORMAL
@@: mov rcx, hWnd
call ShowWindow
mov rcx, hWnd
call SetForegroundWindow
mov rcx, hWnd
call SetFocus
mov rcx, hWnd
call UpdateWindow
mov rcx, 1
call SetCursor
call RestartGame
call timeGetTime
cvtsi2ss xmm0, eax
movss lastFrameTime, xmm0
mainLoop:
lea rcx, msg
xor rdx, rdx
xor r8, r8
xor r9, r9
push PM_REMOVE
sub rsp, 20h
call PeekMessageA
add rsp, 28h
test rax, rax
jz update
mov eax, msg.message
cmp eax, WM_QUIT
jne @f
jmp kill
@@: lea rcx, msg
call TranslateMessage
lea rcx, msg
call DispatchMessageA
jmp mainLoop
update: call Update
call Draw
; Calculates delta time
call timeGetTime
cvtsi2ss xmm0, eax
movss xmm2, xmm0
movss xmm1, lastFrameTime
subss xmm0, xmm1
movss lastFrameTime, xmm2
movss xmm1, MS2SEC
mulss xmm0, xmm1
movss deltaTime, xmm0
jmp mainLoop
kill: call KillWindow
xor rcx, rcx
call ExitProcess
add rsp, 28h
ret
WinMainCRTStartup endp
;================================================
; Update
;================================================
Update proc
sub rsp, 28h
; Quits the game when pressing escape key
lea rax, keysPressed
mov al, [rax + KEY_ESCAPE]
test al, al
je @f
mov rcx, 0
call ExitProcess
add rsp, 28h
ret
@@:
; Restarts the game when the ship is destroyed and pressing space key
mov al, ship.destroyed
test al, al
jz @f
lea rax, keysPressed
mov al, byte ptr [rax + KEY_SPACE]
test al, al
je @f
call RestartGame
jmp skip
@@:
; Resets the game automatically if there are no asteroids left
xor rcx, rcx
@@: cmp rcx, MAX_ASTEROIDS
jge @f
mov rax, sizeof ASTEROID
mul rcx
lea rdx, asteroids
mov dl, (ASTEROID ptr [rdx + rax]).active
add rcx, 1
test dl, dl
jz @b
jmp noRestartNeeded
@@: inc ASTEROIDS_ON_START
cmp ASTEROIDS_ON_START, MAX_BIG_ASTEROIDS
jle @f
mov ASTEROIDS_ON_START, MAX_BIG_ASTEROIDS
@@: call RestartGame
noRestartNeeded:
; Jumps over if the ship is destroyed
mov al, ship.destroyed
test al, al
jnz noShip
; Updates the ship
mov ship.accelerating, 0
movss xmm1, [ship.vel.x]
movss xmm2, deltaTime
mulss xmm1, xmm2
movss xmm0, [ship.pos.x]
addss xmm0, xmm1
movss [ship.pos.x], xmm0
movss xmm1, [ship.vel.y]
movss xmm2, deltaTime
mulss xmm1, xmm2
movss xmm0, [ship.pos.y]
addss xmm0, xmm1
movss [ship.pos.y], xmm0
lea rcx, ship.pos
mov rdx, SHIP_BOUNDARY
call WarpPosition
; Rotates the ship to the left when pressing left key
lea rax, keys
mov al, byte ptr [rax + KEY_LEFT]
cmp al, 1
jne @f
movss xmm0, ship.rot
movss xmm1, SHIP_ROTATION_SPEED
movss xmm2, deltaTime
mulss xmm1, xmm2
subss xmm0, xmm1
movss [ship.rot], xmm0
@@:
; Rotates the ship to the right when pressing right key
lea rax, keys
mov al, byte ptr [rax + KEY_RIGHT]
cmp al, 1
jne @f
movss xmm0, ship.rot
movss xmm1, SHIP_ROTATION_SPEED
movss xmm2, deltaTime
mulss xmm1, xmm2
addss xmm0, xmm1
movss [ship.rot], xmm0
@@:
; Accelerates the ship forward when pressing up key
lea rax, keys
mov al, byte ptr [rax + KEY_UP]
cmp al, 1
jne @f
mov ship.accelerating, 1
movss xmm0, DEG2RAN
movss xmm1, [ship.rot]
mulss xmm0, xmm1
call sinf
movss xmm1, SHIP_MOVE_SPEED
mulss xmm0, xmm1
movss xmm1, [ship.vel.x]
addss xmm1, xmm0
movss [ship.vel.x], xmm1
movss xmm0, DEG2RAN
movss xmm1, [ship.rot]
mulss xmm0, xmm1
call cosf
movss xmm1, SHIP_MOVE_SPEED
mulss xmm0, xmm1
movss xmm1, [ship.vel.y]
addss xmm1, xmm0
movss [ship.vel.y], xmm1
; Plays rocket engine sound if enabled
;mov al, SOUND_ENABLED
;test al, al
;jz @f
;lea rcx, rocketEnginePath
;mov rdx, 0
;mov r8d, SND_FLAGS
;call PlaySound
@@:
; Shoots bullets when pressing space key
lea rax, keysPressed
mov al, byte ptr [rax + KEY_SPACE]
cmp al, 1
jne shootingEnd
; Checks if there is an inactive bullet in bullets array
xor rcx, rcx
bulletsWhile:
cmp rcx, MAX_BULLETS
jge shootingEnd
mov rax, sizeof BULLET
mul rcx
lea rdx, bullets
mov dl, (BULLET ptr [rdx + rax]).active
test dl, dl
jz @f
add rcx, 1
jmp bulletsWhile
; If so, makes it active and sets its proper position and speed
@@: movss xmm0, DEG2RAN
movss xmm1, [ship.rot]
mulss xmm0, xmm1
call sinf
mov rax, sizeof BULLET
mul rcx
lea rdx, bullets
movss xmm1, BULLET_SPEED
mulss xmm1, xmm0
movss xmm2, ship.vel.x
addss xmm1, xmm2
movss (BULLET ptr [rdx + rax]).vel.x, xmm1
cvtsi2ss xmm1, SHIP_FORWARD_SIZE
mulss xmm1, xmm0
movss xmm0, ship.pos.x
addss xmm0, xmm1
movss (BULLET ptr [rdx + rax]).pos.x, xmm0
movss xmm0, DEG2RAN
movss xmm1, [ship.rot]
mulss xmm0, xmm1
call cosf
mov rax, sizeof BULLET
mul rcx
lea rdx, bullets
movss xmm1, BULLET_SPEED
mulss xmm1, xmm0
movss xmm2, ship.vel.y
addss xmm1, xmm2
movss (BULLET ptr [rdx + rax]).vel.y, xmm1
cvtsi2ss xmm1, SHIP_FORWARD_SIZE
mulss xmm1, xmm0
movss xmm0, ship.pos.y
addss xmm0, xmm1
movss (BULLET ptr [rdx + rax]).pos.y, xmm0
mov (BULLET ptr [rdx + rax]).active, 1
; Plays blaster sound if enabled
mov al, SOUND_ENABLED
test al, al
jz @f
lea rcx, blasterPath
mov rdx, 0
mov r8d, SND_FLAGS
call PlaySound
@@:
shootingEnd:
noShip:
; Updates bullets
xor rcx, rcx
bulletsFor:
cmp rcx, MAX_BULLETS
jge bulletsForEnd
mov rax, sizeof BULLET
mul rcx
lea rdx, bullets
mov dl, (BULLET ptr [rdx + rax]).active
test dl, dl
jz bulletsForContinue
; Updates bullet positions
lea rdx, bullets
movss xmm1, (BULLET ptr [rdx + rax]).vel.x
movss xmm2, deltaTime
mulss xmm1, xmm2
movss xmm0, (BULLET ptr [rdx + rax]).pos.x
addss xmm0, xmm1
movss (BULLET ptr [rdx + rax]).pos.x, xmm0
movss xmm1, (BULLET ptr [rdx + rax]).vel.y
movss xmm2, deltaTime
mulss xmm1, xmm2
movss xmm0, (BULLET ptr [rdx + rax]).pos.y
addss xmm0, xmm1
movss (BULLET ptr [rdx + rax]).pos.y, xmm0
; Checks whether a bullet is out of the screen or not
lea rdx, bullets
mov rax, sizeof BULLET
push rdx
mul rcx
pop rdx
; Left border
movss xmm0, (BULLET ptr [rdx + rax]).pos.x
xorps xmm1, xmm1
comiss xmm0, xmm1
jb @f
; Right border
movss xmm0, (BULLET ptr [rdx + rax]).pos.x
push rax
mov eax, WINDOW_WIDTH
cvtsi2ss xmm1, eax
pop rax
comiss xmm0, xmm1
ja @f
; Upper border
movss xmm0, (BULLET ptr [rdx + rax]).pos.y
xorps xmm1, xmm1
comiss xmm0, xmm1
jb @f
; Bottom border
movss xmm0, (BULLET ptr [rdx + rax]).pos.y
push rax
mov eax, WINDOW_HEIGHT
cvtsi2ss xmm1, eax
pop rax
comiss xmm0, xmm1
ja @f
jmp bulletsForContinue
; If yes, destroys it
@@: push rcx
lea rcx, BULLET ptr [rdx + rax]
mov rdx, 0
mov r8, sizeof BULLET
sub rsp, 28h
call memset
add rsp, 28h
pop rcx
bulletsForContinue:
inc rcx
jmp bulletsFor
bulletsForEnd:
; Updates asteroids
push rbx
xor rcx, rcx
asteroidsFor:
cmp rcx, MAX_ASTEROIDS
jge asteroidsForEnd
mov rax, sizeof ASTEROID
mul rcx
lea rdx, asteroids
mov dl, (ASTEROID ptr [rdx + rax]).active
test dl, dl
jz asteroidsForContinue
; Updates rotation and position
mov rax, sizeof ASTEROID
mul rcx
lea rdx, asteroids
mov ax, (ASTEROID ptr [rdx + rax]).sizeType
cmp ax, ASTEROID_BIG
jne @f
mov rbx, ASTEROID_BIG_SIZE
jmp sizeChosen
@@:
cmp ax, ASTEROID_MIDDLE
jne @f
mov rbx, ASTEROID_MIDDLE_SIZE
jmp sizeChosen
@@:
cmp ax, ASTEROID_SMALL
jne @f
mov rbx, ASTEROID_SMALL_SIZE
jmp sizeChosen
@@:
sizeChosen:
mov rax, sizeof ASTEROID
mul rcx
lea rdx, asteroids
movss xmm0, (ASTEROID ptr [rdx + rax]).rot
movss xmm1, (ASTEROID ptr [rdx + rax]).rotSpeed
movss xmm2, deltaTime
mulss xmm1, xmm2
addss xmm0, xmm1
movss (ASTEROID ptr [rdx + rax]).rot, xmm0
movss xmm1, (ASTEROID ptr [rdx + rax]).vel.x
movss xmm2, deltaTime
mulss xmm1, xmm2
movss xmm0, (ASTEROID ptr [rdx + rax]).pos.x
addss xmm0, xmm1
movss (ASTEROID ptr [rdx + rax]).pos.x, xmm0
movss xmm1, (ASTEROID ptr [rdx + rax]).vel.y
movss xmm2, deltaTime
mulss xmm1, xmm2
movss xmm0, (ASTEROID ptr [rdx + rax]).pos.y
addss xmm0, xmm1
movss (ASTEROID ptr [rdx + rax]).pos.y, xmm0
; Warps position
push rcx
sub rsp, 20h
lea rcx, (ASTEROID ptr [rdx + rax]).pos
mov rdx, rbx
call WarpPosition
add rsp, 20h
pop rcx
; Destroys the ship if it collides with an asteroid
mov al, ship.destroyed
test al, al
jnz shipNotCollided
push rcx
sub rsp, 20h
mov rax, sizeof ASTEROID
mul rcx
lea rdx, asteroids
lea rcx, (ASTEROID ptr [rdx + rax]).pos
mov rdx, rbx
lea r8, ship.pos
mov r9, SHIP_BOUNDARY
call IsCollided
add rsp, 20h
pop rcx
test rax, rax
jz shipNotCollided
mov ship.destroyed, 1
push rcx
lea rcx, ship.pos
sub rsp, 20h
call SpawnParticle
; Plays ship explosion sound if enabled
mov al, SOUND_ENABLED
test al, al
jz @f
lea rcx, shipExplosionPath
mov rdx, 0
mov r8d, SND_FLAGS
call PlaySound
@@: add rsp, 20h
pop rcx
shipNotCollided:
; Iterates over bullets to check for collisions
push rcx
xor rcx, rcx
asteroidsBulletsFor:
cmp rcx, MAX_BULLETS
jge asteroidsBulletsForEnd
mov rax, sizeof BULLET
mul rcx
lea rdx, bullets
mov dl, (BULLET ptr [rdx + rax]).active
test dl, dl
jz asteroidsBulletsForContinue
; Checks for collisions with an asteroid
push rcx
sub rsp, 28h
mov rax, sizeof BULLET
mul rcx
lea rdx, bullets
lea rcx, (BULLET ptr [rdx + rax]).pos
mov edx, BULLET_SIZE
push rcx
push rdx
mov rcx, [rsp + 40h]
mov rax, sizeof ASTEROID
mul rcx
lea rdx, asteroids
lea r8, (ASTEROID ptr [rdx + rax]).pos
mov r9, rbx
pop rdx
pop rcx
call IsCollided
add rsp, 28h
pop rcx
test rax, rax
jz notCollided
; If collided