User Tools

Site Tools


sd:writing_games_in_assembly_language

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
sd:writing_games_in_assembly_language [2026/05/10 13:44] appledogsd:writing_games_in_assembly_language [2026/05/10 16:36] (current) appledog
Line 1076: Line 1076:
     CALL @draw_borders     CALL @draw_borders
     CALL @draw_world     CALL @draw_world
-    CALL @draw_player 
     CALL @draw_mobs     CALL @draw_mobs
 +    CALL @draw_player
     CALL @draw_stats     CALL @draw_stats
     CALL @draw_msgs     CALL @draw_msgs
Line 1662: Line 1662:
     JZ @draw_items_loop    ; Skip non-initialized/empty objects     JZ @draw_items_loop    ; Skip non-initialized/empty objects
  
 +    LDI @OBJ_TYPE
 +    LDA [ELM+I]
 +    CMP A, #1
 +    JNZ @draw_items_loop         ; not amn item. skip
 +    
     ; Does this item have an X and Y position?     ; Does this item have an X and Y position?
     LDI @OBJ_X     LDI @OBJ_X
Line 2112: Line 2117:
     CALL @draw_world     CALL @draw_world
     ;CALL @draw_items     ;CALL @draw_items
-    ;CALL @draw_player 
     ;CALL @draw_mobs     ;CALL @draw_mobs
 +    ;CALL @draw_player
     CALL @draw_stats     CALL @draw_stats
     CALL @draw_msgs     CALL @draw_msgs
Line 3281: Line 3286:
     PUSH B     PUSH B
  
-    ; --- Default: map tile glyph ---+    ; map tile glyph
     LDK [@map1_dim]     LDK [@map1_dim]
     MOV Z, Y     MOV Z, Y
Line 3290: Line 3295:
     LDAL [ELM]              ; AL = map glyph (default return)     LDAL [ELM]              ; AL = map glyph (default return)
  
-    ; --- Override if any object sits at (X, Y) ---+    ; Override if any object sits at (X, Y)
     LDFLD @OBJS_BASE     LDFLD @OBJS_BASE
 get_glyph_obj_loop: get_glyph_obj_loop:
     LDFLD [FLD]     LDFLD [FLD]
     CMP FLD, @OBJS_BASE     CMP FLD, @OBJS_BASE
-    JZ @get_glyph_done      ; wrapped to head, no match → keep map glyph+    JZ @get_glyph_done      ; wrapped to head, no matchkeep map glyph
  
     LDI @OBJ_ID     LDI @OBJ_ID
Line 3311: Line 3316:
     JNZ @get_glyph_obj_loop     JNZ @get_glyph_obj_loop
  
-    ; Match — override AL with the object's VIS, then exit loop+    ; Match will override AL with the object's VIS, then exit loop
     LDI @OBJ_VIS     LDI @OBJ_VIS
     LDAL [FLD+I]     LDAL [FLD+I]
Line 3383: Line 3388:
  
 ==== move_mon ==== move_mon
-This is where we attempt to move the monsters.+This is where we attempt to move the monsters. Don't forget to move them //before// you draw them in the game loop: 
 + 
 +draw_map: 
 +    LDAH $51        ; VSTOP 
 +    INT 0x18 
 + 
 +    CALL @draw_borders 
 +    CALL @draw_world 
 +    CALL @draw_items 
 +    CALL @move_mon 
 +    CALL @draw_mobs 
 +    CALL @draw_player 
 +    CALL @draw_stats 
 +    CALL @draw_msgs 
 +    CALL @msg_display 
 + 
 +    LDAH $50        ; VSTART 
 +    INT 0x18 
 + 
 +    RET
  
 Add this in, and add ''CALL @move_mon'' before ''CALL @draw_mon'' in ''draw_map:''. Add this in, and add ''CALL @move_mon'' before ''CALL @draw_mon'' in ''draw_map:''.
Line 3411: Line 3435:
     JNZ @move_mon_loop     JNZ @move_mon_loop
  
-    ; --- (mx, my) --- 
     LDI @OBJ_X     LDI @OBJ_X
     LDXL [ELM+I]     LDXL [ELM+I]
Line 3445: Line 3468:
 mm_dy_done: mm_dy_done:
  
-    ; --- Pick axis ---+    ; Pick axis
     CMP CL, #0     CMP CL, #0
     JNZ @mm_dx_nz     JNZ @mm_dx_nz
