]> 4ch.mooo.com Git - 16.git/blob - 16/xw/mxot.asm
more
[16.git] / 16 / xw / mxot.asm
1 ;-----------------------------------------------------------\r
2 ;\r
3 ; MXOT.ASM - Text functions\r
4 ; Copyright (c) 1994 by Alessandro Scotti\r
5 ;\r
6 ;-----------------------------------------------------------\r
7 WARN    PRO\r
8 NOWARN  RES                             ; We use the reserved name 'WIDTH'\r
9 INCLUDE MODEX.DEF\r
10 \r
11 PUBLIC  mxOutChar\r
12 PUBLIC  mxOutText\r
13 PUBLIC  mxSetFont\r
14 PUBLIC  mxSetTextColor\r
15 PUBLIC  mxGetTextStep\r
16 PUBLIC  mxSetTextStep\r
17 \r
18 MAX_WIDTH       EQU     16              ; Must be <= 16\r
19 MAX_HEIGHT      EQU     32\r
20 \r
21 MX_TEXT         SEGMENT USE16 PARA PUBLIC 'CODE'\r
22                 ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
23 \r
24 EXTRN   mx_CodeSegment  : WORD\r
25 EXTRN   mxPutImage      : FAR\r
26 \r
27 ; Default 8x8 font\r
28 fnt_Default     LABEL\r
29         INCLUDE DEFAULT.FNT\r
30 \r
31 ; Table of system fonts\r
32 tbl_SystemFont   LABEL   WORD\r
33         DW      fnt_Default, 8, 8\r
34 \r
35 MX_MAXSYSFONT   EQU     ($-OFFSET tbl_SystemFont) SHR 2\r
36 \r
37 mx_FontPtr      DW      OFFSET fnt_Default, SEG MX_TEXT\r
38 mx_FontWidth    DW      8               ; Font width in pixels\r
39 mx_FontHeight   DW      8               ; Font height in pixels\r
40 mx_FontCharSize DW      8               ; Size in bytes of a font character\r
41 mx_FontColor    DW      00FFh           ; Color: foreground + background*256\r
42 mx_FontOp       DW      OP_MOVE         ; Raster op\r
43 mx_DeltaX       DW      8               ; Horizontal step\r
44 mx_DeltaY       DW      0               ; Vertical step\r
45 \r
46 ;-----------------------------------------------------------\r
47 ;\r
48 ; Sets the current font.\r
49 ;\r
50 ; Input:\r
51 ;       Font    = pointer to font data\r
52 ;       Width   = width of font character in pixels\r
53 ;       Height  = height of font character in pixels\r
54 ; Output:\r
55 ;       AX = 0 on success, else invalid parameters\r
56 ;\r
57 ; Note: when the high word of Font (i.e. the segment) is zero, the low\r
58 ;       word is used to select one of the system fonts.\r
59 ;\r
60 mxSetFont       PROC FAR\r
61         ARG     Height:WORD,    \\r
62                 Width:WORD,     \\r
63                 Font:DWORD      = ARG_SIZE\r
64         .enter  0\r
65         .push   ds\r
66 \r
67         mov     ds, [mx_CodeSegment]\r
68         ASSUME  ds:MX_TEXT\r
69 \r
70         mov     ax, WORD PTR Font[2]    ; Get font segment\r
71         test    ax, ax                  ; Null segment?\r
72         jnz     @@UserFont              ; No, install user font\r
73 \r
74 ; Install system font\r
75         mov     ax, WORD PTR Font[0]    ; Get font number\r
76         cmp     ax, MX_MAXSYSFONT       ; Check range\r
77         jb      @@SystemFont\r
78         xor     ax, ax                  ; Out of range, use default font\r
79 @@SystemFont:\r
80         shl     ax, 1\r
81         shl     ax, 1\r
82         mov     bx, ax\r
83         mov     ax, tbl_SystemFont[bx]  ; Get font offset\r
84         mov     WORD PTR mx_FontPtr[0], ax\r
85         mov     WORD PTR mx_FontPtr[2], cs\r
86         mov     al, BYTE PTR tbl_SystemFont[bx+2]\r
87         xor     ah, ah\r
88         mov     [mx_FontWidth], ax\r
89         mov     [mx_DeltaX], ax\r
90         mov     dl, BYTE PTR tbl_SystemFont[bx+3]\r
91         xor     dh, dh\r
92         mov     [mx_FontHeight], dx\r
93         mul     dx\r
94         mov     [mx_FontCharSize], ax\r
95         mov     [mx_DeltaX], ax\r
96         xor     ax, ax\r
97         mov     [mx_DeltaY], ax\r
98         jmp     @@Exit\r
99 \r
100 ; Install user font\r
101 @@UserFont:\r
102         mov     ax, -1                  ; Assume an error\r
103         mov     bx, [Width]\r
104         cmp     bx, MAX_WIDTH\r
105         ja      @@Exit                  ; Invalid character width\r
106         mov     dx, [Height]\r
107         cmp     dx, MAX_HEIGHT\r
108         ja      @@Exit                  ; Invalid character height\r
109         mov     [mx_FontWidth], bx\r
110         mov     [mx_FontHeight], dx\r
111         mov     ax, bx\r
112         add     ax, 7\r
113         .shr    ax, 3\r
114         mul     dx\r
115         mov     [mx_FontCharSize], ax\r
116         mov     ax, WORD PTR Font[0]\r
117         mov     WORD PTR mx_FontPtr[0], ax\r
118         mov     ax, WORD PTR Font[2]\r
119         mov     WORD PTR mx_FontPtr[2], ax\r
120         xor     ax, ax\r
121 \r
122 @@Exit:\r
123         .pop    ds\r
124         ASSUME  ds:NOTHING\r
125         .leave  ARG_SIZE\r
126 mxSetFont       ENDP\r
127 \r
128 ;-----------------------------------------------------------\r
129 ;\r
130 ; Sets the text color and raster op.\r
131 ;\r
132 ; Input:\r
133 ;       Color   = text color (foreground + background*256)\r
134 ;       Op      = raster op\r
135 ; Output:\r
136 ;       none\r
137 ;\r
138 mxSetTextColor  PROC FAR\r
139         ARG     Op:WORD,        \\r
140                 Color:WORD      = ARG_SIZE\r
141         .enter  0\r
142         .push   ds\r
143 \r
144         mov     ds, [mx_CodeSegment]\r
145         ASSUME  ds:MX_TEXT\r
146 \r
147         mov     ax, [Color]\r
148         mov     [mx_FontColor], ax\r
149         mov     ax, [Op]\r
150         mov     [mx_FontOp], ax\r
151 \r
152         xor     ax, ax\r
153         .pop    ds\r
154         ASSUME  ds:NOTHING\r
155         .leave  ARG_SIZE\r
156 mxSetTextColor  ENDP\r
157 \r
158 ;-----------------------------------------------------------\r
159 ;\r
160 ; Writes a character using the current font and attributes.\r
161 ;\r
162 ; Input:\r
163 ;       X, Y    = video coordinates\r
164 ;       C       = character to print\r
165 ; Output:\r
166 ;       none\r
167 ;\r
168 mxOutChar       PROC FAR\r
169         ARG     C:BYTE:2,       \\r
170                 Y:WORD,         \\r
171                 X:WORD          = ARG_SIZE\r
172         LOCAL   Image:BYTE:MAX_WIDTH*MAX_HEIGHT,        \\r
173                 Count:WORD                              = AUTO_SIZE\r
174         .enter  AUTO_SIZE\r
175         .push   ds, si, es, di\r
176         ASSUME  ds:NOTHING\r
177 \r
178 ; Gets the pointer to font data for the selected character\r
179         lds     si, DWORD PTR [mx_FontPtr]\r
180         mov     al, [C]\r
181         xor     ah, ah\r
182         mul     [mx_FontCharSize]       ; Offset into font\r
183         add     si, ax                  ; DS:SI -> font data for character\r
184 \r
185 ; Converts font data into a 256-color linear image\r
186         mov     ax, ss\r
187         mov     es, ax\r
188         lea     di, [Image]\r
189         mov     dx, [mx_FontColor]\r
190         mov     ax, [mx_FontHeight]\r
191         mov     [Count], ax\r
192 @@HeightLoop:\r
193         mov     cx, [mx_FontWidth]\r
194         mov     bh, ds:[si]\r
195         inc     si                      ; Get a byte from font data\r
196         cmp     cx, 8\r
197         jbe     @@WidthLoop             ; Ok for width <= 8\r
198         mov     bl, ds:[si]             ; Get another byte\r
199         inc     si\r
200 @@WidthLoop:\r
201         mov     al, dl                  ; Assume foreground color\r
202         shl     bx, 1                   ; Is font bit set?\r
203         jc      @@1                     ; Yes, foreground is just great\r
204         mov     al, dh                  ; Get background color\r
205 @@1:\r
206         mov     es:[di], al             ; Put pixel into image\r
207         inc     di\r
208         dec     cx\r
209         jnz     @@WidthLoop\r
210         dec     [Count]\r
211         jnz     @@HeightLoop\r
212 \r
213 ; Now pass image to mx_PutImage\r
214         lea     ax, [Image]\r
215         push    es\r
216         push    ax                      ; Pointer to image\r
217         push    [X]\r
218         push    [Y]                     ; Image coordinates\r
219         push    [mx_FontWidth]\r
220         push    [mx_FontHeight]         ; Image size\r
221         push    [mx_FontOp]             ; Raster op\r
222         call    mxPutImage              ; Write character\r
223 \r
224         xor     ax, ax\r
225         .pop    ds, si, es, di\r
226         .leave  ARG_SIZE\r
227 mxOutChar       ENDP\r
228 \r
229 ;-----------------------------------------------------------\r
230 ;\r
231 ; Writes a string at the coordinates specified.\r
232 ;\r
233 ; Input:\r
234 ;       X, Y    = text coordinates\r
235 ;       S       = pointer to ASCIIZ string\r
236 ; Output:\r
237 ;       none\r
238 ;\r
239 mxOutText       PROC FAR\r
240         ARG     S:DWORD,        \\r
241                 Y:WORD,         \\r
242                 X:WORD          = ARG_SIZE\r
243         .enter  0\r
244         .push   ds, si\r
245         ASSUME  ds:NOTHING\r
246 \r
247         lds     si, [S]\r
248 @@Loop:\r
249         mov     al, ds:[si]\r
250         test    al, al                  ; End of string?\r
251         jz      @@Exit                  ; Yes, exit\r
252         inc     si\r
253         push    [X]                     ; Display character\r
254         push    [Y]\r
255         push    ax\r
256         call    mxOutChar\r
257         mov     ax, [mx_DeltaX]\r
258         add     [X], ax                 ; Bump X coordinate\r
259         mov     ax, [mx_DeltaY]\r
260         add     [Y], ax                 ; Bump Y coordinate\r
261         dec     [Count]\r
262         jnz     @@Loop\r
263 \r
264 @@Exit:\r
265         xor     ax, ax\r
266         .pop    ds, si\r
267         .leave  ARG_SIZE\r
268         ret\r
269 mxOutText       ENDP\r
270 \r
271 ;-----------------------------------------------------------\r
272 ;\r
273 ; Sets the distance between characters.\r
274 ;\r
275 ; Input:\r
276 ;       DeltaX  = horizontal distance in pixels\r
277 ;       DeltaY  = vertical distance in pixels\r
278 ; Output:\r
279 ;       none\r
280 ;\r
281 ; Note: this function may be used to set the text direction.\r
282 ;\r
283 mxSetTextStep   PROC FAR\r
284         ARG     DeltaY:WORD,    \\r
285                 DeltaX:WORD     = ARG_SIZE\r
286         .enter  0\r
287         .push   ds\r
288 \r
289         mov     ds, [mx_CodeSegment]\r
290         ASSUME  ds:MX_TEXT\r
291 \r
292         mov     ax, [DeltaX]\r
293         mov     [mx_DeltaX], ax\r
294         mov     ax, [DeltaY]\r
295         mov     [mx_DeltaY], ax\r
296 \r
297         .pop    ds\r
298         .leave  ARG_SIZE\r
299 mxSetTextStep   ENDP\r
300 \r
301 ;-----------------------------------------------------------\r
302 ;\r
303 ; Gets the current distance between characters.\r
304 ;\r
305 ; Input:\r
306 ;       DeltaX  = pointer to horizontal distance in pixels (integer)\r
307 ;       DeltaY  = pointer to vertical distance in pixels (integer)\r
308 ; Output:\r
309 ;       none\r
310 ;\r
311 mxGetTextStep   PROC FAR\r
312         ARG     DeltaY:DWORD,   \\r
313                 DeltaX:DWORD    = ARG_SIZE\r
314         .enter  0\r
315         .push   ds, si\r
316         ASSUME  ds:NOTHING\r
317 \r
318         mov     ax, [mx_DeltaX]\r
319         lds     si, [DeltaX]\r
320         mov     ds:[si], ax\r
321         mov     ax, [mx_DeltaY]\r
322         lds     si, [DeltaY]\r
323         mov     ds:[si], ax\r
324 \r
325         .pop    ds, si\r
326         .leave  ARG_SIZE\r
327 mxGetTextStep   ENDP\r
328 \r
329 MX_TEXT         ENDS\r
330 END\r