1 /*
2 This file is part of "Avanor, the Land of Mystery" roguelike game
3 Home page: http://www.avanor.com/
4 Copyright (C) 2000-2003 Vadim Gaidukevich
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <stdlib.h>
24 #include "global.h"
25 #include "string.h"
26
27 unsigned long total_cr = 0;
28 unsigned long total_it = 0;
29 unsigned long cr_kiled = 0;
30 unsigned long cr_died = 0;
31
32
33 const char* color_convert_table[] =
34 {
35 "\x1F\x00", "\x1F\x01", "\x1F\x02", "\x1F\x03",
36 "\x1F\x04", "\x1F\x05", "\x1F\x06", "\x1F\x07",
37 "\x1F\x08", "\x1F\x09", "\x1F\x0A", "\x1F\x0B",
38 "\x1F\x0C", "\x1F\x0D", "\x1F\x0E", "\x1F\x0F",
39 };
40
41 int __animation_flag = 100;
42
43 #ifndef XWIN32
44 char * vscreen;
45 #endif
46
47 long size_x = 80;
48 long size_y = 25;
49
50 int cursor_pos_x = 0;
51 int cursor_pos_y = 0;
52 int current_attr = 7;
53
54 #ifdef XWIN32
55 #include <windows.h>
56 HANDLE hStdout;
57 HANDLE hStdin;
58 CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
59 CONSOLE_CURSOR_INFO ccInfo;
60 CHAR_INFO *vscreenw;
61 #endif
62
vInit()63 void vInit()
64 {
65 #ifdef XLINUX
66 mkdir(vMakePath(HOME_DIR, ""), 0755);
67 #endif
68
69 #ifdef XDOS
70 text_info ti;
71 gettextinfo(&ti);
72 size_x = ti.screenwidth;
73 size_y = ti.screenheight;
74 #endif
75
76 #ifdef XWIN32
77 hStdin = GetStdHandle(STD_INPUT_HANDLE);
78 hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
79
80 GetConsoleCursorInfo(hStdout, &ccInfo);
81
82 GetConsoleScreenBufferInfo(hStdout, &csbiInfo);
83 size_x = csbiInfo.srWindow.Right - csbiInfo.srWindow.Left + 1;
84 size_y = csbiInfo.srWindow.Bottom - csbiInfo.srWindow.Top + 1;
85
86 if(size_x != csbiInfo.dwSize.X || size_y != csbiInfo.dwSize.Y)
87 {
88 COORD coord = { (short)size_x, (short)size_y };
89 if(!SetConsoleScreenBufferSize(hStdout, coord))
90 assert(false);
91 }
92
93 vscreenw = new CHAR_INFO[size_x * size_y];
94
95 #endif //XWIN32
96
97 #ifdef XLINUX
98 initscr();
99 cbreak();
100 noecho();
101 nonl();
102 raw();
103 start_color();
104
105 init_pair(0, COLOR_BLACK, COLOR_BLACK);
106 init_pair(xBLUE, COLOR_BLUE, COLOR_BLACK);
107 init_pair(xGREEN, COLOR_GREEN, COLOR_BLACK);
108 init_pair(xRED, COLOR_RED, COLOR_BLACK);
109 init_pair(xMAGENTA, COLOR_MAGENTA, COLOR_BLACK);
110 init_pair(xCYAN, COLOR_CYAN, COLOR_BLACK);
111 init_pair(xBROWN, COLOR_YELLOW, COLOR_BLACK);
112 init_pair(xLIGHTGRAY, COLOR_WHITE, COLOR_BLACK);
113
114 init_pair(xLIGHTBLUE, COLOR_BLUE, COLOR_BLACK);
115 init_pair(xLIGHTGREEN, COLOR_GREEN , COLOR_BLACK);
116 init_pair(xLIGHTRED, COLOR_RED, COLOR_BLACK);
117 init_pair(xLIGHTMAGENTA, COLOR_MAGENTA, COLOR_BLACK);
118 init_pair(xLIGHTCYAN, COLOR_CYAN, COLOR_BLACK);
119 init_pair(xYELLOW, COLOR_YELLOW, COLOR_BLACK);
120 init_pair(xWHITE, COLOR_WHITE, COLOR_BLACK);
121
122 size_x = COLS;
123 size_y = LINES;
124
125 #endif //XLINUX
126
127 #ifndef XWIN32
128 vscreen = new char[size_x * size_y * 2];
129 #endif
130
131 vClrScr();
132 }
133
vClrScr()134 void vClrScr()
135 {
136 #ifdef XWIN32
137 CHAR_INFO blank_char = { ' ', 7 };
138 int screenbuf_size = size_x * size_y;
139 for (int i = 0; i < screenbuf_size; i++)
140 vscreenw[i] = blank_char;
141 #else
142 for (int i = 0; i < size_x * size_y * 2; i += 2)
143 {
144 vscreen[i] = 32;
145 vscreen[i + 1] = 7;
146 }
147 #endif
148 }
149
vFinit()150 void vFinit()
151 {
152 #ifdef XWIN32
153 SetConsoleScreenBufferSize(hStdout, csbiInfo.dwSize);
154 SetConsoleWindowInfo(hStdout, true, &csbiInfo.srWindow);
155 SetConsoleCursorInfo(hStdout, &ccInfo);
156 delete[] vscreenw;
157 #endif
158 #ifdef XLINUX
159 endwin();
160 #endif
161 #ifndef XWIN32
162 delete[] vscreen;
163 #endif
164 }
165
vRefresh()166 void vRefresh()
167 {
168 #ifdef XWIN32
169 COORD buffer_size = { (short)size_x, (short)size_y };
170 COORD buffer_coord = { 0, 0 };
171 SMALL_RECT write_region = { 0, 0, size_x - 1, size_y - 1 };
172
173 WriteConsoleOutput(hStdout, vscreenw, buffer_size, buffer_coord, &write_region);
174 #endif
175 #ifdef XDOS
176 puttext(1, 1, size_x, size_y, vscreen);
177 #endif
178 #ifdef XLINUX
179 move(0, 0);
180 for (int i = 0; i < size_x * size_y; i++)
181 {
182 // attrset(vscreen[i * 1]);
183 char ch2 = vscreen[i * 2 + 1];
184 char ch1 = vscreen[i * 2];
185 if (ch1 < ' ') ch1 = ' ';
186 if (ch2 > 7)
187 addch(ch1 | (ch2 << 8) | A_BOLD);
188 else
189 addch(ch1 | (ch2 << 8));
190
191 }
192
193 refresh();
194 #endif
195 }
196
vPutCh(int x,int y,char ch,int attr)197 void vPutCh(int x, int y, char ch, int attr)
198 {
199 assert(x >= 0 && y >= 0 && x <= size_x && y <= size_y);
200 #ifdef XWIN32
201 CHAR_INFO tmp = { ch, attr };
202 vscreenw[x + y * size_x] = tmp;
203 #else
204 vscreen[x * 2 + y * size_x * 2] = ch;
205 vscreen[x * 2 + y * size_x * 2 + 1] = attr;
206 #endif
207 };
208
vTestCh(int x,int y)209 char vTestCh(int x, int y)
210 {
211 #ifdef XWIN32
212 return vscreenw[x + y * size_x].Char.AsciiChar;
213 #else
214 return vscreen[x * 2 + y * size_x * 2];
215 #endif
216 }
217
vPutCh(int x,int y,char ch)218 void vPutCh(int x, int y, char ch)
219 {
220 #ifdef XWIN32
221 vscreenw[x + y * size_x].Char.AsciiChar = ch;
222 #else
223 vscreen[x * 2 + y * size_x * 2] = ch;
224 #endif
225 };
226
vGotoXY(int x,int y)227 void vGotoXY(int x, int y)
228 {
229 cursor_pos_x = x;
230 cursor_pos_y = y;
231 }
232
vGetCursorPos(int * x,int * y)233 void vGetCursorPos(int * x, int * y)
234 {
235 *x = cursor_pos_x;
236 *y = cursor_pos_y;
237 }
238
vGetS(char * s,int buffer_size)239 int vGetS(char * s, int buffer_size)
240 {
241 int cx;
242 int cy;
243 vGetCursorPos(&cx, &cy);
244 int buffer_pos = 0;
245 char ch;
246 strcpy(s, "");
247 do
248 {
249 vXGotoXY(cx + strlen(s), cy);
250 ch = vGetch();
251
252 s[buffer_pos] = ch;
253 if (ch == 13 || ch == 27 )
254 {
255 s[buffer_pos] = 0;
256 if (ch == 13)
257 return 1;
258 else
259 return 0;
260 }
261 if (ch == 8 && buffer_pos > 0)
262 {
263 s[buffer_pos - 1] = ' ';
264 s[buffer_pos] = 0;
265 vGotoXY(cx, cy);
266 vPutS(s);
267 buffer_pos--;
268 } else
269 if (ch != 8)
270 buffer_pos++;
271 s[buffer_pos] = 0;
272 vGotoXY(cx, cy);
273 vPutS(s);
274 vRefresh();
275 } while (buffer_pos < buffer_size - 1);
276
277 return 1;
278 }
279
vDelay(int n)280 void vDelay(int n)
281 {
282 #ifdef XWIN32
283
284 #endif
285 #ifdef XDOS
286 delay(n);
287 #endif
288
289 }
290
vKbhit()291 int vKbhit()
292 {
293 #ifdef XLINUX
294 timeout(0);
295 int ch = getch();
296 timeout(-1);
297 if (ch == ERR) return 0;
298 ungetch(ch);
299 return 1;
300 #else
301 return kbhit();
302 #endif
303 }
304
vGetch()305 int vGetch()
306 {
307 #ifdef XLINUX
308 int ch = getch();
309 if (ch != 27) return ch;
310
311 timeout(0);
312 ch = getch();
313 timeout(-1);
314
315 if (ch == ERR) return KEY_ESC;
316 if (ch != '[') { ungetch(ch); return KEY_ESC; }
317
318 switch (getch())
319 {
320 case 'A': return KEY_UP;
321 case 'B': return KEY_DOWN;
322 case 'C': return KEY_RIGHT;
323 case 'D': return KEY_LEFT;
324 case 'G': return KEY_CENTER;
325 case '1': return getch() == '~' ? KEY_HOME : KEY_UNKNOWN;
326 case '4': return getch() == '~' ? KEY_END : KEY_UNKNOWN;
327 case '5': return getch() == '~' ? KEY_PGUP : KEY_UNKNOWN;
328 case '6': return getch() == '~' ? KEY_PGDOWN : KEY_UNKNOWN;
329 }
330 return KEY_UNKNOWN;
331 #else
332 int ch = getch();
333 if (ch == 0 || ch == 224) ch = KEY_EXTENDED_CODE | getch();
334 return ch;
335 #endif
336 }
337
vXGetch(char * ch_buf)338 int vXGetch(char * ch_buf)
339 {
340 int slen = strlen(ch_buf);
341 while (1)
342 {
343 int ch = vGetch();
344 for (int i = 0; i < slen; i++)
345 {
346 if (ch == ch_buf[i])
347 return ch;
348 }
349 if (ch == KEY_ESC)
350 return 0;
351 }
352 }
353
vXGotoXY(int x,int y)354 void vXGotoXY(int x, int y)
355 {
356 cursor_pos_x = x;
357 cursor_pos_y = y;
358
359 #ifdef XWIN32
360 CONSOLE_CURSOR_INFO ConsoleCursorInfo = ccInfo;
361 ConsoleCursorInfo.bVisible = TRUE;
362 SetConsoleCursorInfo(hStdout, &ConsoleCursorInfo);
363
364 COORD coord;
365 coord.X = x;
366 coord.Y = y;
367 SetConsoleCursorPosition(hStdout, coord);
368 #endif
369
370 #ifdef XDOS
371 _setcursortype(_NORMALCURSOR);
372 gotoxy(x + 1, y + 1);
373 #endif
374
375 #ifdef XLINUX
376 move(y, x);
377 #endif
378
379 }
380
vHideCursor()381 void vHideCursor()
382 {
383 #ifdef XWIN32
384 // CONSOLE_CURSOR_INFO ConsoleCursorInfo = ccInfo;
385 // ConsoleCursorInfo.bVisible = FALSE;
386 // SetConsoleCursorInfo(hStdout, &ConsoleCursorInfo);
387 #endif
388
389 #ifdef XDOS
390 _setcursortype(_NOCURSOR);
391 #endif
392
393 #ifdef XLINUX
394 vXGotoXY(size_x, size_y);
395 #endif
396 }
397
vSetAttr(int color)398 void vSetAttr(int color)
399 {
400 current_attr = color;
401 }
402
vClrEol()403 void vClrEol()
404 {
405 while (cursor_pos_x < size_x)
406 {
407 vPutCh(cursor_pos_x, cursor_pos_y, ' ');
408 cursor_pos_x++;
409 }
410 }
411
412 // (31, x) - change attr
413 //
vPutS(const char * s)414 void vPutS(const char * s)
415 {
416 if(cursor_pos_y >= size_y) cursor_pos_x = cursor_pos_y = 0;
417
418 while(true)
419 {
420 char ch = *s++;
421 switch(ch)
422 {
423 case 0 :
424 return;
425 case 31 :
426 vSetAttr(*s++); break;
427 case 13 :
428 case '\n' :
429 cursor_pos_x = 0;
430 if(++cursor_pos_y >= size_y) cursor_pos_y = 0;
431 break;
432 default :
433 {
434 if(cursor_pos_x >= size_x)
435 {
436 cursor_pos_x = 0;
437 if(++cursor_pos_y >= size_y) cursor_pos_y = 0;
438 }
439 vPutCh(cursor_pos_x++, cursor_pos_y, ch, current_attr);
440 }
441 }
442 }
443 }
444
vFPutS(FILE * f,const char * s)445 void vFPutS(FILE * f, const char * s)
446 {
447 int pos = 0;
448 while (s[pos])
449 {
450 if (s[pos] == 31)
451 {
452 pos +=2;
453 continue;
454 }
455 fprintf(f, "%c", s[pos]);
456 pos++;
457 }
458 }
459
460 static unsigned long randx;
461
vRandSeed(unsigned long seed)462 void vRandSeed(unsigned long seed)
463 {
464 randx = seed;
465 }
466
467 #define X_RAND_A 0x000343FDUL
468 #define X_RAND_B 0x00269EC3UL
469 #define X_RAND_MAX 0x7FFFFFFFUL
470
vRand()471 long vRand()
472 {
473 randx = randx * X_RAND_A + X_RAND_B;
474 unsigned long randhigh = randx & 0x7FFF0000;
475 randx = randx * X_RAND_A + X_RAND_B;
476 unsigned long randlow = randx >> 16;
477 return randhigh | randlow;
478 }
479
vRand(unsigned long n)480 long vRand(unsigned long n)
481 {
482 assert(n > 0);
483 if (n > 0x8000)
484 {
485 assert(n <= X_RAND_MAX + 1);
486 randx = randx * X_RAND_A + X_RAND_B;
487 unsigned long randhigh = randx & 0x7FFF0000;
488 randx = randx * X_RAND_A + X_RAND_B;
489 unsigned long randlow = randx >> 16;
490 return (randhigh | randlow) % n;
491 }
492 else
493 {
494 randx = randx * X_RAND_A + X_RAND_B;
495 return (randx >> 16) % n;
496 }
497 }
498
V_BUFFER()499 V_BUFFER::V_BUFFER()
500 {
501 #ifdef XWIN32
502 buffer = new char[size_x * size_y * sizeof(CHAR_INFO)];
503 #else
504 buffer = new char[size_x * size_y * 2];
505 #endif
506 }
507
~V_BUFFER()508 V_BUFFER::~V_BUFFER()
509 {
510 delete [] buffer;
511 }
512
vStore(V_BUFFER * buf)513 void vStore(V_BUFFER * buf)
514 {
515 #ifdef XWIN32
516 memcpy(buf->buffer, vscreenw, size_x * size_y * sizeof(CHAR_INFO));
517 #else
518 memcpy(buf->buffer, vscreen, size_x * size_y * 2);
519 #endif
520 }
521
vRestore(V_BUFFER * buf)522 void vRestore(V_BUFFER * buf)
523 {
524 #ifdef XWIN32
525 memcpy(vscreenw, buf->buffer, size_x * size_y * sizeof(CHAR_INFO));
526 #else
527 memcpy(vscreen, buf->buffer, size_x * size_y * 2);
528 #endif
529 }
530
531 static char path_buffer[1024];
532
vMakePath(char * prefix,char * filename)533 char *vMakePath(char *prefix, char *filename)
534 {
535 #ifdef XLINUX
536 if (prefix[0] == '~')
537 {
538 sprintf(path_buffer, "%s%s%s", getenv("HOME"), prefix + 1, filename);
539 }
540 else
541 #endif
542 {
543 sprintf(path_buffer, "%s%s", prefix, filename);
544 }
545 return path_buffer;
546 }
547