mirror of
https://github.com/simtactics/niotso.git
synced 2025-07-04 13:47:05 -04:00
* Some files were still encoded with Windows newlines. I fixed all of that.
* Started using the static keyword in a few more places in the client * Updated libpng, libmpg123, and freetype to the latest versions, with position-independent code turned off rather than set to "both"
This commit is contained in:
parent
ecafff8c5c
commit
5713fc1bd1
23 changed files with 1432 additions and 1456 deletions
|
@ -1,208 +1,208 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
Audio.cpp - Copyright (c) 2011-2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "FileHandler.hpp"
|
||||
#include "wav/read_wav.h"
|
||||
#include "xa/read_xa.h"
|
||||
#include "utk/read_utk.h"
|
||||
#include "libmpg123/mpg123.h"
|
||||
|
||||
namespace File {
|
||||
|
||||
enum SoundType {
|
||||
FSND_WAV,
|
||||
FSND_XA,
|
||||
FSND_UTK,
|
||||
FSND_MP3,
|
||||
FSND_COUNT
|
||||
};
|
||||
|
||||
static uint8_t * ReadWAV(Sound_t * Sound, const uint8_t * InData, size_t FileSize);
|
||||
static uint8_t * ReadXA(Sound_t * Sound, const uint8_t * InData, size_t FileSize);
|
||||
static uint8_t * ReadUTK(Sound_t * Sound, const uint8_t * InData, size_t FileSize);
|
||||
static uint8_t * ReadMP3(Sound_t * Sound, const uint8_t * InData, size_t FileSize);
|
||||
|
||||
static const uint8_t Signature[] = {
|
||||
'R', //WAV
|
||||
'X', //XA
|
||||
'U', //UTK
|
||||
0xFF //MP3
|
||||
};
|
||||
static uint8_t* (* const SoundFunction[])(Sound_t*, const uint8_t*, size_t) = {
|
||||
ReadWAV,
|
||||
ReadXA,
|
||||
ReadUTK,
|
||||
ReadMP3
|
||||
};
|
||||
|
||||
Sound_t * ReadSoundFile(const char * Filename){
|
||||
uint8_t * InData = File::ReadFile(Filename);
|
||||
if(InData == NULL) return NULL;
|
||||
|
||||
if(File::FileSize < 4){
|
||||
free(InData);
|
||||
File::Error = FERR_INVALIDDATA;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Sound_t * Sound = (Sound_t*) malloc(sizeof(Sound_t));
|
||||
if(Sound == NULL){
|
||||
free(InData);
|
||||
File::Error = FERR_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(int i=0; i<FSND_COUNT; i++){
|
||||
if(InData[0] == Signature[i]){
|
||||
uint8_t * OutData = SoundFunction[i](Sound, InData, File::FileSize);
|
||||
free(InData);
|
||||
if(OutData == NULL){
|
||||
File::Error = FERR_INVALIDDATA;
|
||||
return NULL;
|
||||
}
|
||||
return Sound;
|
||||
}
|
||||
}
|
||||
|
||||
free(InData);
|
||||
File::Error = FERR_UNRECOGNIZED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static uint8_t * ReadWAV(Sound_t * Sound, const uint8_t * InData, size_t FileSize){
|
||||
wavheader_t WAVHeader;
|
||||
if(!wav_read_header(&WAVHeader, InData, FileSize)){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t * OutData = (uint8_t*) malloc(WAVHeader.DataSize);
|
||||
if(OutData == NULL){
|
||||
return NULL;
|
||||
}
|
||||
memcpy(OutData, InData+44, WAVHeader.DataSize);
|
||||
|
||||
Sound->Channels = WAVHeader.nChannels;
|
||||
Sound->SamplingRate = WAVHeader.nSamplesPerSec;
|
||||
Sound->BitDepth = WAVHeader.wBitsPerSample;
|
||||
Sound->Duration = WAVHeader.DataSize / WAVHeader.nBlockAlign;
|
||||
Sound->Data = OutData;
|
||||
return OutData;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t * ReadXA(Sound_t * Sound, const uint8_t * InData, size_t FileSize){
|
||||
xaheader_t XAHeader;
|
||||
if(!xa_read_header(&XAHeader, InData, FileSize)){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t * OutData = (uint8_t*) malloc(XAHeader.dwOutSize);
|
||||
if(OutData == NULL){
|
||||
return NULL;
|
||||
}
|
||||
if(!xa_decode(InData+24, OutData, XAHeader.Frames, XAHeader.nChannels)){
|
||||
free(OutData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Sound->Channels = XAHeader.nChannels;
|
||||
Sound->SamplingRate = XAHeader.nSamplesPerSec;
|
||||
Sound->BitDepth = XAHeader.wBitsPerSample;
|
||||
Sound->Duration = XAHeader.dwOutSize / XAHeader.nBlockAlign;
|
||||
Sound->Data = OutData;
|
||||
return OutData;
|
||||
}
|
||||
|
||||
static uint8_t * ReadUTK(Sound_t * Sound, const uint8_t * InData, size_t FileSize){
|
||||
utkheader_t UTKHeader;
|
||||
if(!utk_read_header(&UTKHeader, InData, FileSize)){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t * OutData = (uint8_t*) malloc(UTKHeader.dwOutSize);
|
||||
if(OutData == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool generated = false;
|
||||
if(!generated){
|
||||
UTKGenerateTables();
|
||||
generated = true;
|
||||
}
|
||||
|
||||
if(!utk_decode(InData+32, OutData, UTKHeader.Frames)){
|
||||
free(OutData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Sound->Channels = 1;
|
||||
Sound->SamplingRate = UTKHeader.nSamplesPerSec;
|
||||
Sound->BitDepth = UTKHeader.wBitsPerSample;
|
||||
Sound->Duration = UTKHeader.dwOutSize / UTKHeader.nBlockAlign;
|
||||
Sound->Data = OutData;
|
||||
return OutData;
|
||||
}
|
||||
|
||||
static uint8_t * ReadMP3(Sound_t * Sound, const uint8_t * InData, size_t FileSize){
|
||||
mpg123_handle *mh;
|
||||
if(mpg123_init() != MPG123_OK || (mh = mpg123_new(NULL, NULL)) == NULL){
|
||||
mpg123_exit();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
long rate;
|
||||
int channels, encoding;
|
||||
unsigned samples;
|
||||
size_t OutSize;
|
||||
uint8_t * OutData;
|
||||
|
||||
if(mpg123_format_none(mh) != MPG123_OK ||
|
||||
mpg123_format(mh, 44100, MPG123_MONO | MPG123_STEREO, MPG123_ENC_SIGNED_16) != MPG123_OK ||
|
||||
mpg123_open_feed(mh) != MPG123_OK ||
|
||||
mpg123_feed(mh, InData, FileSize) != MPG123_OK ||
|
||||
mpg123_set_filesize(mh, FileSize) != MPG123_OK ||
|
||||
mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK ||
|
||||
(samples = mpg123_length(mh)) == 0 ||
|
||||
(OutData = (uint8_t*) malloc(OutSize = samples * channels * 2)) == NULL
|
||||
){
|
||||
mpg123_close(mh);
|
||||
mpg123_delete(mh);
|
||||
mpg123_exit();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t decoded;
|
||||
mpg123_read(mh, OutData, OutSize, &decoded);
|
||||
mpg123_close(mh);
|
||||
mpg123_delete(mh);
|
||||
mpg123_exit();
|
||||
|
||||
if(decoded != OutSize){
|
||||
free(OutData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Sound->Channels = channels;
|
||||
Sound->SamplingRate = rate;
|
||||
Sound->BitDepth = 16;
|
||||
Sound->Duration = samples;
|
||||
Sound->Data = OutData;
|
||||
return OutData;
|
||||
}
|
||||
|
||||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
Audio.cpp - Copyright (c) 2011-2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "FileHandler.hpp"
|
||||
#include "wav/read_wav.h"
|
||||
#include "xa/read_xa.h"
|
||||
#include "utk/read_utk.h"
|
||||
#include "libmpg123/mpg123.h"
|
||||
|
||||
namespace File {
|
||||
|
||||
enum SoundType {
|
||||
FSND_WAV,
|
||||
FSND_XA,
|
||||
FSND_UTK,
|
||||
FSND_MP3,
|
||||
FSND_COUNT
|
||||
};
|
||||
|
||||
static uint8_t * ReadWAV(Sound_t * Sound, const uint8_t * InData, size_t FileSize);
|
||||
static uint8_t * ReadXA(Sound_t * Sound, const uint8_t * InData, size_t FileSize);
|
||||
static uint8_t * ReadUTK(Sound_t * Sound, const uint8_t * InData, size_t FileSize);
|
||||
static uint8_t * ReadMP3(Sound_t * Sound, const uint8_t * InData, size_t FileSize);
|
||||
|
||||
static const uint8_t Signature[] = {
|
||||
'R', //WAV
|
||||
'X', //XA
|
||||
'U', //UTK
|
||||
0xFF //MP3
|
||||
};
|
||||
static uint8_t* (* const SoundFunction[])(Sound_t*, const uint8_t*, size_t) = {
|
||||
ReadWAV,
|
||||
ReadXA,
|
||||
ReadUTK,
|
||||
ReadMP3
|
||||
};
|
||||
|
||||
Sound_t * ReadSoundFile(const char * Filename){
|
||||
uint8_t * InData = File::ReadFile(Filename);
|
||||
if(InData == NULL) return NULL;
|
||||
|
||||
if(File::FileSize < 4){
|
||||
free(InData);
|
||||
File::Error = FERR_INVALIDDATA;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Sound_t * Sound = (Sound_t*) malloc(sizeof(Sound_t));
|
||||
if(Sound == NULL){
|
||||
free(InData);
|
||||
File::Error = FERR_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(int i=0; i<FSND_COUNT; i++){
|
||||
if(InData[0] == Signature[i]){
|
||||
uint8_t * OutData = SoundFunction[i](Sound, InData, File::FileSize);
|
||||
free(InData);
|
||||
if(OutData == NULL){
|
||||
File::Error = FERR_INVALIDDATA;
|
||||
return NULL;
|
||||
}
|
||||
return Sound;
|
||||
}
|
||||
}
|
||||
|
||||
free(InData);
|
||||
File::Error = FERR_UNRECOGNIZED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static uint8_t * ReadWAV(Sound_t * Sound, const uint8_t * InData, size_t FileSize){
|
||||
wavheader_t WAVHeader;
|
||||
if(!wav_read_header(&WAVHeader, InData, FileSize)){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t * OutData = (uint8_t*) malloc(WAVHeader.DataSize);
|
||||
if(OutData == NULL){
|
||||
return NULL;
|
||||
}
|
||||
memcpy(OutData, InData+44, WAVHeader.DataSize);
|
||||
|
||||
Sound->Channels = WAVHeader.nChannels;
|
||||
Sound->SamplingRate = WAVHeader.nSamplesPerSec;
|
||||
Sound->BitDepth = WAVHeader.wBitsPerSample;
|
||||
Sound->Duration = WAVHeader.DataSize / WAVHeader.nBlockAlign;
|
||||
Sound->Data = OutData;
|
||||
return OutData;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t * ReadXA(Sound_t * Sound, const uint8_t * InData, size_t FileSize){
|
||||
xaheader_t XAHeader;
|
||||
if(!xa_read_header(&XAHeader, InData, FileSize)){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t * OutData = (uint8_t*) malloc(XAHeader.dwOutSize);
|
||||
if(OutData == NULL){
|
||||
return NULL;
|
||||
}
|
||||
if(!xa_decode(InData+24, OutData, XAHeader.Frames, XAHeader.nChannels)){
|
||||
free(OutData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Sound->Channels = XAHeader.nChannels;
|
||||
Sound->SamplingRate = XAHeader.nSamplesPerSec;
|
||||
Sound->BitDepth = XAHeader.wBitsPerSample;
|
||||
Sound->Duration = XAHeader.dwOutSize / XAHeader.nBlockAlign;
|
||||
Sound->Data = OutData;
|
||||
return OutData;
|
||||
}
|
||||
|
||||
static uint8_t * ReadUTK(Sound_t * Sound, const uint8_t * InData, size_t FileSize){
|
||||
utkheader_t UTKHeader;
|
||||
if(!utk_read_header(&UTKHeader, InData, FileSize)){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t * OutData = (uint8_t*) malloc(UTKHeader.dwOutSize);
|
||||
if(OutData == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool generated = false;
|
||||
if(!generated){
|
||||
UTKGenerateTables();
|
||||
generated = true;
|
||||
}
|
||||
|
||||
if(!utk_decode(InData+32, OutData, UTKHeader.Frames)){
|
||||
free(OutData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Sound->Channels = 1;
|
||||
Sound->SamplingRate = UTKHeader.nSamplesPerSec;
|
||||
Sound->BitDepth = UTKHeader.wBitsPerSample;
|
||||
Sound->Duration = UTKHeader.dwOutSize / UTKHeader.nBlockAlign;
|
||||
Sound->Data = OutData;
|
||||
return OutData;
|
||||
}
|
||||
|
||||
static uint8_t * ReadMP3(Sound_t * Sound, const uint8_t * InData, size_t FileSize){
|
||||
mpg123_handle *mh;
|
||||
if(mpg123_init() != MPG123_OK || (mh = mpg123_new(NULL, NULL)) == NULL){
|
||||
mpg123_exit();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
long rate;
|
||||
int channels, encoding;
|
||||
unsigned samples;
|
||||
size_t OutSize;
|
||||
uint8_t * OutData;
|
||||
|
||||
if(mpg123_format_none(mh) != MPG123_OK ||
|
||||
mpg123_format(mh, 44100, MPG123_MONO | MPG123_STEREO, MPG123_ENC_SIGNED_16) != MPG123_OK ||
|
||||
mpg123_open_feed(mh) != MPG123_OK ||
|
||||
mpg123_feed(mh, InData, FileSize) != MPG123_OK ||
|
||||
mpg123_set_filesize(mh, FileSize) != MPG123_OK ||
|
||||
mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK ||
|
||||
(samples = mpg123_length(mh)) == 0 ||
|
||||
(OutData = (uint8_t*) malloc(OutSize = samples * channels * 2)) == NULL
|
||||
){
|
||||
mpg123_close(mh);
|
||||
mpg123_delete(mh);
|
||||
mpg123_exit();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t decoded;
|
||||
mpg123_read(mh, OutData, OutSize, &decoded);
|
||||
mpg123_close(mh);
|
||||
mpg123_delete(mh);
|
||||
mpg123_exit();
|
||||
|
||||
if(decoded != OutSize){
|
||||
free(OutData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Sound->Channels = channels;
|
||||
Sound->SamplingRate = rate;
|
||||
Sound->BitDepth = 16;
|
||||
Sound->Duration = samples;
|
||||
Sound->Data = OutData;
|
||||
return OutData;
|
||||
}
|
||||
|
||||
}
|
|
@ -29,10 +29,6 @@
|
|||
#define read_uint16(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)))
|
||||
#endif
|
||||
|
||||
#ifndef __restrict
|
||||
#define __restrict
|
||||
#endif
|
||||
|
||||
int bmp_read_header(bmpheader_t * BMPHeader, const uint8_t * Buffer, size_t FileSize){
|
||||
unsigned padding;
|
||||
if(FileSize < 54) return 0;
|
||||
|
|
|
@ -1,49 +1,49 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
cst.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "cst.h"
|
||||
|
||||
static unsigned cst_count_strings(const char * Buffer, size_t FileSize){
|
||||
unsigned count = 0;
|
||||
int instring = 0;
|
||||
while(FileSize--){
|
||||
if(*Buffer == '^' && (instring = !instring) == 0)
|
||||
count++;
|
||||
Buffer++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int cst_read(CSTFile * CSTFileInfo, char * Buffer, size_t FileSize){
|
||||
CSTFileInfo->CSTData = Buffer;
|
||||
CSTFileInfo->StringCount = cst_count_strings(Buffer, FileSize);
|
||||
if(CSTFileInfo->StringCount != 0){
|
||||
unsigned i;
|
||||
CSTFileInfo->Strings = malloc(CSTFileInfo->StringCount * sizeof(char *));
|
||||
if(CSTFileInfo->Strings == NULL)
|
||||
return 0;
|
||||
for(i=0; i<CSTFileInfo->StringCount; i++){
|
||||
CSTFileInfo->Strings[i] = Buffer = strchr(Buffer, '^') + 1;
|
||||
*(Buffer = strchr(Buffer, '^')) = 0x00;
|
||||
Buffer++;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
cst.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "cst.h"
|
||||
|
||||
static unsigned cst_count_strings(const char * Buffer, size_t FileSize){
|
||||
unsigned count = 0;
|
||||
int instring = 0;
|
||||
while(FileSize--){
|
||||
if(*Buffer == '^' && (instring = !instring) == 0)
|
||||
count++;
|
||||
Buffer++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int cst_read(CSTFile * CSTFileInfo, char * Buffer, size_t FileSize){
|
||||
CSTFileInfo->CSTData = Buffer;
|
||||
CSTFileInfo->StringCount = cst_count_strings(Buffer, FileSize);
|
||||
if(CSTFileInfo->StringCount != 0){
|
||||
unsigned i;
|
||||
CSTFileInfo->Strings = malloc(CSTFileInfo->StringCount * sizeof(char *));
|
||||
if(CSTFileInfo->Strings == NULL)
|
||||
return 0;
|
||||
for(i=0; i<CSTFileInfo->StringCount; i++){
|
||||
CSTFileInfo->Strings[i] = Buffer = strchr(Buffer, '^') + 1;
|
||||
*(Buffer = strchr(Buffer, '^')) = 0x00;
|
||||
Buffer++;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
|
@ -1,23 +1,23 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
cst.h - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
char * CSTData;
|
||||
unsigned StringCount;
|
||||
char ** Strings;
|
||||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
cst.h - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
char * CSTData;
|
||||
unsigned StringCount;
|
||||
char ** Strings;
|
||||
} CSTFile;
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
read_cur.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
read_cur.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
read_cur.h - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
read_cur.h - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
|
@ -17,11 +17,7 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
typedef unsigned char uint8_t;
|
||||
|
||||
#ifndef __restrict
|
||||
#define __restrict
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
|
||||
int RefPackDecompress(const uint8_t *__restrict CompressedData, size_t CompressedSize,
|
||||
uint8_t *__restrict DecompressedData, size_t DecompressedSize, unsigned HNSV){
|
||||
|
|
|
@ -1,53 +1,53 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
bcon.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Ahmed El-Mahdawy <aa.mahdawy.10@gmail.com>
|
||||
Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_bcon(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFF_BCON *BCONData;
|
||||
unsigned i;
|
||||
|
||||
if(ChunkInfo->Size < 2)
|
||||
return 0;
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFF_BCON));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
BCONData = ChunkInfo->FormattedData;
|
||||
BCONData->ConstantCount = read_uint8le(Buffer);
|
||||
BCONData->Flags = read_uint8le(Buffer + 1);
|
||||
if(BCONData->ConstantCount == 0)
|
||||
return 1;
|
||||
if(BCONData->ConstantCount * 2 /* bytes */ > ChunkInfo->Size - 2)
|
||||
return 0;
|
||||
|
||||
BCONData->Constants = malloc(BCONData->ConstantCount * sizeof(uint16_t));
|
||||
if(BCONData->Constants == NULL)
|
||||
return 0;
|
||||
|
||||
Buffer += 2;
|
||||
for(i=0; i<BCONData->ConstantCount; i++, Buffer += 2)
|
||||
BCONData->Constants[i] = read_uint16le(Buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_bcon(void * FormattedData){
|
||||
IFF_BCON *BCONData = FormattedData;
|
||||
free(BCONData->Constants);
|
||||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
bcon.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Ahmed El-Mahdawy <aa.mahdawy.10@gmail.com>
|
||||
Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_bcon(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFF_BCON *BCONData;
|
||||
unsigned i;
|
||||
|
||||
if(ChunkInfo->Size < 2)
|
||||
return 0;
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFF_BCON));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
BCONData = ChunkInfo->FormattedData;
|
||||
BCONData->ConstantCount = read_uint8le(Buffer);
|
||||
BCONData->Flags = read_uint8le(Buffer + 1);
|
||||
if(BCONData->ConstantCount == 0)
|
||||
return 1;
|
||||
if(BCONData->ConstantCount * 2 /* bytes */ > ChunkInfo->Size - 2)
|
||||
return 0;
|
||||
|
||||
BCONData->Constants = malloc(BCONData->ConstantCount * sizeof(uint16_t));
|
||||
if(BCONData->Constants == NULL)
|
||||
return 0;
|
||||
|
||||
Buffer += 2;
|
||||
for(i=0; i<BCONData->ConstantCount; i++, Buffer += 2)
|
||||
BCONData->Constants[i] = read_uint16le(Buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_bcon(void * FormattedData){
|
||||
IFF_BCON *BCONData = FormattedData;
|
||||
free(BCONData->Constants);
|
||||
}
|
|
@ -1,108 +1,108 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
dgrp.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
#define read_split(x, y, z) \
|
||||
(largefields ? read_uint##z(x) : read_uint##y(x))
|
||||
|
||||
int iff_parse_dgrp(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFDrawGroup *Group;
|
||||
bytestream b;
|
||||
int largefields;
|
||||
unsigned i;
|
||||
|
||||
if(ChunkInfo->Size < 52)
|
||||
return 0;
|
||||
set_bytestream(&b, Buffer, ChunkInfo->Size);
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFDrawGroup));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
Group = ChunkInfo->FormattedData;
|
||||
Group->Version = read_uint16(&b);
|
||||
if(Group->Version < 20000 || Group->Version > 20004 || Group->Version == 20002)
|
||||
return 0;
|
||||
largefields = (Group->Version >= 20003);
|
||||
Group->AngleCount = read_split(&b, 16, 32);
|
||||
if(Group->AngleCount != 12)
|
||||
return 0;
|
||||
|
||||
for(i=0; i<12; i++){
|
||||
IFFDrawAngle * Angle = &Group->DrawAngles[i];
|
||||
unsigned j;
|
||||
|
||||
if(b.Size < ((!largefields) ? 4 : 12))
|
||||
return 0;
|
||||
|
||||
if(!largefields)
|
||||
Angle->SpriteCount = read_uint16(&b);
|
||||
Angle->Direction = read_split(&b, 8, 32);
|
||||
Angle->Zoom = read_split(&b, 8, 32);
|
||||
if(largefields)
|
||||
Angle->SpriteCount = read_uint32(&b);
|
||||
|
||||
if((Angle->Direction != 1 && Angle->Direction != 4 && Angle->Direction != 16 && Angle->Direction != 64)
|
||||
|| (!Angle->Zoom || Angle->Zoom > 3))
|
||||
return 0;
|
||||
if(Angle->SpriteCount == 0)
|
||||
continue;
|
||||
|
||||
Angle->SpriteInfo = calloc(Angle->SpriteCount, sizeof(IFFSpriteInfo));
|
||||
if(Angle->SpriteInfo == NULL)
|
||||
return 0;
|
||||
|
||||
for(j=0; j<Angle->SpriteCount; j++){
|
||||
IFFSpriteInfo * Sprite = &Angle->SpriteInfo[j];
|
||||
const uint8_t size[5] = {12, 16, 0, 24, 32};
|
||||
|
||||
if(b.Size < size[Group->Version - 20000])
|
||||
return 0;
|
||||
|
||||
if(!largefields)
|
||||
Sprite->Type = read_uint16(&b);
|
||||
Sprite->ChunkID = read_split(&b, 16, 32);
|
||||
Sprite->SpriteIndex = read_split(&b, 16, 32);
|
||||
if(!largefields)
|
||||
Sprite->Flags = read_uint16(&b);
|
||||
Sprite->SpriteX = read_split(&b, 16, 32);
|
||||
Sprite->SpriteY = read_split(&b, 16, 32);
|
||||
if(Group->Version >= 20001){
|
||||
Sprite->ObjectZ = read_float(&b);
|
||||
if(Group->Version >= 20003){
|
||||
Sprite->Flags = read_uint32(&b);
|
||||
if(Group->Version == 20004){
|
||||
Sprite->ObjectX = read_float(&b);
|
||||
Sprite->ObjectY = read_float(&b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_dgrp(void * FormattedData){
|
||||
IFFDrawGroup *Group = FormattedData;
|
||||
int i;
|
||||
for(i=0; i<12; i++){
|
||||
IFFDrawAngle *Angle = &Group->DrawAngles[i];
|
||||
free(Angle->SpriteInfo);
|
||||
}
|
||||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
dgrp.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
#define read_split(x, y, z) \
|
||||
(largefields ? read_uint##z(x) : read_uint##y(x))
|
||||
|
||||
int iff_parse_dgrp(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFDrawGroup *Group;
|
||||
bytestream b;
|
||||
int largefields;
|
||||
unsigned i;
|
||||
|
||||
if(ChunkInfo->Size < 52)
|
||||
return 0;
|
||||
set_bytestream(&b, Buffer, ChunkInfo->Size);
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFDrawGroup));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
Group = ChunkInfo->FormattedData;
|
||||
Group->Version = read_uint16(&b);
|
||||
if(Group->Version < 20000 || Group->Version > 20004 || Group->Version == 20002)
|
||||
return 0;
|
||||
largefields = (Group->Version >= 20003);
|
||||
Group->AngleCount = read_split(&b, 16, 32);
|
||||
if(Group->AngleCount != 12)
|
||||
return 0;
|
||||
|
||||
for(i=0; i<12; i++){
|
||||
IFFDrawAngle * Angle = &Group->DrawAngles[i];
|
||||
unsigned j;
|
||||
|
||||
if(b.Size < ((!largefields) ? 4 : 12))
|
||||
return 0;
|
||||
|
||||
if(!largefields)
|
||||
Angle->SpriteCount = read_uint16(&b);
|
||||
Angle->Direction = read_split(&b, 8, 32);
|
||||
Angle->Zoom = read_split(&b, 8, 32);
|
||||
if(largefields)
|
||||
Angle->SpriteCount = read_uint32(&b);
|
||||
|
||||
if((Angle->Direction != 1 && Angle->Direction != 4 && Angle->Direction != 16 && Angle->Direction != 64)
|
||||
|| (!Angle->Zoom || Angle->Zoom > 3))
|
||||
return 0;
|
||||
if(Angle->SpriteCount == 0)
|
||||
continue;
|
||||
|
||||
Angle->SpriteInfo = calloc(Angle->SpriteCount, sizeof(IFFSpriteInfo));
|
||||
if(Angle->SpriteInfo == NULL)
|
||||
return 0;
|
||||
|
||||
for(j=0; j<Angle->SpriteCount; j++){
|
||||
IFFSpriteInfo * Sprite = &Angle->SpriteInfo[j];
|
||||
const uint8_t size[5] = {12, 16, 0, 24, 32};
|
||||
|
||||
if(b.Size < size[Group->Version - 20000])
|
||||
return 0;
|
||||
|
||||
if(!largefields)
|
||||
Sprite->Type = read_uint16(&b);
|
||||
Sprite->ChunkID = read_split(&b, 16, 32);
|
||||
Sprite->SpriteIndex = read_split(&b, 16, 32);
|
||||
if(!largefields)
|
||||
Sprite->Flags = read_uint16(&b);
|
||||
Sprite->SpriteX = read_split(&b, 16, 32);
|
||||
Sprite->SpriteY = read_split(&b, 16, 32);
|
||||
if(Group->Version >= 20001){
|
||||
Sprite->ObjectZ = read_float(&b);
|
||||
if(Group->Version >= 20003){
|
||||
Sprite->Flags = read_uint32(&b);
|
||||
if(Group->Version == 20004){
|
||||
Sprite->ObjectX = read_float(&b);
|
||||
Sprite->ObjectY = read_float(&b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_dgrp(void * FormattedData){
|
||||
IFFDrawGroup *Group = FormattedData;
|
||||
int i;
|
||||
for(i=0; i<12; i++){
|
||||
IFFDrawAngle *Angle = &Group->DrawAngles[i];
|
||||
free(Angle->SpriteInfo);
|
||||
}
|
||||
}
|
|
@ -1,93 +1,93 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
rsmp.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_rsmp(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFResourceMap *Map;
|
||||
bytestream b;
|
||||
unsigned i;
|
||||
|
||||
if(ChunkInfo->Size < 20)
|
||||
return 0;
|
||||
set_bytestream(&b, Buffer, ChunkInfo->Size);
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFResourceMap));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
Map = ChunkInfo->FormattedData;
|
||||
Map->Reserved = read_uint32(&b);
|
||||
Map->Version = read_uint32(&b);
|
||||
memcpy(Map->MagicNumber, b.Buffer, 4);
|
||||
skipbytes(&b, 4);
|
||||
Map->IFFSize = read_uint32(&b);
|
||||
Map->TypeCount = read_uint32(&b);
|
||||
if(Map->Reserved != 0 || Map->Version > 1)
|
||||
return 0;
|
||||
|
||||
Map->ResourceTypes = calloc(Map->TypeCount, sizeof(IFFResourceType));
|
||||
if(Map->ResourceTypes == NULL)
|
||||
return 0;
|
||||
|
||||
for(i=0; i<Map->TypeCount; i++){
|
||||
IFFResourceType * Type = &Map->ResourceTypes[i];
|
||||
unsigned j;
|
||||
if(b.Size < 8) return 0;
|
||||
|
||||
memcpy(Type->Type, b.Buffer, 4);
|
||||
skipbytes(&b, 4);
|
||||
Type->ResourceCount = read_uint32(&b);
|
||||
Type->Resources = calloc(Type->ResourceCount, sizeof(IFFResource));
|
||||
if(Type->Resources == NULL)
|
||||
return 0;
|
||||
|
||||
for(j=0; j<Type->ResourceCount; j++){
|
||||
IFFResource * Resource = &Type->Resources[j];
|
||||
if(b.Size < ((Map->Version == 0) ? 9 : 11)) return 0;
|
||||
Resource->Offset = read_uint32(&b);
|
||||
Resource->ChunkID = (Map->Version == 0) ? read_uint16(&b) : read_uint32(&b);
|
||||
Resource->Flags = read_uint16(&b);
|
||||
|
||||
if(Map->Version == 0){
|
||||
if(!read_c_string(&b, &Resource->Label))
|
||||
return 0;
|
||||
}else{
|
||||
if(!read_pascal_string(&b, &Resource->Label))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_rsmp(void * FormattedData){
|
||||
IFFResourceMap * Map = FormattedData;
|
||||
if(Map->ResourceTypes){
|
||||
unsigned t;
|
||||
for(t=0; t<Map->TypeCount; t++){
|
||||
IFFResourceType * Type = &Map->ResourceTypes[t];
|
||||
if(Type->Resources){
|
||||
unsigned r;
|
||||
for(r=0; r<Type->ResourceCount; r++)
|
||||
free(Type->Resources[r].Label);
|
||||
free(Type->Resources);
|
||||
}
|
||||
}
|
||||
free(Map->ResourceTypes);
|
||||
}
|
||||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
rsmp.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_rsmp(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFResourceMap *Map;
|
||||
bytestream b;
|
||||
unsigned i;
|
||||
|
||||
if(ChunkInfo->Size < 20)
|
||||
return 0;
|
||||
set_bytestream(&b, Buffer, ChunkInfo->Size);
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFResourceMap));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
Map = ChunkInfo->FormattedData;
|
||||
Map->Reserved = read_uint32(&b);
|
||||
Map->Version = read_uint32(&b);
|
||||
memcpy(Map->MagicNumber, b.Buffer, 4);
|
||||
skipbytes(&b, 4);
|
||||
Map->IFFSize = read_uint32(&b);
|
||||
Map->TypeCount = read_uint32(&b);
|
||||
if(Map->Reserved != 0 || Map->Version > 1)
|
||||
return 0;
|
||||
|
||||
Map->ResourceTypes = calloc(Map->TypeCount, sizeof(IFFResourceType));
|
||||
if(Map->ResourceTypes == NULL)
|
||||
return 0;
|
||||
|
||||
for(i=0; i<Map->TypeCount; i++){
|
||||
IFFResourceType * Type = &Map->ResourceTypes[i];
|
||||
unsigned j;
|
||||
if(b.Size < 8) return 0;
|
||||
|
||||
memcpy(Type->Type, b.Buffer, 4);
|
||||
skipbytes(&b, 4);
|
||||
Type->ResourceCount = read_uint32(&b);
|
||||
Type->Resources = calloc(Type->ResourceCount, sizeof(IFFResource));
|
||||
if(Type->Resources == NULL)
|
||||
return 0;
|
||||
|
||||
for(j=0; j<Type->ResourceCount; j++){
|
||||
IFFResource * Resource = &Type->Resources[j];
|
||||
if(b.Size < ((Map->Version == 0) ? 9 : 11)) return 0;
|
||||
Resource->Offset = read_uint32(&b);
|
||||
Resource->ChunkID = (Map->Version == 0) ? read_uint16(&b) : read_uint32(&b);
|
||||
Resource->Flags = read_uint16(&b);
|
||||
|
||||
if(Map->Version == 0){
|
||||
if(!read_c_string(&b, &Resource->Label))
|
||||
return 0;
|
||||
}else{
|
||||
if(!read_pascal_string(&b, &Resource->Label))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_rsmp(void * FormattedData){
|
||||
IFFResourceMap * Map = FormattedData;
|
||||
if(Map->ResourceTypes){
|
||||
unsigned t;
|
||||
for(t=0; t<Map->TypeCount; t++){
|
||||
IFFResourceType * Type = &Map->ResourceTypes[t];
|
||||
if(Type->Resources){
|
||||
unsigned r;
|
||||
for(r=0; r<Type->ResourceCount; r++)
|
||||
free(Type->Resources[r].Label);
|
||||
free(Type->Resources);
|
||||
}
|
||||
}
|
||||
free(Map->ResourceTypes);
|
||||
}
|
||||
}
|
|
@ -1,221 +1,221 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
spr.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_spr(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFSpriteList *SpriteList;
|
||||
bytestream b;
|
||||
unsigned NextSpriteOffset; /* Used for Version 1001 in place of the offset table */
|
||||
unsigned i;
|
||||
|
||||
if(ChunkInfo->Size < 12)
|
||||
return 0;
|
||||
set_bytestream(&b, Buffer, ChunkInfo->Size);
|
||||
if((Buffer[0]|Buffer[1]) == 0) b.Endian++; /* Big endian */
|
||||
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFSpriteList));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
SpriteList = ChunkInfo->FormattedData;
|
||||
SpriteList->Version = read_uint32(&b);
|
||||
SpriteList->SpriteCount = read_uint32(&b);
|
||||
SpriteList->PaletteID = read_uint32(&b);
|
||||
if(SpriteList->Version < 502 || (SpriteList->Version > 505 && SpriteList->Version != 1001))
|
||||
return 0;
|
||||
|
||||
if(SpriteList->Version != 1001){
|
||||
if(SpriteList->SpriteCount > b.Size/4)
|
||||
return 0;
|
||||
}else{
|
||||
/* Sprite count is blank in version 1001, so we must walk and count up the sprites ourselves;
|
||||
** this is easy with the sprite size field */
|
||||
for(SpriteList->SpriteCount = 0; b.Size >= 16; SpriteList->SpriteCount++){
|
||||
if(read_uint32(&b) != 1001 || !skipbytes(&b, read_uint32(&b)))
|
||||
return 0;
|
||||
}
|
||||
NextSpriteOffset = 16;
|
||||
}
|
||||
|
||||
if(SpriteList->SpriteCount == 0)
|
||||
return 1;
|
||||
SpriteList->Sprites = calloc(SpriteList->SpriteCount, sizeof(IFFSprite));
|
||||
if(SpriteList->Sprites == NULL)
|
||||
return 0;
|
||||
|
||||
for(i=0; i<SpriteList->SpriteCount; i++){
|
||||
IFFSprite * Sprite = &SpriteList->Sprites[i];
|
||||
unsigned SpriteSize;
|
||||
unsigned row = 0;
|
||||
|
||||
if(SpriteList->Version != 1001){
|
||||
/* Jump to the next sprite using the offset table; this is mandatory */
|
||||
seekto(&b, 12 + 4*i);
|
||||
if(!seekto(&b, read_uint32(&b)) || b.Size < 8)
|
||||
return 0;
|
||||
SpriteSize = b.Size;
|
||||
}else{
|
||||
/* Jump to the next sprite using the sprite size field; this is mandatory */
|
||||
seekto(&b, NextSpriteOffset);
|
||||
SpriteSize = read_uint32(&b);
|
||||
NextSpriteOffset += SpriteSize + 8;
|
||||
}
|
||||
|
||||
Sprite->Reserved = read_uint32(&b);
|
||||
Sprite->Height = read_uint16(&b);
|
||||
Sprite->Width = read_uint16(&b);
|
||||
if(Sprite->Reserved != 0 || Sprite->Height == 0 || Sprite->Width == 0 || Sprite->Height > UINT_MAX/2/Sprite->Width){
|
||||
/* This happens in the third sprite of every SPR# chunk in sprites.iff */
|
||||
Sprite->InvalidDimensions = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
SpriteSize -= 8;
|
||||
|
||||
Sprite->IndexData = calloc(Sprite->Width*Sprite->Height, 2);
|
||||
if(Sprite->IndexData == NULL)
|
||||
return 0;
|
||||
|
||||
while(1){
|
||||
/****
|
||||
** Row command: valid commands are 0, 4, 5, 9, and 16
|
||||
*/
|
||||
|
||||
uint8_t RowCommand, RowCount;
|
||||
|
||||
if(SpriteSize < 2)
|
||||
return 0;
|
||||
RowCommand = *(b.Buffer++);
|
||||
RowCount = *(b.Buffer++);
|
||||
SpriteSize -= 2;
|
||||
|
||||
if(RowCommand == 0 || RowCommand == 16){
|
||||
/* Start marker */
|
||||
}else if(RowCommand == 4){
|
||||
/****
|
||||
** Pixel command: valid commands are 1, 2, and 3
|
||||
*/
|
||||
|
||||
unsigned pixel = 0;
|
||||
|
||||
if(row == Sprite->Height || RowCount < 2 || (RowCount -= 2) > SpriteSize || RowCount%2 != 0)
|
||||
return 0;
|
||||
SpriteSize -= RowCount;
|
||||
|
||||
while(RowCount){
|
||||
uint8_t PixelCommand, PixelCount;
|
||||
uint8_t * IndexData;
|
||||
if(RowCount < 2)
|
||||
return 0;
|
||||
|
||||
PixelCommand = *(b.Buffer++);
|
||||
PixelCount = *(b.Buffer++);
|
||||
RowCount -= 2;
|
||||
|
||||
if(PixelCount > Sprite->Width - pixel)
|
||||
return 0;
|
||||
|
||||
IndexData = Sprite->IndexData + (Sprite->Width*row + pixel)*2;
|
||||
pixel += PixelCount;
|
||||
|
||||
if(PixelCommand == 1){
|
||||
/* Leave next n pixels as transparent */
|
||||
}else if(PixelCommand == 2){
|
||||
/* Set next n pixels to shared palette index */
|
||||
|
||||
uint8_t PaletteIndex;
|
||||
if(RowCount < 2)
|
||||
return 0;
|
||||
|
||||
PaletteIndex = *(b.Buffer++);
|
||||
b.Buffer++; /* Padding byte */
|
||||
RowCount -= 2;
|
||||
|
||||
while(PixelCount--){
|
||||
*IndexData++ = PaletteIndex;
|
||||
*IndexData++ = 0xFF;
|
||||
}
|
||||
}else if(PixelCommand == 3){
|
||||
/* Set next n pixels to n palette indices */
|
||||
|
||||
int padding = PixelCount%2;
|
||||
if(PixelCount + padding > RowCount)
|
||||
return 0;
|
||||
RowCount -= PixelCount + padding;
|
||||
|
||||
while(PixelCount--){
|
||||
*IndexData++ = *(b.Buffer++);
|
||||
*IndexData++ = 0xFF;
|
||||
}
|
||||
if(padding) b.Buffer++; /* Padding byte */
|
||||
}else return 0;
|
||||
}
|
||||
row++;
|
||||
}else if(RowCommand == 5){
|
||||
/* End marker */
|
||||
break;
|
||||
}else if(RowCommand == 9){
|
||||
/* Leave rows as transparent */
|
||||
|
||||
if(RowCount > Sprite->Height - row)
|
||||
return 0;
|
||||
row += RowCount;
|
||||
}else return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_spr(void * FormattedData){
|
||||
IFFSpriteList *SpriteList = FormattedData;
|
||||
if(SpriteList->Sprites){
|
||||
unsigned s;
|
||||
for(s=0; s<SpriteList->SpriteCount; s++){
|
||||
IFFSprite *Sprite = &SpriteList->Sprites[s];
|
||||
free(Sprite->IndexData);
|
||||
free(Sprite->BGRA32Data);
|
||||
free(Sprite->ZBuffer);
|
||||
}
|
||||
free(SpriteList->Sprites);
|
||||
}
|
||||
}
|
||||
|
||||
int iff_depalette(IFFSprite * Sprite, const IFFPalette * Palette){
|
||||
unsigned PixelCount = Sprite->Width*Sprite->Height;
|
||||
unsigned i;
|
||||
|
||||
Sprite->BGRA32Data = malloc(PixelCount*4);
|
||||
if(Sprite->BGRA32Data == NULL) return 0;
|
||||
|
||||
for(i=0; i<PixelCount; i++){
|
||||
uint8_t Index = Sprite->IndexData[2*i + 0];
|
||||
if(Index >= Palette->ColorCount){
|
||||
free(Sprite->BGRA32Data);
|
||||
Sprite->BGRA32Data = NULL;
|
||||
return 0;
|
||||
}
|
||||
Sprite->BGRA32Data[4*i + 0] = Palette->Data[3*Index + 2];
|
||||
Sprite->BGRA32Data[4*i + 1] = Palette->Data[3*Index + 1];
|
||||
Sprite->BGRA32Data[4*i + 2] = Palette->Data[3*Index + 0];
|
||||
Sprite->BGRA32Data[4*i + 3] = Sprite->IndexData[2*i + 1];
|
||||
}
|
||||
|
||||
return 1;
|
||||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
spr.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_spr(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFSpriteList *SpriteList;
|
||||
bytestream b;
|
||||
unsigned NextSpriteOffset; /* Used for Version 1001 in place of the offset table */
|
||||
unsigned i;
|
||||
|
||||
if(ChunkInfo->Size < 12)
|
||||
return 0;
|
||||
set_bytestream(&b, Buffer, ChunkInfo->Size);
|
||||
if((Buffer[0]|Buffer[1]) == 0) b.Endian++; /* Big endian */
|
||||
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFSpriteList));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
SpriteList = ChunkInfo->FormattedData;
|
||||
SpriteList->Version = read_uint32(&b);
|
||||
SpriteList->SpriteCount = read_uint32(&b);
|
||||
SpriteList->PaletteID = read_uint32(&b);
|
||||
if(SpriteList->Version < 502 || (SpriteList->Version > 505 && SpriteList->Version != 1001))
|
||||
return 0;
|
||||
|
||||
if(SpriteList->Version != 1001){
|
||||
if(SpriteList->SpriteCount > b.Size/4)
|
||||
return 0;
|
||||
}else{
|
||||
/* Sprite count is blank in version 1001, so we must walk and count up the sprites ourselves;
|
||||
** this is easy with the sprite size field */
|
||||
for(SpriteList->SpriteCount = 0; b.Size >= 16; SpriteList->SpriteCount++){
|
||||
if(read_uint32(&b) != 1001 || !skipbytes(&b, read_uint32(&b)))
|
||||
return 0;
|
||||
}
|
||||
NextSpriteOffset = 16;
|
||||
}
|
||||
|
||||
if(SpriteList->SpriteCount == 0)
|
||||
return 1;
|
||||
SpriteList->Sprites = calloc(SpriteList->SpriteCount, sizeof(IFFSprite));
|
||||
if(SpriteList->Sprites == NULL)
|
||||
return 0;
|
||||
|
||||
for(i=0; i<SpriteList->SpriteCount; i++){
|
||||
IFFSprite * Sprite = &SpriteList->Sprites[i];
|
||||
unsigned SpriteSize;
|
||||
unsigned row = 0;
|
||||
|
||||
if(SpriteList->Version != 1001){
|
||||
/* Jump to the next sprite using the offset table; this is mandatory */
|
||||
seekto(&b, 12 + 4*i);
|
||||
if(!seekto(&b, read_uint32(&b)) || b.Size < 8)
|
||||
return 0;
|
||||
SpriteSize = b.Size;
|
||||
}else{
|
||||
/* Jump to the next sprite using the sprite size field; this is mandatory */
|
||||
seekto(&b, NextSpriteOffset);
|
||||
SpriteSize = read_uint32(&b);
|
||||
NextSpriteOffset += SpriteSize + 8;
|
||||
}
|
||||
|
||||
Sprite->Reserved = read_uint32(&b);
|
||||
Sprite->Height = read_uint16(&b);
|
||||
Sprite->Width = read_uint16(&b);
|
||||
if(Sprite->Reserved != 0 || Sprite->Height == 0 || Sprite->Width == 0 || Sprite->Height > UINT_MAX/2/Sprite->Width){
|
||||
/* This happens in the third sprite of every SPR# chunk in sprites.iff */
|
||||
Sprite->InvalidDimensions = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
SpriteSize -= 8;
|
||||
|
||||
Sprite->IndexData = calloc(Sprite->Width*Sprite->Height, 2);
|
||||
if(Sprite->IndexData == NULL)
|
||||
return 0;
|
||||
|
||||
while(1){
|
||||
/****
|
||||
** Row command: valid commands are 0, 4, 5, 9, and 16
|
||||
*/
|
||||
|
||||
uint8_t RowCommand, RowCount;
|
||||
|
||||
if(SpriteSize < 2)
|
||||
return 0;
|
||||
RowCommand = *(b.Buffer++);
|
||||
RowCount = *(b.Buffer++);
|
||||
SpriteSize -= 2;
|
||||
|
||||
if(RowCommand == 0 || RowCommand == 16){
|
||||
/* Start marker */
|
||||
}else if(RowCommand == 4){
|
||||
/****
|
||||
** Pixel command: valid commands are 1, 2, and 3
|
||||
*/
|
||||
|
||||
unsigned pixel = 0;
|
||||
|
||||
if(row == Sprite->Height || RowCount < 2 || (RowCount -= 2) > SpriteSize || RowCount%2 != 0)
|
||||
return 0;
|
||||
SpriteSize -= RowCount;
|
||||
|
||||
while(RowCount){
|
||||
uint8_t PixelCommand, PixelCount;
|
||||
uint8_t * IndexData;
|
||||
if(RowCount < 2)
|
||||
return 0;
|
||||
|
||||
PixelCommand = *(b.Buffer++);
|
||||
PixelCount = *(b.Buffer++);
|
||||
RowCount -= 2;
|
||||
|
||||
if(PixelCount > Sprite->Width - pixel)
|
||||
return 0;
|
||||
|
||||
IndexData = Sprite->IndexData + (Sprite->Width*row + pixel)*2;
|
||||
pixel += PixelCount;
|
||||
|
||||
if(PixelCommand == 1){
|
||||
/* Leave next n pixels as transparent */
|
||||
}else if(PixelCommand == 2){
|
||||
/* Set next n pixels to shared palette index */
|
||||
|
||||
uint8_t PaletteIndex;
|
||||
if(RowCount < 2)
|
||||
return 0;
|
||||
|
||||
PaletteIndex = *(b.Buffer++);
|
||||
b.Buffer++; /* Padding byte */
|
||||
RowCount -= 2;
|
||||
|
||||
while(PixelCount--){
|
||||
*IndexData++ = PaletteIndex;
|
||||
*IndexData++ = 0xFF;
|
||||
}
|
||||
}else if(PixelCommand == 3){
|
||||
/* Set next n pixels to n palette indices */
|
||||
|
||||
int padding = PixelCount%2;
|
||||
if(PixelCount + padding > RowCount)
|
||||
return 0;
|
||||
RowCount -= PixelCount + padding;
|
||||
|
||||
while(PixelCount--){
|
||||
*IndexData++ = *(b.Buffer++);
|
||||
*IndexData++ = 0xFF;
|
||||
}
|
||||
if(padding) b.Buffer++; /* Padding byte */
|
||||
}else return 0;
|
||||
}
|
||||
row++;
|
||||
}else if(RowCommand == 5){
|
||||
/* End marker */
|
||||
break;
|
||||
}else if(RowCommand == 9){
|
||||
/* Leave rows as transparent */
|
||||
|
||||
if(RowCount > Sprite->Height - row)
|
||||
return 0;
|
||||
row += RowCount;
|
||||
}else return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_spr(void * FormattedData){
|
||||
IFFSpriteList *SpriteList = FormattedData;
|
||||
if(SpriteList->Sprites){
|
||||
unsigned s;
|
||||
for(s=0; s<SpriteList->SpriteCount; s++){
|
||||
IFFSprite *Sprite = &SpriteList->Sprites[s];
|
||||
free(Sprite->IndexData);
|
||||
free(Sprite->BGRA32Data);
|
||||
free(Sprite->ZBuffer);
|
||||
}
|
||||
free(SpriteList->Sprites);
|
||||
}
|
||||
}
|
||||
|
||||
int iff_depalette(IFFSprite * Sprite, const IFFPalette * Palette){
|
||||
unsigned PixelCount = Sprite->Width*Sprite->Height;
|
||||
unsigned i;
|
||||
|
||||
Sprite->BGRA32Data = malloc(PixelCount*4);
|
||||
if(Sprite->BGRA32Data == NULL) return 0;
|
||||
|
||||
for(i=0; i<PixelCount; i++){
|
||||
uint8_t Index = Sprite->IndexData[2*i + 0];
|
||||
if(Index >= Palette->ColorCount){
|
||||
free(Sprite->BGRA32Data);
|
||||
Sprite->BGRA32Data = NULL;
|
||||
return 0;
|
||||
}
|
||||
Sprite->BGRA32Data[4*i + 0] = Palette->Data[3*Index + 2];
|
||||
Sprite->BGRA32Data[4*i + 1] = Palette->Data[3*Index + 1];
|
||||
Sprite->BGRA32Data[4*i + 2] = Palette->Data[3*Index + 0];
|
||||
Sprite->BGRA32Data[4*i + 3] = Sprite->IndexData[2*i + 1];
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -1,227 +1,227 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
spr2.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_spr2(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFSpriteList *SpriteList;
|
||||
bytestream b;
|
||||
unsigned NextSpriteOffset; /* Used for Version 1001 in place of the offset table */
|
||||
unsigned i;
|
||||
|
||||
if(ChunkInfo->Size < 12)
|
||||
return 0;
|
||||
set_bytestream(&b, Buffer, ChunkInfo->Size);
|
||||
if((Buffer[0]|Buffer[1]) == 0) b.Endian++; /* Big endian */
|
||||
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFSpriteList));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
SpriteList = ChunkInfo->FormattedData;
|
||||
SpriteList->Version = read_uint32(&b);
|
||||
if(SpriteList->Version != 1000 && SpriteList->Version != 1001)
|
||||
return 0;
|
||||
|
||||
if(SpriteList->Version == 1000){
|
||||
SpriteList->SpriteCount = read_uint32(&b);
|
||||
SpriteList->PaletteID = read_uint32(&b);
|
||||
if(SpriteList->SpriteCount > b.Size/4)
|
||||
return 0;
|
||||
}else{
|
||||
SpriteList->PaletteID = read_uint32(&b);
|
||||
skipbytes(&b, 4);
|
||||
|
||||
/* Sprite count is blank in version 1001, so we must walk and count up the sprites ourselves;
|
||||
** this is easy with the sprite size field */
|
||||
for(SpriteList->SpriteCount = 0; b.Size >= 24; SpriteList->SpriteCount++){
|
||||
if(read_uint32(&b) != 1001 || !skipbytes(&b, read_uint32(&b)))
|
||||
return 0;
|
||||
}
|
||||
NextSpriteOffset = 16;
|
||||
}
|
||||
|
||||
if(SpriteList->SpriteCount == 0)
|
||||
return 1;
|
||||
SpriteList->Sprites = calloc(SpriteList->SpriteCount, sizeof(IFFSprite));
|
||||
if(SpriteList->Sprites == NULL)
|
||||
return 0;
|
||||
|
||||
for(i=0; i<SpriteList->SpriteCount; i++){
|
||||
IFFSprite * Sprite = &SpriteList->Sprites[i];
|
||||
unsigned SpriteSize;
|
||||
unsigned row = 0;
|
||||
int j;
|
||||
|
||||
if(SpriteList->Version != 1001){
|
||||
/* Jump to the next sprite using the offset table; this is mandatory */
|
||||
seekto(&b, 12 + 4*i);
|
||||
if(!seekto(&b, read_uint32(&b)) || b.Size < 16)
|
||||
return 0;
|
||||
SpriteSize = b.Size;
|
||||
}else{
|
||||
/* Jump to the next sprite using the sprite size field; this is mandatory */
|
||||
seekto(&b, NextSpriteOffset);
|
||||
SpriteSize = read_uint32(&b);
|
||||
NextSpriteOffset += SpriteSize + 8;
|
||||
}
|
||||
|
||||
Sprite->Width = read_uint16(&b);
|
||||
Sprite->Height = read_uint16(&b);
|
||||
Sprite->Flags = read_uint32(&b);
|
||||
Sprite->PaletteID = read_uint16(&b);
|
||||
Sprite->TransparentColor = read_uint16(&b);
|
||||
Sprite->YLoc = read_uint16(&b);
|
||||
Sprite->XLoc = read_uint16(&b);
|
||||
if((Sprite->Flags != 1 && Sprite->Flags != 3 && Sprite->Flags != 7) || Sprite->TransparentColor >= 256)
|
||||
return 0;
|
||||
if(Sprite->Height == 0 || Sprite->Width == 0 || Sprite->Height > UINT_MAX/2/Sprite->Width){
|
||||
/* This happens in the many chunks in 2personportal.spf */
|
||||
Sprite->InvalidDimensions = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
SpriteSize -= 16;
|
||||
|
||||
Sprite->IndexData = malloc(Sprite->Width*Sprite->Height*2);
|
||||
if(Sprite->IndexData == NULL)
|
||||
return 0;
|
||||
for(j=0; j<Sprite->Width*Sprite->Height; j++){
|
||||
Sprite->IndexData[2*j + 0] = Sprite->TransparentColor;
|
||||
Sprite->IndexData[2*j + 1] = 0x00;
|
||||
}
|
||||
|
||||
if(Sprite->Flags >= 3){ /* Has the Z-Buffer flag */
|
||||
Sprite->ZBuffer = malloc(Sprite->Width*Sprite->Height);
|
||||
if(Sprite->ZBuffer == NULL)
|
||||
return 0;
|
||||
memset(Sprite->ZBuffer, 0xFF, Sprite->Width*Sprite->Height);
|
||||
}
|
||||
|
||||
while(1){
|
||||
/****
|
||||
** Row command: valid commands are 0, 4, and 5
|
||||
*/
|
||||
|
||||
uint8_t RowCommand; /* 3 bits */
|
||||
uint16_t RowCount; /* 13 bits */
|
||||
|
||||
if(SpriteSize < 2)
|
||||
return 0;
|
||||
RowCount = read_uint16le(b.Buffer);
|
||||
RowCommand = RowCount >> 13;
|
||||
RowCount &= 0x1FFF;
|
||||
|
||||
b.Buffer += 2;
|
||||
SpriteSize -= 2;
|
||||
|
||||
if(RowCommand == 0){
|
||||
/****
|
||||
** Pixel command: valid commands are 1, 2, 3, and 6
|
||||
*/
|
||||
|
||||
unsigned pixel = 0;
|
||||
|
||||
if(row == Sprite->Height || RowCount < 2 || (RowCount -= 2) > SpriteSize || RowCount%2 != 0)
|
||||
return 0;
|
||||
SpriteSize -= RowCount;
|
||||
|
||||
while(RowCount){
|
||||
uint8_t PixelCommand; /* 3 bits */
|
||||
uint16_t PixelCount; /* 13 bits */
|
||||
uint8_t * IndexData, * ZBuffer;
|
||||
if(RowCount < 2)
|
||||
return 0;
|
||||
|
||||
PixelCount = read_uint16le(b.Buffer);
|
||||
PixelCommand = PixelCount >> 13;
|
||||
PixelCount &= 0x1FFF;
|
||||
|
||||
b.Buffer += 2;
|
||||
RowCount -= 2;
|
||||
|
||||
if(PixelCount > Sprite->Width - pixel)
|
||||
return 0;
|
||||
|
||||
IndexData = Sprite->IndexData + (Sprite->Width*row + pixel)*2;
|
||||
ZBuffer = Sprite->ZBuffer + (Sprite->Width*row + pixel)*1;
|
||||
pixel += PixelCount;
|
||||
|
||||
if(PixelCommand == 1){
|
||||
/* color+z-buffer: Set next n pixels to n palette indices */
|
||||
|
||||
if(Sprite->Flags < 3 || PixelCount*2 > RowCount)
|
||||
return 0;
|
||||
RowCount -= PixelCount*2;
|
||||
|
||||
while(PixelCount--){
|
||||
*ZBuffer++ = *(b.Buffer++);
|
||||
IndexData[0] = *(b.Buffer++);
|
||||
IndexData[1] = (IndexData[0] != Sprite->TransparentColor) ? 0xFF : 0x00;
|
||||
IndexData += 2;
|
||||
}
|
||||
}else if(PixelCommand == 2){
|
||||
/* color+z-buffer+alpha: Set next n pixels to n palette indices */
|
||||
|
||||
int padding = PixelCount%2;
|
||||
if(Sprite->Flags < 7 || PixelCount*3 + padding > RowCount)
|
||||
return 0;
|
||||
RowCount -= PixelCount*3 + padding;
|
||||
|
||||
while(PixelCount--){
|
||||
*ZBuffer++ = *(b.Buffer++);
|
||||
*IndexData++ = *(b.Buffer++);
|
||||
*IndexData++ = *(b.Buffer++);
|
||||
}
|
||||
if(padding) b.Buffer++; /* Padding byte */
|
||||
}else if(PixelCommand == 3){
|
||||
/* Leave next n pixels as transparent */
|
||||
}else if(PixelCommand == 6){
|
||||
/* color: Set next n pixels to n palette indices */
|
||||
|
||||
int padding = PixelCount%2;
|
||||
if(PixelCount + padding > RowCount)
|
||||
return 0;
|
||||
RowCount -= PixelCount + padding;
|
||||
|
||||
while(PixelCount--){
|
||||
IndexData[0] = *(b.Buffer++);
|
||||
IndexData[1] = (IndexData[0] != Sprite->TransparentColor) ? 0xFF : 0x00;
|
||||
if(Sprite->Flags >= 3)
|
||||
*ZBuffer++ = (IndexData[0] != Sprite->TransparentColor) ? 0x00 : 0xFF;
|
||||
IndexData += 2;
|
||||
}
|
||||
if(padding) b.Buffer++; /* Padding byte */
|
||||
} else return 0;
|
||||
}
|
||||
row++;
|
||||
}else if(RowCommand == 4){
|
||||
/* Leave rows as transparent */
|
||||
|
||||
if(RowCount > Sprite->Height - row)
|
||||
return 0;
|
||||
row += RowCount;
|
||||
}else if(RowCommand == 5){
|
||||
/* End marker */
|
||||
break;
|
||||
}else return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
spr2.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_spr2(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFSpriteList *SpriteList;
|
||||
bytestream b;
|
||||
unsigned NextSpriteOffset; /* Used for Version 1001 in place of the offset table */
|
||||
unsigned i;
|
||||
|
||||
if(ChunkInfo->Size < 12)
|
||||
return 0;
|
||||
set_bytestream(&b, Buffer, ChunkInfo->Size);
|
||||
if((Buffer[0]|Buffer[1]) == 0) b.Endian++; /* Big endian */
|
||||
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFSpriteList));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
SpriteList = ChunkInfo->FormattedData;
|
||||
SpriteList->Version = read_uint32(&b);
|
||||
if(SpriteList->Version != 1000 && SpriteList->Version != 1001)
|
||||
return 0;
|
||||
|
||||
if(SpriteList->Version == 1000){
|
||||
SpriteList->SpriteCount = read_uint32(&b);
|
||||
SpriteList->PaletteID = read_uint32(&b);
|
||||
if(SpriteList->SpriteCount > b.Size/4)
|
||||
return 0;
|
||||
}else{
|
||||
SpriteList->PaletteID = read_uint32(&b);
|
||||
skipbytes(&b, 4);
|
||||
|
||||
/* Sprite count is blank in version 1001, so we must walk and count up the sprites ourselves;
|
||||
** this is easy with the sprite size field */
|
||||
for(SpriteList->SpriteCount = 0; b.Size >= 24; SpriteList->SpriteCount++){
|
||||
if(read_uint32(&b) != 1001 || !skipbytes(&b, read_uint32(&b)))
|
||||
return 0;
|
||||
}
|
||||
NextSpriteOffset = 16;
|
||||
}
|
||||
|
||||
if(SpriteList->SpriteCount == 0)
|
||||
return 1;
|
||||
SpriteList->Sprites = calloc(SpriteList->SpriteCount, sizeof(IFFSprite));
|
||||
if(SpriteList->Sprites == NULL)
|
||||
return 0;
|
||||
|
||||
for(i=0; i<SpriteList->SpriteCount; i++){
|
||||
IFFSprite * Sprite = &SpriteList->Sprites[i];
|
||||
unsigned SpriteSize;
|
||||
unsigned row = 0;
|
||||
int j;
|
||||
|
||||
if(SpriteList->Version != 1001){
|
||||
/* Jump to the next sprite using the offset table; this is mandatory */
|
||||
seekto(&b, 12 + 4*i);
|
||||
if(!seekto(&b, read_uint32(&b)) || b.Size < 16)
|
||||
return 0;
|
||||
SpriteSize = b.Size;
|
||||
}else{
|
||||
/* Jump to the next sprite using the sprite size field; this is mandatory */
|
||||
seekto(&b, NextSpriteOffset);
|
||||
SpriteSize = read_uint32(&b);
|
||||
NextSpriteOffset += SpriteSize + 8;
|
||||
}
|
||||
|
||||
Sprite->Width = read_uint16(&b);
|
||||
Sprite->Height = read_uint16(&b);
|
||||
Sprite->Flags = read_uint32(&b);
|
||||
Sprite->PaletteID = read_uint16(&b);
|
||||
Sprite->TransparentColor = read_uint16(&b);
|
||||
Sprite->YLoc = read_uint16(&b);
|
||||
Sprite->XLoc = read_uint16(&b);
|
||||
if((Sprite->Flags != 1 && Sprite->Flags != 3 && Sprite->Flags != 7) || Sprite->TransparentColor >= 256)
|
||||
return 0;
|
||||
if(Sprite->Height == 0 || Sprite->Width == 0 || Sprite->Height > UINT_MAX/2/Sprite->Width){
|
||||
/* This happens in the many chunks in 2personportal.spf */
|
||||
Sprite->InvalidDimensions = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
SpriteSize -= 16;
|
||||
|
||||
Sprite->IndexData = malloc(Sprite->Width*Sprite->Height*2);
|
||||
if(Sprite->IndexData == NULL)
|
||||
return 0;
|
||||
for(j=0; j<Sprite->Width*Sprite->Height; j++){
|
||||
Sprite->IndexData[2*j + 0] = Sprite->TransparentColor;
|
||||
Sprite->IndexData[2*j + 1] = 0x00;
|
||||
}
|
||||
|
||||
if(Sprite->Flags >= 3){ /* Has the Z-Buffer flag */
|
||||
Sprite->ZBuffer = malloc(Sprite->Width*Sprite->Height);
|
||||
if(Sprite->ZBuffer == NULL)
|
||||
return 0;
|
||||
memset(Sprite->ZBuffer, 0xFF, Sprite->Width*Sprite->Height);
|
||||
}
|
||||
|
||||
while(1){
|
||||
/****
|
||||
** Row command: valid commands are 0, 4, and 5
|
||||
*/
|
||||
|
||||
uint8_t RowCommand; /* 3 bits */
|
||||
uint16_t RowCount; /* 13 bits */
|
||||
|
||||
if(SpriteSize < 2)
|
||||
return 0;
|
||||
RowCount = read_uint16le(b.Buffer);
|
||||
RowCommand = RowCount >> 13;
|
||||
RowCount &= 0x1FFF;
|
||||
|
||||
b.Buffer += 2;
|
||||
SpriteSize -= 2;
|
||||
|
||||
if(RowCommand == 0){
|
||||
/****
|
||||
** Pixel command: valid commands are 1, 2, 3, and 6
|
||||
*/
|
||||
|
||||
unsigned pixel = 0;
|
||||
|
||||
if(row == Sprite->Height || RowCount < 2 || (RowCount -= 2) > SpriteSize || RowCount%2 != 0)
|
||||
return 0;
|
||||
SpriteSize -= RowCount;
|
||||
|
||||
while(RowCount){
|
||||
uint8_t PixelCommand; /* 3 bits */
|
||||
uint16_t PixelCount; /* 13 bits */
|
||||
uint8_t * IndexData, * ZBuffer;
|
||||
if(RowCount < 2)
|
||||
return 0;
|
||||
|
||||
PixelCount = read_uint16le(b.Buffer);
|
||||
PixelCommand = PixelCount >> 13;
|
||||
PixelCount &= 0x1FFF;
|
||||
|
||||
b.Buffer += 2;
|
||||
RowCount -= 2;
|
||||
|
||||
if(PixelCount > Sprite->Width - pixel)
|
||||
return 0;
|
||||
|
||||
IndexData = Sprite->IndexData + (Sprite->Width*row + pixel)*2;
|
||||
ZBuffer = Sprite->ZBuffer + (Sprite->Width*row + pixel)*1;
|
||||
pixel += PixelCount;
|
||||
|
||||
if(PixelCommand == 1){
|
||||
/* color+z-buffer: Set next n pixels to n palette indices */
|
||||
|
||||
if(Sprite->Flags < 3 || PixelCount*2 > RowCount)
|
||||
return 0;
|
||||
RowCount -= PixelCount*2;
|
||||
|
||||
while(PixelCount--){
|
||||
*ZBuffer++ = *(b.Buffer++);
|
||||
IndexData[0] = *(b.Buffer++);
|
||||
IndexData[1] = (IndexData[0] != Sprite->TransparentColor) ? 0xFF : 0x00;
|
||||
IndexData += 2;
|
||||
}
|
||||
}else if(PixelCommand == 2){
|
||||
/* color+z-buffer+alpha: Set next n pixels to n palette indices */
|
||||
|
||||
int padding = PixelCount%2;
|
||||
if(Sprite->Flags < 7 || PixelCount*3 + padding > RowCount)
|
||||
return 0;
|
||||
RowCount -= PixelCount*3 + padding;
|
||||
|
||||
while(PixelCount--){
|
||||
*ZBuffer++ = *(b.Buffer++);
|
||||
*IndexData++ = *(b.Buffer++);
|
||||
*IndexData++ = *(b.Buffer++);
|
||||
}
|
||||
if(padding) b.Buffer++; /* Padding byte */
|
||||
}else if(PixelCommand == 3){
|
||||
/* Leave next n pixels as transparent */
|
||||
}else if(PixelCommand == 6){
|
||||
/* color: Set next n pixels to n palette indices */
|
||||
|
||||
int padding = PixelCount%2;
|
||||
if(PixelCount + padding > RowCount)
|
||||
return 0;
|
||||
RowCount -= PixelCount + padding;
|
||||
|
||||
while(PixelCount--){
|
||||
IndexData[0] = *(b.Buffer++);
|
||||
IndexData[1] = (IndexData[0] != Sprite->TransparentColor) ? 0xFF : 0x00;
|
||||
if(Sprite->Flags >= 3)
|
||||
*ZBuffer++ = (IndexData[0] != Sprite->TransparentColor) ? 0x00 : 0xFF;
|
||||
IndexData += 2;
|
||||
}
|
||||
if(padding) b.Buffer++; /* Padding byte */
|
||||
} else return 0;
|
||||
}
|
||||
row++;
|
||||
}else if(RowCommand == 4){
|
||||
/* Leave rows as transparent */
|
||||
|
||||
if(RowCount > Sprite->Height - row)
|
||||
return 0;
|
||||
row += RowCount;
|
||||
}else if(RowCommand == 5){
|
||||
/* End marker */
|
||||
break;
|
||||
}else return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -38,13 +38,6 @@
|
|||
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#ifndef __inline
|
||||
#define __inline
|
||||
#endif
|
||||
#ifndef __restrict
|
||||
#define __restrict
|
||||
#endif
|
||||
|
||||
static uint8_t ReadBits(utkparams_t *p, uint8_t bits);
|
||||
static void SetUTKParameters(utkparams_t *p);
|
||||
static void DecompressBlock(utkparams_t *p);
|
||||
|
|
|
@ -27,10 +27,6 @@
|
|||
#define read_uint16(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)))
|
||||
#endif
|
||||
|
||||
#ifndef __restrict
|
||||
#define __restrict
|
||||
#endif
|
||||
|
||||
int wav_read_header(wavheader_t * WAVHeader, const uint8_t * Buffer, size_t FileSize){
|
||||
if(FileSize < 45) return 0;
|
||||
WAVHeader->sID = read_uint32(Buffer);
|
||||
|
|
|
@ -29,13 +29,6 @@
|
|||
#define read_uint16(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)))
|
||||
#endif
|
||||
|
||||
#ifndef __inline
|
||||
#define __inline
|
||||
#endif
|
||||
#ifndef __restrict
|
||||
#define __restrict
|
||||
#endif
|
||||
|
||||
unsigned xa_compressed_size(unsigned Frames, unsigned Channels)
|
||||
{
|
||||
/* This function calculates the size of compressed XA data with known frames and channels, as such:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue