Autoroot.asm 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. include_macros equ 1
  2. include_deb_mac equ 1
  3. include_struc equ 1
  4. include_error_codes equ 1
  5. include include.asm
  6. route_grid_width equ ((game_screen_width/8)+2)
  7. route_grid_height equ ((game_screen_height/8)+2)
  8. route_grid_size equ (route_grid_width*route_grid_height*2)
  9. walk_jump equ 8 ;walk in blocks of 8
  10. check_block macro offst
  11. local label
  12. test wpt[esi+(offst)],-1 ;check for empty or a wall
  13. jle label
  14. cmp [esi+(offst)],ax
  15. jnc label
  16. mov ax,[esi+offst]
  17. mov [grid_changed],1
  18. label:
  19. endm
  20. start32data
  21. route_grid dd ? ;pointer to route data grid
  22. direction_x dd ?
  23. direction_y dd ?
  24. ar_init_x dw ?
  25. ar_init_y dw ?
  26. ar_post_x dw ?
  27. ar_post_y dw ?
  28. grid_changed dd ?
  29. route_data dd ? ;pointer to where route data goes
  30. end32data
  31. start32code
  32. initialise_router proc
  33. mov eax,route_grid_size
  34. call my_malloc
  35. mov [route_grid],eax
  36. ret
  37. initialise_router endp
  38. auto_route proc
  39. ; esi is compact to route.
  40. mov eax,(cpt[esi]).c_anim_scratch ;find where to put route data
  41. mov [route_data],eax
  42. ; Initially only do the player, and don't terminate routes half way.
  43. movzx eax,(cpt[esi]).c_screen ;get current screen
  44. mov al,bpt [offset grid_convert_table+eax]
  45. cherror al,nc,tot_no_grids,em_internal_error
  46. imul eax,grid_size
  47. add eax,[game_grids]
  48. add eax,grid_size-4 ;point to end of grid (makes stretching easier)
  49. mov edx,esi ;put compact in here
  50. mov esi,eax
  51. mov edi,[route_grid]
  52. add edi,route_grid_size-2
  53. std ;do it all backwards
  54. movzx eax,(cpt[edx]).c_mega_set ;get the width of the mega
  55. mov bh,bpt (cpt[edx+eax]).c_grid_width
  56. clear bl ;bh:bl are stretching registers
  57. ; First clear the bottom line and right hand edge of next line
  58. mov ecx,route_grid_width+1
  59. clear eax
  60. rep stosw
  61. mov ebp,route_grid_height-2
  62. mov ch,route_grid_width-2
  63. lodsd ;get 4 bytes of grid data
  64. mov cl,32
  65. stretch: shr eax,1 ;check a bit
  66. jc bit_set
  67. ; This bit is clear, are we still stretching
  68. jifne bl,still_stretching
  69. mov wpt[edi],0 ;this block is free
  70. jmp next_stretch
  71. still_stretching: ;Still stretching from a previous block
  72. dec bl
  73. mov wpt[edi],-1
  74. jmp next_stretch
  75. bit_set: mov wpt[edi],-1
  76. mov bl,bh ;set up stretch factor
  77. next_stretch: sub edi,2
  78. floop cl,still_bits ;check for end of bit pattern
  79. lodsd
  80. mov cl,32
  81. still_bits: dec ch
  82. jne stretch
  83. ; floop ch,stretch ;do a line
  84. mov dpt[edi-2],0 ;do edges
  85. lea edi,[edi-4]
  86. mov ch,route_grid_width-2
  87. xor bl,bl ;clear stretch factor
  88. floop ebp,stretch ;and do the whole grid
  89. ; Finally clear the top line (right hand edge already done)
  90. clear eax
  91. mov ecx,route_grid_width-1
  92. rep stosw
  93. cld
  94. ; The grid has been initialised.
  95. ; Calculate the start and end points
  96. clear eax
  97. mov [ar_init_x],ax ;clear start and end offsets
  98. mov [ar_init_y],ax
  99. mov [ar_post_x],ax
  100. mov [ar_post_y],ax
  101. mov ax,(cpt[edx]).c_ycood
  102. sub ax,136 ;change coordinate systems
  103. jnc no_init_y1
  104. mov [ar_init_y],ax
  105. clear ax
  106. no_init_y1: cmp ax,game_screen_height
  107. jc no_init_y2
  108. sub ax,game_screen_height
  109. mov [ar_init_y],ax
  110. mov ax,game_screen_height-1
  111. no_init_y2: shr ax,3 ;change into blocks
  112. mov bh,al ;and save it
  113. mov ax,(cpt[edx]).c_xcood
  114. sub ax,128 ;change coordinate systems
  115. jnc no_init_x1
  116. mov [ar_init_x],ax
  117. clear ax
  118. no_init_x1: cmp ax,game_screen_width
  119. jc no_init_x2
  120. sub ax,game_screen_width-1 ;changed to -1 to match amiga
  121. mov [ar_init_x],ax
  122. mov ax,game_screen_width-1
  123. no_init_x2: shr ax,3 ;change into blocks
  124. mov bl,al ;and save it
  125. ; and destination
  126. mov ax,(cpt[edx]).c_ar_target_y
  127. sub ax,136 ;change coordinate systems
  128. jnc no_post_y1
  129. mov [ar_post_y],ax
  130. clear ax
  131. no_post_y1: cmp ax,game_screen_height
  132. jc no_post_y2
  133. sub ax,game_screen_height
  134. mov [ar_post_y],ax
  135. mov ax,game_screen_height-1
  136. no_post_y2: shr ax,3 ;change into blocks
  137. mov ch,al ;and save it
  138. mov ax,(cpt[edx]).c_ar_target_x
  139. sub ax,128 ;change coordinate systems
  140. jnc no_post_x1
  141. mov [ar_post_x],ax
  142. clear ax
  143. no_post_x1: cmp ax,game_screen_width
  144. jc no_post_x2
  145. sub ax,game_screen_width
  146. mov [ar_post_x],ax
  147. mov ax,game_screen_width-1
  148. no_post_x2: shr ax,3 ;change into blocks
  149. mov cl,al ;and save it
  150. ; bh:bl is source y,x
  151. ; ch:cl is destination y,x
  152. cmp bh,ch
  153. jne yes_route
  154. cmp bl,cl
  155. je empty_route
  156. yes_route: ;Work out the route calculation direction
  157. cmp bh,ch
  158. jc go_down
  159. mov [direction_y],-(route_grid_width*2) ;go up
  160. mov dh,bh ;this no of lines to do
  161. jmp go_up
  162. go_down: mov [direction_y],route_grid_width*2 ;go down
  163. mov dh,route_grid_height-1 ;-2
  164. sub dh,bh ;this no of lines to do
  165. go_up: cmp bl,cl
  166. jc go_right
  167. mov [direction_x],-2 ;go left
  168. mov dl,bl ;this no of lines to do
  169. add dl,2
  170. jmp go_left
  171. go_right: mov [direction_x],2 ;go right
  172. mov dl,route_grid_width-1 ;2 ;-1 put in 8/7/93
  173. sub dl,bl
  174. go_left: shl cx,1 ;multiply values by 2
  175. mov al,route_grid_width ;calculate destination address
  176. mul ch
  177. add al,cl
  178. adc ah,0
  179. mov edi,eax
  180. add edi,[route_grid]
  181. add edi,(route_grid_width+1)*2 ;skip blank edges
  182. shl bx,1 ;mpy vals by 2
  183. mov al,route_grid_width ;calculate source address
  184. mul bh
  185. add al,bl
  186. adc ah,0
  187. mov esi,eax
  188. add esi,[route_grid]
  189. add esi,(route_grid_width+1)*2 ;skip blank edges
  190. mov wpt[esi],1 ;start this one off
  191. cmp dh,route_grid_height-3 ;2 ;if we are not on the edge,
  192. jnc not_hor_edge ;move diagonally from start
  193. sub esi,[direction_y]
  194. not_hor_edge: cmp dl,route_grid_width-2
  195. jnc not_ver_edge
  196. sub esi,[direction_x]
  197. not_ver_edge:
  198. ; So, dh:dl is no of blocks to check in y,x
  199. ; esi = start address
  200. ; edi = destination address
  201. ; If destination is a wall then we have no route
  202. test wpt[edi],-1
  203. jne no_route
  204. ; mov wpt[edi],0 ;IF DEST IS WALL REMOVE WALL WHY?????
  205. wallow_y: mov ch,dh
  206. push esi
  207. mov [grid_changed],0
  208. wallow_x: mov cl,dl
  209. push esi
  210. wallow: ;do current block
  211. test wpt[esi],-1 ;only do block if block not done yet
  212. jne block_done
  213. ; ignore a block if it is empty or a wall
  214. mov ax,-1
  215. check_block 2
  216. check_block -2
  217. check_block route_grid_width*2
  218. check_block -route_grid_width*2
  219. inc ax ;add 1, will turn wall (-1) into 0
  220. je block_done
  221. mov [esi],ax
  222. block_done: add esi,[direction_x] ;onwards horizontally
  223. floop cl,wallow
  224. pop esi
  225. add esi,[direction_y]
  226. floop ch,wallow_x
  227. pop esi
  228. test wpt[edi],-1 ;have we found the route?
  229. jne route_found
  230. test [grid_changed],-1 ;will we ever find the route?
  231. je no_route
  232. ; We have done a section, see if we want to shift backwards
  233. cmp dh,route_grid_height-4
  234. jnc no_move_ver
  235. sub esi,[direction_y]
  236. inc dh
  237. no_move_ver: cmp dl,route_grid_width-4
  238. jnc no_move_hor
  239. sub esi,[direction_x]
  240. inc dl
  241. no_move_hor: jmp wallow_y
  242. route_found: ;The time has come, to work out the route
  243. mov esi,[route_data] ;and point to where route data goes
  244. add esi,route_space-2 ;go backwards
  245. mov wpt[esi],0 ;route is null terminated
  246. mov ax,[edi] ;get final value
  247. dec ax ;and look for the path to this door
  248. ; check left and right first as this means last animation type is horizontal,
  249. ; looks better when exiting left or right
  250. check_dir: cmp ax,[edi-2] ;look left
  251. je look_left
  252. cmp ax,[edi+2] ;look right
  253. je look_right
  254. cmp ax,[edi-route_grid_width*2] ;look up
  255. je look_up
  256. cherror ax,ne,[edi+route_grid_width*2],em_internal_error ;MUST be look down
  257. jmp look_down
  258. ; Must be right
  259. look_right: sub esi,4
  260. mov wpt[esi+2],lefty ;going backwards remember
  261. mov wpt[esi],walk_jump
  262. right_loop: dec ax
  263. je route_done
  264. add edi,2
  265. cmp ax,[edi+2] ;keep checking right
  266. jne check_dir
  267. add wpt[esi],walk_jump
  268. jmp right_loop
  269. look_left: ;going left
  270. sub esi,4
  271. mov wpt[esi+2],righty ;going backwards remember
  272. mov wpt[esi],walk_jump
  273. left_loop: dec ax
  274. je route_done
  275. sub edi,2
  276. cmp ax,[edi-2] ;keep checking left
  277. jne check_dir
  278. add wpt[esi],walk_jump
  279. jmp left_loop
  280. look_up: ;going up
  281. sub esi,4
  282. mov wpt[esi+2],downy ;going backwards remember
  283. mov wpt[esi],walk_jump
  284. up_loop: dec ax
  285. je route_done
  286. sub edi,route_grid_width*2
  287. cmp ax,[edi-route_grid_width*2] ;keep checking up
  288. jne check_dir
  289. add wpt[esi],walk_jump
  290. jmp up_loop
  291. look_down: ;going down
  292. sub esi,4
  293. mov wpt[esi+2],upy ;going backwards remember
  294. mov wpt[esi],walk_jump
  295. down_loop: dec ax
  296. je route_done
  297. add edi,route_grid_width*2
  298. cmp ax,[edi+route_grid_width*2] ;keep checking up
  299. jne check_dir
  300. add wpt[esi],walk_jump
  301. jmp down_loop
  302. route_done: ;if there was an initial x/y movement tag it onto the start
  303. mov ax,[ar_init_x]
  304. or ax,ax
  305. je no_init_x
  306. js init_right
  307. mov bx,lefty
  308. jmp init_left
  309. init_right: mov bx,righty
  310. neg ax
  311. init_left: sub esi,4
  312. mov 2[esi],bx
  313. add ax,7 ;was +1, changed to match amiga
  314. and ax,0fff8h
  315. mov [esi],ax
  316. no_init_x: ;esi points to the start of the route data
  317. cherror esi,c,[route_data],em_internal_error
  318. mov eax,1 ;signal success
  319. debug_route
  320. ret
  321. empty_route: mov esi,[route_data] ;point to zero route
  322. mov wpt[esi],0
  323. mov eax,1
  324. debug_route
  325. ret
  326. no_route: mov eax,2 ;signal route failure
  327. ifdef ar_debug
  328. mov wpt[edi],-1
  329. debug_route
  330. endif
  331. ret
  332. auto_route endp
  333. ifdef ar_debug
  334. proc_start _draw_box__Nciiii
  335. ; void draw_box(int col,int x,int y,int w,int h);
  336. db_col equ 24
  337. db_x equ 20
  338. db_y equ 16
  339. db_w equ 12
  340. db_h equ 8
  341. mov eax,full_screen_width
  342. mul dpt db_y[ebp]
  343. add eax,db_x[ebp]
  344. mov edi,eax
  345. push es
  346. mov es,[screen_segment]
  347. mov al,db_col[ebp]
  348. mov edx,db_h[ebp]
  349. box_loop: push edi
  350. mov ecx,db_w[ebp]
  351. rep stosb
  352. pop edi
  353. add edi,full_screen_width
  354. floop edx,box_loop
  355. pop es
  356. proc_end _draw_box__Nciiii,20
  357. endif
  358. end32code
  359. end
  360.