From 4ee3298550e97e59a279b9950f6d1d4c6355173d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 4 Apr 2006 11:53:45 +0000 Subject: Completed disassembly of the Lure pathfinding code svn-id: r21593 --- engines/lure/diassembly/LURE.ASM | 688 ++++++++++++++++++--------------- engines/lure/diassembly/Lure_notes.txt | 24 ++ 2 files changed, 395 insertions(+), 317 deletions(-) (limited to 'engines/lure') diff --git a/engines/lure/diassembly/LURE.ASM b/engines/lure/diassembly/LURE.ASM index 8dc96d8d8b..a06a1073c0 100644 --- a/engines/lure/diassembly/LURE.ASM +++ b/engines/lure/diassembly/LURE.ASM @@ -27,6 +27,11 @@ NUM_VERT_RECTS equ 6 FULL_HORIZ_RECTS equ 18 FULL_VERT_RECTS equ 14 +ROOM_PATHS_WIDTH equ 40 +ROOM_PATHS_HEIGHT equ 24 +DECODED_PATHS_WIDTH equ 42 +DECODED_PATHS_HEIGHT equ 26 + WRITE_BUFFER_SIZE equ 0f010h FILE_BUFFER_SIZE equ 0600h ENTRY_READ_BUFFER equ 80h @@ -296,8 +301,8 @@ FACING_RIGHT equ 3 FACING2_LEFT equ 1 FACING2_RIGHT equ 2 -FACING2_DOWN equ 3 FACING2_UP equ 4 +FACING2_DOWN equ 8 ; Movement record constants MOVEMENT_FRAME_NUM equ 0 @@ -330,6 +335,21 @@ CHAR_ACTION_EXEC_SCRIPT equ 3 CHAR_ACTION_PROCESSING_PATH equ 4 CHAR_ACTION_CONTINUE_WALK equ 5 +PATHFIND_CHARACTER_ID equ 2 +PATHFIND_HS4C equ 4 +PATHFIND_DEST_STATE equ 5 +PATHFIND_DEST_X equ 6 +PATHFIND_DEST_Y equ 8 +PATHFIND_X equ 0Ch +PATHFIND_Y equ 0Ah +PATHFIND_0E equ 0Eh +PATHFIND_DEST_X2 equ 10h +PATHFIND_DEST_OCCUPIED equ 12h +PATHFIND_CELL_POPULATED equ 13h +PATHFIND_X_CHANGE1 equ 14h +PATHFIND_Y_CHANGE1 equ 16h +PATHFIND_X_CHANGE2 equ 18h +PATHFIND_Y_CHANGE2 equ 1Ah ; The following equates show data references outside the range of the program. @@ -11422,24 +11442,9 @@ CHAR_ACTION_CONTINUE_WALK equ 5 ; ax=character Hotspot Id, bx=dest x, cx=dest y, dl=[4ch] ;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ -3983h/4227h = record - 2 = ax hotspot Id - 4 = HS[4Ch] - 6 = dest x - 8 = dest y -end; - -TEMP_CHARACTER_ID equ 2 -TEMP_HS4C equ 04h -TEMP_DEST_X equ 06h -TEMP_DEST_Y equ 08h -TEMP_X equ 0Ch -TEMP_Y equ 0Ah -TEMP_DEST_X2 equ 10h - character_pathfind proc near 273F:49F6 89 26 3942 mov pathfind_sp, sp ; Backup current SP -273F:49FA C7 06 3944 0FA0 mov pathfind_v2, 0FA0h +273F:49FA C7 06 3944 0FA0 mov pathfind_countdown_ctr, 0FA0h 273F:4A00 F6 06 3946 FF test pathfind_in_progress, 0FFh 273F:4A05 74 0E jz loc_933 ; Jump if zero 273F:4A07 3D 03E8 cmp ax, PLAYER_HOTSPOT_ID @@ -11469,8 +11474,8 @@ TEMP_DEST_X2 equ 10h 273F:4A37 loc_935: ; xref 273F:4A1E 273F:4A37 C6 06 3946 01 mov pathfind_in_progress, 1 273F:4A3C loc_936: ; xref 273F:4A2A -273F:4A3C 88 54 04 mov [si+TEMP_HS4C], dl ; Store HS[4Ch] -273F:4A3F 89 44 02 mov [si+TEMP_CHARACTER_ID], ax ; Store character Id +273F:4A3C 88 54 04 mov [si+PATHFIND_HS4C], dl +273F:4A3F 89 44 02 mov [si+PATHFIND_CHARACTER_ID], ax ; Store character Id 273F:4A42 8B E5 mov sp, bp ; Handle adjusting destination X for left & right screen edges to place it completely @@ -11484,8 +11489,8 @@ TEMP_DEST_X2 equ 10h 273F:4A53 72 03 jb loc_938 ; Jump if below 273F:4A55 83 C3 32 add bx, 50 273F:4A58 loc_938: -273F:4A58 89 5C 06 mov [si+TEMP_DEST_X], bx ; Store X -273F:4A5B 89 4C 08 mov [si+TEMP_DEST_Y], cx ; Store Y +273F:4A58 89 5C 06 mov [si+PATHFIND_DEST_X], bx ; Store X +273F:4A5B 89 4C 08 mov [si+PATHFIND_DEST_Y], cx ; Store Y 273F:4A5E 8B 6D 13 mov bp, [di+ANIM_WIDTH_COPY] 273F:4A61 83 ED 01 sub bp, 1 @@ -11493,6 +11498,8 @@ TEMP_DEST_X2 equ 10h 273F:4A66 D3 ED shr bp, cl ; bp=(width copy-1)/8 273F:4A68 57 push di 273F:4A69 ú81 C6 08A2 add si, 8A2h + +; Figure out the address for the bit-compressed data for screen walkable areas 273F:4A6D 8B 45 0E mov ax, [di+ANIM_ROOM_NUM] 273F:4A70 8B D8 mov bx, ax 273F:4A72 B1 04 mov cl, 4 @@ -11500,6 +11507,12 @@ TEMP_DEST_X2 equ 10h 273F:4A76 2B C3 sub ax, bx 273F:4A78 B1 03 mov cl, 3 273F:4A7A D3 E0 shl ax, cl ; ax=Room # * 120 + +; Extract the bit-compressed data of the pathfinding data for the room into an +; uncompressed 26*42 byte array indicating whether each 8x8 pixel block on screen +; (and a surrounding column and row around the screen edge) can be traveled on +; cx = bit number, dl = number of columns, dh = number of rows + 273F:4A7C 05 9849 add ax, offset pathfind_data2 - 1 273F:4A7F 1E push ds 273F:4A80 07 pop es @@ -11507,26 +11520,22 @@ TEMP_DEST_X2 equ 10h 273F:4A83 8B F0 mov si, ax ; si=end of pathfind layer for room 273F:4A85 FD std ; Set for reverse direction 273F:4A86 33 C0 xor ax, ax -273F:4A88 B9 002B mov cx, 2Bh +273F:4A88 B9 002B mov cx, 2Bh ; # cols + start col of row #2 273F:4A8B F3/ AB rep stosw ; Clear area 273F:4A8D 83 C7 01 add di, 1 ; For player di=41D0h -; Extract the bit-compressed data of the pathfinding data for the room into an -; uncompressed array indicating whether each 8x8 pixel block can be traveled on -; cx = bit number, dl = number of columns, dh = number of rows - -273F:4A90 B6 18 mov dh, 18h +273F:4A90 B6 18 mov dh, 24 ; Number of rows on-screen 273F:4A92 loc_939: -273F:4A92 B2 05 mov dl, 5 +273F:4A92 B2 05 mov dl, 5 ; Number of bytes horizontally 273F:4A94 loc_940: -273F:4A94 AC lodsb ; ax=c6h, si=98c0h -273F:4A95 86 E0 xchg ah, al -273F:4A97 32 C0 xor al, al ; ax=c600h -273F:4A99 B9 0008 mov cx, 8 +273F:4A94 AC lodsb ; Get next byte +273F:4A95 86 E0 xchg ah, al ; Move it into AH +273F:4A97 32 C0 xor al, al ; Reset AL to 0 for storage +273F:4A99 B9 0008 mov cx, 8 ; Number of bits in the byte 273F:4A9C locloop_941: ; xref 273F:4AA2, 4AB3 -273F:4A9C D0 EC shr ah, 1 ; Shift w/zeros fill +273F:4A9C D0 EC shr ah, 1 ; Move next bit for processing 273F:4A9E 72 06 jc loc_942 ; Jump if bit set (block occupied) 273F:4AA0 AA stosb ; Store 0 to es:[di] 273F:4AA1 AA stosb ; Store 0 to es:[di] @@ -11579,25 +11588,26 @@ TEMP_DEST_X2 equ 10h 273F:4AE5 80 EE 01 sub dh, 1 273F:4AE8 75 A8 jnz loc_939 ; Jump if not zero -; End of decompression code for the path finding layer 273F:4AEA 83 EF 01 sub di, 1 -273F:4AED B9 0029 mov cx, 29h -273F:4AF0 33 C0 xor ax, ax ; Zero register -273F:4AF2 F3/ AB rep stosw ; Rep when cx >0 Store ax to es:[di] -273F:4AF4 83 EF 1A sub di, 1Ah ; di=3983 again +273F:4AED B9 0029 mov cx, 29h ; Handle final off-screen row +273F:4AF0 33 C0 xor ax, ax +273F:4AF2 F3/ AB rep stosw +; End of decompression code for the path finding layer. + +273F:4AF4 83 EF 1A sub di, 1Ah ; di=3983 again (skips local variables) 273F:4AF7 5E pop si ; si=anim slot 273F:4AF8 33 C0 xor ax, ax ; Zero register -273F:4AFA 89 45 0A mov [di+0Ah], ax -273F:4AFD 89 45 0C mov [di+0Ch], ax -273F:4B00 89 45 10 mov [di+10h], ax -273F:4B03 89 45 0E mov [di+0Eh], ax -273F:4B06 88 45 05 mov [di+5], al -273F:4B09 81 2E 3944 02BC sub pathfind_v2, 2BCh +273F:4AFA 89 45 0A mov [di+PATHFIND_Y], ax +273F:4AFD 89 45 0C mov [di+PATHFIND_X], ax +273F:4B00 89 45 10 mov [di+PATHFIND_DEST_X2], ax +273F:4B03 89 45 0E mov [di+PATHFIND_0E], ax +273F:4B06 88 45 05 mov [di+PATHFIND_DEST_STATE], al +273F:4B09 81 2E 3944 02BC sub pathfind_countdown_ctr, 2BCh ; v2=0FA0h-2BCh=CE4h 273F:4B0F 8B 04 mov ax, [si+ANIM_X] ; Get current X 273F:4B11 2D 0080 sub ax, 80h ; Subtract the 80h offset 273F:4B14 73 05 jnc loc_950 ; Jump if current X on-screen -273F:4B16 89 45 0C mov [di+TEMP_X], ax +273F:4B16 89 45 0C mov [di+PATHFIND_X], ax 273F:4B19 33 C0 xor ax, ax ; Zero register 273F:4B1B loc_950: ; ax = max(0, X) 273F:4B1B BB 013F mov bx, 319 @@ -11605,43 +11615,44 @@ TEMP_DEST_X2 equ 10h 273F:4B21 3B C3 cmp ax, bx 273F:4B23 72 07 jb loc_951 ; X + full width on screen? 273F:4B25 2B C3 sub ax, bx -273F:4B27 89 45 0C mov [di+TEMP_X], ax ; X = min(X, 319 - width) +273F:4B27 89 45 0C mov [di+PATHFIND_X], ax ; X = min(X, 319 - width) 273F:4B2A 8B C3 mov ax, bx 273F:4B2C loc_951: 273F:4B2C 8B 5C 02 mov bx, [si+ANIM_Y] 273F:4B2F 80 E3 F8 and bl, 0F8h 273F:4B32 03 5C 15 add bx, [si+ANIM_HEIGHT_COPY] 273F:4B35 83 EB 04 sub bx, 4 -273F:4B38 81 EB 0088 sub bx, 88h -273F:4B3C 73 05 jnc loc_952 ; Jump if carry=0 -273F:4B3E 89 5D 0A mov [di+TEMP_Y], bx +273F:4B38 81 EB 0088 sub bx, 88h ; bx=(Y&0F8h+height-4-8) +273F:4B3C 73 05 jnc loc_952 ; Jump if bx (y bottom) < 0 +273F:4B3E 89 5D 0A mov [di+PATHFIND_Y], bx 273F:4B41 33 DB xor bx, bx ; Zero register -273F:4B43 loc_952: ; xref 273F:4B3C -273F:4B43 81 FB 00C0 cmp bx, 192 +273F:4B43 loc_952: +273F:4B43 81 FB 00C0 cmp bx, 192 ; Is it on-screen? 273F:4B47 72 0A jb loc_953 ; Jump if below 273F:4B49 81 EB 00BF sub bx, 191 -273F:4B4D 89 5D 0A mov [di+TEMP_Y], bx +273F:4B4D 89 5D 0A mov [di+PATHFIND_Y], bx 273F:4B50 BB 00BF mov bx, 191 -273F:4B53 loc_953: ; xref 273F:4B47 -273F:4B53 8B 4D 06 mov cx, [di+TEMP_DEST_X] + +273F:4B53 loc_953: +273F:4B53 8B 4D 06 mov cx, [di+PATHFIND_DEST_X] 273F:4B56 81 E9 0080 sub cx, 128 273F:4B5A 73 05 jnc loc_954 ; Jump if x >= 0 -273F:4B5C 89 4D 10 mov [di+TEMP_DEST_X2], cx ; Store X (will be negative) +273F:4B5C 89 4D 10 mov [di+PATHFIND_DEST_X2], cx ; Store X (will be negative) 273F:4B5F 33 C9 xor cx, cx -273F:4B61 loc_954: +273F:4B61 loc_954: 273F:4B61 BA 0140 mov dx, 320 273F:4B64 2B 54 13 sub dx, [si+ANIM_WIDTH_COPY] 273F:4B67 3B CA cmp cx, dx 273F:4B69 72 07 jb loc_955 ; Jump if fully on screen 273F:4B6B 2B CA sub cx, dx -273F:4B6D 89 4D 10 mov [di+TEMP_DEST_X2], cx +273F:4B6D 89 4D 10 mov [di+PATHFIND_DEST_X2], cx 273F:4B70 8B CA mov cx, dx -273F:4B72 loc_955: ; xref 273F:4B69 -273F:4B72 8B 55 08 mov dx, [di+TEMP_DEST_Y] +273F:4B72 loc_955: +273F:4B72 8B 55 08 mov dx, [di+PATHFIND_DEST_Y] 273F:4B75 81 EA 0088 sub dx, 88h -273F:4B79 73 02 jnc loc_956 ; Jump if carry=0 +273F:4B79 73 02 jnc loc_956 ; Jump if y >= 0 273F:4B7B 33 D2 xor dx, dx ; Zero register -273F:4B7D loc_956: ; xref 273F:4B79 +273F:4B7D loc_956: 273F:4B7D 81 FA 00C0 cmp dx, 192 273F:4B81 72 03 jb loc_957 ; Jump if below 273F:4B83 BA 00BF mov dx, 191 @@ -11650,18 +11661,23 @@ TEMP_DEST_X2 equ 10h ; current=(ax,bx), dest=(bp,dx). Check to see if a move of only a few pixels is required 273F:4B88 B1 03 mov cl, 3 -273F:4B8A D3 E8 shr ax, cl ; Shift w/zeros fill -273F:4B8C D3 EB shr bx, cl ; Shift w/zeros fill -273F:4B8E D3 ED shr bp, cl ; Shift w/zeros fill -273F:4B90 D3 EA shr dx, cl ; Shift w/zeros fill -273F:4B92 3B C5 cmp ax, bp -273F:4B94 75 2B jne loc_961 ; Jump if not equal -273F:4B96 3B DA cmp bx, dx -273F:4B98 75 27 jne loc_961 ; Jump if not equal +273F:4B8A D3 E8 shr ax, cl +273F:4B8C D3 EB shr bx, cl +273F:4B8E D3 ED shr bp, cl +273F:4B90 D3 EA shr dx, cl +273F:4B92 3B C5 cmp ax, bp ; Is x/8=dest_x/8? +273F:4B94 75 2B jne loc_961 ; Jump if not +273F:4B96 3B DA cmp bx, dx ; Is y/8=dest_y/8? +273F:4B98 75 27 jne loc_961 ; Jump if not + +; Destination is very close to source. +; If (I think) the PATHFIND_DEST_X2 != 0 (ie. dest is partially off-screen), then +; an initial walk entry is placed. Then irrespective, control jumps to loc_1003, +; which puts another left/right walking entry to move the character to dest X 273F:4B9A úBB 3940 mov bx, offset pathfind_buffer_end 273F:4B9D C7 07 0000 mov word ptr [bx], 0 ; Set end of pathfind sequence -273F:4BA1 8B 45 10 mov ax, [di+TEMP_DEST_X2] +273F:4BA1 8B 45 10 mov ax, [di+PATHFIND_DEST_X2] 273F:4BA4 0B C0 or ax, ax ; Any partial off-screen move? 273F:4BA6 74 16 jz loc_960 ; Jump if zero 273F:4BA8 78 07 js loc_958 ; Jump if sign=1 @@ -11675,80 +11691,87 @@ TEMP_DEST_X2 equ 10h 273F:4BBB 83 EB 04 sub bx, 4 ; Move back for next record 273F:4BBE loc_960: 273F:4BBE E9 02B3 jmp loc_1003 + +; Destination isn't close, so here's where the actual pathfinding needs to be done +; current=(ax,bx)/8, dest=(bp,dx)/8 + 273F:4BC1 loc_961: ; xref 273F:4B94, 4B98 273F:4BC1 50 push ax 273F:4BC2 53 push bx 273F:4BC3 55 push bp 273F:4BC4 52 push dx -273F:4BC5 89 6D 06 mov [di+6],bp -273F:4BC8 89 55 08 mov [di+8],dx -273F:4BCB D1 E0 shl ax,1 ; Shift w/zeros fill -273F:4BCD 8B F3 mov si,bx -273F:4BCF B1 02 mov cl,2 -273F:4BD1 D3 E3 shl bx,cl ; Shift w/zeros fill -273F:4BD3 03 DE add bx,si -273F:4BD5 D3 E3 shl bx,cl ; Shift w/zeros fill -273F:4BD7 03 DE add bx,si -273F:4BD9 D3 E3 shl bx,cl ; Shift w/zeros fill -273F:4BDB 03 D8 add bx,ax -273F:4BDD 83 C3 72 add bx,72h -273F:4BE0 03 DF add bx,di -273F:4BE2 C7 07 0001 mov word ptr [bx],1 -273F:4BE6 D1 E5 shl bp,1 ; Shift w/zeros fill -273F:4BE8 8B F2 mov si,dx -273F:4BEA D3 E6 shl si,cl ; Shift w/zeros fill -273F:4BEC 03 F2 add si,dx -273F:4BEE D3 E6 shl si,cl ; Shift w/zeros fill -273F:4BF0 03 F2 add si,dx -273F:4BF2 D3 E6 shl si,cl ; Shift w/zeros fill -273F:4BF4 03 F5 add si,bp -273F:4BF6 83 C6 72 add si,72h -273F:4BF9 03 F7 add si,di -273F:4BFB C6 45 12 00 mov byte ptr [di+12h],0 -273F:4BFF F6 04 FF test byte ptr [si],0FFh -273F:4C02 74 0C jz loc_962 ; Jump if zero -273F:4C04 C7 04 0000 mov word ptr [si],0 -273F:4C08 C6 45 12 01 mov byte ptr [di+12h],1 -273F:4C0C C6 45 05 01 mov byte ptr [di+5],1 -273F:4C10 loc_962: ; xref 273F:4C02 -273F:4C10 F6 45 04 FF test byte ptr [di+4],0FFh -273F:4C14 74 00 jz $+2 ; delay for I/O +273F:4BC5 89 6D 06 mov [di+PATHFIND_DEST_X], bp ; Store dest pos/8 +273F:4BC8 89 55 08 mov [di+PATHFIND_DEST_Y], dx + +273F:4BCB D1 E0 shl ax, 1 ; ax=sb_x*2 +273F:4BCD 8B F3 mov si, bx ; si=sb_y +273F:4BCF B1 02 mov cl, 2 +273F:4BD1 D3 E3 shl bx, cl ; bx=sb_y*4 +273F:4BD3 03 DE add bx, si ; bx=sb_y*5 +273F:4BD5 D3 E3 shl bx, cl ; bx=sb_y*20 +273F:4BD7 03 DE add bx, si ; bx=sb_y*21 +273F:4BD9 D3 E3 shl bx, cl ; bx=sb_y*84 +273F:4BDB 03 D8 add bx, ax ; bx=sb_y*84 + sb_x*2 +273F:4BDD 83 C3 72 add bx, 72h ; Add on buffer & blank line offset +273F:4BE0 03 DF add bx, di ; bx=source cell +273F:4BE2 C7 07 0001 mov word ptr [bx],1 ; Flag source cell +273F:4BE6 D1 E5 shl bp, 1 +273F:4BE8 8B F2 mov si, dx +273F:4BEA D3 E6 shl si, cl +273F:4BEC 03 F2 add si, dx +273F:4BEE D3 E6 shl si, cl +273F:4BF0 03 F2 add si, dx +273F:4BF2 D3 E6 shl si, cl +273F:4BF4 03 F5 add si, bp +273F:4BF6 83 C6 72 add si, 72h +273F:4BF9 03 F7 add si, di ; si=dest cell +273F:4BFB C6 45 12 00 mov byte ptr [di+PATHFIND_DEST_OCCUPIED], 0 +273F:4BFF F6 04 FF test byte ptr [si], 0FFh ; Is dest cell blocked? +273F:4C02 74 0C jz loc_962 ; Jump if clear +273F:4C04 C7 04 0000 mov word ptr [si], 0 ; Mark dest cell as unblocked +273F:4C08 C6 45 12 01 mov byte ptr [di+PATHFIND_DEST_OCCUPIED], 1 +273F:4C0C C6 45 05 01 mov byte ptr [di+PATHFIND_DEST_STATE], 1 ; Dest occupied +273F:4C10 loc_962: +273F:4C10 F6 45 04 FF test byte ptr [di+PATHFIND_HS4C],0FFh +273F:4C14 74 00 jz $+2 273F:4C16 5A pop dx 273F:4C17 59 pop cx 273F:4C18 5D pop bp 273F:4C19 58 pop ax -273F:4C1A 3B C1 cmp ax,cx -273F:4C1C 73 19 jae loc_964 ; Jump if above or = -273F:4C1E 0B C0 or ax,ax ; Zero ? -273F:4C20 74 06 jz loc_963 ; Jump if zero -273F:4C22 2D 0001 sub ax,1 -273F:4C25 83 EB 02 sub bx,2 -273F:4C28 loc_963: ; xref 273F:4C20 -273F:4C28 C7 45 14 0002 mov word ptr [di+14h],2 -273F:4C2D B9 0028 mov cx,28h -273F:4C30 2B C8 sub cx,ax -273F:4C32 89 4D 18 mov [di+18h],cx + +; Source/8=(ax,bp), Dest/8=(cx,dx), si=source cell, bx=dest cell +273F:4C1A 3B C1 cmp ax,cx ; Start X against Dest X +273F:4C1C 73 19 jae loc_964 ; Jump if >= +273F:4C1E 0B C0 or ax,ax ; Is Start X 0? +273F:4C20 74 06 jz loc_963 ; Jump if yes +273F:4C22 2D 0001 sub ax, 1 +273F:4C25 83 EB 02 sub bx, 2 +273F:4C28 loc_963: +273F:4C28 C7 45 14 0002 mov word ptr [di+PATHFIND_X_CHANGE1], 2 +273F:4C2D B9 0028 mov cx, 28h +273F:4C30 2B C8 sub cx, ax +273F:4C32 89 4D 18 mov [di+PATHFIND_X_CHANGE2], cx 273F:4C35 EB 17 jmp short loc_966 ; (4C4E) 273F:4C37 loc_964: ; xref 273F:4C1C -273F:4C37 3D 0027 cmp ax,27h +273F:4C37 3D 0027 cmp ax, 27h 273F:4C3A 74 06 je loc_965 ; Jump if equal -273F:4C3C 05 0001 add ax,1 -273F:4C3F 83 C3 02 add bx,2 +273F:4C3C 05 0001 add ax, 1 +273F:4C3F 83 C3 02 add bx, 2 273F:4C42 loc_965: ; xref 273F:4C3A -273F:4C42 C7 45 14 FFFE mov word ptr [di+14h],0FFFEh -273F:4C47 89 45 18 mov [di+18h],ax -273F:4C4A 83 45 18 01 add word ptr [di+18h],1 +273F:4C42 C7 45 14 FFFE mov word ptr [di+PATHFIND_X_CHANGE1], 0FFFEh +273F:4C47 89 45 18 mov [di+PATHFIND_X_CHANGE2],ax +273F:4C4A 83 45 18 01 add word ptr [di+PATHFIND_X_CHANGE2], 1 273F:4C4E loc_966: ; xref 273F:4C35 -273F:4C4E 3B EA cmp bp,dx +273F:4C4E 3B EA cmp bp, dx 273F:4C50 72 19 jb loc_968 ; Jump if below -273F:4C52 83 FD 17 cmp bp,17h +273F:4C52 83 FD 17 cmp bp, 17h 273F:4C55 74 06 je loc_967 ; Jump if equal -273F:4C57 83 C5 01 add bp,1 -273F:4C5A 83 C3 54 add bx,54h +273F:4C57 83 C5 01 add bp, 1 +273F:4C5A 83 C3 54 add bx, DECODED_PATHS_WIDTH * 2 273F:4C5D loc_967: ; xref 273F:4C55 -273F:4C5D C7 45 16 FFAC mov word ptr [di+16h],0FFACh -273F:4C62 89 6D 1A mov [di+1Ah],bp -273F:4C65 83 45 1A 01 add word ptr [di+1Ah],1 +273F:4C5D C7 45 16 FFAC mov [di+PATHFIND_Y_CHANGE1], -DECODED_PATHS_WIDTH*2 +273F:4C62 89 6D 1A mov [di+PATHFIND_Y_CHANGE2], bp +273F:4C65 83 45 1A 01 add [di+PATHFIND_Y_CHANGE2], 1 273F:4C69 EB 17 jmp short loc_970 ; (4C82) 273F:4C6B loc_968: ; xref 273F:4C50 273F:4C6B 0B ED or bp,bp ; Zero ? @@ -11756,159 +11779,179 @@ TEMP_DEST_X2 equ 10h 273F:4C6F 83 ED 01 sub bp,1 273F:4C72 83 EB 54 sub bx,54h 273F:4C75 loc_969: ; xref 273F:4C6D -273F:4C75 C7 45 16 0054 mov word ptr [di+16h],54h +273F:4C75 C7 45 16 0054 mov word ptr [di+PATHFIND_Y_CHANGE1], DECODED_PATHS_WIDTH * 2 273F:4C7A B9 0018 mov cx,18h 273F:4C7D 2B CD sub cx,bp -273F:4C7F 89 4D 1A mov [di+1Ah],cx -273F:4C82 loc_970: ; xref 273F:4C69 -273F:4C82 8B 55 14 mov dx,[di+14h] +273F:4C7F 89 4D 1A mov [di+PATHFIND_Y_CHANGE2], cx +273F:4C82 loc_970: + +; This next section populates the walkable sections of the decompressed array +; with incrementing numbers indicating the number of cells away each cell is +; from the destination. A walkable path can be later formed by following the +; path of decrementing numbers from the source to the destination + +273F:4C82 8B 55 14 mov dx,[di+PATHFIND_X_CHANGE1] 273F:4C85 loc_971: ; xref 273F:4CC6, 4CCE, 4CDA 273F:4C85 ú56 push si 273F:4C86 53 push bx -273F:4C87 8B 36 3944 mov si, pathfind_v2 -273F:4C8B 8B 4D 1A mov cx, [di+1Ah] +273F:4C87 8B 36 3944 mov si, pathfind_countdown_ctr +273F:4C8B 8B 4D 1A mov cx, [di+PATHFIND_Y_CHANGE2] 273F:4C8E locloop_972: ; xref 273F:4C9F 273F:4C8E 51 push cx 273F:4C8F 53 push bx -273F:4C90 8B 4D 18 mov cx, [di+18h] +273F:4C90 8B 4D 18 mov cx, [di+PATHFIND_X_CHANGE2] 273F:4C93 locloop_973: ; xref 273F:4C98 -273F:4C93 E8 021A call sub_120 ; (4EB0) -273F:4C96 03 DA add bx,dx +273F:4C93 E8 021A call pathfind_populate_cells +273F:4C96 03 DA add bx, dx 273F:4C98 E2 F9 loop locloop_973 ; Loop if cx > 0 273F:4C9A 5B pop bx 273F:4C9B 59 pop cx -273F:4C9C 03 5D 16 add bx,[di+16h] +273F:4C9C 03 5D 16 add bx, [di+PATHFIND_Y_CHANGE1] 273F:4C9F E2 ED loop locloop_972 ; Loop if cx > 0 -273F:4CA1 89 36 3944 mov pathfind_v2, si +273F:4CA1 89 36 3944 mov pathfind_countdown_ctr, si 273F:4CA5 5B pop bx 273F:4CA6 5E pop si -273F:4CA7 F7 04 FFFF test word ptr [si],0FFFFh -273F:4CAB 75 2F jnz loc_977 ; Jump if not zero -273F:4CAD 80 7D 1A 18 cmp byte ptr [di+1Ah],18h +273F:4CA7 F7 04 FFFF test word ptr [si], 0FFFFh ; Dest been filled in yet? +273F:4CAB 75 2F jnz loc_977 ; Jump if yes + +273F:4CAD 80 7D 1A 18 cmp byte ptr [di+PATHFIND_Y_CHANGE2], ROOM_PATHS_HEIGHT 273F:4CB1 75 08 jne loc_974 ; Jump if not equal -273F:4CB3 80 7D 18 28 cmp byte ptr [di+18h],28h ; '(' +273F:4CB3 80 7D 18 28 cmp byte ptr [di+PATHFIND_X_CHANGE2], ROOM_PATHS_WIDTH 273F:4CB7 74 17 je loc_976 ; Jump if equal -273F:4CB9 EB 07 jmp short loc_975 ; (4CC2) +273F:4CB9 EB 07 jmp short loc_975 273F:4CBB loc_974: ; xref 273F:4CB1 -273F:4CBB 2B 5D 16 sub bx,[di+16h] -273F:4CBE 83 45 1A 01 add word ptr [di+1Ah],1 -273F:4CC2 loc_975: ; xref 273F:4CB9 -273F:4CC2 80 7D 18 28 cmp byte ptr [di+18h],28h ; '(' +273F:4CBB 2B 5D 16 sub bx, [di+PATHFIND_Y_CHANGE1] +273F:4CBE 83 45 1A 01 add word ptr [di+PATHFIND_Y_CHANGE2], 1 +273F:4CC2 loc_975: +273F:4CC2 80 7D 18 28 cmp byte ptr [di+PATHFIND_X_CHANGE2], ROOM_PATHS_WIDTH 273F:4CC6 74 BD je loc_971 ; Jump if equal -273F:4CC8 2B DA sub bx,dx -273F:4CCA 83 45 18 01 add word ptr [di+18h],1 -273F:4CCE EB B5 jmp short loc_971 ; (4C85) -273F:4CD0 loc_976: ; xref 273F:4CB7 -273F:4CD0 F6 45 13 FF test byte ptr [di+13h],0FFh -273F:4CD4 74 08 jz loc_978 ; Jump if zero -273F:4CD6 C6 45 13 00 mov byte ptr [di+13h],0 -273F:4CDA EB A9 jmp short loc_971 ; (4C85) -273F:4CDC loc_977: ; xref 273F:4CAB -273F:4CDC EB 66 jmp short loc_982 ; (4D44) -273F:4CDE loc_978: ; xref 273F:4CD4 -273F:4CDE C6 45 05 02 mov byte ptr [di+5],2 -273F:4CE2 loc_979: ; xref 273F:4D48 -273F:4CE2 F6 45 12 FF test byte ptr [di+12h],0FFh +273F:4CC8 2B DA sub bx, dx +273F:4CCA 83 45 18 01 add word ptr [di+PATHFIND_X_CHANGE2], 1 +273F:4CCE EB B5 jmp short loc_971 + +273F:4CD0 loc_976: +273F:4CD0 F6 45 13 FF test byte ptr [di+PATHFIND_CELL_POPULATED], 0FFh +273F:4CD4 74 08 jz loc_978 ; Jump if no cell populated +273F:4CD6 C6 45 13 00 mov byte ptr [di+PATHFIND_CELL_POPULATED], 0 +273F:4CDA EB A9 jmp short loc_971 ; Jump for another try +273F:4CDC loc_977: +273F:4CDC EB 66 jmp short loc_982 +273F:4CDE loc_978: +273F:4CDE C6 45 05 02 mov byte ptr [di+PATHFIND_DEST_STATE], 2 ; No path to destination +273F:4CE2 loc_979: +273F:4CE2 F6 45 12 FF test byte ptr [di+PATHFIND_DEST_OCCUPIED], 0FFh 273F:4CE6 74 08 jz loc_980 ; Jump if zero -273F:4CE8 C7 04 FFFF mov word ptr [si],0FFFFh -273F:4CEC C6 45 12 00 mov byte ptr [di+12h],0 -273F:4CF0 loc_980: ; xref 273F:4CE6 +273F:4CE8 C7 04 FFFF mov word ptr [si], 0FFFFh ; Restore destination occupied +273F:4CEC C6 45 12 00 mov byte ptr [di+PATHFIND_DEST_OCCUPIED], 0 +273F:4CF0 loc_980: + +; Do a prescanning of the lines 273F:4CF0 57 push di -273F:4CF1 8B EE mov bp,si -273F:4CF3 8B DE mov bx,si -273F:4CF5 B2 FF mov dl,0FFh -273F:4CF7 8B 4D 06 mov cx,[di+6] -273F:4CFA 83 C1 01 add cx,1 -273F:4CFD BF FFFE mov di,0FFFEh -273F:4D00 E8 0220 call sub_121 ; (4F23) +273F:4CF1 8B EE mov bp, si +273F:4CF3 8B DE mov bx, si ; bx=bp=destination cell +273F:4CF5 B2 FF mov dl, 0FFh +273F:4CF7 8B 4D 06 mov cx, [di+PATHFIND_DEST_X] +273F:4CFA 83 C1 01 add cx, 1 +273F:4CFD BF FFFE mov di, 0FFFEh +273F:4D00 E8 0220 call pathfind_scan_line 273F:4D03 5F pop di 273F:4D04 57 push di -273F:4D05 B9 0028 mov cx,28h -273F:4D08 2B 4D 06 sub cx,[di+6] -273F:4D0B BF 0002 mov di,2 -273F:4D0E E8 0212 call sub_121 ; (4F23) +273F:4D05 B9 0028 mov cx, ROOM_PATHS_WIDTH +273F:4D08 2B 4D 06 sub cx, [di+PATHFIND_DEST_X] +273F:4D0B BF 0002 mov di, 2 +273F:4D0E E8 0212 call pathfind_scan_line 273F:4D11 5F pop di 273F:4D12 57 push di -273F:4D13 8B 4D 08 mov cx,[di+8] -273F:4D16 83 C1 01 add cx,1 -273F:4D19 BF FFAC mov di,0FFACh -273F:4D1C E8 0204 call sub_121 ; (4F23) +273F:4D13 8B 4D 08 mov cx, [di+PATHFIND_DEST_Y] +273F:4D16 83 C1 01 add cx, 1 +273F:4D19 BF FFAC mov di, -DECODED_PATHS_WIDTH*2 +273F:4D1C E8 0204 call pathfind_scan_line 273F:4D1F 5F pop di 273F:4D20 57 push di -273F:4D21 B9 0018 mov cx,18h -273F:4D24 2B 4D 08 sub cx,[di+8] -273F:4D27 BF 0054 mov di,54h -273F:4D2A E8 01F6 call sub_121 ; (4F23) +273F:4D21 B9 0018 mov cx, ROOM_PATHS_HEIGHT +273F:4D24 2B 4D 08 sub cx, [di+PATHFIND_DEST_Y] +273F:4D27 BF 0054 mov di, DECODED_PATHS_WIDTH*2 +273F:4D2A E8 01F6 call pathfind_scan_line 273F:4D2D 5F pop di -273F:4D2E 8B F5 mov si,bp -273F:4D30 3B DE cmp bx,si +273F:4D2E 8B F5 mov si, bp +273F:4D30 3B DE cmp bx, si 273F:4D32 75 0E jne loc_981 ; Jump if not equal -273F:4D34 C6 45 05 03 mov byte ptr [di+5],3 -273F:4D38 úBB 3940 mov bx,3940h ; (273F:3940=0C7h) -273F:4D3B C7 07 0000 mov word ptr [bx],0 +273F:4D34 C6 45 05 03 mov byte ptr [di+PATHFIND_DEST_STATE], 3 +273F:4D38 úBB 3940 mov bx, offset pathfind_buffer_end +273F:4D3B C7 07 0000 mov word ptr [bx], 0 273F:4D3F E9 0132 jmp loc_1003 ; (4E74) 273F:4D42 loc_981: ; xref 273F:4D32 -273F:4D42 8B F3 mov si,bx +273F:4D42 8B F3 mov si, bx + 273F:4D44 loc_982: ; xref 273F:4CDC -273F:4D44 F6 45 12 FF test byte ptr [di+12h],0FFh +273F:4D44 F6 45 12 FF test byte ptr [di+PATHFIND_DEST_OCCUPIED], 0FFh 273F:4D48 75 98 jnz loc_979 ; Jump if not zero + +; end of cell population +; Fill out any cells that are still blank (ie. anywhere that can't reach the +; destination) as occupied + 273F:4D4A FC cld ; Clear direction 273F:4D4B 57 push di -273F:4D4C 83 C7 1C add di,1Ch -273F:4D4F B9 0445 mov cx,445h -273F:4D52 33 C0 xor ax,ax ; Zero register -273F:4D54 loc_983: ; xref 273F:4D5F -273F:4D54 úF2/ AF repne scasw ; Rep zf=0+cx >0 Scan es:[di] for ax -273F:4D56 0B C9 or cx,cx ; Zero ? -273F:4D58 74 07 jz loc_984 ; Jump if zero -273F:4D5A C7 45 FE FFFF mov word ptr [di-2],0FFFFh -273F:4D5F EB F3 jmp short loc_983 ; (4D54) -273F:4D61 loc_984: ; xref 273F:4D58 +273F:4D4C 83 C7 1C add di, 1Ch ; di=start of grid +273F:4D4F B9 0445 mov cx, DECODED_PATHS_WIDTH*DECODED_PATHS_HEIGHT+1 ;445h +273F:4D52 33 C0 xor ax, ax +273F:4D54 loc_983: +273F:4D54 úF2/ AF repne scasw ; Scan for an empty cell +273F:4D56 0B C9 or cx, cx ; Reached end of list? +273F:4D58 74 07 jz loc_984 ; Jump if yes +273F:4D5A C7 45 FE FFFF mov word ptr [di-2], 0FFFFh ; Replace it with occupied state +273F:4D5F EB F3 jmp short loc_983 + +273F:4D61 loc_984: 273F:4D61 5F pop di -273F:4D62 33 D2 xor dx,dx ; Zero register +273F:4D62 33 D2 xor dx, dx 273F:4D64 B1 FF mov cl,0FFh -273F:4D66 úBB 3940 mov bx,3940h ; (273F:3940=0C7h) -273F:4D69 C7 07 0000 mov word ptr [bx],0 -273F:4D6D F6 45 05 FF test byte ptr [di+5],0FFh +273F:4D66 úBB 3940 mov bx, offset pathfind_buffer_end +273F:4D69 C7 07 0000 mov word ptr [bx], 0 +273F:4D6D F6 45 05 FF test byte ptr [di+PATHFIND_DEST_STATE], 0FFh 273F:4D71 75 1D jnz loc_987 ; Jump if not zero -273F:4D73 8B 45 10 mov ax,[di+10h] +273F:4D73 8B 45 10 mov ax, [di+PATHFIND_DEST_X2] 273F:4D76 0B C0 or ax,ax ; Zero ? 273F:4D78 74 16 jz loc_987 ; Jump if zero 273F:4D7A 78 07 js loc_985 ; Jump if sign=1 -273F:4D7C C7 47 FE 0002 mov word ptr [bx-2],2 +273F:4D7C C7 47 FE 0002 mov word ptr [bx-2], FACING2_RIGHT 273F:4D81 EB 07 jmp short loc_986 ; (4D8A) 273F:4D83 loc_985: ; xref 273F:4D7A -273F:4D83 C7 47 FE 0001 mov word ptr [bx-2],1 +273F:4D83 C7 47 FE 0001 mov word ptr [bx-2], FACING2_LEFT 273F:4D88 F7 D8 neg ax 273F:4D8A loc_986: ; xref 273F:4D81 -273F:4D8A 89 47 FC mov [bx-4],ax -273F:4D8D 83 EB 04 sub bx,4 +273F:4D8A 89 47 FC mov [bx-4], ax ; Save # steps +273F:4D8D 83 EB 04 sub bx, 4 273F:4D90 loc_987: ; xref 273F:4D71, 4D78, 4E64, 4E6F + 273F:4D90 ú53 push bx 273F:4D91 56 push si -273F:4D92 loc_988: ; xref 273F:4DE1, 4E06, 4E2B, 4E4F -273F:4D92 ú8B 04 mov ax,[si] -273F:4D94 2D 0001 sub ax,1 + +; Form a set of steps starting at the source +273F:4D92 loc_988: +273F:4D92 ú8B 04 mov ax, [si] ; Get steps value from current pos +273F:4D94 2D 0001 sub ax, 1 273F:4D97 74 4A jz loc_992 ; Jump if zero -273F:4D99 F6 C2 26 test dl,26h ; '&' +273F:4D99 F6 C2 26 test dl, 38 273F:4D9C 75 11 jnz loc_989 ; Jump if not zero -273F:4D9E 39 44 AC cmp [si-54h],ax +273F:4D9E 39 44 AC cmp [si-DECODED_PATHS_WIDTH*2], ax 273F:4DA1 74 67 je loc_996 ; Jump if equal -273F:4DA3 39 44 54 cmp [si+HS_DEST_X], ax +273F:4DA3 39 44 54 cmp [si+DECODED_PATHS_WIDTH*2], ax 273F:4DA6 74 60 je loc_995 ; Jump if equal -273F:4DA8 39 44 02 cmp [si+2],ax +273F:4DA8 39 44 02 cmp [si+2], ax 273F:4DAB 74 38 je loc_993 ; Jump if equal 273F:4DAD EB 11 jmp short loc_990 ; (4DC0) 273F:4DAF loc_989: ; xref 273F:4D9C -273F:4DAF 39 44 02 cmp [si+2],ax +273F:4DAF 39 44 02 cmp [si+2], ax 273F:4DB2 74 31 je loc_993 ; Jump if equal -273F:4DB4 39 44 FE cmp [si-2],ax +273F:4DB4 39 44 FE cmp [si-2], ax 273F:4DB7 74 07 je loc_990 ; Jump if equal -273F:4DB9 39 44 54 cmp [si+HS_DEST_X], ax +273F:4DB9 39 44 54 cmp [si+DECODED_PATHS_WIDTH*2], ax 273F:4DBC 74 70 je loc_998 ; Jump if equal 273F:4DBE EB 4A jmp short loc_996 ; (4E0A) 273F:4DC0 loc_990: ; xref 273F:4DAD, 4DB7 @@ -11916,9 +11959,9 @@ TEMP_DEST_X2 equ 10h 273F:4DC3 F6 C2 02 test dl,2 273F:4DC6 75 10 jnz loc_991 ; Jump if not zero 273F:4DC8 80 C6 01 add dh,1 -273F:4DCB C7 47 FE 0002 mov word ptr [bx-2],2 -273F:4DD0 C7 47 FC 0000 mov word ptr [bx-4],0 -273F:4DD5 83 EB 04 sub bx,4 +273F:4DCB C7 47 FE 0002 mov word ptr [bx-2], FACING2_RIGHT +273F:4DD0 C7 47 FC 0000 mov word ptr [bx-4], 0 +273F:4DD5 83 EB 04 sub bx, 4 273F:4DD8 loc_991: ; xref 273F:4DC6 273F:4DD8 83 EE 02 sub si,2 273F:4DDB 83 07 08 add word ptr [bx],8 @@ -11931,13 +11974,13 @@ TEMP_DEST_X2 equ 10h 273F:4DE8 F6 C2 04 test dl,4 273F:4DEB 75 10 jnz loc_994 ; Jump if not zero 273F:4DED 80 C6 01 add dh,1 -273F:4DF0 C7 47 FE 0001 mov word ptr [bx-2],1 -273F:4DF5 C7 47 FC 0000 mov word ptr [bx-4],0 -273F:4DFA 83 EB 04 sub bx,4 +273F:4DF0 C7 47 FE 0001 mov word ptr [bx-2], FACING2_LEFT +273F:4DF5 C7 47 FC 0000 mov word ptr [bx-4], 0 +273F:4DFA 83 EB 04 sub bx, 4 273F:4DFD loc_994: ; xref 273F:4DEB -273F:4DFD 83 C6 02 add si,2 -273F:4E00 83 07 08 add word ptr [bx],8 -273F:4E03 80 CA 04 or dl,4 +273F:4DFD 83 C6 02 add si, 2 +273F:4E00 83 07 08 add word ptr [bx], 8 ; Add # steps +273F:4E03 80 CA 04 or dl, 4 273F:4E06 EB 8A jmp short loc_988 ; (4D92) 273F:4E08 loc_995: ; xref 273F:4DA6 273F:4E08 EB 24 jmp short loc_998 ; (4E2E) @@ -11946,52 +11989,58 @@ TEMP_DEST_X2 equ 10h 273F:4E0D F6 C2 08 test dl,8 273F:4E10 75 10 jnz loc_997 ; Jump if not zero 273F:4E12 80 C6 01 add dh,1 -273F:4E15 C7 47 FE 0008 mov word ptr [bx-2],8 -273F:4E1A C7 47 FC 0000 mov word ptr [bx-4],0 -273F:4E1F 83 EB 04 sub bx,4 +273F:4E15 C7 47 FE 0008 mov word ptr [bx-2], FACING2_DOWN +273F:4E1A C7 47 FC 0000 mov word ptr [bx-4], 0 +273F:4E1F 83 EB 04 sub bx, 4 273F:4E22 loc_997: ; xref 273F:4E10 -273F:4E22 83 EE 54 sub si,54h -273F:4E25 83 07 08 add word ptr [bx],8 -273F:4E28 80 CA 08 or dl,8 +273F:4E22 83 EE 54 sub si, DECODED_PATHS_WIDTH*2 +273F:4E25 83 07 08 add word ptr [bx], 8 ; Add # steps +273F:4E28 80 CA 08 or dl, 8 273F:4E2B E9 FF64 jmp loc_988 ; (4D92) 273F:4E2E loc_998: ; xref 273F:4DBC, 4E08 273F:4E2E 80 E2 11 and dl,11h 273F:4E31 F6 C2 10 test dl,10h 273F:4E34 75 10 jnz loc_999 ; Jump if not zero 273F:4E36 80 C6 01 add dh,1 -273F:4E39 C7 47 FE 0004 mov word ptr [bx-2],4 -273F:4E3E C7 47 FC 0000 mov word ptr [bx-4],0 -273F:4E43 83 EB 04 sub bx,4 +273F:4E39 C7 47 FE 0004 mov word ptr [bx-2], FACING2_UP +273F:4E3E C7 47 FC 0000 mov word ptr [bx-4], 0 +273F:4E43 83 EB 04 sub bx, 4 273F:4E46 loc_999: ; xref 273F:4E34 -273F:4E46 83 C6 54 add si,54h -273F:4E49 83 07 08 add word ptr [bx],8 -273F:4E4C 80 CA 10 or dl,10h +273F:4E46 83 C6 54 add si, DECODED_PATHS_WIDTH*2 +273F:4E49 83 07 08 add word ptr [bx], 8 ; Add # steps +273F:4E4C 80 CA 10 or dl, 10h 273F:4E4F E9 FF40 jmp loc_988 ; (4D92) -273F:4E52 loc_1000: ; xref 273F:4DE3 -273F:4E52 F6 C2 01 test dl,1 -273F:4E55 75 1B jnz loc_1002 ; Jump if not zero -273F:4E57 F6 C1 80 test cl,80h + +; This post-check is used to go through the paths two times - the first two +; tries the path using standard direction checks, the second using the alternate +; checks. If the first run through was the shortest, redo the process a third +; time to get the walking sequence that was obtained the first time +273F:4E52 loc_1000: +273F:4E52 F6 C2 01 test dl, 1 ; Test for exit flag +273F:4E55 75 1B jnz loc_1002 ; Jump if yes +273F:4E57 F6 C1 80 test cl, 80h 273F:4E5A 74 0B jz loc_1001 ; Jump if zero 273F:4E5C 5E pop si 273F:4E5D 5B pop bx -273F:4E5E 8A CE mov cl,dh -273F:4E60 32 F6 xor dh,dh ; Zero register -273F:4E62 B2 20 mov dl,20h ; ' ' -273F:4E64 E9 FF29 jmp loc_987 ; (4D90) -273F:4E67 loc_1001: ; xref 273F:4E5A -273F:4E67 3A CE cmp cl,dh +273F:4E5E 8A CE mov cl, dh ; Store number of steps +273F:4E60 32 F6 xor dh, dh ; Reset counter +273F:4E62 B2 20 mov dl, 20h ; Flag for alt direction check +273F:4E64 E9 FF29 jmp loc_987 ; Go get directions again +273F:4E67 loc_1001: +273F:4E67 3A CE cmp cl, dh 273F:4E69 73 07 jae loc_1002 ; Jump if above or = 273F:4E6B 5E pop si 273F:4E6C 5B pop bx -273F:4E6D B2 01 mov dl,1 -273F:4E6F E9 FF1E jmp loc_987 ; (4D90) -273F:4E72 loc_1002: ; xref 273F:4E55, 4E69 +273F:4E6D B2 01 mov dl, 1 ; Flag for exit after retry +273F:4E6F E9 FF1E jmp loc_987 + +273F:4E72 loc_1002: 273F:4E72 5E pop si 273F:4E73 58 pop ax 273F:4E74 loc_1003: 273F:4E74 FC cld ; Clear direction -273F:4E75 8B 45 0C mov ax, [di+TEMP_X] +273F:4E75 8B 45 0C mov ax, [di+PATHFIND_X] 273F:4E78 A9 FFFF test ax, 0FFFFh ; Check X position 273F:4E7B 74 19 jz loc_1006 273F:4E7D 78 0A js loc_1004 ; Move @@ -12007,9 +12056,9 @@ TEMP_DEST_X2 equ 10h 273F:4E96 loc_1006: ; End of pathfinding 273F:4E96 C7 05 0000 mov word ptr [di], 0 273F:4E9A 8B 26 3942 mov sp, pathfind_sp -273F:4E9E C6 06 3946 00 mov pathfind_in_progress, 0 -273F:4EA3 B8 0001 mov ax, 1 -273F:4EA6 02 45 05 add al, [di+5] +273F:4E9E C6 06 3946 00 mov pathfind_in_progress, 0 ; Reset in-progress flag +273F:4EA3 B8 0001 mov ax, 1 ; Set return value +273F:4EA6 02 45 05 add al, [di+PATHFIND_DEST_STATE] 273F:4EA9 50 push ax 273F:4EAA 53 push bx 273F:4EAB 06 push es @@ -12026,53 +12075,58 @@ TEMP_DEST_X2 equ 10h ; Called from: 273F:4C93 ;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ -273F:4EB0 sub_120 proc near -273F:4EB0 F7 07 FFFF test word ptr [bx],0FFFFh -273F:4EB4 75 48 jnz loc_1013 ; Jump if not zero -273F:4EB6 BD FFFF mov bp,0FFFFh -273F:4EB9 8B 47 AC mov ax,[bx-54h] -273F:4EBC 0B C0 or ax,ax ; Zero ? -273F:4EBE 74 06 jz loc_1007 ; Jump if zero -273F:4EC0 3B C5 cmp ax,bp -273F:4EC2 73 02 jae loc_1007 ; Jump if above or = -273F:4EC4 8B E8 mov bp,ax -273F:4EC6 loc_1007: ; xref 273F:4EBE, 4EC2 -273F:4EC6 8B 47 54 mov ax,[bx+HS_DEST_X] -273F:4EC9 0B C0 or ax,ax ; Zero ? -273F:4ECB 74 06 jz loc_1008 ; Jump if zero -273F:4ECD 3B C5 cmp ax,bp -273F:4ECF 73 02 jae loc_1008 ; Jump if above or = -273F:4ED1 8B E8 mov bp,ax -273F:4ED3 loc_1008: ; xref 273F:4ECB, 4ECF -273F:4ED3 8B 47 FE mov ax,[bx-2] -273F:4ED6 0B C0 or ax,ax ; Zero ? -273F:4ED8 74 06 jz loc_1009 ; Jump if zero -273F:4EDA 3B C5 cmp ax,bp -273F:4EDC 73 02 jae loc_1009 ; Jump if above or = -273F:4EDE 8B E8 mov bp,ax -273F:4EE0 loc_1009: ; xref 273F:4ED8, 4EDC -273F:4EE0 8B 47 02 mov ax,[bx+2] -273F:4EE3 0B C0 or ax,ax ; Zero ? -273F:4EE5 74 06 jz loc_1010 ; Jump if zero -273F:4EE7 3B C5 cmp ax,bp -273F:4EE9 73 02 jae loc_1010 ; Jump if above or = -273F:4EEB 8B E8 mov bp,ax -273F:4EED loc_1010: ; xref 273F:4EE5, 4EE9 -273F:4EED 83 C5 01 add bp,1 -273F:4EF0 74 06 jz loc_1011 ; Jump if zero -273F:4EF2 89 2F mov [bx],bp -273F:4EF4 C6 45 13 01 mov byte ptr [di+13h],1 + pathfind_populate_cells proc near +273F:4EB0 F7 07 FFFF test word ptr [bx], 0FFFFh ; Is cell occupied? +273F:4EB4 75 48 jnz loc_1013 ; Jump if it is +273F:4EB6 BD FFFF mov bp, 0FFFFh +273F:4EB9 8B 47 AC mov ax, [bx-(DECODED_PATHS_WIDTH*2)] ; Get cell from one line up +273F:4EBC 0B C0 or ax, ax ; Is it occupied +273F:4EBE 74 06 jz loc_1007 ; Jump if not +273F:4EC0 3B C5 cmp ax, bp ; Is it standard occupied indicator? +273F:4EC2 73 02 jae loc_1007 +273F:4EC4 8B E8 mov bp,ax ; Store loaded cell value +273F:4EC6 loc_1007: +273F:4EC6 8B 47 54 mov ax, [bx+(DECODED_PATHS_WIDTH*2)] ; Get cell from next line +273F:4EC9 0B C0 or ax, ax ; Is it occupied? +273F:4ECB 74 06 jz loc_1008 ; Jump if not +273F:4ECD 3B C5 cmp ax, bp +273F:4ECF 73 02 jae loc_1008 +273F:4ED1 8B E8 mov bp, ax ; Store loaded cell value +273F:4ED3 loc_1008: +273F:4ED3 8B 47 FE mov ax, [bx-2] ; Get cell from left +273F:4ED6 0B C0 or ax, ax ; Is it occupied? +273F:4ED8 74 06 jz loc_1009 ; Jump if not +273F:4EDA 3B C5 cmp ax, bp +273F:4EDC 73 02 jae loc_1009 ; Store loaded cell value +273F:4EDE 8B E8 mov bp, ax +273F:4EE0 loc_1009: +273F:4EE0 8B 47 02 mov ax, [bx+2] ; Get cell from right +273F:4EE3 0B C0 or ax, ax ; Is it occupied? +273F:4EE5 74 06 jz loc_1010 ; Jump if not +273F:4EE7 3B C5 cmp ax, bp +273F:4EE9 73 02 jae loc_1010 +273F:4EEB 8B E8 mov bp, ax ; Store loaded cell value +273F:4EED loc_1010: + +; At this point, bp contains the lowest value from the surrounding cells, not +; counting entries with 0ffff (occupied). Below we will now add 1 to the value +; and store it in the cell. By repeated calls processing the entire grid, we +; can figure out a path to the destination by following sequential numbers +273F:4EED 83 C5 01 add bp, 1 +273F:4EF0 74 06 jz loc_1011 ; If no vals found, skip save +273F:4EF2 89 2F mov [bx], bp ; Store value +273F:4EF4 C6 45 13 01 mov byte ptr [di+PATHFIND_CELL_POPULATED], 1 273F:4EF8 loc_1011: ; xref 273F:4EF0 -273F:4EF8 83 EE 03 sub si,3 -273F:4EFB 72 06 jc loc_1014 ; Jump if carry Set +273F:4EF8 83 EE 03 sub si, 3 ; Decrement countdown ctr +273F:4EFB 72 06 jc loc_1014 ; Break if countdown ended 273F:4EFD loc_ret_1012: ; xref 273F:4F01 273F:4EFD C3 retn 273F:4EFE loc_1013: ; xref 273F:4EB4 -273F:4EFE 83 EE 01 sub si,1 -273F:4F01 73 FA jnc loc_ret_1012 ; Jump if carry=0 -273F:4F03 loc_1014: ; xref 273F:4EFB -273F:4F03 89 36 3944 mov pathfind_v2, si +273F:4EFE 83 EE 01 sub si, 1 ; Decrement countdown ctr +273F:4F01 73 FA jnc loc_ret_1012 ; Don't break if countdown not ended +273F:4F03 loc_1014: +273F:4F03 89 36 3944 mov pathfind_countdown_ctr, si 273F:4F07 50 push ax 273F:4F08 53 push bx 273F:4F09 51 push cx @@ -12084,7 +12138,7 @@ TEMP_DEST_X2 equ 10h 273F:4F0F 06 push es 273F:4F10 9C pushf 273F:4F11 E8 0034 call pathfind_return_to_sp -273F:4F14 9D popf +273F:4F14 9D popf 273F:4F15 07 pop es 273F:4F16 1F pop ds 273F:4F17 5D pop bp @@ -12094,9 +12148,9 @@ TEMP_DEST_X2 equ 10h 273F:4F1B 59 pop cx 273F:4F1C 5B pop bx 273F:4F1D 58 pop ax -273F:4F1E 8B 36 3944 mov si, pathfind_v2 +273F:4F1E 8B 36 3944 mov si, pathfind_countdown_ctr 273F:4F22 C3 retn - sub_120 endp + pathfind_populate_cells endp ;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß @@ -12105,25 +12159,25 @@ TEMP_DEST_X2 equ 10h ; Called from: 273F:4D00, 4D0E, 4D1C, 4D2A ;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ -273F:4F23 sub_121 proc near -273F:4F23 8B F5 mov si,bp -273F:4F25 32 F6 xor dh,dh ; Zero register + pathfind_scan_line proc near +273F:4F23 8B F5 mov si, bp +273F:4F25 32 F6 xor dh, dh 273F:4F27 locloop_1015: ; xref 273F:4F45 -273F:4F27 03 F7 add si,di +273F:4F27 03 F7 add si, di ; Add increment amount 273F:4F29 80 C6 01 add dh,1 -273F:4F2C F7 04 FFFF test word ptr [si],0FFFFh -273F:4F30 74 13 jz loc_1018 ; Jump if zero -273F:4F32 78 11 js loc_1018 ; Jump if sign=1 -273F:4F34 3A D6 cmp dl,dh -273F:4F36 72 0C jb loc_ret_1017 ; Jump if below -273F:4F38 75 06 jnz loc_1016 ; Jump if not zero -273F:4F3A 8B 04 mov ax,[si] -273F:4F3C 3B 07 cmp ax,[bx] +273F:4F2C F7 04 FFFF test word ptr [si], 0FFFFh ; Check cell +273F:4F30 74 13 jz loc_1018 ; Skip if empty (unpopulated) +273F:4F32 78 11 js loc_1018 ; Or if occupied +273F:4F34 3A D6 cmp dl, dh ; Check ctr against max +273F:4F36 72 0C jb loc_ret_1017 ; Exit if below +273F:4F38 75 06 jnz loc_1016 ; Jump if not equal +273F:4F3A 8B 04 mov ax, [si] +273F:4F3C 3B 07 cmp ax, [bx] 273F:4F3E 73 04 jae loc_ret_1017 ; Jump if above or = 273F:4F40 loc_1016: ; xref 273F:4F38 273F:4F40 8B DE mov bx,si -273F:4F42 8A D6 mov dl,dh +273F:4F42 8A D6 mov dl, dh 273F:4F44 loc_ret_1017: ; xref 273F:4F36, 4F3E 273F:4F44 C3 retn @@ -12131,7 +12185,7 @@ TEMP_DEST_X2 equ 10h 273F:4F45 E2 E0 loop locloop_1015 ; Loop if cx > 0 273F:4F47 C3 retn - sub_121 endp + pathfind_scan_line endp ;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß @@ -26305,7 +26359,7 @@ TEMP_DEST_X2 equ 10h 31E4:38B4 008D[00] db 140 dup (0) 31E4:3940 0000 pathfind_buffer_end dw 0 31E4:3942 0000 pathfind_sp dw 0 -31E4:3944 0000 pathfind_v2 dw 0 +31E4:3944 0000 pathfind_countdown_ctr dw 0 31E4:3946 0000 pathfind_in_progress db 0 31E4:3947 003C[00] db 60 dup (0) 31E4:3983 000A[00] player_pathfind_data dw 5 dup (0) diff --git a/engines/lure/diassembly/Lure_notes.txt b/engines/lure/diassembly/Lure_notes.txt index ca737ab459..5bb5738761 100644 --- a/engines/lure/diassembly/Lure_notes.txt +++ b/engines/lure/diassembly/Lure_notes.txt @@ -349,6 +349,26 @@ pathfind_get_cell - Returns the byte and bit index for the given animation's cx = Number of bits covering the width of the animation ZF = If set, animation is not onscreen +pathfind_populate_cells - Helper method used by character_pathfind to populate + a decompressed array indicating which areas of a room are walkable + with incrementing numbers emnating from the destination. This is + later used to figure out a walkable path by going from cell to + cell in order of decrementing index to get from source to dest + +pathfind_scan_line - Support method for the character_pathfind, and is used to + scan in a given direction + Input: bp = Starting position + bx = Destination position + cx = Number of loops + di = Change amount for each loop + dl = max value for comparison + Output: bx = New destination position + dl = New maximum + +pathfind_return_to_sp - Creates a breaking point during processing of the + character_pathfind method such that the next time character_pathfind + is called, it will pick up after the call to pathfind_return_to_sp + pause_for_input - Waits until either a key or a mouse button is pressed player_inc_inventory_items - Checks if the specified hotspot is the player, @@ -808,6 +828,10 @@ The format of hotspots are as follows: 49h 1 Flags whether the hotspot has currently got the cells of the pathfinding (walkable areas) layer that it's base occupies as covered + 4Ch 1 Only known use so far is in character pathfinding, where + if 0, introduces a jz $+2 delay at one point, that is not + even inside of a loop. This flag may thus be an artefact + of early code that was no longer used in the final build 50h 2 Character direction: 80h=up, 40h=down, 20h=left, 10h=right 52h 2 Hotspot Id for selected hotspot 54h 2 X ending position for character + 80h - 10h -- cgit v1.2.3