replay.c

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2005 Michael K. McCarty & Fritz Bronner
00003 
00004     This program is free software; you can redistribute it and/or modify
00005     it under the terms of the GNU General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or
00007     (at your option) any later version.
00008 
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program; if not, write to the Free Software
00016     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 */
00018 // Interplay's BUZZ ALDRIN's RACE into SPACE
00019 //
00020 // Formerly -=> LiftOff : Race to the Moon :: IBM version MCGA
00021 // Copyright 1991 by Strategic Visions, Inc.
00022 // Designed by Fritz Bronner
00023 // Programmed by Michael K McCarty
00024 //
00025 #include "gamedata.h"
00026 #include "Buzz_inc.h"
00027 #include "externs.h"
00028 #include <assert.h>
00029 #include "mmfile.h"
00030 #include "av.h"
00031 #include "logging.h"
00032 
00033 #ifdef DEADCODE
00034 
00035 #define FRM_Delay       25
00036 
00037 #define STL_OFF         26715
00038 #define ANIM_PARTS      297
00039 
00040 extern char STEPnum, loc[4];
00041 extern struct MisEval Mev[60];
00042 extern char MANNED[2], STEP, pal2[768], AI[2];
00043 extern int tFrames, cFrame;
00044 extern long aLoc;
00045 extern GXHEADER dply;
00046 extern struct AnimType AHead;
00047 extern struct BlockHead BHead;
00048 #endif
00049 
00050 LOG_DEFAULT_CATEGORY(LOG_ROOT_CAT);
00051 
00052 #if 0
00053 void
00054 RLEF(char *dest, char *src, unsigned int src_size)
00055 {
00056     asm push es;                // preserve ES
00057     asm push ds;                // preserve DS
00058     asm les di, dest;           // move dest into ES:DI
00059     asm lds si, src;            // move src into DS:SI
00060     asm mov cx, 0;              // clear CX
00061     asm mov bx, src_size;       // move counter into BX
00062 
00063   loa:
00064     asm lodsb;                     // move byte into AL
00065     asm dec bx;                 // decrement CX
00066     asm cmp al, 0;              // compare AL to 0
00067     asm jl repeat;              // if al < 0 jump to repeat
00068 
00069     // copy bytes
00070     asm mov ah, 0;              // clear AH
00071     asm inc al;                 // increment AL
00072     asm mov cl, al;             // put value of AL into CL
00073     asm rep movsb;              // move CX bytes from DS:SI to ES:DI
00074     asm sub bx, ax;             // increment BX by approp value
00075     asm cmp bx, 0;              // see if finished
00076     asm jg loa;                 // if not then loop
00077     asm jmp bot;                // else jump to bottom
00078 
00079   repeat:
00080     asm neg al;                    // negate AL
00081     asm inc al;                 // increment AL by 1
00082     asm mov cl, al;             // move counter value to CX
00083     asm lodsb;                  // load value to copy
00084 
00085   lob:
00086     asm stosb;                     // copy AL into ES:DI
00087     asm loop lob;               // do while CX >0
00088     asm dec bx;                 // decrement bx;
00089 
00090     asm cmp bx, 100 h;
00091     asm jg sk;
00092     asm int 03 h;
00093 
00094   sk:
00095     asm cmp bx, 0;                 // see if finished
00096     asm jg loa;                 // if not then loop
00097 
00098   bot:                             // bottom of routine
00099     asm pop ds;                    // restore ds
00100     asm pop es;                 // restore es
00101 
00102     return;
00103 }
00104 #endif
00105 
00106 /** find and fill REPLAY structure and return 0, or -1 if failed.
00107  * if grp != NULL and oGROUP at offset rep->off[0] is found, then fill grp too
00108  * 
00109  * \return -1 on bad sequence
00110  * \return  0 in all other cases
00111  */
00112 static int
00113 find_replay(REPLAY * rep, struct oGROUP *grp, char player, int num,
00114     const char *type)
00115 {
00116     FILE *fseq = NULL;
00117     struct oGROUP group;
00118     size_t offset = 0;
00119     int retval = 0;
00120 
00121     assert(rep);
00122 
00123     /** \note uses SEQ.DAT */
00124     fseq = sOpen("SEQ.DAT", "rb", 0);
00125     if (!fseq)
00126         return -1;
00127 
00128     if (strncmp("OOOO", type, 4) == 0)
00129     {
00130         FILE *f = sOpen("REPLAY.DAT", "rb", 1);
00131 
00132         offset = (player * 100) + num;
00133         fseek(f, offset * (sizeof *rep), SEEK_SET);
00134         /** \todo Uses fread() here - should be fread_REPLAY(&Rep, 1, f); */
00135         fread(rep, (sizeof *rep), 1, f);
00136         fclose(f);
00137         if (grp && fseek(fseq, sizeof_oGROUP * rep->Off[0], SEEK_SET) == 0)
00138             fread_oGROUP(grp, 1, fseq);
00139     }
00140     else
00141     {
00142         int j = 0;
00143 
00144         while (fread_oGROUP(&group, 1, fseq))
00145         {
00146             if (strncmp(group.ID, "XXXX", 4) == 0)
00147             {
00148                 /* bad sequence? */
00149                 retval = -1;
00150                 goto done;
00151             }
00152             if (strcmp(&group.ID[3], type) == 0)
00153                 break;
00154             j++;
00155         }
00156         rep->Qty = 1;
00157         rep->Off[0] = j;
00158         if (grp)
00159             memcpy(grp, &group, sizeof(group));
00160     }
00161   done:
00162     if (fseq)
00163         fclose(fseq);
00164 
00165     return retval;
00166 }
00167 
00168 /**
00169  * 
00170  * \returns nothing if find_replay() fails
00171  * \returns nothing if it can't open the [f]seq.dat file
00172  */
00173 void
00174 Replay(char plr, int num, int dx, int dy, int width, int height, char *Type)
00175 {
00176     int keep_going;
00177     int i, kk, mode, max;
00178     FILE *seqf, *fseqf;
00179     long offset;
00180     struct oGROUP group;
00181     struct oFGROUP fgroup;
00182     struct Table table;
00183     REPLAY Rep;
00184 
00185     mm_file vidfile;
00186     float fps;
00187     double last_time;
00188     if (find_replay(&Rep, NULL, plr, num, Type) < 0)
00189         return;
00190 
00191     /** \note uses SEQ.DAT
00192      *  \note uses FSEQ.DAT
00193      */
00194     seqf = sOpen("SEQ.DAT", "rb", 0);
00195     fseqf = sOpen("FSEQ.DAT", "rb", 0);
00196 
00197     if (!seqf || !fseqf)
00198     {
00199         if (!seqf)
00200             fclose(seqf);
00201         if (!fseqf)
00202             fclose(fseqf);
00203         return;
00204     }
00205 
00206     WaitForMouseUp();
00207 
00208     DEBUG2("video sequence: %d segments", Rep.Qty);
00209     for (kk = 0; kk < Rep.Qty; kk++)
00210     {
00211         DEBUG3("playing segment %d: %d", kk, Rep.Off[kk]);
00212         if (Rep.Off[kk] < 1000)    //Specs: success seq
00213         {
00214             fseek(seqf, Rep.Off[kk] * sizeof_oGROUP, SEEK_SET);
00215             fread_oGROUP(&group, 1, seqf);
00216             max = group.ID[1] - '0';
00217             mode = 0;
00218         }
00219         else
00220         {                          //Specs: failure seq
00221             int j = 0;
00222             // MAX 50 Tables
00223             i = Rep.Off[kk] / 1000;
00224             j = Rep.Off[kk] % 1000;
00225             if (i == 0 || i == 50)
00226                 goto done;
00227             i--;                   //Specs: offset index klugge
00228             fseek(fseqf, i * sizeof_Table, SEEK_SET);
00229             fread_Table(&table, 1, fseqf);
00230             offset = table.foffset;
00231             fseek(fseqf, offset + j * sizeof_oFGROUP, SEEK_SET);
00232             fread_oFGROUP(&fgroup, 1, fseqf);
00233             mode = 1;
00234             max = fgroup.ID[1] - '0';
00235         };
00236 
00237         i = 0;
00238         keep_going = 1;
00239         //  update_map = 0;
00240         while (keep_going && i < max)
00241         {
00242             int frm_idx;
00243             char *seq_fname = NULL;
00244             char fname[20];
00245 
00246             if (mode == 1)         /* failure */
00247                 frm_idx = fgroup.oLIST[i].aIdx;
00248             else
00249                 frm_idx = group.oLIST[i].aIdx;
00250 
00251             /* here we should create YUV Overlay, but we can't use it on
00252              * pallettized surface, so we use a global Overlay initialized in
00253              * sdl.c. */
00254             seq_fname = seq_filename(frm_idx, mode);
00255             if (!seq_fname)
00256                 seq_fname = "(unknown)";
00257 
00258             /** \todo assumption on file extension */
00259             snprintf(fname, sizeof(fname), "%s.ogg", seq_fname);
00260 
00261             INFO2("opening video file `%s'", fname);
00262 
00263             if (mm_open_fp(&vidfile, sOpen(fname, "rb", FT_VIDEO)) <= 0)
00264                 goto done;
00265 
00266             /** \todo do not ignore width/height */
00267             if (mm_video_info(&vidfile, NULL, NULL, &fps) <= 0)
00268                 goto done;
00269 
00270             last_time = get_time();
00271 
00272             while (keep_going)
00273             {
00274                 video_rect.x = dx;
00275                 video_rect.y = dy;
00276                 video_rect.w = width;
00277                 video_rect.h = height;
00278 
00279                 screen_dirty = 1;
00280 
00281                 /** \todo track decoding time and adjust delays */
00282                 if (mm_decode_video(&vidfile, video_overlay) <= 0)
00283                     break;
00284 
00285                 if (bioskey(0) || grGetMouseButtons())
00286                     keep_going = 0;
00287 
00288                 /** \todo idle_loop is too inaccurate for this */
00289                 idle_loop_secs(1.0 / fps);
00290             }
00291 
00292             mm_close(&vidfile);
00293             i++;
00294         }
00295     }
00296   done:
00297     mm_close(&vidfile);
00298     video_rect.w = 0;
00299     video_rect.h = 0;
00300     fclose(fseqf);
00301     fclose(seqf);
00302     return;
00303 }
00304 
00305 void
00306 DispBaby(int x, int y, int loc, char neww)
00307 {
00308     int i;
00309     FILE *fin;
00310     GXHEADER boob;
00311     ui16 *bot, off = 0;
00312     long locl;
00313 
00314     off = 224;
00315 
00316     GV(&boob, 68, 46);
00317     bot = (ui16 *) boob.vptr;
00318 
00319     fin = sOpen("BABYPICX.CDR", "rb", 0);
00320     locl = (long) 1612 *loc;    // First Image
00321 
00322     fseek(fin, locl, SEEK_SET);
00323     for (i = 0; i < 48; i++)
00324         pal[off * 3 + i] = 0;
00325     if (neww)
00326         gxSetDisplayPalette(pal);
00327     fread(&pal[off * 3], 48, 1, fin);
00328     fread(boob.vptr, 1564, 1, fin);
00329     fclose(fin);
00330 
00331     for (i = 0; i < 782; i++)
00332     {
00333         bot[i + 782] = ((bot[i] & 0xF0F0) >> 4);
00334         bot[i] = (bot[i] & 0x0F0F);
00335     }
00336     for (i = 0; i < 1564; i++)
00337     {
00338         boob.vptr[i] += off;
00339         boob.vptr[1564 + i] += off;
00340     }
00341 
00342     gxPutImage(&boob, gxSET, x, y, 0);
00343     if (neww)
00344         gxSetDisplayPalette(pal);
00345     DV(&boob);
00346 
00347     return;
00348 }
00349 
00350 void
00351 AbzFrame(char plr, int num, int dx, int dy, int width, int height,
00352     char *Type, char mode)
00353 {
00354     int idx = 0;
00355     struct oGROUP grp;
00356     REPLAY Rep;
00357 
00358     /* force mode to zero */
00359     mode = 0;
00360 
00361     char fname[100];
00362     mm_file vidfile;
00363 
00364     memset(&grp, 0, sizeof grp);
00365 
00366     if (find_replay(&Rep, &grp, plr, num, Type) < 0)
00367         return;
00368 
00369     idx = grp.oLIST[0].aIdx;
00370 
00371     /* XXX use a generic function */
00372     snprintf(fname, sizeof(fname), "%s.ogg", seq_filename(idx, mode));
00373 
00374     INFO2("opening video file `%s'", fname);
00375     if (mm_open_fp(&vidfile, sOpen(fname, "rb", FT_VIDEO)) <= 0)
00376         return;
00377 
00378     if (mm_video_info(&vidfile, NULL, NULL, NULL) <= 0)
00379         goto done;
00380 
00381     if (mm_decode_video(&vidfile, video_overlay) <= 0)
00382         goto done;
00383 
00384     video_rect.x = dx;
00385     video_rect.y = dy;
00386     video_rect.w = width;
00387     video_rect.h = height;
00388 
00389   done:
00390     mm_close(&vidfile);
00391 }

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