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