// play demo from binary file ------------------------------------------------- // int Cmd_PlayBinaryDemoFile( char *command ) { //NOTE: //CONCOM: // play_command ::= 'play' <demo_name> // demo_name ::= "valid script name" ASSERT( command != NULL ); HANDLE_COMMAND_DOMAIN_SEP( command ); // split off argument (name of demo) char *demoname = strtok( command, " " ); if ( demoname == NULL ) { CON_AddLine( arg_missing ); return TRUE; } // check for too many arguments if ( strtok( NULL, " " ) != NULL ) { CON_AddLine( too_many_args ); return TRUE; } // exit if currently replaying if ( DEMO_BinaryReplayActive() ) { CON_AddLine( "demo replay already in progress." ); return TRUE; } // remember demo name for cut output SetDemoCutName( demoname ); // open demo file FILE *fp = DEMO_BinaryOpenDemo( demoname ); if ( fp == NULL ) { CON_AddLine( "demo file not found." ); return TRUE; } // read demo data as one big block if ( !DEMO_BinaryReadDemo( fp, TRUE, TRUE ) ) { SYS_fclose( fp ); return TRUE; } // close file since it has been read in its entirety SYS_fclose( fp ); // timedemo is allowed DEMO_EnableTimedemo(); // start loaded demo DEMO_BinaryStartDemo( TRUE, TRUE ); return TRUE; }
// fetch and store info from headers of all registered demos ------------------ // PRIVATE void CreateRegisteredDemoInfo() { for ( int cdem = 0; cdem < num_registered_demos; cdem++ ) { FILE *fp = DEMO_BinaryOpenDemo( registered_demo_names[ cdem ] ); if ( fp != NULL ) { DEMO_ParseDemoHeader( fp, cdem, FALSE ); SYS_fclose( fp ); } } }
// start binary demo replay from menu ----------------------------------------- // int DEMO_PlayFromMenu( const char *demoname ) { ASSERT( demoname != NULL ); // exit if currently replaying if ( DEMO_BinaryReplayActive() ) { return FALSE; } // remember demo name for cut output SetDemoCutName( demoname ); // open demo file FILE *fp = DEMO_BinaryOpenDemo( demoname ); if ( fp == NULL ) { return FALSE; } // read demo data as one big block if ( !DEMO_BinaryReadDemo( fp, TRUE, TRUE ) ) { SYS_fclose( fp ); return FALSE; } // close file since it has been read in its entirety SYS_fclose( fp ); // timedemo is allowed DEMO_EnableTimedemo(); // start loaded demo DEMO_BinaryStartDemo( FALSE, TRUE ); // no user interference allowed DEMO_DisableUserInput(); return TRUE; }
// play demo from binary file behind menu ------------------------------------- // int DEMO_PlayBehindMenu( const char *demoname ) { ASSERT( demoname != NULL ); // only possible if we are not yet connected if ( NetConnected ) return FALSE; // exit if currently replaying if ( DEMO_BinaryReplayActive() ) return FALSE; // remember demo name for cut output SetDemoCutName( demoname ); // open demo file FILE *fp = DEMO_BinaryOpenDemo( demoname ); if ( fp == NULL ) { return FALSE; } // read demo data as one big block if ( !DEMO_BinaryReadDemo( fp, FALSE, FALSE ) ) { SYS_fclose( fp ); return FALSE; } // close file since it has been read in its entirety SYS_fclose( fp ); // timedemo is not allowed DEMO_DisableTimedemo(); // start loaded demo DEMO_BinaryStartDemo( FALSE, FALSE ); return TRUE; }
// read palette files into buffer --------------------------------------------- // PRIVATE void ReadPalettes() { // exit if nothing to read if ( NumLoadedPalettes == 0 ) PANIC( "no palette defined." ); if ( ( PaletteMem = (char *) ALLOCMEM( PALETTE_SIZE * NumLoadedPalettes ) ) == NULL ) OUTOFMEM( no_palette_mem ); if ( display_info ) { MSGPUT( "Loading palettes" ); if ( show_palettes_loaded ) { MSGOUT( ":\n" ); } else { MSGPUT( "..." ); } } // load all palettes size_t readofs = 0; for ( int pid = 0; pid < NumLoadedPalettes; pid++ ) { if ( display_info && !show_palettes_loaded ) MSGPUT( "." ); FILE *fp = SYS_fopen( palette_fnames[ pid ], "rb" ); if ( fp == NULL ) FERROR( palette_not_found, palette_fnames[ pid ] ); if ( display_info && show_palettes_loaded ) { MSGOUT( "loading \"%s\" (palette)\n", palette_fnames[ pid ] ); } size_t bytesread = SYS_fread( PaletteMem + readofs, 1, PALETTE_SIZE, fp ); if ( bytesread != PALETTE_SIZE ) FERROR( palette_readerror, palette_fnames[ pid ] ); readofs += PALETTE_SIZE; SYS_fclose( fp ); } if ( display_info ) { MSGOUT( "done.\n" ); } }
// console command for loading a level ---------------------------------------- // PRIVATE int Cmd_LEVEL_LOAD( char *paramstr ) { //NOTE: //CONCOM: // level_load_command ::= 'level.load' levelname_spec // levelname_spec ::= <string> ASSERT( paramstr != NULL ); HANDLE_COMMAND_DOMAIN_SEP( paramstr ); const char *levelname = GetStringBehindCommand( paramstr, FALSE ); if ( levelname == NULL ) { CON_AddLine( "no level name specified" ); return TRUE; } // must be done to ensure the file can be found independently of // whether it is read from a package or from a real directory char *path = SYSs_ProcessPathString( (char *) levelname ); // check whether the file exists FILE* fp = SYS_fopen( path, "r" ); if ( fp == NULL ) { char szBuffer[ 256 ]; sprintf( szBuffer, "level file %s could not be found", levelname ); CON_AddLine( szBuffer ); return TRUE; } else { SYS_fclose( fp ); } // load the level LVL_LoadLevel( levelname ); return TRUE; }
// play specified stream file ------------------------------------------------- // int AUDs_PlayAudioStream( char *fname ) { if (SoundDisabled) return 1; ASSERT(fname!=NULL); if (Mix_PlayingMusic()) Mix_HaltMusic(); if (music != NULL) { Mix_FreeMusic(music); FREEMEM(tmp_music_buffer); tmp_music_buffer = NULL; music = NULL; } // because SDL_RWFromFP doesn't work cross platform, we need // to get a little bit kinky // set up a buffer for the file size_t tmp_music_size = 0; // get the size of this sample tmp_music_size = SYS_GetFileLength(fname); if (tmp_music_size <= 0) { return 1; // return on error } // alloc space for the buffer if (tmp_music_buffer != NULL) { printf("ERROR: Shouldn't be this far without being cleaned up previously\n"); FREEMEM(tmp_music_buffer); tmp_music_buffer = NULL; } tmp_music_buffer = (char *)ALLOCMEM(tmp_music_size + 1); // open the sample file FILE *musicfp = SYS_fopen(fname, "rb"); if (musicfp == NULL) return 1; // read the file into the temp_sample_buffer int read_rc = SYS_fread((void *)tmp_music_buffer, 1, tmp_music_size, musicfp); if(read_rc <= 0) { MSGOUT("ERROR: Error reading music %s.", fname); return FALSE; } SDL_RWops *musicrwops = SDL_RWFromMem((void *)tmp_music_buffer, tmp_music_size); music = Mix_LoadMUS_RW(musicrwops, 1); //MSGOUT(" PlayAudioStream() with %s ", fname); if (music == NULL) { printf("Mix_LoadMUS(\"%s\"): %s\n", fname, Mix_GetError()); // this might be a critical error... FREEMEM(tmp_music_buffer); tmp_music_buffer = NULL; return 1; } Mix_VolumeMusic(128); if (music != NULL) { Mix_PlayMusic(music, 0); } //Pick up your your toys when you finish SYS_fclose(musicfp); return 1; }
int AUDs_LoadWaveFile( int num ) { if (SoundDisabled) return AUD_RETURN_SUCCESS; ASSERT( ( num >= 0 ) && ( num < MAX_SAMPLES ) ); if ( !SoundAvailable ) return AUD_RETURN_SUCCESS; // read the sample and assign the list entry sample_s* pSample = SND_ReadSample( &SampleInfo[ num ] ); SND_ConvertRate( pSample, aud_sample_quality ); // because SDL_RWFromFP doesn't work cross platform, we need // to get a little bit kinky // set up a buffer for the file char *tmp_sample_buffer = NULL; size_t tmp_sample_size = 0; // get the size of this sample tmp_sample_size = SYS_GetFileLength(SampleInfo[num].file); if (tmp_sample_size <= 0) { return FALSE; // return on error } // alloc space for the buffer tmp_sample_buffer = (char *)ALLOCMEM(tmp_sample_size + 1); // open the sample file FILE *wave = SYS_fopen(SampleInfo[num].file, "rb"); if (wave == NULL) return FALSE; // read the file into the temp_sample_buffer int read_rc = SYS_fread((void *)tmp_sample_buffer, 1, tmp_sample_size, wave); if (read_rc <= 0) { MSGOUT("ERROR: Error reading sample %s.", SampleInfo[num].file); return FALSE; } SDL_RWops *waverwops = SDL_RWFromMem((void *)tmp_sample_buffer, tmp_sample_size); snd_chunks[num] = Mix_LoadWAV_RW(waverwops, 0); SYS_fclose(wave); FREEMEM( tmp_sample_buffer ); FREEMEM( pSample->samplebuffer ); pSample->samplebuffer = NULL; #ifdef SHOW_SAMPLE_LOADING_INFO MSGOUT("loaded %-12s to slot %03d: rate: %05d, numch: %02d, type: %s, bytes: %07d", SampleInfo[ num ].file, num, pSample->samplerate, pSample->numchannels, ( pSample->samplesize == 8 ) ? "8" : "16" , pSample->samplebytes ); #endif // SHOW_SAMPLE_LOADING_INFO // store the slot submitted to the play functions SampleInfo[ num ].samplepointer = (char *)num; //CAVEAT: for now we store the number of refframes in size SampleInfo[ num ].size = FLOAT2INT( (float) FRAME_MEASURE_TIMEBASE * (float) pSample->samplebytes / (float) ( pSample->samplerate * pSample->alignment ) + 0.5f ); FREEMEM( pSample ); return AUD_RETURN_SUCCESS; }
// read needed textures into memory ------------------------------------------- // PRIVATE void ReadTextures() { // exit if nothing to read if ( NumLoadedTextures == 0 ) return; if ( display_info ) { MSGPUT( "Loading textures" ); if ( show_textures_loaded ) { MSGOUT( ":\n" ); } else { MSGPUT( "..." ); } } // get filesizes of textures to allocate mem in one piece size_t texmemsize = 0; int tid = 0; for ( tid = 0; tid < NumLoadedTextures; tid++ ) { ssize_t siz = SYS_GetFileLength( TextureInfo[ tid ].file ); if ( siz == -1 ) FERROR( texture_not_found, TextureInfo[ tid ].file ); texmemsize += siz; } // allocate texture buffer TextureMem = (char *) ALLOCMEM( texmemsize + sizeof( TextureMap ) * NumLoadedTextures ); if ( TextureMem == NULL ) OUTOFMEM( no_texture_mem ); char *texreadpo = TextureMem + sizeof( TextureMap ) * NumLoadedTextures; TextureMap *controlpo = (TextureMap *) TextureMem; size_t stillfree = texmemsize; // read in texturedata and fill control structures for ( tid = 0; tid < NumLoadedTextures; tid++ ) { if ( ( ( tid & 0x03 ) == 0 ) && display_info && !show_textures_loaded ) MSGPUT( "." ); FILE *fp = SYS_fopen( TextureInfo[ tid ].file, "rb" ); if ( fp == NULL ) FERROR( texture_not_found, TextureInfo[ tid ].file ); if ( display_info && show_textures_loaded ) { MSGOUT( "loading \"%s\" (texture)\n", TextureInfo[ tid ].file ); } size_t bytesread = SYS_fread( texreadpo, 1, stillfree, fp ); if ( bytesread == 0 ) FERROR( texture_readerror, TextureInfo[ tid ].file ); // if geometry not explicitly specified read it from header if ( ( TextureInfo[ tid ].width == -1 ) || ( TextureInfo[ tid ].height == -1 ) ) { TexHeader *header = (TexHeader *) texreadpo; // swap endianness of TexHeader SYS_SwapTexHeader( header ); if ( stricmp( header->signature, TEX_SIGNATURE ) != 0 ) PERROR( tex_sig_invalid ); if ( header->version < REQUIRED_TEX_VERSION ) PERROR( tex_ver_invalid ); TextureInfo[ tid ].width = header->width; TextureInfo[ tid ].height = header->height; stillfree -= sizeof( TexHeader ); bytesread -= sizeof( TexHeader ); texreadpo += sizeof( TexHeader ); } // set additional texture info fields TextureInfo[ tid ].flags = TEXINFOFLAG_NONE; // fill texture control structure ----------------------------------- controlpo->Width = CeilPow2Exp( TextureInfo[ tid ].width ); controlpo->Height = CeilPow2Exp( TextureInfo[ tid ].height ); // check validity of texture geometry if ( ( controlpo->Width < TEX_WIDTH_POW2_MIN ) || ( controlpo->Width > TEX_WIDTH_POW2_MAX ) || ( controlpo->Height < TEX_HEIGHT_POW2_MIN ) || ( controlpo->Height > TEX_HEIGHT_POW2_MAX ) || ( controlpo->Width < controlpo->Height ) || // check texture's aspect ratio ( ( controlpo->Width - controlpo->Height ) > 1 ) ) { SYS_fclose( fp ); PERROR( "texture dimension not allowed (texture %d).", tid + 1 ); } // calculate geometry code used by texture mapper dword geom = ( controlpo->Width - TEX_WIDTH_POW2_MIN ) * 2; if ( controlpo->Width == controlpo->Height ) geom++; controlpo->Geometry = geom - 1; // set pointers to texture bitmap and name controlpo->BitMap = texreadpo; controlpo->TexMapName = TextureInfo[ tid ].name; // set additional texture fields controlpo->Flags = TEXFLG_NONE; controlpo->LOD_small = 0; controlpo->LOD_large = 0; controlpo->TexPalette = NULL; controlpo->TexelFormat = TEXFMT_STANDARD; // store pointer to texture in texture info table TextureInfo[ tid ].texpointer = controlpo; TextureInfo[ tid ].standardbitmap = controlpo->BitMap; stillfree -= bytesread; texreadpo += bytesread; controlpo++; SYS_fclose( fp ); } if ( display_info ) { MSGOUT( "done.\n" ); } }
// read bitmaps and charsets into memory -------------------------------------- // PRIVATE void ReadBitmapsAndCharsets() { // exit if nothing to read if ( ( NumLoadedBitmaps == 0 ) && ( NumLoadedCharsets == 0 ) ) return; // print message if ( display_info ) { MSGPUT( "Loading bitmaps and charsets" ); if ( show_bitmaps_loaded ) { MSGOUT( ":\n" ); } else { MSGPUT( "..." ); } } // get filesizes of bitmap files size_t bitmmemsize = 0; int bmid = 0; for ( bmid = 0; bmid < NumLoadedBitmaps; bmid++ ) { ssize_t siz = SYS_GetFileLength( BitmapInfo[ bmid ].file ); if ( siz == -1 ) FERROR( bitmap_not_found, BitmapInfo[ bmid ].file ); bitmmemsize += siz; } // get filesizes of charset files int ftid = 0; for ( ftid = 0; ftid < NumLoadedCharsets; ftid++ ) { ssize_t siz; // if geometry not set interpret specified file as info-file if ( CharsetInfo[ ftid ].width == -1 ) { siz = SYS_GetFileLength( CharsetInfo[ ftid ].file ); if ( siz == -1 ) FERROR( fontinfo_not_found, CharsetInfo[ ftid ].file ); CopyFileNameAlterExt( paste_str, CharsetInfo[ ftid ].file, FONT_EXTENSION ); ssize_t gsiz = SYS_GetFileLength( paste_str ); if ( gsiz == -1 ) FERROR( font_not_found, paste_str ); siz += gsiz; } else { siz = SYS_GetFileLength( CharsetInfo[ ftid ].file ); if ( siz == -1 ) FERROR( font_not_found, CharsetInfo[ ftid ].file ); } bitmmemsize += siz; } // allocate buffer for bitmaps and charsets if ( ( BitmapMem = (char *) ALLOCMEM( bitmmemsize ) ) == NULL ) OUTOFMEM( no_bitmap_mem ); char *bitmreadpo = BitmapMem; size_t stillfree = bitmmemsize; // read in raw bitmap files ----------------------------------------------- for ( bmid = 0; bmid < NumLoadedBitmaps; bmid++ ) { if ( ( ( bmid & 0x03 ) == 0 ) && display_info && !show_bitmaps_loaded ) MSGPUT( "." ); FILE *fp = SYS_fopen( BitmapInfo[ bmid ].file, "rb" ); if ( fp == NULL ) FERROR( bitmap_not_found, BitmapInfo[ bmid ].file ); if ( display_info && show_bitmaps_loaded ) MSGOUT( "loading \"%s\" (bitmap)\n", BitmapInfo[ bmid ].file ); ssize_t bytesread = SYS_fread( bitmreadpo, 1, stillfree, fp ); if ( bytesread == 0 ) FERROR( bitmap_readerror, BitmapInfo[ bmid ].file ); // if width and height not already set header must be present if ( BitmapInfo[ bmid ].width == -1 ) { BdtHeader *header = (BdtHeader *) bitmreadpo; // swap endianness of BdtHeader SYS_SwapBdtHeader( header ); if ( stricmp( header->signature, BDT_SIGNATURE ) != 0 ) PERROR( bdt_sig_invalid ); if ( header->version < REQUIRED_BDT_VERSION ) PERROR( bdt_ver_invalid ); // store width and height BitmapInfo[ bmid ].width = header->width; BitmapInfo[ bmid ].height = header->height; // store pointer to bitmap into control structure (header excluded) BitmapInfo[ bmid ].bitmappointer = (char *) ( header + 1 ); } else { // store pointer to bitmap into control structure (was raw format) BitmapInfo[ bmid ].bitmappointer = bitmreadpo; } // store pointer to originally loaded data (needed for different color depths) BitmapInfo[ bmid ].loadeddata = BitmapInfo[ bmid ].bitmappointer; // set bitmap name (static storage!) ASSERT( num_default_bitmaps == BM_CONTROLFILE_NUMBER ); ASSERT( bmid < num_default_bitmaps ); BitmapInfo[ bmid ].name = (char *) default_bitmap_names[ bmid ]; stillfree -= bytesread; bitmreadpo += bytesread; SYS_fclose( fp ); } // read in raw charset data ----------------------------------------------- int charset_datasize = 0; for ( ftid = 0; ftid < NumLoadedCharsets; ftid++ ) { if ( ( ( ftid & 0x03 ) == 0 ) && display_info && !show_bitmaps_loaded ) MSGPUT( "." ); if ( CharsetInfo[ ftid ].srcwidth == -1 ) { FILE *fp = SYS_fopen( CharsetInfo[ ftid ].file, "rb" ); if ( fp == NULL ) FERROR( fontinfo_not_found, CharsetInfo[ ftid ].file ); if ( display_info && show_bitmaps_loaded ) MSGOUT( "loading \"%s\" (fontinfo)\n", CharsetInfo[ ftid ].file ); size_t gsiz = SYS_fread( bitmreadpo, 1, stillfree, fp ); if ( gsiz < sizeof( PfgHeader ) + 8 ) FERROR( fontinfo_readerror, CharsetInfo[ ftid ].file ); PfgHeader *header = (PfgHeader *) bitmreadpo; // swap endianness of PfgHeader SYS_SwapPfgHeader( header ); if ( stricmp( header->signature, PFG_SIGNATURE ) != 0 ) PERROR( pfg_sig_invalid ); if ( header->version < REQUIRED_PFG_VERSION ) PERROR( pfg_ver_invalid ); CharsetInfo[ ftid ].srcwidth = header->srcwidth; CharsetInfo[ ftid ].width = header->width; CharsetInfo[ ftid ].height = header->height; // ensure table is multiple of four in length size_t geomsiz = gsiz - sizeof( PfgHeader ) - 4; if ( ( geomsiz & 0x03 ) != 0x00 ) FERROR( pfg_corrupted, CharsetInfo[ ftid ].file ); // create pointer to table excluding startchar dword *geomtab = (dword *)( bitmreadpo + sizeof( PfgHeader ) + 4 ); //TODO: //CAVEAT: //NOTE: // the font-type determination assumes that exactly // those fonts with width==height are fixed-size fonts. // determine whether fixed-size font int fonttype = ( header->width == header->height ); // swap endianness of geometry table SYS_SwapPfgTable( fonttype, geomtab, geomsiz ); // geometry pointer must point one dword past the geometry table!! CharsetInfo[ ftid ].geompointer = geomtab; bitmreadpo += gsiz; stillfree -= gsiz; SYS_fclose( fp ); CopyFileNameAlterExt( paste_str, CharsetInfo[ ftid ].file, FONT_EXTENSION ); if ( ( fp = SYS_fopen( paste_str, "rb" ) ) == NULL ) FERROR( font_not_found, paste_str ); if ( display_info && show_bitmaps_loaded ) MSGOUT( "loading \"%s\" (font)\n", paste_str ); size_t bytesread = SYS_fread( bitmreadpo, 1, stillfree, fp ); if ( bytesread == 0 ) FERROR( font_readerror, paste_str ); FntHeader *dheader = (FntHeader *) bitmreadpo; // swap endianness of FntHeader SYS_SwapFntHeader( dheader ); if ( stricmp( dheader->signature, FNT_SIGNATURE ) != 0 ) PERROR( fnt_sig_invalid ); if ( dheader->version < REQUIRED_FNT_VERSION ) PERROR( fnt_ver_invalid ); if ( dheader->width != CharsetInfo[ ftid ].srcwidth ) PERROR( fnt_inconsistency ); CharsetInfo[ ftid ].charsetpointer = bitmreadpo + sizeof( FntHeader ); bitmreadpo += bytesread; stillfree -= bytesread; SYS_fclose( fp ); charset_datasize = bytesread - sizeof( FntHeader ); } else { FILE *fp = SYS_fopen( CharsetInfo[ ftid ].file, "rb" ); if ( fp == NULL ) FERROR( font_not_found, CharsetInfo[ ftid ].file ); if ( display_info && show_bitmaps_loaded ) MSGOUT( "loading \"%s\" (font)\n", CharsetInfo[ ftid ].file ); size_t bytesread = SYS_fread( bitmreadpo, 1, stillfree, fp ); if ( bytesread == 0 ) FERROR( font_readerror, CharsetInfo[ ftid ].file ); CharsetInfo[ ftid ].charsetpointer = bitmreadpo; // set pointer to geometry data //FIXME: [momentan noch pfusch!!] if ( ftid == 1 ) CharsetInfo[ ftid ].geompointer = Char04x09Geom; else if ( ftid == 2 ) CharsetInfo[ ftid ].geompointer = Char08x08Geom; else if ( ftid == 4 ) CharsetInfo[ ftid ].geompointer = CharGoldGeom; else CharsetInfo[ ftid ].geompointer = Char16x16Geom; stillfree -= bytesread; bitmreadpo += bytesread; SYS_fclose( fp ); charset_datasize = bytesread; } // store pointer to originally loaded data (needed for different color depths) CharsetInfo[ ftid ].loadeddata = CharsetInfo[ ftid ].charsetpointer; ASSERT( CharsetInfo[ ftid ].fonttexture == NULL ); // store size of data block CharsetInfo[ ftid ].datasize = charset_datasize; // set additional info fields CharsetInfo[ ftid ].flags = 0x00000000; } if ( display_info ) { MSGOUT( "done.\n" ); } }
// parse control file --------------------------------------------------------- // PRIVATE void ParseCtrlFile( dword flags ) { int i; char* remptr; char line[ LINE_LENGTH_MAX ]; if ( flags & PARSE_TEXTURES ) NumLoadedTextures = 0; if ( flags & PARSE_OBJECTS ) NumLoadedObjects = 0; if ( flags & PARSE_BITMAPS ) NumLoadedBitmaps = 0; if ( flags & PARSE_CHARSETS ) NumLoadedCharsets = 0; if ( flags & PARSE_SAMPLES ) NumLoadedSamples = 0; if ( flags & PARSE_SONGS ) NumLoadedSongs = 0; if ( flags & PARSE_PALETTES ) NumLoadedPalettes = 0; FILE *fp = SYS_fopen( ctrl_file_name, "r" ); if ( fp == NULL ) { SERROR( "Controlfile error" ); } if ( display_info ) { MSGPUT( "Parsing control file..." ); } // parse sections --------------------------------------------- int linecount = 0; while ( SYS_fgets( line, LINE_LENGTH_MAX, fp ) != NULL ) { if ( ( ( linecount++ & 0x0f ) == 0 ) && display_info ) MSGPUT( "." ); char *scanptr = strtok( line, "/, \t\n\r" ); if ( scanptr == NULL ) continue; else if ( *scanptr == ';' ) continue; else if ( strnicmp( scanptr, "<end", 4 ) == 0 ) break; else if ( *scanptr == '#' ) { if ( stricmp( scanptr, _palette_str ) == 0 ) section = _palette; else if ( stricmp( scanptr, _textures_str ) == 0 ) section = _textures; else if ( stricmp( scanptr, _objects_str ) == 0 ) section = _objects; else if ( stricmp( scanptr, _bitmaps_str ) == 0 ) section = _bitmaps; else if ( stricmp( scanptr, _charsets_str ) == 0 ) section = _charsets; else if ( stricmp( scanptr, _samples_str ) == 0 ) section = _samples; else if ( stricmp( scanptr, _songs_str ) == 0 ) section = _songs; else if ( stricmp( scanptr, _comment_str ) == 0 ) section = _comment; else { SYS_fclose( fp ); PERROR( "Control file-parser: " "[undefined section name]: %s.", scanptr ); } } else switch ( section ) { // texturing data ----------------------------------- case _textures : if ( flags & PARSE_TEXTURES ) { int txwidth, txheight; if ( *scanptr != '\"' ) { txwidth = strtol( scanptr, &remptr, 10 ); if ( *remptr != '\0' ) ParseError( section ); if ( ( scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL ) ParseError( section ); txheight = strtol( scanptr, &remptr, 10 ); if ( *remptr != '\0' ) ParseError( section ); while ( *scanptr++ != '\0' ) {} while ( ( *scanptr == ' ' ) || ( *scanptr == '\t' ) ) scanptr++; } else { txwidth = -1; // fill in later from txheight = -1; // texture file-header remptr = scanptr; while ( *remptr++ != '\0' ) {} if ( *remptr == '\0' ) ParseError( section ); *--remptr = ' '; } if ( ( scanptr = strtok( scanptr, "\"" ) ) == NULL ) ParseError( section ); SETTABENTRY_NAME( TextureInfo, NumLoadedTextures ); if ( ( scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL ) ParseError( section ); SETTABENTRY_FILENAME( TextureInfo, NumLoadedTextures ); TextureInfo[ NumLoadedTextures ].width = txwidth; TextureInfo[ NumLoadedTextures ].height = txheight; if ( ++NumLoadedTextures >= MAX_TEXTURES ) PANIC( "too many textures." ); } break; // object data files -------------------------------- case _objects : if ( flags & PARSE_OBJECTS ) { int objnum = strtol( scanptr, &remptr, 10 ); if ( *remptr != '\0' ) ParseError( section ); while ( *scanptr++ != '\0' ) {} while ( ( *scanptr == ' ' ) || ( *scanptr == '\t' ) ) scanptr++; if ( ( scanptr = strtok( scanptr, "\"" ) ) == NULL ) ParseError( section ); SETTABENTRY_NAME( ObjectInfo, NumLoadedObjects ); if ( ( scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL ) ParseError( section ); int objtype = -1; for ( i = 0; i < NUM_DISTINCT_OBJTYPES; i++ ) { if ( stricmp( scanptr, objtype_name[ i ] ) == 0 ) { objtype = i; break; } } if ( ( objtype < 0 ) || ( objtype >= NUM_DISTINCT_OBJTYPES ) ) ParseError( section ); ObjectInfo[ NumLoadedObjects ].type = objtype_id[ objtype ]; if ( ( scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL ) ParseError( section ); SETTABENTRY_FILENAME( ObjectInfo, NumLoadedObjects ); ObjectInfo[ NumLoadedObjects ].lodinfo = NULL; if ( ++NumLoadedObjects >= MAX_DISTINCT_OBJCLASSES ) PANIC( "too many object classes." ); } break; // bitmap files ------------------------------------- case _bitmaps : if ( flags & PARSE_BITMAPS ) { int bitmapnum = strtol( scanptr, &remptr, 10 ); if ( *remptr != '\0' ) ParseError( section ); if ( ( scanptr = strtok( NULL, "x,/ \t\n\r" ) ) == NULL ) ParseError( section ); if ( isdigit( *scanptr ) ) { BitmapInfo[ NumLoadedBitmaps ].width = strtol( scanptr, &remptr, 10 ); if ( *remptr != '\0' ) ParseError( section ); if ( ( scanptr = strtok( NULL, "x,/ \t\n\r" ) ) == NULL ) ParseError( section ); BitmapInfo[ NumLoadedBitmaps ].height = strtol( scanptr, &remptr, 10 ); if ( *remptr != '\0' ) ParseError( section ); if ( ( scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL ) ParseError( section ); } else { BitmapInfo[ NumLoadedBitmaps ].width = -1; // fill in later from BitmapInfo[ NumLoadedBitmaps ].height = -1; // bitmapfile header } SETTABENTRY_FILENAME( BitmapInfo, NumLoadedBitmaps ); BitmapInfo[ NumLoadedBitmaps ].bitmappointer = NULL; if ( ++NumLoadedBitmaps >= MAX_BITMAPS ) PANIC( "too many bitmaps." ); } break; // charset data ------------------------------------- case _charsets : if ( flags & PARSE_CHARSETS ) { int charsetnum = strtol( scanptr, &remptr, 10 ); if ( *remptr != '\0' ) ParseError( section ); if ( ( scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL ) ParseError( section ); if ( isdigit( *scanptr ) ) { CharsetInfo[ NumLoadedCharsets ].srcwidth = strtol( scanptr, &remptr, 10 ); if ( *remptr != '\0' ) ParseError( section ); if ( ( scanptr = strtok( NULL, "x,/ \t\n\r" ) ) == NULL ) ParseError( section ); CharsetInfo[ NumLoadedCharsets ].width = strtol( scanptr, &remptr, 10 ); if ( *remptr != '\0' ) ParseError( section ); if ( ( scanptr = strtok( NULL, "x,/ \t\n\r" ) ) == NULL ) ParseError( section ); CharsetInfo[ NumLoadedCharsets ].height = strtol( scanptr, &remptr, 10 ); if ( *remptr != '\0' ) ParseError( section ); if ( ( scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL ) ParseError( section ); } else { CharsetInfo[ NumLoadedCharsets ].srcwidth = -1; // fill in later CharsetInfo[ NumLoadedCharsets ].width = -1; // from font-info CharsetInfo[ NumLoadedCharsets ].height = -1; // file } SETTABENTRY_FILENAME( CharsetInfo, NumLoadedCharsets ); CharsetInfo[ NumLoadedCharsets ].charsetpointer = NULL; CharsetInfo[ NumLoadedCharsets ].fonttexture = NULL; if ( ++NumLoadedCharsets >= MAX_CHARSETS ) PANIC( "too many charsets." ); } break; // sample data -------------------------------------- case _samples: if ( flags & PARSE_SAMPLES ) { int samplenum = strtol( scanptr, &remptr, 10 ); if ( *remptr != '\0' ) ParseError( section ); // defaults SampleInfo[ NumLoadedSamples ].samplepointer = NULL; SampleInfo[ NumLoadedSamples ].flags = 0; SampleInfo[ NumLoadedSamples ].stereolevel = 0; SampleInfo[ NumLoadedSamples ].volume = AUD_MAX_VOLUME; SampleInfo[ NumLoadedSamples ].samplefreq = 0; SampleInfo[ NumLoadedSamples ].stdfreq = 44100.0f; while ( *scanptr++ != '\0' ) {} if ( isdigit( *scanptr ) ) { if ( ( scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL ) ParseError( section ); float stdfreq = strtod( scanptr, &remptr ); if ( *remptr != '\0' ) ParseError( section ); SampleInfo[ NumLoadedSamples ].stdfreq = stdfreq; while ( *scanptr++ != '\0' ) {} } while ( ( *scanptr == ' ' ) || ( *scanptr == '\t' ) ) scanptr++; if ( ( scanptr = strtok( scanptr, "\"" ) ) == NULL ) ParseError( section ); SETTABENTRY_NAME( SampleInfo, NumLoadedSamples ); if ( ( scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL ) ParseError( section ); SETTABENTRY_FILENAME( SampleInfo, NumLoadedSamples ); if ( ++NumLoadedSamples >= MAX_SAMPLES ) PANIC( "too many samples." ); } break; // song data ---------------------------------------- case _songs: if ( flags & PARSE_SONGS ) { int songnum = strtol( scanptr, &remptr, 10 ); if ( *remptr != '\0' ) ParseError( section ); while ( *scanptr++ != '\0' ) {} while ( ( *scanptr == ' ' ) || ( *scanptr == '\t' ) ) scanptr++; if ( ( scanptr = strtok( scanptr, "\"" ) ) == NULL ) ParseError( section ); SETTABENTRY_NAME( SongInfo, NumLoadedSongs ); if ( ( scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL ) ParseError( section ); SETTABENTRY_FILENAME( SongInfo, NumLoadedSongs ); SongInfo[ NumLoadedSongs ].songpointer = NULL; if ( ++NumLoadedSongs >= MAX_SONGS ) PANIC( "too many songs." ); } break; // filenames of palette files ----------------------- case _palette : if ( flags & PARSE_PALETTES ) { ASSERT( palette_fnames[ NumLoadedPalettes ] == NULL ); palette_fnames[ NumLoadedPalettes ] = (char *) ALLOCMEM( strlen( scanptr ) + 1 ); ASSERT( palette_fnames[ NumLoadedPalettes ] != NULL ); strcpy( palette_fnames[ NumLoadedPalettes ], scanptr ); if ( ++NumLoadedPalettes >= MAX_PALETTES ) PANIC( "too many palettes." ); } break; default: break; } } SYS_fclose( fp ); if ( display_info ) { MSGOUT( "done.\n" ); } }
// read sample data into buffer ----------------------------------------------- // PRIVATE void ReadSamples() { #ifdef SAMPLES_MUST_BE_PRELOADED // exit if nothing to read if ( ( NumLoadedSamples == 0 ) && ( NumLoadedSongs == 0 ) ) return; if ( display_info ) { MSGPUT( "Loading sound data" ); if ( show_samples_loaded ) { MSGOUT( ":\n" ); } else { MSGPUT( "..." ); } } // get filesizes of samples to allocate mem in one piece size_t samplememsize = 0; for ( int i = 0; i < NumLoadedSamples; i++ ) { size_t = SYS_GetFileLength( SampleInfo[ i ].file ); if ( siz == -1 ) FERROR( sample_not_found, SampleInfo[ i ].file ); samplememsize += siz; } #ifndef DISABLE_SONGS // get filesizes of songs to allocate mem in one piece together with samples for ( i = 0; i < NumLoadedSongs; i++ ) { size_t = SYS_GetFileLength( SongInfo[ i ].file ); if ( siz == -1 ) FERROR( song_not_found, SongInfo[ i ].file ); samplememsize += siz; } #endif // allocate sample buffer (also used for songdata) if ( ( SampleMem = (char *) ALLOCMEM( samplememsize ) ) == NULL ) OUTOFMEM( no_sample_mem ); char *samplereadpo = SampleMem; size_t stillfree = samplememsize; // read in sample data for ( i = 0; i < NumLoadedSamples; i++ ) { if ( ( ( i & 0x01 ) == 0 ) && display_info && !show_samples_loaded ) MSGPUT( "." ); FILE *fp = SYS_fopen( SampleInfo[ i ].file, "rb" ); if ( fp == NULL ) FERROR( sample_not_found, SampleInfo[ i ].file ); if ( display_info && show_samples_loaded ) MSGOUT( "loading \"%s\" (sample)\n", SampleInfo[ i ].file ); size_t bytesread = SYS_fread( samplereadpo, 1, stillfree, fp ); if ( bytesread == 0 ) FERROR( sample_readerror, SampleInfo[ i ].file ); // store pointer to sample into control structure ------------ SampleInfo[ i ].samplepointer = samplereadpo; SampleInfo[ i ].size = bytesread; stillfree -= bytesread; samplereadpo += bytesread; SYS_fclose( fp ); } #ifndef DISABLE_SONGS // read in song data for ( i = 0; i < NumLoadedSongs; i++ ) { if ( ( ( i & 0x01 ) == 0 ) && display_info && !show_samples_loaded ) MSGPUT( "." ); FILE *fp = SYS_fopen( SongInfo[ i ].file, "rb" ); if ( fp == NULL ) FERROR( song_not_found, SongInfo[ i ].file ); if ( display_info && show_samples_loaded ) MSGOUT( "loading \"%s\" (song)\n", SongInfo[ i ].file ); size_t bytesread = SYS_fread( samplereadpo, 1, stillfree, fp ); if ( bytesread == 0 ) FERROR( song_readerror, SongInfo[ i ].file ); // store pointer to song into control structure -------------- SongInfo[ i ].songpointer = samplereadpo; stillfree -= bytesread; samplereadpo += bytesread; SYS_fclose( fp ); } #endif if ( display_info ) { MSGOUT( "done.\n" ); } #endif }