User Tools

Site Tools


sd:rogueima_i_mvp-4

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:rogueima_i_mvp-4 [2026/05/09 15:51] appledogsd:rogueima_i_mvp-4 [2026/05/10 16:47] (current) appledog
Line 1: Line 1:
 = Rogueima I MPV-4 = Rogueima I MPV-4
  
-* rogueima.sda 559 +* rogueima.asm: 384 
-* draw.sda 282 +* draw.asm: 247 
-* map.sda 54+* map.asm: 51 
 +* mon.asm: 99 
 +* msg.asm: 166 
 +* obj.asm: 171 
 +* talk.asm: 166 
 +* combat.asm: 149 
 + 
 +Total: 1,385 SLOC. According to SLOCCOUNT, a program by David A. Wheeler, using traditional software development metrics this program would have taken four months and cost $38,033 to develop. The four months is about right, then again I did this in about 2 months; and frankly, I would have done it for half the cost!
  
 == rogueima.sda == rogueima.sda
Line 78: Line 85:
     CALL @draw_map     CALL @draw_map
     CALL @get_input     CALL @get_input
-    CALL @move_mobs 
-    ;CALL @robot_beep 
     CALL @inc_game_time     CALL @inc_game_time
  
Line 231: Line 236:
     RET     RET
  
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
-;; Move the robot. 
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
-move_mobs: 
-    RET 
  
 ;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;
Line 276: Line 276:
     POP ELM ; destroy return address of CALL from main loop     POP ELM ; destroy return address of CALL from main loop
     RET     ; exit program.     RET     ; exit program.
- 
-robot_beep: 
-    LDELM @robot_sfx 
-    LDAH $52 
-    INT $11 
-    RET 
  
 ; ============================================================================ ; ============================================================================
Line 292: Line 286:
 msg_quit: msg_quit:
     .bytes "QUIT GAME", 10,13,0     .bytes "QUIT GAME", 10,13,0
 +msg_died:
 +    .bytes "You died.", 10,13,0
 robot_sfx: robot_sfx:
     .bytes "T120 W1 V5 O2 L24 B", 0     .bytes "T120 W1 V5 O2 L24 B", 0
Line 587: Line 583:
     CALL @draw_world     CALL @draw_world
     CALL @draw_items     CALL @draw_items
-    CALL @draw_player+    CALL @move_mon
     CALL @draw_mobs     CALL @draw_mobs
 +    CALL @draw_player
     CALL @draw_stats     CALL @draw_stats
     CALL @draw_msgs     CALL @draw_msgs
Line 595: Line 592:
     LDAH $50        ; VSTART     LDAH $50        ; VSTART
     INT 0x18     INT 0x18
 +
 +    LDA [@player_hp]
 +    CMP A, 0
 +    JZ @kill_player
  
     RET     RET
Line 669: Line 670:
     RET     RET
  
 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +;; Draw all the monsters that are placed on the map.
 +;; Filters on OBJ_TYPE == 2 (monster), skips items.
 +;;
 draw_mobs: draw_mobs:
-    ; stub for now+    LDD [@cam_origin_x]         DL = I_start, DH = J_start 
 +    LDT [@disp_dim]             ; TL = play_width, TH = play_height 
 +    LDELM @OBJS_BASE 
 +draw_mobs_loop: 
 +    LDELM [ELM] 
 +    CMP ELM, @OBJS_BASE 
 +    JZ @draw_mobs_done 
 + 
 +    LDI @OBJ_ID 
 +    LDA [ELM+I] 
 +    JZ @draw_mobs_loop          ; uninitialized slot 
 + 
 +    LDI @OBJ_TYPE 
 +    LDA [ELM+I] 
 +    CMP A, #2                    ; OBJ_TYPE_MONSTER 
 +    JNZ @draw_mobs_loop         ; not a mob → skip 
 + 
 +    LDI @OBJ_X 
 +    LDX [ELM+I] 
 +    LDI @OBJ_Y 
 +    LDY [ELM+I] 
 + 
 +    ; --- Visibility: is (XL, YL) inside the viewport? --- 
 +    CMP XL, DL 
 +    JNC @draw_mobs_loop          ; XL < I_start → off-screen left 
 +    MOV AL, DL 
 +    ADD AL, TL 
 +    CMP XL, AL 
 +    JC  @draw_mobs_loop          ; XL >= I_start + TL → off-screen right 
 + 
 +    CMP YL, DH 
 +    JNC @draw_mobs_loop 
 +    MOV AL, DH 
 +    ADD AL, TH 
 +    CMP YL, AL 
 +    JC  @draw_mobs_loop 
 + 
 +    ; --- Map → screen --- 
 +    SUB XL, DL 
 +    ADD XL, #1                   ; play_x_offset 
 +    SUB YL, DH 
 +    ADD YL, #1                   ; play_y_offset 
 + 
 +    ; --- Draw --- 
 +    LDI @OBJ_VIS 
 +    LDBL [ELM+I] 
 +    LDAH $11 
 +    INT $10 
 +    JMP @draw_mobs_loop 
 +draw_mobs_done:
     RET     RET
  
Line 1054: Line 1108:
     STAL [ELM+I]     STAL [ELM+I]
     RET     RET