Line 3456: Line 3479:
     JZ  @mm_use_x     JZ  @mm_use_x
  
-    ; Both non-zero — coin flip+    ; Both non-zero (coin flip)
     LDAH $00     LDAH $00
     INT 0x13     INT 0x13
Line 3603: Line 3626:
     CMP AL, YL     CMP AL, YL
     JNZ @mm_check_obj     JNZ @mm_check_obj
-    +
     ; Target tile IS the player, so attack instead of move     ; Target tile IS the player, so attack instead of move
     LDFLD @player_obj           ; ELM attacks FLD     LDFLD @player_obj           ; ELM attacks FLD
 +
     CALL @do_combat     CALL @do_combat
     JMP @move_mon_loop          ; monster's turn is spent attacking     JMP @move_mon_loop          ; monster's turn is spent attacking
Line 3618: Line 3642:
     ; commit the move     ; commit the move
     POP ELM     POP ELM
 +    SED
     LDI @OBJ_X     LDI @OBJ_X
     STXL [ELM+I]     STXL [ELM+I]
     LDI @OBJ_Y     LDI @OBJ_Y
     STYL [ELM+I]     STYL [ELM+I]
 +    CLD
     JMP @move_mon_loop     JMP @move_mon_loop
  
Line 3659: Line 3685:
 str_unknown: str_unknown:
     .bytes "thing ", 0     .bytes "thing ", 0
 +str_dies:
 +    .bytes "dies!", 13, 10, 0
 +str_you_die:
 +    .bytes "You die!", 13, 10, 0
  
 copy_player_to_obj: copy_player_to_obj:
     PUSH ELM     PUSH ELM
 +    PUSH A
 +    PUSH I
 +
     LDELM @player_obj     LDELM @player_obj
  
Line 3671: Line 3704:
     LDA [@player_str]     LDA [@player_str]
     STA [ELM+I]     STA [ELM+I]
 +
 +    POP I
 +    POP A
     POP ELM     POP ELM
     RET     RET
Line 3676: Line 3712:
 copy_obj_to_player: copy_obj_to_player:
     PUSH ELM     PUSH ELM
 +    PUSH A
 +    PUSH I
     LDELM @player_obj     LDELM @player_obj
  
Line 3685: Line 3723:
     LDA [ELM+I]     LDA [ELM+I]
     STA [@player_str]     STA [@player_str]
 +    POP I
 +    POP A
     POP ELM     POP ELM
     RET     RET
Line 3691: Line 3731:
 print_mon_name: print_mon_name:
     PUSH ELM     PUSH ELM
 +    PUSH A
 +    PUSH I
     LDI @OBJ_VIS     LDI @OBJ_VIS
     LDAL [ELM+I]     LDAL [ELM+I]
Line 3699: Line 3741:
     CMP AL, #'x'     CMP AL, #'x'
     JZ  @pmn_spider     JZ  @pmn_spider
-    LDFLD @str_unknown+    LDELM @str_unknown
     JMP @pmn_emit     JMP @pmn_emit
 pmn_rat: pmn_rat:
-    LDFLD @str_rat+    LDELM @str_rat
     JMP @pmn_emit     JMP @pmn_emit
 pmn_snake: pmn_snake:
-    LDFLD @str_snake+    LDELM @str_snake
     JMP @pmn_emit     JMP @pmn_emit
 pmn_spider: pmn_spider:
-    LDFLD @str_spider+    LDELM @str_spider
 pmn_emit: pmn_emit:
     CALL @print_msg     CALL @print_msg
 +    POP I
 +    POP A
     POP ELM     POP ELM
     RET     RET
Line 3722: Line 3766:
 ;; Note: If player is attacking or defending, ;; Note: If player is attacking or defending,
 ;;       pass @player_obj in ELM or FLD as appropriate. ;;       pass @player_obj in ELM or FLD as appropriate.
 +;;       If the player is not involved, syncing doesn't hurt.
 ;; ;;
 do_combat: do_combat:
-    ; sync player to data object. +    ; sync
-    ; This is a bit bad since we could have checked +
-    ; if the player was involved in combat +
-    ; or not, but, it doesn't matter.+
     CALL @copy_player_to_obj     CALL @copy_player_to_obj
  
 combat_damage: combat_damage:
