Text.asm 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417
  1. include_macros equ 1
  2. include_deb_mac equ 1
  3. include_files equ 1
  4. include_struc equ 1
  5. include_flags equ 1
  6. include_logic equ 1
  7. include_error_codes equ 1
  8. include include.asm
  9. first_text_sec equ 77
  10. no_of_text_sections equ 8 ;8 sections per language
  11. first_text_buffer equ 274
  12. text_buffer_size equ 120
  13. char_set_header equ 128
  14. text_mouse_width equ 80h
  15. fixed_text_width equ 128
  16. start32data
  17. text_buffer db text_buffer_size dup (?)
  18. dt_col db 0 ;text colour
  19. align 4
  20. set_font_data_size equ 12
  21. main_character_set dd ? ;address of game character set
  22. dd main_char_height ;char height
  23. dd 0
  24. link_character_set dd ? ;address of link character set
  25. dd 12
  26. dd 1
  27. control_char_set dd ? ;address of control character set
  28. dd 12
  29. dd 0
  30. cur_char_set dd 0
  31. character_set dd ? ;address of current character set
  32. char_height dd ? ;height of character set
  33. ; display text variables
  34. dt_line_width dd 0 ;width of a line in pixels
  35. dt_lines dd 0 ;no of lines to do
  36. dt_line_size dd 0 ;size of one line in bytes
  37. dt_data dd 0 ;address for data
  38. ;dt_words2 dd 0 ;no of words in message
  39. dt_letters dd 0 ;no of chars in message
  40. dt_text dd ? ;pointer to text
  41. dt_char_spacing dd 0 ;character seperation adjustment
  42. dt_last_width dd 0 ;width of chars in last line (for editing)
  43. dt_centre dd 0 ;set for centre text
  44. mouse_text_data dd 0 ;space for the text mouse
  45. low_text_width dd ? ;variables for the pointer mouse
  46. pm_offset_x dd ?
  47. pm_offset_y dd ?
  48. max_no_lines equ 10
  49. centre_table dd max_no_lines dup (0) ;table for centering text
  50. speech_convert_table dd 0 ;Text numbers to file numbers
  51. dd 600 ; 553 lines in section 0
  52. dd 600+500 ; 488 lines in section 1
  53. dd 600+500+1330 ;1303 lines in section 2
  54. dd 600+500+1330+950 ; 922 lines in section 3
  55. dd 600+500+1330+950+1150 ;1140 lines in section 4
  56. dd 600+500+1330+950+1150+550 ; 531 lines in section 5
  57. dd 600+500+1330+950+1150+550+150 ; 150 lines in section 6
  58. max_speech_items equ 10 ;How many we can have loaded at any one time
  59. speech_items_list dd max_speech_items*2 dup (0)
  60. pre_after_table_area dd 0 ;location of preafter table
  61. speech_text_no dd ?
  62. speech_file_no dd ?
  63. ifdef debug_42
  64. last_speech_file dd 0
  65. last_speech_screen dd 200
  66. endif
  67. end32data
  68. start32code
  69. public logic_cursor
  70. extrn get_text_char:near
  71. initialise_text proc
  72. mov eax,char_set_file
  73. clear edx
  74. call load_file
  75. mov [main_character_set],eax
  76. clear eax
  77. call fn_set_font
  78. ifndef s1_demo
  79. mov eax,60520
  80. clear edx
  81. call load_file
  82. mov [control_char_set],eax
  83. mov eax,60521
  84. clear edx
  85. call load_file
  86. mov [link_character_set],eax
  87. endif
  88. test [_cd_version],-1 ;load preafter table for cd version
  89. je no_pre_load
  90. mov eax,60522
  91. clear edx
  92. call load_file
  93. mov [pre_after_table_area],eax
  94. no_pre_load:
  95. ifdef do_text_dump
  96. end32code
  97. start32data
  98. ; how much to jump by
  99. td_line_jump equ 10
  100. max_speech_section equ 7
  101. dump_convert_table dd 553 ; 553 lines in section 0
  102. dd 484 ; 488 lines in section 1
  103. dd 1303 ;1303 lines in section 2
  104. dd 922 ; 922 lines in section 3
  105. dd 1140 ;1140 lines in section 4
  106. dd 531 ; 531 lines in section 5
  107. dd 120 ; 150 lines in section 6
  108. end32data
  109. start32code
  110. ; Print out samples of the text files
  111. clear ebx ;section counter
  112. section_loop: ;find out how many messages in this file
  113. mov ecx,[offset dump_convert_table + ebx*4]
  114. ;printf "%d lines in section %d",ecx,ebx
  115. clear edx ;text number counter
  116. dtext_loop: mov esi,ebx ;calculate actual message number
  117. shl esi,12
  118. add esi,edx
  119. printf "section %d item %d number %d",ebx,edx,esi
  120. push ebx
  121. push ecx
  122. push edx
  123. mov eax,esi
  124. call get_text
  125. pop edx
  126. pop ecx
  127. pop ebx
  128. mov esi,offset text_buffer
  129. printf "text %s",esi
  130. printf "-"
  131. add edx,td_line_jump
  132. sub ecx,td_line_jump
  133. jnc dtext_loop
  134. ;printf "ended s%d with m%d",ebx,edx
  135. ; on to next section
  136. inc ebx
  137. cmp ebx,max_speech_section
  138. jc section_loop
  139. endif
  140. ret
  141. initialise_text endp
  142. fn_set_font proc
  143. ; set font eax
  144. mov [cur_char_set],eax
  145. imul eax,set_font_data_size
  146. add eax,offset main_character_set
  147. mov ebx,[eax]
  148. mov [character_set],ebx
  149. mov ebx,4[eax]
  150. mov [char_height],ebx
  151. mov ebx,8[eax]
  152. mov [dt_char_spacing],ebx
  153. ret
  154. fn_set_font endp
  155. fn_speak_wait proc
  156. ; non player mega char speaks
  157. ; player will wait for it to finish before continuing script processing
  158. ; esi isplayer
  159. ; eax is id to speak
  160. ; ebx is message number
  161. ; ecx is animation number
  162. mov (cpt[esi]).c_flag,ax
  163. mov (cpt[esi]).c_logic,l_listen
  164. jmp fn_speak_me
  165. fn_speak_wait endp
  166. FN_speak_wait_dir proc
  167. ; non player mega chr$ speaks S2(20Jan93tw)
  168. ; the player will wait for it to finish
  169. ; before continuing script processing
  170. ; this function sets the directional option whereby
  171. ; the anim chosen is linked to c_dir -
  172. ; esi is player
  173. ; eax is id to speak (not us)
  174. ; ebx is text message number
  175. ; ecx is base of mini table within anim_talk_table
  176. mov (cpt[esi]).c_flag,ax ;save id
  177. mov (cpt[esi]).c_logic,l_listen
  178. fetch_compact edi
  179. jife ecx,null_table ;0 means ignore anim / dir infi
  180. movzx edx,(cpt[edi]).c_dir
  181. shl edx,1
  182. add ecx,edx
  183. ; ok, got the animation number & a6 is correct
  184. null_table: call std_speak
  185. clear eax
  186. ret
  187. FN_speak_wait_dir endp
  188. fn_speak_me_dir proc
  189. ; must be player so don't cause script to drop out
  190. ; this function sets the directional option whereby
  191. ; the anim chosen is linked to c_dir
  192. ; esi is player
  193. ; eax is target id
  194. ; ebx is message number
  195. ; ecx is animation
  196. mov dx,(cpt[esi]).c_dir
  197. shl dx,1 ;2 sizes (large and small)
  198. add cx,dx
  199. fn_speak_me_dir endp
  200. ;NOWT IN YERE
  201. fn_speak_me proc
  202. ; Must be player
  203. ; esi is player
  204. ; eax is target id
  205. ; ebx is message number
  206. ; ecx is animation number
  207. fetch_compact edi
  208. call std_speak
  209. clear eax ;drop out of script
  210. ret
  211. fn_speak_me endp
  212. std_speak proc
  213. ; edi is target
  214. ; ebx is text number
  215. ; ecx is animation number or -1 for directional
  216. ; edx is optional base
  217. ; first set the animation up
  218. ; use the value in d2 as the actual anim number, except -
  219. ; for each mega set add one more to the animation number
  220. ifdef debug_42
  221. mov ebx,4277
  222. endif
  223. ifdef with_screen_saver
  224. mov [sssss_count],0
  225. endif
  226. mov [c_text_no],ebx
  227. mov ax,(cpt[edi]).c_mega_set
  228. mov dl,next_mega_set
  229. div dl
  230. add al,cl ;get correct anim no
  231. movzx eax,al
  232. mov edx,[offset anim_talk_table+eax*4] ;get animation address
  233. jife edx,no_talk_file
  234. cmp dx,-1 ;flag for special type
  235. jne old_address_type
  236. shr edx,16 ;id of a talk
  237. movzx eax,dx
  238. fetch_compact edx
  239. old_address_type: flodsws ax,edx ;sprite offset
  240. mov (cpt[edi]).c_offset,ax
  241. flodsws ax,edx
  242. mov (cpt[edi]).c_get_to_flag,ax
  243. no_talk_file: mov (cpt[edi]).c_grafix_prog,edx
  244. ; now form the text sprite
  245. ;--------------------------------------------------------------------------------------------------
  246. ; Try and say something
  247. push ebx
  248. push esi
  249. push edi
  250. ifdef clicking_optional
  251. jmp no_speech
  252. endif
  253. test [_cd_version],-1
  254. je no_speech
  255. bt [system_flags],sf_play_vocs ;sblaster only
  256. jnc no_speech
  257. bt [system_flags],sf_allow_speech
  258. jnc no_speech
  259. mov [speech_text_no],ebx
  260. mov eax,ebx ;work out section
  261. and ebx,0f000h ;section no is top 4 bits
  262. and eax,0fffh
  263. shr ebx,10 ;section no * 4
  264. add eax,[offset speech_convert_table + ebx]
  265. mov [speech_file_no],eax
  266. ifdef debug_42
  267. test [last_speech_file],-1
  268. je nolsf
  269. mov esi,[pre_after_table_area]
  270. test wpt[esi + eax*2],-1
  271. jne nolsf
  272. printf "after speech file %d comes %d in room %d",[last_speech_file],[speech_file_no],[last_speech_screen]
  273. nolsf: push eax
  274. mov eax,[speech_file_no]
  275. mov [last_speech_file],eax
  276. mov eax,[screen]
  277. mov [last_speech_screen],eax
  278. pop eax
  279. endif
  280. ; Search through the loaded speech table looking for this line or an empty space
  281. mov esi,offset speech_items_list
  282. mov ecx,max_speech_items
  283. clear ebx
  284. sp_lk_lop: cmp eax,[esi]
  285. je found_sp
  286. test dpt[esi],-1
  287. jne not_empty
  288. mov ebx,esi
  289. not_empty: lea esi,8[esi]
  290. loop sp_lk_lop
  291. ; Item is not there, did we find an empty slot
  292. cherror ebx,e,0,em_internal_error
  293. ;printf "%d not pre loaded",eax
  294. ; Load the data into this slot
  295. mov esi,ebx
  296. mov [esi],eax
  297. push esi
  298. bts [system_flags],sf_speech_file
  299. add eax,50000
  300. clear edx
  301. call load_file
  302. btr [system_flags],sf_speech_file
  303. pop esi
  304. ifdef cd_version_prot
  305. jife eax,sp_file_missing2
  306. else
  307. jife eax,sp_file_missing
  308. endif
  309. mov 4[esi],eax
  310. found_sp: ;Transfer and play the speech
  311. push esi
  312. mov eax,4[esi]
  313. movzx ecx,(s ptr[eax]).s_tot_size
  314. lea eax,SIZE s[eax]
  315. push eax
  316. push ecx
  317. push 1
  318. call _play_voc_data__Npcii
  319. bts [system_flags],sf_voc_playing
  320. pop esi ;get pointer to voc data
  321. mov dpt[esi],0 ;and kill it
  322. mov eax,4[esi]
  323. call my_free
  324. ; Trash any loaded voc files as they obviously are not needed
  325. mov esi,offset speech_items_list
  326. mov ecx,max_speech_items
  327. clear ebx
  328. sp_lk_lopz: test dpt[esi],-1
  329. je zz_slot_mt
  330. mov dpt[esi],0
  331. mov eax,4[esi]
  332. push esi
  333. push ecx
  334. call my_free
  335. pop ecx
  336. pop esi
  337. zz_slot_mt: lea esi,8[esi]
  338. loop sp_lk_lopz
  339. ; If this line is followed by another one then load it
  340. mov eax,[speech_file_no]
  341. mov esi,[pre_after_table_area]
  342. test wpt[esi + eax*2],-1
  343. je none_2lod
  344. ; Search through the loaded speech table looking for empty slot
  345. mov esi,offset speech_items_list
  346. sp_lk_lop2: test dpt[esi],-1
  347. je found_mt
  348. lea esi,8[esi]
  349. jmp sp_lk_lop2
  350. found_mt: mov edx,[pre_after_table_area]
  351. movzx eax,wpt[edx + eax*2]
  352. mov [esi],eax
  353. push esi
  354. bts [system_flags],sf_speech_file
  355. add eax,50000
  356. clear edx
  357. call load_file
  358. btr [system_flags],sf_speech_file
  359. pop esi
  360. mov 4[esi],eax
  361. jifne eax,none_2lod
  362. mov dpt[esi],0 ;file was not there!!
  363. none_2lod: ;Check if we are allowing text as well as speech
  364. bt [system_flags],sf_allow_text
  365. jc no_speech
  366. pop edi
  367. pop esi
  368. pop ebx
  369. mov (cpt[edi]).c_sp_text_id,-1 ;So we know this is a voc file
  370. mov (cpt[edi]).c_sp_time,10000000 ;We test for end of voc so this doesn't matter
  371. mov (cpt[edi]).c_logic,l_talk
  372. mov [logic_talk_button_release],1 ;reset button check
  373. ret
  374. ifdef cd_version_prot
  375. sp_file_missing2: mov dpt[esi],0
  376. pop edi
  377. pop esi
  378. pop ebx
  379. ret
  380. endif
  381. sp_file_missing: printf "missing speech file %d %d",[speech_text_no],[speech_file_no]
  382. mov dpt[esi],0
  383. jmp no_speech
  384. no_speech: pop edi
  385. pop esi
  386. pop ebx
  387. ;--------------------------------------------------------------------------------------------------
  388. mov eax,ebx
  389. mov dl,bpt (cpt[edi]).c_sp_colour ;pen
  390. ; movzx ebx,(cpt[edi]).c_sp_width ;pixel width
  391. mov ebx,fixed_text_width ;*******On PC make all speech 128 wide
  392. clear ecx ;null logic
  393. push edi
  394. mov ebp,1 ;centre the text
  395. call low_text_manager
  396. pop edi
  397. ; esi is text item compact ( text_n )
  398. ; edi is text sprite compact ( person saying )
  399. ; ebx is text compact number
  400. ; eax is text data (including sprite header)
  401. mov (cpt[edi]).c_sp_text_id,bx ;So we know what text to kill
  402. mov edx,eax
  403. ; create the x coordinate for the speech text
  404. ; we need the talkers sprite information
  405. movzx eax,(cpt[edi]).c_screen ;put our screen in
  406. mov (cpt[esi]).c_screen,ax
  407. cmp eax,[screen] ;only use coordinates if we are on the current screen
  408. jne talking_off_screen
  409. movzx eax,(cpt[edi]).c_frame ;work out text address
  410. shr eax,6
  411. fetch_item ebx
  412. mov ax,(cpt[edi]).c_xcood
  413. add ax,(s ptr[ebx]).s_offset_x ;+ our sprite offset
  414. mov cx,(s ptr[ebx]).s_width ;width of talker
  415. shr cx,1 ;halved
  416. add ax,cx ;middle of talker
  417. ; mov cx,(cpt[edi]).c_sp_width ;text width
  418. ; shr cx,1 ;middle of text
  419. ; sub ax,cx
  420. sub ax,fixed_text_width/2
  421. cmp ax,top_left_x ;off left?
  422. jnc lok
  423. mov ax,top_left_x
  424. lok: mov cx,ax ;off right?
  425. ; add cx,(cpt[edi]).c_sp_width
  426. add cx,fixed_text_width
  427. cmp cx,top_left_x+full_screen_width
  428. jc rok
  429. mov ax,top_left_x+full_screen_width
  430. ; sub ax,(cpt[edi]).c_sp_width
  431. sub ax,fixed_text_width
  432. rok: mov (cpt[esi]).c_xcood,ax
  433. mov ax,(cpt[edi]).c_ycood
  434. add ax,(s ptr[ebx]).s_offset_y
  435. sub ax,6
  436. sub ax,(s ptr[edx]).s_height ;depth of speech sprite
  437. cmp ax,top_left_y
  438. jnc yok
  439. mov ax,top_left_y
  440. yok: mov (cpt[esi]).c_ycood,ax
  441. ;mov eax,[dt_words] ;get no of words
  442. ;inc eax ;one more for timer
  443. ;imul eax,[text_rate]
  444. mov eax,[dt_letters]
  445. add eax,5
  446. mov (cpt[edi]).c_sp_time,ax
  447. mov (cpt[edi]).c_logic,l_talk
  448. mov [logic_talk_button_release],1
  449. ret
  450. talking_off_screen: ;mov eax,[dt_words] ;get no of words
  451. ;inc eax ;one more for timer
  452. ;imul eax,[text_rate]
  453. mov eax,[dt_letters]
  454. add eax,5
  455. mov (cpt[edi]).c_sp_time,ax
  456. mov (cpt[edi]).c_logic,l_talk
  457. mov (cpt[edi]).c_sp_text_id,0 ;don't kill any text 'cos none was made
  458. mov (cpt[esi]).c_status,0 ;don't display text
  459. mov [logic_talk_button_release],1
  460. ret
  461. std_speak endp
  462. low_text_manager proc
  463. ; eax = message number
  464. ; ebx = pixel_width
  465. ; ecx = text logic number
  466. ; dl = pen
  467. ; ebp = 1 for centre text
  468. push ecx
  469. push ebx
  470. push edx
  471. push ebp
  472. call get_text
  473. pop ebp
  474. pop edx
  475. pop ecx
  476. clear ebx
  477. mov esi,offset text_buffer
  478. call display_text
  479. mov [low_text_width],ebx ;save text width for pointer text
  480. pop ecx ;get logic back
  481. push eax ;save text data address
  482. mov ebx,first_text_compact
  483. text_free_loop: mov eax,ebx
  484. fetch_compact ;look at a text item
  485. test (cpt[esi]).c_status,-1
  486. je heres_the_slot
  487. inc ebx
  488. jmp text_free_loop
  489. heres_the_slot: ;esi is a free text compact
  490. pop eax ;get sprite data pointer
  491. push eax ;save it agian
  492. push ebx ;save compact number
  493. sub ebx,first_text_compact ;calculate entry buffer item no
  494. add ebx,first_text_buffer
  495. mov (cpt[esi]).c_flag,bx
  496. xchg eax,[offset item_list+ebx*4]
  497. ; eax could be old text data that can be free'd
  498. jife eax,no_free
  499. push ecx
  500. push esi
  501. call my_free
  502. pop esi
  503. pop ecx
  504. no_free: ;set up the compact to display the data
  505. mov (cpt[esi]).c_logic,cx
  506. mov (cpt[esi]).c_status,st_logic+st_foreground+st_recreate
  507. mov eax,[screen]
  508. mov (cpt[esi]).c_screen,ax
  509. pop ebx ;compact number
  510. pop eax ;text data
  511. ret
  512. low_text_manager endp
  513. get_text proc
  514. ; mov eax,24646
  515. ; Decompress a text message
  516. ; eax is text message number
  517. mov ebx,eax ;section number is top four bits
  518. and ebx,0f000h
  519. shr ebx,10 ;pointer to dwords
  520. mov esi,[offset item_list+first_text_sec*4+ebx]
  521. jifne esi,section_loaded
  522. ; We must load this section
  523. push eax
  524. push ebx
  525. mov eax,ebx
  526. shr eax,2
  527. mov ebx,[_language] ;calculate language offset
  528. imul ebx,ebx,no_of_text_sections
  529. add eax,ebx
  530. add eax,60600
  531. clear edx
  532. call load_file
  533. mov esi,eax
  534. pop ebx
  535. mov [offset item_list+first_text_sec*4+ebx],eax
  536. pop eax
  537. section_loaded: clear ecx ;offset calculator
  538. mov ebx,eax ;first look at 32 message blocks
  539. and ebx,0fe0h
  540. je no_32s
  541. lea edx,4[esi]
  542. shr ebx,5
  543. loop_32: movzx ebp,wpt[edx]
  544. add ecx,ebp
  545. ifdef debug_42
  546. jc text_error
  547. endif
  548. add edx,2
  549. floop ebx,loop_32
  550. no_32s: mov edx,eax ;point to start of single offset block
  551. and ax,1fh ;no of singles to do
  552. je no_singles
  553. and edx,0fe0h
  554. add dx,[esi]
  555. add edx,esi
  556. single_loop: movzx ebx,bpt[edx]
  557. inc edx
  558. btr bx,7
  559. jc big_mess
  560. add ecx,ebx
  561. floop ax,single_loop
  562. jmp no_singles
  563. big_mess: shl ebx,3 ;double bytes to double bits
  564. add ecx,ebx
  565. floop ax,single_loop
  566. no_singles: ;ecx is offset into message
  567. mov edx,ecx
  568. shr ecx,2 ;double bits to bytes
  569. add cx,2[esi]
  570. ifdef debug_42
  571. jc text_error
  572. endif
  573. add esi,ecx
  574. ; Bit pointer: 0->8 , 1->6 , 2->4 , 3->2 ( 0->4 , 1-> 3 , 2->2 , 3->1 )
  575. and edx,3
  576. xor dl,3
  577. inc edx
  578. shl edx,1
  579. mov bl,[esi] ;get a byte
  580. inc esi
  581. mov edi,offset text_buffer
  582. text_loop: call get_text_char
  583. stosb
  584. cherror edi,nc,offset text_buffer+text_buffer_size,em_internal_error
  585. jifne al,text_loop
  586. ;ifdef debug_42
  587. ; mov edi,offset text_buffer
  588. ; printf "text message %s",edi
  589. ;endif
  590. ret
  591. ifdef debug_42
  592. text_error: program_error em_internal_error
  593. endif
  594. get_text endp
  595. get_tbit proc
  596. dec dl
  597. jns no_new_byte
  598. mov bl,[esi]
  599. inc esi
  600. mov dx,7
  601. no_new_byte: bt bx,dx
  602. ret
  603. get_tbit endp
  604. display_text proc
  605. ; Turn a text message into a sprite.
  606. ; dl = text colour number
  607. ; cx = pixel width
  608. ; ebx = 0 : Allocate data for text
  609. ; ebx != 0 : Use memory at ebx for data
  610. ; esi points to text
  611. ; ebp = 1 for centre text
  612. ; First split the message into seperate lines that will fit a fixed width
  613. mov [dt_col],dl ;save colour
  614. mov wpt[dt_line_width],cx ;and width
  615. mov [dt_lines],0
  616. ;mov [dt_words2],1
  617. mov [dt_letters],1
  618. mov [dt_data],ebx
  619. mov [dt_text],esi
  620. mov [dt_centre],ebp
  621. mov edi,[character_set]
  622. clear edx ;use dx for width
  623. clear eax ;clear bit 8-31
  624. mov ebp,offset centre_table
  625. ifdef debug_42
  626. clear ebx ;will cause frame error if first word too long
  627. endif
  628. split_loop: lodsb ;get a character
  629. inc [dt_letters]
  630. sub al,' '
  631. jc line_split ;< 20h means end of line (0)
  632. jne not_space
  633. mov ebx,esi ;keep track of last space
  634. ;inc [dt_words2]
  635. mov ds:[ebp],edx ;save width for centering
  636. not_space: add dl,[edi+eax] ;add character width
  637. adc dh,0
  638. add dx,wpt[dt_char_spacing] ;include character spacing
  639. cmp dx,cx
  640. jc split_loop
  641. ; we have exceeded the line width
  642. cherror bpt[ebx-1],e,10,em_internal_error
  643. mov bpt[ebx-1],10 ;turn last space into line feed
  644. clear edx
  645. inc [dt_lines] ;one more line
  646. lea ebp,4[ebp] ;next space in centering table
  647. mov esi,ebx ;go back for new count
  648. jmp split_loop
  649. line_split: mov wpt[dt_last_width],dx ;save width of last line (for editing single lines)
  650. mov ds:[ebp],edx ;and update centering table
  651. ;dt_lines = no of lines-1
  652. inc [dt_lines]
  653. cherror [dt_lines],nc,max_no_lines,em_internal_error
  654. movzx eax,cx ;calc size of one character line
  655. imul eax,[char_height]
  656. mov [dt_line_size],eax
  657. imul eax,[dt_lines] ;get amount of memory to allocate
  658. add eax,SIZE s+4 ;4 for safety (rounding up)
  659. push eax ;save no of bytes
  660. mov edi,[dt_data] ;check if memory already exists
  661. jifne edi,got_mem
  662. call my_malloc ;and fetch the memory
  663. mov edi,eax
  664. mov [dt_data],eax
  665. got_mem: pop ecx ;no of bytes to clear
  666. sub ecx,SIZE s ;don't touch the header
  667. push edi
  668. add edi,SIZE s
  669. clear eax
  670. shr ecx,2 ;do dwords
  671. rep stosd
  672. pop edi
  673. ; Make the header
  674. mov eax,[dt_line_width]
  675. mov (s ptr[edi]).s_width,ax
  676. mov ebx,[char_height]
  677. imul ebx,[dt_lines]
  678. mov (s ptr[edi]).s_height,bx
  679. imul eax,ebx
  680. mov (s ptr[edi]).s_sp_size,ax
  681. mov (s ptr[edi]).s_offset_x,0
  682. mov (s ptr[edi]).s_offset_y,0
  683. mov esi,[dt_text]
  684. add edi,SIZE s ;point to where pixels start
  685. push edi ;save it
  686. mov ebx,[character_set]
  687. mov dl,[dt_col]
  688. mov ecx,offset centre_table
  689. line_loop: test [dt_centre],-1 ;check for centering
  690. je text_loop
  691. mov eax,[dt_line_width] ;centre the text
  692. sub eax,[ecx]
  693. lea ecx,4[ecx]
  694. shr eax,1
  695. add edi,eax
  696. text_loop: movzx eax,bpt[esi] ;get a character
  697. inc esi
  698. sub al,' '
  699. jc line_end
  700. call make_game_character ;[make_character]
  701. jmp text_loop
  702. line_end: ;end of line or end of text?
  703. cmp al,10-' '
  704. jne text_end
  705. pop edi ;start of last line
  706. add edi,[dt_line_size] ;start of next
  707. push edi
  708. jmp line_loop
  709. text_end: ;The sprite has been done (yo ho ho)
  710. pop eax ;trash dummy edi
  711. mov eax,[dt_data]
  712. mov ebx,[dt_last_width]
  713. ret
  714. display_text endp
  715. make_game_character proc
  716. ; eax is character to print - 20h
  717. ; ebx points to character set
  718. ; edi points to data
  719. ; dl is colour
  720. push esi
  721. push ebx
  722. push ecx
  723. mov cl,ds:[eax+ebx] ;get char width
  724. inc cl ;bodge 'cos main character set widths are wrong
  725. sub cl,bpt [dt_char_spacing] ;only main char set has 0 spacing
  726. mov dh,bpt[char_height]
  727. shl dh,2 ;4 bytes per character line
  728. mul dh
  729. mov esi,eax
  730. add esi,char_set_header
  731. add esi,ebx
  732. mov ebp,[char_height]
  733. push edi
  734. line_loop: push edi
  735. lodsw ;ax = data
  736. xchg ah,al
  737. mov bx,[esi] ;bx = mask
  738. xchg bh,bl
  739. add esi,2
  740. mov ch,cl
  741. bit_loop: shl bx,1 ;check mask
  742. jc yes_mask
  743. ;ifndef text_test
  744. ; mov bpt[edi],0 ;no mask no nothing
  745. ;endif
  746. shl ax,1 ;shift data too
  747. jmp bit_clear
  748. yes_mask: shl ax,1 ;check data
  749. jc bit_set
  750. mov bpt[edi],240 ;1
  751. jmp bit_clear
  752. bit_set: mov bpt[edi],dl ;15
  753. bit_clear: inc edi
  754. floop ch,bit_loop
  755. pop edi
  756. add edi,[dt_line_width]
  757. floop ebp,line_loop
  758. pop edi
  759. and ecx,0ffh
  760. add edi,ecx
  761. add edi,[dt_char_spacing]
  762. dec edi ;bodge 'cos main character set widths are wrong
  763. add edi,[dt_char_spacing] ;only main char set has 0 spacing
  764. pop ecx
  765. pop ebx
  766. pop esi
  767. ret
  768. make_game_character endp
  769. fn_pointer_text proc
  770. ; eax = id of compact pointer is over
  771. fetch_compact
  772. movzx eax,(cpt[esi]).c_cursor_text
  773. mov ebx,text_mouse_width
  774. mov ecx,l_cursor
  775. mov dl,242
  776. clear ebp
  777. call low_text_manager
  778. mov [cursor_id],ebx
  779. ; Calculate offsets and things
  780. test [menu],-1 ;menu items are different
  781. je not_menu
  782. mov [pm_offset_y],top_left_y-2
  783. cmp [amouse_x],150
  784. jc menu_right
  785. ; Text to left of cursor
  786. mov eax,top_left_x - 4
  787. sub eax,[low_text_width]
  788. mov [pm_offset_x],eax
  789. jmp logic_cursor
  790. menu_right: mov [pm_offset_x],top_left_x+24
  791. jmp logic_cursor
  792. not_menu: mov [pm_offset_y],top_left_y-10
  793. cmp [amouse_x],150
  794. jc nmenu_right
  795. ; Text to left of cursor
  796. mov eax,top_left_x - 4
  797. sub eax,[low_text_width]
  798. mov [pm_offset_x],eax
  799. jmp logic_cursor
  800. nmenu_right: mov [pm_offset_x],top_left_x+13
  801. logic_cursor::
  802. ; mov eax,[amouse_x]
  803. ; add eax,5 + top_left_x
  804. ; sub eax,[mouse_offset_x]
  805. ;
  806. ; mov ebx,[amouse_y]
  807. ;
  808. ; cmp ebx,26 ;put it above or below
  809. ; jc below
  810. ;
  811. ; add ebx,top_left_y - 11
  812. ; jmp above
  813. ;
  814. ;below: add ebx,top_left_y + 1
  815. ; add eax,17
  816. ;
  817. ;above: sub ebx,[mouse_offset_y]
  818. mov eax,[amouse_x]
  819. sub eax,[mouse_offset_x]
  820. add eax,[pm_offset_x]
  821. mov ebx,[amouse_y]
  822. sub ebx,[mouse_offset_y]
  823. add ebx,[pm_offset_y]
  824. cmp ebx,top_left_y
  825. jnc no_yovf
  826. mov ebx,top_left_y
  827. no_yovf: mov (cpt[esi]).c_xcood,ax
  828. mov (cpt[esi]).c_ycood,bx
  829. mov al,1
  830. ret
  831. fn_pointer_text endp
  832. fn_look_at proc
  833. ; eax = text no
  834. ; ebx = colour
  835. ; ecx = y_coord
  836. push ecx
  837. mov ebp,1
  838. ; mov dl,bl
  839. mov dl,248
  840. clear ecx
  841. mov ebx,240
  842. call low_text_manager
  843. mov (cpt[esi]).c_xcood,168
  844. pop eax
  845. mov (cpt[esi]).c_ycood,ax
  846. push esi
  847. ;mov eax,[cursor_id]
  848. ;call fn_kill_id
  849. ;call run_get_off ;clear anything else
  850. call re_create
  851. call sprite_engine
  852. call flip
  853. call fn_no_human
  854. call lock_mouse
  855. clear eax ;reset relative timer
  856. call wait_relative
  857. call wait_mouse_not_pressed
  858. ifdef with_replay
  859. call check_replay_skip
  860. jc skip_wait
  861. endif
  862. ;mov eax,[dt_letters] ;keep up for minimum time based on length
  863. ;imul eax,3
  864. mov eax,40
  865. call wait_relative
  866. skip_wait: call unlock_mouse
  867. call fn_add_human
  868. pop esi
  869. mov (cpt[esi]).c_status,0
  870. mov al,1
  871. ret
  872. fn_look_at endp
  873. fn_print_credit proc
  874. ; eax = text no
  875. ; ebx = colour
  876. ; ecx = y_coord
  877. push ecx
  878. mov ebp,1
  879. ; mov dl,bl
  880. mov dl,248
  881. clear ecx
  882. mov ebx,240
  883. call low_text_manager
  884. mov [result],ebx
  885. mov (cpt[esi]).c_xcood,168
  886. pop eax
  887. mov (cpt[esi]).c_ycood,ax
  888. mov al,1
  889. ret
  890. fn_print_credit endp
  891. change_text_sprite_colour proc
  892. ; Change colour of text sprite at esi to colour bl
  893. ; mov bl,bpt[offset dt_col_table+ebx] ;convert colour
  894. movzx ecx,(s ptr[esi]).s_sp_size ;do whole sprite
  895. add esi,SIZE s ;and point to pixel data
  896. high_loop: cmp bpt[esi],241 ;don't change 1 or 0 (or 2 or 3 or 4 or 5 or 6 or 7 or 8 or
  897. jc no_change
  898. mov [esi],bl
  899. no_change: inc esi
  900. loop high_loop
  901. ret
  902. change_text_sprite_colour endp
  903. fn_text_module proc
  904. ; eax = id of text info
  905. ; ebx = text no
  906. push eax
  907. push ebx
  908. mov eax,1
  909. call fn_set_font
  910. pop ebx
  911. pop eax
  912. fetch_compact
  913. mov eax,ebx ;message no
  914. mov dx,[esi] ;pen
  915. mov dx,209
  916. movzx ebx,wpt 2[esi] ;width
  917. movzx ecx,wpt 4[esi] ;logic
  918. push esi
  919. clear ebp ;no centre
  920. call low_text_manager
  921. mov [result],ebx ;text id
  922. pop edi
  923. mov ax,6[edi]
  924. mov (cpt[esi]).c_xcood,ax
  925. mov eax,8[edi]
  926. mov (cpt[esi]).c_ycood,ax
  927. clear eax
  928. call fn_set_font
  929. mov al,1
  930. ret
  931. fn_text_module endp
  932. fn_linc_text_module proc
  933. ; eax = text number
  934. ; ebx = text no
  935. ; ecx = button action no , -1 for none. On 0 or -1 clear button action nos
  936. ; push ecx
  937. push ebx
  938. push eax
  939. ; Put button no in
  940. push eax
  941. btr ecx,15
  942. jnc no_clr
  943. push ecx
  944. mov edi,offset linc_digit_0
  945. clear eax
  946. mov ecx,10
  947. rep stosd
  948. pop ecx
  949. no_clr: cmp cx,10
  950. jnc no_but
  951. mov [offset linc_digit_0 + ecx*4],ebx
  952. no_but: pop eax
  953. mov eax,ebx ;message no
  954. mov dx,215 ;213 ;242 ;pen
  955. mov ebx,220 ;width
  956. clear ecx
  957. clear ebp ;no centre
  958. call low_text_manager
  959. pop eax
  960. ; if eax < 20 then eax = line number (text items)
  961. ; if eax > 20 then eax = x coordinate (numbers)
  962. ; if eax = 20 then something has gone wrong
  963. cmp eax,20
  964. jnc numbers
  965. mov (cpt[esi]).c_xcood,152
  966. imul eax,13
  967. add eax,170
  968. mov (cpt[esi]).c_ycood,ax
  969. jmp letters
  970. numbers: mov (cpt[esi]).c_xcood,ax
  971. mov (cpt[esi]).c_ycood,214
  972. letters: pop eax
  973. mov (cpt[esi]).c_get_to_flag,ax
  974. mov al,1
  975. ret
  976. fn_linc_text_module endp
  977. ifdef mem_check
  978. free_text_items proc
  979. mov ecx,8
  980. mov esi,offset item_list+first_text_sec*4
  981. ft_loop: lodsd
  982. push esi
  983. push ecx
  984. jife eax,no_free
  985. call my_free
  986. no_free: pop ecx
  987. pop esi
  988. loop ft_loop
  989. mov ecx,10
  990. mov esi,offset item_list+first_text_buffer*4
  991. ft_loop2: lodsd
  992. push esi
  993. push ecx
  994. jife eax,no_free2
  995. call my_free
  996. no_free2: pop ecx
  997. pop esi
  998. loop ft_loop2
  999. ret
  1000. free_text_items endp
  1001. endif
  1002. end32code
  1003. end
  1004.