-</codify>+ 
 + 
 +;;;;;;;;;;;;;;;;;; 
 +;; has_mon(x,y) 
 +;; 
 +;; Returns CARRY SET if monster. 
 +;; Returns monster pointer in FLD. 
 +;; 
 +has_mon: 
 +    PUSH I 
 +    PUSH B 
 + 
 +    LDFLD @OBJS_BASE 
 +has_mon_loop: 
 +    LDFLD [FLD] 
 +    CMP FLD, @OBJS_BASE 
 +    JZ @has_mon_no 
 + 
 +    LDI @OBJ_ID 
 +    LDB [FLD+I] 
 +    JZ @has_mon_loop           ; uninitialized slot 
 + 
 +    LDI @OBJ_TYPE 
 +    LDB [FLD+I] 
 +    CMP B, #2                   ; OBJ_TYPE_MONSTER 
 +    JNZ @has_mon_loop 
 + 
 +    LDI @OBJ_X 
 +    LDBL [FLD+I] 
 +    CMP BL, XL 
 +    JNZ @has_mon_loop 
 + 
 +    LDI @OBJ_Y 
 +    LDBL [FLD+I] 
 +    CMP BL, YL 
 +    JNZ @has_mon_loop 
 + 
 +    ; Match returns pointer in FLD, CF=1 
 +    SEC 
 +    JMP @has_mon_done 
 + 
 +has_mon_no: 
 +    CLC                          ; no monster; FLD unchanged. 
 + 
 +has_mon_done: 
 +    POP B 
 +    POP I 
 +    RET 
 + 
 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
 +;; move_mon 
 +;; 
 +;; Attempt to move every live monster 
 +;; towards the player 
 +;; 
 +move_mon: 
 +    LDELM @OBJS_BASE 
 +move_mon_loop: 
 +    LDELM [ELM] 
 +    CMP ELM, @OBJS_BASE 
 +    JZ @move_mon_done 
 + 
 +    ; live monsters only 
 +    LDI @OBJ_ID 
 +    LDA [ELM+I] 
 +    JZ @move_mon_loop 
 +    LDI @OBJ_TYPE 
 +    LDA [ELM+I] 
 +    CMP A, #2                  ; OBJ_TYPE_MONSTER 
 +    JNZ @move_mon_loop 
 + 
 +    LDI @OBJ_X 
 +    LDXL [ELM+I] 
 +    LDI @OBJ_Y 
 +    LDYL [ELM+I] 
 + 
 +    ; sign(PX - mx) to CL 
 +    LDAL [@PX] 
 +    CMP AL, XL 
 +    JZ  @mm_dx_zero 
 +    JC  @mm_dx_pos             ; PX > mx 
 +    LDCL #$FF                  ; PX < mx, step left 
 +    JMP @mm_dx_done 
 + 
 +mm_dx_pos: 
 +    LDCL #$01 
 +    JMP @mm_dx_done 
 + 
 +mm_dx_zero: 
 +    LDCL #$00 
 + 
 +mm_dx_done: 
 +    LDAL [@PY] 
 +    CMP AL, YL 
 +    JZ  @mm_dy_zero 
 +    JC  @mm_dy_pos 
 +    LDDL #$FF 
 +    JMP @mm_dy_done 
 + 
 +mm_dy_pos: 
 +    LDDL #$01 
 +    JMP @mm_dy_done 
 + 
 +mm_dy_zero: 
 +    LDDL #$00 
 + 
 +mm_dy_done: 
 +    ; Pick axis 
 +    CMP CL, #0 
 +    JNZ @mm_dx_nz 
 +    CMP DL, #0 
 +    JZ  @move_mon_loop         ; both zero, monster sits on player, skip 
 +    JMP @mm_use_y 
 + 
 +mm_dx_nz: 
 +    CMP DL, #0 
 +    JZ  @mm_use_x 
 + 
 +    ; Both non-zero; coin flip 
 +    LDAH $00 
 +    INT 0x13 
 +    MOD B, #2 
 +    CMP B, #0 
 +    JZ  @mm_use_x 
 +    ; fall through to mm_use_y 
 + 
 +mm_use_y: 
 +    ADD YL, DL                 ; YL = my + sign(dy) 
 +    JMP @mm_check 
 + 
 +mm_use_x: 
 +    ADD XL, CL                 ; XL = mx + sign(dx) 
 + 
 +mm_check: 
 +    LDAL [@PX] 
 +    CMP AL, XL 
 +    JNZ @mm_check_obj 
 +    LDAL [@PY] 
 +    CMP AL, YL 
 +    JNZ @mm_check_obj 
 + 
 +    ; Target tile IS the player, so attack instead of move 
 +    LDFLD @player_obj           ; ELM attacks FLD 
 + 
 +    CALL @do_combat 
 +    JMP @move_mon_loop          ; monster's turn is spent attacking 
 + 
 +mm_check_obj: 
 +    PUSH ELM 
 +    CALL @has_mon 
 +    JC  @mm_pop_skip            ; another monster occupies target 
 +    CALL @is_walkable 
 +    JNC @mm_pop_skip            ; wall or other non-walkable 
 + 
 +    ; commit the move 
 +    POP ELM 
 +    SED 
 +    LDI @OBJ_X 
 +    STXL [ELM+I] 
 +    LDI @OBJ_Y 
 +    STYL [ELM+I] 
 +    CLD 
 +    JMP @move_mon_loop 
 + 
 +mm_pop_skip: 
 +    POP ELM 
 +    JMP @move_mon_loop 
 + 
 +move_mon_done: 
 +    RET</codify>
  
 == msg.sda == msg.sda
Line 1465: Line 1688:
     LDA [ELM+I]     LDA [ELM+I]
     JZ @draw_items_loop     JZ @draw_items_loop
 +
 +    LDI @OBJ_TYPE
 +    LDA [ELM+I]
 +    CMP A, #1                  ; OBJ_TYPE_GOLD — this filter is the fix
 +    JNZ @draw_items_loop
  
     LDI @OBJ_X     LDI @OBJ_X
