예제 #1
0
파일: rts.c 프로젝트: SilkyPantsDan/eduke32
/*
= RTS_AddFile
=
= All files are optional, but at least one file must be found
= Files with a .rts extension are wadlink files with multiple lumps
= Other files are single lumps with the base filename for the lump name
*/
static int32_t RTS_AddFile(const char *filename)
{
    wadinfo_t  header;
    int32_t i, handle, length, startlump;
    filelump_t *fileinfo, *fileinfoo;

    // read the entire file in
    //      FIXME: shared opens

    handle = kopen4loadfrommod(filename, 0);
    if (handle < 0)
    {
        initprintf("RTS file \"%s\" was not found\n",filename);
        return -1;
    }

    startlump = rts_numlumps;

    // WAD file
    i = kread(handle, &header, sizeof(header));
    if (i != sizeof(header) || Bmemcmp(header.identification, "IWAD", 4))
    {
        initprintf("RTS file \"%s\" too short or doesn't have IWAD id\n", filename);
        kclose(handle);
        return -1;
    }

    header.numlumps = B_LITTLE32(header.numlumps);
    header.infotableofs = B_LITTLE32(header.infotableofs);

    length = header.numlumps*sizeof(filelump_t);
    fileinfo = fileinfoo = (filelump_t *)Xmalloc(length);

    klseek(handle, header.infotableofs, SEEK_SET);
    kread(handle, fileinfo, length);

    {
        lumpinfo_t *lump_p = (lumpinfo_t *)Xrealloc(
            rts_lumpinfo, (rts_numlumps + header.numlumps)*sizeof(lumpinfo_t));

        rts_lumpinfo = lump_p;
    }

    rts_numlumps += header.numlumps;

    for (i=startlump; i<rts_numlumps; i++, fileinfo++)
    {
        lumpinfo_t *lump = &rts_lumpinfo[i];

        lump->handle = handle;  // NOTE: cache1d-file is not closed!
        lump->position = B_LITTLE32(fileinfo->filepos);
        lump->size = B_LITTLE32(fileinfo->size);

        Bstrncpy(lump->name, fileinfo->name, 8);
    }

    Bfree(fileinfoo);

    return 0;
}
예제 #2
0
int32_t S_PlayMusic(const char *fn)
{
    if (!ud.config.MusicToggle || fn == NULL)
        return 0;

    int32_t fp = S_OpenAudio(fn, 0, 1);
    if (EDUKE32_PREDICT_FALSE(fp < 0))
    {
        OSD_Printf(OSD_ERROR "S_PlayMusic(): error: can't open \"%s\" for playback!\n",fn);
        return 0;
    }

    S_StopMusic();

    int32_t MusicLen = kfilelength(fp);

    if (EDUKE32_PREDICT_FALSE(MusicLen < 4))
    {
        OSD_Printf(OSD_ERROR "S_PlayMusic(): error: empty music file \"%s\"\n", fn);
        kclose(fp);
        return 0;
    }

    ALIGNED_FREE_AND_NULL(MusicPtr);  // in case the following allocation was never freed
    MusicPtr = (char *)Xaligned_alloc(16, MusicLen);
    g_musicSize = kread(fp, (char *)MusicPtr, MusicLen);

    if (EDUKE32_PREDICT_FALSE(g_musicSize != MusicLen))
    {
        OSD_Printf(OSD_ERROR "S_PlayMusic(): error: read %d bytes from \"%s\", expected %d\n",
                   g_musicSize, fn, MusicLen);
        kclose(fp);
        g_musicSize = 0;
        return 0;
    }

    kclose(fp);

    if (!Bmemcmp(MusicPtr, "MThd", 4))
    {
        MUSIC_PlaySong(MusicPtr, MUSIC_LoopSong);
        MusicIsWaveform = 0;
    }
    else
    {
        int32_t const mvol = MASTER_VOLUME(ud.config.MusicVolume);
        MusicVoice = FX_PlayLoopedAuto(MusicPtr, MusicLen, 0, 0,
                                       0, mvol, mvol, mvol,
                                       FX_MUSIC_PRIORITY, MUSIC_ID);
        if (MusicVoice > FX_Ok)
            MusicIsWaveform = 1;
    }

    return 0;
}
예제 #3
0
파일: texcache.c 프로젝트: clobber/eduke32
// returns 1 on success
int32_t texcache_readtexheader(const char *fn, int32_t len, int32_t dameth, char effect,
                         texcacheheader *head, int32_t modelp)
{
    int32_t i, err = 0;
    char cachefn[BMAX_PATH];

    if (!texcache_enabled())
        return 0;

    i = hash_find(&texcache.hashes, texcache_calcid(cachefn, fn, len, dameth, effect));

    if (i < 0 || !texcache.iptrs[i])
        return 0;  // didn't find it

    texcache.filepos = texcache.iptrs[i]->offset;
//    initprintf("%s %d got a match for %s offset %d\n",__FILE__, __LINE__, cachefn,offset);

    if (texcache_readdata(head, sizeof(texcacheheader)))
        READTEXHEADER_FAILURE(0);

    if (Bmemcmp(head->magic, TEXCACHEMAGIC, 4))
        READTEXHEADER_FAILURE(1);

    // native (little-endian) -> internal
    head->xdim = B_LITTLE32(head->xdim);
    head->ydim = B_LITTLE32(head->ydim);
    head->flags = B_LITTLE32(head->flags);
    head->quality = B_LITTLE32(head->quality);

    if (modelp && head->quality != r_downsize)
        READTEXHEADER_FAILURE(2);
    if ((head->flags & CACHEAD_COMPRESSED) && glusetexcache != 2)
        READTEXHEADER_FAILURE(3);
    if (!(head->flags & CACHEAD_COMPRESSED) && glusetexcache == 2)
        READTEXHEADER_FAILURE(4);

    // handle nocompress
    if (!modelp && !(head->flags & CACHEAD_NOCOMPRESS) && head->quality != r_downsize)
        return 0;

    if (gltexmaxsize && (head->xdim > (1<<gltexmaxsize) || head->ydim > (1<<gltexmaxsize)))
        READTEXHEADER_FAILURE(5);
    if (!glinfo.texnpot && (head->flags & CACHEAD_NONPOW2))
        READTEXHEADER_FAILURE(6);

    return 1;

failure:
    {
        static const char *error_msgs[] = {
            "failed reading texture cache header",  // 0
            "header magic string doesn't match",  // 1
            "r_downsize doesn't match",  // 2  (skins only)
            "compression doesn't match: cache contains compressed tex",  // 3
            "compression doesn't match: cache contains uncompressed tex",  // 4
            "texture in cache exceeds maximum supported size",  // 5
            "texture in cache has non-power-of-two size, unsupported",  // 6
        };

        initprintf("%s cache miss: %s\n", modelp?"Skin":"Texture", error_msgs[err]);
    }

    return 0;
}