00001 #include "Buzz_inc.h"
00002 #include "externs.h"
00003 #include "assert.h"
00004 #include "pace.h"
00005 #include "av.h"
00006 #include "options.h"
00007 #include "utils.h"
00008 #include "logging.h"
00009
00010 LOG_DEFAULT_CATEGORY(LOG_ROOT_CAT);
00011
00012 extern GXHEADER vhptr;
00013
00014 void seq_init (void);
00015
00016 char
00017 DoModem(int sel)
00018 {
00019 NOTICE1("DoModem not implemented");
00020 return (0);
00021 }
00022
00023 char
00024 MPrefs(char mode)
00025 {
00026 return (0);
00027 }
00028
00029 struct Prest_Upd MP[3];
00030
00031 int put_serial(unsigned char n) {return 0;}
00032 void MesCenter(void){}
00033
00034 int
00035 AquireDrive (void)
00036 {
00037 return 'K' - 'A';
00038 }
00039
00040 char *letter_dat;
00041
00042 void
00043 OpenEmUp(void)
00044 {
00045 randomize();
00046
00047 seq_init ();
00048
00049 GV(&vhptr,320,200);
00050
00051 XMAS=1;
00052
00053 letter_dat = slurp_gamedat ("letter.dat");
00054 }
00055
00056 int
00057 PCX_D (void *src_raw,void *dest_raw,unsigned src_size)
00058 {
00059 char *src = src_raw;
00060 char *dest = dest_raw;
00061 char num;
00062 char *orig_dest = dest;
00063 do {
00064 if ((*src&0xc0)==0xc0) {
00065 num=*(src++)&0x3f; src_size--;
00066 while ((num--)>0) {*(dest++)=*src;}
00067 src++;src_size--;
00068 } else {
00069 (*dest++)=*(src++);src_size--;
00070 };
00071 } while(src_size);
00072 return (dest - orig_dest);
00073 }
00074
00075 int
00076 RLED (void *src_raw, void *dest_raw, unsigned int src_size)
00077 {
00078 signed char *src = src_raw;
00079 signed char *dest = dest_raw;
00080 unsigned int used;
00081 int count, val;
00082 int i;
00083
00084 used = 0;
00085 while (used < src_size) {
00086 count = src[used++];
00087
00088 if (count < 0) {
00089 count = -count + 1;
00090 val = src[used++];
00091 for (i = 0; i < count; i++)
00092 *dest++ = val;
00093 } else {
00094 count++;
00095 for (i = 0; i < count; i++)
00096 *dest++ = src[used++];
00097 }
00098 }
00099
00100 if (0)
00101 printf ("total bytes %d\n", (void *)dest - (void *)dest_raw);
00102
00103 return ((void *)dest - (void *)dest_raw);
00104 }
00105
00106 int
00107 RLED_img (void *src_raw, void *dest_raw, unsigned int src_size, int w, int h)
00108 {
00109 signed char *src = src_raw;
00110 signed char *dest;
00111 unsigned int used;
00112 int count, val;
00113 int total;
00114 signed char buf[128 * 1024];
00115 int row;
00116
00117 dest = buf;
00118
00119 used = 0;
00120 while (used < src_size) {
00121 count = src[used++];
00122
00123 if (count < 0) {
00124 count = -count + 1;
00125 val = src[used++];
00126 memset(dest, val, count);
00127 dest += count;
00128 } else {
00129 count++;
00130 memcpy(dest, &src[used], count);
00131 used += count;
00132 dest += count;
00133 }
00134 }
00135
00136 total = dest - buf;
00137
00138 if (total < w * h + h) {
00139 memcpy (dest_raw, buf, w * h);
00140 return (w * h);
00141 }
00142
00143 dest = dest_raw;
00144 for (row = 0; row < h; row++) {
00145 memcpy(dest, &buf[row * (w+1)], w);
00146 dest += w;
00147 }
00148
00149 return (w * h);
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 void
00163 FadeIn (char wh,char *palx,int steps,int val,char mode)
00164 {
00165 int from = 0;
00166 int to = 256;
00167 if (wh == 0)
00168 to = val;
00169 else if (wh == 1)
00170 from = val;
00171 else
00172 assert(wh == 2);
00173 av_set_fading(AV_FADE_IN, from, to, steps, !!mode);
00174 }
00175
00176 void
00177 FadeOut(char wh,char *palx,int steps,int val,char mode)
00178 {
00179 int from = 0;
00180 int to = 256;
00181
00182 if (wh == 0)
00183 to = val;
00184 else if (wh == 1)
00185 from = val;
00186 else
00187 assert(wh == 2);
00188 av_set_fading(AV_FADE_OUT, from, to, steps, !!mode);
00189 }
00190
00191 void
00192 delay (int millisecs)
00193 {
00194 idle_loop_secs (millisecs / 1000.0);
00195 }
00196
00197 void
00198 bzdelay (int ticks)
00199 {
00200 idle_loop_secs (ticks / 100.0);
00201 }
00202
00203 int
00204 CDAccess (int drive,int track,char op)
00205 {
00206 return (0);
00207 }
00208
00209 int
00210 brandom (int limit)
00211 {
00212 if (limit == 0)
00213 return (0);
00214 return (int) (limit * (rand() / (RAND_MAX + 1.0)));
00215 }
00216
00217 long RLEC (char *src, char *dest, unsigned int src_size)
00218 {
00219 unsigned int src_i;
00220 int dest_i,cpr;
00221
00222 for (src_i = dest_i=0; src_i< src_size; ) {
00223 int k;
00224 k = 0;
00225 cpr= ((src_size-src_i-1)<128) ? src_size-src_i-1 : 128;
00226 while (k<cpr && src[src_i] != src[src_i+1]) {
00227 k++;
00228 src_i++;
00229 }
00230 if (k) {
00231 dest[dest_i++] = (k-1);
00232 memcpy (&dest[dest_i], &src[src_i-k], k);
00233 dest_i += k;
00234 } else {
00235 k = 2;
00236 src_i++;
00237 while ( k<cpr && src[src_i] == src[src_i+1]) {
00238 k++;
00239 src_i++;
00240 }
00241 dest[dest_i++] = (-k+1);
00242 dest[dest_i++] = src[src_i++];
00243 }
00244 }
00245 return (dest_i);
00246 }
00247
00248 void
00249 StopAudio(char mode)
00250 {
00251 av_silence(AV_SOUND_CHANNEL);
00252 }
00253
00254 void
00255 CloseEmUp (unsigned char error,unsigned int value)
00256 {
00257
00258 exit(EXIT_SUCCESS);
00259 }
00260
00261
00262
00263 struct tblinfo {
00264 int count;
00265 char **strings;
00266 };
00267
00268
00269
00270
00271
00272
00273 void
00274 frm_read_tbl (char *keyname, struct tblinfo *tbl)
00275 {
00276 FILE *fin;
00277 int lo, hi;
00278 int idx;
00279 char *p;
00280 char name[100];
00281
00282 if ((fin = sOpen (keyname, "rb", 0)) == NULL){
00283 WARNING2("Unable to open file '%s'.", keyname);
00284 return;
00285 }
00286
00287
00288 lo = getc (fin);
00289 hi = getc (fin);
00290 tbl->count = (hi << 8) | lo;
00291
00292
00293 tbl->strings = xcalloc(tbl->count, sizeof *tbl->strings);
00294
00295 idx = 0;
00296 while (fread (name, 1, 8, fin) == 8) {
00297 name[8] = '\0';
00298 for (p = name; *p; p++) {
00299 *p = tolower (*p);
00300 if (*p == '#')
00301 *p = '_';
00302 }
00303 DEBUG4("Found name '%s' at position %d in file %s.",name, idx, keyname);
00304 tbl->strings[idx++] = xstrdup (name);
00305 }
00306
00307
00308 if (tbl->count != idx) {
00309 tbl->count = idx;
00310 tbl->strings = xrealloc(tbl->strings, sizeof *tbl->strings);
00311 }
00312
00313 fclose (fin);
00314 }
00315
00316
00317 static struct tblinfo frm_tbl;
00318
00319
00320 static struct tblinfo frm_ftbl;
00321
00322
00323
00324
00325
00326 void
00327 seq_init (void)
00328 {
00329 frm_read_tbl ("SEQ.KEY", &frm_tbl);
00330 frm_read_tbl ("FSEQ.KEY", &frm_ftbl);
00331 }
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 char *
00343 seq_filename (int seq, int mode)
00344 {
00345 struct tblinfo *tp;
00346
00347 if (mode == 0)
00348 tp = &frm_tbl;
00349 else
00350 tp = &frm_ftbl;
00351
00352 if (seq < 0 || seq >= tp->count)
00353 return NULL;
00354
00355 return (tp->strings[seq]);
00356 }
00357
00358 void
00359 SMove (void *p, int x, int y)
00360 {
00361 GXHEADER local;
00362
00363 GV (&local, 160, 100);
00364 memcpy (local.vptr, p, 160 * 100);
00365 gxPutImage (&local, gxSET, x, y, 0);
00366 DV (&local);
00367 }
00368
00369 void
00370 LMove (void *p)
00371 {
00372 GXHEADER local;
00373
00374 memset (screen, 0, 320 * 200);
00375
00376 GV (&local, 160, 100);
00377 memcpy (local.vptr, p, 160 * 100);
00378 gxPutImage (&local, gxSET, 320 / 4, 200 / 4, 0);
00379 DV (&local);
00380 }
00381
00382 void
00383 randomize (void)
00384 {
00385 srand (get_time() * 1000);
00386 }
00387
00388
00389
00390
00391
00392
00393
00394 void
00395 idle_loop_secs (double secs)
00396 {
00397 double start;
00398
00399 gr_maybe_sync ();
00400
00401 start = get_time ();
00402
00403 while (1) {
00404 av_block ();
00405
00406 if (get_time () - start >= secs)
00407 break;
00408 }
00409 }
00410
00411
00412
00413
00414
00415 void
00416 idle_loop (int ticks)
00417 {
00418 idle_loop_secs (ticks / 2000.0);
00419 }
00420
00421 long VoiceOff;
00422
00423 char *soundbuf;
00424 size_t soundbuf_size = 0;
00425 size_t soundbuf_used = 0;
00426 struct audio_chunk news_chunk;
00427
00428 ssize_t
00429 load_audio_file(const char *name, char **data, size_t *size)
00430 {
00431 mm_file mf;
00432 unsigned channels, rate;
00433 const size_t def_size = 16 * 1024;
00434 size_t offset = 0;
00435 ssize_t read = 0;
00436 double start = get_time();
00437
00438
00439 start *= 1.0;
00440
00441 assert(name);
00442 assert(data);
00443 assert(size);
00444
00445 if (mm_open_fp(&mf, sOpen(name, "rb", FT_AUDIO)) < 0)
00446 return -1;
00447
00448 if (mm_audio_info(&mf, &channels, &rate) < 0)
00449 {
00450 CWARNING3(audio, "no audio data in file `%s'", name);
00451 mm_close(&mf);
00452 return -1;
00453 }
00454
00455 if (channels != 1 || rate != 11025)
00456 {
00457 CERROR3(audio, "file `%s' should be mono, 11025Hz", name);
00458 mm_close(&mf);
00459 return -1;
00460 }
00461
00462 if (!*data)
00463 *data = xmalloc(*size = def_size);
00464
00465 while (0 < (read = mm_decode_audio(&mf,
00466 *data+offset, *size-offset)))
00467 {
00468 offset += read;
00469 if (*size <= offset)
00470 *data = xrealloc(*data, *size *= 2);
00471 }
00472
00473 mm_close(&mf);
00474
00475 CDEBUG4(audio, "loading file `%s' took %5.4f seconds",
00476 name, get_time() - start);
00477
00478 return offset;
00479 }
00480
00481 void
00482 NGetVoice(char plr,char val)
00483 {
00484 char fname[100];
00485 ssize_t bytes = 0;
00486
00487 sprintf(fname, "%s_%03d.ogg", (plr ? "sov" : "usa"), val);
00488 bytes = load_audio_file(fname, &soundbuf, &soundbuf_size);
00489 soundbuf_used = (bytes > 0) ? bytes : 0;
00490 }
00491
00492 void
00493 PlayVoice (void)
00494 {
00495 if (!soundbuf_used)
00496 return;
00497 news_chunk.data = soundbuf;
00498 news_chunk.size = soundbuf_used;
00499 news_chunk.next = NULL;
00500 play(&news_chunk, AV_SOUND_CHANNEL);
00501 }
00502
00503 void
00504 KillVoice (void)
00505 {
00506 av_silence(AV_SOUND_CHANNEL);
00507 }
00508
00509 void
00510 StopVoice (void)
00511 {
00512 av_silence(AV_SOUND_CHANNEL);
00513 }
00514
00515 void
00516 PlayAudio(char *name, char mode)
00517 {
00518 ssize_t bytes = 0;
00519 bytes = load_audio_file(name, &soundbuf, &soundbuf_size);
00520 soundbuf_used = (bytes > 0) ? bytes : 0;
00521 PlayVoice();
00522 }
00523
00524 int
00525 getch (void)
00526 {
00527 int c;
00528
00529 while (1) {
00530 av_block ();
00531 if ((c = bioskey (0)) != 0)
00532 return (c);
00533 }
00534 }
00535
00536 void
00537 play_audio (int sidx, int mode)
00538 {
00539 char filename[40];
00540 ssize_t size;
00541 char * name = seq_filename(sidx,mode);
00542
00543 if (!name)
00544 {
00545 CWARNING4(audio, "failed request for sound idx %d, mode %d",
00546 sidx, mode);
00547 return;
00548 }
00549 snprintf(filename, sizeof(filename), "%s.ogg", name);
00550 CINFO3(audio, "play sound file `%s'", filename);
00551 size = load_audio_file(filename, &soundbuf, &soundbuf_size);
00552 soundbuf_used = (size > 0) ? size : 0;
00553 PlayVoice ();
00554 }
00555
00556 #define debug_file stdout
00557 #if 0
00558 void
00559 vdbg (char const *fmt, va_list args)
00560 {
00561 char buf[10000];
00562 char *p;
00563 struct tm tm;
00564 struct timeval tv;
00565 time_t t;
00566 int binchars;
00567 static unsigned long last_millitime;
00568 unsigned long this_millitime;
00569 int delta;
00570
00571 gettimeofday (&tv, NULL);
00572 t = tv.tv_sec;
00573 tm = *localtime (&t);
00574
00575 p = buf;
00576
00577 sprintf (p, "%02d:%02d:%02d.%03d ", tm.tm_hour, tm.tm_min, tm.tm_sec,
00578 (int)(tv.tv_usec / 1000));
00579 p += strlen (p);
00580
00581 this_millitime = (tm.tm_hour * 3600 + tm.tm_min * 60 + tm.tm_sec)
00582 * 1000 + tv.tv_usec / 1000;
00583
00584 if (last_millitime == 0)
00585 last_millitime = this_millitime;
00586
00587 delta = this_millitime - last_millitime;
00588 last_millitime = this_millitime;
00589
00590 if (delta < 0)
00591 delta = 0;
00592
00593 sprintf (p, "%5d ", delta);
00594 p += strlen (p);
00595
00596 vsprintf (p, fmt, args);
00597
00598 p += strlen (p);
00599 while (p != buf && (p[-1] == '\n' || p[-1] == '\r'))
00600 *--p = 0;
00601
00602 binchars = 0;
00603 for (p = buf; *p && binchars < 20; p++) {
00604 int c = *p;
00605 if ((c >= ' ' && c < 0177) || c == '\t' || c == '\n') {
00606 putc (c, debug_file);
00607 } else {
00608 binchars++;
00609 putc ('.', debug_file);
00610 }
00611 }
00612 putc ('\n', debug_file);
00613 fflush (debug_file);
00614 }
00615
00616 void
00617 dbg (char const *fmt, ...)
00618 {
00619 va_list args;
00620
00621 va_start (args, fmt);
00622 vdbg (fmt, args);
00623 va_end (args);
00624 }
00625 #endif