Line 1782: Line 2010:
 </codify> </codify>
  
 +== combat.sda
 +<codify armasm>
 +player_obj:
 +    ; 40 bytes, about sizeof(OBJ)
 +    .bytes 0,0,0,0,0,0,0,0,0,0
 +    .bytes 0,0,0,0,0,0,0,0,0,0
 +    .bytes 0,0,0,0,0,0,0,0,0,0
 +    .bytes 0,0,0,0,0,0,0,0,0,0
 +
 +str_you:
 +    .bytes "You ", 0
 +str_the:
 +    .bytes "The ", 0
 +str_attack:
 +    .bytes "attack for 1 damage!", 13, 10, 0   ; player verb
 +str_attacks:
 +    .bytes "attacks for 1 damage!", 13, 10, 0  ; monster verb
 +str_rat:
 +    .bytes "rat ", 0
 +str_snake:
 +    .bytes "snake ", 0
 +str_spider:
 +    .bytes "spider ", 0
 +str_unknown:
 +    .bytes "thing ", 0
 +str_dies:
 +    .bytes "dies!", 13, 10, 0
 +str_you_die:
 +    .bytes "You die!", 13, 10, 0
 +
 +copy_player_to_obj:
 +    PUSH ELM
 +    PUSH A
 +    PUSH I
 +
 +    LDELM @player_obj
 +
 +    LDI @OBJ_DATA1
 +    LDA [@player_hp]
 +    STA [ELM+I]
 +
 +    LDI @OBJ_DATA2
 +    LDA [@player_str]
 +    STA [ELM+I]
 +
 +    POP I
 +    POP A
 +    POP ELM
 +    RET
 +
 +copy_obj_to_player:
 +    PUSH ELM
 +    PUSH A
 +    PUSH I
 +    LDELM @player_obj
 +
 +    LDI @OBJ_DATA1
 +    LDA [ELM+I]
 +    STA [@player_hp]
 +
 +    LDI @OBJ_DATA2
 +    LDA [ELM+I]
 +    STA [@player_str]
 +    POP I
 +    POP A
 +    POP ELM
 +    RET
 +
 +print_mon_name:
 +    PUSH ELM
 +    PUSH A
 +    PUSH I
 +    LDI @OBJ_VIS
 +    LDAL [ELM+I]
 +    CMP AL, #'r'
 +    JZ  @pmn_rat
 +    CMP AL, #'s'
 +    JZ  @pmn_snake
 +    CMP AL, #'x'
 +    JZ  @pmn_spider
 +    LDELM @str_unknown
 +    JMP @pmn_emit
 +pmn_rat:
 +    LDELM @str_rat
 +    JMP @pmn_emit
 +pmn_snake:
 +    LDELM @str_snake
 +    JMP @pmn_emit
 +pmn_spider:
 +    LDELM @str_spider
 +pmn_emit:
 +    CALL @print_msg
 +    POP I
 +    POP A
 +    POP ELM
 +    RET
 +
 +
 +
 +;;;;;;;;;;;;;;;;;;;;;;;;;;
 +;; Call with:
 +;; ELM is the attacker
 +;; FLD is the defender
 +;; Note: If player is attacking or defending,
 +;;       pass @player_obj in ELM or FLD as appropriate.
 +;;       If the player is not involved, syncing doesn't hurt.
 +;;
 +do_combat:
 +    ; sync
 +    CALL @copy_player_to_obj
 +
 +combat_damage:
 +    ; part 2: damage
 +    LDI @OBJ_DATA1
 +    LDA [FLD+I]
 +    JZ  @combat_msg                   ; defender already 0 (defensive)
 +    DEC AL
 +    STAL [FLD+I]                      ; HP -= 1, stored (may be 0)
 +
 +combat_msg:
 +    CMP ELM, @player_obj
 +    JZ  @combat_msg_player
 +    PUSH ELM
 +    LDELM @str_the
 +    CALL @print_msg
 +    POP ELM
 +
 +    CALL @print_mon_name              ; ELM = attacker
 +    PUSH ELM
 +    LDELM @str_attacks
 +    CALL @print_msg
 +    POP ELM
 +    JMP @combat_check_dead
 +
 +combat_msg_player:
 +    PUSH ELM
 +    LDELM @str_you
 +    CALL @print_msg
 +    LDELM @str_attack
 +    CALL @print_msg
 +    POP ELM
 +
 +combat_check_dead:
 +    LDI @OBJ_DATA1
 +    LDA [FLD+I]
 +    JNZ @combat_post
 +    CALL @kill_obj
 +
 +combat_post:
 +    CALL @copy_obj_to_player
 +
 +combat_done:
 +    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>
sd/rogueima_i_mvp-4.1778341900.txt.gz · Last modified: by appledog

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki