pace.c

Go to the documentation of this file.
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);     // Allocate only Virtual Buffer
00050 
00051     XMAS=1; /* we do have a mouse */
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  * Original sources say:
00154  * @param wh = 0 - fade colors from 0 to val,
00155  *           = 1 - fade colors from val to 3*256,
00156  *           = 2 - fade all colors
00157  * @param palx pointer to palette
00158  * @param steps
00159  * @param val pivot index in palette array
00160  * @param mode if mode == 1 then preserve non-faded colors, else make black
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;  /* holds the number of characters to copy or repeat. */
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++;       /* increment the number of characters to copy */
00228             src_i++;   /* move pointer to the next character */
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;   /* there are at least two characters to be repeated */
00236             src_i++; /* advance pointer beyond the first match*/
00237             while ( k<cpr && src[src_i] == src[src_i+1]) {
00238                 k++;       /* increment the number of characters to copy */
00239                 src_i++;   /* move pointer to the next character */
00240             }  /* while */
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     /* DEBUG */ /* fprintf (stderr, "CloseEmUp()\n"); */
00258     exit(EXIT_SUCCESS);
00259 }
00260 
00261 /** Structure to save the sequence number to name mapping
00262  */
00263 struct tblinfo {
00264   int count; /**< number of sequences in this array */
00265   char **strings; /**< array of strings. Keys are sequence numbers, values are sequence names */
00266 };
00267 
00268 /** Read sequence name array from file
00269  * 
00270  * \param keyname Name of the file to read from
00271  * \param tblinfo Pointer to the tblinfo to fill
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]; /** \todo Assumption about the size of name is too high, right? */
00281 
00282     if ((fin = sOpen (keyname, "rb", 0)) == NULL){
00283         WARNING2("Unable to open file '%s'.", keyname);
00284         return;
00285     }
00286 
00287     /* get number of sequence keys */
00288     lo = getc (fin);
00289     hi = getc (fin);
00290     tbl->count = (hi << 8) | lo;
00291     
00292     /* alloc enough memory for all the sequence names */
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     /* now idx is number of read strings */
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 /** Mapping from success sequence numbers to audio/video filenames. */
00317 static struct tblinfo frm_tbl;
00318 
00319 /** Mapping from failure sequence numbers to audio/video filenames. */
00320 static struct tblinfo frm_ftbl;
00321 
00322 /** Initialize the sequence keymaps
00323  * 
00324  * Reads success and failure sequences
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 /** Get sequence filename by sequence number
00334  * 
00335  * \param seq Index number of sequence
00336  * \param mode 0=success, other is failure
00337  * 
00338  * \return NULL if the sequence number is out of bound
00339  * \return name of the sequence file as string
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 /** do nothing for a few seconds.
00389  * 
00390  * The function will wait a number of seconds but will call av_block() in the meantime.
00391  * 
00392  * \param secs Number of seconds to wait.
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 /** wait a number of ticks
00412  * 
00413  * \param ticks Number of ticks to wait.
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     /* make compiler happy */
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

Generated on Fri Sep 28 00:35:45 2007 for raceintospace by  doxygen 1.5.3