-    ; Part 2: damage+    ; part 2: damage
-    ; This has been simplified. +
-    ; We will just take 1 HP off the defender. +
-    ; Later you could make this based off STR, or make it random, anything.+
     LDI @OBJ_DATA1     LDI @OBJ_DATA1
-    LDAL [FLD+I] +    LDA [FLD+I] 
-    JZ @combat_kill        ; defender already at 0 (defensive)+    JZ  @combat_msg                   ; defender already 0 (defensive)
     DEC AL     DEC AL
-    JZ @combat_kill        ; just dropped to 0 +    STAL [FLD+I]                      ; HP -= 1, stored (may be 0)
-    STAL [FLD+I]           ; HP -= 1, survives +
-    JMP @combat_msg +
- +
-combat_kill: +
-    LDAL #0 +
-    STAL [FLD+I]           ; HP = 0 +
-    CMP FLD, @player_obj +
-    JZ @combat_msg         ; player died? let game loop notice +
-    LDI @OBJ_ID +
-    LDA #0 +
-    STA [FLD+I]            ; monster: free the slot+
  
 combat_msg: combat_msg:
     CMP ELM, @player_obj     CMP ELM, @player_obj
-    JZ @combat_msg_player+    JZ  @combat_msg_player 
 +    PUSH ELM 
 +    LDELM @str_the 
 +    CALL @print_msg 
 +    POP ELM
  
-    ; "The <name>attacks for 1 damage!\n" +    CALL @print_mon_name              ; ELM = attacker 
-    LDFLD @str_the +    PUSH ELM 
-    CALL @print_msg +    LDELM @str_attacks
-    CALL @print_mon_name   ; emits "rat " / "snake " / "spider " +
-    LDFLD @str_attacks+
     CALL @print_msg     CALL @print_msg
-    JMP @combat_post+    POP ELM 
 +    JMP @combat_check_dead
  
 combat_msg_player: combat_msg_player:
-    ; "You attack for 1 damage!\n" +    PUSH ELM 
-    LDFLD @str_you+    LDELM @str_you
     CALL @print_msg     CALL @print_msg
-    LDFLD @str_attack+    LDELM @str_attack
     CALL @print_msg     CALL @print_msg
 +    POP ELM
 +
 +combat_check_dead:
 +    LDI @OBJ_DATA1
 +    LDA [FLD+I]
 +    JNZ @combat_post
 +    CALL @kill_obj
  
 combat_post: combat_post:
-    ; Sync obj back to player 
-    ; We might not have to do this, but if the player wasn't involved it doesn't hurt. 
     CALL @copy_obj_to_player     CALL @copy_obj_to_player
  
 combat_done: combat_done:
     RET     RET
 +
 +
 +kill_obj:
 +    ; Monster dies
 +    ; player will be handled in main loop
 +    PUSH ELM                         ; save caller's attacker
 +    MOV ELM, FLD                    ; ELM = victim for everything below
 +
 +    PUSH ELM
 +    LDELM @str_the
 +    CALL @print_msg
 +    POP ELM
 +    CALL @print_mon_name              ; reads OBJ_VIS via ELM = victim
 +    PUSH ELM
 +    LDELM @str_dies
 +    CALL @print_msg
 +    POP ELM
 +
 +    LDI @OBJ_ID
 +    LDA #0
 +    STA [ELM+I]                       ; free the slot
 +
 +    POP ELM                           ; restore attacker
 +    RET
 +
 +
 +kill_player:
 +    PUSH ELM
 +    LDELM @str_you_die
 +    CALL @print_msg
 +    POP ELM
 +
 +    ; CLS
 +    LDAH $10
 +    INT $10
 +
 +    ; Print "You died."
 +    LDBLX @msg_died
 +    LDAH $66
 +    INT $05
 +
 +    POP ELM ; get rid of return address from CALL @draw_map game loop
 +    RET     ; exit program.
 </codify> </codify>
 +
 +Finally, if the player is dead, we end the game. in ''draw_map:''
 +
 +    ...
 +    CALL @draw_stats
 +    CALL @draw_msgs
 +    CALL @msg_display
 +    
 +    LDAH $50        ; VSTART
 +    INT 0x18
 +    
 +    LDA [@player_hp]
 +    CMP A, 0
 +    JZ @kill_player
 +
 +    RET
 +    
  
 == Appendix III: DungeonMaker == Appendix III: DungeonMaker
sd/writing_games_in_assembly_language.1778420690.txt.gz · Last modified: by appledog

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki