コード例 #1
0
ファイル: mmio.c プロジェクト: Jay-Jay-OPL/ps2sdk-ports
static int _mm_RWopsReader_Get(MREADER* reader)
{
	char buf;
	if ( SDL_RWread(((MRWOPSREADER*)reader)->rw, &buf, 1, 1) != 1 ) return EOF;
	else return (int)buf;
}
コード例 #2
0
ファイル: ldat.c プロジェクト: callaa/luola
/* Open an SDL_RWops for reading */
LDAT *ldat_open_rw (SDL_RWops * rw)
{
    char header[LDAT_MAGIC_LEN];
    LDAT *newldat;
    LDAT_Block *newblock;
    Uint16 i, itemcount;
    Uint8 idlen;
    newldat = ldat_create ();
    newldat->data = rw;
    /* Read header */
    SDL_RWread (newldat->data, header, 1, LDAT_MAGIC_LEN);
    if (strncmp (header, "LDAT", 4)) {
        fprintf (stderr,"Error: this is not an LDAT archive !\n");
        return NULL;
    }
    if (header[4] != LDAT_MAJOR) {
        fprintf (stderr, "Error: Unsupported version (%d.%d) !\n", header[4],
                header[5]);
        fprintf (stderr, "Latest supported version is %d.%d\n", LDAT_MAJOR,
                LDAT_MINOR);
        return NULL;
    }
    /* Read catalog */
    if(Luola_ReadLE16 (newldat->data,&itemcount) == -1) {
        fprintf(stderr,"Error occured while reading itemcount!\n");
    }

    for (i = 0; i < itemcount; i++) {
        newblock = malloc (sizeof (LDAT_Block));
        memset (newblock, 0, sizeof (LDAT_Block));
        if (SDL_RWread (newldat->data, &idlen, 1, 1) == -1) {
            fprintf (stderr, "(%d) Error occured while reading idlen!\n", i);
            return NULL;
        }
        newblock->ID = malloc (idlen + 1);
        if (SDL_RWread (newldat->data, newblock->ID, 1, idlen) == -1) {
            fprintf (stderr, "(%d) Error occured while reading ID string!\n", i);
            return NULL;
        }
        newblock->ID[idlen] = '\0';
        if (Luola_ReadLE16(newldat->data, &newblock->index) == -1) {
            fprintf (stderr, "(%d) Error occured while reading index number!\n", i);
            return NULL;
        }

        if (Luola_ReadLE32(newldat->data, &newblock->pos) == -1) {
            fprintf (stderr, "(%d) Error occured while reading position!\n", i);
            return NULL;
        }
        if (Luola_ReadLE32(newldat->data, &newblock->size) == -1) {
            fprintf (stderr, "(%d) Error occured while reading size!\n", i);
            return NULL;
        }
        if (newldat->catalog == NULL)
            newldat->catalog = newblock;
        else {
            newblock->prev = newldat->catalog;
            newldat->catalog->next = newblock;
            newldat->catalog = newblock;
        }
    }
    newldat->catalog_size = SDL_RWtell (newldat->data) - LDAT_HEADER_LEN;
    /* Rewing catalog */
    while (newldat->catalog->prev)
        newldat->catalog = newldat->catalog->prev;
    return newldat;
}
コード例 #3
0
ファイル: music_ogg.c プロジェクト: Jay-Jay-OPL/ps2sdk-ports
static size_t sdl_read_func(void *ptr, size_t size, size_t nmemb, void *datasource)
{
    return SDL_RWread((SDL_RWops*)datasource, ptr, size, nmemb);
}
コード例 #4
0
ファイル: IMG_pnm.c プロジェクト: Jay-Jay-OPL/ps2sdk-ports
SDL_Surface *IMG_LoadPNM_RW(SDL_RWops *src)
{
	SDL_Surface *surface = NULL;
	int width, height;
	int maxval, y, bpl;
	Uint8 *row;
	Uint8 *buf = NULL;
	char *error = NULL;
	Uint8 magic[2];
	int ascii;
	enum { PBM, PGM, PPM } kind;

#define ERROR(s) do { error = (s); goto done; } while(0)

	if ( !src ) {
		/* The error message has been set in SDL_RWFromFile */
		return NULL;
	}

	SDL_RWread(src, magic, 2, 1);
	kind = magic[1] - '1';
	ascii = 1;
	if(kind >= 3) {
		ascii = 0;
		kind -= 3;
	}

	width = ReadNumber(src);
	height = ReadNumber(src);
	if(width <= 0 || height <= 0)
		ERROR("Unable to read image width and height");

	if(kind != PBM) {
		maxval = ReadNumber(src);
		if(maxval <= 0 || maxval > 255)
			ERROR("unsupported PNM format");
	} else
		maxval = 255;	/* never scale PBMs */

	/* binary PNM allows just a single character of whitespace after
	   the last parameter, and we've already consumed it */

	if(kind == PPM) {
		/* 24-bit surface in R,G,B byte order */
		surface = SDL_AllocSurface(SDL_SWSURFACE, width, height, 24,
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
					   0x000000ff, 0x0000ff00, 0x00ff0000,
#else
					   0x00ff0000, 0x0000ff00, 0x000000ff,
#endif
					   0);
	} else {
		/* load PBM/PGM as 8-bit indexed images */
		surface = SDL_AllocSurface(SDL_SWSURFACE, width, height, 8,
					   0, 0, 0, 0);
	}
	if ( surface == NULL )
		ERROR("Out of memory");
	bpl = width * surface->format->BytesPerPixel;
	if(kind == PGM) {
		SDL_Color *c = surface->format->palette->colors;
		int i;
		for(i = 0; i < 256; i++)
			c[i].r = c[i].g = c[i].b = i;
		surface->format->palette->ncolors = 256;
	} else if(kind == PBM) {
		/* for some reason PBM has 1=black, 0=white */
		SDL_Color *c = surface->format->palette->colors;
		c[0].r = c[0].g = c[0].b = 255;
		c[1].r = c[1].g = c[1].b = 0;
		surface->format->palette->ncolors = 2;
		bpl = (width + 7) >> 3;
		buf = malloc(bpl);
		if(buf == NULL)
			ERROR("Out of memory");
	}
コード例 #5
0
ファイル: sdlrwops.cpp プロジェクト: weihuoya/HelloSDL
size_t SDLRWops::read(void *ptr, size_t size, size_t num)
{
    return SDL_RWread(rwops_, ptr, num, size);
}
コード例 #6
0
ファイル: native_midi_macosx.c プロジェクト: Ailick/socoolpal
NativeMidiSong *native_midi_loadsong_RW(SDL_RWops *rw)
{
    NativeMidiSong *retval = NULL;
    void *buf = NULL;
    int len = 0;
    CFDataRef data = NULL;

    if (SDL_RWseek(rw, 0, RW_SEEK_END) < 0)
        goto fail;
    len = SDL_RWtell(rw);
    if (len < 0)
        goto fail;
    if (SDL_RWseek(rw, 0, RW_SEEK_SET) < 0)
        goto fail;

    buf = malloc(len);
    if (buf == NULL)
        goto fail;

    if (SDL_RWread(rw, buf, len, 1) != 1)
        goto fail;

    retval = malloc(sizeof(NativeMidiSong));
    if (retval == NULL)
        goto fail;

    memset(retval, '\0', sizeof (*retval));

    if (NewMusicPlayer(&retval->player) != noErr)
        goto fail;
    if (NewMusicSequence(&retval->sequence) != noErr)
        goto fail;

    data = CFDataCreate(NULL, (const UInt8 *) buf, len);
    if (data == NULL)
        goto fail;

    free(buf);
    buf = NULL;

    #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 /* this is deprecated, but works back to 10.3 */
    if (MusicSequenceLoadSMFDataWithFlags(retval->sequence, data, 0) != noErr)
        goto fail;
    #else  /* not deprecated, but requires 10.5 or later */
    if (MusicSequenceFileLoadData(retval->sequence, data, 0, 0) != noErr)
        goto fail;
    #endif

    CFRelease(data);
    data = NULL;

    if (GetSequenceLength(retval->sequence, &retval->endTime) != noErr)
        goto fail;

    if (MusicPlayerSetSequence(retval->player, retval->sequence) != noErr)
        goto fail;

    return retval;

fail:
    if (retval) {
        if (retval->sequence)
            DisposeMusicSequence(retval->sequence);
        if (retval->player)
            DisposeMusicPlayer(retval->player);
        free(retval);
    }

    if (data)
        CFRelease(data);

    if (buf)
        free(buf);

    return NULL;
}
コード例 #7
0
ファイル: th_sound.cpp プロジェクト: MarkL1961/CorsixTH
size_t THSoundArchive::getSoundDuration(size_t iIndex)
{
    SDL_RWops *pFile = loadSound(iIndex);
    if(!pFile)
        return 0;

    uint16_t iWaveAudioFormat = 0;
    uint16_t iWaveChannelCount = 0;
    uint32_t iWaveSampleRate = 0;
    uint32_t iWaveByteRate = 0;
    uint16_t iWaveBlockAlign = 0;
    uint16_t iWaveBitsPerSample = 0;
    uint32_t iWaveDataLength = 0;

    // This is a very crude RIFF parser, but it does the job.
    uint32_t iFourCC;
    uint32_t iChunkLength;
    for(;;)
    {
        if(SDL_RWread(pFile, &iFourCC, 4, 1) != 1)
            break;
        if(SDL_RWread(pFile, &iChunkLength, 4, 1) != 1)
            break;
        if(iFourCC == FOURCC('R','I','F','F') || iFourCC == FOURCC('L','I','S','T'))
        {
            if(iChunkLength >= 4)
            {
                if(SDL_RWread(pFile, &iFourCC, 4, 1) != 1)
                    break;
                else
                    continue;
            }
        }
        if(iFourCC == FOURCC('f','m','t',' ') && iChunkLength >= 16)
        {
            if(SDL_RWread(pFile, &iWaveAudioFormat, 2, 1) != 1)
                break;
            if(SDL_RWread(pFile, &iWaveChannelCount, 2, 1) != 1)
                break;
            if(SDL_RWread(pFile, &iWaveSampleRate, 4, 1) != 1)
                break;
            if(SDL_RWread(pFile, &iWaveByteRate, 4, 1) != 1)
                break;
            if(SDL_RWread(pFile, &iWaveBlockAlign, 2, 1) != 1)
                break;
            if(SDL_RWread(pFile, &iWaveBitsPerSample, 2, 1) != 1)
                break;
            iChunkLength -= 16;
        }
        //Finally:
        if(iFourCC == FOURCC('d','a','t','a'))
        {
            iWaveDataLength = iChunkLength;
            break;
        }
        if(SDL_RWseek(pFile, iChunkLength + (iChunkLength & 1), RW_SEEK_CUR) == -1) {
            break;
        }
    }
    SDL_RWclose(pFile);
    if(iWaveAudioFormat != 1 || iWaveChannelCount == 0 || iWaveSampleRate == 0
    || iWaveDataLength == 0 || iWaveBitsPerSample == 0)
    {
        return 0;
    }
#define mul64(a, b) (static_cast<uint64_t>(a) * static_cast<uint64_t>(b))
    return static_cast<size_t>(mul64(iWaveDataLength, 8000) /
        mul64(mul64(iWaveBitsPerSample, iWaveChannelCount), iWaveSampleRate));
#undef mul64
}
コード例 #8
0
ファイル: l_tr5.cpp プロジェクト: ActiveMath/OpenTomb
void TR_Level::read_tr5_room(SDL_RWops * const src, tr5_room_t & room)
{
    uint32_t room_data_size;
    //uint32_t portal_offset;
    uint32_t sector_data_offset;
    uint32_t static_meshes_offset;
    uint32_t layer_offset;
    uint32_t vertices_offset;
    uint32_t poly_offset;
    uint32_t poly_offset2;
    uint32_t vertices_size;
    //uint32_t light_size;

    SDL_RWops *newsrc = NULL;
    uint32_t temp;
    uint32_t i;
    uint8_t *buffer;

    if (read_bitu32(src) != 0x414C4558)
        Sys_extError("read_tr5_room: 'XELA' not found");

    room_data_size = read_bitu32(src);
    buffer = new uint8_t[room_data_size];

    if (SDL_RWread(src, buffer, 1, room_data_size) < room_data_size)
        Sys_extError("read_tr5_room: room_data");

    if ((newsrc = SDL_RWFromMem(buffer, room_data_size)) == NULL)
        Sys_extError("read_tr5_room: SDL_RWFromMem");

    room.intensity1 = 32767;
    room.intensity2 = 32767;
    room.light_mode = 0;

    if (read_bitu32(newsrc) != 0xCDCDCDCD)
        Sys_extWarn("read_tr5_room: seperator1 has wrong value");

    /*portal_offset = */read_bit32(newsrc);             // StartPortalOffset?   // endSDOffset
    sector_data_offset = read_bitu32(newsrc);    // StartSDOffset
    temp = read_bitu32(newsrc);
    if ((temp != 0) && (temp != 0xCDCDCDCD))
        Sys_extWarn("read_tr5_room: seperator2 has wrong value");

    static_meshes_offset = read_bitu32(newsrc);     // endPortalOffset
    // static_meshes_offset or room_layer_offset
    // read and change coordinate system
    room.offset.x = (float)read_bit32(newsrc);
    room.offset.y = read_bitu32(newsrc);
    room.offset.z = (float)-read_bit32(newsrc);
    room.y_bottom = (float)-read_bit32(newsrc);
    room.y_top = (float)-read_bit32(newsrc);

    room.num_zsectors = read_bitu16(newsrc);
    room.num_xsectors = read_bitu16(newsrc);

    room.light_colour.b = read_bitu8(newsrc) / 255.0f;
    room.light_colour.g = read_bitu8(newsrc) / 255.0f;
    room.light_colour.r = read_bitu8(newsrc) / 255.0f;
    room.light_colour.a = read_bitu8(newsrc) / 255.0f;

    room.num_lights = read_bitu16(newsrc);
    if (room.num_lights > 512)
        Sys_extWarn("read_tr5_room: num_lights > 512");

    room.num_static_meshes = read_bitu16(newsrc);
    if (room.num_static_meshes > 512)
        Sys_extWarn("read_tr5_room: num_static_meshes > 512");

    room.reverb_info = read_bitu8(newsrc);
    room.alternate_group = read_bitu8(newsrc);
    room.water_scheme = read_bitu16(newsrc);

    if (read_bitu32(newsrc) != 0x00007FFF)
        Sys_extWarn("read_tr5_room: filler1 has wrong value");

    if (read_bitu32(newsrc) != 0x00007FFF)
        Sys_extWarn("read_tr5_room: filler2 has wrong value");

    if (read_bitu32(newsrc) != 0xCDCDCDCD)
        Sys_extWarn("read_tr5_room: seperator4 has wrong value");

    if (read_bitu32(newsrc) != 0xCDCDCDCD)
        Sys_extWarn("read_tr5_room: seperator5 has wrong value");

    if (read_bitu32(newsrc) != 0xFFFFFFFF)
        Sys_extWarn("read_tr5_room: seperator6 has wrong value");

    room.alternate_room = read_bit16(newsrc);

    room.flags = read_bitu16(newsrc);

    room.unknown_r1 = read_bitu32(newsrc);
    room.unknown_r2 = read_bitu32(newsrc);
    room.unknown_r3 = read_bitu32(newsrc);

    temp = read_bitu32(newsrc);
    if ((temp != 0) && (temp != 0xCDCDCDCD))
        Sys_extWarn("read_tr5_room: seperator7 has wrong value");

    room.unknown_r4a = read_bitu16(newsrc);
    room.unknown_r4b = read_bitu16(newsrc);

    room.room_x = read_float(newsrc);
    room.unknown_r5 = read_bitu32(newsrc);
    room.room_z = -read_float(newsrc);

    if (read_bitu32(newsrc) != 0xCDCDCDCD)
        Sys_extWarn("read_tr5_room: seperator8 has wrong value");

    if (read_bitu32(newsrc) != 0xCDCDCDCD)
        Sys_extWarn("read_tr5_room: seperator9 has wrong value");

    if (read_bitu32(newsrc) != 0xCDCDCDCD)
        Sys_extWarn("read_tr5_room: seperator10 has wrong value");

    if (read_bitu32(newsrc) != 0xCDCDCDCD)
        Sys_extWarn("read_tr5_room: seperator11 has wrong value");

    temp = read_bitu32(newsrc);
    if ((temp != 0) && (temp != 0xCDCDCDCD))
        Sys_extWarn("read_tr5_room: seperator12 has wrong value");

    if (read_bitu32(newsrc) != 0xCDCDCDCD)
        Sys_extWarn("read_tr5_room: seperator13 has wrong value");

    room.num_triangles = read_bitu32(newsrc);
    if (room.num_triangles == 0xCDCDCDCD)
            room.num_triangles = 0;
    if (room.num_triangles > 512)
        Sys_extWarn("read_tr5_room: num_triangles > 512");

    room.num_rectangles = read_bitu32(newsrc);
    if (room.num_rectangles == 0xCDCDCDCD)
            room.num_rectangles = 0;
    if (room.num_rectangles > 1024)
        Sys_extWarn("read_tr5_room: num_rectangles > 1024");

    if (read_bitu32(newsrc) != 0)
        Sys_extWarn("read_tr5_room: seperator14 has wrong value");

    /*light_size = */read_bitu32(newsrc);
    if (read_bitu32(newsrc) != room.num_lights)
        Sys_extError("read_tr5_room: room.num_lights2 != room.num_lights");

    room.unknown_r6 = read_bitu32(newsrc);
    room.room_y_top = -read_float(newsrc);
    room.room_y_bottom = -read_float(newsrc);

    room.num_layers = read_bitu32(newsrc);

    /*
       if (room.num_layers != 0) {
       if (room.x != room.room_x)
       throw TR_ReadError("read_tr5_room: x != room_x");
       if (room.z != room.room_z)
       throw TR_ReadError("read_tr5_room: z != room_z");
       if (room.y_top != room.room_y_top)
       throw TR_ReadError("read_tr5_room: y_top != room_y_top");
       if (room.y_bottom != room.room_y_bottom)
       throw TR_ReadError("read_tr5_room: y_bottom != room_y_bottom");
       }
     */

    layer_offset = read_bitu32(newsrc);
    vertices_offset = read_bitu32(newsrc);
    poly_offset = read_bitu32(newsrc);
    poly_offset2 = read_bitu32(newsrc);
    if (poly_offset != poly_offset2)
        Sys_extError("read_tr5_room: poly_offset != poly_offset2");

    vertices_size = read_bitu32(newsrc);
    if ((vertices_size % 28) != 0)
        Sys_extError("read_tr5_room: vertices_size has wrong value");

    if (read_bitu32(newsrc) != 0xCDCDCDCD)
        Sys_extWarn("read_tr5_room: seperator15 has wrong value");

    if (read_bitu32(newsrc) != 0xCDCDCDCD)
        Sys_extWarn("read_tr5_room: seperator16 has wrong value");

    if (read_bitu32(newsrc) != 0xCDCDCDCD)
        Sys_extWarn("read_tr5_room: seperator17 has wrong value");

    if (read_bitu32(newsrc) != 0xCDCDCDCD)
        Sys_extWarn("read_tr5_room: seperator18 has wrong value");

    room.lights = (tr5_room_light_t*)malloc(room.num_lights * sizeof(tr5_room_light_t));
    for (i = 0; i < room.num_lights; i++)
        read_tr5_room_light(newsrc, room.lights[i]);

    SDL_RWseek(newsrc, 208 + sector_data_offset, SEEK_SET);

    room.sector_list = (tr_room_sector_t*)malloc(room.num_zsectors * room.num_xsectors * sizeof(tr_room_sector_t));
    for (i = 0; i < (uint32_t)(room.num_zsectors * room.num_xsectors); i++)
        read_tr_room_sector(newsrc, room.sector_list[i]);

    /*
       if (room.portal_offset != 0xFFFFFFFF) {
       if (room.portal_offset != (room.sector_data_offset + (room.num_zsectors * room.num_xsectors * 8)))
       throw TR_ReadError("read_tr5_room: portal_offset has wrong value");

       SDL_RWseek(newsrc, 208 + room.portal_offset, SEEK_SET);
       }
     */

    room.num_portals = read_bit16(newsrc);
    room.portals = (tr_room_portal_t*)malloc(room.num_portals * sizeof(tr_room_portal_t));
    for (i = 0; i < room.num_portals; i++)
        read_tr_room_portal(newsrc, room.portals[i]);

    SDL_RWseek(newsrc, 208 + static_meshes_offset, SEEK_SET);

    room.static_meshes = (tr2_room_staticmesh_t*)malloc(room.num_static_meshes * sizeof(tr2_room_staticmesh_t));
    for (i = 0; i < room.num_static_meshes; i++)
        read_tr4_room_staticmesh(newsrc, room.static_meshes[i]);

    SDL_RWseek(newsrc, 208 + layer_offset, SEEK_SET);

    room.layers = (tr5_room_layer_t*)malloc(room.num_layers * sizeof(tr5_room_layer_t));
    for (i = 0; i < room.num_layers; i++)
        read_tr5_room_layer(newsrc, room.layers[i]);

    SDL_RWseek(newsrc, 208 + poly_offset, SEEK_SET);

    {
        uint32_t vertex_index = 0;
        uint32_t rectangle_index = 0;
        uint32_t triangle_index = 0;

        room.rectangles = (tr4_face4_t*)malloc(room.num_rectangles * sizeof(tr4_face4_t));
        room.triangles = (tr4_face3_t*)malloc(room.num_triangles * sizeof(tr4_face3_t));
        for (i = 0; i < room.num_layers; i++) {
            uint32_t j;

            for (j = 0; j < room.layers[i].num_rectangles; j++) {
                read_tr4_face4(newsrc, room.rectangles[rectangle_index]);
                room.rectangles[rectangle_index].vertices[0] += vertex_index;
                room.rectangles[rectangle_index].vertices[1] += vertex_index;
                room.rectangles[rectangle_index].vertices[2] += vertex_index;
                room.rectangles[rectangle_index].vertices[3] += vertex_index;
                rectangle_index++;
            }
            for (j = 0; j < room.layers[i].num_triangles; j++) {
                read_tr4_face3(newsrc, room.triangles[triangle_index]);
                room.triangles[triangle_index].vertices[0] += vertex_index;
                room.triangles[triangle_index].vertices[1] += vertex_index;
                room.triangles[triangle_index].vertices[2] += vertex_index;
                triangle_index++;
            }
            vertex_index += room.layers[i].num_vertices;
        }
    }

    SDL_RWseek(newsrc, 208 + vertices_offset, SEEK_SET);

    {
        uint32_t vertex_index = 0;
        room.num_vertices = vertices_size / 28;
        //int temp1 = room_data_size - (208 + vertices_offset + vertices_size);
        room.vertices = (tr5_room_vertex_t*)calloc(room.num_vertices, sizeof(tr5_room_vertex_t));
        for (i = 0; i < room.num_layers; i++) {
            uint32_t j;

            for (j = 0; j < room.layers[i].num_vertices; j++)
                    read_tr5_room_vertex(newsrc, room.vertices[vertex_index++]);
        }
    }

    SDL_RWseek(newsrc, room_data_size, SEEK_SET);

    SDL_RWclose(newsrc);
    newsrc = NULL;
    delete [] buffer;
}
コード例 #9
0
ファイル: l_tr5.cpp プロジェクト: ActiveMath/OpenTomb
void TR_Level::read_tr5_level(SDL_RWops * const src)
{
    uint32_t i;
    uint8_t *comp_buffer = NULL;
    uint8_t *uncomp_buffer = NULL;
    SDL_RWops *newsrc = NULL;

    // Version
    uint32_t file_version = read_bitu32(src);

    if (file_version != 0x00345254)
        Sys_extError("Wrong level version");

    this->num_textiles = 0;
    this->num_room_textiles = 0;
    this->num_obj_textiles = 0;
    this->num_bump_textiles = 0;
    this->num_misc_textiles = 0;
    this->read_32bit_textiles = false;

    uint32_t uncomp_size;
    uint32_t comp_size;
    unsigned long size;

    this->num_room_textiles = read_bitu16(src);
    this->num_obj_textiles = read_bitu16(src);
    this->num_bump_textiles = read_bitu16(src);
    this->num_misc_textiles = 3;
    this->num_textiles = this->num_room_textiles + this->num_obj_textiles + this->num_bump_textiles + this->num_misc_textiles;

    uncomp_size = read_bitu32(src);
    if (uncomp_size == 0)
        Sys_extError("read_tr5_level: textiles32 uncomp_size == 0");

    comp_size = read_bitu32(src);
    if (comp_size > 0) {
        uncomp_buffer = new uint8_t[uncomp_size];

        this->textile32.resize( this->num_textiles );
        comp_buffer = new uint8_t[comp_size];

        if (SDL_RWread(src, comp_buffer, 1, comp_size) < comp_size)
            Sys_extError("read_tr5_level: textiles32");

        size = uncomp_size;
        if (uncompress(uncomp_buffer, &size, comp_buffer, comp_size) != Z_OK)
            Sys_extError("read_tr5_level: uncompress");

        if (size != uncomp_size)
            Sys_extError("read_tr5_level: uncompress size mismatch");
        delete [] comp_buffer;

        comp_buffer = NULL;
        if ((newsrc = SDL_RWFromMem(uncomp_buffer, uncomp_size)) == NULL)
            Sys_extError("read_tr5_level: SDL_RWFromMem");

        for (i = 0; i < (this->num_textiles - this->num_misc_textiles); i++)
            read_tr4_textile32(newsrc, this->textile32[i]);
        SDL_RWclose(newsrc);
        newsrc = NULL;
        delete [] uncomp_buffer;

        uncomp_buffer = NULL;
        this->read_32bit_textiles = true;
    }

    uncomp_size = read_bitu32(src);
    if (uncomp_size == 0)
        Sys_extError("read_tr5_level: textiles16 uncomp_size == 0");

    comp_size = read_bitu32(src);
    if (comp_size > 0) {
        if (this->textile32.empty()) {
            uncomp_buffer = new uint8_t[uncomp_size];

            this->textile16_count = this->num_textiles;
            this->textile16 = (tr2_textile16_t*)malloc(this->textile16_count * sizeof(tr2_textile16_t));
            comp_buffer = new uint8_t[comp_size];

            if (SDL_RWread(src, comp_buffer, 1, comp_size) < comp_size)
                Sys_extError("read_tr5_level: textiles16");

            size = uncomp_size;
            if (uncompress(uncomp_buffer, &size, comp_buffer, comp_size) != Z_OK)
                Sys_extError("read_tr5_level: uncompress");

            if (size != uncomp_size)
                Sys_extError("read_tr5_level: uncompress size mismatch");
            delete [] comp_buffer;

            comp_buffer = NULL;
            if ((newsrc = SDL_RWFromMem(uncomp_buffer, uncomp_size)) == NULL)
                Sys_extError("read_tr5_level: SDL_RWFromMem");

            for (i = 0; i < (this->num_textiles - this->num_misc_textiles); i++)
                read_tr2_textile16(newsrc, this->textile16[i]);
            SDL_RWclose(newsrc);
            newsrc = NULL;
            delete [] uncomp_buffer;

            uncomp_buffer = NULL;
        } else {
            SDL_RWseek(src, comp_size, SEEK_CUR);
        }
    }

    uncomp_size = read_bitu32(src);
    if (uncomp_size == 0)
        Sys_extError("read_tr5_level: textiles32d uncomp_size == 0");

    comp_size = read_bitu32(src);
    if (comp_size > 0) {
        uncomp_buffer = new uint8_t[uncomp_size];

        if ((uncomp_size / (256 * 256 * 4)) > 3)
            Sys_extWarn("read_tr5_level: num_misc_textiles > 3");

        if (this->textile32.empty())
        {
            this->textile32.resize( this->num_misc_textiles );
        }

        comp_buffer = new uint8_t[comp_size];

        if (SDL_RWread(src, comp_buffer, 1, comp_size) < comp_size)
            Sys_extError("read_tr5_level: misc_textiles");

        size = uncomp_size;
        if (uncompress(uncomp_buffer, &size, comp_buffer, comp_size) != Z_OK)
            Sys_extError("read_tr5_level: uncompress");

        if (size != uncomp_size)
            Sys_extError("read_tr5_level: uncompress size mismatch");
        delete [] comp_buffer;

        comp_buffer = NULL;
        if ((newsrc = SDL_RWFromMem(uncomp_buffer, uncomp_size)) == NULL)
            Sys_extError("read_tr5_level: SDL_RWFromMem");

        for (i = (this->num_textiles - this->num_misc_textiles); i < this->num_textiles; i++)
            read_tr4_textile32(newsrc, this->textile32[i]);
        SDL_RWclose(newsrc);
        newsrc = NULL;
        delete [] uncomp_buffer;

        uncomp_buffer = NULL;
    }

    // flags?
    /*
       I found 2 flags in the TR5 file format. Directly after the sprite textures are 2 ints as a flag. The first one is the lara type:
       0 Normal
       3 Catsuit
       4 Divesuit
       6 Invisible

       The second one is the weather type (effects all outside rooms):
       0 No weather
       1 Rain
       2 Snow (in title.trc these are red triangles falling from the sky).
     */
    i = read_bitu16(src);
    i = read_bitu16(src);
    if (read_bitu32(src) != 0)
        Sys_extWarn("Bad value for flags[1]");

    if (read_bitu32(src) != 0)
        Sys_extWarn("Bad value for flags[2]");

    if (read_bitu32(src) != 0)
        Sys_extWarn("Bad value for flags[3]");

    if (read_bitu32(src) != 0)
        Sys_extWarn("Bad value for flags[4]");

    if (read_bitu32(src) != 0)
        Sys_extWarn("Bad value for flags[5]");

    if (read_bitu32(src) != 0)
        Sys_extWarn("Bad value for flags[6]");

    if (read_bitu32(src) != 0)
        Sys_extWarn("Bad value for flags[7]");

    // LevelDataSize1
    read_bitu32(src);
    // LevelDataSize2
    read_bitu32(src);

    // Unused
    if (read_bitu32(src) != 0)
        Sys_extWarn("Bad value for 'unused'");

    this->rooms_count = read_bitu32(src);
    this->rooms = (tr5_room_t*)calloc(this->rooms_count, sizeof(tr5_room_t));
    for (i = 0; i < this->rooms_count; i++)
        read_tr5_room(src, this->rooms[i]);

    this->floor_data_size = read_bitu32(src);
    this->floor_data = (uint16_t*)malloc(this->floor_data_size * sizeof(uint16_t));
    for(i = 0; i < this->floor_data_size; i++)
        this->floor_data[i] = read_bitu16(src);

    read_mesh_data(src);

    this->animations_count = read_bitu32(src);
    this->animations = (tr_animation_t*)malloc(this->animations_count * sizeof(tr_animation_t));
    for (i = 0; i < this->animations_count; i++)
    {
        read_tr4_animation(src, this->animations[i]);
    }

    this->state_changes_count = read_bitu32(src);
    this->state_changes = (tr_state_change_t*)malloc(this->state_changes_count * sizeof(tr_state_change_t));
    for (i = 0; i < this->state_changes_count; i++)
        read_tr_state_changes(src, this->state_changes[i]);

    this->anim_dispatches_count = read_bitu32(src);
    this->anim_dispatches = (tr_anim_dispatch_t*)malloc(this->anim_dispatches_count * sizeof(tr_anim_dispatch_t));
    for (i = 0; i < this->anim_dispatches_count; i++)
        read_tr_anim_dispatches(src, this->anim_dispatches[i]);

    this->anim_commands_count = read_bitu32(src);
    this->anim_commands = (int16_t*)malloc(this->anim_commands_count * sizeof(int16_t));
    for (i = 0; i < this->anim_commands_count; i++)
        this->anim_commands[i] = read_bit16(src);

    this->mesh_tree_data_size = read_bitu32(src);
    this->mesh_tree_data = (uint32_t*)malloc(this->mesh_tree_data_size * sizeof(uint32_t));
    for (i = 0; i < this->mesh_tree_data_size; i++)
        this->mesh_tree_data[i] = read_bitu32(src);                     // 4 bytes

    read_frame_moveable_data(src);

    this->static_meshes_count = read_bitu32(src);
    this->static_meshes = (tr_staticmesh_t*)malloc(this->static_meshes_count * sizeof(tr_staticmesh_t));
    for (i = 0; i < this->static_meshes_count; i++)
        read_tr_staticmesh(src, this->static_meshes[i]);

    if (read_bit8(src) != 'S')
        Sys_extError("read_tr5_level: 'SPR' not found");

    if (read_bit8(src) != 'P')
        Sys_extError("read_tr5_level: 'SPR' not found");

    if (read_bit8(src) != 'R')
        Sys_extError("read_tr5_level: 'SPR' not found");

    if (read_bit8(src) != 0)
        Sys_extError("read_tr5_level: 'SPR' not found");

    this->sprite_textures.resize( read_bitu32(src) );
    for (i = 0; i < this->sprite_textures.size(); i++)
        read_tr4_sprite_texture(src, this->sprite_textures[i]);

    this->sprite_sequences_count = read_bitu32(src);
    this->sprite_sequences = (tr_sprite_sequence_t*)malloc(this->sprite_sequences_count * sizeof(tr_sprite_sequence_t));
    for (i = 0; i < this->sprite_sequences_count; i++)
        read_tr_sprite_sequence(src, this->sprite_sequences[i]);

    this->cameras_count = read_bitu32(src);
    this->cameras = (tr_camera_t*)malloc(this->cameras_count * sizeof(tr_camera_t));
    for (i = 0; i < this->cameras_count; i++)
    {
        this->cameras[i].x = read_bit32(src);
        this->cameras[i].y = read_bit32(src);
        this->cameras[i].z = read_bit32(src);

        this->cameras[i].room = read_bit16(src);
        this->cameras[i].unknown1 = read_bitu16(src);
    }

    this->flyby_cameras_count = read_bitu32(src);
    this->flyby_cameras = (tr4_flyby_camera_t*)malloc(this->flyby_cameras_count * sizeof(tr4_flyby_camera_t));
    for (i = 0; i < this->flyby_cameras_count; i++)
    {
        this->flyby_cameras[i].cam_x = read_bit32(src);
        this->flyby_cameras[i].cam_y = read_bit32(src);
        this->flyby_cameras[i].cam_z = read_bit32(src);
        this->flyby_cameras[i].target_x = read_bit32(src);
        this->flyby_cameras[i].target_y = read_bit32(src);
        this->flyby_cameras[i].target_z = read_bit32(src);

        this->flyby_cameras[i].sequence = read_bit8(src);
        this->flyby_cameras[i].index    = read_bit8(src);

        this->flyby_cameras[i].fov   = read_bitu16(src);
        this->flyby_cameras[i].roll  = read_bitu16(src);
        this->flyby_cameras[i].timer = read_bitu16(src);
        this->flyby_cameras[i].speed = read_bitu16(src);
        this->flyby_cameras[i].flags = read_bitu16(src);

        this->flyby_cameras[i].room_id = read_bitu32(src);
    }

    this->sound_sources_count = read_bitu32(src);
    this->sound_sources = (tr_sound_source_t*)malloc(this->sound_sources_count * sizeof(tr_sound_source_t));
    for(i = 0; i < this->sound_sources_count; i++)
    {
        this->sound_sources[i].x = read_bit32(src);
        this->sound_sources[i].y = read_bit32(src);
        this->sound_sources[i].z = read_bit32(src);

        this->sound_sources[i].sound_id = read_bitu16(src);
        this->sound_sources[i].flags = read_bitu16(src);
    }

    this->boxes_count = read_bitu32(src);
    this->boxes = (tr_box_t*)malloc(this->boxes_count * sizeof(tr_box_t));
    for (i = 0; i < this->boxes_count; i++)
        read_tr2_box(src, this->boxes[i]);

    this->overlaps_count = read_bitu32(src);
    this->overlaps = (uint16_t*)malloc(this->overlaps_count * sizeof(uint16_t));
    for (i = 0; i < this->overlaps_count; i++)
        this->overlaps[i] = read_bitu16(src);

    // Zones
    SDL_RWseek(src, this->boxes_count * 20, SEEK_CUR);

    this->animated_textures_count = read_bitu32(src);
    this->animated_textures = (uint16_t*)malloc(this->animated_textures_count * sizeof(uint16_t));
    for (i = 0; i < this->animated_textures_count; i++)
    {
        this->animated_textures[i] = read_bitu16(src);
    }

    this->animated_textures_uv_count = read_bitu8(src);

    if (read_bit8(src) != 'T')
        Sys_extError("read_tr5_level: '\\0TEX' not found");

    if (read_bit8(src) != 'E')
        Sys_extError("read_tr5_level: '\\0TEX' not found");

    if (read_bit8(src) != 'X')
        Sys_extError("read_tr5_level: '\\0TEX' not found");

    if (read_bit8(src) != 0)
        Sys_extError("read_tr5_level: '\\0TEX' not found");

    this->object_textures.resize( read_bitu32(src) );
    for (i = 0; i < this->object_textures.size(); i++)
    {
        read_tr4_object_texture(src, this->object_textures[i]);
        if (read_bitu16(src) != 0)
            Sys_extWarn("read_tr5_level: obj_tex trailing bitu16 != 0");
    }

    this->items_count = read_bitu32(src);
    this->items = (tr2_item_t*)malloc(this->items_count * sizeof(tr2_item_t));
    for (i = 0; i < this->items_count; i++)
        read_tr4_item(src, this->items[i]);

    this->ai_objects_count = read_bitu32(src);
    this->ai_objects = (tr4_ai_object_t*)malloc(this->ai_objects_count * sizeof(tr4_ai_object_t));
    for(i=0; i < this->ai_objects_count; i++)
    {
        this->ai_objects[i].object_id = read_bitu16(src);
        this->ai_objects[i].room = read_bitu16(src);

        this->ai_objects[i].x = read_bit32(src);
        this->ai_objects[i].y = read_bit32(src);
        this->ai_objects[i].z = read_bit32(src);                            // 16

        this->ai_objects[i].ocb = read_bitu16(src);
        this->ai_objects[i].flags = read_bitu16(src);                       // 20
        this->ai_objects[i].angle = read_bit32(src);                        // 24
    }

    this->demo_data_count = read_bitu16(src);
    this->demo_data = (uint8_t*)malloc(this->demo_data_count * sizeof(uint8_t));
    for(i=0; i < this->demo_data_count; i++)
        this->demo_data[i] = read_bitu8(src);

    // Soundmap
    this->soundmap = (int16_t*)malloc(TR_AUDIO_MAP_SIZE_TR5 * sizeof(int16_t));
    for(i=0; i < TR_AUDIO_MAP_SIZE_TR5; i++)
        this->soundmap[i] = read_bit16(src);

    this->sound_details_count = read_bitu32(src);
    this->sound_details = (tr_sound_details_t*)malloc(this->sound_details_count * sizeof(tr_sound_details_t));

    for(i=0; i < this->sound_details_count; i++)
    {
        this->sound_details[i].sample = read_bitu16(src);
        this->sound_details[i].volume = (uint16_t)read_bitu8(src);        // n x 2.6
        this->sound_details[i].sound_range = (uint16_t)read_bitu8(src);   // n as is
        this->sound_details[i].chance = (uint16_t)read_bitu8(src);        // If n = 99, n = 0 (max. chance)
        this->sound_details[i].pitch = (int16_t)read_bit8(src);           // n as is
        this->sound_details[i].num_samples_and_flags_1 = read_bitu8(src);
        this->sound_details[i].flags_2 = read_bitu8(src);
    }

    this->sample_indices_count = read_bitu32(src);
    this->sample_indices = (uint32_t*)malloc(this->sample_indices_count * sizeof(uint32_t));
    for(i=0; i < this->sample_indices_count; i++)
        this->sample_indices[i] = read_bitu32(src);

    SDL_RWseek(src, 6, SEEK_CUR);   // In TR5, sample indices are followed by 6 0xCD bytes. - correct - really 0xCDCDCDCDCDCD

    // LOAD SAMPLES
    i = read_bitu32(src);                                                       // Read num samples
    if(i)
    {
        this->samples_count = i;
        // Since sample data is the last part, we simply load whole last
        // block of file as single array.
        this->samples_data.resize( SDL_RWsize(src) - SDL_RWtell(src) );
        for(i = 0; i < this->samples_data.size(); i++)
            this->samples_data[i] = read_bitu8(src);
    }
}
コード例 #10
0
ファイル: SDL_bmp.c プロジェクト: Solexid/SDL-mirror
SDL_Surface *
SDL_LoadBMP_RW(SDL_RWops * src, int freesrc)
{
    SDL_bool was_error;
    Sint64 fp_offset = 0;
    int bmpPitch;
    int i, pad;
    SDL_Surface *surface;
    Uint32 Rmask = 0;
    Uint32 Gmask = 0;
    Uint32 Bmask = 0;
    Uint32 Amask = 0;
    SDL_Palette *palette;
    Uint8 *bits;
    Uint8 *top, *end;
    SDL_bool topDown;
    int ExpandBMP;
    SDL_bool haveRGBMasks = SDL_FALSE;
    SDL_bool haveAlphaMask = SDL_FALSE;
    SDL_bool correctAlpha = SDL_FALSE;

    /* The Win32 BMP file header (14 bytes) */
    char magic[2];
    /* Uint32 bfSize = 0; */
    /* Uint16 bfReserved1 = 0; */
    /* Uint16 bfReserved2 = 0; */
    Uint32 bfOffBits = 0;

    /* The Win32 BITMAPINFOHEADER struct (40 bytes) */
    Uint32 biSize = 0;
    Sint32 biWidth = 0;
    Sint32 biHeight = 0;
    /* Uint16 biPlanes = 0; */
    Uint16 biBitCount = 0;
    Uint32 biCompression = 0;
    /* Uint32 biSizeImage = 0; */
    /* Sint32 biXPelsPerMeter = 0; */
    /* Sint32 biYPelsPerMeter = 0; */
    Uint32 biClrUsed = 0;
    /* Uint32 biClrImportant = 0; */

    /* Make sure we are passed a valid data source */
    surface = NULL;
    was_error = SDL_FALSE;
    if (src == NULL) {
        was_error = SDL_TRUE;
        goto done;
    }

    /* Read in the BMP file header */
    fp_offset = SDL_RWtell(src);
    SDL_ClearError();
    if (SDL_RWread(src, magic, 1, 2) != 2) {
        SDL_Error(SDL_EFREAD);
        was_error = SDL_TRUE;
        goto done;
    }
    if (SDL_strncmp(magic, "BM", 2) != 0) {
        SDL_SetError("File is not a Windows BMP file");
        was_error = SDL_TRUE;
        goto done;
    }
    /* bfSize = */ SDL_ReadLE32(src);
    /* bfReserved1 = */ SDL_ReadLE16(src);
    /* bfReserved2 = */ SDL_ReadLE16(src);
    bfOffBits = SDL_ReadLE32(src);

    /* Read the Win32 BITMAPINFOHEADER */
    biSize = SDL_ReadLE32(src);
    if (biSize == 12) {   /* really old BITMAPCOREHEADER */
        biWidth = (Uint32) SDL_ReadLE16(src);
        biHeight = (Uint32) SDL_ReadLE16(src);
        /* biPlanes = */ SDL_ReadLE16(src);
        biBitCount = SDL_ReadLE16(src);
        biCompression = BI_RGB;
    } else if (biSize >= 40) {  /* some version of BITMAPINFOHEADER */
        Uint32 headerSize;
        biWidth = SDL_ReadLE32(src);
        biHeight = SDL_ReadLE32(src);
        /* biPlanes = */ SDL_ReadLE16(src);
        biBitCount = SDL_ReadLE16(src);
        biCompression = SDL_ReadLE32(src);
        /* biSizeImage = */ SDL_ReadLE32(src);
        /* biXPelsPerMeter = */ SDL_ReadLE32(src);
        /* biYPelsPerMeter = */ SDL_ReadLE32(src);
        biClrUsed = SDL_ReadLE32(src);
        /* biClrImportant = */ SDL_ReadLE32(src);

        /* 64 == BITMAPCOREHEADER2, an incompatible OS/2 2.x extension. Skip this stuff for now. */
        if (biSize == 64) {
            /* ignore these extra fields. */
            if (biCompression == BI_BITFIELDS) {
                /* this value is actually huffman compression in this variant. */
                SDL_SetError("Compressed BMP files not supported");
                was_error = SDL_TRUE;
                goto done;
            }
        } else {
            /* This is complicated. If compression is BI_BITFIELDS, then
               we have 3 DWORDS that specify the RGB masks. This is either
               stored here in an BITMAPV2INFOHEADER (which only differs in
               that it adds these RGB masks) and biSize >= 52, or we've got
               these masks stored in the exact same place, but strictly
               speaking, this is the bmiColors field in BITMAPINFO immediately
               following the legacy v1 info header, just past biSize. */
            if (biCompression == BI_BITFIELDS) {
                haveRGBMasks = SDL_TRUE;
                Rmask = SDL_ReadLE32(src);
                Gmask = SDL_ReadLE32(src);
                Bmask = SDL_ReadLE32(src);

                /* ...v3 adds an alpha mask. */
                if (biSize >= 56) {  /* BITMAPV3INFOHEADER; adds alpha mask */
                    haveAlphaMask = SDL_TRUE;
                    Amask = SDL_ReadLE32(src);
                }
            } else {
                /* the mask fields are ignored for v2+ headers if not BI_BITFIELD. */
                if (biSize >= 52) {  /* BITMAPV2INFOHEADER; adds RGB masks */
                    /*Rmask = */ SDL_ReadLE32(src);
                    /*Gmask = */ SDL_ReadLE32(src);
                    /*Bmask = */ SDL_ReadLE32(src);
                }
                if (biSize >= 56) {  /* BITMAPV3INFOHEADER; adds alpha mask */
                    /*Amask = */ SDL_ReadLE32(src);
                }
            }

            /* Insert other fields here; Wikipedia and MSDN say we're up to
               v5 of this header, but we ignore those for now (they add gamma,
               color spaces, etc). Ignoring the weird OS/2 2.x format, we
               currently parse up to v3 correctly (hopefully!). */
        }

        /* skip any header bytes we didn't handle... */
        headerSize = (Uint32) (SDL_RWtell(src) - (fp_offset + 14));
        if (biSize > headerSize) {
            SDL_RWseek(src, (biSize - headerSize), RW_SEEK_CUR);
        }
    }
    if (biHeight < 0) {
        topDown = SDL_TRUE;
        biHeight = -biHeight;
    } else {
        topDown = SDL_FALSE;
    }

    /* Check for read error */
    if (SDL_strcmp(SDL_GetError(), "") != 0) {
        was_error = SDL_TRUE;
        goto done;
    }

    /* Expand 1 and 4 bit bitmaps to 8 bits per pixel */
    switch (biBitCount) {
    case 1:
    case 4:
        ExpandBMP = biBitCount;
        biBitCount = 8;
        break;
    default:
        ExpandBMP = 0;
        break;
    }

    /* We don't support any BMP compression right now */
    switch (biCompression) {
    case BI_RGB:
        /* If there are no masks, use the defaults */
        SDL_assert(!haveRGBMasks);
        SDL_assert(!haveAlphaMask);
        /* Default values for the BMP format */
        switch (biBitCount) {
        case 15:
        case 16:
            Rmask = 0x7C00;
            Gmask = 0x03E0;
            Bmask = 0x001F;
            break;
        case 24:
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
            Rmask = 0x000000FF;
            Gmask = 0x0000FF00;
            Bmask = 0x00FF0000;
#else
            Rmask = 0x00FF0000;
            Gmask = 0x0000FF00;
            Bmask = 0x000000FF;
#endif
            break;
        case 32:
            /* We don't know if this has alpha channel or not */
            correctAlpha = SDL_TRUE;
            Amask = 0xFF000000;
            Rmask = 0x00FF0000;
            Gmask = 0x0000FF00;
            Bmask = 0x000000FF;
            break;
        default:
            break;
        }
        break;

    case BI_BITFIELDS:
        break;  /* we handled this in the info header. */

    default:
        SDL_SetError("Compressed BMP files not supported");
        was_error = SDL_TRUE;
        goto done;
    }

    /* Create a compatible surface, note that the colors are RGB ordered */
    surface =
        SDL_CreateRGBSurface(0, biWidth, biHeight, biBitCount, Rmask, Gmask,
                             Bmask, Amask);
    if (surface == NULL) {
        was_error = SDL_TRUE;
        goto done;
    }

    /* Load the palette, if any */
    palette = (surface->format)->palette;
    if (palette) {
        SDL_assert(biBitCount <= 8);
        if (biClrUsed == 0) {
            biClrUsed = 1 << biBitCount;
        }
        if ((int) biClrUsed > palette->ncolors) {
            SDL_Color *colors;
            int ncolors = biClrUsed;
            colors =
                (SDL_Color *) SDL_realloc(palette->colors,
                                          ncolors *
                                          sizeof(*palette->colors));
            if (!colors) {
                SDL_OutOfMemory();
                was_error = SDL_TRUE;
                goto done;
            }
            palette->ncolors = ncolors;
            palette->colors = colors;
        } else if ((int) biClrUsed < palette->ncolors) {
            palette->ncolors = biClrUsed;
        }
        if (biSize == 12) {
            for (i = 0; i < (int) biClrUsed; ++i) {
                SDL_RWread(src, &palette->colors[i].b, 1, 1);
                SDL_RWread(src, &palette->colors[i].g, 1, 1);
                SDL_RWread(src, &palette->colors[i].r, 1, 1);
                palette->colors[i].a = SDL_ALPHA_OPAQUE;
            }
        } else {
            for (i = 0; i < (int) biClrUsed; ++i) {
                SDL_RWread(src, &palette->colors[i].b, 1, 1);
                SDL_RWread(src, &palette->colors[i].g, 1, 1);
                SDL_RWread(src, &palette->colors[i].r, 1, 1);
                SDL_RWread(src, &palette->colors[i].a, 1, 1);

                /* According to Microsoft documentation, the fourth element
                   is reserved and must be zero, so we shouldn't treat it as
                   alpha.
                */
                palette->colors[i].a = SDL_ALPHA_OPAQUE;
            }
        }
    }

    /* Read the surface pixels.  Note that the bmp image is upside down */
    if (SDL_RWseek(src, fp_offset + bfOffBits, RW_SEEK_SET) < 0) {
        SDL_Error(SDL_EFSEEK);
        was_error = SDL_TRUE;
        goto done;
    }
    top = (Uint8 *)surface->pixels;
    end = (Uint8 *)surface->pixels+(surface->h*surface->pitch);
    switch (ExpandBMP) {
    case 1:
        bmpPitch = (biWidth + 7) >> 3;
        pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0);
        break;
    case 4:
        bmpPitch = (biWidth + 1) >> 1;
        pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0);
        break;
    default:
        pad = ((surface->pitch % 4) ? (4 - (surface->pitch % 4)) : 0);
        break;
    }
    if (topDown) {
        bits = top;
    } else {
        bits = end - surface->pitch;
    }
    while (bits >= top && bits < end) {
        switch (ExpandBMP) {
        case 1:
        case 4: {
            Uint8 pixel = 0;
            int shift = (8 - ExpandBMP);
            for (i = 0; i < surface->w; ++i) {
                if (i % (8 / ExpandBMP) == 0) {
                    if (!SDL_RWread(src, &pixel, 1, 1)) {
                        SDL_SetError("Error reading from BMP");
                        was_error = SDL_TRUE;
                        goto done;
                    }
                }
                *(bits + i) = (pixel >> shift);
                pixel <<= ExpandBMP;
            }
        }
        break;

        default:
            if (SDL_RWread(src, bits, 1, surface->pitch)
                    != surface->pitch) {
                SDL_Error(SDL_EFREAD);
                was_error = SDL_TRUE;
                goto done;
            }
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
            /* Byte-swap the pixels if needed. Note that the 24bpp
               case has already been taken care of above. */
            switch (biBitCount) {
            case 15:
            case 16: {
                Uint16 *pix = (Uint16 *) bits;
                for (i = 0; i < surface->w; i++)
                    pix[i] = SDL_Swap16(pix[i]);
                break;
            }

            case 32: {
                Uint32 *pix = (Uint32 *) bits;
                for (i = 0; i < surface->w; i++)
                    pix[i] = SDL_Swap32(pix[i]);
                break;
            }
            }
#endif
            break;
        }
        /* Skip padding bytes, ugh */
        if (pad) {
            Uint8 padbyte;
            for (i = 0; i < pad; ++i) {
                SDL_RWread(src, &padbyte, 1, 1);
            }
        }
        if (topDown) {
            bits += surface->pitch;
        } else {
            bits -= surface->pitch;
        }
    }
    if (correctAlpha) {
        CorrectAlphaChannel(surface);
    }
done:
    if (was_error) {
        if (src) {
            SDL_RWseek(src, fp_offset, RW_SEEK_SET);
        }
        SDL_FreeSurface(surface);
        surface = NULL;
    }
    if (freesrc && src) {
        SDL_RWclose(src);
    }
    return (surface);
}
コード例 #11
0
ファイル: music.c プロジェクト: cubemoon/game-editor
/* Initialize the music players with a certain desired audio format */
int open_music(SDL_AudioSpec *mixer)
{
	int music_error;


	music_error = 0;
#ifdef WAV_MUSIC
	if ( WAVStream_Init(mixer) < 0 ) {
		++music_error;
	}
#endif
#ifdef MOD_MUSIC
	/* Set the MikMod music format */
	music_swap8 = 0;
	music_swap16 = 0;
	switch (mixer->format) {

		case AUDIO_U8:
		case AUDIO_S8: {
			if ( mixer->format == AUDIO_S8 ) {
				music_swap8 = 1;
			}
			md_mode = 0;
		}
		break;

		case AUDIO_S16LSB:
		case AUDIO_S16MSB: {
			/* See if we need to correct MikMod mixing */
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
			if ( mixer->format == AUDIO_S16MSB ) {
#else
			if ( mixer->format == AUDIO_S16LSB ) {
#endif
				music_swap16 = 1;
			}
			md_mode = DMODE_16BITS;
		}
		break;

		default: {
			Mix_SetError("Unknown hardware audio format");
			++music_error;
		}
	}
	if ( mixer->channels > 1 ) {
		if ( mixer->channels > 2 ) {
			Mix_SetError("Hardware uses more channels than mixer");
			++music_error;
		}
		md_mode |= DMODE_STEREO;
	}
	md_mixfreq	 = mixer->freq;
	md_device	  = 0;
	md_volume	  = 96;
	md_musicvolume = 128;
	md_sndfxvolume = 128;
	md_pansep	  = 128;
	md_reverb	  = 0;
	MikMod_RegisterAllLoaders();
	MikMod_RegisterAllDrivers();
	if ( MikMod_Init() ) {
		Mix_SetError("%s", MikMod_strerror(MikMod_errno));
		++music_error;
	}
#endif
#ifdef MID_MUSIC
#ifdef USE_TIMIDITY_MIDI
	samplesize = mixer->size / mixer->samples;
	if ( Timidity_Init(mixer->freq, mixer->format,
	                    mixer->channels, mixer->samples) == 0 ) {
		timidity_ok = 1;
	} else {
		timidity_ok = 0;
	}
#endif
#ifdef USE_NATIVE_MIDI
#ifdef USE_TIMIDITY_MIDI
	native_midi_ok = !timidity_ok;
	if ( native_midi_ok )
#endif
		native_midi_ok = native_midi_detect();
#endif
#endif
#ifdef OGG_MUSIC
	if ( OGG_init(mixer) < 0 ) {
		++music_error;
	}
#endif
#ifdef MP3_MUSIC
	/* Keep a copy of the mixer */
	used_mixer = *mixer;
#endif
	music_playing = NULL;
	music_stopped = 0;
	if ( music_error ) {
		return(-1);
	}
	Mix_VolumeMusic(SDL_MIX_MAXVOLUME);

	/* Calculate the number of ms for each callback */
	ms_per_step = (int) (((float)mixer->samples * 1000.0) / mixer->freq);

	return(0);
}

/* Portable case-insensitive string compare function */
int MIX_string_equals(const char *str1, const char *str2)
{
	while ( *str1 && *str2 ) {
		if ( toupper((unsigned char)*str1) !=
		     toupper((unsigned char)*str2) )
			break;
		++str1;
		++str2;
	}
	return (!*str1 && !*str2);
}

/* Load a music file */
Mix_Music *Mix_LoadMUS(const char *file)
{
	char *ext;
	Uint8 magic[5];
	Mix_Music *music;
	SDL_RWops *src; //maks

	/* Figure out what kind of file this is */
	/*fp = fopen(file, "rb"); //maks
	if ( (fp == NULL) || !fread(magic, 4, 1, fp) ) {
		if ( fp != NULL ) {
			fclose(fp);
		}
		Mix_SetError("Couldn't read from '%s'", file);
		return(NULL);
	}
	magic[4] = '\0';
	fclose(fp);*/

	src = SDL_RWFromFile(file, "rb"); //maks
	if ( (src == NULL) || !SDL_RWread(src, magic, 4, 1) ) {
		if ( src != NULL ) {
			SDL_RWclose(src);
		}
		Mix_SetError("Couldn't read from '%s'", file);
		return(NULL);
	}
	magic[4] = '\0';
	SDL_RWclose(src);

	/* Figure out the file extension, so we can determine the type */
	ext = strrchr(file, '.');
	if ( ext ) ++ext; /* skip the dot in the extension */

	/* Allocate memory for the music structure */
	music = (Mix_Music *)malloc(sizeof(Mix_Music));
	if ( music == NULL ) {
		Mix_SetError("Out of memory");
		return(NULL);
	}
	music->error = 0;

#ifdef CMD_MUSIC
	if ( music_cmd ) {
		music->type = MUS_CMD;
		music->data.cmd = MusicCMD_LoadSong(music_cmd, file);
		if ( music->data.cmd == NULL ) {
			music->error = 1;
		}
	} else
#endif
#ifdef WAV_MUSIC
	/* WAVE files have the magic four bytes "RIFF"
	   AIFF files have the magic 12 bytes "FORM" XXXX "AIFF"
	 */
	if ( (ext && MIX_string_equals(ext, "WAV")) ||
	     (strcmp((char *)magic, "RIFF") == 0) ||
	     (strcmp((char *)magic, "FORM") == 0) ) {
		music->type = MUS_WAV;
		music->data.wave = WAVStream_LoadSong(file, (char *)magic);
		if ( music->data.wave == NULL ) {
		  	Mix_SetError("Unable to load WAV file");
			music->error = 1;
		}
	} else
#endif

#ifndef _WIN32_WCE

#ifdef MID_MUSIC
	/* MIDI files have the magic four bytes "MThd" */
	if ( (ext && MIX_string_equals(ext, "MID")) ||
	     (ext && MIX_string_equals(ext, "MIDI")) ||
	     strcmp((char *)magic, "MThd") == 0 ) {
		music->type = MUS_MID;
#ifdef USE_NATIVE_MIDI
  		if ( native_midi_ok ) {
  			music->data.nativemidi = native_midi_loadsong((char *)file);
	  		if ( music->data.nativemidi == NULL ) {
		  		Mix_SetError("%s", native_midi_error());
			  	music->error = 1;
			}
	  	} MIDI_ELSE
#endif
#ifdef USE_TIMIDITY_MIDI
		if ( timidity_ok ) {
			music->data.midi = Timidity_LoadSong((char *)file);
			if ( music->data.midi == NULL ) {
				Mix_SetError("%s", Timidity_Error());
				music->error = 1;
			}
		} else {
			Mix_SetError("%s", Timidity_Error());
			music->error = 1;
		}
#endif
	} else
コード例 #12
0
ファイル: cfgFile.c プロジェクト: JesseRahikainen/Xturos
// opens the file, returns NULL if it fails.
void* cfg_OpenFile( const char* fileName )
{
	if( SDL_strlen( fileName ) >= ( FILE_PATH_LEN - 1 ) ) {
		llog( LOG_ERROR, "Configuration file path too long" );
		return NULL;
	}

	CFGFile* newFile = (CFGFile*)mem_Allocate( sizeof( CFGFile ) );
	if( newFile == NULL ) {
		llog( LOG_INFO, "Unable to open configuration file." );
		return NULL;
	}
	newFile->sbAttributes = NULL;
	SDL_strlcpy( newFile->filePath, fileName, FILE_PATH_LEN - 1 );
	newFile->filePath[FILE_PATH_LEN-1] = 0;

	SDL_RWops* rwopsFile = SDL_RWFromFile( fileName, "r" );
	if( rwopsFile == NULL ) {
		// file doesn't exist, just create a new empty configuration file to use
		return newFile;
	}

	// TODO: change this so everything is happening in place and there are no allocations
	// parse what this configuration file currently has in it
	char buffer[READ_BUFFER_SIZE];
	size_t numRead;
	char* fileText = NULL;
	llog( LOG_INFO, "Stream size: %i", (int)SDL_RWsize( rwopsFile ) );
	while( ( numRead = SDL_RWread( rwopsFile, (void*)buffer, sizeof( char ), sizeof( buffer ) ) ) != 0 ) {
		char* c = sb_Add( fileText, (int)numRead );
		for( size_t i = 0; i < numRead; ++i ) {
			*c++ = buffer[i];
		}
	}
	sb_Push( fileText, 0 ); // make this c-string compatible

	// got the entire file text, now tokenize and parse
	//  only tokens we're worried about are '=' and '/r/n'
	//  everything before the '=' is the attribute name, everything
	//  after is the attribute value, all white space should be cut
	//  off of each end
	int gettingAttrName = 1;
	const char* delimiters = "\f\v\t =\r\n";
	char* token = strtok( fileText, delimiters );
	CFGAttribute attr;

	while( token != NULL ) {

		// cut off white space, don't care about preserving memory
		if( gettingAttrName ) {
			SDL_strlcpy( attr.fileName, token, sizeof( attr.fileName ) - 1 );
			attr.fileName[sizeof( attr.fileName ) - 1] = 0;
			gettingAttrName = 0;
		} else {
			attr.value = SDL_atoi( token );
			sb_Push( newFile->sbAttributes, attr );
			llog( LOG_INFO, "New attribute: %s  %i", attr.fileName, attr.value );
			gettingAttrName = 1;
		}

		token = strtok( NULL, delimiters );
	}

	sb_Release( fileText );
	SDL_RWclose( rwopsFile );

	return newFile;
}
コード例 #13
0
int main(int argc, char **argv)
{
    Uint8* RawMooseData;
    SDL_RWops* handle;
    SDL_Surface* screen;
    SDL_Surface* MooseFrame[MOOSEFRAMES_COUNT];
    SDL_Overlay* overlay;
    SDL_Rect overlayrect;
    SDL_Event event;
    Uint32 lastftick;
    int paused=0;
    int resized=0;
    int i;
    int fps=12;
    int fpsdelay;
    int overlay_format=SDL_YUY2_OVERLAY;
    int scale=5;

    while ( argc > 1 )
    {
        if (strcmp(argv[1], "-fps")== 0)
        {
            if (argv[2])
            {
                fps = atoi(argv[2]);
                if (fps==0)
                {
                    fprintf(stderr, "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
                    return -1;
                }
                if ((fps<0) || (fps>1000))
                {
                    fprintf(stderr, "The -fps option must be in range from 1 to 1000, default is 12.\n");
                    return -1;
                }
                argv += 2;
                argc -= 2;
            }
            else
            {
                fprintf(stderr, "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
                return -1;
            }
        } else
        if (strcmp(argv[1], "-format") == 0)
        {
            if (argv[2])
            {
                if (!strcmp(argv[2],"YV12"))
                    overlay_format = SDL_YV12_OVERLAY;
                else if(!strcmp(argv[2],"IYUV"))
                    overlay_format = SDL_IYUV_OVERLAY;
                else if(!strcmp(argv[2],"YUY2"))
                    overlay_format = SDL_YUY2_OVERLAY;
                else if(!strcmp(argv[2],"UYVY"))
                    overlay_format = SDL_UYVY_OVERLAY;
                else if(!strcmp(argv[2],"YVYU"))
                    overlay_format = SDL_YVYU_OVERLAY;
                else
                {
                    fprintf(stderr, "The -format option %s is not recognized, see help for info.\n", argv[2]);
                    return -1;
                }
                argv += 2;
                argc -= 2;
            }
            else
            {
                fprintf(stderr, "The -format option requires an argument, default is YUY2.\n");
                return -1;
            }
        } else
        if (strcmp(argv[1], "-scale") == 0)
        {
            if (argv[2])
            {
                scale = atoi(argv[2]);
                if (scale==0)
                {
                    fprintf(stderr, "The -scale option requires an argument [from 1 to 50], default is 5.\n");
                    return -1;
                }
                if ((scale<0) || (scale>50))
                {
                    fprintf(stderr, "The -scale option must be in range from 1 to 50, default is 5.\n");
                    return -1;
                }
                argv += 2;
                argc -= 2;
            }
            else
            {
                fprintf(stderr, "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
                return -1;
            }
        } else
        if ((strcmp(argv[1], "-help") == 0 ) || (strcmp(argv[1], "-h") == 0))
        {
            PrintUsage(argv[0]);
            return 0;
        } else
        {
            fprintf(stderr, "Unrecognized option: %s.\n", argv[1]);
            return -1;
        }
        break;
    }
   
    RawMooseData=(Uint8*)malloc(MOOSEFRAME_SIZE * MOOSEFRAMES_COUNT);
    if (RawMooseData==NULL)
    {
        fprintf(stderr, "Can't allocate memory for movie !\n");
        free(RawMooseData);
        return 1;
    }

    /* load the trojan moose images */
    handle=SDL_RWFromFile("moose.dat", "rb");
    if (handle==NULL)
    {
        fprintf(stderr, "Can't find the file moose.dat !\n");
        free(RawMooseData);
        return 2;
    }
   
    SDL_RWread(handle, RawMooseData, MOOSEFRAME_SIZE, MOOSEFRAMES_COUNT);

    SDL_RWclose(handle);

    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0)
    {
        fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
        free(RawMooseData);
        return 3;
    }
    atexit(SDL_Quit);

    /* Set video mode */
    if ( (screen=SDL_SetVideoMode(MOOSEPIC_W*scale, MOOSEPIC_H*scale, 0, SDL_RESIZABLE | SDL_SWSURFACE)) == NULL )
    {
        fprintf(stderr, "Couldn't set video mode: %s\n", 0, SDL_GetError());
        free(RawMooseData);
        return 4;
    }

    /* Set the window manager title bar */
    SDL_WM_SetCaption("SDL test overlay: running moose", "testoverlay2");

    for (i=0; i<MOOSEFRAMES_COUNT; i++)
    {
        MooseFrame[i]=SDL_CreateRGBSurfaceFrom(RawMooseData+i*MOOSEFRAME_SIZE, MOOSEPIC_W,
                                               MOOSEPIC_H, 8, MOOSEPIC_W, 0, 0, 0, 0);
        if (MooseFrame[i]==NULL)
        {
            fprintf(stderr, "Couldn't create SDL_Surfaces:%s\n", 0, SDL_GetError());
            free(RawMooseData);
            return 5;
        }
        SDL_SetColors(MooseFrame[i], MooseColors, 0, 84);

	{
		SDL_Surface *newsurf;
		SDL_PixelFormat format;

		format.palette=NULL;
		format.BitsPerPixel=32;
		format.BytesPerPixel=4;
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
		format.Rshift=0;
		format.Gshift=8;
		format.Bshift=16;
#else
		format.Rshift=24;
		format.Gshift=16;
		format.Bshift=8;
#endif
		format.Ashift=0;
		format.Rmask=0xff<<format.Rshift;
		format.Gmask=0xff<<format.Gshift;
		format.Bmask=0xff<<format.Bshift;
		format.Amask=0;
		format.Rloss=0;
		format.Gloss=0;
		format.Bloss=0;
		format.Aloss=8;
		format.colorkey=0;
		format.alpha=0;

		newsurf=SDL_ConvertSurface(MooseFrame[i], &format, SDL_SWSURFACE);
		if(!newsurf)
		{
                    fprintf(stderr, "Couldn't convert picture to 32bits RGB: %s\n", SDL_GetError());
                    return 6;
		}
		SDL_FreeSurface(MooseFrame[i]);
		MooseFrame[i]=newsurf;
	}
    }

    free(RawMooseData);

    overlay=SDL_CreateYUVOverlay(MOOSEPIC_W, MOOSEPIC_H, overlay_format, screen);
    if (!overlay)
    {
        fprintf(stderr, "Couldn't create overlay: %s\n", SDL_GetError());
        return 7;
    }

    printf("Created %dx%dx%d %s %s overlay\n",overlay->w,overlay->h,overlay->planes,
           overlay->hw_overlay?"hardware":"software",
           overlay->format==SDL_YV12_OVERLAY?"YV12":
           overlay->format==SDL_IYUV_OVERLAY?"IYUV":
           overlay->format==SDL_YUY2_OVERLAY?"YUY2":
           overlay->format==SDL_UYVY_OVERLAY?"UYVY":
           overlay->format==SDL_YVYU_OVERLAY?"YVYU":
           "Unknown");

    for(i=0; i<overlay->planes; i++)
    {
        printf("  plane %d: pitch=%d\n", i, overlay->pitches[i]);
    }

    overlayrect.x=0;
    overlayrect.y=0;
    overlayrect.w=MOOSEPIC_W*scale;
    overlayrect.h=MOOSEPIC_H*scale;

    /* set the start frame */
    i=0;
    fpsdelay=1000/fps;

    /* Ignore key up events, they don't even get filtered */
    SDL_EventState(SDL_KEYUP, SDL_IGNORE);

    lastftick=SDL_GetTicks();

    /* Loop, waiting for QUIT or RESIZE */
    while (1)
    {
        if (SDL_PollEvent(&event))
        {
            switch (event.type)
            {
                case SDL_VIDEORESIZE:
                     screen=SDL_SetVideoMode(event.resize.w, event.resize.h, 0, SDL_RESIZABLE | SDL_SWSURFACE);
                     overlayrect.w=event.resize.w;
                     overlayrect.h=event.resize.h;
                     if (paused)
                     {
                         resized=1;
                     }
                     break;
                case SDL_KEYDOWN:
                     if (event.key.keysym.sym == SDLK_SPACE)
                     {
                         paused=!paused;
                         break;
                     }
                     if (event.key.keysym.sym != SDLK_ESCAPE)
                     {
                         break;
                     }
                case SDL_QUIT:
                     SDL_FreeYUVOverlay(overlay);
                     for (i=0; i<MOOSEFRAMES_COUNT; i++)
                     {
                         SDL_FreeSurface(MooseFrame[i]);
                     }
                     return 0;
            }
        }

        if ((!paused)||(resized))
        {
            if (((SDL_GetTicks()-lastftick)>fpsdelay)||(resized))
            {
                lastftick=SDL_GetTicks();

                switch (overlay_format)
                {
                    case SDL_YUY2_OVERLAY:
                         ConvertRGBtoYUY2(MooseFrame[i], overlay, 0, 100);
                         break;
                    case SDL_YV12_OVERLAY:
                         ConvertRGBtoYV12(MooseFrame[i], overlay, 0, 100);
                         break;
                    case SDL_UYVY_OVERLAY:
                         ConvertRGBtoUYVY(MooseFrame[i], overlay, 0, 100);
                         break;
                    case SDL_YVYU_OVERLAY:
                         ConvertRGBtoYVYU(MooseFrame[i], overlay, 0, 100);
                         break;
                    case SDL_IYUV_OVERLAY:
                         ConvertRGBtoIYUV(MooseFrame[i], overlay, 0, 100);
                         break;
                }

                SDL_DisplayYUVOverlay(overlay, &overlayrect);
                if (!resized)
                {
                    i++;
                    if (i==10)
                    {
                        i=0;
                    }
                }
                else
                {
                    resized=0;
                }
            }
        }
        /* kind of timeslice to OS */
        SDL_Delay(1);
    }

    return 0;
}
コード例 #14
0
/* Reads the next frame from the file.  Returns true on success or
   false on failure. */
static int
read_next_frame(mad_data *mp3_mad) {
  if (mp3_mad->stream.buffer == NULL || 
	  mp3_mad->stream.error == MAD_ERROR_BUFLEN) {
	size_t read_size;
	size_t remaining;
	unsigned char *read_start;
	
	/* There might be some bytes in the buffer left over from last
	   time.  If so, move them down and read more bytes following
	   them. */
	if (mp3_mad->stream.next_frame != NULL) {
	  remaining = mp3_mad->stream.bufend - mp3_mad->stream.next_frame;
	  memmove(mp3_mad->input_buffer, mp3_mad->stream.next_frame, remaining);
	  read_start = mp3_mad->input_buffer + remaining;
	  read_size = MAD_INPUT_BUFFER_SIZE - remaining;
	  
	} else {
	  read_size = MAD_INPUT_BUFFER_SIZE;
	  read_start = mp3_mad->input_buffer;
	  remaining = 0;
	}

	/* Now read additional bytes from the input file. */
	read_size = SDL_RWread(mp3_mad->rw, read_start, 1, read_size);
	
	if (read_size <= 0) {
	  if ((mp3_mad->status & (MS_input_eof | MS_input_error)) == 0) {
		if (read_size == 0) {
		  mp3_mad->status |= MS_input_eof;
		} else {
		  mp3_mad->status |= MS_input_error;
		}
		
		/* At the end of the file, we must stuff MAD_BUFFER_GUARD
		   number of 0 bytes. */
		memset(read_start + read_size, 0, MAD_BUFFER_GUARD);
		read_size += MAD_BUFFER_GUARD;
	  }
	}
	
	/* Now feed those bytes into the libmad stream. */
	mad_stream_buffer(&mp3_mad->stream, mp3_mad->input_buffer,
					  read_size + remaining);
	mp3_mad->stream.error = MAD_ERROR_NONE;
  }
  
  /* Now ask libmad to extract a frame from the data we just put in
	 its buffer. */
  if (mad_frame_decode(&mp3_mad->frame, &mp3_mad->stream)) {
	if (MAD_RECOVERABLE(mp3_mad->stream.error)) {
	  return 0;
	  
	} else if (mp3_mad->stream.error == MAD_ERROR_BUFLEN) {
	  return 0;
	  
	} else {
	  mp3_mad->status |= MS_decode_error;
	  return 0;
	}
  }
  
  mp3_mad->frames_read++;
  mad_timer_add(&mp3_mad->next_frame_start, mp3_mad->frame.header.duration);

  return 1;
}
コード例 #15
0
/*
 * Add or update an entry into the Mappings Database
 */
int
SDL_GameControllerAddMappingsFromRW(SDL_RWops * rw, int freerw)
{
    const char *platform = SDL_GetPlatform();
    int controllers = 0;
    char *buf, *line, *line_end, *tmp, *comma, line_platform[64];
    size_t db_size, platform_len;
    
    if (rw == NULL) {
        return SDL_SetError("Invalid RWops");
    }
    db_size = (size_t)SDL_RWsize(rw);
    
    buf = (char *)SDL_malloc(db_size + 1);
    if (buf == NULL) {
        if (freerw) {
            SDL_RWclose(rw);
        }
        return SDL_SetError("Could not allocate space to read DB into memory");
    }
    
    if (SDL_RWread(rw, buf, db_size, 1) != 1) {
        if (freerw) {
            SDL_RWclose(rw);
        }
        SDL_free(buf);
        return SDL_SetError("Could not read DB");
    }
    
    if (freerw) {
        SDL_RWclose(rw);
    }
    
    buf[db_size] = '\0';
    line = buf;
    
    while (line < buf + db_size) {
        line_end = SDL_strchr(line, '\n');
        if (line_end != NULL) {
            *line_end = '\0';
        } else {
            line_end = buf + db_size;
        }
        
        /* Extract and verify the platform */
        tmp = SDL_strstr(line, SDL_CONTROLLER_PLATFORM_FIELD);
        if (tmp != NULL) {
            tmp += SDL_strlen(SDL_CONTROLLER_PLATFORM_FIELD);
            comma = SDL_strchr(tmp, ',');
            if (comma != NULL) {
                platform_len = comma - tmp + 1;
                if (platform_len + 1 < SDL_arraysize(line_platform)) {
                    SDL_strlcpy(line_platform, tmp, platform_len);
                    if (SDL_strncasecmp(line_platform, platform, platform_len) == 0 &&
                        SDL_GameControllerAddMapping(line) > 0) {
                        controllers++;
                    }
                }
            }
        }
        
        line = line_end + 1;
    }

    SDL_free(buf);
    return controllers;
}
コード例 #16
0
ファイル: sound_openal.c プロジェクト: Delll/naev
/*
 * Vorbis stuff.
 */
static size_t ovpack_read( void *ptr, size_t size, size_t nmemb, void *datasource )
{  
   SDL_RWops *rw = datasource;
   return (size_t) SDL_RWread( rw, ptr, size, nmemb );
}
コード例 #17
0
ファイル: IMG_pcx.c プロジェクト: mhernando/SDL2_image
/* Load a PCX type image from an SDL datasource */
SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src)
{
    Sint64 start;
    struct PCXheader pcxh;
    Uint32 Rmask;
    Uint32 Gmask;
    Uint32 Bmask;
    Uint32 Amask;
    SDL_Surface *surface = NULL;
    int width, height;
    int y, bpl;
    Uint8 *row, *buf = NULL;
    char *error = NULL;
    int bits, src_bits;

    if ( !src ) {
        /* The error message has been set in SDL_RWFromFile */
        return NULL;
    }
    start = SDL_RWtell(src);

    if ( ! SDL_RWread(src, &pcxh, sizeof(pcxh), 1) ) {
        error = "file truncated";
        goto done;
    }
    pcxh.Xmin = SDL_SwapLE16(pcxh.Xmin);
    pcxh.Ymin = SDL_SwapLE16(pcxh.Ymin);
    pcxh.Xmax = SDL_SwapLE16(pcxh.Xmax);
    pcxh.Ymax = SDL_SwapLE16(pcxh.Ymax);
    pcxh.BytesPerLine = SDL_SwapLE16(pcxh.BytesPerLine);

    /* Create the surface of the appropriate type */
    width = (pcxh.Xmax - pcxh.Xmin) + 1;
    height = (pcxh.Ymax - pcxh.Ymin) + 1;
    Rmask = Gmask = Bmask = Amask = 0;
    src_bits = pcxh.BitsPerPixel * pcxh.NPlanes;
    if((pcxh.BitsPerPixel == 1 && pcxh.NPlanes >= 1 && pcxh.NPlanes <= 4)
       || (pcxh.BitsPerPixel == 8 && pcxh.NPlanes == 1)) {
        bits = 8;
    } else if(pcxh.BitsPerPixel == 8 && pcxh.NPlanes == 3) {
        bits = 24;
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
            Rmask = 0x000000FF;
            Gmask = 0x0000FF00;
            Bmask = 0x00FF0000;
#else
            Rmask = 0xFF0000;
            Gmask = 0x00FF00;
            Bmask = 0x0000FF;
#endif
    } else {
        error = "unsupported PCX format";
        goto done;
    }
    surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height,
                   bits, Rmask, Gmask, Bmask, Amask);
    if ( surface == NULL )
        goto done;

    bpl = pcxh.NPlanes * pcxh.BytesPerLine;
    if (bpl > surface->pitch) {
        error = "bytes per line is too large (corrupt?)";
    }
    buf = (Uint8 *)SDL_malloc(bpl);
    row = (Uint8 *)surface->pixels;
    for ( y=0; y<surface->h; ++y ) {
        /* decode a scan line to a temporary buffer first */
        int i, count = 0;
        Uint8 ch;
        Uint8 *dst = (src_bits == 8) ? row : buf;
        if ( pcxh.Encoding == 0 ) {
            if(!SDL_RWread(src, dst, bpl, 1)) {
                error = "file truncated";
                goto done;
            }
        } else {
            for(i = 0; i < bpl; i++) {
                if(!count) {
                    if(!SDL_RWread(src, &ch, 1, 1)) {
                        error = "file truncated";
                        goto done;
                    }
                    if( (ch & 0xc0) == 0xc0) {
                        count = ch & 0x3f;
                        if(!SDL_RWread(src, &ch, 1, 1)) {
                            error = "file truncated";
                            goto done;
                        }
                    } else
                        count = 1;
                }
                dst[i] = ch;
                count--;
            }
        }

        if(src_bits <= 4) {
            /* expand planes to 1 byte/pixel */
            Uint8 *innerSrc = buf;
            int plane;
            for(plane = 0; plane < pcxh.NPlanes; plane++) {
                int j, k, x = 0;
                for(j = 0; j < pcxh.BytesPerLine; j++) {
                    Uint8 byte = *innerSrc++;
                    for(k = 7; k >= 0; k--) {
                        unsigned bit = (byte >> k) & 1;
                        /* skip padding bits */
                        if (j * 8 + k >= width)
                            continue;
                        row[x++] |= bit << plane;
                    }
                }
            }
        } else if(src_bits == 24) {
コード例 #18
0
ファイル: sound_openal.c プロジェクト: Delll/naev
/**
 * @brief Loads a wav file from the rw if possible.
 *
 * @note Closes the rw.
 *
 *    @param snd Sound to load wav into.
 *    @param rw Data for the wave.
 */
static int sound_al_loadWav( alSound *snd, SDL_RWops *rw )
{
   int len;
   uint32_t i;
   char magic[4], *buf;
   ALenum format;
   uint32_t filelen, chunklen, rate, unused32;
   uint16_t compressed, channels, align, unused16;

   /* Some initialization. */
   compressed = 0;
   channels   = 0;

   /* Seek to start. */
   SDL_RWseek( rw, 0, SEEK_SET );

   /* Check RIFF header. */
   if (sound_al_wavReadCmp( rw, "RIFF", 4 )) {
      WARN("RIFF header not found.");
      goto wav_err;
   }
   /* Get file length. */
   if (sound_al_wavGetLen32( rw, &filelen )) {
      WARN("Unable to get WAVE length.");
      goto wav_err;
   }
   /* Check WAVE header. */
   if (sound_al_wavReadCmp( rw, "WAVE", 4 )) {
      WARN("WAVE header not found.");
      goto wav_err;
   }

   /*
    * Chunk information header.
    */
   /* Check chunk header. */
   if (sound_al_wavReadCmp( rw, "fmt ", 4 )) {
      WARN("Chunk header 'fmt ' header not found.");
      goto wav_err;
   }
   /* Get chunk length. */
   if (sound_al_wavGetLen32( rw, &chunklen )) {
      WARN("Unable to get WAVE chunk length.");
      goto wav_err;
   }
   i = 0;

   /* Get compression. */
   if (sound_al_wavGetLen16( rw, &compressed )) {
      WARN("Unable to get WAVE chunk compression type.");
      goto wav_err;
   }
   if (compressed != 0x0001) {
      WARN("Unsupported WAVE chunk compression '0x%04x'.", compressed);
      goto wav_err;
   }
   i += 2;

   /* Get channels. */
   if (sound_al_wavGetLen16( rw, &channels )) {
      WARN("Unable to get WAVE chunk channels.");
      goto wav_err;
   }
   i += 2;

   /* Get sample rate. */
   if (sound_al_wavGetLen32( rw, &rate )) {
      WARN("Unable to get WAVE chunk sample rate.");
      goto wav_err;
   }
   i += 4;

   /* Get average bytes. */
   if (sound_al_wavGetLen32( rw, &unused32 )) {
      WARN("Unable to get WAVE chunk average byte rate.");
      goto wav_err;
   }
   i += 4;

   /* Get block align. */
   if (sound_al_wavGetLen16( rw, &unused16 )) {
      WARN("Unable to get WAVE chunk block align.");
      goto wav_err;
   }
   i += 2;

   /* Get significant bits. */
   if (sound_al_wavGetLen16( rw, &align )) {
      WARN("Unable to get WAVE chunk significant bits.");
      goto wav_err;
   }
   align /= channels;
   i += 2;

   /* Seek to end. */
   SDL_RWseek( rw, chunklen-i, SEEK_CUR );


   /* Read new header. */
   len = SDL_RWread( rw, magic, 4, 1 );
   if (len != 1) {
      WARN("Unable to read chunk header.");
      goto wav_err;
   }

   /* Skip fact. */
   if (memcmp( magic, "fact", 4)==0) {
      /* Get chunk length. */
      if (sound_al_wavGetLen32( rw, &chunklen )) {
         WARN("Unable to get WAVE chunk data length.");
         goto wav_err;
      }

      /* Seek to end of chunk. */
      SDL_RWseek( rw, chunklen, SEEK_CUR );

      /* Read new header. */
      len = SDL_RWread( rw, magic, 4, 1 );
      if (len != 1) {
         WARN("Unable to read chunk header.");
         goto wav_err;
      }
   }

   /* Should be chunk header now. */
   if (memcmp( magic, "data", 4)) {
      WARN("Unable to find WAVE 'data' chunk header.");
      goto wav_err;
   }

   /*
    * Chunk data header.
    */
   /* Get chunk length. */
   if (sound_al_wavGetLen32( rw, &chunklen )) {
      WARN("Unable to get WAVE chunk data length.");
      goto wav_err;
   }

   /* Load the chunk data. */
   buf = malloc( chunklen );
   i = 0;
   while (i < chunklen) {
      i += SDL_RWread( rw, &buf[i], 1, chunklen-i );
   }

   /* Calculate format. */
   if (channels == 2) {
      if (align == 16)
         format = AL_FORMAT_STEREO16;
      else if (align == 8)
         format = AL_FORMAT_STEREO8;
      else {
         WARN("Unsupported byte alignment (%d) in WAVE file.", align);
         goto chunk_err;
      }
   }
   else if (channels == 1) {
      if (align == 16)
         format = AL_FORMAT_MONO16;
      else if (align == 8)
         format = AL_FORMAT_MONO8;
      else {
         WARN("Unsupported byte alignment (%d) in WAVE file.", align);
         goto chunk_err;
      }
   }
   else {
      WARN("Unsupported number of channels (%d) in WAVE file.", channels);
      goto chunk_err;
   }

   soundLock();
   /* Create new buffer. */
   alGenBuffers( 1, &snd->u.al.buf );
   /* Put into the buffer. */
   alBufferData( snd->u.al.buf, format, buf, chunklen, rate );
   soundUnlock();

   free(buf);
   return 0;

chunk_err:
   free(buf);
wav_err:
   return -1;
}
コード例 #19
0
ファイル: IMG_webp.c プロジェクト: vasilecristian/SDL2_image
SDL_Surface *IMG_LoadWEBP_RW(SDL_RWops *src)
{
    Sint64 start;
    const char *error = NULL;
    SDL_Surface *volatile surface = NULL;
    Uint32 Rmask;
    Uint32 Gmask;
    Uint32 Bmask;
    Uint32 Amask;
    WebPBitstreamFeatures features;
    int raw_data_size;
    uint8_t *raw_data = NULL;
    int r;
    uint8_t *ret;

    if ( !src ) {
        /* The error message has been set in SDL_RWFromFile */
        return NULL;
    }

    start = SDL_RWtell(src);

    if ( !IMG_Init(IMG_INIT_WEBP) ) {
        goto error;
    }

    raw_data_size = -1;
    if ( !webp_getinfo( src, &raw_data_size ) ) {
        error = "Invalid WEBP";
        goto error;
    }

    // seek to start of file
    SDL_RWseek(src, 0, RW_SEEK_SET );

    raw_data = (uint8_t*) SDL_malloc( raw_data_size );
    if ( raw_data == NULL ) {
        error = "Failed to allocate enought buffer for WEBP";
        goto error;
    }

    r = SDL_RWread(src, raw_data, 1, raw_data_size );
    if ( r != raw_data_size ) {
        error = "Failed to read WEBP";
        goto error;
    }

#if 0
    // extract size of picture, not interesting since we don't know about alpha channel
    int width = -1, height = -1;
    if ( !WebPGetInfo( raw_data, raw_data_size, &width, &height ) ) {
        printf("WebPGetInfo has failed\n" );
        return NULL;
    }
#endif

    if ( lib.webp_get_features_internal( raw_data, raw_data_size, &features, WEBP_DECODER_ABI_VERSION ) != VP8_STATUS_OK ) {
        error = "WebPGetFeatures has failed";
        goto error;
    }

    /* Check if it's ok !*/
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
    Rmask = 0x000000FF;
    Gmask = 0x0000FF00;
    Bmask = 0x00FF0000;
    Amask = (features.has_alpha) ? 0xFF000000 : 0;
#else
    s = (features.has_alpha) ? 0 : 8;
    Rmask = 0xFF000000 >> s;
    Gmask = 0x00FF0000 >> s;
    Bmask = 0x0000FF00 >> s;
    Amask = 0x000000FF >> s;
#endif

    surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
            features.width, features.height,
            features.has_alpha?32:24, Rmask,Gmask,Bmask,Amask);

    if ( surface == NULL ) {
        error = "Failed to allocate SDL_Surface";
        goto error;
    }

    if ( features.has_alpha ) {
        ret = lib.webp_decode_rgba_into( raw_data, raw_data_size, (uint8_t *)surface->pixels, surface->pitch * surface->h,  surface->pitch );
    } else {
        ret = lib.webp_decode_rgb_into( raw_data, raw_data_size, (uint8_t *)surface->pixels, surface->pitch * surface->h,  surface->pitch );
    }

    if ( !ret ) {
        error = "Failed to decode WEBP";
        goto error;
    }

    return surface;


error:

    if ( surface ) {
        SDL_FreeSurface( surface );
    }

    if ( raw_data ) {
        SDL_free( raw_data );
    }

    if ( error ) {
        IMG_SetError( error );
    }

    SDL_RWseek(src, start, RW_SEEK_SET);
    return(NULL);
}
コード例 #20
0
MentatTextFile::MentatTextFile(SDL_RWops* rwop) {
	unsigned char* pFiledata;

	if(rwop == NULL) {
	    throw std::invalid_argument("MentatTextFile:MentatTextFile(): rwop == NULL!");
	}

	int mentatTextFilesize = SDL_RWseek(rwop,0,SEEK_END);
	if(mentatTextFilesize <= 0) {
        throw std::runtime_error("MentatTextFile:MentatTextFile(): Cannot determine size of this file!");
	}

	if(mentatTextFilesize < 20) {
        throw std::runtime_error("MentatTextFile:MentatTextFile(): No valid mentat textfile: File too small!");
	}

	if(SDL_RWseek(rwop,0,SEEK_SET) != 0) {
        throw std::runtime_error("MentatTextFile:MentatTextFile(): Seeking in this mentat textfile failed!");
	}

	if( (pFiledata = (unsigned char*) malloc(mentatTextFilesize)) == NULL) {
        throw std::bad_alloc();
	}

	if(SDL_RWread(rwop, pFiledata, mentatTextFilesize, 1) != 1) {
	    free(pFiledata);
        throw std::runtime_error("MentatTextFile:MentatTextFile(): Reading this mentat textfile failed!");
	}

	if((pFiledata[0] != 'F') || (pFiledata[1] != 'O') || (pFiledata[2] != 'R') || (pFiledata[3] != 'M')) {
		free(pFiledata);
		throw std::runtime_error("MentatTextFile:MentatTextFile(): Invalid mentat textfile! Must start with 'FORM'");
	}

	Uint32 formSectionSize = SDL_SwapBE32(*((Uint32*) (pFiledata+4)));

	if((int) formSectionSize + 8 != mentatTextFilesize) {
		free(pFiledata);
		throw std::runtime_error("MentatTextFile:MentatTextFile(): Invalid mentat textfile!");
	}

	if((pFiledata[8] != 'M') || (pFiledata[9] != 'E') || (pFiledata[10] != 'N') || (pFiledata[11] != 'T') || (pFiledata[12] != 'N') || (pFiledata[13] != 'A') || (pFiledata[14] != 'M') || (pFiledata[15] != 'E')) {
		free(pFiledata);
		throw std::runtime_error("MentatTextFile:MentatTextFile(): Invalid mentat textfile!");
	}

	Uint32 mentnameSectionSize = SDL_SwapBE32(*((Uint32*) (pFiledata+16)));

	unsigned char* pMentNameSection = pFiledata + 20;

	unsigned char* pCurrentPos = pMentNameSection;
	unsigned char* pMentNameSectionEnd = pMentNameSection + mentnameSectionSize;
	while(pCurrentPos < pMentNameSectionEnd) {
		unsigned int entryLength = *pCurrentPos;

		Uint32 entryContentOffset = SDL_SwapBE32(*((Uint32*) (pCurrentPos+1)));

		unsigned int numMenuEntry = *((char*) pCurrentPos + 5) - '0';
		unsigned int menuLevel = *((char*) pCurrentPos + 6) - '0';
		std::string entryTitle((char*) pCurrentPos + 7);

		int techLevel = *((char*) pCurrentPos + entryLength - 1);

		if((int) entryContentOffset >= mentatTextFilesize) {
			free(pFiledata);
			fprintf(stderr, "0x%x\n", entryContentOffset);
			throw std::runtime_error("MentatTextFile:MentatTextFile(): Entry offset beyond file end!");
		}

		std::string compressedEntryContent((char*) pFiledata + entryContentOffset);

		std::string entryContent = convertCP850ToISO8859_1(decodeString(compressedEntryContent));

		size_t delimPos = entryContent.find_first_of('*');
		std::string filename = entryContent.substr(0,delimPos);
		std::string nameAndContent = (delimPos == std::string::npos) ? "" : entryContent.substr(delimPos + 1);

		size_t delimPos2 = nameAndContent.find(" \n");
		std::string name = nameAndContent.substr(0,delimPos2);
		std::string content = (delimPos2 == std::string::npos) ? "" : nameAndContent.substr(delimPos2 + 2);

		mentatEntries.push_back( MentatEntry( convertCP850ToISO8859_1(entryTitle), numMenuEntry, menuLevel, techLevel, filename, name, content) );

		pCurrentPos += entryLength;
	}

	free(pFiledata);
}
コード例 #21
0
ファイル: fsys.c プロジェクト: exdev/exsdk
size_t ex_os_fread ( ex_file_t *_file, void *_buf, uint64 _size ) {
    return SDL_RWread( (SDL_RWops *)_file, _buf, 1, (size_t)_size );
}
コード例 #22
0
ファイル: screen_model.c プロジェクト: auuuux/multigcs
static void model_parseDoc (char *docname) {
	xmlDocPtr doc;
	xmlNodePtr cur;
	xmlChar *key;

	if (strncmp(docname, "./", 2) == 0) {
		docname += 2;
	}

	char *buffer = NULL;
	int len = 0;
	SDL_RWops *ops_file = SDL_RWFromFile(docname, "r");
	if (ops_file == NULL) {
		SDL_Log("map: Document open failed: %s\n", docname);
		return;
	}
	len = SDL_RWseek(ops_file, 0, SEEK_END);
	SDL_RWseek(ops_file, 0, SEEK_SET);
	buffer = malloc(len);
	SDL_RWread(ops_file, buffer, 1, len);
	doc = xmlParseMemory(buffer, len);
	SDL_RWclose(ops_file);
	free(buffer);

	if (doc == NULL) {
		SDL_Log("Document parsing failed: %s\n", docname);
		return;
	}
	cur = xmlDocGetRootElement(doc);
	if (cur == NULL) {
		xmlFreeDoc(doc);
		die("Document is Empty!!!\n");
		return;
	}
	strncpy(ModelData[ModelActive].name, basename(docname), 199);
	cur = cur->xmlChildrenNode;
	while (cur != NULL) {
		if ((!xmlStrcasecmp(cur->name, (const xmlChar *)"name"))) {
			key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
			if ((char *)key != NULL) {
				strncpy(ModelData[ModelActive].name, (char *)key, 199);
				if (strstr(ModelData[ModelActive].name, ".xml\0") <= 0) {
					strcat(ModelData[ModelActive].name, ".xml");
				}
			}
			xmlFree(key);
		} else if ((!xmlStrcasecmp(cur->name, (const xmlChar *)"image"))) {
			key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
			if ((char *)key != NULL) {
				strncpy(ModelData[ModelActive].image, (char *)key, 511);
			}
			xmlFree(key);
		} else if ((!xmlStrcasecmp(cur->name, (const xmlChar *)"type"))) {
			key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
			if ((char *)key != NULL) {
				ModelData[ModelActive].dronetype = model_get_dronetype_by_name((char *)key);
			}
			xmlFree(key);
		} else if ((!xmlStrcasecmp(cur->name, (const xmlChar *)"telemetry"))) {
			model_parseTelemetry(doc, cur);

		} else if ((!xmlStrcasecmp(cur->name, (const xmlChar *)"mavlink"))) {
			mavlink_xml_load(ModelActive, doc, cur);
		} else if ((!xmlStrcasecmp(cur->name, (const xmlChar *)"mwi21"))) {
			mwi21_xml_load(ModelActive, doc, cur);
		} else if ((!xmlStrcasecmp(cur->name, (const xmlChar *)"OpenPilot"))) {
			openpilot_xml_load(doc, cur);

		}
		cur = cur->next;
	}
	xmlFreeDoc(doc);
	return;
}
コード例 #23
0
ファイル: save_data.cpp プロジェクト: openglad/openglad
bool SaveData::load(const std::string& filename)
{
	char filler[50] = "GTLGTLGTLGTLGTLGTLGTLGTLGTLGTLGTLGTLGTLGTL"; // for RESERVED
	SDL_RWops  *infile;
	char temp_filename[80];

	char temptext[10] = "GTL";
	char savedgame[40];
	char temp_campaign[41];
	strcpy(temp_campaign, "org.openglad.gladiator");
	temp_campaign[40] = '\0';
	char temp_version = 9;
	Uint32 newcash;
	Uint32 newscore = 0;
	//  short numguys;
	short listsize;
	short i;

	char tempname[12] = "FRED";
	char guyname[12] = "JOE";
	char temp_order, temp_family;
	short temp_str, temp_dex, temp_con;
	short temp_short, temp_arm, temp_lev;
	unsigned char temp_numplayers;
	Uint32 temp_exp;
	short temp_kills;
	Sint32 temp_level_kills;
	Sint32 temp_td, temp_th, temp_ts;
	short temp_teamnum; // version 5+
	short temp_allied;            // v.7+
	short temp_registered;        // v.7+

	// Format of a team list file is:
	// 3-byte header: 'GTL'
	// 1-byte version number
	// 2-bytes registered mark            // Versions 7+
	// 40-bytes saved game name, version 2 and up
	// 40-bytes current campaign ID       // Version 8+
	// 2-bytes (short) = scenario number
	// 4-bytes (Sint32)= cash (unsigned)
	// 4-bytes (Sint32)= score (unsigned)
	// 4-bytes (Sint32)= cash-B (unsigned)   // All alternate scores
	// 4-bytes (Sint32)= score-B (unsigned)  // version 6+
	// 4-bytes (Sint32)= cash-C (unsigned)
	// 4-bytes (Sint32)= score-C (unsigned)
	// 4-bytes (Sint32)= cash-D (unsigned)
	// 4-bytes (Sint32)= score-D (unsigned)
	// 2-bytes Allied mode                // Versions 7+
	// 2-bytes (short) = # of team members in list
	// 1-byte number of players
	// 31-bytes RESERVED
	// List of n objects, each of 58-bytes of form:
	// 1-byte ORDER
	// 1-byte FAMILY
	// 12-byte name
	// 2-bytes strength
	// 2-bytes dexterity
	// 2-bytes constitution
	// 2-bytes intelligence
	// 2-bytes armor
	// 2-bytes level  // Does not include upgraded stats in version 8 or lower
	// 4-bytes unsigned experience
	// 2-bytes # kills, v.3
	// 4-bytes # total levels killed, v.3
	// 4-bytes total damage dealt, v.4+
	// 4-bytes total hits inflicted, v.4+
	// 4-bytes total shots made, v.4+
	// 2-bytes team number
	// 2*4 = 8 bytes RESERVED
	// List of 200 or 500 (max levels) 1-byte scenario-level status  // Versions 1-7
	// 2-bytes Number of campaigns in list      // Version 8+
	// List of n campaigns                      // Version 8+
	//   40-bytes Campaign ID string
	//   2-bytes Current level in this campaign
	//   2-bytes Number of level indices in list
	//   List of n level indices
	//     2-bytes Level index
    
    Log("Loading save: %s\n", filename.c_str());
	strcpy(temp_filename, filename.c_str());
	strcat(temp_filename, ".gtl"); // gladiator team list

	if ( (infile = open_read_file("save/", temp_filename)) == NULL )
	{
		Log("Failed to open save file: %s\n", filename.c_str());
		return 0;
	}
    
    completed_levels.clear();
    current_levels.clear();
    
	for(int i = 0; i < team_size; i++)
    {
        delete team_list[i];
        team_list[i] = NULL;
    }
    team_size = 0;

	// Read id header
	SDL_RWread(infile, temptext, 3, 1);
	if ( strcmp(temptext,"GTL"))
	{
	    SDL_RWclose(infile);
		Log("Error, selected file is not a GTL file: %s\n", filename.c_str());
		return 0; //not a gtl file
	}

	// Read version number
	SDL_RWread(infile, &temp_version, 1, 1);

	// Versions 7+ have a registered mark ..
	if (temp_version >= 7)
	{
		SDL_RWread(infile, &temp_registered, 2, 1);
	}

	// Do other stuff based on version ..
	if (temp_version != 1)
	{
		if (temp_version >= 2)
			SDL_RWread(infile, savedgame, 40, 1); // read and ignore the name
		else
		{
            SDL_RWclose(infile);
			Log("Error, selected files is not version one: %s\n", filename.c_str());
			return 0;
		}
	}
	save_name = savedgame;

    // Read campaign ID
	if (temp_version >= 8)
	{
		SDL_RWread(infile, temp_campaign, 1, 40);
		temp_campaign[40] = '\0';
		if(strlen(temp_campaign) > 3)
            current_campaign = temp_campaign;
        else
            current_campaign = "org.openglad.gladiator";
	}
	
	// Read scenario number
	short temp_scenario;
	SDL_RWread(infile, &temp_scenario, 2, 1);
	scen_num = temp_scenario;

	// Read cash
	SDL_RWread(infile, &newcash, 4, 1);
	totalcash = newcash;
	// Read score
	SDL_RWread(infile, &newscore, 4, 1);
	totalscore = newscore;

	// Versions 6+ have a score for each possible team, 0-3
	if (temp_version >= 6)
	{
		for (i=0; i < 4; i++)
		{
			SDL_RWread(infile, &newcash, 4, 1);
			m_totalcash[i] = newcash;
			SDL_RWread(infile, &newscore, 4, 1);
			m_totalscore[i] = newscore;
		}
	}

	// Versions 7+ have the allied information ..
	if (temp_version >= 7)
	{
		SDL_RWread(infile, &temp_allied, 2, 1);
		allied_mode = temp_allied;
	}

	// Get # of guys to read
	SDL_RWread(infile, &listsize, 2, 1);

	// Read the # of players
	SDL_RWread(infile, &temp_numplayers, 1, 1);
	#ifdef DISABLE_MULTIPLAYER
	temp_numplayers = 1;
	#endif
	numplayers = temp_numplayers;

	// Read the reserved area, 31 bytes
	SDL_RWread(infile, filler, 31, 1);

	// Okay, we've read header .. now read the team list data ..
    for(int i = 0; i < listsize; i++)
    {
        guy* temp_guy = new guy;
        team_list[i] = temp_guy;
        team_size++;
        
		// Get temp values to be read
		temp_order = ORDER_LIVING; // may be changed later
		// Read name of current guy...
		memset(guyname, 0, 12);
		strcpy(guyname, tempname);
		// Now write all those values
		SDL_RWread(infile, &temp_order, 1, 1);
		SDL_RWread(infile, &temp_family,1, 1);
		SDL_RWread(infile, guyname, 12, 1);
		SDL_RWread(infile, &temp_str, 2, 1);
		SDL_RWread(infile, &temp_dex, 2, 1);
		SDL_RWread(infile, &temp_con, 2, 1);
		SDL_RWread(infile, &temp_short, 2, 1);
		SDL_RWread(infile, &temp_arm, 2, 1);
		SDL_RWread(infile, &temp_lev, 2, 1);
		SDL_RWread(infile, &temp_exp, 4, 1);
		// Below here is version 3 and up..
		SDL_RWread(infile, &temp_kills, 2, 1); // how many kills we have
		SDL_RWread(infile, &temp_level_kills, 4, 1); // levels of kills
		// Below here is version 4 and up ..
		SDL_RWread(infile, &temp_td, 4, 1); // total damage
		SDL_RWread(infile, &temp_th, 4, 1); // total hits
		SDL_RWread(infile, &temp_ts, 4, 1); // total shots
		SDL_RWread(infile, &temp_teamnum, 2, 1); // team number

		// And the filler
		SDL_RWread(infile, filler, 8, 1);
		// Now set the values ..
		temp_guy->family       = temp_family;
		strcpy(temp_guy->name,guyname);
		temp_guy->strength     = temp_str;
		temp_guy->dexterity    = temp_dex;
		temp_guy->constitution = temp_con;
		temp_guy->intelligence = temp_short;
		temp_guy->armor        = temp_arm;
		if(temp_version >= 9)
            temp_guy->set_level_number(temp_lev);
        else
            temp_guy->upgrade_to_level(temp_lev);
		temp_guy->exp          = temp_exp;
		if (temp_version >=3)
		{
			temp_guy->kills      = temp_kills;
			temp_guy->level_kills= temp_level_kills;
		}
		else // version 2 or earlier
		{
			temp_guy->kills      = 0;
			temp_guy->level_kills= 0;
		}
		if (temp_version >= 4)
		{
			temp_guy->total_damage = temp_td;
			temp_guy->total_hits   = temp_th;
			temp_guy->total_shots  = temp_ts;
		}
		else
		{
			temp_guy->total_damage = 0;
			temp_guy->total_hits   = 0;
			temp_guy->total_shots  = 0;
		}
		if (temp_version >= 5)
		{
			temp_guy->teamnum = temp_teamnum;
		}
		else
		{
			temp_guy->teamnum = 0;
		}
	}
	
    // Make sure the default campaign is included
	completed_levels.insert(std::make_pair("org.openglad.gladiator", std::set<int>()));
	current_levels.insert(std::make_pair("org.openglad.gladiator", 1));

    if(temp_version < 8)
    {
        char levelstatus[MAX_LEVELS];
        memset(levelstatus, 0, 500);
        
        if (temp_version >= 5)
            SDL_RWread(infile, levelstatus, 500, 1);
        else
            SDL_RWread(infile, levelstatus, 200, 1);
        
        // Guaranteed to be the default campaign if version < 8
        for(int i = 0; i < 500; i++)
        {
            if(levelstatus[i])
                add_level_completed(current_campaign, i);
        }
    }
    else
    {
        short num_campaigns = 0;
        char campaign[41];
        short num_levels = 0;
        // How many campaigns are stored?
        SDL_RWread(infile, &num_campaigns, 2, 1);
        for(int i = 0; i < num_campaigns; i++)
        {
            // Get the campaign ID (40 chars)
            SDL_RWread(infile, campaign, 1, 40);
            campaign[40] = '\0';
            
            short index = 1;
            // Get the current level for this campaign
            SDL_RWread(infile, &index, 2, 1);
            current_levels[campaign] = index;
            
            // Get the number of cleared levels
            SDL_RWread(infile, &num_levels, 2, 1);
            for(int j = 0; j < num_levels; j++)
            {
                // Get the level index
                SDL_RWread(infile, &index, 2, 1);
                
                // Add it to our list
                add_level_completed(campaign, index);
            }
        }
    }
    
	Log("Loading campaign: %s\n", current_campaign.c_str());
    int current_level = load_campaign(current_campaign, current_levels);
    if(current_level >= 0)
    {
        if(scen_num != current_level)
            Log("Error: Loaded scen_num %d, but found current_level %d\n", scen_num, current_level);
        //scen_num = current_level;
    }

    SDL_RWclose(infile);

	return 1;
}
コード例 #24
0
ファイル: File.cpp プロジェクト: PeteX/Urho3D
unsigned File::Read(void* dest, unsigned size)
{
    #ifdef ANDROID
    if (!handle_ && !assetHandle_)
    #else
    if (!handle_)
    #endif
    {
        // Do not log the error further here to prevent spamming the stderr stream
        return 0;
    }

    if (mode_ == FILE_WRITE)
    {
        LOGERROR("File not opened for reading");
        return 0;
    }

    if (size + position_ > size_)
        size = size_ - position_;
    if (!size)
        return 0;

    #ifdef ANDROID
    if (assetHandle_)
    {
        unsigned sizeLeft = size;
        unsigned char* destPtr = (unsigned char*)dest;

        while (sizeLeft)
        {
            if (readBufferOffset_ >= readBufferSize_)
            {
                readBufferSize_ = Min((int)size_ - position_, (int)READ_BUFFER_SIZE);
                readBufferOffset_ = 0;
                SDL_RWread(assetHandle_, readBuffer_.Get(), readBufferSize_, 1);
            }

            unsigned copySize = Min((int)(readBufferSize_ - readBufferOffset_), (int)sizeLeft);
            memcpy(destPtr, readBuffer_.Get() + readBufferOffset_, copySize);
            destPtr += copySize;
            sizeLeft -= copySize;
            readBufferOffset_ += copySize;
            position_ += copySize;
        }

        return size;
    }
    #endif
    if (compressed_)
    {
        unsigned sizeLeft = size;
        unsigned char* destPtr = (unsigned char*)dest;

        while (sizeLeft)
        {
            if (!readBuffer_ || readBufferOffset_ >= readBufferSize_)
            {
                unsigned char blockHeaderBytes[4];
                fread(blockHeaderBytes, sizeof blockHeaderBytes, 1, (FILE*)handle_);

                MemoryBuffer blockHeader(&blockHeaderBytes[0], sizeof blockHeaderBytes);
                unsigned unpackedSize = blockHeader.ReadUShort();
                unsigned packedSize = blockHeader.ReadUShort();

                if (!readBuffer_)
                {
                    readBuffer_ = new unsigned char[unpackedSize];
                    inputBuffer_ = new unsigned char[LZ4_compressBound(unpackedSize)];
                }

                /// \todo Handle errors
                fread(inputBuffer_.Get(), packedSize, 1, (FILE*)handle_);
                LZ4_decompress_fast((const char*)inputBuffer_.Get(), (char *)readBuffer_.Get(), unpackedSize);

                readBufferSize_ = unpackedSize;
                readBufferOffset_ = 0;
            }

            unsigned copySize = Min((int)(readBufferSize_ - readBufferOffset_), (int)sizeLeft);
            memcpy(destPtr, readBuffer_.Get() + readBufferOffset_, copySize);
            destPtr += copySize;
            sizeLeft -= copySize;
            readBufferOffset_ += copySize;
            position_ += copySize;
        }

        return size;
    }

    size_t ret = fread(dest, size, 1, (FILE*)handle_);
    if (ret != 1)
    {
        // Return to the position where the read began
        fseek((FILE*)handle_, position_ + offset_, SEEK_SET);
        LOGERROR("Error while reading from file " + GetName());
        return 0;
    }

    position_ += size;
    return size;
}
コード例 #25
0
/**
 * @brief Makes sure parameters work properly. Local helper function.
 *
 * \sa
 * http://wiki.libsdl.org/moin.cgi/SDL_RWseek
 * http://wiki.libsdl.org/moin.cgi/SDL_RWread
 */
void
_testGenericRWopsValidations(SDL_RWops *rw, int write)
{
   char buf[sizeof(RWopsHelloWorldTestString)];
   Sint64 i;
   size_t s;
   int seekPos = SDLTest_RandomIntegerInRange(4, 8);

   /* Clear buffer */
   SDL_zero(buf);

   /* Set to start. */
   i = SDL_RWseek(rw, 0, RW_SEEK_SET );
   SDLTest_AssertPass("Call to SDL_RWseek succeeded");
   SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_RWseek (RW_SEEK_SET), expected 0, got %"SDL_PRIs64, i);

   /* Test write. */
   s = SDL_RWwrite(rw, RWopsHelloWorldTestString, sizeof(RWopsHelloWorldTestString)-1, 1);
   SDLTest_AssertPass("Call to SDL_RWwrite succeeded");
   if (write) {
        SDLTest_AssertCheck(s == (size_t)1, "Verify result of writing one byte with SDL_RWwrite, expected 1, got %i", (int) s);
   }
   else {
        SDLTest_AssertCheck(s == (size_t)0, "Verify result of writing with SDL_RWwrite, expected: 0, got %i", (int) s);
   }

   /* Test seek to random position */
   i = SDL_RWseek( rw, seekPos, RW_SEEK_SET );
   SDLTest_AssertPass("Call to SDL_RWseek succeeded");
   SDLTest_AssertCheck(i == (Sint64)seekPos, "Verify seek to %i with SDL_RWseek (RW_SEEK_SET), expected %i, got %"SDL_PRIs64, seekPos, seekPos, i);

   /* Test seek back to start */
   i = SDL_RWseek(rw, 0, RW_SEEK_SET );
   SDLTest_AssertPass("Call to SDL_RWseek succeeded");
   SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_RWseek (RW_SEEK_SET), expected 0, got %"SDL_PRIs64, i);

   /* Test read */
   s = SDL_RWread( rw, buf, 1, sizeof(RWopsHelloWorldTestString)-1 );
   SDLTest_AssertPass("Call to SDL_RWread succeeded");
   SDLTest_AssertCheck(
       s == (size_t)(sizeof(RWopsHelloWorldTestString)-1),
       "Verify result from SDL_RWread, expected %i, got %i",
       (int) (sizeof(RWopsHelloWorldTestString)-1),
       (int) s);
   SDLTest_AssertCheck(
       SDL_memcmp(buf, RWopsHelloWorldTestString, sizeof(RWopsHelloWorldTestString)-1 ) == 0,
       "Verify read bytes match expected string, expected '%s', got '%s'", RWopsHelloWorldTestString, buf);

   /* More seek tests. */
   i = SDL_RWseek( rw, -4, RW_SEEK_CUR );
   SDLTest_AssertPass("Call to SDL_RWseek(...,-4,RW_SEEK_CUR) succeeded");
   SDLTest_AssertCheck(
       i == (Sint64)(sizeof(RWopsHelloWorldTestString)-5),
       "Verify seek to -4 with SDL_RWseek (RW_SEEK_CUR), expected %i, got %i",
       (int) (sizeof(RWopsHelloWorldTestString)-5),
       (int) i);

   i = SDL_RWseek( rw, -1, RW_SEEK_END );
   SDLTest_AssertPass("Call to SDL_RWseek(...,-1,RW_SEEK_END) succeeded");
   SDLTest_AssertCheck(
       i == (Sint64)(sizeof(RWopsHelloWorldTestString)-2),
       "Verify seek to -1 with SDL_RWseek (RW_SEEK_END), expected %i, got %i",
       (int) (sizeof(RWopsHelloWorldTestString)-2),
       (int) i);

   /* Invalid whence seek */
   i = SDL_RWseek( rw, 0, 999 );
   SDLTest_AssertPass("Call to SDL_RWseek(...,0,invalid_whence) succeeded");
   SDLTest_AssertCheck(
       i == (Sint64)(-1),
       "Verify seek with SDL_RWseek (invalid_whence); expected: -1, got %i",
       (int) i);
}
コード例 #26
0
ファイル: IMG_lbm.c プロジェクト: knepe/cdogs-sdl-android
SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src )
{
	int start;
	SDL_Surface *Image;
	Uint8       id[4], pbm, colormap[MAXCOLORS*3], *MiniBuf, *ptr, count, color, msk;
	Uint32      size, bytesloaded, nbcolors;
	Uint32      i, j, bytesperline, nbplanes, stencil, plane, h;
	Uint32      remainingbytes;
	Uint32      width;
	BMHD	      bmhd;
	char        *error;
	Uint8       flagHAM,flagEHB;

	Image   = NULL;
	error   = NULL;
	MiniBuf = NULL;

	if ( !src ) {
		/* The error message has been set in SDL_RWFromFile */
		return NULL;
	}
	start = SDL_RWtell(src);

	if ( !SDL_RWread( src, id, 4, 1 ) )
	{
		error="error reading IFF chunk";
		goto done;
	}

	/* Should be the size of the file minus 4+4 ( 'FORM'+size ) */
	if ( !SDL_RWread( src, &size, 4, 1 ) )
	{
		error="error reading IFF chunk size";
		goto done;
	}

	/* As size is not used here, no need to swap it */

	if ( memcmp( id, "FORM", 4 ) != 0 )
	{
		error="not a IFF file";
		goto done;
	}

	if ( !SDL_RWread( src, id, 4, 1 ) )
	{
		error="error reading IFF chunk";
		goto done;
	}

	pbm = 0;

	/* File format : PBM=Packed Bitmap, ILBM=Interleaved Bitmap */
	if ( !memcmp( id, "PBM ", 4 ) ) pbm = 1;
	else if ( memcmp( id, "ILBM", 4 ) )
	{
		error="not a IFF picture";
		goto done;
	}

	nbcolors = 0;

	memset( &bmhd, 0, sizeof( BMHD ) );
	flagHAM = 0;
	flagEHB = 0;

	while ( memcmp( id, "BODY", 4 ) != 0 )
	{
		if ( !SDL_RWread( src, id, 4, 1 ) ) 
		{
			error="error reading IFF chunk";
			goto done;
		}

		if ( !SDL_RWread( src, &size, 4, 1 ) )
		{
			error="error reading IFF chunk size";
			goto done;
		}

		bytesloaded = 0;

		size = SDL_SwapBE32( size );

		if ( !memcmp( id, "BMHD", 4 ) ) /* Bitmap header */
		{
			if ( !SDL_RWread( src, &bmhd, sizeof( BMHD ), 1 ) )
			{
				error="error reading BMHD chunk";
				goto done;
			}

			bytesloaded = sizeof( BMHD );

			bmhd.w 		= SDL_SwapBE16( bmhd.w );
			bmhd.h 		= SDL_SwapBE16( bmhd.h );
			bmhd.x 		= SDL_SwapBE16( bmhd.x );
			bmhd.y 		= SDL_SwapBE16( bmhd.y );
			bmhd.tcolor = SDL_SwapBE16( bmhd.tcolor );
			bmhd.Lpage 	= SDL_SwapBE16( bmhd.Lpage );
			bmhd.Hpage 	= SDL_SwapBE16( bmhd.Hpage );
		}

		if ( !memcmp( id, "CMAP", 4 ) ) /* palette ( Color Map ) */
		{
			if ( !SDL_RWread( src, &colormap, size, 1 ) )
			{
				error="error reading CMAP chunk";
				goto done;
			}

			bytesloaded = size;
			nbcolors = size / 3;
		}

		if ( !memcmp( id, "CAMG", 4 ) ) /* Amiga ViewMode  */
		{
			Uint32 viewmodes;
			if ( !SDL_RWread( src, &viewmodes, sizeof(viewmodes), 1 ) )
			{
				error="error reading CAMG chunk";
				goto done;
			}

			bytesloaded = size;
			viewmodes = SDL_SwapBE32( viewmodes );
			if ( viewmodes & 0x0800 )
				flagHAM = 1;
			if ( viewmodes & 0x0080 )
				flagEHB = 1;
		}

		if ( memcmp( id, "BODY", 4 ) )
		{
			if ( size & 1 )	++size;  	/* padding ! */
			size -= bytesloaded;
			/* skip the remaining bytes of this chunk */
			if ( size )	SDL_RWseek( src, size, RW_SEEK_CUR );
		}
	}

	/* compute some usefull values, based on the bitmap header */

	width = ( bmhd.w + 15 ) & 0xFFFFFFF0;  /* Width in pixels modulo 16 */

	bytesperline = ( ( bmhd.w + 15 ) / 16 ) * 2;

	nbplanes = bmhd.planes;

	if ( pbm )                         /* File format : 'Packed Bitmap' */
	{
		bytesperline *= 8;
		nbplanes = 1;
	}

	stencil = (bmhd.mask & 1);   /* There is a mask ( 'stencil' ) */

	/* Allocate memory for a temporary buffer ( used for
           decompression/deinterleaving ) */

	MiniBuf = (void *)malloc( bytesperline * (nbplanes + stencil) );
	if ( MiniBuf == NULL )
	{
		error="no enough memory for temporary buffer";
		goto done;
	}

	if ( ( Image = SDL_CreateRGBSurface( SDL_SWSURFACE, width, bmhd.h, (bmhd.planes==24 || flagHAM==1)?24:8, 0, 0, 0, 0 ) ) == NULL )
	   goto done;

	if ( bmhd.mask & 2 )               /* There is a transparent color */
#if (SDL_VERSION_ATLEAST(1,3,0))
		SDL_SetColorKey( Image, SDL_TRUE, bmhd.tcolor );
#else
		SDL_SetColorKey( Image, SDL_SRCCOLORKEY, bmhd.tcolor );
#endif


	/* Update palette informations */

	/* There is no palette in 24 bits ILBM file */
	if ( nbcolors>0 && flagHAM==0 )
	{
		/* FIXME: Should this include the stencil? See comment below */
		int nbrcolorsfinal = 1 << (nbplanes + stencil);
		ptr = &colormap[0];

		for ( i=0; i<nbcolors; i++ )
		{
			Image->format->palette->colors[i].r = *ptr++;
			Image->format->palette->colors[i].g = *ptr++;
			Image->format->palette->colors[i].b = *ptr++;
		}

		/* Amiga EHB mode (Extra-Half-Bright) */
		/* 6 bitplanes mode with a 32 colors palette */
		/* The 32 last colors are the same but divided by 2 */
		/* Some Amiga pictures save 64 colors with 32 last wrong colors, */
		/* they shouldn't !, and here we overwrite these 32 bad colors. */
		if ( (nbcolors==32 || flagEHB ) && (1<<bmhd.planes)==64 )
		{
			nbcolors = 64;
			ptr = &colormap[0];
			for ( i=32; i<64; i++ )
			{
				Image->format->palette->colors[i].r = (*ptr++)/2;
				Image->format->palette->colors[i].g = (*ptr++)/2;
				Image->format->palette->colors[i].b = (*ptr++)/2;
			}
		}

		/* If nbcolors < 2^nbplanes, repeat the colormap */
		/* This happens when pictures have a stencil mask */
		if ( nbrcolorsfinal > (1<<bmhd.planes) ) {
			nbrcolorsfinal = (1<<bmhd.planes);
		}
		for ( i=nbcolors; i < (Uint32)nbrcolorsfinal; i++ )
		{
			Image->format->palette->colors[i].r = Image->format->palette->colors[i%nbcolors].r;
			Image->format->palette->colors[i].g = Image->format->palette->colors[i%nbcolors].g;
			Image->format->palette->colors[i].b = Image->format->palette->colors[i%nbcolors].b;
		}
		if ( !pbm )
			Image->format->palette->ncolors = nbrcolorsfinal;
	}

	/* Get the bitmap */

	for ( h=0; h < bmhd.h; h++ )
	{
		/* uncompress the datas of each planes */

		for ( plane=0; plane < (nbplanes+stencil); plane++ )
		{
			ptr = MiniBuf + ( plane * bytesperline );

			remainingbytes = bytesperline;

			if ( bmhd.tcomp == 1 )	    /* Datas are compressed */
			{
				do
				{
					if ( !SDL_RWread( src, &count, 1, 1 ) )
					{
						error="error reading BODY chunk";
						goto done;
					}

					if ( count & 0x80 )
					{
						count ^= 0xFF;
						count += 2; /* now it */

						if ( ( count > remainingbytes ) || !SDL_RWread( src, &color, 1, 1 ) )
						{
							error="error reading BODY chunk";
							goto done;
						}
						memset( ptr, color, count );
					}
					else
					{
						++count;

						if ( ( count > remainingbytes ) || !SDL_RWread( src, ptr, count, 1 ) )
						{
						   error="error reading BODY chunk";
							goto done;
						}
					}

					ptr += count;
					remainingbytes -= count;

				} while ( remainingbytes > 0 );
			}
			else
			{
				if ( !SDL_RWread( src, ptr, bytesperline, 1 ) )
				{
					error="error reading BODY chunk";
					goto done;
				}
			}
		}

		/* One line has been read, store it ! */

		ptr = Image->pixels;
		if ( nbplanes==24 || flagHAM==1 )
			ptr += h * width * 3;
		else
			ptr += h * width;

		if ( pbm )                 /* File format : 'Packed Bitmap' */
		{
		   memcpy( ptr, MiniBuf, width );
		}
		else		/* We have to un-interlace the bits ! */
		{
			if ( nbplanes!=24 && flagHAM==0 )
			{
				size = ( width + 7 ) / 8;

				for ( i=0; i < size; i++ )
				{
					memset( ptr, 0, 8 );

					for ( plane=0; plane < (nbplanes + stencil); plane++ )
					{
						color = *( MiniBuf + i + ( plane * bytesperline ) );
						msk = 0x80;

						for ( j=0; j<8; j++ )
						{
							if ( ( plane + j ) <= 7 ) ptr[j] |= (Uint8)( color & msk ) >> ( 7 - plane - j );
							else 	                    ptr[j] |= (Uint8)( color & msk ) << ( plane + j - 7 );

							msk >>= 1;
						}
					}
					ptr += 8;
				}
			}
			else
			{
コード例 #27
0
ファイル: IMG_tif.c プロジェクト: pgimeno/GCSx-fork
static tsize_t tiff_read(thandle_t fd, tdata_t buf, tsize_t size)
{
	return SDL_RWread((SDL_RWops*)fd, buf, 1, size);
}
コード例 #28
0
ファイル: music_gme.c プロジェクト: zigurana/PGE-Project
struct MUSIC_GME *GME_LoadSongRW(SDL_RWops *src, int trackNum)
{
    if(src != NULL) {

        void *bytes=0;
        long spcsize;

        Sint64 length=0;
        length = SDL_RWseek(src, 0, RW_SEEK_END);
        if (length < 0)
        {
            Mix_SetError("GAME-EMU: wrong file\n");
            return NULL;
        }

        SDL_RWseek(src, 0, RW_SEEK_SET);
        bytes = malloc(length);

        long bytes_l;
        unsigned char byte[1];
        spcsize=0;
        while( (bytes_l=SDL_RWread(src, &byte, sizeof(unsigned char), 1))!=0)
        {
            ((unsigned char*)bytes)[spcsize] = byte[0];
            spcsize++;
        }

        if (spcsize == 0)
        {
            Mix_SetError("GAME-EMU: wrong file\n");
            return NULL;
        }

        Music_Emu* game_emu;

        char *err = (char*)gme_open_data( bytes, spcsize, &game_emu, gme_t_sample_rate );
        //spc_load_spc( snes_spc, bytes, spcsize );
        free(bytes);
        if(err!=0)
        {
            Mix_SetError("GAME-EMU: %s", err);
            return NULL;
        }

        if((trackNum<0)||(trackNum >= gme_track_count(game_emu)))
            trackNum = gme_track_count(game_emu)-1;

        err = (char*)gme_start_track( game_emu, trackNum );
        if(err!=0)
        {
            Mix_SetError("GAME-EMU: %s", err);
            return NULL;
        }

        struct MUSIC_GME *spcSpec = (struct MUSIC_GME*)malloc(sizeof(struct MUSIC_GME));
        spcSpec->game_emu=game_emu;
        spcSpec->playing=0;
        spcSpec->gme_t_sample_rate=mixer.freq;
        spcSpec->volume=MIX_MAX_VOLUME;
        spcSpec->mus_title=NULL;
        spcSpec->mus_artist=NULL;
        spcSpec->mus_album=NULL;
        spcSpec->mus_copyright=NULL;
        gme_info_t *musInfo;
        err = (char*)gme_track_info(spcSpec->game_emu, &musInfo, trackNum);
        if(err!=0)
        {
            gme_delete(spcSpec->game_emu);
            free(spcSpec);
            Mix_SetError("GAME-EMU: %s", err);
            return NULL;
        }
        spcSpec->mus_title = (char *)SDL_malloc(sizeof(char)*strlen(musInfo->song)+1);
        strcpy(spcSpec->mus_title, musInfo->song);
        spcSpec->mus_artist = (char *)SDL_malloc(sizeof(char)*strlen(musInfo->author)+1);
        strcpy(spcSpec->mus_artist, musInfo->author);
        spcSpec->mus_album = (char *)SDL_malloc(sizeof(char)*strlen(musInfo->game)+1);
        strcpy(spcSpec->mus_album, musInfo->game);
        spcSpec->mus_copyright = (char *)SDL_malloc(sizeof(char)*strlen(musInfo->copyright)+1);
        strcpy(spcSpec->mus_copyright, musInfo->copyright);
        gme_free_info( musInfo );

        SDL_BuildAudioCVT(&spcSpec->cvt, AUDIO_S16, 2,
                          mixer.freq,
                          mixer.format,
                          mixer.channels,
                          mixer.freq);

        return spcSpec;
    }
    return NULL;
}
コード例 #29
0
// This callback reads some bytes from an SDL_rwops and copies it
// to a Quartz buffer (supplied by Apple framework).
static size_t MyProviderGetBytesCallback(void* rwops_userdata, void* quartz_buffer, size_t the_count)
{
	return (size_t)SDL_RWread((struct SDL_RWops *)rwops_userdata, quartz_buffer, 1, the_count);
}
コード例 #30
0
ファイル: mmio.c プロジェクト: Jay-Jay-OPL/ps2sdk-ports
static BOOL _mm_RWopsReader_Read(MREADER* reader,void* ptr,size_t size)
{
	return SDL_RWread(((MRWOPSREADER*)reader)->rw, ptr, size, 1);
}