Space Invaders

Please support our Assembly advertiser: Programming Forums - DaniWeb Sister Site
cscgal cscgal is offline Offline Aug 28th, 2006, 4:55 pm |
0
This is a program I wrote for my x86 assembly class which is basically the Spade Invaders game in all its glory. It uses Irvine32.inc which came with the textbook.
Quick reply to this message  
Assembly Syntax
  1. title SpaceInvaders (spacegame.asm)
  2.  
  3. ; Dani Horowitz
  4. ; CSC111 x86 Assembly Programming
  5.  
  6. INCLUDE Irvine32.inc
  7.  
  8. .data ; begin data segment
  9. use_default byte 0 ; don't use user variables?
  10. ; ##### USER VARIABLES #####
  11. ; ## used if use_default=1 #
  12. ; ##########################
  13. dodge_bullets byte 1 ; boolean for whether invaders can dodge bullets
  14. invader_count dword 20 ; number of invaders wanted (min 14)
  15. bottom_row byte 20 ; screen height (console vs fullscreen)
  16. ; ##########################
  17. ; ##########################
  18. invader_char = 2 ; character symbol to represent
  19. player_char = 1 ; character symbol to represent
  20. bullet_char = 30 ; character symbol to represent
  21. invader_color = red
  22. player_color = lightCyan
  23. bullet_color = yellow
  24. default_color = white
  25. ; ##########################
  26. invader_steps byte 1 ; number of rows and columns invaders move at a time
  27. game_running byte 0 ; boolean value for whether game is running or not
  28. ; ##########################
  29. bullet_row byte 0 ; current location of bullet (dh)
  30. bullet_col byte 0 ; current location of bullet (dl)
  31. invader_col byte 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70
  32. invader_row byte 2, 5, 8, 5, 2, 5, 8, 5, 2, 5, 8, 5, 2, 5
  33. current_loc byte ? ; player's current column (dl) location
  34. direction byte ? ; player's left/right direction
  35. inv_direction byte 0 ; current direction of invaders
  36. ; ##########################
  37. time dword 0 ; iterations of the game loop (loop counter)
  38. delay_time dword 70 ; length of pause time
  39. points dword 0 ; invaders killed
  40. counter dword 0 ; invaders that escaped
  41. number_invaders dword 14 ; current number of invaders
  42. icounter dword 0 ; invader loop counter
  43. score sdword 0
  44. ; ##########################
  45. msg_bottom byte 21 ; bottom location for message (dh)
  46. msg_left = 2 ; left location for message (dl)
  47. msg_right = 65 ; right location for score (dl)
  48. ; ##########################
  49. stdInHandle dword ? ; keyboard input handler
  50. buffer byte 80 DUP(?) ; keyboard input buffer
  51. bug_fix_counter byte 0
  52. ; ##################################################
  53. .code ; begin code segment
  54. ; ##################################################
  55.  
  56. ; ##################################################
  57. INIT_KEYBOARD PROC
  58. ; get handle to standard keyboard input
  59. ; populate the stdInHandle variable
  60. ; ##################################################
  61. ; abstraction is a wonderful, glorious thing!
  62. INVOKE GetStdHandle, STD_INPUT_HANDLE
  63. mov stdInHandle, eax
  64. ret
  65. ; ##################################################
  66. INIT_KEYBOARD ENDP
  67. ; ##################################################
  68.  
  69. ; ##################################################
  70. KYBD_HANDLER PROC
  71. ; set console flags to appropriate mode to read a single character
  72. ; determine if a new character is waiting in the buffer
  73. ; if yes, read it in and call the KEY_LISTENER procedure
  74. ; reset console flags to their previous values
  75. ; bug: all keypresses are executed twice ??
  76. ; ##################################################
  77. .data
  78. saveFlags dword ? ; default console flags
  79. bytesRead dword ? ; number of bytes in buffer
  80. .code
  81. INVOKE GetConsoleMode, stdInhandle, saveFlags
  82. INVOKE SetConsoleMode, stdInHandle, 0
  83. ; ----------
  84. ; peek in buffer and see if anything new is there
  85. INVOKE PeekConsoleInput,
  86. stdInHandle, ADDR buffer, 1, ADDR bytesRead
  87. ; if no, skip to the end
  88. cmp bytesRead, 1
  89. jne Done
  90. ; ----------
  91. ; if a keypress is waiting in the buffer,
  92. ; put its value into al and call KEY_LISTENER
  93. ; to do something with it
  94. INVOKE ReadConsoleInput,
  95. stdInHandle, ADDR buffer, 1, ADDR bytesRead
  96. xor eax, eax
  97. mov esi, OFFSET buffer
  98. add esi, 14
  99. mov al, [esi]
  100. call KEY_LISTENER
  101. Done:
  102. INVOKE SetConsoleMode, stdInHandle, saveFlags
  103. ret
  104. ; ##################################################
  105. KYBD_HANDLER ENDP
  106. ; ##################################################
  107.  
  108. ; ##################################################
  109. PRINT_BLANK PROC
  110. ; assume dh and dl have already been set
  111. ; position cursor
  112. ; print a blank space to the screen
  113. ; ##################################################
  114. mov al, ' '
  115. call Gotoxy
  116. call WriteChar
  117. ret
  118. ; ##################################################
  119. PRINT_BLANK ENDP
  120. ; ##################################################
  121.  
  122. ; ##################################################
  123. PRINT_INVADER PROC
  124. ; assume dh and dl have already been set
  125. ; position cursor
  126. ; set cursor color to the invader color
  127. ; print the invader character to the screen
  128. ; reset cursor color to the default color
  129. ; ##################################################
  130. call Gotoxy
  131. mov eax, invader_color
  132. call SetTextColor
  133. mov al, invader_char
  134. call WriteChar
  135. mov eax, default_color
  136. call SetTextColor
  137. ret
  138. ; ##################################################
  139. PRINT_INVADER ENDP
  140. ; ##################################################
  141.  
  142. ; ##################################################
  143. PRINT_PLAYER PROC
  144. ; assume dh and dl have already been set
  145. ; position cursor
  146. ; set cursor color to the player color
  147. ; print the player character to the screen
  148. ; reset cursor color to the default color
  149. ; ##################################################
  150. call Gotoxy
  151. mov eax, player_color
  152. call SetTextColor
  153. mov al, player_char
  154. call WriteChar
  155. mov eax, default_color
  156. call SetTextColor
  157. ret
  158. ; ##################################################
  159. PRINT_PLAYER ENDP
  160. ; ##################################################
  161.  
  162. ; ##################################################
  163. PRINT_BULLET PROC
  164. ; assume dh and dl have already been set
  165. ; position cursor
  166. ; set cursor color to the bullet color
  167. ; print the bullet character to the screen
  168. ; reset cursor color to the default color
  169. ; ##################################################
  170. call Gotoxy
  171. mov eax, bullet_color
  172. call SetTextColor
  173. mov al, bullet_char
  174. call WriteChar
  175. mov eax, default_color
  176. call SetTextColor
  177. ret
  178. ; ##################################################
  179. PRINT_BULLET ENDP
  180. ; ##################################################
  181.  
  182. ; ##################################################
  183. INIT_GAME PROC
  184. ; determine if using default variables
  185. ; if not using defaults, call INIT_VARS procedure to prompt for them
  186. ; screen print that the game is starting
  187. ; call INIT_KEYBOARD procedure to set up the keyboard console input handler
  188. ; call CREATE_OBJS procedure to print the player and invaders on the screen
  189. ; call RUN_GAME procedure to run the game loop
  190. ; return to main when finished
  191. ; ##################################################
  192. .data
  193. msg byte "Game starting ...", 0
  194. msg_howto_left byte "F to move left ", 0
  195. msg_howto_right byte "J to move right", 0
  196. msg_howto_fire byte "B to fire ", 0
  197. msg_howto_quit byte "E to quit game ", 0
  198. .code
  199. mov eax, default_color ; set cursor to use default text color
  200. call SetTextColor
  201. .IF use_default == 0 ; use user-defined variables?
  202. call INIT_VARS ; initialize global variables
  203. call DumpRegs ; pretty print out what is in the registers
  204. .ENDIF
  205. mov edx, OFFSET msg
  206. call WriteString ; print "Game starting"
  207. call Crlf
  208. ; give user directions how to play
  209. mov edx, OFFSET msg_howto_left
  210. call WriteString
  211. call Crlf
  212. mov edx, OFFSET msg_howto_right
  213. call WriteString
  214. call Crlf
  215. mov edx, OFFSET msg_howto_fire
  216. call WriteString
  217. call Crlf
  218. mov edx, OFFSET msg_howto_quit
  219. call WriteString
  220. call Crlf
  221. mov eax, 500
  222. call Delay ; pause
  223. call WaitMsg
  224. call Clrscr
  225. call INIT_KEYBOARD ; set up keyboard handler to get input
  226. call CREATE_OBJS ; create visual objects
  227. call RUN_GAME ; run the game
  228. ret ; game over
  229. ; ##################################################
  230. INIT_GAME ENDP
  231. ; ##################################################
  232.  
  233. ; ##################################################
  234. INIT_VARS PROC
  235. ; this is only invoked if use_default=0
  236. ; prompt for and populate user-defined value for dodge_bullets
  237. ; prompt for and populate user-defined value for invader_count
  238. ; prompt for and populate user-defined value for bottom_row
  239. ; use bottom_row value to also set the msg_bottom variable
  240. ; return to INIT_GAME when finished
  241. ; ##################################################
  242. .data
  243. promptA byte "Allow invaders to dodge bullets? (0=no 1=yes) ", 0
  244. promptB byte "Maximum number of invaders? (minimum 14) ", 0
  245. promptC byte "How many screen rows for your monitor? (20 or 45) ", 0
  246. .code
  247. PromptForA:
  248. mov edx, OFFSET promptA ; prompt for dodge_bullets
  249. call WriteString
  250. call ReadInt ; assume user enters a small value
  251. mov dodge_bullets, al ; and prey this doesn't break
  252. .IF al!=0 && al!=1
  253. jmp PromptForA
  254. .ENDIF
  255. ; ----------
  256. PromptForB:
  257. mov edx, OFFSET promptB ; prompt for # of invaders
  258. call WriteString
  259. call ReadInt
  260. mov invader_count, eax
  261. cmp eax, 14
  262. jl PromptForB
  263. ; ----------
  264. PromptForC:
  265. mov edx, OFFSET promptC ; prompt for screen resolution
  266. call WriteString
  267. call ReadInt
  268. mov bottom_row, al
  269. .IF al!=20 && al!=45
  270. jmp PromptForC
  271. .ENDIF
  272. inc al
  273. mov msg_bottom, al
  274. ret
  275. ; ##################################################
  276. INIT_VARS ENDP
  277. ; ##################################################
  278.  
  279. ; ##################################################
  280. RUN_GAME PROC
  281. ; expects a bunch of stuff to already be populated
  282. ; continuously runs game loop until all invaders accounted for
  283. ; by either having been killed or escaped
  284. ; call KYBD_HANDLER procedure to check for a key press
  285. ; move existing bullet up
  286. ; move a random invader down
  287. ; when appropriate, call the END_GAME procedure
  288. ; return to INIT_GAME when finished
  289. ; ##################################################
  290. .data
  291. msg_run_game byte "Game started ", 0
  292. .code
  293. ; ##############################
  294. mov dh, msg_bottom
  295. mov dl, msg_left
  296. call Gotoxy
  297. mov edx, OFFSET msg_run_game
  298. call WriteString
  299. ; ##############################
  300. call Randomize ; randomize seed
  301. mov game_running, 1 ; set game_running flag on
  302. Step:
  303. mov eax, delay_time ; pause
  304. .IF delay_time<20
  305. mov delay_time, 20
  306. .ENDIF
  307. call Delay
  308. mov dh, 0
  309. mov dl, 0
  310. call Gotoxy ; position cursor at top left of screen
  311. mov eax, counter
  312. add eax, points
  313. cmp eax, number_invaders ; loop if not all invaders accounted for
  314. jge GameOver
  315. call KYBD_HANDLER ; continously run
  316. call MOVE_BULLET ; step bullet, if exists, up
  317. call MOVE_INVADERS ; step invaders down
  318. call PRINT_SCORE
  319. inc time ; increment game time
  320. cmp game_running, 0 ; game over if game_running flag switched to off
  321. je GameOver
  322. jmp Step
  323. GameOver:
  324. call END_GAME ; end game
  325. ret
  326. ; ##################################################
  327. RUN_GAME ENDP
  328. ; ##################################################
  329.  
  330. ; ##################################################
  331. END_GAME PROC
  332. ; assumes points has been populated with # of invaders killed
  333. ; assumes counter has been populated with # of invaders escaped
  334. ; assumes time has been populated with # of game loop iterations
  335. ; clears the screen
  336. ; pretty prints points, counter, time variables to the screen
  337. ; return to end of RUN_GAME when finished
  338. ; ##################################################
  339. .data
  340. msg_points byte "Invader Death Counter: ",0
  341. msg_counter byte "Invaders That Escaped: ",0
  342. msg_time byte "Game length: ", 0
  343. .code
  344. call Clrscr
  345. ; ----------
  346. mov dh, 10
  347. mov dl, 10
  348. call Gotoxy
  349. mov edx, OFFSET msg_points ; print points
  350. call WriteString
  351. mov eax, points
  352. call WriteDec
  353. ; ----------
  354. mov dh, 15
  355. mov dl, 10
  356. call Gotoxy
  357. mov edx, OFFSET msg_counter ; print counter
  358. call WriteString
  359. mov eax, counter
  360. call WriteDec
  361. ; ----------
  362. mov dh, 20
  363. mov dl, 10
  364. call Gotoxy
  365. mov edx, OFFSET msg_time ; print timer
  366. call WriteString
  367. mov eax, time
  368. call WriteDec
  369. ; ----------
  370. mov dh, 30
  371. mov dl, 10
  372. call Gotoxy
  373. ret
  374. ; ##################################################
  375. END_GAME ENDP
  376. ; ##################################################
  377.  
  378. ; ##################################################
  379. PRINT_SCORE PROC
  380. ; pretty print current game score at bottom right of screen
  381. ; ##################################################
  382. .data
  383. msg_score byte "Score: ", 0
  384. msg_speed byte "Game Speed: ", 0
  385. .code
  386. mov dh, msg_bottom
  387. mov dl, msg_right
  388. call Gotoxy ; position cursor
  389. mov edx, OFFSET msg_score
  390. call WriteString ; write "Score: "
  391. mov eax, score
  392. call WriteInt ; write the value
  393. ; ----------
  394. mov dh, msg_bottom
  395. inc dh
  396. mov dl, msg_left
  397. call Gotoxy ; position cursor
  398. mov edx, OFFSET msg_speed ; write "Game Speed: "
  399. call WriteString
  400. mov eax, 70
  401. sub eax, delay_time
  402. call WriteDec ; write the value
  403. ret
  404. ; ##################################################
  405. PRINT_SCORE ENDP
  406. ; ##################################################
  407.  
  408. ; ##################################################
  409. CREATE_OBJS PROC
  410. ; self-explanatory
  411. ; return to INIT_GAME when finished
  412. ; ##################################################
  413. call Clrscr
  414. call CREATE_PLAYER
  415. call CREATE_INVADERS
  416. ret
  417. ; ##################################################
  418. CREATE_OBJS ENDP
  419. ; ##################################################
  420.  
  421. ; ##################################################
  422. CREATE_PLAYER PROC
  423. ; draw player at bottom center screen location
  424. ; populate player coordinate to correct value
  425. ; return to CREATE_OBJS when finished
  426. ; ##################################################
  427. mov dh, bottom_row ; row current_bottom
  428. dec dh
  429. mov dl, 40 ; column 40
  430. call PRINT_PLAYER
  431. mov current_loc, 40 ; set current_loc variable
  432. ret
  433. ; ##################################################
  434. CREATE_PLAYER ENDP
  435. ; ##################################################
  436.  
  437. ; ##################################################
  438. CREATE_INVADERS PROC
  439. ; traverse a loop to draw 14 invaders at starting locations
  440. ; starting locations are read from byte arrays
  441. ; return to CREATE_OBJS when finished
  442. ; ##################################################
  443. mov icounter, 0 ; initialize loop
  444. PrintInvader:
  445. mov esi, OFFSET invader_col ; get col
  446. add esi, icounter
  447. mov dl, [esi] ; set column value
  448. mov esi, OFFSET invader_row ; get row
  449. add esi, icounter
  450. mov dh, [esi] ; set row value
  451. call PRINT_INVADER ; print invader to the screen
  452. inc icounter ; increment loop counter
  453. cmp icounter, 14 ; did we do all 14 invaders?
  454. jl PrintInvader ; if not, do next invader
  455. ret
  456. ; ##################################################
  457. CREATE_INVADERS ENDP
  458. ; ##################################################
  459.  
  460. ; ##################################################
  461. MOVE_PLAYER PROC
  462. ; invoked from within KEY_LISTENER
  463. ; assumes a keyboard char to move the player has been pressed
  464. ; prints empty character over player's current location
  465. ; moves player's current location variable one space left or right
  466. ; prints player character to screen at the new location
  467. ; doesn't allow player to move out of bounds
  468. ; return to KEY_LISTENER when finished
  469. ; ##################################################
  470. .data
  471. temp_dl byte ?
  472. temp_dh byte ?
  473. msg_move_player_left byte "Moving left ", 0
  474. msg_move_player_right byte "Moving right ", 0
  475. .code
  476. inc bug_fix_counter ; bug workaround!!
  477. .IF bug_fix_counter==2
  478. mov bug_fix_counter, 0
  479. jmp Done
  480. .ENDIF ; end bug fix :(
  481. mov dh, bottom_row ; erase from old location
  482. dec dh
  483. mov dl, current_loc
  484. call PRINT_BLANK
  485. mov temp_dh, dh
  486. mov temp_dl, dl
  487. ; ----------
  488. .IF direction == 'j' ; determine direction
  489. cmp dl, 70
  490. jge RightBound ; handle out of bounds
  491. inc temp_dl ; increment dl
  492. ; ##############################
  493. mov dh, msg_bottom
  494. mov dl, msg_left
  495. call Gotoxy
  496. mov edx, OFFSET msg_move_player_right
  497. call WriteString
  498. ; ##############################
  499. .ELSE
  500. cmp dl, 5
  501. jle LeftBound ; handle out of bounds
  502. dec temp_dl ; decrement dl
  503. ; ##############################
  504. mov dh, msg_bottom
  505. mov dl, msg_left
  506. call Gotoxy
  507. mov edx, OFFSET msg_move_player_left
  508. call WriteString
  509. ; ##############################
  510. .ENDIF
  511. jmp Move
  512. LeftBound:
  513. mov dl, 5
  514. jmp Move
  515. RightBound:
  516. mov dl, 70
  517. Move:
  518. mov dl, temp_dl
  519. mov dh, temp_dh
  520. mov current_loc, dl ; position cursor at new location
  521. call PRINT_PLAYER ; print the player all pretty-like
  522. Done:
  523. ret
  524. ; ##################################################
  525. MOVE_PLAYER ENDP
  526. ; ##################################################
  527.  
  528. ; ##################################################
  529. KEY_LISTENER PROC
  530. ; assumes al is populated with a character pressed from the keyboard
  531. ; initiates FIRE procedure if 'b' key pressed
  532. ; sets game_running flag to off if 'e' key is pressed
  533. ; otherwise, initiates MOVE_PLAYER procedure
  534. ; returns to KYBD_HANDLER when finished
  535. ; ##################################################
  536. mov direction, al ; stick it in direction
  537. .IF direction == 'b' ; if entered 'b' fire bullet
  538. call FIRE
  539. .ELSEIF direction == 'e'
  540. mov game_running, 0
  541. .ELSE
  542. call MOVE_PLAYER ; else, move player
  543. .ENDIF
  544. Done:
  545. ret
  546. ; ##################################################
  547. KEY_LISTENER ENDP
  548. ; ##################################################
  549.  
  550. ; ##################################################
  551. FIRE PROC
  552. ; assumes 'b' key has been pressed to fire a bullet
  553. ; determine starting location of bullet
  554. ; draw bullet to screen if another bullet isn't in progress
  555. ; return to KEY_LISTENER when finished
  556. ; ##################################################
  557. .data
  558. msg_fire byte "Bullet fired ", 0
  559. msg_fire_inprogress byte "Cannot Fire ", 0
  560. .code
  561. ; ##############################
  562. mov dh, msg_bottom
  563. mov dl, msg_left
  564. call Gotoxy
  565. mov edx, OFFSET msg_fire
  566. call WriteString
  567. ; ##############################
  568. cmp bullet_col, 0 ; is a bullet currently in progress?
  569. jne ExistingBullet ; if yes, skip down and do nothing
  570. mov dh, bottom_row
  571. sub dh, 2
  572. mov bullet_row, dh ; position bullet's starting location
  573. mov al, current_loc ; from player's current location
  574. mov bullet_col, al
  575. mov dh, bullet_row ; set bullet location
  576. mov dl, bullet_col
  577. call PRINT_BULLET ; print bullet to screen
  578. sub score, 50
  579. jmp Done
  580. ExistingBullet:
  581. ; ##############################
  582. mov dh, msg_bottom ; only one bullet allowed in the air at a time
  583. mov dl, msg_left
  584. call Gotoxy
  585. mov edx, OFFSET msg_fire_inprogress
  586. call WriteString
  587. ; ##############################
  588. Done:
  589. ret
  590. ; ##################################################
  591. FIRE ENDP
  592. ; ##################################################
  593.  
  594. ; ##################################################
  595. MOVE_BULLET PROC
  596. ; determine if there are any bullets in progress
  597. ; if yes, move bullet up
  598. ; update bullet location
  599. ; erase bullet from old location and draw to new location
  600. ; initiate procedure to determine if bullet hit an invader
  601. ; if bullet reached top of screen, update variables to
  602. ; indicate no bullets are in progress
  603. ; return to loop in RUN_GAME when finished
  604. ; ##################################################
  605. cmp bullet_row, 0 ; determine if bullet is in progress
  606. je NoBullets ; if no, there is nothing to move
  607. mov dh, bullet_row
  608. mov dl, bullet_col
  609. call PRINT_BLANK ; write empty string in current location
  610. mov al, invader_steps ; move bullet_row up
  611. sub bullet_row, al
  612. mov dh, bullet_row
  613. call PRINT_BULLET
  614. call HIT_INVADER ; see if we hit any invaders
  615. .IF dodge_bullets==1
  616. call SHIFT_INVADERS ; shift invaders to the side
  617. .ENDIF
  618. ; ----------
  619. cmp bullet_row, 1 ; see if we reached the top of the screen
  620. jle HideBullet
  621. jmp NoBullets
  622. HideBullet:
  623. mov bullet_row, 0 ; set value to default (no bullets in progress)
  624. mov bullet_col, 0 ; set value to default (no bullets in progress)
  625. sub score, 100
  626. NoBullets:
  627. ret
  628. ; ##################################################
  629. MOVE_BULLET ENDP
  630. ; ##################################################
  631.  
  632. ; ##################################################
  633. HIT_INVADER PROC
  634. ; traverse through each column an invader is in
  635. ; determine if bullet is in the same column
  636. ; if yes, check to see if rows match too
  637. ; if everything matches, invoke KILL_INVADER procedure
  638. ; return to MOVE_BULLET when finished
  639. ; ##################################################
  640. mov icounter, 0
  641. CheckCol:
  642. mov esi, OFFSET invader_col ; find the invader column array
  643. add esi, icounter
  644. mov dl, [esi] ; get column location for invader
  645. cmp bullet_col, dl ; compare to column location for bullet
  646. je CheckRow ; if a match, check the row
  647. inc icounter
  648. cmp icounter, 14 ; loop for all invaders
  649. jl CheckCol
  650. jmp Done
  651. CheckRow:
  652. mov esi, OFFSET invader_row ; find the invader row array
  653. add esi, icounter
  654. mov dh, [esi] ; get row location for invader
  655. mov dl, bullet_row ; get row location for bullet
  656. sub dl, dh ; difference in location
  657. .IF dl<=invader_steps && dl>=0 && dh!=bottom_row
  658. call KILL_INVADER ; if we got here, he's dead
  659. .ENDIF
  660. Done:
  661. ret
  662. ; ##################################################
  663. HIT_INVADER ENDP
  664. ; ##################################################
  665.  
  666. ; ##################################################
  667. KILL_INVADER PROC
  668. ; delete bullet from screen
  669. ; draw an X where invader was killed
  670. ; pause, and then draw a blank space
  671. ; (need to handle this separately in case going at different speeds)
  672. ; move bullet location to default (none in progress)
  673. ; set invader row to bottom_row
  674. ; if we want another invader, create it!
  675. ; increase points value
  676. ; return to HIT_INVADER when finished
  677. ; ##################################################
  678. .data
  679. msg_kill_invader byte "Invader Killed ", 0
  680. .code
  681. ; ##############################
  682. mov dh, msg_bottom
  683. mov dl, msg_left
  684. call Gotoxy
  685. mov edx, OFFSET msg_kill_invader
  686. call WriteString
  687. ; ##############################
  688. add score, 500
  689. mov dh, bullet_row
  690. mov dl, bullet_col
  691. call PRINT_BLANK ; delete bullet from screen
  692. ; ----------
  693. mov esi, OFFSET invader_row ; find the invader row array
  694. add esi, icounter
  695. mov dh, [esi]
  696. mov esi, OFFSET invader_col ; find the invader col array
  697. add esi, icounter
  698. mov dl, [esi]
  699. ; ----------
  700. mov al, 'X' ; X marks the spot
  701. call Gotoxy
  702. call WriteChar ; draw an X really quickly
  703. mov eax, 100
  704. call Delay
  705. call PRINT_BLANK ; pause, and then draw a blank space over the X
  706. ; ----------
  707. mov bullet_col, 0 ; move bullet column location to default
  708. mov bullet_row, 0 ; move bullet row location to default
  709. mov esi, OFFSET invader_row ; find the invader row array
  710. add esi, icounter
  711. mov dh, bottom_row
  712. mov eax, invader_count
  713. .IF number_invaders < eax ; do we want more invaders?
  714. mov dh, 2 ; if yes, create a new one
  715. inc number_invaders
  716. .ENDIF
  717. mov [esi], dh ; set invader row to bottom_row
  718. inc points ; increase points value
  719. sub delay_time, 2 ; game runs faster as it progresses
  720. ret
  721. ; ##################################################
  722. KILL_INVADER ENDP
  723. ; ##################################################
  724.  
  725. ; ##################################################
  726. MOVE_INVADERS PROC
  727. ; find a random invader
  728. ; if the invader is already gone, choose another one
  729. ; move the chosen invader down
  730. ; if invader reached the bottom, delete the invader
  731. ; if we want another invader, create it!
  732. ; return to loop in RUN_GAME when finished
  733. ; ##################################################
  734. .data
  735. prevent_loop byte 0 ; just in case ...
  736. .code
  737. mov prevent_loop, 0
  738. ChooseInvader: ; prevent an infinite loop if
  739. inc prevent_loop ; no invaders are available
  740. cmp prevent_loop, 14
  741. jg Done
  742. ; ----------
  743. mov eax, 14 ; generate random number between 0-13
  744. call RandomRange
  745. mov icounter, eax ; put random number into icounter
  746. PrintInvader:
  747. mov esi, OFFSET invader_col ; get invader row array
  748. add esi, icounter
  749. mov dl, [esi] ; set dl to current column of icounter invader
  750. mov esi, OFFSET invader_row ; get invader column array
  751. add esi, icounter
  752. mov dh, [esi] ; set dh to current row of icounter invader
  753. ; ----------
  754. cmp dh, bottom_row ; if invader is gone already, choose another invader
  755. jge ChooseInvader
  756. ; ----------
  757. call PRINT_BLANK ; delete invader from current location
  758. ; ----------
  759. add dh, invader_steps
  760. mov al, bottom_row
  761. dec al
  762. cmp dh, al ; did we reach bottom?
  763. jge HideInvader ; if yes, delete invader
  764. call PRINT_INVADER
  765. Continue:
  766. mov [esi], dh ; update invader array
  767. jmp Done
  768. HideInvader:
  769. sub score, 100
  770. mov dh, bottom_row ; position below player
  771. inc counter ; add to invaders that escaped counter
  772. call PRINT_BLANK
  773. mov eax, invader_count
  774. .IF number_invaders < eax ; do we want more invaders?
  775. mov dh, 2 ; if yes, create a new one
  776. inc number_invaders
  777. .ENDIF
  778. jmp Continue
  779. Done:
  780. ret
  781. ; ##################################################
  782. MOVE_INVADERS ENDP
  783. ; ##################################################
  784.  
  785. ; ##################################################
  786. SHIFT_INVADERS PROC
  787. ; only when a bullet is in the air:
  788. ; every few iterations, move all invaders right or left
  789. ; don't let invaders go out of bounds
  790. ; return to MOVE_BULLET when finished
  791. ; ##################################################
  792. mov icounter, 0
  793. ShiftInvaders:
  794. mov esi, OFFSET invader_row ; find the invader row array
  795. add esi, icounter
  796. mov dh, [esi] ; get row location for invader
  797. mov esi, OFFSET invader_col ; find the invader column array
  798. add esi, icounter
  799. mov dl, [esi] ; get column location for invader
  800. cmp dh, bottom_row
  801. jge NextInvader
  802. ; ----------
  803. call PRINT_BLANK ; write a blank space to current location
  804. ; ----------
  805. .IF inv_direction == 5 ; wobble back and forth
  806. add dl, invader_steps
  807. .ELSEIF inv_direction == 10
  808. sub dl, invader_steps
  809. .ENDIF
  810. .IF dl < 5 ; don't let invaders go out of bounds
  811. mov dl, 5
  812. .ELSEIF dl > 70
  813. mov dl, 70
  814. .ENDIF
  815. mov [esi], dl
  816. ; ----------
  817. mov esi, OFFSET invader_row ; get invader row array
  818. add esi, icounter
  819. mov dh, [esi] ; set dh to current row of icounter invader
  820. mov esi, OFFSET invader_col ; get invader column array
  821. add esi, icounter
  822. mov dl, [esi] ; set dh to current column of icounter invader
  823. call PRINT_INVADER
  824. ; ----------
  825. NextInvader:
  826. inc icounter
  827. cmp icounter, 14 ; loop for all invaders
  828. jl ShiftInvaders
  829. .IF inv_direction < 15 ; don't wobble every time
  830. inc inv_direction
  831. .ELSE
  832. mov inv_direction, 0
  833. .ENDIF
  834. ret
  835. ; ##################################################
  836. SHIFT_INVADERS ENDP
  837. ; ##################################################
  838.  
  839. ;---------------------------------------------------
  840. main proc
  841. ; our glorious starting point
  842. ;---------------------------------------------------
  843. call Clrscr ; clear the screen
  844. call INIT_GAME ; initialize game variables and start game
  845. call WaitMsg
  846. exit ; game over!
  847. main endp
  848. end main
  849. ;---------------------------------------------------
0
gsbr gsbr is offline Offline | Aug 8th, 2008
Looks nice , but ..I cannot translate nor test

1/ What is that Irvine 32 ?
2/ What is the assembler ?

I personally use RosAsm,It is very user friendly (when past the querks) (original : It contains its source in the PE file)
I would like , as an exercise , to translate to RosAsm
I have plenty stuff in RosAsm , simple to complicated . (including up to FFT's )

gsbr
 
0
randutty randutty is offline Offline | Oct 14th, 2009
Hi..........
I am abeginner to assembly language and we are using 8051 assembly language..Can anyone plz help me to convert space invaders program into 8051 assembly language so that it will be helpful to me.........I need to understand the logic too...
Thank you
 
 

Message:


Similar Threads
Thread Tools Search this Thread



Tag cloud for Assembly
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC