Fix crash if Num_walls=0
[btb/d2x.git] / main / console.c
1 /* $Id: console.c,v 1.18 2003-11-26 12:39:00 btb Exp $ */
2 /*
3  *
4  * Code for controlling the console
5  *
6  *
7  */
8
9 #ifdef HAVE_CONFIG_H
10 #include <conf.h>
11 #endif
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <stdarg.h>
16 #include <string.h>
17 #ifndef _WIN32_WCE
18 #include <fcntl.h>
19 #endif
20 #include <ctype.h>
21
22 #include <SDL.h>
23 #ifdef CONSOLE
24 #include "CON_console.h"
25 #endif
26
27 #include "pstypes.h"
28 #include "u_mem.h"
29 #include "error.h"
30 #include "console.h"
31 #include "cmd.h"
32 #include "gr.h"
33 #include "gamefont.h"
34 #include "pcx.h"
35 #include "cfile.h"
36
37 #ifndef __MSDOS__
38 int text_console_enabled = 1;
39 #else
40 int isvga();
41 #define text_console_enabled (!isvga())
42 #endif
43
44 cvar_t *cvar_vars = NULL;
45
46 /* Console specific cvars */
47 /* How discriminating we are about which messages are displayed */
48 cvar_t con_threshold = {"con_threshold", "0",};
49
50 /* Private console stuff */
51 #define CON_NUM_LINES 40
52 #if 0
53 #define CON_LINE_LEN 40
54 static char con_display[40][40];
55 static int  con_line; /* Current display line */
56 #endif
57
58 #ifdef CONSOLE
59 static int con_initialized;
60
61 ConsoleInformation *Console;
62
63 void con_parse(ConsoleInformation *console, char *command);
64
65
66 /* ======
67  * con_free - Free the console.
68  * ======
69  */
70 void con_free(void)
71 {
72         if (con_initialized)
73                 CON_Free(Console);
74         con_initialized = 0;
75 }
76 #endif
77
78
79 /* ======
80  * con_init - Initialise the console.
81  * ======
82  */
83 int con_init(void)
84 {
85         /* Initialise the cvars */
86         cvar_registervariable (&con_threshold);
87         return 0;
88 }
89
90 #ifdef CONSOLE
91
92 #define CON_BG_HIRES (cfexist("scoresb.pcx")?"scoresb.pcx":"scores.pcx")
93 #define CON_BG_LORES (cfexist("scores.pcx")?"scores.pcx":"scoresb.pcx") // Mac datafiles only have scoresb.pcx
94 #define CON_BG ((SWIDTH>=640)?CON_BG_HIRES:CON_BG_LORES)
95
96 void con_background(char *filename)
97 {
98         int pcx_error;
99         grs_bitmap bmp;
100         ubyte pal[256*3];
101
102         gr_init_bitmap_data(&bmp);
103         pcx_error = pcx_read_bitmap(filename, &bmp, BM_LINEAR, pal);
104         Assert(pcx_error == PCX_ERROR_NONE);
105         gr_remap_bitmap_good(&bmp, pal, -1, -1);
106         CON_Background(Console, &bmp);
107         gr_free_bitmap_data(&bmp);
108 }
109
110
111 void con_init_real(void)
112 {
113         Console = CON_Init(SMALL_FONT, grd_curscreen, CON_NUM_LINES, 0, 0, SWIDTH, SHEIGHT / 2);
114
115         Assert(Console);
116
117         CON_SetExecuteFunction(Console, con_parse);
118
119         con_background(CON_BG);
120
121         con_initialized = 1;
122
123         atexit(con_free);
124 }
125 #endif
126
127
128 void con_resize(void)
129 {
130 #ifdef CONSOLE
131         if (!con_initialized)
132                 con_init_real();
133
134         CON_Font(Console, SMALL_FONT, gr_getcolor(63, 63, 63), -1);
135         CON_Resize(Console, 0, 0, SWIDTH, SHEIGHT / 2);
136         con_background(CON_BG);
137 #endif
138 }
139
140 /* ======
141  * con_printf - Print a message to the console.
142  * ======
143  */
144 void con_printf(int priority, char *fmt, ...)
145 {
146         va_list arglist;
147         char buffer[2048];
148
149         if (priority <= ((int)con_threshold.value))
150         {
151                 va_start (arglist, fmt);
152                 vsprintf (buffer,  fmt, arglist);
153                 va_end (arglist);
154
155 #ifdef CONSOLE
156                 if (con_initialized)
157                         CON_Out(Console, buffer);
158 #endif
159
160 /*              for (i=0; i<l; i+=CON_LINE_LEN,con_line++)
161                 {
162                         memcpy(con_display, &buffer[i], min(80, l-i));
163                 }*/
164
165                 if (text_console_enabled)
166                 {
167                         /* Produce a sanitised version and send it to the console */
168                         char *p1, *p2;
169
170                         p1 = p2 = buffer;
171                         do
172                                 switch (*p1)
173                                 {
174                                 case CC_COLOR:
175                                 case CC_LSPACING:
176                                         p1++;
177                                 case CC_UNDERLINE:
178                                         p1++;
179                                         break;
180                                 default:
181                                         *p2++ = *p1++;
182                                 }
183                         while (*p1);
184                         *p2 = 0;
185
186                         printf(buffer);
187                 }
188         }
189 }
190
191 /* ======
192  * con_update - Check for new console input. If it's there, use it.
193  * ======
194  */
195 void con_update(void)
196 {
197 #if 0
198         char buffer[CMD_MAX_LENGTH], *t;
199
200         /* Check for new input */
201         t = fgets(buffer, sizeof(buffer), stdin);
202         if (t == NULL) return;
203
204         cmd_parse(buffer);
205 #endif
206         con_draw();
207 }
208
209
210 int con_events(int key)
211 {
212 #ifdef CONSOLE
213         return CON_Events(key);
214 #else
215         return key;
216 #endif
217 }
218
219
220 /* ======
221  * cvar_registervariable - Register a CVar
222  * ======
223  */
224 void cvar_registervariable (cvar_t *cvar)
225 {
226         cvar_t *ptr;
227
228         Assert(cvar != NULL);
229
230         cvar->next = NULL;
231         cvar->value = strtod(cvar->string, (char **) NULL);
232
233         if (cvar_vars == NULL)
234         {
235                 cvar_vars = cvar;
236         } else
237         {
238                 for (ptr = cvar_vars; ptr->next != NULL; ptr = ptr->next) ;
239                 ptr->next = cvar;
240         }
241 }
242
243 /* ======
244  * cvar_set - Set a CVar's value
245  * ======
246  */
247 void cvar_set (char *cvar_name, char *value)
248 {
249         cvar_t *ptr;
250
251         for (ptr = cvar_vars; ptr != NULL; ptr = ptr->next)
252                 if (!strcmp(cvar_name, ptr->name)) break;
253
254         if (ptr == NULL) return; // If we didn't find the cvar, give up
255
256         ptr->value = strtod(value, (char **) NULL);
257 }
258
259 /* ======
260  * cvar() - Get a CVar's value
261  * ======
262  */
263 float cvar (char *cvar_name)
264 {
265         cvar_t *ptr;
266
267         for (ptr = cvar_vars; ptr != NULL; ptr = ptr->next)
268                 if (!strcmp(cvar_name, ptr->name)) break;
269
270         if (ptr == NULL) return 0.0; // If we didn't find the cvar, give up
271
272         return ptr->value;
273 }
274
275
276 /* ==========================================================================
277  * DRAWING
278  * ==========================================================================
279  */
280 void con_draw(void)
281 {
282 #ifdef CONSOLE
283         CON_DrawConsole(Console);
284 #else
285 #if 0
286         char buffer[CON_LINE_LEN+1];
287         int i,j;
288         for (i = con_line, j=0; j < 20; i = (i+1) % CON_NUM_LINES, j++)
289         {
290                 memcpy(buffer, con_display[i], CON_LINE_LEN);
291                 buffer[CON_LINE_LEN] = 0;
292                 gr_string(1,j*10,buffer);
293         }
294 #endif
295 #endif
296 }
297
298 void con_show(void)
299 {
300 #ifdef CONSOLE
301         if (!con_initialized)
302                 con_init_real();
303
304         CON_Show(Console);
305         CON_Topmost(Console);
306 #endif
307 }
308
309 #ifdef CONSOLE
310 void con_parse(ConsoleInformation *console, char *command)
311 {
312         cmd_parse(command);
313 }
314 #endif