Sprites.asm 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. include_macros equ 1
  2. include_deb_mac equ 1
  3. include_struc equ 1
  4. include_flags equ 1
  5. include_error_codes equ 1
  6. include include.asm
  7. st_sort_list struc
  8. y_cord dw ?
  9. compact dd ?
  10. sprite dd ?
  11. st_sort_list ends
  12. start32data
  13. align 4
  14. sort_list_size equ 30
  15. sort_list st_sort_list sort_list_size dup (<?>)
  16. sprite_x dd ? ;calculated by draw sprite
  17. sprite_y dd ?
  18. sprite_w dd ?
  19. sprite_h dd ?
  20. mask_x1 dd ? ;pixels to skip on left of sprite
  21. mask_x2 dd ? ;pixels to skip on right of sprite
  22. end32data
  23. start32code
  24. extrn load_file:near
  25. sprite_engine proc
  26. call back_sprites
  27. call sort_sprites
  28. call fore_sprites
  29. se_ret: ret
  30. fore_sprites: mov ecx,1 ;test status bit 1 (foreground
  31. jmp std_sprites
  32. back_sprites: clear ecx ;test status bit 0 (background)
  33. std_sprites: mov ebx,offset draw_list_no
  34. std_sp_loop: flodsd eax,ebx ;look for draw list
  35. jife eax,se_ret
  36. new_draw_list: fetch_compact edi
  37. back_loop: ;edi points to list
  38. flodswl eax,edi
  39. jife ax,std_sp_loop
  40. ; ax is an id
  41. cmp ax,-1
  42. jne not_new_list
  43. movzx eax,word ptr[edi]
  44. jmp new_draw_list
  45. not_new_list: fetch_compact
  46. bt (cpt[esi]).c_status,cx ;is it fore/back ground
  47. jnc back_loop
  48. mov ax,(cpt[esi]).c_screen ;on this screen?
  49. cmp ax,wpt [screen]
  50. jne back_loop
  51. ; ecx is fore/back bit
  52. ; ebx points to draw_list_no+1
  53. ; esi is compact
  54. ; edi is current draw_list pointer
  55. push ecx
  56. push ebx
  57. push edi
  58. push ecx ;save fore/back for vertical mask
  59. movzx eax,(cpt[esi]).c_frame ;get the frame number
  60. shr eax,6 ;devide by 64
  61. fetch_item edi,eax
  62. call draw_sprite
  63. pop ecx
  64. jifne ecx,no_v_mask
  65. call vertical_mask
  66. no_v_mask: mov bl,81h
  67. bt (cpt[esi]).c_status,3 ;re_create?
  68. jc no_reform
  69. mov bl,1
  70. no_reform: call vector_to_game
  71. pop edi
  72. pop ebx
  73. pop ecx
  74. jmp back_loop
  75. ;----------------------------------
  76. sort_sprites: ;calculate and sort normal sprites
  77. mov ebx,offset draw_list_no
  78. big_sort_loop: flodsws ax,ebx
  79. jife ax,se_ret
  80. push ebx
  81. mov ebp,offset sort_list
  82. clear ecx ;sprite count
  83. a_new_draw_list: fetch_compact edi ;get list
  84. form_list: flodsws ax,edi ;get an id
  85. jife ax,made_list
  86. cmp ax,-1 ;new list?
  87. jne process_this_id
  88. mov ax,[edi]
  89. jmp a_new_draw_list
  90. process_this_id: fetch_compact
  91. bt (cpt[esi]).c_status,2 ;is it sortable playfield?(!?!)
  92. jnc form_list
  93. mov ax,(cpt[esi]).c_screen ;on current screen?
  94. cmp ax,wpt [screen]
  95. jne form_list
  96. movzx eax,(cpt[esi]).c_frame ;get frame
  97. shr eax,6 ;devide by 64
  98. fetch_item ebx,eax
  99. ; If ebx=0 then the sprite data has not been loaded, a program error
  100. ; The simplest solution is to ignore the sprite
  101. ifdef debug_42
  102. jifne ebx,no_error
  103. printf "Missing file (1) %d",eax
  104. debug_compact esi,"missing file 1"
  105. mov (cpt[esi]).c_status,0
  106. jmp form_list
  107. no_error:
  108. else
  109. jife ebx,form_list ;just continue
  110. endif
  111. mov ax,(cpt[esi]).c_ycood ;calculate y coordinate
  112. add ax,(s ptr[ebx]).s_offset_y ;add offset
  113. add ax,(s ptr[ebx]).s_height ;get bottom of sprite
  114. mov ds:(st_sort_list ptr[ebp]).y_cord,ax
  115. mov ds:(st_sort_list ptr[ebp]).compact,esi
  116. mov ds:(st_sort_list ptr[ebp]).sprite,ebx
  117. add ebp,SIZE st_sort_list
  118. inc ecx
  119. jmp form_list
  120. made_list: ;now sort the list
  121. dec ecx
  122. js no_sprites ;no sprites to sort
  123. mov edx,ecx
  124. je not_my_sort ;1 sprite is already sorted
  125. ; Now really sort the list
  126. bubble_loop: clear ebx ;sort flag
  127. mov esi,offset sort_list
  128. mov ecx,edx
  129. inner_bubble: mov ax,[esi] ;first y coordinate
  130. cmp ax,[esi+SIZE st_sort_list] ;second y coordinate
  131. jna no_swap
  132. xchg ax,[esi+SIZE st_sort_list] ;swap y coords
  133. mov [esi],ax
  134. mov eax,(st_sort_list ptr[esi]).compact ;swap compacts
  135. xchg eax,(st_sort_list ptr[esi+SIZE st_sort_list]).compact
  136. mov (st_sort_list ptr[esi]).compact,eax
  137. mov eax,(st_sort_list ptr[esi]).sprite ;swap sprites
  138. xchg eax,(st_sort_list ptr[esi+SIZE st_sort_list]).sprite
  139. mov (st_sort_list ptr[esi]).sprite,eax
  140. mov bl,1
  141. no_swap: add esi,SIZE st_sort_list
  142. loop inner_bubble
  143. jifne ebx,bubble_loop
  144. not_my_sort: ;now print them all
  145. ; edx is no of sprites-1
  146. inc edx
  147. cherror edx,nc,sort_list_size,em_internal_error
  148. mov esi,offset sort_list
  149. print_loop: push edx
  150. push esi
  151. mov edi,(st_sort_list ptr[esi]).sprite
  152. mov esi,(st_sort_list ptr[esi]).compact
  153. call draw_sprite
  154. mov bl,81h
  155. bt (cpt[esi]).c_status,3
  156. jc not_reform
  157. mov bl,1
  158. not_reform: call vector_to_game
  159. bt (cpt[esi]).c_status,9
  160. jc no_vertical_mask
  161. call vertical_mask
  162. no_vertical_mask: pop esi
  163. add esi,SIZE st_sort_list
  164. pop edx
  165. floop edx,print_loop
  166. no_sprites: pop ebx
  167. jmp big_sort_loop
  168. sprite_engine endp
  169. draw_sprite proc
  170. ; esi points to compact
  171. ; edi points to sprite data
  172. ; if edi=0 then the sprite data has not been loaded, a program bug
  173. ; The simplest solution is to not print the sprite
  174. ifdef debug_42
  175. jifne edi,no_error
  176. movzx eax,(cpt[esi]).c_frame
  177. shr eax,6
  178. printf "Missing File (2) %d",eax
  179. debug_compact esi,"Missing file 2"
  180. mov [sprite_w],0
  181. mov (cpt[esi]).c_status,0
  182. ret
  183. no_error:
  184. else
  185. jife edi,nowt_to_do
  186. endif
  187. push esi
  188. push edi
  189. movzx ebx,(s ptr[edi]).s_width ;put width and height in
  190. mov [sprite_w],ebx
  191. movzx edx,(s ptr[edi]).s_height
  192. mov [sprite_h],edx
  193. mov [mask_x1],0
  194. mov [mask_x2],0
  195. movzx eax,(cpt[esi]).c_frame ;get pointer to data
  196. and ax,3fh
  197. movsx ecx,(s ptr[edi]).s_sp_size
  198. mul ecx
  199. add eax,SIZE s
  200. add eax,edi
  201. mov ecx,eax ;pointer to sprite data
  202. ; Look at y values
  203. movzx eax,(cpt[esi]).c_ycood
  204. add ax,(s ptr[edi]).s_offset_y
  205. sub eax,top_left_y
  206. jnc no_top_clip
  207. ; We must clip the top of the sprite
  208. neg eax
  209. sub [sprite_h],eax ;do fewer lines
  210. jna no_sprite
  211. mul (s ptr[edi]).s_width ;offset into sprite
  212. add ecx,eax
  213. clear eax
  214. no_top_clip: mov ebx,game_screen_height
  215. sub bx,(s ptr[edi]).s_height
  216. sub ebx,eax
  217. jnc no_bot_clip
  218. neg ebx
  219. sub [sprite_h],ebx
  220. jna no_sprite
  221. no_bot_clip: ;eax is screen y coordinate
  222. mov [sprite_y],eax
  223. imul eax,eax,game_screen_width
  224. ; Look at x values
  225. movzx ebx,(cpt[esi]).c_xcood
  226. add bx,(s ptr[edi]).s_offset_x
  227. sub ebx,top_left_x
  228. jnc left_ok
  229. ; Need to mask left of sprite
  230. neg ebx
  231. sub [sprite_w],ebx
  232. jna no_sprite
  233. mov [mask_x1],ebx
  234. clear ebx
  235. left_ok: mov edx,game_screen_width
  236. sub dx,(s ptr[edi]).s_width
  237. sub edx,ebx
  238. jnc right_ok
  239. ; Mask right of sprite
  240. neg edx
  241. sub [sprite_w],edx
  242. jna no_sprite
  243. mov [mask_x2],edx
  244. right_ok: mov [sprite_x],ebx
  245. add eax,ebx
  246. add eax,[backscreen] ;pointer to where sprite is printed
  247. mov ebx,[sprite_w]
  248. mov edx,[sprite_h]
  249. cherror ebx,nc,321,em_internal_error
  250. cherror dx,nc,192,em_internal_error
  251. mov esi,ecx
  252. mov edi,eax
  253. draw_loop: push edi
  254. mov ecx,ebx
  255. add esi,[mask_x1]
  256. pix_loop: lodsb
  257. jife al,no_pix
  258. mov [edi],al
  259. no_pix: inc edi
  260. floop ecx,pix_loop
  261. pop edi
  262. add edi,full_screen_width
  263. add esi,[mask_x2]
  264. floop dx,draw_loop
  265. pop edi
  266. pop esi
  267. ; Convert the sprite coordinate/size values to blocks for vertical mask and/or vector to game
  268. mov eax,[sprite_x]
  269. mov ebx,[sprite_w]
  270. mov ecx,[sprite_y]
  271. mov edx,[sprite_h]
  272. add ebx,eax
  273. add ebx,GRID_W-1 ;-1 pixel, +1 block for looping
  274. add edx,ecx
  275. add edx,GRID_H-1
  276. shr eax,GRID_W_SHIFT
  277. shr ebx,GRID_W_SHIFT
  278. shr ecx,GRID_H_SHIFT
  279. shr edx,GRID_H_SHIFT
  280. sub ebx,eax
  281. sub edx,ecx
  282. mov [sprite_x],eax
  283. mov [sprite_w],ebx
  284. mov [sprite_y],ecx
  285. mov [sprite_h],edx
  286. ret
  287. no_sprite: mov [sprite_w],0
  288. pop edi
  289. pop esi
  290. ret
  291. draw_sprite endp
  292. vector_to_game proc
  293. ; Plot sprite onto screen grid
  294. ; plot with value in bl
  295. ; esi is compact
  296. ; edi is sprite data
  297. mov ebp,[sprite_h]
  298. mov edx,[sprite_w]
  299. jife edx,nowt_to_do
  300. mov eax,[sprite_y]
  301. imul eax,eax,GRID_X
  302. add eax,[sprite_x]
  303. add eax,[game_grid]
  304. vg_loop1: push eax
  305. mov cx,dx
  306. vg_loop2: or bpt[eax],bl
  307. inc eax
  308. floop cx,vg_loop2
  309. pop eax
  310. add eax,GRID_X
  311. floop ebp,vg_loop1
  312. nowt_to_do:: ret ;label used elsewhere
  313. vector_to_game endp
  314. vertical_mask proc
  315. ; Calculate grid coordinates
  316. push esi
  317. push edi
  318. test [sprite_w],-1
  319. je no_plot
  320. mov edx,[sprite_y] ;get bottom y
  321. add edx,[sprite_h]
  322. dec edx
  323. mov ecx,edx
  324. imul ecx,ecx,GRID_X
  325. add ecx,[sprite_x] ;get grid offset
  326. shl ecx,1 ;words
  327. mov eax,edx
  328. imul eax,eax,GRID_H*full_screen_width ;calculate screen offset
  329. mov ebx,[sprite_x]
  330. imul ebx,ebx,GRID_W
  331. add eax,ebx
  332. mov edi,[backscreen] ;pointer to back screen
  333. add edi,eax
  334. ; edi = screen offset
  335. ; ecx = grid offset
  336. mov edx,offset layer_1_id ;start with layer 1
  337. layer_loop: push edi
  338. push ecx
  339. mov ebx,[sprite_w]
  340. ; move upwards in vertical strips
  341. x_loop: push edx
  342. push ebx
  343. push ecx
  344. push edi
  345. try_nlayer: mov eax,12[edx] ;get layer 1 grid item
  346. jife eax,next_x
  347. fetch_item ;pointer to grid in esi
  348. test wpt[esi+ecx],-1 ;is there a block here?
  349. jne start_x
  350. lea edx,4[edx] ;try a new layer
  351. jmp try_nlayer
  352. start_x: mov ebp,[sprite_h] ;move all the way up
  353. block_loop: push edx ;save current layer
  354. push esi
  355. try_dummy: movzx eax,wpt[esi+ecx] ;get block
  356. jife ax,next_x_edx ;anything here?
  357. js dummy_block ;check for dummy block
  358. dec eax
  359. push ecx
  360. push edi
  361. ; Do block eax
  362. imul eax,eax,GRID_W*GRID_H ;get pointer to data
  363. mov ecx,[edx]
  364. fetch_item esi,ecx ;pointer to source
  365. add esi,eax
  366. mov ch,GRID_H
  367. block_loop2: push edi
  368. mov cl,GRID_W
  369. pix_loop: lodsb
  370. jife al,no_pix
  371. mov [edi],al
  372. no_pix: inc edi
  373. floop cl,pix_loop
  374. pop edi
  375. add edi,full_screen_width
  376. floop ch,block_loop2
  377. pop edi
  378. pop ecx
  379. dummy_end: pop esi
  380. sub edi,GRID_H*full_screen_width
  381. sub ecx,GRID_X*2 ;up one
  382. pop edx
  383. floop ebp,block_loop
  384. jmp next_x
  385. dummy_block: jmp dummy_end ;Shorley not???
  386. lea edx,4[edx] ;try another layer
  387. mov eax,12[edx]
  388. fetch_item
  389. jifne eax,try_dummy
  390. jmp dummy_end
  391. next_x_edx: pop esi
  392. pop edx
  393. next_x: pop edi
  394. add edi,GRID_W
  395. pop ecx
  396. add ecx,2
  397. pop ebx
  398. pop edx
  399. floop ebx,x_loop
  400. ; try for another layer
  401. pop ecx
  402. pop edi
  403. lea edx,4[edx]
  404. test dpt 12[edx],-1
  405. jne layer_loop
  406. no_plot: pop edi
  407. pop esi
  408. ret
  409. vertical_mask endp
  410. end32code
  411. end
  412.