fix off by .5 errors in ogl_upixelc and ogl_ulinec (d1x r1.29)
[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  * $Source: /cvs/cvsroot/d2x/arch/dos/mono.c,v $
15  * $Revision: 1.1.1.1 $
16  * $Author: bradleyb $
17  * $Date: 2001-01-19 03:30:15 $
18  *
19  * Library functions for printing to mono card.
20  *
21  * $Log: not supported by cvs2svn $
22  * Revision 1.1.1.1  1999/06/14 21:58:35  donut
23  * Import of d1x 1.37 source.
24  *
25  * Revision 1.12  1995/02/23  11:59:57  john
26  * Made the windows smaller so they don't overwrite the debug file menus.
27  * 
28  * Revision 1.11  1994/11/27  23:07:50  matt
29  * Made changes needed to be able to compile out monochrome debugging code
30  * 
31  * Revision 1.10  1994/10/26  22:23:43  john
32  * Limited windows to 2.  Took away saving what was under
33  * a window.
34  * 
35  * Revision 1.9  1994/07/14  23:25:44  matt
36  * Allow window 0 to be opened; don't allow mono to be initialized twice
37  * 
38  * Revision 1.8  1994/03/09  10:45:38  john
39  * Sped up scroll.
40  * 
41  * Revision 1.7  1994/01/26  08:56:55  mike
42  * Comment out int3 in mputc.
43  * 
44  * Revision 1.6  1994/01/12  15:56:34  john
45  * made backspace do an int3 during mono stuff.
46  * .,
47  * 
48  * Revision 1.5  1993/12/07  12:33:23  john
49  * *** empty log message ***
50  * 
51  * Revision 1.4  1993/10/15  10:10:25  john
52  * *** empty log message ***
53  * 
54  * Revision 1.3  1993/09/14  20:55:13  matt
55  * Made minit() and mopen() check for presence of mono card in machine.
56  * 
57  * Revision 1.2  1993/07/22  13:10:21  john
58  * *** empty log message ***
59  * 
60  * Revision 1.1  1993/07/10  13:10:38  matt
61  * Initial revision
62  *
63  *
64  */
65
66 #ifdef RCS
67 static char rcsid[] = "$Id: mono.c,v 1.1.1.1 2001-01-19 03:30:15 bradleyb Exp $";
68 #endif
69
70 // Library functions for printing to mono card.
71
72 #include <stdio.h>
73 #include <stdlib.h>
74 #include <stdarg.h>
75 #include <string.h>
76 #include <dos.h>
77 #include <conio.h>
78
79 #include "key.h"
80
81 //#define MONO_IS_STDERR
82 #ifndef __GNUC__
83 void mono_int_3();
84 #pragma aux mono_int_3 = "int 3";
85 #else
86 static inline void mono_int_3() { asm("int $3"); }
87 #endif
88 void msetcursor(short row, short col);
89
90 #define MAX_NUM_WINDOWS 2
91
92 struct mono_element {
93         unsigned char character;
94         unsigned char attribute;
95 };
96
97 typedef struct  {
98         short   first_row;
99         short   height;
100         short   first_col;
101         short   width;
102         short   cursor_row;
103         short   cursor_col;
104         short   open;
105         struct  mono_element save_buf[25][80];
106         struct  mono_element text[25][80];
107 } WINDOW;
108
109
110 void scroll( short n );
111 void drawbox( short n );
112
113 #define ROW             Window[n].first_row
114 #define HEIGHT          Window[n].height
115 #define COL             Window[n].first_col
116 #define WIDTH           Window[n].width
117 #define CROW            Window[n].cursor_row
118 #define CCOL            Window[n].cursor_col
119 #define OPEN            Window[n].open
120 #define CHAR(r,c)       (*monoscreen)[ROW+(r)][COL+(c)].character
121 #define ATTR(r,c)       (*monoscreen)[ROW+(r)][COL+(c)].attribute
122 #define XCHAR(r,c)      Window[n].text[ROW+(r)][COL+(c)].character
123 #define XATTR(r,c)      Window[n].text[ROW+(r)][COL+(c)].attribute
124
125 static WINDOW Window[MAX_NUM_WINDOWS];
126
127 struct mono_element (*monoscreen)[25][80];
128
129 void mputc( short n, char c )
130 {
131         if (!OPEN) return;
132
133 //      if (keyd_pressed[KEY_BACKSP]) 
134 //              mono_int_3();
135
136         switch (c)
137         {
138         case 8:
139                 if (CCOL > 0) CCOL--;
140                 break;
141         case 9:
142                 CHAR( CROW, CCOL ) = ' ';
143                 ATTR( CROW, CCOL ) = XATTR( CROW, CCOL );
144                 XCHAR( CROW, CCOL ) = ' ';
145                 CCOL++;
146                 while (CCOL % 4) {
147                         CHAR( CROW, CCOL ) = ' ';
148                         ATTR( CROW, CCOL ) = XATTR( CROW, CCOL );
149                         XCHAR( CROW, CCOL ) = ' ';
150                         CCOL++;
151                 }
152                 break;
153         case 10:
154         case 13:
155                 CCOL = 0;
156                 CROW++;
157                 break;
158         default:
159                 CHAR( CROW, CCOL ) = c;
160                 ATTR( CROW, CCOL ) = XATTR( CROW, CCOL );
161                 XCHAR( CROW, CCOL ) = c;
162                 CCOL++;
163         }
164
165         if ( CCOL >= WIDTH )    {
166                 CCOL = 0;
167                 CROW++;
168         }
169         if ( CROW >= HEIGHT )   {
170                 CROW--;
171                 scroll(n);
172         }
173
174         msetcursor( ROW+CROW, COL+CCOL );
175
176 }
177
178 void mputc_at( short n, short row, short col, char c )
179 {
180         CROW = row;
181         CCOL = col;
182
183         if (!OPEN) return;
184
185         mputc( n, c );
186
187 }
188
189 #ifdef __WATCOMC__
190 void copy_row(int nwords,short *src, short *dest1, short *dest2 );
191 #pragma aux copy_row parm [ecx] [esi] [ebx] [edx] modify exact [eax ebx ecx edx esi] = \
192 "                               shr             ecx, 1"                         \
193 "                               jnc             even_num"                       \
194 "                               mov             ax, [esi]"                      \
195 "                               add             esi, 2"                         \
196 "                               mov             [ebx], ax"                      \
197 "                               add             ebx, 2"                         \
198 "                               mov             [edx], ax"                      \
199 "                               add             edx, 2"                         \
200 "even_num:      cmp             ecx, 0"                         \
201 "                               je                      done"                                   \
202 "rowloop:       mov             eax, [esi]"                     \
203 "                               add             esi, 4"                         \
204 "                               mov             [edx], eax"                     \
205 "                               add             edx, 4"                         \
206 "                               mov             [ebx], eax"                     \
207 "                               add             ebx, 4"                         \
208 "                               loop            rowloop"                                \
209 "done:  "
210 #else
211 void copy_row(int nwords,short *src, short *dest1, short *dest2 ) {
212         while (nwords--)
213                 *(dest1++) = *(dest2++) = *(src++);
214 }
215 #endif
216
217 void scroll( short n )
218 {
219         register int row, col;
220
221         if (!OPEN) return;
222
223         col = 0;
224         for ( row = 0; row < (HEIGHT-1); row++ )
225                 copy_row( WIDTH, (short *)&XCHAR(row+1,col), (short *)&CHAR(row,col), (short *)&XCHAR(row,col) );
226
227 //              for ( col = 0; col < WIDTH; col++ )
228 //              {
229 //                      CHAR( row, col ) = XCHAR( row+1, col );
230 //                      ATTR( row, col ) = XATTR( row+1, col );
231 //                      XCHAR( row, col ) = XCHAR( row+1, col );
232 //                      XATTR( row, col ) = XATTR( row+1, col );
233 //              }
234
235         for ( col = 0; col < WIDTH; col++ )
236         {
237                 CHAR( HEIGHT-1, col ) = ' ';
238                 ATTR( HEIGHT-1, col ) = XATTR( HEIGHT-1, col );
239                 XCHAR( HEIGHT-1, col ) = ' ';
240         }
241
242 }
243
244 void msetcursor(short row, short col)
245 {
246         int pos = row*80+col;
247
248         outp( 0x3b4, 15 );
249         outp( 0x3b5, pos & 0xFF );
250         outp( 0x3b4, 14 );
251         outp( 0x3b5, (pos >> 8) & 0xff );
252 }
253
254 static char temp_m_buffer[1000];
255 void _mprintf( short n, char * format, ... )
256 {
257 #ifdef MONO_IS_STDERR
258         va_list args;
259         va_start(args, format );
260         vfprintf(stderr, format, args);
261 #else
262         char *ptr=temp_m_buffer;
263         va_list args;
264
265         if (!OPEN) return;
266
267         va_start(args, format );
268         vsprintf(temp_m_buffer,format,args);
269         while( *ptr )
270                 mputc( n, *ptr++ );
271 #endif
272 }
273
274 void _mprintf_at( short n, short row, short col, char * format, ... )
275 {
276         int r,c;
277         char buffer[1000], *ptr=buffer;
278         va_list args;
279
280         if (!OPEN) return;
281
282         r = CROW; c = CCOL;
283
284         CROW = row;
285         CCOL = col;
286
287         va_start(args, format );
288         vsprintf(buffer,format,args);
289         while( *ptr )
290                 mputc( n, *ptr++ );
291
292
293         CROW = r; CCOL = c;
294
295         msetcursor( ROW+CROW, COL+CCOL );
296
297 }
298
299
300 void drawbox(short n)
301 {
302         short row, col;
303
304         if (!OPEN) return;
305
306         for (row=0; row <HEIGHT; row++ )    {
307                 CHAR( row, -1 ) = 179;
308                 CHAR( row, WIDTH ) = 179;
309                 XCHAR( row, -1 ) = 179;
310                 XCHAR( row, WIDTH ) = 179;
311         }
312
313         for (col=0; col < WIDTH; col++ )  {
314                 CHAR( -1, col ) = 196;
315                 CHAR( HEIGHT, col ) = 196;
316                 XCHAR( -1, col ) = 196;
317                 XCHAR( HEIGHT, col ) = 196;
318         }
319
320         CHAR( -1,-1 ) = 218;
321         CHAR( -1, WIDTH ) = 191;
322         CHAR( HEIGHT, -1 ) = 192;
323         CHAR( HEIGHT, WIDTH ) = 217;
324         XCHAR( -1,-1 ) = 218;
325         XCHAR( -1, WIDTH ) = 191;
326         XCHAR( HEIGHT, -1 ) = 192;
327         XCHAR( HEIGHT, WIDTH ) = 217;
328
329 }
330
331 void mclear( short n )
332 {
333         short row, col;
334
335         if (!OPEN) return;
336
337         for (row=0; row<HEIGHT; row++ )
338                 for (col=0; col<WIDTH; col++ )  {
339                         CHAR(row,col) = 32;
340                         ATTR(row,col) = 7;
341                         XCHAR(row,col) = 32;
342                         XATTR(row,col) = 7;
343                 }
344         CCOL = 0;
345         CROW = 0;
346 }
347
348 void mclose(short n)
349 {
350         short row, col;
351
352         if (!OPEN) return;
353
354         for (row=-1; row<HEIGHT+1; row++ )
355                 for (col=-1; col<WIDTH+1; col++ )  {
356                         CHAR(row,col) = 32;
357                         ATTR(row,col) = 7;
358                 }
359         OPEN = 0;
360         CCOL = 0;
361         CROW = 0;
362
363         msetcursor(0,0);
364
365 }
366
367 void mrefresh(short n)
368 {
369         short row, col;
370
371         if (!OPEN) return;
372
373         for (row=-1; row<HEIGHT+1; row++ )
374                 for (col=-1; col<WIDTH+1; col++ )  {
375                         CHAR(row,col) = XCHAR(row,col);
376                         ATTR(row,col) = XATTR(row,col);
377                 }
378
379         msetcursor( ROW+CROW, COL+CCOL );
380
381 }
382
383
384 int mono_present();             //return true if mono monitor in system
385
386
387 void mopen( short n, short row, short col, short width, short height, char * title )
388 {
389 //      if (n==0) return;
390
391         if (! mono_present()) return;   //error! no mono card
392
393         if (OPEN) mclose(n);
394
395         OPEN = 1;
396         ROW = row;
397         COL = col;
398         WIDTH = width;
399         HEIGHT = height;
400
401         for (row=-1; row<HEIGHT+1; row++ )
402                 for (col=-1; col<WIDTH+1; col++ )  {
403                         CHAR(row,col) = 32;
404                         ATTR(row,col) = 7;
405                         XCHAR(row,col) = 32;
406                         XATTR(row,col) = 7;
407                 }
408
409         drawbox(n);
410         CROW=-1; CCOL=0;
411         _mprintf( n, title );
412         CROW=0; CCOL=0;
413         msetcursor( ROW+CROW, COL+CCOL );
414
415 }
416
417 #ifndef __GNUC__
418 #pragma aux mono_present value [eax] modify [bx] = \
419         "mov    ax,1a00h"       \
420         "int    10h"                    \       
421         "mov    eax,-1"         \       
422         "cmp    bl,1"                   \
423         "je     got_it"         \
424         "cmp    bh,1"                   \
425         "je     got_it"         \
426         "xor    eax,eax"                \       
427 "got_it:";
428 #else
429 int mono_present() { return 0; }
430 #endif
431
432 int minit()
433 {
434         short n;
435         static int initialized=0;
436         //short col, row;
437
438         if (! mono_present()) return 0; //error! no mono card
439
440         if (initialized)
441                 return 1;
442
443         initialized=1;
444
445         monoscreen = (struct mono_element (*)[25][80])0xB0000;
446
447         n=0;
448         OPEN=1;
449         ROW=2;
450         COL=0;
451         WIDTH=80;
452         HEIGHT=24;
453         CCOL=0;
454         CROW=0;
455
456         mclear(0);
457
458         for (n=1; n<MAX_NUM_WINDOWS; n++ )  {
459                 OPEN = 0;
460                 ROW = 2;
461                 COL = 1;
462                 WIDTH=78;
463                 HEIGHT=23;
464                 CROW=0;
465                 CCOL=0;
466         }
467
468         return -1;      //everything ok
469 }
470