]> icculus.org git repositories - btb/d2x.git/blob - arch/dos/mono.c
remove rcs tags
[btb/d2x.git] / arch / dos / mono.c
1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
11 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13 /*
14  *
15  * Library functions for printing to mono card.
16  *
17  */
18
19 // Library functions for printing to mono card.
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24 #include <string.h>
25 #include <dos.h>
26 #include <conio.h>
27
28 #include "key.h"
29
30 //#define MONO_IS_STDERR
31 #ifndef __GNUC__
32 void mono_int_3();
33 #pragma aux mono_int_3 = "int 3";
34 #else
35 static inline void mono_int_3() { asm("int $3"); }
36 #endif
37 void msetcursor(short row, short col);
38
39 #define MAX_NUM_WINDOWS 2
40
41 struct mono_element {
42         unsigned char character;
43         unsigned char attribute;
44 };
45
46 typedef struct  {
47         short   first_row;
48         short   height;
49         short   first_col;
50         short   width;
51         short   cursor_row;
52         short   cursor_col;
53         short   open;
54         struct  mono_element save_buf[25][80];
55         struct  mono_element text[25][80];
56 } WINDOW;
57
58
59 void scroll( short n );
60 void drawbox( short n );
61
62 #define ROW             Window[n].first_row
63 #define HEIGHT          Window[n].height
64 #define COL             Window[n].first_col
65 #define WIDTH           Window[n].width
66 #define CROW            Window[n].cursor_row
67 #define CCOL            Window[n].cursor_col
68 #define OPEN            Window[n].open
69 #define CHAR(r,c)       (*monoscreen)[ROW+(r)][COL+(c)].character
70 #define ATTR(r,c)       (*monoscreen)[ROW+(r)][COL+(c)].attribute
71 #define XCHAR(r,c)      Window[n].text[ROW+(r)][COL+(c)].character
72 #define XATTR(r,c)      Window[n].text[ROW+(r)][COL+(c)].attribute
73
74 static WINDOW Window[MAX_NUM_WINDOWS];
75
76 struct mono_element (*monoscreen)[25][80];
77
78 void mputc( short n, char c )
79 {
80         if (!OPEN) return;
81
82 //      if (keyd_pressed[KEY_BACKSP]) 
83 //              mono_int_3();
84
85         switch (c)
86         {
87         case 8:
88                 if (CCOL > 0) CCOL--;
89                 break;
90         case 9:
91                 CHAR( CROW, CCOL ) = ' ';
92                 ATTR( CROW, CCOL ) = XATTR( CROW, CCOL );
93                 XCHAR( CROW, CCOL ) = ' ';
94                 CCOL++;
95                 while (CCOL % 4) {
96                         CHAR( CROW, CCOL ) = ' ';
97                         ATTR( CROW, CCOL ) = XATTR( CROW, CCOL );
98                         XCHAR( CROW, CCOL ) = ' ';
99                         CCOL++;
100                 }
101                 break;
102         case 10:
103         case 13:
104                 CCOL = 0;
105                 CROW++;
106                 break;
107         default:
108                 CHAR( CROW, CCOL ) = c;
109                 ATTR( CROW, CCOL ) = XATTR( CROW, CCOL );
110                 XCHAR( CROW, CCOL ) = c;
111                 CCOL++;
112         }
113
114         if ( CCOL >= WIDTH )    {
115                 CCOL = 0;
116                 CROW++;
117         }
118         if ( CROW >= HEIGHT )   {
119                 CROW--;
120                 scroll(n);
121         }
122
123         msetcursor( ROW+CROW, COL+CCOL );
124
125 }
126
127 void mputc_at( short n, short row, short col, char c )
128 {
129         CROW = row;
130         CCOL = col;
131
132         if (!OPEN) return;
133
134         mputc( n, c );
135
136 }
137
138 #ifdef __WATCOMC__
139 void copy_row(int nwords,short *src, short *dest1, short *dest2 );
140 #pragma aux copy_row parm [ecx] [esi] [ebx] [edx] modify exact [eax ebx ecx edx esi] = \
141 "                               shr             ecx, 1"                         \
142 "                               jnc             even_num"                       \
143 "                               mov             ax, [esi]"                      \
144 "                               add             esi, 2"                         \
145 "                               mov             [ebx], ax"                      \
146 "                               add             ebx, 2"                         \
147 "                               mov             [edx], ax"                      \
148 "                               add             edx, 2"                         \
149 "even_num:      cmp             ecx, 0"                         \
150 "                               je                      done"                                   \
151 "rowloop:       mov             eax, [esi]"                     \
152 "                               add             esi, 4"                         \
153 "                               mov             [edx], eax"                     \
154 "                               add             edx, 4"                         \
155 "                               mov             [ebx], eax"                     \
156 "                               add             ebx, 4"                         \
157 "                               loop            rowloop"                                \
158 "done:  "
159 #else
160 void copy_row(int nwords,short *src, short *dest1, short *dest2 ) {
161         while (nwords--)
162                 *(dest1++) = *(dest2++) = *(src++);
163 }
164 #endif
165
166 void scroll( short n )
167 {
168         register int row, col;
169
170         if (!OPEN) return;
171
172         col = 0;
173         for ( row = 0; row < (HEIGHT-1); row++ )
174                 copy_row( WIDTH, (short *)&XCHAR(row+1,col), (short *)&CHAR(row,col), (short *)&XCHAR(row,col) );
175
176 //              for ( col = 0; col < WIDTH; col++ )
177 //              {
178 //                      CHAR( row, col ) = XCHAR( row+1, col );
179 //                      ATTR( row, col ) = XATTR( row+1, col );
180 //                      XCHAR( row, col ) = XCHAR( row+1, col );
181 //                      XATTR( row, col ) = XATTR( row+1, col );
182 //              }
183
184         for ( col = 0; col < WIDTH; col++ )
185         {
186                 CHAR( HEIGHT-1, col ) = ' ';
187                 ATTR( HEIGHT-1, col ) = XATTR( HEIGHT-1, col );
188                 XCHAR( HEIGHT-1, col ) = ' ';
189         }
190
191 }
192
193 void msetcursor(short row, short col)
194 {
195         int pos = row*80+col;
196
197         outp( 0x3b4, 15 );
198         outp( 0x3b5, pos & 0xFF );
199         outp( 0x3b4, 14 );
200         outp( 0x3b5, (pos >> 8) & 0xff );
201 }
202
203 static char temp_m_buffer[1000];
204 void _mprintf( short n, char * format, ... )
205 {
206 #ifdef MONO_IS_STDERR
207         va_list args;
208         va_start(args, format );
209         vfprintf(stderr, format, args);
210 #else
211         char *ptr=temp_m_buffer;
212         va_list args;
213
214         if (!OPEN) return;
215
216         va_start(args, format );
217         vsprintf(temp_m_buffer,format,args);
218         while( *ptr )
219                 mputc( n, *ptr++ );
220 #endif
221 }
222
223 void _mprintf_at( short n, short row, short col, char * format, ... )
224 {
225         int r,c;
226         char buffer[1000], *ptr=buffer;
227         va_list args;
228
229         if (!OPEN) return;
230
231         r = CROW; c = CCOL;
232
233         CROW = row;
234         CCOL = col;
235
236         va_start(args, format );
237         vsprintf(buffer,format,args);
238         while( *ptr )
239                 mputc( n, *ptr++ );
240
241
242         CROW = r; CCOL = c;
243
244         msetcursor( ROW+CROW, COL+CCOL );
245
246 }
247
248
249 void drawbox(short n)
250 {
251         short row, col;
252
253         if (!OPEN) return;
254
255         for (row=0; row <HEIGHT; row++ )    {
256                 CHAR( row, -1 ) = 179;
257                 CHAR( row, WIDTH ) = 179;
258                 XCHAR( row, -1 ) = 179;
259                 XCHAR( row, WIDTH ) = 179;
260         }
261
262         for (col=0; col < WIDTH; col++ )  {
263                 CHAR( -1, col ) = 196;
264                 CHAR( HEIGHT, col ) = 196;
265                 XCHAR( -1, col ) = 196;
266                 XCHAR( HEIGHT, col ) = 196;
267         }
268
269         CHAR( -1,-1 ) = 218;
270         CHAR( -1, WIDTH ) = 191;
271         CHAR( HEIGHT, -1 ) = 192;
272         CHAR( HEIGHT, WIDTH ) = 217;
273         XCHAR( -1,-1 ) = 218;
274         XCHAR( -1, WIDTH ) = 191;
275         XCHAR( HEIGHT, -1 ) = 192;
276         XCHAR( HEIGHT, WIDTH ) = 217;
277
278 }
279
280 void mclear( short n )
281 {
282         short row, col;
283
284         if (!OPEN) return;
285
286         for (row=0; row<HEIGHT; row++ )
287                 for (col=0; col<WIDTH; col++ )  {
288                         CHAR(row,col) = 32;
289                         ATTR(row,col) = 7;
290                         XCHAR(row,col) = 32;
291                         XATTR(row,col) = 7;
292                 }
293         CCOL = 0;
294         CROW = 0;
295 }
296
297 void mclose(short n)
298 {
299         short row, col;
300
301         if (!OPEN) return;
302
303         for (row=-1; row<HEIGHT+1; row++ )
304                 for (col=-1; col<WIDTH+1; col++ )  {
305                         CHAR(row,col) = 32;
306                         ATTR(row,col) = 7;
307                 }
308         OPEN = 0;
309         CCOL = 0;
310         CROW = 0;
311
312         msetcursor(0,0);
313
314 }
315
316 void mrefresh(short n)
317 {
318         short row, col;
319
320         if (!OPEN) return;
321
322         for (row=-1; row<HEIGHT+1; row++ )
323                 for (col=-1; col<WIDTH+1; col++ )  {
324                         CHAR(row,col) = XCHAR(row,col);
325                         ATTR(row,col) = XATTR(row,col);
326                 }
327
328         msetcursor( ROW+CROW, COL+CCOL );
329
330 }
331
332
333 int mono_present();             //return true if mono monitor in system
334
335
336 void mopen( short n, short row, short col, short width, short height, char * title )
337 {
338 //      if (n==0) return;
339
340         if (! mono_present()) return;   //error! no mono card
341
342         if (OPEN) mclose(n);
343
344         OPEN = 1;
345         ROW = row;
346         COL = col;
347         WIDTH = width;
348         HEIGHT = height;
349
350         for (row=-1; row<HEIGHT+1; row++ )
351                 for (col=-1; col<WIDTH+1; col++ )  {
352                         CHAR(row,col) = 32;
353                         ATTR(row,col) = 7;
354                         XCHAR(row,col) = 32;
355                         XATTR(row,col) = 7;
356                 }
357
358         drawbox(n);
359         CROW=-1; CCOL=0;
360         _mprintf( n, title );
361         CROW=0; CCOL=0;
362         msetcursor( ROW+CROW, COL+CCOL );
363
364 }
365
366 #ifndef __GNUC__
367 #pragma aux mono_present value [eax] modify [bx] = \
368         "mov    ax,1a00h"       \
369         "int    10h"                    \       
370         "mov    eax,-1"         \       
371         "cmp    bl,1"                   \
372         "je     got_it"         \
373         "cmp    bh,1"                   \
374         "je     got_it"         \
375         "xor    eax,eax"                \       
376 "got_it:";
377 #else
378 int mono_present() { return 0; }
379 #endif
380
381 int minit()
382 {
383         short n;
384         static int initialized=0;
385         //short col, row;
386
387         if (! mono_present()) return 0; //error! no mono card
388
389         if (initialized)
390                 return 1;
391
392         initialized=1;
393
394         monoscreen = (struct mono_element (*)[25][80])0xB0000;
395
396         n=0;
397         OPEN=1;
398         ROW=2;
399         COL=0;
400         WIDTH=80;
401         HEIGHT=24;
402         CCOL=0;
403         CROW=0;
404
405         mclear(0);
406
407         for (n=1; n<MAX_NUM_WINDOWS; n++ )  {
408                 OPEN = 0;
409                 ROW = 2;
410                 COL = 1;
411                 WIDTH=78;
412                 HEIGHT=23;
413                 CROW=0;
414                 CCOL=0;
415         }
416
417         return -1;      //everything ok
418 }
419