Added GemRB sources

This commit is contained in:
pelya
2010-12-14 09:47:29 +00:00
parent 674da851ef
commit 38bceffddd
455 changed files with 137680 additions and 0 deletions

View File

@@ -0,0 +1,120 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#include "2DAImporter.h"
#include "win32def.h"
#include "Interface.h"
#include "System/FileStream.h"
#define MAXLENGTH 4096 //if a 2da has longer lines, change this
#define SIGNLENGTH 256 //if a 2da has longer default value, change this
p2DAImporter::p2DAImporter(void)
{
str = NULL;
autoFree = false;
}
p2DAImporter::~p2DAImporter(void)
{
if (str && autoFree) {
delete( str );
}
for (unsigned int i = 0; i < ptrs.size(); i++) {
free( ptrs[i] );
}
}
bool p2DAImporter::Open(DataStream* stream, bool autoFree)
{
if (stream == NULL) {
return false;
}
if (str && this->autoFree) {
delete( str );
}
str = stream;
this->autoFree = autoFree;
char Signature[SIGNLENGTH];
str->CheckEncrypted();
str->ReadLine( Signature, sizeof(Signature) );
char* strp = Signature;
while (*strp == ' ')
strp++;
if (strncmp( strp, "2DA V1.0", 8 ) != 0) {
printMessage("2DAImporter", "Bad signature!\n",YELLOW );
// we don't care about this, so exptable.2da of iwd2 won't cause a bigger problem
// return false;
}
Signature[0] = 0;
str->ReadLine( Signature, sizeof(Signature) );
char* token = strtok( Signature, " " );
if (token) {
strncpy(defVal, token, sizeof(defVal) );
} else { // no whitespace
strncpy(defVal, Signature, sizeof(defVal) );
}
bool colHead = true;
int row = 0;
while (true) {
char* line = ( char* ) malloc( MAXLENGTH );
int len = str->ReadLine( line, MAXLENGTH-1 );
if (len <= 0) {
free( line );
break;
}
if (line[0] == '#') { // allow comments
free( line );
continue;
}
if (len < MAXLENGTH)
line = ( char * ) realloc( line, len + 1 );
ptrs.push_back( line );
if (colHead) {
colHead = false;
char* str = strtok( line, " " );
while (str != NULL) {
colNames.push_back( str );
str = strtok( NULL, " " );
}
} else {
char* str = strtok( line, " " );
if (str == NULL)
continue;
rowNames.push_back( str );
RowEntry r;
rows.push_back( r );
while (( str = strtok( NULL, " " ) ) != NULL) {
rows[row].push_back( str );
}
row++;
}
}
return true;
}
#include "plugindef.h"
GEMRB_PLUGIN(0xB22F938, "2DA File Importer")
PLUGIN_CLASS(IE_2DA_CLASS_ID, p2DAImporter)
END_PLUGIN()

View File

@@ -0,0 +1,169 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#ifndef P2DAIMPORTER_H
#define P2DAIMPORTER_H
#include "TableMgr.h"
#include "globals.h"
#include <cstring>
typedef std::vector< char*> RowEntry;
class p2DAImporter : public TableMgr {
private:
DataStream* str;
bool autoFree;
std::vector< char*> colNames;
std::vector< char*> rowNames;
std::vector< char*> ptrs;
std::vector< RowEntry> rows;
char defVal[32];
public:
p2DAImporter(void);
~p2DAImporter(void);
bool Open(DataStream* stream, bool autoFree = true);
/** Returns the actual number of Rows in the Table */
inline ieDword GetRowCount() const
{
return ( ieDword ) rows.size();
}
inline ieDword GetColNamesCount() const
{
return (ieDword) colNames.size();
}
/** Returns the actual number of Columns in the Table */
inline ieDword GetColumnCount(unsigned int row = 0) const
{
if (rows.size() <= row) {
return 0;
}
return ( ieDword ) rows[row].size();
}
/** Returns a pointer to a zero terminated 2da element,
if it cannot return a value, it returns the default */
inline const char* QueryField(unsigned int row = 0, unsigned int column = 0) const
{
if (rows.size() <= row) {
return ( char * ) defVal;
}
if (rows[row].size() <= column) {
return ( char * ) defVal;
}
if (rows[row][column][0]=='*' && !rows[row][column][1]) {
return ( char * ) defVal;
}
return rows[row][column];
}
/** Returns a pointer to a zero terminated 2da element,
uses column name and row name to search the field */
inline const char* QueryField(const char* row, const char* column) const
{
int rowi, coli;
rowi = GetRowIndex(row);
if (rowi < 0) {
return ( char * ) defVal;
}
coli = GetColumnIndex(column);
if (coli < 0) {
return ( char * ) defVal;
}
return QueryField((unsigned int) rowi, (unsigned int) coli);
}
virtual const char* QueryDefault() const
{
return defVal;
}
inline int GetRowIndex(const char* string) const
{
for (unsigned int index = 0; index < rowNames.size(); index++) {
if (stricmp( rowNames[index], string ) == 0) {
return (int) index;
}
}
return -1;
}
inline int GetColumnIndex(const char* string) const
{
for (unsigned int index = 0; index < colNames.size(); index++) {
if (stricmp( colNames[index], string ) == 0) {
return (int) index;
}
}
return -1;
}
inline const char* GetColumnName(unsigned int index) const
{
if (index < colNames.size()) {
return colNames[index];
}
return "";
}
inline const char* GetRowName(unsigned int index) const
{
if (index < rowNames.size()) {
return rowNames[index];
}
return "";
}
inline int FindTableValue(unsigned int col, long val, int start) const
{
ieDword row, max;
max = GetRowCount();
for (row = start; row < max; row++) {
const char* ret = QueryField( row, col );
long Value;
if (valid_number( ret, Value ) && (Value == val) )
return (int) row;
}
return -1;
}
inline int FindTableValue(unsigned int col, const char* val, int start) const
{
ieDword row, max;
max = GetRowCount();
for (row = start; row < max; row++) {
const char* ret = QueryField( row, col );
if (stricmp(ret, val) == 0)
return (int) row;
}
return -1;
}
};
#endif

View File

@@ -0,0 +1 @@
ADD_GEMRB_PLUGIN(2DAImporter 2DAImporter.cpp 2DAImporter.h )

View File

@@ -0,0 +1,3 @@
plugin_LTLIBRARIES = 2DAImporter.la
2DAImporter_la_LDFLAGS = -module -avoid-version -shared
2DAImporter_la_SOURCES = 2DAImporter.cpp 2DAImporter.h

View File

@@ -0,0 +1,117 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "ACMReader.h"
#include "general.h"
bool ACMReader::Open(DataStream* stream)
{
str = stream;
Close();
ACM_Header hdr;
char Signature[4];
ieDword SignatureDword;
stream->Read( Signature, 4 );
stream->Seek( 0, GEM_STREAM_START );
stream->ReadDword( &SignatureDword );
if (!memcmp( Signature, "WAVC", 4 )) {
str->Seek( 28, GEM_STREAM_START );
} else if (SignatureDword == IP_ACM_SIG) {
stream->Seek( 0, GEM_STREAM_START );
} else {
return false;
}
str->ReadDword( &hdr.signature );
str->ReadDword( &hdr.samples );
str->ReadWord( &hdr.channels );
str->ReadWord( &hdr.rate );
ieWord tmpword;
str->ReadWord( &tmpword );
//subblocks = (int) (tmpword&0xfff);
//levels = (int) (tmpword>>12);
subblocks = (int) (tmpword>>4);
levels = (int) (tmpword&15);
if (hdr.signature != IP_ACM_SIG) {
return false;
}
samples_left = ( samples = hdr.samples );
channels = hdr.channels;
samplerate = hdr.rate;
//levels = hdr.levels;
//subblocks = hdr.subblocks;
block_size = ( 1 << levels ) * subblocks;
//using malloc for simple arrays (supposed to be faster)
block = (int *) malloc(sizeof(int)*block_size);
if (!block) {
return false;
}
unpacker = new CValueUnpacker( levels, subblocks, str );
if (!unpacker || !unpacker->init_unpacker()) {
return false;
}
decoder = new CSubbandDecoder( levels );
if (!decoder || !decoder->init_decoder()) {
return false;
}
return true;
}
int ACMReader::make_new_samples()
{
if (!unpacker->get_one_block( block )) {
return 0;
}
decoder->decode_data( block, subblocks );
values = block;
samples_ready = ( block_size > samples_left ) ? samples_left : block_size;
samples_left -= samples_ready;
return 1;
}
int ACMReader::read_samples(short* buffer, int count)
{
int res = 0;
while (res < count) {
if (samples_ready == 0) {
if (samples_left == 0)
break;
if (!make_new_samples())
break;
}
*buffer = ( short ) ( ( *values ) >> levels );
values++;
buffer++;
res += 1;
samples_ready--;
}
return res;
}
#include "plugindef.h"
GEMRB_PLUGIN(0x10373EE, "ACM File Importer")
PLUGIN_IE_RESOURCE(ACMReader, ".acm", (ieWord)IE_ACM_CLASS_ID)
PLUGIN_IE_RESOURCE(ACMReader, ".wav", (ieWord)IE_WAV_CLASS_ID)
END_PLUGIN()

View File

@@ -0,0 +1,73 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef ACMREADER_H
#define ACMREADER_H
#include "SoundMgr.h"
#include "decoder.h"
#include "general.h"
#include "unpacker.h"
#include "System/DataStream.h"
#include <cstdio>
#include <cstring>
#include <cstdlib>
// IP's ACM files
class ACMReader : public SoundMgr {
private:
int samples_left; // count of unread samples
int levels, subblocks;
int block_size;
int* block, * values;
int samples_ready;
CValueUnpacker* unpacker; // ACM-stream unpacker
CSubbandDecoder* decoder; // IP's subband decoder
int make_new_samples();
public:
ACMReader()
: samples_left( 0 ), block( NULL ), values( NULL ),
samples_ready( 0 ), unpacker( NULL ), decoder( NULL )
{
}
virtual ~ACMReader()
{
Close();
}
void Close()
{
if (block) {
free(block);
}
if (unpacker) {
delete unpacker;
}
if (decoder) {
delete decoder;
}
}
bool Open(DataStream* stream);
virtual int read_samples(short* buffer, int count);
};
#endif

View File

@@ -0,0 +1,3 @@
FILE( GLOB ACMReader_files *.cpp )
ADD_GEMRB_PLUGIN (ACMReader ${ACMReader_files})

View File

@@ -0,0 +1,3 @@
plugin_LTLIBRARIES = ACMReader.la
ACMReader_la_LDFLAGS = -module -avoid-version -shared
ACMReader_la_SOURCES = ACMReader.cpp ACMReader.h decoder.cpp decoder.h unpacker.cpp unpacker.h general.h

View File

@@ -0,0 +1,177 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#include "decoder.h"
#include <cstdlib>
int CSubbandDecoder::init_decoder()
{
int memory_size = ( levels == 0 ) ? 0 : ( 3 * ( block_size >> 1 ) - 2 );
if (memory_size) {
memory_buffer = ( int * ) calloc( memory_size, sizeof( int ) );
if (!memory_buffer)
return 0;
}
return 1;
}
void CSubbandDecoder::decode_data(int* buffer, int blocks)
{
if (!levels) {
return;
} // no levels - no work
int* buff_ptr = buffer, * mem_ptr = memory_buffer;
int sb_size = block_size >> 1; // current subband size
blocks <<= 1;
sub_4d3fcc( ( short * ) mem_ptr, buff_ptr, sb_size, blocks );
mem_ptr += sb_size;
for (int i = 0; i < blocks; i++)
buff_ptr[i * sb_size]++;
sb_size >>= 1;
blocks <<= 1;
while (sb_size != 0) {
sub_4d420c( mem_ptr, buff_ptr, sb_size, blocks );
mem_ptr += sb_size << 1;
sb_size >>= 1;
blocks <<= 1;
}
}
void CSubbandDecoder::sub_4d3fcc(short* memory, int* buffer, int sb_size,
int blocks)
{
int row_0, row_1, row_2 = 0, row_3 = 0, db_0, db_1;
int i;
int sb_size_2 = sb_size * 2, sb_size_3 = sb_size * 3;
if (blocks == 2) {
for (i = 0; i < sb_size; i++) {
row_0 = buffer[0];
row_1 = buffer[sb_size];
buffer[0] = buffer[0] + memory[0] + 2 * memory[1];
buffer[sb_size] = 2 * row_0 - memory[1] - buffer[sb_size];
memory[0] = ( short ) row_0;
memory[1] = ( short ) row_1;
memory += 2;
buffer++;
}
} else if (blocks == 4) {
for (i = 0; i < sb_size; i++) {
row_0 = buffer[0];
row_1 = buffer[sb_size];
row_2 = buffer[sb_size_2];
row_3 = buffer[sb_size_3];
buffer[0] = memory[0] + 2 * memory[1] + row_0;
buffer[sb_size] = -memory[1] + 2 * row_0 - row_1;
buffer[sb_size_2] = row_0 + 2 * row_1 + row_2;
buffer[sb_size_3] = -row_1 + 2 * row_2 - row_3;
memory[0] = ( short ) row_2;
memory[1] = ( short ) row_3;
memory += 2;
buffer++;
}
} else {
for (i = 0; i < sb_size; i++) {
int* buff_ptr = buffer;
if (( blocks >> 1 ) & 1) {
row_0 = buff_ptr[0];
row_1 = buff_ptr[sb_size];
buff_ptr[0] = memory[0] + 2 * memory[1] + row_0;
buff_ptr[sb_size] = -memory[1] + 2 * row_0 - row_1;
buff_ptr += sb_size_2;
db_0 = row_0;
db_1 = row_1;
} else {
db_0 = memory[0];
db_1 = memory[1];
}
for (int j = 0; j < blocks >> 2; j++) {
row_0 = buff_ptr[0]; buff_ptr[0] = db_0 + 2 * db_1 + row_0; buff_ptr += sb_size;
row_1 = buff_ptr[0]; buff_ptr[0] = -db_1 + 2 * row_0 - row_1; buff_ptr += sb_size;
row_2 = buff_ptr[0]; buff_ptr[0] = row_0 + 2 * row_1 + row_2; buff_ptr += sb_size;
row_3 = buff_ptr[0]; buff_ptr[0] = -row_1 + 2 * row_2 -
row_3; buff_ptr += sb_size;
db_0 = row_2;
db_1 = row_3;
}
memory[0] = ( short ) row_2;
memory[1] = ( short ) row_3;
memory += 2;
buffer++;
}
}
}
void CSubbandDecoder::sub_4d420c(int* memory, int* buffer, int sb_size,
int blocks)
{
int row_0, row_1, row_2 = 0, row_3 = 0, db_0, db_1;
int i;
int sb_size_2 = sb_size * 2, sb_size_3 = sb_size * 3;
if (blocks == 4) {
for (i = 0; i < sb_size; i++) {
row_0 = buffer[0];
row_1 = buffer[sb_size];
row_2 = buffer[sb_size_2];
row_3 = buffer[sb_size_3];
buffer[0] = memory[0] + 2 * memory[1] + row_0;
buffer[sb_size] = -memory[1] + 2 * row_0 - row_1;
buffer[sb_size_2] = row_0 + 2 * row_1 + row_2;
buffer[sb_size_3] = -row_1 + 2 * row_2 - row_3;
memory[0] = row_2;
memory[1] = row_3;
memory += 2;
buffer++;
}
} else {
for (i = 0; i < sb_size; i++) {
int* buff_ptr = buffer;
db_0 = memory[0]; db_1 = memory[1];
for (int j = 0; j < blocks >> 2; j++) {
row_0 = buff_ptr[0]; buff_ptr[0] = db_0 + 2 * db_1 + row_0; buff_ptr += sb_size;
row_1 = buff_ptr[0]; buff_ptr[0] = -db_1 + 2 * row_0 - row_1; buff_ptr += sb_size;
row_2 = buff_ptr[0]; buff_ptr[0] = row_0 + 2 * row_1 + row_2; buff_ptr += sb_size;
row_3 = buff_ptr[0]; buff_ptr[0] = -row_1 + 2 * row_2 -
row_3; buff_ptr += sb_size;
db_0 = row_2;
db_1 = row_3;
}
memory[0] = row_2;
memory[1] = row_3;
memory += 2;
buffer++;
}
}
}

View File

@@ -0,0 +1,48 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#ifndef _ACM_LAB_SUBBAND_DECODER_H
#define _ACM_LAB_SUBBAND_DECODER_H
#include <cstdlib>
class CSubbandDecoder {
private:
int levels, block_size;
int* memory_buffer;
void sub_4d3fcc(short* memory, int* buffer, int sb_size, int blocks);
void sub_4d420c(int* memory, int* buffer, int sb_size, int blocks);
public:
CSubbandDecoder(int lev_cnt)
: levels( lev_cnt ), block_size( 1 << lev_cnt ), memory_buffer( NULL )
{
}
virtual ~CSubbandDecoder()
{
if (memory_buffer) {
free( memory_buffer );
}
}
int init_decoder();
void decode_data(int* buffer, int blocks);
};
#endif

View File

@@ -0,0 +1,36 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#ifndef _ACM_LAB_GENERAL_H
#define _ACM_LAB_GENERAL_H
// Interplay ACM signature
#define IP_ACM_SIG 0x01032897
struct ACM_Header {
unsigned int signature;
unsigned int samples;
unsigned short channels;
unsigned short rate;
unsigned short levels : 4;
unsigned short subblocks : 12;
};
#endif

View File

@@ -0,0 +1,454 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
// IP's ACM-stream unpacker.
#include "unpacker.h"
#include <cstdio>
char Table1[27] = {
0, 1, 2, 4, 5, 6, 8, 9, 10, 16, 17, 18, 20, 21, 22, 24, 25, 26, 32, 33,
34, 36, 37, 38, 40, 41, 42
};
//Eng: in base-4 system it is:
//Rus: â ÷åòâåðè÷íîé ñèñòåìå ýòî áóäåò:
// 000 001 002 010 011 012 020 021 022
// 100 101 102 110 111 112 120 121 122
// 200 201 202 210 211 212 220 221 222
short Table2[125] = {
0, 1, 2, 3, 4, 8, 9, 10, 11, 12, 16, 17, 18, 19, 20, 24, 25, 26, 27, 28,
32, 33, 34, 35, 36, 64, 65, 66, 67, 68, 72, 73, 74, 75, 76, 80, 81, 82,
83, 84, 88, 89, 90, 91, 92, 96, 97, 98, 99, 100, 128, 129, 130, 131, 132,
136, 137, 138, 139, 140, 144, 145, 146, 147, 148, 152, 153, 154, 155, 156,
160, 161, 162, 163, 164, 192, 193, 194, 195, 196, 200, 201, 202, 203, 204,
208, 209, 210, 211, 212, 216, 217, 218, 219, 220, 224, 225, 226, 227, 228,
256, 257, 258, 259, 260, 264, 265, 266, 267, 268, 272, 273, 274, 275, 276,
280, 281, 282, 283, 284, 288, 289, 290, 291, 292
};
//Eng: in base-8 system:
//Rus: â âîñüìåðè÷íîé ñèñòåìå:
// 000 001 002 003 004 010 011 012 013 014 ...
// 100 101 102 103 104 ...
// 200 ...
// ...
unsigned char Table3[121] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x20, 0x21,
0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x30, 0x31, 0x32,
0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x40, 0x41, 0x42, 0x43,
0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x50, 0x51, 0x52, 0x53, 0x54,
0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65,
0x66, 0x67, 0x68, 0x69, 0x6A, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
0x77, 0x78, 0x79, 0x7A, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8A, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
0x99, 0x9A, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9,
0xAA
};
FillerProc Fillers[32] = {
&CValueUnpacker::zero_fill, & CValueUnpacker::return0,
& CValueUnpacker::return0, & CValueUnpacker::linear_fill,
& CValueUnpacker::linear_fill, & CValueUnpacker::linear_fill,
& CValueUnpacker::linear_fill, & CValueUnpacker::linear_fill,
& CValueUnpacker::linear_fill, & CValueUnpacker::linear_fill,
& CValueUnpacker::linear_fill, & CValueUnpacker::linear_fill,
& CValueUnpacker::linear_fill, & CValueUnpacker::linear_fill,
& CValueUnpacker::linear_fill, & CValueUnpacker::linear_fill,
& CValueUnpacker::linear_fill, & CValueUnpacker::k1_3bits,
& CValueUnpacker::k1_2bits, & CValueUnpacker::t1_5bits,
& CValueUnpacker::k2_4bits, & CValueUnpacker::k2_3bits,
& CValueUnpacker::t2_7bits, & CValueUnpacker::k3_5bits,
& CValueUnpacker::k3_4bits, & CValueUnpacker::return0,
& CValueUnpacker::k4_5bits, & CValueUnpacker::k4_4bits,
& CValueUnpacker::return0, & CValueUnpacker::t3_7bits,
& CValueUnpacker::return0, & CValueUnpacker::return0
};
inline void CValueUnpacker::prepare_bits(int bits)
{
while (bits > avail_bits) {
unsigned char one_byte;
if (buffer_bit_offset == UNPACKER_BUFFER_SIZE) {
unsigned long remains = stream->Remains();
if (remains > UNPACKER_BUFFER_SIZE)
remains = UNPACKER_BUFFER_SIZE;
buffer_bit_offset = UNPACKER_BUFFER_SIZE - remains;
if (buffer_bit_offset != UNPACKER_BUFFER_SIZE)
stream->Read( bits_buffer + buffer_bit_offset, remains);
}
//our stream read returns -1 instead of 0 on failure
//comparing with 1 will solve annoying interface changes
if (buffer_bit_offset < UNPACKER_BUFFER_SIZE) {
one_byte = bits_buffer[buffer_bit_offset];
buffer_bit_offset++;
} else {
one_byte = 0;
}
next_bits |= ( ( unsigned int ) one_byte << avail_bits );
avail_bits += 8;
}
}
int CValueUnpacker::get_bits(int bits)
{
prepare_bits( bits );
int res = next_bits;
avail_bits -= bits;
next_bits >>= bits;
return res;
}
int CValueUnpacker::init_unpacker()
{
//using malloc, supposed to be faster
amp_buffer =(short *) malloc(sizeof(short)*0x10000);
if (!amp_buffer) {
return 0;
}
buff_middle = amp_buffer + 0x8000;
return 1;
}
int CValueUnpacker::get_one_block(int* block)
{
block_ptr = block;
int pwr = get_bits( 4 ) & 0xF, val = get_bits( 16 ) & 0xFFFF,
count = 1 << pwr, v = 0;
int i;
for (i = 0; i < count; i++) {
buff_middle[i] = ( short ) v;
v += val;
}
v = -val;
for (i = 0; i < count; i++) {
buff_middle[-i - 1] = ( short ) v;
v -= val;
}
for (int pass = 0; pass < sb_size; pass++) {
int ind = get_bits( 5 ) & 0x1F;
if (!( ( this->*Fillers[ind] ) ( pass, ind ) )) {
return 0;
}
}
return 1;
}
// Filling functions:
// int CValueUnpacker::FillerProc (int pass, int ind)
int CValueUnpacker::return0(int /*pass*/, int /*ind*/)
{
return 0;
}
int CValueUnpacker::zero_fill(int pass, int /*ind*/)
{
//Eng: used when the whole column #pass is zero-filled
//Rus: èñïîëüçóåòñÿ, êîãäà âåñü ñòîëáåö ñ íîìåðîì pass çàïîëíåí íóëÿìè
int* sb_ptr = &block_ptr[pass], step = sb_size, i = subblocks;
do {
*sb_ptr = 0;
sb_ptr += step;
} while (( --i ) != 0);
return 1;
}
int CValueUnpacker::linear_fill(int pass, int ind)
{
int mask = ( 1 << ind ) - 1;
short* lb_ptr = buff_middle + ( ( -1l ) << ( ind - 1 ) );
for (int i = 0; i < subblocks; i++)
block_ptr[i * sb_size + pass] = lb_ptr[get_bits( ind ) & mask];
return 1;
}
int CValueUnpacker::k1_3bits(int pass, int /*ind*/)
{
//Eng: column with number pass is filled with zeros, and also +/-1, zeros are repeated frequently
//Rus: còîëáåö pass çàïîëíåí íóëÿìè, à òàêæå +/- 1, íî íóëè ÷àñòî èäóò ïîäðÿä
// efficiency (bits per value): 3-p0-2.5*p00, p00 - cnt of paired zeros, p0 - cnt of single zeros.
//Eng: it makes sense to use, when the freqnecy of paired zeros (p00) is greater than 2/3
//Rus: èìååò ñìûñë èñïîëüçîâàòü, êîãäà âåðîÿòíîñòü ïàðíûõ íóëåé (p00) áîëüøå 2/3
for (int i = 0; i < subblocks; i++) {
prepare_bits( 3 );
if (( next_bits & 1 ) == 0) {
avail_bits--;
next_bits >>= 1;
block_ptr[i * sb_size + pass] = 0; if (( ++i ) == subblocks)
break;
block_ptr[i * sb_size + pass] = 0;
} else if (( next_bits & 2 ) == 0) {
avail_bits -= 2;
next_bits >>= 2;
block_ptr[i * sb_size + pass] = 0;
} else {
block_ptr[i * sb_size + pass] = ( next_bits & 4 ) ?
buff_middle[1] :
buff_middle[-1];
avail_bits -= 3;
next_bits >>= 3;
}
}
return 1;
}
int CValueUnpacker::k1_2bits(int pass, int /*ind*/)
{
//Eng: column is filled with zero and +/-1
//Rus: còîëáåö pass çàïîëíåí íóëÿìè, à òàêæå +/- 1
// efficiency: 2-P0. P0 - cnt of any zero (P0 = p0 + p00)
//Eng: use it when P0 > 1/3
//Rus: èìååò ñìûñë èñïîëüçîâàòü, êîãäà âåðîÿòíîñòü íóëÿ áîëüøå 1/3
for (int i = 0; i < subblocks; i++) {
prepare_bits( 2 );
if (( next_bits & 1 ) == 0) {
avail_bits--;
next_bits >>= 1;
block_ptr[i * sb_size + pass] = 0;
} else {
block_ptr[i * sb_size + pass] = ( next_bits & 2 ) ?
buff_middle[1] :
buff_middle[-1];
avail_bits -= 2;
next_bits >>= 2;
}
}
return 1;
}
int CValueUnpacker::t1_5bits(int pass, int /*ind*/)
{
//Eng: all the -1, 0, +1 triplets
//Rus: âñå êîìáèíàöèè òðîåê -1, 0, +1.
// efficiency: always 5/3 bits per value
// use it when P0 <= 1/3
for (int i = 0; i < subblocks; i++) {
int bits = ( int ) ( get_bits( 5 ) & 0x1f );
bits = ( int ) Table1[bits];
block_ptr[i * sb_size + pass] = buff_middle[-1 + ( bits & 3 )];
if (( ++i ) == subblocks)
break;
bits >>= 2;
block_ptr[i * sb_size + pass] = buff_middle[-1 + ( bits & 3 )];
if (( ++i ) == subblocks)
break;
bits >>= 2;
block_ptr[i * sb_size + pass] = buff_middle[-1 + bits];
}
return 1;
}
int CValueUnpacker::k2_4bits(int pass, int /*ind*/)
{
// -2, -1, 0, 1, 2, and repeating zeros
// efficiency: 4-2*p0-3.5*p00, p00 - cnt of paired zeros, p0 - cnt of single zeros.
//Eng: makes sense to use when p00>2/3
//Rus: èìååò ñìûñë èñïîëüçîâàòü, êîãäà âåðîÿòíîñòü ïàðíûõ íóëåé (p00) áîëüøå 2/3
for (int i = 0; i < subblocks; i++) {
prepare_bits( 4 );
if (( next_bits & 1 ) == 0) {
avail_bits--;
next_bits >>= 1;
block_ptr[i * sb_size + pass] = 0; if (( ++i ) == subblocks)
break;
block_ptr[i * sb_size + pass] = 0;
} else if (( next_bits & 2 ) == 0) {
avail_bits -= 2;
next_bits >>= 2;
block_ptr[i * sb_size + pass] = 0;
} else {
block_ptr[i * sb_size + pass] = ( next_bits & 8 ) ?
( ( next_bits & 4 ) ? buff_middle[2] : buff_middle[1] ) :
( ( next_bits & 4 ) ? buff_middle[-1] : buff_middle[-2] );
avail_bits -= 4;
next_bits >>= 4;
}
}
return 1;
}
int CValueUnpacker::k2_3bits(int pass, int /*ind*/)
{
// -2, -1, 0, 1, 2
// efficiency: 3-2*P0, P0 - cnt of any zero (P0 = p0 + p00)
//Eng: use when P0>1/3
//Rus: èìååò ñìûñë èñïîëüçîâàòü, êîãäà âåðîÿòíîñòü íóëÿ áîëüøå 1/3
for (int i = 0; i < subblocks; i++) {
prepare_bits( 3 );
if (( next_bits & 1 ) == 0) {
avail_bits--;
next_bits >>= 1;
block_ptr[i * sb_size + pass] = 0;
} else {
block_ptr[i * sb_size + pass] = ( next_bits & 4 ) ?
( ( next_bits & 2 ) ? buff_middle[2] : buff_middle[1] ) :
( ( next_bits & 2 ) ? buff_middle[-1] : buff_middle[-2] );
avail_bits -= 3;
next_bits >>= 3;
}
}
return 1;
}
int CValueUnpacker::t2_7bits(int pass, int /*ind*/)
{
//Eng: all the +/-2, +/-1, 0 triplets
// efficiency: always 7/3 bits per value
//Rus: âñå êîìáèíàöèè òðîåê -2, -1, 0, +1, 2.
// ýôôåêòèâíîñòü: 7/3 áèòà íà çíà÷åíèå - âñåãäà
// use it when p0 <= 1/3
for (int i = 0; i < subblocks; i++) {
int bits = ( int ) ( get_bits( 7 ) & 0x7f );
short val = Table2[bits];
block_ptr[i * sb_size + pass] = buff_middle[-2 + ( val & 7 )];
if (( ++i ) == subblocks)
break;
val >>= 3;
block_ptr[i * sb_size + pass] = buff_middle[-2 + ( val & 7 )];
if (( ++i ) == subblocks)
break;
val >>= 3;
block_ptr[i * sb_size + pass] = buff_middle[-2 + val];
}
return 1;
}
int CValueUnpacker::k3_5bits(int pass, int /*ind*/)
{
// fills with values: -3, -2, -1, 0, 1, 2, 3, and double zeros
// efficiency: 5-3*p0-4.5*p00-p1, p00 - cnt of paired zeros, p0 - cnt of single zeros, p1 - cnt of +/- 1.
// can be used when frequency of paired zeros (p00) is greater than 2/3
for (int i = 0; i < subblocks; i++) {
prepare_bits( 5 );
if (( next_bits & 1 ) == 0) {
avail_bits--;
next_bits >>= 1;
block_ptr[i * sb_size + pass] = 0; if (( ++i ) == subblocks)
break;
block_ptr[i * sb_size + pass] = 0;
} else if (( next_bits & 2 ) == 0) {
avail_bits -= 2;
next_bits >>= 2;
block_ptr[i * sb_size + pass] = 0;
} else if (( next_bits & 4 ) == 0) {
block_ptr[i * sb_size + pass] = ( next_bits & 8 ) ?
buff_middle[1] :
buff_middle[-1];
avail_bits -= 4;
next_bits >>= 4;
} else {
avail_bits -= 5;
int val = ( next_bits & 0x18 ) >> 3;
next_bits >>= 5;
if (val >= 2)
val += 3;
block_ptr[i * sb_size + pass] = buff_middle[-3 + val];
}
}
return 1;
}
int CValueUnpacker::k3_4bits(int pass, int /*ind*/)
{
// fills with values: -3, -2, -1, 0, 1, 2, 3.
// efficiency: 4-3*P0-p1, P0 - cnt of all zeros (P0 = p0 + p00), p1 - cnt of +/- 1.
for (int i = 0; i < subblocks; i++) {
prepare_bits( 4 );
if (( next_bits & 1 ) == 0) {
avail_bits--;
next_bits >>= 1;
block_ptr[i * sb_size + pass] = 0;
} else if (( next_bits & 2 ) == 0) {
avail_bits -= 3;
block_ptr[i * sb_size + pass] = ( next_bits & 4 ) ?
buff_middle[1] :
buff_middle[-1];
next_bits >>= 3;
} else {
int val = ( next_bits &0xC ) >> 2;
avail_bits -= 4;
next_bits >>= 4;
if (val >= 2)
val += 3;
block_ptr[i * sb_size + pass] = buff_middle[-3 + val];
}
}
return 1;
}
int CValueUnpacker::k4_5bits(int pass, int /*ind*/)
{
// fills with values: +/-4, +/-3, +/-2, +/-1, 0, and double zeros
// efficiency: 5-3*p0-4.5*p00, p00 - cnt of paired zeros, p0 - cnt of single zeros.
//Eng: makes sense to use when p00>2/3
//Rus: èìååò ñìûñë èñïîëüçîâàòü, êîãäà âåðîÿòíîñòü ïàðíûõ íóëåé (p00) áîëüøå 2/3
for (int i = 0; i < subblocks; i++) {
prepare_bits( 5 );
if (( next_bits & 1 ) == 0) {
avail_bits--;
next_bits >>= 1;
block_ptr[i * sb_size + pass] = 0; if (( ++i ) == subblocks)
break;
block_ptr[i * sb_size + pass] = 0;
} else if (( next_bits & 2 ) == 0) {
avail_bits -= 2;
next_bits >>= 2;
block_ptr[i * sb_size + pass] = 0;
} else {
int val = ( next_bits &0x1C ) >> 2;
if (val >= 4)
val++;
block_ptr[i * sb_size + pass] = buff_middle[-4 + val];
avail_bits -= 5;
next_bits >>= 5;
}
}
return 1;
}
int CValueUnpacker::k4_4bits(int pass, int /*ind*/)
{
// fills with values: +/-4, +/-3, +/-2, +/-1, 0, and double zeros
// efficiency: 4-3*P0, P0 - cnt of all zeros (both single and paired).
for (int i = 0; i < subblocks; i++) {
prepare_bits( 4 );
if (( next_bits & 1 ) == 0) {
avail_bits--;
next_bits >>= 1;
block_ptr[i * sb_size + pass] = 0;
} else {
int val = ( next_bits &0xE ) >> 1;
avail_bits -= 4;
next_bits >>= 4;
if (val >= 4)
val++;
block_ptr[i * sb_size + pass] = buff_middle[-4 + val];
}
}
return 1;
}
int CValueUnpacker::t3_7bits(int pass, int /*ind*/)
{
//Eng: all the pairs of values from -5 to +5
// efficiency: 7/2 bits per value
//Rus: âñå êîìáèíàöèè ïàð îò -5 äî +5
// ýôôåêòèâíîñòü: 7/2 áèòà íà çíà÷åíèå - âñåãäà
for (int i = 0; i < subblocks; i++) {
int bits = ( int ) ( get_bits( 7 ) & 0x7f );
unsigned char val = Table3[bits];
block_ptr[i * sb_size + pass] = buff_middle[-5 + ( val & 0xF )];
if (( ++i ) == subblocks)
break;
val >>= 4;
block_ptr[i * sb_size + pass] = buff_middle[-5 + val];
}
return 1;
}

View File

@@ -0,0 +1,93 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#ifndef _ACM_LAB_VALUE_UNPACKER_H
#define _ACM_LAB_VALUE_UNPACKER_H
#include "System/DataStream.h"
#define UNPACKER_BUFFER_SIZE 16384
class CValueUnpacker {
private:
// Parameters of ACM stream
int levels, subblocks;
//FILE* file;
DataStream* stream;
// Bits
unsigned int next_bits; // new bits
int avail_bits; // count of new bits
unsigned char bits_buffer[UNPACKER_BUFFER_SIZE];
unsigned int buffer_bit_offset;
int sb_size, block_size;
short* amp_buffer, * buff_middle;
int* block_ptr;
// Reading routines
void prepare_bits(int bits); // request bits
int get_bits(int bits); // request and return next bits
public:
// These functions are used to fill the buffer with the amplitude values
int return0(int pass, int ind);
int zero_fill(int pass, int ind);
int linear_fill(int pass, int ind);
int k1_3bits(int pass, int ind);
int k1_2bits(int pass, int ind);
int t1_5bits(int pass, int ind);
int k2_4bits(int pass, int ind);
int k2_3bits(int pass, int ind);
int t2_7bits(int pass, int ind);
int k3_5bits(int pass, int ind);
int k3_4bits(int pass, int ind);
int k4_5bits(int pass, int ind);
int k4_4bits(int pass, int ind);
int t3_7bits(int pass, int ind);
CValueUnpacker(int lev_cnt, int sb_count, DataStream* stream)
: levels( lev_cnt ), subblocks( sb_count ), next_bits( 0 ),
avail_bits( 0 ), buffer_bit_offset( UNPACKER_BUFFER_SIZE ),
sb_size( 1 << levels ),
block_size( sb_size*subblocks ), amp_buffer( NULL ),
buff_middle( NULL ), block_ptr( NULL )
{
this->stream = stream;
}
virtual ~CValueUnpacker()
{
if (amp_buffer) {
free(amp_buffer);
amp_buffer = NULL;
}
}
int init_unpacker();
int get_one_block(int* block);
};
typedef int (CValueUnpacker::* FillerProc) (int pass, int ind);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,92 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#ifndef AREIMPORTER_H
#define AREIMPORTER_H
#include "MapMgr.h"
class Animation;
class AnimationFactory;
class AREImporter : public MapMgr {
private:
DataStream* str;
bool autoFree;
int bigheader;
ieResRef WEDResRef;
ieDword LastSave;
ieDword AreaFlags;
ieWord AreaType, WRain, WSnow, WFog, WLightning, WUnknown;
ieDword ActorOffset, EmbeddedCreOffset, AnimOffset, AnimCount;
ieDword VerticesOffset;
ieDword DoorsCount, DoorsOffset;
ieDword ExploredBitmapSize, ExploredBitmapOffset;
ieDword EntrancesOffset, EntrancesCount;
ieDword SongHeader, RestHeader;
ieWord ActorCount, VerticesCount, AmbiCount;
ieWord ContainersCount, InfoPointsCount, ItemsCount;
ieDword VariablesCount;
ieDword ContainersOffset, InfoPointsOffset, ItemsOffset;
ieDword AmbiOffset, VariablesOffset;
ieDword SpawnOffset, SpawnCount;
ieDword TileOffset, TileCount;
ieDword NoteOffset, NoteCount;
ieDword TrapOffset, TrapCount; //only in ToB?
proIterator piter; //iterator for saving projectiles
ieDword EffectOffset;
ieResRef Script;
ieResRef Dream1, Dream2; //only in ToB
public:
AREImporter(void);
~AREImporter(void);
bool Open(DataStream* stream, bool autoFree = true);
bool ChangeMap(Map *map, bool day_or_night);
Map* GetMap(const char* ResRef, bool day_or_night);
int GetStoredFileSize(Map *map);
/* stores an area in the Cache (swaps it out) */
int PutArea(DataStream *stream, Map *map);
private:
void ReadEffects(DataStream *ds, EffectQueue *fx, ieDword EffectsCount);
CREItem* GetItem();
int PutHeader(DataStream *stream, Map *map);
int PutPoints(DataStream *stream, Point *p, unsigned int count);
int PutDoors(DataStream *stream, Map *map, ieDword &VertIndex);
int PutItems(DataStream *stream, Map *map);
int PutContainers(DataStream *stream, Map *map, ieDword &VertIndex);
int PutRegions(DataStream *stream, Map *map, ieDword &VertIndex);
int PutVertices(DataStream *stream, Map *map);
int PutSpawns(DataStream *stream, Map *map);
void PutScript(DataStream *stream, Actor *ac, unsigned int index);
int PutActors(DataStream *stream, Map *map);
int PutAnimations(DataStream *stream, Map *map);
int PutEntrances(DataStream *stream, Map *map);
int PutVariables(DataStream *stream, Map *map);
int PutAmbients(DataStream *stream, Map *map);
int PutMapnotes(DataStream *stream, Map *map);
int PutEffects( DataStream *stream, EffectQueue *fxqueue);
int PutTraps(DataStream *stream, Map *map);
int PutExplored(DataStream *stream, Map *map);
int PutTiles(DataStream *stream, Map *map);
int PutRestHeader(DataStream *stream, Map *map);
int PutSongHeader(DataStream *stream, Map *map);
};
#endif

View File

@@ -0,0 +1 @@
ADD_GEMRB_PLUGIN (AREImporter AREImporter.cpp)

View File

@@ -0,0 +1,3 @@
plugin_LTLIBRARIES = AREImporter.la
AREImporter_la_LDFLAGS = -module -avoid-version -shared
AREImporter_la_SOURCES = AREImporter.cpp AREImporter.h

View File

@@ -0,0 +1,395 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#if defined(__HAIKU__)
#include <unistd.h>
#endif
#ifdef ANDROID
#include "swab.h"
#endif
#include "BAMImporter.h"
#include "win32def.h"
#include "Compressor.h"
#include "GameData.h"
#include "Interface.h"
#include "Palette.h"
#include "Video.h"
#include "System/FileStream.h"
BAMImporter::BAMImporter(void)
{
str = NULL;
autoFree = false;
frames = NULL;
cycles = NULL;
palette = NULL;
FramesCount = 0;
CyclesCount = 0;
}
BAMImporter::~BAMImporter(void)
{
if (str && autoFree) {
delete( str );
}
delete[] frames;
delete[] cycles;
gamedata->FreePalette(palette);
}
bool BAMImporter::Open(DataStream* stream, bool autoFree)
{
unsigned int i;
if (stream == NULL) {
return false;
}
if (str && this->autoFree) {
delete( str );
}
delete[] frames;
delete[] cycles;
gamedata->FreePalette(palette);
str = stream;
this->autoFree = autoFree;
char Signature[8];
str->Read( Signature, 8 );
if (strncmp( Signature, "BAMCV1 ", 8 ) == 0) {
//Check if Decompressed file has already been Cached
char cpath[_MAX_PATH];
strcpy( cpath, core->CachePath );
strcat( cpath, stream->filename );
FILE* exist_in_cache = fopen( cpath, "rb" );
if (exist_in_cache) {
//File was previously cached, using local copy
if (autoFree) {
delete( str );
}
fclose( exist_in_cache );
FileStream* s = new FileStream();
s->Open( cpath );
str = s;
str->Read( Signature, 8 );
} else {
//No file found in Cache, Decompressing and storing for further use
str->Seek( 4, GEM_CURRENT_POS );
if (!core->IsAvailable( PLUGIN_COMPRESSION_ZLIB )) {
printf( "No Compression Manager Available.\nCannot Load Compressed Bam File.\n" );
return false;
}
FILE* newfile = fopen( cpath, "wb" );
if (!newfile) {
printMessage("BAMImporter", " ", RED);
printf( "Cannot write %s.\n", cpath );
return false;
}
PluginHolder<Compressor> comp(PLUGIN_COMPRESSION_ZLIB);
comp->Decompress( newfile, str );
fclose( newfile );
if (autoFree)
delete( str );
FileStream* s = new FileStream();
s->Open( cpath );
str = s;
str->Read( Signature, 8 );
}
}
if (strncmp( Signature, "BAM V1 ", 8 ) != 0) {
return false;
}
str->ReadWord( &FramesCount );
str->Read( &CyclesCount, 1 );
str->Read( &CompressedColorIndex, 1 );
str->ReadDword( &FramesOffset );
str->ReadDword( &PaletteOffset );
str->ReadDword( &FLTOffset );
str->Seek( FramesOffset, GEM_STREAM_START );
frames = new FrameEntry[FramesCount];
DataStart = str->Size();
for (i = 0; i < FramesCount; i++) {
str->ReadWord( &frames[i].Width );
str->ReadWord( &frames[i].Height );
str->ReadWord( &frames[i].XPos );
str->ReadWord( &frames[i].YPos );
str->ReadDword( &frames[i].FrameData );
if ((frames[i].FrameData & 0x7FFFFFFF) < DataStart)
DataStart = (frames[i].FrameData & 0x7FFFFFFF);
}
cycles = new CycleEntry[CyclesCount];
for (i = 0; i < CyclesCount; i++) {
str->ReadWord( &cycles[i].FramesCount );
str->ReadWord( &cycles[i].FirstFrame );
}
str->Seek( PaletteOffset, GEM_STREAM_START );
palette = new Palette();
// no need to switch this
for (i = 0; i < 256; i++) {
RevColor rc;
str->Read( &rc, 4 );
palette->col[i].r = rc.r;
palette->col[i].g = rc.g;
palette->col[i].b = rc.b;
palette->col[i].a = rc.a;
}
return true;
}
int BAMImporter::GetCycleSize(unsigned char Cycle)
{
if(Cycle >= CyclesCount ) {
return -1;
}
return cycles[Cycle].FramesCount;
}
Sprite2D* BAMImporter::GetFrameInternal(unsigned short findex, unsigned char mode,
bool BAMsprite, const unsigned char* data,
AnimationFactory* datasrc)
{
Sprite2D* spr = 0;
if (BAMsprite) {
bool RLECompressed = (frames[findex].FrameData & 0x80000000) == 0;
assert(data);
const unsigned char* framedata = data;
framedata += (frames[findex].FrameData & 0x7FFFFFFF) - DataStart;
if (RLECompressed) {
spr = core->GetVideoDriver()->CreateSpriteBAM8(
frames[findex].Width, frames[findex].Height,
true, framedata, datasrc, palette, CompressedColorIndex);
} else {
spr = core->GetVideoDriver()->CreateSpriteBAM8(
frames[findex].Width, frames[findex].Height, false,
framedata, datasrc, palette, CompressedColorIndex );
}
} else {
void* pixels = GetFramePixels(findex);
spr = core->GetVideoDriver()->CreateSprite8(
frames[findex].Width, frames[findex].Height, 8,
pixels, palette->col, true, 0 );
}
spr->XPos = (ieWordSigned)frames[findex].XPos;
spr->YPos = (ieWordSigned)frames[findex].YPos;
if (mode == IE_SHADED) {
// CHECKME: is this ever used? Should we modify the sprite's palette
// without creating a local copy for this sprite?
Palette* pal = spr->GetPalette();
pal->CreateShadedAlphaChannel();
pal->Release();
}
return spr;
}
void* BAMImporter::GetFramePixels(unsigned short findex)
{
if (findex >= FramesCount) {
findex = cycles[0].FirstFrame;
}
str->Seek( ( frames[findex].FrameData & 0x7FFFFFFF ), GEM_STREAM_START );
unsigned long pixelcount = frames[findex].Height * frames[findex].Width;
void* pixels = malloc( pixelcount );
bool RLECompressed = ( ( frames[findex].FrameData & 0x80000000 ) == 0 );
if (RLECompressed) {
//if RLE Compressed
unsigned long RLESize;
RLESize = ( unsigned long )
( frames[findex].Width * frames[findex].Height * 3 ) / 2 + 1;
//without partial reads, we should be careful
unsigned long remains = str->Remains();
if (RLESize > remains) {
RLESize = remains;
}
unsigned char* inpix;
inpix = (unsigned char*)malloc( RLESize );
if (str->Read( inpix, RLESize ) == GEM_ERROR) {
free( inpix );
return NULL;
}
unsigned char * p = inpix;
unsigned char * Buffer = (unsigned char*)pixels;
unsigned int i = 0;
while (i < pixelcount) {
if (*p == CompressedColorIndex) {
p++;
// FIXME: Czech HOW has apparently broken frame
// #141 in REALMS.BAM. Maybe we should put
// this condition to #ifdef BROKEN_xx ?
// Or maybe rather put correct REALMS.BAM
// into override/ dir?
if (i + ( *p ) + 1 > pixelcount) {
memset( &Buffer[i], CompressedColorIndex, pixelcount - i );
printf ("Broken frame %d\n", findex);
} else {
memset( &Buffer[i], CompressedColorIndex, ( *p ) + 1 );
}
i += *p;
} else
Buffer[i] = *p;
p++;
i++;
}
free( inpix );
} else {
str->Read( pixels, pixelcount );
}
return pixels;
}
ieWord * BAMImporter::CacheFLT(unsigned int &count)
{
int i;
count = 0;
for (i = 0; i < CyclesCount; i++) {
unsigned int tmp = cycles[i].FirstFrame + cycles[i].FramesCount;
if (tmp > count) {
count = tmp;
}
}
ieWord * FLT = ( ieWord * ) calloc( count, sizeof(ieWord) );
str->Seek( FLTOffset, GEM_STREAM_START );
str->Read( FLT, count * sizeof(ieWord) );
if( DataStream::IsEndianSwitch() ) {
//msvc likes it as char *
swab( (char*) FLT, (char*) FLT, count * sizeof(ieWord) );
}
return FLT;
}
AnimationFactory* BAMImporter::GetAnimationFactory(const char* ResRef, unsigned char mode)
{
unsigned int i, count;
AnimationFactory* af = new AnimationFactory( ResRef );
ieWord *FLT = CacheFLT( count );
bool videoBAMsupport = core->GetVideoDriver()->SupportsBAMSprites();
unsigned char* data = NULL;
if (videoBAMsupport) {
str->Seek( DataStart, GEM_STREAM_START );
unsigned long length = str->Remains();
if (length == 0) return af;
//data = new unsigned char[length];
data = (unsigned char *) malloc(length);
str->Read( data, length );
af->SetFrameData(data);
}
for (i = 0; i < FramesCount; ++i) {
Sprite2D* frame = GetFrameInternal(i, mode, videoBAMsupport, data, af);
assert(!videoBAMsupport || frame->BAM);
af->AddFrame(frame);
}
for (i = 0; i < CyclesCount; ++i) {
af->AddCycle( cycles[i] );
}
af->LoadFLT ( FLT, count );
free (FLT);
return af;
}
/** This function will load the Animation as a Font */
Font* BAMImporter::GetFont()
{
unsigned int i;
int w = 0, h = 0;
unsigned int Count;
ieWord *FLT = CacheFLT(Count);
// Numeric fonts have all frames in single cycle
if (CyclesCount > 1) {
Count = CyclesCount;
} else {
Count = FramesCount;
}
for (i = 0; i < Count; i++) {
unsigned int index;
if (CyclesCount > 1) {
index = FLT[cycles[i].FirstFrame];
if (index >= FramesCount)
continue;
} else {
index = i;
}
w = w + frames[index].Width;
if (frames[index].Height > h)
h = frames[index].Height;
}
Font* fnt = new Font( w, h, palette );
for (i = 0; i < Count; i++) {
unsigned int index;
if (CyclesCount > 1) {
index = FLT[cycles[i].FirstFrame];
if (index >= FramesCount) {
fnt->AddChar( NULL, 0, 0, 0, 0 );
continue;
}
} else {
index = i;
}
unsigned char* pixels = (unsigned char*)GetFramePixels( index );
if( !pixels) {
fnt->AddChar( NULL, 0, 0, 0, 0 );
continue;
}
fnt->AddChar( pixels, frames[index].Width,
frames[index].Height,
frames[index].XPos,
frames[index].YPos );
free( pixels );
}
free( FLT );
fnt->FinalizeSprite( true, 0 );
return fnt;
}
/** Debug Function: Returns the Global Animation Palette as a Sprite2D Object.
If the Global Animation Palette is NULL, returns NULL. */
Sprite2D* BAMImporter::GetPalette()
{
unsigned char * pixels = ( unsigned char * ) malloc( 256 );
unsigned char * p = pixels;
for (int i = 0; i < 256; i++) {
*p++ = ( unsigned char ) i;
}
return core->GetVideoDriver()->CreateSprite8( 16, 16, 8, pixels, palette->col, false );
}
#include "plugindef.h"
GEMRB_PLUGIN(0x3AD6427A, "BAM File Importer")
PLUGIN_CLASS(IE_BAM_CLASS_ID, BAMImporter)
END_PLUGIN()

View File

@@ -0,0 +1,90 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#ifndef BAMIMPORTER_H
#define BAMIMPORTER_H
#include "AnimationMgr.h"
#include "RGBAColor.h"
#include "globals.h"
struct FrameEntry {
ieWord Width;
ieWord Height;
ieWord XPos;
ieWord YPos;
ieDword FrameData;
};
class Palette;
class BAMImporter : public AnimationMgr {
private:
DataStream* str;
bool autoFree;
FrameEntry* frames;
CycleEntry* cycles;
ieWord FramesCount;
ieByte CyclesCount;
Palette* palette;
ieByte CompressedColorIndex;
ieDword FramesOffset, PaletteOffset, FLTOffset;
unsigned long DataStart;
private:
Sprite2D* GetFrameInternal(unsigned short findex, unsigned char mode,
bool BAMsprite, const unsigned char* data,
AnimationFactory* datasrc);
void* GetFramePixels(unsigned short findex);
ieWord * CacheFLT(unsigned int &count);
public:
BAMImporter(void);
~BAMImporter(void);
bool Open(DataStream* stream, bool autoFree = true);
int GetCycleSize(unsigned char Cycle);
AnimationFactory* GetAnimationFactory(const char* ResRef,
unsigned char mode = IE_NORMAL);
/** This function will load the Animation as a Font */
Font* GetFont();
/** Debug Function: Returns the Global Animation Palette as a Sprite2D Object.
If the Global Animation Palette is NULL, returns NULL. */
Sprite2D* GetPalette();
/** Gets a Pixel Index from the Image, unused */
unsigned int GetPixelIndex(unsigned int /*x*/, unsigned int /*y*/)
{
return 0;
}
/** Gets a Pixel from the Image, unused */
Color GetPixel(unsigned int /*x*/, unsigned int /*y*/)
{
Color null = {
0x00, 0x00, 0x00, 0x00
};
return null;
}
public:
int GetCycleCount()
{
return CyclesCount;
}
};
#endif

View File

@@ -0,0 +1 @@
ADD_GEMRB_PLUGIN (BAMImporter BAMImporter.cpp)

View File

@@ -0,0 +1,3 @@
plugin_LTLIBRARIES = BAMImporter.la
BAMImporter_la_LDFLAGS = -module -avoid-version -shared
BAMImporter_la_SOURCES = BAMImporter.cpp BAMImporter.h

View File

@@ -0,0 +1,348 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#include "BIFImporter.h"
#include "win32def.h"
#include "Compressor.h"
#include "Interface.h"
#include "System/CachedFileStream.h"
#include "System/FileStream.h"
BIFImporter::BIFImporter(void)
{
stream = NULL;
fentries = NULL;
tentries = NULL;
}
BIFImporter::~BIFImporter(void)
{
if (stream) {
delete( stream );
}
if (fentries) {
delete[] fentries;
}
if (tentries) {
delete[] tentries;
}
}
int BIFImporter::DecompressSaveGame(DataStream *compressed)
{
char Signature[8];
compressed->Read( Signature, 8 );
if (strncmp( Signature, "SAV V1.0", 8 ) ) {
return GEM_ERROR;
}
int All = compressed->Remains();
int Current;
if (!All) return GEM_ERROR;
do {
ieDword fnlen, complen, declen;
compressed->ReadDword( &fnlen );
char* fname = ( char* ) malloc( fnlen );
compressed->Read( fname, fnlen );
strlwr(fname);
compressed->ReadDword( &declen );
compressed->ReadDword( &complen );
PathJoin( path, core->CachePath, fname, NULL );
printf( "Decompressing %s\n",fname );
free( fname );
if (!core->IsAvailable( PLUGIN_COMPRESSION_ZLIB ))
return GEM_ERROR;
FILE *in_cache = fopen( path, "wb" );
if (!in_cache) {
printMessage("BIFImporter", " ", RED);
printf( "Cannot write %s.\n", path );
return GEM_ERROR;
}
PluginHolder<Compressor> comp(PLUGIN_COMPRESSION_ZLIB);
if (comp->Decompress( in_cache, compressed, complen ) != GEM_OK) {
return GEM_ERROR;
}
fclose( in_cache );
Current = compressed->Remains();
//starting at 20% going up to 70%
core->LoadProgress( 20+(All-Current)*50/All );
}
while(Current);
return GEM_OK;
}
//this one can create .sav files only
int BIFImporter::CreateArchive(DataStream *compressed)
{
if (stream) {
delete( stream );
stream = NULL;
}
if (!compressed) {
return GEM_ERROR;
}
char Signature[8];
memcpy(Signature,"SAV V1.0",8);
compressed->Write(Signature, 8);
return GEM_OK;
}
int BIFImporter::AddToSaveGame(DataStream *str, DataStream *uncompressed)
{
ieDword fnlen, declen, complen;
fnlen = strlen(uncompressed->filename)+1;
declen = uncompressed->Size();
str->WriteDword( &fnlen);
str->Write( uncompressed->filename, fnlen);
str->WriteDword( &declen);
//baaah, we dump output right in the stream, we get the compressed length
//only after the compressed data was written
complen = 0xcdcdcdcd; //placeholder
unsigned long Pos = str->GetPos(); //storing the stream position
str->WriteDword( &complen);
PluginHolder<Compressor> comp(PLUGIN_COMPRESSION_ZLIB);
comp->Compress( str, uncompressed );
//writing compressed length (calculated)
unsigned long Pos2 = str->GetPos();
complen = Pos2-Pos-sizeof(ieDword); //calculating the compressed stream size
str->Seek(Pos, GEM_STREAM_START); //going back to the placeholder
str->WriteDword( &complen); //updating size
str->Seek(Pos2, GEM_STREAM_START);//resuming work
return GEM_OK;
}
int BIFImporter::OpenArchive(const char* filename)
{
if (stream) {
delete( stream );
stream = NULL;
}
FILE* in_cache = fopen( filename, "rb" );
if( !in_cache) {
return GEM_ERROR;
}
char Signature[8];
if (fread( &Signature, 1, 8, in_cache ) != 8) {
fclose ( in_cache );
return GEM_ERROR;
}
fclose( in_cache );
//normal bif, not in cache
if (strncmp( Signature, "BIFFV1 ", 8 ) == 0) {
stream = new CachedFileStream( filename );
stream->Read( Signature, 8 );
strcpy( path, filename );
ReadBIF();
return GEM_OK;
}
//not found as normal bif
//checking compression type
FileStream* compressed = new FileStream();
compressed->Open( filename, true );
compressed->Read( Signature, 8 );
if (strncmp( Signature, "BIF V1.0", 8 ) == 0) {
ieDword fnlen, complen, declen;
compressed->ReadDword( &fnlen );
char* fname = ( char* ) malloc( fnlen );
compressed->Read( fname, fnlen );
strlwr(fname);
compressed->ReadDword( &declen );
compressed->ReadDword( &complen );
PathJoin( path, core->CachePath, fname, NULL );
free( fname );
in_cache = fopen( path, "rb" );
if (in_cache) {
//printf("Found in Cache\n");
fclose( in_cache );
delete( compressed );
stream = new CachedFileStream( path );
stream->Read( Signature, 8 );
if (strncmp( Signature, "BIFFV1 ", 8 ) == 0)
ReadBIF();
else
return GEM_ERROR;
return GEM_OK;
}
printf( "Decompressing\n" );
if (!core->IsAvailable( PLUGIN_COMPRESSION_ZLIB )) {
printMessage("BIFImporter", "No Compression Manager Available.", RED);
return GEM_ERROR;
}
in_cache = fopen( path, "wb" );
if (!in_cache) {
printMessage("BIFImporter", " ", RED);
printf( "Cannot write %s.\n", path );
return GEM_ERROR;
}
PluginHolder<Compressor> comp(PLUGIN_COMPRESSION_ZLIB);
if (comp->Decompress( in_cache, compressed, complen ) != GEM_OK) {
return GEM_ERROR;
}
fclose( in_cache );
delete( compressed );
stream = new CachedFileStream( path );
stream->Read( Signature, 8 );
if (strncmp( Signature, "BIFFV1 ", 8 ) == 0)
ReadBIF();
else
return GEM_ERROR;
return GEM_OK;
}
if (strncmp( Signature, "BIFCV1.0", 8 ) == 0) {
//printf("'BIFCV1.0' Compressed File Found\n");
PathJoin( path, core->CachePath, compressed->filename, NULL );
in_cache = fopen( path, "rb" );
if (in_cache) {
//printf("Found in Cache\n");
fclose( in_cache );
delete( compressed );
stream = new CachedFileStream( path );
stream->Read( Signature, 8 );
if (strncmp( Signature, "BIFFV1 ", 8 ) == 0) {
ReadBIF();
} else
return GEM_ERROR;
return GEM_OK;
}
printf( "Decompressing\n" );
if (!core->IsAvailable( PLUGIN_COMPRESSION_ZLIB ))
return GEM_ERROR;
PluginHolder<Compressor> comp(PLUGIN_COMPRESSION_ZLIB);
ieDword unCompBifSize;
compressed->ReadDword( &unCompBifSize );
printf( "\nDecompressing file: [..........]" );
fflush(stdout);
in_cache = fopen( path, "wb" );
if (!in_cache) {
printMessage("BIFImporter", " ", RED);
printf( "Cannot write %s.\n", path );
return GEM_ERROR;
}
ieDword finalsize = 0;
int laststep = 0;
while (finalsize < unCompBifSize) {
ieDword complen, declen;
compressed->ReadDword( &declen );
compressed->ReadDword( &complen );
if (comp->Decompress( in_cache, compressed, complen ) != GEM_OK) {
return GEM_ERROR;
}
finalsize = ftell( in_cache );
if (( int ) ( finalsize * ( 10.0 / unCompBifSize ) ) != laststep) {
laststep++;
printf( "\b\b\b\b\b\b\b\b\b\b\b" );
int l;
for (l = 0; l < laststep; l++)
printf( "|" );
for (; l < 10; l++)//l starts from laststep
printf( "." );
printf( "]" );
fflush(stdout);
}
}
printf( "\n" );
fclose( in_cache );
delete( compressed );
stream = new CachedFileStream( path );
stream->Read( Signature, 8 );
if (strncmp( Signature, "BIFFV1 ", 8 ) == 0)
ReadBIF();
else
return GEM_ERROR;
return GEM_OK;
}
delete (compressed);
return GEM_ERROR;
}
DataStream* BIFImporter::GetStream(unsigned long Resource, unsigned long Type)
{
if (Type == IE_TIS_CLASS_ID) {
unsigned int srcResLoc = Resource & 0xFC000;
for (unsigned int i = 0; i < tentcount; i++) {
if (( tentries[i].resLocator & 0xFC000 ) == srcResLoc) {
return new CachedFileStream( stream, tentries[i].dataOffset,
tentries[i].tileSize * tentries[i].tilesCount );
}
}
} else {
ieDword srcResLoc = Resource & 0x3FFF;
for (ieDword i = 0; i < fentcount; i++) {
if (( fentries[i].resLocator & 0x3FFF ) == srcResLoc) {
return new CachedFileStream( stream, fentries[i].dataOffset,
fentries[i].fileSize );
}
}
}
return NULL;
}
void BIFImporter::ReadBIF(void)
{
ieDword foffset;
stream->ReadDword( &fentcount );
stream->ReadDword( &tentcount );
stream->ReadDword( &foffset );
stream->Seek( foffset, GEM_STREAM_START );
fentries = new FileEntry[fentcount];
tentries = new TileEntry[tentcount];
if (!fentries || !tentries) {
if (fentries) {
delete fentries;
fentries = NULL;
}
if (tentries) {
delete tentries;
tentries = NULL;
}
return;
}
unsigned int i;
for (i=0;i<fentcount;i++) {
stream->ReadDword( &fentries[i].resLocator);
stream->ReadDword( &fentries[i].dataOffset);
stream->ReadDword( &fentries[i].fileSize);
stream->ReadWord( &fentries[i].type);
stream->ReadWord( &fentries[i].u1);
}
for (i=0;i<tentcount;i++) {
stream->ReadDword( &tentries[i].resLocator);
stream->ReadDword( &tentries[i].dataOffset);
stream->ReadDword( &tentries[i].tilesCount);
stream->ReadDword( &tentries[i].tileSize);
stream->ReadWord( &tentries[i].type);
stream->ReadWord( &tentries[i].u1);
}
}
#include "plugindef.h"
GEMRB_PLUGIN(0xC7F133C, "BIF File Importer")
PLUGIN_CLASS(IE_BIF_CLASS_ID, BIFImporter)
END_PLUGIN()

View File

@@ -0,0 +1,66 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#ifndef BIFIMPORTER_H
#define BIFIMPORTER_H
#include "ArchiveImporter.h"
#include "globals.h"
#include "System/CachedFileStream.h"
struct FileEntry {
ieDword resLocator;
ieDword dataOffset;
ieDword fileSize;
ieWord type;
ieWord u1; //Unknown Field
};
struct TileEntry {
ieDword resLocator;
ieDword dataOffset;
ieDword tilesCount;
ieDword tileSize; //named tilesize so it isn't confused
ieWord type;
ieWord u1; //Unknown Field
};
class BIFImporter : public ArchiveImporter {
private:
char path[_MAX_PATH];
FileEntry* fentries;
TileEntry* tentries;
ieDword fentcount, tentcount;
CachedFileStream* stream;
public:
BIFImporter(void);
~BIFImporter(void);
int DecompressSaveGame(DataStream *compressed);
int AddToSaveGame(DataStream *str, DataStream *uncompressed);
int OpenArchive(const char* filename);
int CreateArchive(DataStream *compressed);
DataStream* GetStream(unsigned long Resource, unsigned long Type);
private:
void ReadBIF(void);
};
#endif

View File

@@ -0,0 +1 @@
ADD_GEMRB_PLUGIN (BIFImporter BIFImporter.cpp)

View File

@@ -0,0 +1,3 @@
plugin_LTLIBRARIES = BIFImporter.la
BIFImporter_la_LDFLAGS = -module -avoid-version -shared
BIFImporter_la_SOURCES = BIFImporter.cpp BIFImporter.h

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,235 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#ifndef BIKPLAYER_H
#define BIKPLAYER_H
#include "MoviePlayer.h"
#include "globals.h"
#include "win32def.h"
#include "Interface.h"
// FIXME: This has to be included last, since it defines int*_t, which causes
// mingw g++ 4.5.0 to choke.
#include "GetBitContext.h"
#include "common.h"
#include "dsputil.h"
#include "rational.h"
#define BIK_SIGNATURE_LEN 4
#define BIK_SIGNATURE_DATA "BIKi"
#define MAX_CHANNELS 2
#define BINK_BLOCK_MAX_SIZE (MAX_CHANNELS << 11)
enum BinkAudFlags {
BINK_AUD_16BITS = 0x4000, ///< prefer 16-bit output
BINK_AUD_STEREO = 0x2000,
BINK_AUD_USEDCT = 0x1000
};
/**
* IDs for different data types used in Bink video codec
*/
enum Sources {
BINK_SRC_BLOCK_TYPES = 0, ///< 8x8 block types
BINK_SRC_SUB_BLOCK_TYPES, ///< 16x16 block types (a subset of 8x8 block types)
BINK_SRC_COLORS, ///< pixel values used for different block types
BINK_SRC_PATTERN, ///< 8-bit values for 2-colour pattern fill
BINK_SRC_X_OFF, ///< X components of motion value
BINK_SRC_Y_OFF, ///< Y components of motion value
BINK_SRC_INTRA_DC, ///< DC values for intrablocks with DCT
BINK_SRC_INTER_DC, ///< DC values for intrablocks with DCT
BINK_SRC_RUN, ///< run lengths for special fill block
BINK_NB_SRC
};
/**
* Bink video block types
*/
enum BlockTypes {
SKIP_BLOCK = 0, ///< skipped block
SCALED_BLOCK, ///< block has size 16x16
MOTION_BLOCK, ///< block is copied from previous frame with some offset
RUN_BLOCK, ///< block is composed from runs of colours with custom scan order
RESIDUE_BLOCK, ///< motion block with some difference added
INTRA_BLOCK, ///< intra DCT block
FILL_BLOCK, ///< block is filled with single colour
INTER_BLOCK, ///< motion block with DCT applied to the difference
PATTERN_BLOCK, ///< block is filled with two colours following custom pattern
RAW_BLOCK ///< uncoded 8x8 block
};
typedef struct AVFrame {
/**
* pointer to the picture planes.
* This might be different from the first allocated byte
* - encoding:
* - decoding:
*/
uint8_t *data[3];
int linesize[3];
} AVFrame;
typedef struct {
char signature[BIK_SIGNATURE_LEN];
ieDword filesize;
ieDword framecount;
ieDword maxframesize;
//ieDword framecount2; //unused by player
ieDword width;
ieDword height;
ieDword fps;
ieDword divider;
ieDword videoflag;
ieDword tracks; //BinkAudFlags
//optional if tracks == 1 (original had multiple tracks)
ieWord unknown2;
ieWord channels;
ieWord samplerate;
ieWord audioflag;
ieDword unknown4;
} binkheader;
typedef struct {
int keyframe;
ieDword pos;
ieDword size;
} binkframe;
typedef struct Bundle {
int len; ///< length of number of entries to decode (in bits)
Tree tree; ///< Huffman tree-related data
uint8_t *data; ///< buffer for decoded symbols
uint8_t *data_end; ///< buffer end
uint8_t *cur_dec; ///< pointer to the not yet decoded part of the buffer
uint8_t *cur_ptr; ///< pointer to the data that is not read from buffer yet
} Bundle;
class BIKPlayer : public MoviePlayer {
private:
Video *video;
bool validVideo;
binkheader header;
std::vector<binkframe> frames;
ieByte *inbuff;
//subtitle and frame counting
ieDword maxRow;
ieDword rowCount;
ieDword frameCount;
//audio context (consider packing it in a struct)
unsigned int s_frame_len;
unsigned int s_channels;
int s_overlap_len;
int s_block_size;
unsigned int *s_bands;
float s_root;
unsigned int s_num_bands;
int s_first;
bool s_audio;
int s_stream; //openal stream handle
#pragma pack(push,16)
FFTSample s_coeffs[BINK_BLOCK_MAX_SIZE];
short s_previous[BINK_BLOCK_MAX_SIZE / 16]; ///< coeffs from previous audio block
#pragma pack(pop)
float *s_coeffs_ptr[MAX_CHANNELS]; ///< pointers to the coeffs arrays for float_to_int16_interleave
union {
RDFTContext rdft;
DCTContext dct;
} s_trans;
GetBitContext s_gb;
//video context (consider packing it in a struct)
AVRational v_timebase;
long timer_last_sec;
long timer_last_usec;
unsigned int frame_wait;
bool video_rendered_frame;
unsigned int video_frameskip;
bool done;
int outputwidth, outputheight;
unsigned int video_skippedframes;
//bink specific
uint8_t c_idct_permutation[64];
ScanTable c_scantable;
Bundle c_bundle[BINK_NB_SRC]; ///< bundles for decoding all data types
Tree c_col_high[16]; ///< trees for decoding high nibble in "colours" data type
int c_col_lastval; ///< value of last decoded high nibble in "colours" data type
//huffman trees for video decoding
VLC bink_trees[16];
int16_t table[16 * 128][2];
GetBitContext v_gb;
AVFrame c_pic, c_last;
private:
void timer_start();
void timer_wait();
void segment_video_play();
bool next_frame();
int doPlay();
unsigned int fileRead(unsigned int pos, void* buf, unsigned int count);
void showFrame(unsigned char** buf, unsigned int *strides, unsigned int bufw,
unsigned int bufh, unsigned int w, unsigned int h, unsigned int dstx,
unsigned int dsty);
int pollEvents();
int setAudioStream();
void freeAudioStream(int stream);
void queueBuffer(int stream, unsigned short bits,
int channels, short* memory, int size, int samplerate);
int sound_init(bool need_init);
void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable);
int video_init(int w, int h);
void av_set_pts_info(AVRational &time_base, unsigned int pts_num, unsigned int pts_den);
int ReadHeader();
void DecodeBlock(short *out);
int DecodeAudioFrame(void *data, int data_size);
inline int get_value(int bundle);
int read_dct_coeffs(DCTELEM block[64], const uint8_t *scan);
int read_residue(DCTELEM block[64], int masks_count);
int read_runs(Bundle *b);
int read_motion_values(Bundle *b);
int read_block_types(Bundle *b);
int read_patterns(Bundle *b);
int read_colors(Bundle *b);
int read_dcs(Bundle *b, int start_bits, int has_sign);
int get_vlc2(int16_t (*table)[2], int bits, int max_depth);
void read_bundle(int bundle_num);
void init_lengths(int width, int bw);
int DecodeVideoFrame(void *data, int data_size);
int EndAudio();
int EndVideo();
public:
BIKPlayer(void);
~BIKPlayer(void);
bool Open(DataStream* stream);
void CallBackAtFrames(ieDword cnt, ieDword *arg, ieDword *arg2);
int Play();
};
#endif

View File

@@ -0,0 +1 @@
ADD_GEMRB_PLUGIN ( BIKPlayer BIKPlayer.cpp dct.cpp fft.cpp GetBitContext.cpp mem.cpp rational.cpp rdft.cpp )

View File

@@ -0,0 +1,333 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2009 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
// code derived from FFMPEG's libavcodec/get_bits.h
// copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
// and binkaudio.cpp
// Copyright (c) 2007-2009 Peter Ross (pross@xvid.org)
// Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu)
#include <math.h>
#include "GetBitContext.h"
//don't return more than 25 bits this way
unsigned int GetBitContext::get_bits(int n) {
register unsigned int tmp;
tmp = AV_RL32(buffer+(index>>3))>>(index&7);
index+=n;
return tmp& (0xffffffff>>(32-n));
}
//peek at the next <25 bits (without bumping the bit counter)
unsigned int GetBitContext::peek_bits(int n) {
register unsigned int tmp;
tmp = AV_RL32(buffer+(index>>3))>>(index&7);
return tmp& (0xffffffff>>(32-n));
}
//i think, this get_bits_long could be simple get_bits (less than 25 bits taken)
float GetBitContext::get_float()
{
int power = get_bits(5);
float f = ldexpf((float) get_bits_long(23), power - 23);
if (get_bits(1))
f = -f;
return f;
}
void GetBitContext::get_bits_align32()
{
int n = (-get_bits_count()) & 31;
if (n) skip_bits(n);
}
unsigned int GetBitContext::get_bits_long(int n)
{
if(n<=17) return get_bits(n);
else {
int ret= get_bits(16);
return ret | (get_bits(n-16) << 16);
}
}
void GetBitContext::init_get_bits(const uint8_t *b, int bit_size)
{
int buffer_size = (bit_size+7)>>3;
if(buffer_size < 0 || bit_size < 0) {
buffer_size = bit_size = 0;
buffer = NULL;
}
buffer = b;
size_in_bits = bit_size;
buffer_end = buffer + buffer_size;
index=0;
}
//bink video related from bink.c
// * Copyright (c) 2009 Konstantin Shishkov
/**
* Reads information about Huffman tree used to decode data.
*
* @param tree pointer for storing tree data
*/
void GetBitContext::read_tree(Tree *tree)
{
uint8_t tmp1[16], tmp2[16], *in = tmp1, *out = tmp2;
int i, t, len;
tree->vlc_num = get_bits(4);
if (!tree->vlc_num) {
for (i = 0; i < 16; i++)
tree->syms[i] = i;
return;
}
if (get_bits(1)) {
len = get_bits(3);
memset(tmp1, 0, sizeof(tmp1));
for (i = 0; i <= len; i++) {
tree->syms[i] = get_bits(4);
tmp1[tree->syms[i]] = 1;
}
for (i = 0; i < 16; i++)
if (!tmp1[i])
tree->syms[++len] = i;
} else {
len = get_bits(2);
for (i = 0; i < 16; i++)
in[i] = i;
for (i = 0; i <= len; i++) {
int size = 1 << i;
for (t = 0; t < 16; t += size << 1)
merge(out + t, in + t, size);
FFSWAP(uint8_t*, in, out);
}
memcpy(tree->syms, in, 16);
}
}
/**
* Merges two consequent lists of equal size depending on bits read.
*
* @param gb context for reading bits
* @param dst buffer where merged list will be written to
* @param src pointer to the head of the first list (the second lists starts at src+size)
* @param size input lists size
*/
void GetBitContext::merge( uint8_t *dst, uint8_t *src, int size)
{
uint8_t *src2 = src + size;
int size2 = size;
do {
if (!get_bits(1)) {
*dst++ = *src++;
size--;
} else {
*dst++ = *src2++;
size2--;
}
} while (size && size2);
while (size--)
*dst++ = *src++;
while (size2--)
*dst++ = *src2++;
}
void GetBitContext::debug(const char *prefix)
{
printf("%s: %d\n", prefix, index);
}
//VLC specific code from bitstream.c
//removed all non-static parts for simplicity
int VLC::alloc_table(int size)
{
int index;
index = table_size;
table_size += size;
if (table_size > table_allocated) {
abort(); //cant do anything, init_vlc() is used with too little memory
}
return index;
}
#define GET_DATA(v, table, i, wrap, size) \
{\
const uint8_t *ptr = (const uint8_t *)table + i * wrap;\
switch(size) {\
case 1:\
v = *(const uint8_t *)ptr;\
break;\
case 2:\
v = *(const uint16_t *)ptr;\
break;\
default:\
v = *(const uint32_t *)ptr;\
break;\
}\
}
int VLC::build_table(int table_nb_bits, int nb_codes,
const void *bits, int bits_wrap, int bits_size,
const void *codes, int codes_wrap, int codes_size,
uint32_t code_prefix, int n_prefix, int flags)
{
int i, j, k, n, table_size, table_index, nb, n1, index, symbol;
uint32_t code_prefix2;
uint32_t code;
int16_t (*p_table)[2];
table_size = 1 << table_nb_bits;
table_index = alloc_table(table_size);
if (table_index < 0)
return -1;
p_table = &table[table_index];
for(i=0;i<table_size;i++) {
p_table[i][1] = 0; //bits
p_table[i][0] = -1; //codes
}
/* first pass: map codes and compute auxillary table sizes */
for(i=0;i<nb_codes;i++) {
GET_DATA(n, bits, i, bits_wrap, bits_size);
GET_DATA(code, codes, i, codes_wrap, codes_size);
/* we accept tables with holes */
if (n <= 0)
continue;
symbol = i;
/* if code matches the prefix, it is in the table */
n -= n_prefix;
if(flags & INIT_VLC_LE)
code_prefix2= code & (n_prefix>=32 ? 0xffffffff : (1 << n_prefix)-1);
else
code_prefix2= code >> n;
if (n > 0 && code_prefix2 == code_prefix) {
if (n <= table_nb_bits) {
/* no need to add another table */
j = (code << (table_nb_bits - n)) & (table_size - 1);
nb = 1 << (table_nb_bits - n);
for(k=0;k<nb;k++) {
if(flags & INIT_VLC_LE)
j = (code >> n_prefix) + (k<<n);
if (p_table[j][1] /*bits*/ != 0) {
//av_log(NULL, AV_LOG_ERROR, "incorrect codes\n");
return -1;
}
p_table[j][1] = n; //bits
p_table[j][0] = symbol;
j++;
}
} else {
n -= table_nb_bits;
j = (code >> ((flags & INIT_VLC_LE) ? n_prefix : n)) & ((1 << table_nb_bits) - 1);
/* compute table size */
n1 = -p_table[j][1]; //bits
if (n > n1)
n1 = n;
p_table[j][1] = -n1; //bits
}
}
}
/* second pass : fill auxillary tables recursively */
for(i=0;i<table_size;i++) {
n = p_table[i][1]; //bits
if (n < 0) {
n = -n;
if (n > table_nb_bits) {
n = table_nb_bits;
p_table[i][1] = -n; //bits
}
index = build_table(n, nb_codes,
bits, bits_wrap, bits_size,
codes, codes_wrap, codes_size,
(flags & INIT_VLC_LE) ? (code_prefix | (i << n_prefix)) : ((code_prefix << table_nb_bits) | i),
n_prefix + table_nb_bits, flags);
if (index < 0)
return -1;
/* note: realloc has been done, so reload tables */
p_table = &table[table_index];
p_table[i][0] = index; //code
}
}
return table_index;
}
/* Build VLC decoding tables suitable for use with get_vlc().
'nb_bits' set thee decoding table size (2^nb_bits) entries. The
bigger it is, the faster is the decoding. But it should not be too
big to save memory and L1 cache. '9' is a good compromise.
'nb_codes' : number of vlcs codes
'bits' : table which gives the size (in bits) of each vlc code.
'codes' : table which gives the bit pattern of of each vlc code.
'symbols' : table which gives the values to be returned from get_vlc().
'xxx_wrap' : give the number of bytes between each entry of the
'bits' or 'codes' tables.
'xxx_size' : gives the number of bytes of each entry of the 'bits'
or 'codes' tables.
'wrap' and 'size' allows to use any memory configuration and types
(byte/word/long) to store the 'bits', 'codes', and 'symbols' tables.
'use_static' should be set to 1 for tables, which should be freed
with av_free_static(), 0 if free_vlc() will be used.
*/
int VLC::init_vlc(int nb_bits, int nb_codes,
const void *p_bits, int bits_wrap, int bits_size,
const void *codes, int codes_wrap, int codes_size,
int flags)
{
bits = nb_bits;
if(table_size) {
if(table_size == table_allocated) {
return 0;
} else if(table_size) {
//trying to reallocate static table
return -1;
}
}
if (build_table(nb_bits, nb_codes, p_bits, bits_wrap, bits_size,
codes, codes_wrap, codes_size, 0, 0, flags) < 0) {
//no need of freeing this, it was allocated staticly
//av_freep((void **) &table);
return -1;
}
if(table_size != table_allocated) {
//av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", table_size, table_allocated);
}
return 0;
}

View File

@@ -0,0 +1,75 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2009 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
//code derived from FFMPEG
//using code from get_bits.h, bitstream.c
#include "common.h"
#define INIT_VLC_LE 2
#define INIT_VLC_USE_NEW_STATIC 4
class VLC
{
public:
int bits;
int16_t (*table)[2]; ///< code, bits
int table_size, table_allocated;
public:
int init_vlc(int nb_bits, int nb_codes,
const void *bits, int bits_wrap, int bits_size,
const void *codes, int codes_wrap, int codes_size,
int flags);
private:
int alloc_table(int size);
int build_table(int table_nb_bits, int nb_codes,
const void *bits, int bits_wrap, int bits_size,
const void *codes, int codes_wrap, int codes_size,
uint32_t code_prefix, int n_prefix, int flags);
};
#define AV_RL32(x) \
((((const uint8_t*)(x))[3] << 24) | \
(((const uint8_t*)(x))[2] << 16) | \
(((const uint8_t*)(x))[1] << 8) | \
((const uint8_t*)(x))[0])
class GetBitContext
{
public:
const uint8_t *buffer, *buffer_end;
int index;
int size_in_bits;
public:
void debug(const char *prefix);
float get_float();
void skip_bits(int x) { index+=x; }
int get_bits_count() { return index; }
void get_bits_align32();
unsigned int get_bits(int x);
unsigned int peek_bits(int x);
unsigned int get_bits_long(int n);
void init_get_bits(const uint8_t *b, int bit_size);
void read_tree(Tree *tree);
private:
void merge( uint8_t *dst, uint8_t *src, int size);
};

View File

@@ -0,0 +1,16 @@
plugin_LTLIBRARIES = BIKPlayer.la
BIKPlayer_la_LDFLAGS = -module -avoid-version -shared
BIKPlayer_la_SOURCES = \
BIKPlayer.cpp \
BIKPlayer.h \
GetBitContext.cpp \
GetBitContext.h \
dct.cpp \
fft.cpp \
rdft.cpp \
rational.cpp \
rational.h \
mem.cpp \
binkdata.h \
dsputil.h \
common.h

View File

@@ -0,0 +1,612 @@
/*
* Bink video decoder
* Copyright (C) 2009 Kostya Shishkov
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_BINKDATA_H
#define AVCODEC_BINKDATA_H
/** Bink DCT and residue 8x8 block scan order */
static const uint8_t bink_scan[64] = {
0, 1, 8, 9, 2, 3, 10, 11,
4, 5, 12, 13, 6, 7, 14, 15,
20, 21, 28, 29, 22, 23, 30, 31,
16, 17, 24, 25, 32, 33, 40, 41,
34, 35, 42, 43, 48, 49, 56, 57,
50, 51, 58, 59, 18, 19, 26, 27,
36, 37, 44, 45, 38, 39, 46, 47,
52, 53, 60, 61, 54, 55, 62, 63
};
static const uint8_t bink_tree_bits[16][16] = {
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
},
{
0x00, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D,
0x0F, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,
},
{
0x00, 0x02, 0x01, 0x09, 0x05, 0x15, 0x0D, 0x1D,
0x03, 0x13, 0x0B, 0x1B, 0x07, 0x17, 0x0F, 0x1F,
},
{
0x00, 0x02, 0x06, 0x01, 0x09, 0x05, 0x0D, 0x1D,
0x03, 0x13, 0x0B, 0x1B, 0x07, 0x17, 0x0F, 0x1F,
},
{
0x00, 0x04, 0x02, 0x06, 0x01, 0x09, 0x05, 0x0D,
0x03, 0x13, 0x0B, 0x1B, 0x07, 0x17, 0x0F, 0x1F,
},
{
0x00, 0x04, 0x02, 0x0A, 0x06, 0x0E, 0x01, 0x09,
0x05, 0x0D, 0x03, 0x0B, 0x07, 0x17, 0x0F, 0x1F,
},
{
0x00, 0x02, 0x0A, 0x06, 0x0E, 0x01, 0x09, 0x05,
0x0D, 0x03, 0x0B, 0x1B, 0x07, 0x17, 0x0F, 0x1F,
},
{
0x00, 0x01, 0x05, 0x03, 0x13, 0x0B, 0x1B, 0x3B,
0x07, 0x27, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F,
},
{
0x00, 0x01, 0x03, 0x13, 0x0B, 0x2B, 0x1B, 0x3B,
0x07, 0x27, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F,
},
{
0x00, 0x01, 0x05, 0x0D, 0x03, 0x13, 0x0B, 0x1B,
0x07, 0x27, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F,
},
{
0x00, 0x02, 0x01, 0x05, 0x0D, 0x03, 0x13, 0x0B,
0x1B, 0x07, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F,
},
{
0x00, 0x01, 0x09, 0x05, 0x0D, 0x03, 0x13, 0x0B,
0x1B, 0x07, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F,
},
{
0x00, 0x02, 0x01, 0x03, 0x13, 0x0B, 0x1B, 0x3B,
0x07, 0x27, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F,
},
{
0x00, 0x01, 0x05, 0x03, 0x07, 0x27, 0x17, 0x37,
0x0F, 0x4F, 0x2F, 0x6F, 0x1F, 0x5F, 0x3F, 0x7F,
},
{
0x00, 0x01, 0x05, 0x03, 0x07, 0x17, 0x37, 0x77,
0x0F, 0x4F, 0x2F, 0x6F, 0x1F, 0x5F, 0x3F, 0x7F,
},
{
0x00, 0x02, 0x01, 0x05, 0x03, 0x07, 0x27, 0x17,
0x37, 0x0F, 0x2F, 0x6F, 0x1F, 0x5F, 0x3F, 0x7F,
},
};
static const uint8_t bink_tree_lens[16][16] = {
{ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 },
{ 1, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 },
{ 2, 2, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 },
{ 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 },
{ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5 },
{ 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5 },
{ 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5 },
{ 1, 3, 3, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
{ 1, 2, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
{ 1, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6 },
{ 2, 2, 3, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6 },
{ 1, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6 },
{ 2, 2, 2, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
{ 1, 3, 3, 3, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7 },
{ 1, 3, 3, 3, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 },
{ 2, 2, 3, 3, 3, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7 },
};
static const uint8_t bink_patterns[16][64] = {
{
0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38,
0x39, 0x31, 0x29, 0x21, 0x19, 0x11, 0x09, 0x01,
0x02, 0x0A, 0x12, 0x1A, 0x22, 0x2A, 0x32, 0x3A,
0x3B, 0x33, 0x2B, 0x23, 0x1B, 0x13, 0x0B, 0x03,
0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x34, 0x3C,
0x3D, 0x35, 0x2D, 0x25, 0x1D, 0x15, 0x0D, 0x05,
0x06, 0x0E, 0x16, 0x1E, 0x26, 0x2E, 0x36, 0x3E,
0x3F, 0x37, 0x2F, 0x27, 0x1F, 0x17, 0x0F, 0x07,
},
{
0x3B, 0x3A, 0x39, 0x38, 0x30, 0x31, 0x32, 0x33,
0x2B, 0x2A, 0x29, 0x28, 0x20, 0x21, 0x22, 0x23,
0x1B, 0x1A, 0x19, 0x18, 0x10, 0x11, 0x12, 0x13,
0x0B, 0x0A, 0x09, 0x08, 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07, 0x0F, 0x0E, 0x0D, 0x0C,
0x14, 0x15, 0x16, 0x17, 0x1F, 0x1E, 0x1D, 0x1C,
0x24, 0x25, 0x26, 0x27, 0x2F, 0x2E, 0x2D, 0x2C,
0x34, 0x35, 0x36, 0x37, 0x3F, 0x3E, 0x3D, 0x3C,
},
{
0x19, 0x11, 0x12, 0x1A, 0x1B, 0x13, 0x0B, 0x03,
0x02, 0x0A, 0x09, 0x01, 0x00, 0x08, 0x10, 0x18,
0x20, 0x28, 0x30, 0x38, 0x39, 0x31, 0x29, 0x2A,
0x32, 0x3A, 0x3B, 0x33, 0x2B, 0x23, 0x22, 0x21,
0x1D, 0x15, 0x16, 0x1E, 0x1F, 0x17, 0x0F, 0x07,
0x06, 0x0E, 0x0D, 0x05, 0x04, 0x0C, 0x14, 0x1C,
0x24, 0x2C, 0x34, 0x3C, 0x3D, 0x35, 0x2D, 0x2E,
0x36, 0x3E, 0x3F, 0x37, 0x2F, 0x27, 0x26, 0x25,
},
{
0x03, 0x0B, 0x02, 0x0A, 0x01, 0x09, 0x00, 0x08,
0x10, 0x18, 0x11, 0x19, 0x12, 0x1A, 0x13, 0x1B,
0x23, 0x2B, 0x22, 0x2A, 0x21, 0x29, 0x20, 0x28,
0x30, 0x38, 0x31, 0x39, 0x32, 0x3A, 0x33, 0x3B,
0x3C, 0x34, 0x3D, 0x35, 0x3E, 0x36, 0x3F, 0x37,
0x2F, 0x27, 0x2E, 0x26, 0x2D, 0x25, 0x2C, 0x24,
0x1C, 0x14, 0x1D, 0x15, 0x1E, 0x16, 0x1F, 0x17,
0x0F, 0x07, 0x0E, 0x06, 0x0D, 0x05, 0x0C, 0x04,
},
{
0x18, 0x19, 0x10, 0x11, 0x08, 0x09, 0x00, 0x01,
0x02, 0x03, 0x0A, 0x0B, 0x12, 0x13, 0x1A, 0x1B,
0x1C, 0x1D, 0x14, 0x15, 0x0C, 0x0D, 0x04, 0x05,
0x06, 0x07, 0x0E, 0x0F, 0x16, 0x17, 0x1E, 0x1F,
0x27, 0x26, 0x2F, 0x2E, 0x37, 0x36, 0x3F, 0x3E,
0x3D, 0x3C, 0x35, 0x34, 0x2D, 0x2C, 0x25, 0x24,
0x23, 0x22, 0x2B, 0x2A, 0x33, 0x32, 0x3B, 0x3A,
0x39, 0x38, 0x31, 0x30, 0x29, 0x28, 0x21, 0x20,
},
{
0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B,
0x10, 0x11, 0x12, 0x13, 0x18, 0x19, 0x1A, 0x1B,
0x20, 0x21, 0x22, 0x23, 0x28, 0x29, 0x2A, 0x2B,
0x30, 0x31, 0x32, 0x33, 0x38, 0x39, 0x3A, 0x3B,
0x04, 0x05, 0x06, 0x07, 0x0C, 0x0D, 0x0E, 0x0F,
0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F,
0x24, 0x25, 0x26, 0x27, 0x2C, 0x2D, 0x2E, 0x2F,
0x34, 0x35, 0x36, 0x37, 0x3C, 0x3D, 0x3E, 0x3F,
},
{
0x06, 0x07, 0x0F, 0x0E, 0x0D, 0x05, 0x0C, 0x04,
0x03, 0x0B, 0x02, 0x0A, 0x09, 0x01, 0x00, 0x08,
0x10, 0x18, 0x11, 0x19, 0x12, 0x1A, 0x13, 0x1B,
0x14, 0x1C, 0x15, 0x1D, 0x16, 0x1E, 0x17, 0x1F,
0x27, 0x2F, 0x26, 0x2E, 0x25, 0x2D, 0x24, 0x2C,
0x23, 0x2B, 0x22, 0x2A, 0x21, 0x29, 0x20, 0x28,
0x31, 0x30, 0x38, 0x39, 0x3A, 0x32, 0x3B, 0x33,
0x3C, 0x34, 0x3D, 0x35, 0x36, 0x37, 0x3F, 0x3E,
},
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38,
},
{
0x00, 0x08, 0x09, 0x01, 0x02, 0x03, 0x0B, 0x0A,
0x12, 0x13, 0x1B, 0x1A, 0x19, 0x11, 0x10, 0x18,
0x20, 0x28, 0x29, 0x21, 0x22, 0x23, 0x2B, 0x2A,
0x32, 0x31, 0x30, 0x38, 0x39, 0x3A, 0x3B, 0x33,
0x34, 0x3C, 0x3D, 0x3E, 0x3F, 0x37, 0x36, 0x35,
0x2D, 0x2C, 0x24, 0x25, 0x26, 0x2E, 0x2F, 0x27,
0x1F, 0x17, 0x16, 0x1E, 0x1D, 0x1C, 0x14, 0x15,
0x0D, 0x0C, 0x04, 0x05, 0x06, 0x0E, 0x0F, 0x07,
},
{
0x18, 0x19, 0x10, 0x11, 0x08, 0x09, 0x00, 0x01,
0x02, 0x03, 0x0A, 0x0B, 0x12, 0x13, 0x1A, 0x1B,
0x1C, 0x1D, 0x14, 0x15, 0x0C, 0x0D, 0x04, 0x05,
0x06, 0x07, 0x0E, 0x0F, 0x16, 0x17, 0x1E, 0x1F,
0x26, 0x27, 0x2E, 0x2F, 0x36, 0x37, 0x3E, 0x3F,
0x3C, 0x3D, 0x34, 0x35, 0x2C, 0x2D, 0x24, 0x25,
0x22, 0x23, 0x2A, 0x2B, 0x32, 0x33, 0x3A, 0x3B,
0x38, 0x39, 0x30, 0x31, 0x28, 0x29, 0x20, 0x21,
},
{
0x00, 0x08, 0x01, 0x09, 0x02, 0x0A, 0x03, 0x0B,
0x13, 0x1B, 0x12, 0x1A, 0x11, 0x19, 0x10, 0x18,
0x20, 0x28, 0x21, 0x29, 0x22, 0x2A, 0x23, 0x2B,
0x33, 0x3B, 0x32, 0x3A, 0x31, 0x39, 0x30, 0x38,
0x3C, 0x34, 0x3D, 0x35, 0x3E, 0x36, 0x3F, 0x37,
0x2F, 0x27, 0x2E, 0x26, 0x2D, 0x25, 0x2C, 0x24,
0x1F, 0x17, 0x1E, 0x16, 0x1D, 0x15, 0x1C, 0x14,
0x0C, 0x04, 0x0D, 0x05, 0x0E, 0x06, 0x0F, 0x07,
},
{
0x00, 0x08, 0x10, 0x18, 0x19, 0x1A, 0x1B, 0x13,
0x0B, 0x03, 0x02, 0x01, 0x09, 0x11, 0x12, 0x0A,
0x04, 0x0C, 0x14, 0x1C, 0x1D, 0x1E, 0x1F, 0x17,
0x0F, 0x07, 0x06, 0x05, 0x0D, 0x15, 0x16, 0x0E,
0x24, 0x2C, 0x34, 0x3C, 0x3D, 0x3E, 0x3F, 0x37,
0x2F, 0x27, 0x26, 0x25, 0x2D, 0x35, 0x36, 0x2E,
0x20, 0x28, 0x30, 0x38, 0x39, 0x3A, 0x3B, 0x33,
0x2B, 0x23, 0x22, 0x21, 0x29, 0x31, 0x32, 0x2A,
},
{
0x00, 0x08, 0x09, 0x01, 0x02, 0x03, 0x0B, 0x0A,
0x13, 0x1B, 0x1A, 0x12, 0x11, 0x10, 0x18, 0x19,
0x21, 0x20, 0x28, 0x29, 0x2A, 0x22, 0x23, 0x2B,
0x33, 0x3B, 0x3A, 0x32, 0x31, 0x39, 0x38, 0x30,
0x34, 0x3C, 0x3D, 0x35, 0x36, 0x3E, 0x3F, 0x37,
0x2F, 0x27, 0x26, 0x2E, 0x2D, 0x2C, 0x24, 0x25,
0x1D, 0x1C, 0x14, 0x15, 0x16, 0x1E, 0x1F, 0x17,
0x0E, 0x0F, 0x07, 0x06, 0x05, 0x0D, 0x0C, 0x04,
},
{
0x18, 0x10, 0x08, 0x00, 0x01, 0x02, 0x03, 0x0B,
0x13, 0x1B, 0x1A, 0x19, 0x11, 0x0A, 0x09, 0x12,
0x1C, 0x14, 0x0C, 0x04, 0x05, 0x06, 0x07, 0x0F,
0x17, 0x1F, 0x1E, 0x1D, 0x15, 0x0E, 0x0D, 0x16,
0x3C, 0x34, 0x2C, 0x24, 0x25, 0x26, 0x27, 0x2F,
0x37, 0x3F, 0x3E, 0x3D, 0x35, 0x2E, 0x2D, 0x36,
0x38, 0x30, 0x28, 0x20, 0x21, 0x22, 0x23, 0x2B,
0x33, 0x3B, 0x3A, 0x39, 0x31, 0x2A, 0x29, 0x32,
},
{
0x00, 0x08, 0x09, 0x01, 0x02, 0x0A, 0x12, 0x11,
0x10, 0x18, 0x19, 0x1A, 0x1B, 0x13, 0x0B, 0x03,
0x07, 0x06, 0x0E, 0x0F, 0x17, 0x16, 0x15, 0x0D,
0x05, 0x04, 0x0C, 0x14, 0x1C, 0x1D, 0x1E, 0x1F,
0x3F, 0x3E, 0x36, 0x37, 0x2F, 0x2E, 0x2D, 0x35,
0x3D, 0x3C, 0x34, 0x2C, 0x24, 0x25, 0x26, 0x27,
0x38, 0x30, 0x31, 0x39, 0x3A, 0x32, 0x2A, 0x29,
0x28, 0x20, 0x21, 0x22, 0x23, 0x2B, 0x33, 0x3B,
},
{
0x00, 0x01, 0x08, 0x09, 0x10, 0x11, 0x18, 0x19,
0x20, 0x21, 0x28, 0x29, 0x30, 0x31, 0x38, 0x39,
0x3A, 0x3B, 0x32, 0x33, 0x2A, 0x2B, 0x22, 0x23,
0x1A, 0x1B, 0x12, 0x13, 0x0A, 0x0B, 0x02, 0x03,
0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x3C, 0x3D,
0x3E, 0x3F, 0x36, 0x37, 0x2E, 0x2F, 0x26, 0x27,
0x1E, 0x1F, 0x16, 0x17, 0x0E, 0x0F, 0x06, 0x07,
}
};
static const uint32_t bink_intra_quant[16][64] = {
{
0x00010000, 0x00016315, 0x00014E7B, 0x00016577, 0x00010000, 0x0000EEDA, 0x0000BE80, 0x0000611E,
0x0001E83D, 0x0002A535, 0x0002F1E6, 0x0002724C, 0x00024102, 0x00017F9B, 0x0001083C, 0x0000A552,
0x0002346F, 0x00030EE5, 0x0002C628, 0x00027F20, 0x00021F88, 0x0001DC53, 0x00014819, 0x0000A743,
0x0001FBFA, 0x0002C096, 0x000297B5, 0x00023F32, 0x00027FAD, 0x0001F697, 0x00015A31, 0x00009688,
0x0001D000, 0x00028396, 0x0002346F, 0x0001FBFA, 0x00025000, 0x0001AB6B, 0x00012669, 0x00008D43,
0x00019247, 0x0001F9AA, 0x0001DC53, 0x000231B8, 0x0001D122, 0x000159B3, 0x0000EE1F, 0x000075ED,
0x00012F12, 0x0001E06C, 0x0001C48C, 0x00019748, 0x0001490C, 0x00010288, 0x0000E0F1, 0x000072AD,
0x0000CB10, 0x000119A8, 0x00014E86, 0x000122AF, 0x0000F735, 0x0000EF51, 0x0000A4D8, 0x00006517,
},
{
0x00015555, 0x0001D971, 0x0001BDF9, 0x0001DC9F, 0x00015555, 0x00013E78, 0x0000FE00, 0x0000817D,
0x00028AFC, 0x000386F1, 0x0003ED33, 0x00034311, 0x00030158, 0x0001FF7A, 0x0001604F, 0x0000DC6D,
0x0002F095, 0x000413DC, 0x0003B2E0, 0x0003542A, 0x0002D4B5, 0x00027B19, 0x0001B577, 0x0000DF04,
0x0002A54E, 0x0003AB73, 0x000374F1, 0x0002FEEE, 0x000354E7, 0x00029E1F, 0x0001CD96, 0x0000C8B6,
0x00026AAB, 0x00035A1E, 0x0002F095, 0x0002A54E, 0x00031555, 0x000239E4, 0x0001888C, 0x0000BC59,
0x0002185E, 0x0002A238, 0x00027B19, 0x0002ECF5, 0x00026C2D, 0x0001CCEE, 0x00013D7E, 0x00009D3C,
0x00019418, 0x00028090, 0x00025B66, 0x00021F0B, 0x0001B6BB, 0x000158B5, 0x00012BEC, 0x000098E6,
0x00010EC0, 0x0001778A, 0x0001BE09, 0x00018394, 0x0001499C, 0x00013F17, 0x0000DBCB, 0x000086C9,
},
{
0x0001AAAB, 0x00024FCE, 0x00022D78, 0x000253C7, 0x0001AAAB, 0x00018E16, 0x00013D80, 0x0000A1DC,
0x00032DBB, 0x000468AD, 0x0004E87F, 0x000413D5, 0x0003C1AE, 0x00027F58, 0x0001B863, 0x00011388,
0x0003ACBA, 0x000518D3, 0x00049F98, 0x00042935, 0x000389E2, 0x000319DF, 0x000222D4, 0x000116C5,
0x00034EA1, 0x0004964F, 0x0004522D, 0x0003BEA9, 0x00042A21, 0x000345A7, 0x000240FC, 0x0000FAE3,
0x00030555, 0x000430A5, 0x0003ACBA, 0x00034EA1, 0x0003DAAB, 0x0002C85D, 0x0001EAAF, 0x0000EB6F,
0x00029E76, 0x00034AC5, 0x000319DF, 0x0003A833, 0x00030738, 0x0002402A, 0x00018CDE, 0x0000C48A,
0x0001F91E, 0x000320B4, 0x0002F23F, 0x0002A6CE, 0x00022469, 0x0001AEE2, 0x000176E7, 0x0000BF20,
0x00015270, 0x0001D56D, 0x00022D8B, 0x0001E479, 0x00019C02, 0x00018EDD, 0x000112BE, 0x0000A87B,
},
{
0x00020000, 0x0002C62A, 0x00029CF6, 0x0002CAEF, 0x00020000, 0x0001DDB4, 0x00017D01, 0x0000C23C,
0x0003D07A, 0x00054A69, 0x0005E3CC, 0x0004E499, 0x00048204, 0x0002FF36, 0x00021077, 0x00014AA3,
0x000468DF, 0x00061DCA, 0x00058C50, 0x0004FE3F, 0x00043F0F, 0x0003B8A6, 0x00029032, 0x00014E86,
0x0003F7F5, 0x0005812C, 0x00052F69, 0x00047E65, 0x0004FF5A, 0x0003ED2E, 0x0002B461, 0x00012D11,
0x0003A000, 0x0005072C, 0x000468DF, 0x0003F7F5, 0x0004A000, 0x000356D6, 0x00024CD2, 0x00011A85,
0x0003248D, 0x0003F353, 0x0003B8A6, 0x00046370, 0x0003A243, 0x0002B365, 0x0001DC3E, 0x0000EBD9,
0x00025E24, 0x0003C0D8, 0x00038919, 0x00032E91, 0x00029218, 0x00020510, 0x0001C1E2, 0x0000E559,
0x00019620, 0x0002334F, 0x00029D0D, 0x0002455E, 0x0001EE69, 0x0001DEA2, 0x000149B0, 0x0000CA2D,
},
{
0x0002AAAB, 0x0003B2E3, 0x00037BF2, 0x0003B93E, 0x0002AAAB, 0x00027CF0, 0x0001FC01, 0x000102FA,
0x000515F8, 0x00070DE2, 0x0007DA65, 0x00068621, 0x000602B1, 0x0003FEF3, 0x0002C09F, 0x0001B8DA,
0x0005E129, 0x000827B8, 0x000765C0, 0x0006A855, 0x0005A96A, 0x0004F632, 0x00036AED, 0x0001BE09,
0x00054A9C, 0x000756E5, 0x0006E9E2, 0x0005FDDB, 0x0006A9CE, 0x00053C3E, 0x00039B2D, 0x0001916B,
0x0004D555, 0x0006B43B, 0x0005E129, 0x00054A9C, 0x00062AAB, 0x000473C8, 0x00031118, 0x000178B2,
0x000430BC, 0x0005446F, 0x0004F632, 0x0005D9EB, 0x0004D85A, 0x000399DC, 0x00027AFD, 0x00013A77,
0x00032830, 0x00050121, 0x0004B6CC, 0x00043E16, 0x00036D76, 0x0002B16A, 0x000257D8, 0x000131CC,
0x00021D80, 0x0002EF14, 0x00037C11, 0x00030728, 0x00029337, 0x00027E2E, 0x0001B796, 0x00010D91,
},
{
0x00038000, 0x0004DACA, 0x000492AE, 0x0004E322, 0x00038000, 0x000343FB, 0x00029AC1, 0x000153E8,
0x0006ACD5, 0x00094238, 0x000A4EA5, 0x0008900C, 0x0007E388, 0x00053E9F, 0x00039CD0, 0x0002429E,
0x0007B786, 0x000AB421, 0x0009B58C, 0x0008BCEF, 0x00076E5B, 0x00068322, 0x00047C57, 0x0002496B,
0x0006F1ED, 0x0009A20D, 0x000912F8, 0x0007DD30, 0x0008BEDE, 0x0006DF11, 0x0004BBAB, 0x00020EDD,
0x00065800, 0x0008CC8E, 0x0007B786, 0x0006F1ED, 0x00081800, 0x0005D7F7, 0x00040670, 0x0001EE69,
0x00057FF7, 0x0006E9D2, 0x00068322, 0x0007AE04, 0x00065BF6, 0x0004B9F1, 0x0003416C, 0x00019CBC,
0x000424BF, 0x0006917B, 0x00062FEB, 0x0005917D, 0x00047FAA, 0x000388DC, 0x0003134C, 0x0001915C,
0x0002C6B8, 0x0003D9CB, 0x000492D7, 0x0003F964, 0x00036138, 0x0003459C, 0x000240F5, 0x000161CF,
},
{
0x00040000, 0x00058C54, 0x000539EC, 0x000595DD, 0x00040000, 0x0003BB68, 0x0002FA01, 0x00018477,
0x0007A0F4, 0x000A94D3, 0x000BC798, 0x0009C932, 0x00090409, 0x0005FE6D, 0x000420EE, 0x00029547,
0x0008D1BE, 0x000C3B94, 0x000B18A0, 0x0009FC7F, 0x00087E1F, 0x0007714C, 0x00052064, 0x00029D0D,
0x0007EFEA, 0x000B0258, 0x000A5ED3, 0x0008FCC9, 0x0009FEB5, 0x0007DA5D, 0x000568C3, 0x00025A21,
0x00074000, 0x000A0E59, 0x0008D1BE, 0x0007EFEA, 0x00094000, 0x0006ADAC, 0x000499A5, 0x0002350B,
0x0006491A, 0x0007E6A7, 0x0007714C, 0x0008C6E0, 0x00074487, 0x000566CA, 0x0003B87B, 0x0001D7B3,
0x0004BC48, 0x000781B1, 0x00071232, 0x00065D22, 0x00052430, 0x00040A20, 0x000383C5, 0x0001CAB3,
0x00032C3F, 0x0004669F, 0x00053A1A, 0x00048ABC, 0x0003DCD3, 0x0003BD45, 0x00029361, 0x0001945A,
},
{
0x00050000, 0x0006EF69, 0x00068867, 0x0006FB55, 0x00050000, 0x0004AA42, 0x0003B881, 0x0001E595,
0x00098931, 0x000D3A07, 0x000EB97E, 0x000C3B7E, 0x000B450B, 0x00077E08, 0x0005292A, 0x00033A99,
0x000B062D, 0x000F4A78, 0x000DDEC8, 0x000C7B9F, 0x000A9DA7, 0x00094D9F, 0x0006687D, 0x00034450,
0x0009EBE4, 0x000DC2EE, 0x000CF687, 0x000B3BFB, 0x000C7E62, 0x0009D0F4, 0x0006C2F4, 0x0002F0AA,
0x00091000, 0x000C91EF, 0x000B062D, 0x0009EBE4, 0x000B9000, 0x00085917, 0x0005C00E, 0x0002C24D,
0x0007DB61, 0x0009E050, 0x00094D9F, 0x000AF898, 0x000915A8, 0x0006C07D, 0x0004A69A, 0x00024D9F,
0x0005EB59, 0x0009621D, 0x0008D6BE, 0x0007F46A, 0x00066D3C, 0x00050CA7, 0x000464B6, 0x00023D5F,
0x0003F74F, 0x00058046, 0x000688A0, 0x0005AD6B, 0x0004D407, 0x0004AC96, 0x00033839, 0x0001F971,
},
{
0x00060000, 0x0008527E, 0x0007D6E1, 0x000860CC, 0x00060000, 0x0005991C, 0x00047702, 0x000246B3,
0x000B716E, 0x000FDF3C, 0x0011AB63, 0x000EADCB, 0x000D860D, 0x0008FDA3, 0x00063165, 0x0003DFEA,
0x000D3A9C, 0x0012595D, 0x0010A4F0, 0x000EFABE, 0x000CBD2E, 0x000B29F1, 0x0007B096, 0x0003EB93,
0x000BE7DF, 0x00108384, 0x000F8E3C, 0x000D7B2E, 0x000EFE0F, 0x000BC78B, 0x00081D24, 0x00038732,
0x000AE000, 0x000F1585, 0x000D3A9C, 0x000BE7DF, 0x000DE000, 0x000A0482, 0x0006E677, 0x00034F90,
0x00096DA8, 0x000BD9FA, 0x000B29F1, 0x000D2A50, 0x000AE6CA, 0x00081A2F, 0x000594B9, 0x0002C38C,
0x00071A6B, 0x000B4289, 0x000A9B4A, 0x00098BB2, 0x0007B649, 0x00060F2F, 0x000545A7, 0x0002B00C,
0x0004C25F, 0x000699EE, 0x0007D727, 0x0006D01A, 0x0005CB3C, 0x00059BE7, 0x0003DD11, 0x00025E87,
},
{
0x00080000, 0x000B18A8, 0x000A73D7, 0x000B2BBB, 0x00080000, 0x000776CF, 0x0005F402, 0x000308EF,
0x000F41E8, 0x001529A5, 0x00178F2F, 0x00139264, 0x00120812, 0x000BFCD9, 0x000841DC, 0x00052A8E,
0x0011A37B, 0x00187727, 0x00163140, 0x0013F8FE, 0x0010FC3E, 0x000EE297, 0x000A40C8, 0x00053A1A,
0x000FDFD4, 0x001604B0, 0x0014BDA5, 0x0011F992, 0x0013FD69, 0x000FB4B9, 0x000AD186, 0x0004B442,
0x000E8000, 0x00141CB1, 0x0011A37B, 0x000FDFD4, 0x00128000, 0x000D5B58, 0x00093349, 0x00046A15,
0x000C9235, 0x000FCD4D, 0x000EE297, 0x00118DC0, 0x000E890D, 0x000ACD94, 0x000770F7, 0x0003AF65,
0x0009788F, 0x000F0362, 0x000E2463, 0x000CBA43, 0x000A4861, 0x0008143F, 0x00070789, 0x00039565,
0x0006587F, 0x0008CD3D, 0x000A7434, 0x00091577, 0x0007B9A6, 0x00077A89, 0x000526C2, 0x000328B4,
},
{
0x000C0000, 0x0010A4FD, 0x000FADC3, 0x0010C198, 0x000C0000, 0x000B3237, 0x0008EE03, 0x00048D66,
0x0016E2DB, 0x001FBE78, 0x002356C7, 0x001D5B96, 0x001B0C1A, 0x0011FB46, 0x000C62CA, 0x0007BFD5,
0x001A7539, 0x0024B2BB, 0x002149E1, 0x001DF57D, 0x00197A5D, 0x001653E3, 0x000F612C, 0x0007D727,
0x0017CFBD, 0x00210709, 0x001F1C78, 0x001AF65B, 0x001DFC1E, 0x00178F16, 0x00103A49, 0x00070E64,
0x0015C000, 0x001E2B0A, 0x001A7539, 0x0017CFBD, 0x001BC000, 0x00140904, 0x000DCCEE, 0x00069F20,
0x0012DB4F, 0x0017B3F4, 0x001653E3, 0x001A54A0, 0x0015CD94, 0x0010345E, 0x000B2972, 0x00058718,
0x000E34D7, 0x00168513, 0x00153695, 0x00131765, 0x000F6C91, 0x000C1E5E, 0x000A8B4E, 0x00056018,
0x000984BE, 0x000D33DC, 0x000FAE4E, 0x000DA033, 0x000B9678, 0x000B37CE, 0x0007BA22, 0x0004BD0E,
},
{
0x00110000, 0x00179466, 0x0016362A, 0x0017BCED, 0x00110000, 0x000FDC79, 0x000CA685, 0x000672FB,
0x00206C0C, 0x002CF87F, 0x00321044, 0x00299714, 0x00265125, 0x0019794E, 0x00118BF4, 0x000AFA6D,
0x00257B66, 0x0033FD33, 0x002F28A9, 0x002A711B, 0x00241804, 0x001FA181, 0x0015C9A9, 0x000B1B77,
0x0021BBA2, 0x002EC9F7, 0x002C12FF, 0x00263256, 0x002A7A80, 0x0021600A, 0x0016FD3C, 0x0009FF0D,
0x001ED000, 0x002ABCF9, 0x00257B66, 0x0021BBA2, 0x00275000, 0x001C621B, 0x00138CFB, 0x0009616E,
0x001AB6B0, 0x00219444, 0x001FA181, 0x00254D38, 0x001EE33C, 0x0016F4DB, 0x000FD00C, 0x0007D4B7,
0x00142030, 0x001FE730, 0x001E0D52, 0x001B0BCF, 0x0015D9CE, 0x00112B06, 0x000EF004, 0x00079D77,
0x000D7C0E, 0x0012B423, 0x001636EE, 0x00134D9E, 0x00106A80, 0x000FE464, 0x000AF25B, 0x0006B67F,
},
{
0x00160000, 0x001E83CF, 0x001CBE90, 0x001EB842, 0x00160000, 0x001486BA, 0x00105F06, 0x00085891,
0x0029F53D, 0x003A3286, 0x0040C9C2, 0x0035D293, 0x00319630, 0x0020F756, 0x0016B51E, 0x000E3506,
0x00308193, 0x004347AC, 0x003D0771, 0x0036ECBA, 0x002EB5AA, 0x0028EF20, 0x001C3225, 0x000E5FC7,
0x002BA786, 0x003C8CE5, 0x00390986, 0x00316E52, 0x0036F8E1, 0x002B30FE, 0x001DC030, 0x000CEFB7,
0x0027E000, 0x00374EE7, 0x00308193, 0x002BA786, 0x0032E000, 0x0024BB33, 0x00194D09, 0x000C23BB,
0x00229212, 0x002B7494, 0x0028EF20, 0x003045D0, 0x0027F8E4, 0x001DB557, 0x001476A6, 0x000A2256,
0x001A0B89, 0x0029494D, 0x0026E410, 0x00230039, 0x001C470A, 0x001637AD, 0x001354B9, 0x0009DAD6,
0x0011735D, 0x00183469, 0x001CBF8F, 0x0018FB09, 0x00153E87, 0x001490FA, 0x000E2A94, 0x0008AFF0,
},
{
0x001C0000, 0x0026D64D, 0x00249572, 0x0027190E, 0x001C0000, 0x001A1FD6, 0x0014D607, 0x000A9F44,
0x003566AA, 0x004A11C2, 0x00527525, 0x0044805E, 0x003F1C3E, 0x0029F4F9, 0x001CE683, 0x001214F0,
0x003DBC30, 0x0055A109, 0x004DAC61, 0x0045E778, 0x003B72D9, 0x00341911, 0x0023E2BB, 0x00124B5B,
0x00378F64, 0x004D1069, 0x004897C2, 0x003EE97F, 0x0045F6F0, 0x0036F889, 0x0025DD54, 0x001076E9,
0x0032C000, 0x0046646C, 0x003DBC30, 0x00378F64, 0x0040C000, 0x002EBFB5, 0x00203380, 0x000F734B,
0x002BFFB9, 0x00374E8E, 0x00341911, 0x003D7020, 0x0032DFAE, 0x0025CF86, 0x001A0B5F, 0x000CE5E2,
0x002125F5, 0x00348BD6, 0x00317F5B, 0x002C8BEB, 0x0023FD53, 0x001C46DC, 0x00189A60, 0x000C8AE2,
0x001635BC, 0x001ECE57, 0x002496B6, 0x001FCB22, 0x001B09C4, 0x001A2CE1, 0x001207A5, 0x000B0E77,
},
{
0x00220000, 0x002F28CC, 0x002C6C53, 0x002F79DA, 0x00220000, 0x001FB8F1, 0x00194D09, 0x000CE5F7,
0x0040D818, 0x0059F0FE, 0x00642089, 0x00532E29, 0x004CA24B, 0x0032F29C, 0x002317E8, 0x0015F4DB,
0x004AF6CC, 0x0067FA67, 0x005E5152, 0x0054E237, 0x00483007, 0x003F4303, 0x002B9351, 0x001636EE,
0x00437743, 0x005D93EE, 0x005825FE, 0x004C64AD, 0x0054F4FF, 0x0042C014, 0x002DFA79, 0x0013FE1A,
0x003DA000, 0x005579F1, 0x004AF6CC, 0x00437743, 0x004EA000, 0x0038C437, 0x002719F7, 0x0012C2DB,
0x00356D61, 0x00432888, 0x003F4303, 0x004A9A70, 0x003DC678, 0x002DE9B5, 0x001FA018, 0x000FA96E,
0x00284060, 0x003FCE60, 0x003C1AA5, 0x0036179D, 0x002BB39B, 0x0022560C, 0x001DE007, 0x000F3AEE,
0x001AF81B, 0x00256845, 0x002C6DDD, 0x00269B3C, 0x0020D500, 0x001FC8C8, 0x0015E4B7, 0x000D6CFE,
},
{
0x002C0000, 0x003D079E, 0x00397D20, 0x003D7083, 0x002C0000, 0x00290D75, 0x0020BE0C, 0x0010B121,
0x0053EA79, 0x0074650C, 0x00819383, 0x006BA525, 0x00632C61, 0x0041EEAC, 0x002D6A3B, 0x001C6A0C,
0x00610326, 0x00868F57, 0x007A0EE2, 0x006DD974, 0x005D6B54, 0x0051DE40, 0x0038644B, 0x001CBF8F,
0x00574F0B, 0x007919CA, 0x0072130C, 0x0062DCA3, 0x006DF1C2, 0x005661FB, 0x003B8060, 0x0019DF6D,
0x004FC000, 0x006E9DCE, 0x00610326, 0x00574F0B, 0x0065C000, 0x00497665, 0x00329A12, 0x00184776,
0x00452423, 0x0056E928, 0x0051DE40, 0x00608BA0, 0x004FF1C9, 0x003B6AAE, 0x0028ED4D, 0x001444AC,
0x00341713, 0x0052929A, 0x004DC821, 0x00460071, 0x00388E14, 0x002C6F5A, 0x0026A973, 0x0013B5AD,
0x0022E6BA, 0x003068D2, 0x00397F1E, 0x0031F611, 0x002A7D0F, 0x002921F4, 0x001C5528, 0x00115FDF,
}
};
static const uint32_t bink_inter_quant[16][64] = {
{
0x00010000, 0x00017946, 0x00016363, 0x000152A7, 0x00012000, 0x0000E248, 0x0000A486, 0x000053E0,
0x0001A5A9, 0x000248DC, 0x000243EC, 0x000209EA, 0x0001BBDA, 0x00015CBC, 0x0000F036, 0x00008095,
0x0001B701, 0x000260EB, 0x00023D97, 0x00020437, 0x0001B701, 0x00016959, 0x0000F8E7, 0x00007EE4,
0x00019DE9, 0x00023E1B, 0x00021CCC, 0x0001E6B4, 0x0001B0B9, 0x000153FD, 0x0000EA30, 0x00007763,
0x00017000, 0x0001FE6E, 0x0001E0D1, 0x0001B0B9, 0x00018000, 0x00012DB5, 0x0000CFD2, 0x00006E5C,
0x00012DB5, 0x0001A27B, 0x00018A33, 0x0001718D, 0x000146D9, 0x000100CE, 0x0000B0E4, 0x00005A2D,
0x0000D87A, 0x00014449, 0x00013178, 0x000112EA, 0x0000E9CC, 0x0000B7B1, 0x00008337, 0x000042E5,
0x00007B9A, 0x0000AB71, 0x0000AD08, 0x00009BB9, 0x0000846F, 0x00006B85, 0x00004A10, 0x00002831,
},
{
0x00015555, 0x0001F708, 0x0001D9D9, 0x0001C389, 0x00018000, 0x00012DB5, 0x0000DB5D, 0x00006FD5,
0x00023237, 0x00030BD0, 0x0003053B, 0x0002B7E3, 0x00024FCE, 0x0001D0FA, 0x00014048, 0x0000AB71,
0x00024957, 0x00032BE4, 0x0002FCC9, 0x0002B04A, 0x00024957, 0x0001E1CC, 0x00014BDE, 0x0000A92F,
0x000227E1, 0x0002FD7A, 0x0002D110, 0x000288F1, 0x000240F7, 0x0001C551, 0x00013840, 0x00009F2F,
0x0001EAAB, 0x0002A893, 0x00028116, 0x000240F7, 0x00020000, 0x00019247, 0x00011518, 0x00009325,
0x00019247, 0x00022DF9, 0x00020D99, 0x0001ECBC, 0x0001B3CC, 0x00015668, 0x0000EBDA, 0x0000783D,
0x000120A3, 0x0001B061, 0x0001974B, 0x00016E8E, 0x000137BB, 0x0000F4ED, 0x0000AEF4, 0x00005931,
0x0000A4CE, 0x0000E497, 0x0000E6B5, 0x0000CFA2, 0x0000B093, 0x00008F5C, 0x000062BF, 0x00003597,
},
{
0x0001AAAB, 0x000274CB, 0x0002504F, 0x0002346C, 0x0001E000, 0x00017922, 0x00011235, 0x00008BCA,
0x0002BEC4, 0x0003CEC4, 0x0003C689, 0x000365DC, 0x0002E3C1, 0x00024539, 0x0001905A, 0x0000D64D,
0x0002DBAD, 0x0003F6DD, 0x0003BBFB, 0x00035C5C, 0x0002DBAD, 0x00025A40, 0x00019ED6, 0x0000D37B,
0x0002B1D9, 0x0003BCD8, 0x00038554, 0x00032B2D, 0x0002D134, 0x000236A5, 0x00018650, 0x0000C6FB,
0x00026555, 0x000352B8, 0x0003215C, 0x0002D134, 0x00028000, 0x0001F6D8, 0x00015A5E, 0x0000B7EF,
0x0001F6D8, 0x0002B977, 0x00029100, 0x000267EB, 0x000220C0, 0x0001AC02, 0x000126D1, 0x0000964C,
0x000168CC, 0x00021C7A, 0x0001FD1E, 0x0001CA31, 0x000185A9, 0x00013228, 0x0000DAB2, 0x00006F7D,
0x0000CE01, 0x00011DBD, 0x00012062, 0x0001038A, 0x0000DCB8, 0x0000B333, 0x00007B6F, 0x000042FC,
},
{
0x00020000, 0x0002F28D, 0x0002C6C5, 0x0002A54E, 0x00024000, 0x0001C48F, 0x0001490C, 0x0000A7BF,
0x00034B52, 0x000491B8, 0x000487D8, 0x000413D5, 0x000377B5, 0x0002B977, 0x0001E06C, 0x0001012A,
0x00036E03, 0x0004C1D6, 0x00047B2D, 0x0004086E, 0x00036E03, 0x0002D2B3, 0x0001F1CE, 0x0000FDC7,
0x00033BD1, 0x00047C37, 0x00043998, 0x0003CD69, 0x00036172, 0x0002A7FA, 0x0001D460, 0x0000EEC7,
0x0002E000, 0x0003FCDD, 0x0003C1A1, 0x00036172, 0x00030000, 0x00025B6A, 0x00019FA3, 0x0000DCB8,
0x00025B6A, 0x000344F5, 0x00031466, 0x0002E31B, 0x00028DB3, 0x0002019B, 0x000161C7, 0x0000B45B,
0x0001B0F5, 0x00028892, 0x000262F1, 0x000225D5, 0x0001D398, 0x00016F63, 0x0001066F, 0x000085C9,
0x0000F735, 0x000156E2, 0x00015A10, 0x00013772, 0x000108DD, 0x0000D70A, 0x0000941F, 0x00005062,
},
{
0x0002AAAB, 0x0003EE11, 0x0003B3B2, 0x00038713, 0x00030000, 0x00025B6A, 0x0001B6BB, 0x0000DFAA,
0x0004646D, 0x000617A0, 0x00060A75, 0x00056FC6, 0x00049F9B, 0x0003A1F4, 0x00028090, 0x000156E2,
0x000492AE, 0x000657C8, 0x0005F991, 0x00056093, 0x000492AE, 0x0003C399, 0x000297BD, 0x0001525F,
0x00044FC1, 0x0005FAF4, 0x0005A220, 0x000511E1, 0x000481ED, 0x00038AA2, 0x00027080, 0x00013E5E,
0x0003D555, 0x00055126, 0x0005022D, 0x000481ED, 0x00040000, 0x0003248D, 0x00022A2F, 0x0001264B,
0x0003248D, 0x00045BF2, 0x00041B33, 0x0003D979, 0x00036799, 0x0002ACCF, 0x0001D7B5, 0x0000F079,
0x00024147, 0x000360C3, 0x00032E96, 0x0002DD1C, 0x00026F75, 0x0001E9D9, 0x00015DE9, 0x0000B262,
0x0001499C, 0x0001C92E, 0x0001CD6A, 0x00019F43, 0x00016127, 0x00011EB8, 0x0000C57F, 0x00006B2D,
},
{
0x00038000, 0x00052876, 0x0004DBD9, 0x0004A148, 0x0003F000, 0x000317FB, 0x00023FD5, 0x0001258F,
0x0005C3CF, 0x0007FF02, 0x0007EDBA, 0x000722B4, 0x0006117C, 0x0004C491, 0x000348BD, 0x0001C209,
0x00060085, 0x00085336, 0x0007D78F, 0x00070EC1, 0x00060085, 0x0004F0B9, 0x00036728, 0x0001BC1C,
0x0005A8AE, 0x0007D960, 0x000764CA, 0x0006A777, 0x0005EA87, 0x0004A5F5, 0x000333A8, 0x0001A1DB,
0x00050800, 0x0006FA82, 0x000692DA, 0x0005EA87, 0x00054000, 0x00041FF9, 0x0002D75E, 0x00018242,
0x00041FF9, 0x0005B8AE, 0x000563B2, 0x00050D6E, 0x000477F9, 0x000382D0, 0x00026B1D, 0x00013B9F,
0x0002F5AD, 0x00046F00, 0x00042D25, 0x0003C235, 0x0003324A, 0x000282ED, 0x0001CB42, 0x0000EA21,
0x0001B09C, 0x0002580C, 0x00025D9B, 0x00022108, 0x0001CF83, 0x00017851, 0x00010336, 0x00008CAC,
},
{
0x00040000, 0x0005E519, 0x00058D8A, 0x00054A9C, 0x00048000, 0x0003891F, 0x00029218, 0x00014F7E,
0x000696A4, 0x00092370, 0x00090FB0, 0x000827AA, 0x0006EF69, 0x000572EE, 0x0003C0D8, 0x00020254,
0x0006DC05, 0x000983AC, 0x0008F65A, 0x000810DD, 0x0006DC05, 0x0005A565, 0x0003E39B, 0x0001FB8E,
0x000677A2, 0x0008F86E, 0x00087330, 0x00079AD1, 0x0006C2E4, 0x00054FF3, 0x0003A8C0, 0x0001DD8D,
0x0005C000, 0x0007F9B9, 0x00078343, 0x0006C2E4, 0x00060000, 0x0004B6D4, 0x00033F47, 0x0001B970,
0x0004B6D4, 0x000689EB, 0x000628CC, 0x0005C635, 0x00051B65, 0x00040337, 0x0002C38F, 0x000168B6,
0x000361EA, 0x00051124, 0x0004C5E1, 0x00044BAA, 0x0003A730, 0x0002DEC6, 0x00020CDD, 0x00010B93,
0x0001EE69, 0x0002ADC5, 0x0002B41F, 0x00026EE5, 0x000211BA, 0x0001AE14, 0x0001283E, 0x0000A0C4,
},
{
0x00050000, 0x00075E60, 0x0006F0ED, 0x00069D43, 0x0005A000, 0x00046B67, 0x0003369E, 0x0001A35E,
0x00083C4D, 0x000B6C4C, 0x000B539C, 0x000A3194, 0x0008AB44, 0x0006CFAA, 0x0004B10F, 0x000282E8,
0x00089307, 0x000BE497, 0x000B33F1, 0x000A1514, 0x00089307, 0x00070EBF, 0x0004DC82, 0x00027A72,
0x0008158B, 0x000B3689, 0x000A8FFC, 0x00098186, 0x0008739C, 0x0006A3F0, 0x000492F0, 0x000254F0,
0x00073000, 0x0009F827, 0x00096413, 0x0008739C, 0x00078000, 0x0005E489, 0x00040F19, 0x000227CC,
0x0005E489, 0x00082C66, 0x0007B2FF, 0x000737C2, 0x0006623F, 0x00050405, 0x00037473, 0x0001C2E3,
0x00043A64, 0x0006556D, 0x0005F75A, 0x00055E94, 0x000490FC, 0x00039677, 0x00029015, 0x00014E78,
0x00026A04, 0x00035936, 0x00036127, 0x00030A9E, 0x00029629, 0x00021999, 0x0001724E, 0x0000C8F5,
},
{
0x00060000, 0x0008D7A6, 0x00085450, 0x0007EFEA, 0x0006C000, 0x00054DAE, 0x0003DB24, 0x0001F73E,
0x0009E1F6, 0x000DB528, 0x000D9788, 0x000C3B7E, 0x000A671E, 0x00082C66, 0x0005A145, 0x0003037D,
0x000A4A08, 0x000E4582, 0x000D7187, 0x000C194B, 0x000A4A08, 0x00087818, 0x0005D569, 0x0002F955,
0x0009B373, 0x000D74A5, 0x000CACC8, 0x000B683A, 0x000A2455, 0x0007F7ED, 0x00057D20, 0x0002CC54,
0x0008A000, 0x000BF696, 0x000B44E4, 0x000A2455, 0x00090000, 0x0007123E, 0x0004DEEA, 0x00029629,
0x0007123E, 0x0009CEE0, 0x00093D32, 0x0008A950, 0x0007A918, 0x000604D2, 0x00042556, 0x00021D11,
0x000512DF, 0x000799B6, 0x000728D2, 0x0006717F, 0x00057AC8, 0x00044E28, 0x0003134C, 0x0001915C,
0x0002E59E, 0x000404A7, 0x00040E2F, 0x0003A657, 0x00031A97, 0x0002851E, 0x0001BC5D, 0x0000F126,
},
{
0x00080000, 0x000BCA33, 0x000B1B15, 0x000A9538, 0x00090000, 0x0007123E, 0x00052430, 0x00029EFD,
0x000D2D48, 0x001246E0, 0x00121F5F, 0x00104F53, 0x000DDED2, 0x000AE5DD, 0x000781B1, 0x000404A7,
0x000DB80B, 0x00130757, 0x0011ECB4, 0x001021B9, 0x000DB80B, 0x000B4ACB, 0x0007C736, 0x0003F71D,
0x000CEF44, 0x0011F0DC, 0x0010E661, 0x000F35A3, 0x000D85C7, 0x000A9FE7, 0x00075180, 0x0003BB1A,
0x000B8000, 0x000FF372, 0x000F0686, 0x000D85C7, 0x000C0000, 0x00096DA8, 0x00067E8E, 0x000372E1,
0x00096DA8, 0x000D13D6, 0x000C5198, 0x000B8C6A, 0x000A36CB, 0x0008066E, 0x0005871E, 0x0002D16B,
0x0006C3D4, 0x000A2248, 0x00098BC3, 0x00089754, 0x00074E60, 0x0005BD8B, 0x000419BB, 0x00021726,
0x0003DCD3, 0x00055B8A, 0x0005683E, 0x0004DDC9, 0x00042374, 0x00035C28, 0x0002507C, 0x00014188,
},
{
0x000C0000, 0x0011AF4C, 0x0010A89F, 0x000FDFD4, 0x000D8000, 0x000A9B5D, 0x0007B649, 0x0003EE7B,
0x0013C3EC, 0x001B6A50, 0x001B2F0F, 0x001876FD, 0x0014CE3C, 0x001058CB, 0x000B4289, 0x000606FB,
0x00149410, 0x001C8B03, 0x001AE30E, 0x00183296, 0x00149410, 0x0010F030, 0x000BAAD2, 0x0005F2AB,
0x001366E6, 0x001AE949, 0x00195991, 0x0016D074, 0x001448AB, 0x000FEFDA, 0x000AFA40, 0x000598A7,
0x00114000, 0x0017ED2B, 0x001689C8, 0x001448AB, 0x00120000, 0x000E247C, 0x0009BDD5, 0x00052C51,
0x000E247C, 0x00139DC1, 0x00127A63, 0x0011529F, 0x000F5230, 0x000C09A5, 0x00084AAC, 0x00043A21,
0x000A25BE, 0x000F336D, 0x000E51A4, 0x000CE2FE, 0x000AF590, 0x00089C51, 0x00062698, 0x000322B9,
0x0005CB3C, 0x0008094E, 0x00081C5D, 0x00074CAE, 0x0006352E, 0x00050A3B, 0x000378BA, 0x0001E24D,
},
{
0x00110000, 0x00190DAC, 0x0017998C, 0x00167D16, 0x00132000, 0x000F06C3, 0x000AECE7, 0x000591D9,
0x001C0039, 0x0026D69C, 0x002682AB, 0x0022A891, 0x001D797F, 0x00172876, 0x000FF398, 0x000889E3,
0x001D2717, 0x00286F9A, 0x002616FF, 0x002247AA, 0x001D2717, 0x0017FEEF, 0x00108754, 0x00086D1D,
0x001B7C71, 0x00261FD3, 0x0023E98D, 0x002051FA, 0x001CBC47, 0x001693CA, 0x000F8D30, 0x0007ED98,
0x00187000, 0x0021E552, 0x001FEDDC, 0x001CBC47, 0x00198000, 0x00140904, 0x000DCCEE, 0x0007541E,
0x00140904, 0x001BCA27, 0x001A2D62, 0x00188A62, 0x0015B46F, 0x00110DAA, 0x000BBF1F, 0x0005FD04,
0x000E6022, 0x001588DA, 0x001448FE, 0x00124192, 0x000F868B, 0x000C32C8, 0x0008B6AD, 0x00047130,
0x00083540, 0x000B6284, 0x000B7D84, 0x000A574B, 0x0008CB57, 0x000723D4, 0x0004EB08, 0x0002AB42,
},
{
0x00160000, 0x00206C0C, 0x001E8A79, 0x001D1A59, 0x0018C000, 0x0013722A, 0x000E2385, 0x00073537,
0x00243C86, 0x003242E8, 0x0031D646, 0x002CDA25, 0x002624C3, 0x001DF820, 0x0014A4A7, 0x000B0CCC,
0x0025BA1D, 0x00345430, 0x00314AEF, 0x002C5CBE, 0x0025BA1D, 0x001F0DAE, 0x001563D6, 0x000AE78E,
0x002391FB, 0x0031565C, 0x002E798A, 0x0029D380, 0x00252FE4, 0x001D37BB, 0x00142021, 0x000A4288,
0x001FA000, 0x002BDD7A, 0x002951EF, 0x00252FE4, 0x00210000, 0x0019ED8D, 0x0011DC06, 0x00097BEA,
0x0019ED8D, 0x0023F68C, 0x0021E061, 0x001FC224, 0x001C16AE, 0x001611AE, 0x000F3391, 0x0007BFE7,
0x00129A87, 0x001BDE47, 0x001A4058, 0x0017A026, 0x00141787, 0x000FC93E, 0x000B46C1, 0x0005BFA8,
0x000A9F44, 0x000EBBBA, 0x000EDEAB, 0x000D61E9, 0x000B617F, 0x00093D6D, 0x00065D55, 0x00037437,
},
{
0x001C0000, 0x002943B2, 0x0026DEC9, 0x00250A43, 0x001F8000, 0x0018BFD8, 0x0011FEA9, 0x00092C75,
0x002E1E7C, 0x003FF810, 0x003F6DCE, 0x003915A3, 0x00308BE1, 0x00262485, 0x001A45EB, 0x000E1049,
0x00300425, 0x004299B2, 0x003EBC76, 0x00387608, 0x00300425, 0x002785C6, 0x001B393F, 0x000DE0E4,
0x002D456E, 0x003ECB00, 0x003B2652, 0x00353BBA, 0x002F5439, 0x00252FA8, 0x00199D41, 0x000D0EDC,
0x00284000, 0x0037D40F, 0x003496D3, 0x002F5439, 0x002A0000, 0x0020FFCB, 0x0016BAF1, 0x000C1213,
0x0020FFCB, 0x002DC56D, 0x002B1D93, 0x00286B74, 0x0023BFC6, 0x001C1681, 0x001358E8, 0x0009DCF8,
0x0017AD66, 0x002377FE, 0x0021692A, 0x001E11A5, 0x0019924F, 0x00141767, 0x000E5A0D, 0x00075104,
0x000D84E2, 0x0012C062, 0x0012ECDA, 0x00110840, 0x000E7C16, 0x000BC28A, 0x000819B2, 0x0004655D,
},
{
0x00220000, 0x00321B58, 0x002F3318, 0x002CFA2D, 0x00264000, 0x001E0D86, 0x0015D9CE, 0x000B23B2,
0x00380072, 0x004DAD38, 0x004D0556, 0x00455122, 0x003AF2FE, 0x002E50EB, 0x001FE730, 0x001113C7,
0x003A4E2D, 0x0050DF33, 0x004C2DFD, 0x00448F54, 0x003A4E2D, 0x002FFDDF, 0x00210EA8, 0x0010DA39,
0x0036F8E1, 0x004C3FA5, 0x0047D31B, 0x0040A3F5, 0x0039788E, 0x002D2795, 0x001F1A61, 0x000FDB2F,
0x0030E000, 0x0043CAA5, 0x003FDBB7, 0x0039788E, 0x00330000, 0x00281209, 0x001B99DB, 0x000EA83B,
0x00281209, 0x0037944D, 0x00345AC4, 0x003114C3, 0x002B68DF, 0x00221B53, 0x00177E3E, 0x000BFA09,
0x001CC044, 0x002B11B4, 0x002891FC, 0x00248324, 0x001F0D17, 0x0018658F, 0x00116D5A, 0x0008E260,
0x00106A80, 0x0016C509, 0x0016FB08, 0x0014AE97, 0x001196AE, 0x000E47A8, 0x0009D60F, 0x00055684,
},
{
0x002C0000, 0x0040D818, 0x003D14F2, 0x003A34B2, 0x00318000, 0x0026E454, 0x001C470A, 0x000E6A6E,
0x0048790C, 0x006485D0, 0x0063AC8D, 0x0059B44A, 0x004C4986, 0x003BF03F, 0x0029494D, 0x00161998,
0x004B743A, 0x0068A861, 0x006295DE, 0x0058B97B, 0x004B743A, 0x003E1B5C, 0x002AC7AC, 0x0015CF1D,
0x004723F6, 0x0062ACB8, 0x005CF313, 0x0053A701, 0x004A5FC7, 0x003A6F75, 0x00284041, 0x00148510,
0x003F4000, 0x0057BAF3, 0x0052A3DE, 0x004A5FC7, 0x00420000, 0x0033DB1A, 0x0023B80D, 0x0012F7D4,
0x0033DB1A, 0x0047ED19, 0x0043C0C2, 0x003F8448, 0x00382D5C, 0x002C235D, 0x001E6723, 0x000F7FCF,
0x0025350D, 0x0037BC8E, 0x003480B0, 0x002F404C, 0x00282F0E, 0x001F927D, 0x00168D83, 0x000B7F50,
0x00153E87, 0x001D7775, 0x001DBD56, 0x001AC3D2, 0x0016C2FF, 0x00127AD9, 0x000CBAAA, 0x0006E86E,
}
};
#endif /* AVCODEC_BINKDATA_H */

View File

@@ -0,0 +1,78 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
* Code derived from FFMPeg/libavutil/common.h
* @author Michael Niedermayer <michaelni@gmx.at>
*/
#ifndef AVUTIL_COMMON_H
#define AVUTIL_COMMON_H
#include "win32def.h"
#include "globals.h"
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define av_const
#define av_cold
#define av_flatten
#define attribute_deprecated
#define av_unused
#define av_uninit(x) x
#define av_always_inline inline
#define uint8_t unsigned char
#define uint16_t unsigned short
#define uint32_t unsigned int
#define uint64_t __int64
#define int8_t signed char
#define int16_t signed short
#define int32_t signed int
#define int64_t signed __int64
#define FFABS(a) ((a) >= 0 ? (a) : (-(a)))
#define FFMIN(a,b) ((a) > (b) ? (b) : (a))
#define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0)
#ifndef M_PI
#define M_PI 3.14159265358979323846 /* pi */
#endif
#ifndef M_SQRT1_2
#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
#endif
void *av_malloc(unsigned int size);
void av_freep(void **ptr);
/**
* data needed to decode 4-bit Huffman-coded value
*/
typedef struct Tree {
int vlc_num; ///< tree number (in bink_trees[])
uint8_t syms[16]; ///< leaf value to symbol mapping
} Tree;
#endif /* AVUTIL_COMMON_H */

View File

@@ -0,0 +1,97 @@
/*
* (I)DCT Transforms
* Copyright (c) 2009 Peter Ross (pross@xvid.org)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file libavcodec/dct.c
* (Inverse) Discrete Cosine Transforms
*/
#define _USE_MATH_DEFINES
#include <math.h>
#include "dsputil.h"
av_cold int ff_dct_init(DCTContext *s, int nbits, int inverse)
{
int n = 1 << nbits;
s->nbits = nbits;
s->inverse = inverse;
s->data = (struct FFTComplex *) av_malloc(sizeof(FFTComplex) * 2 * n);
if (!s->data)
return -1;
if (ff_fft_init(&s->fft, nbits+1, inverse) < 0)
return -1;
return 0;
}
static void ff_dct_calc_c(DCTContext *s, FFTSample *data)
{
int n = 1<<s->nbits;
int i;
#define ROTATE(i,n) (-M_PI*((n)-0.5f)*(i)/(n))
if (s->inverse) {
for(i=0; i < n; i++) {
s->data[i].re = (float) (2 * data[i] * cos(ROTATE(i,n)));
s->data[i].im = (float) (2 * data[i] * sin(ROTATE(i,n)));
}
s->data[n].re = 0;
s->data[n].im = 0;
for(i=0; i<n-1; i++) {
s->data[n+i+1].re = (float) (-2 * data[n - (i+1)] * cos(ROTATE(n+i+1,n)));
s->data[n+i+1].im = (float) (-2 * data[n - (i+1)] * sin(ROTATE(n+i+1,n)));
}
}else{
for(i=0; i < n; i++) {
s->data[i].re = data[n - (i+1)];
s->data[i].im = 0;
s->data[n+i].re = data[i];
s->data[n+i].im = 0;
}
}
ff_fft_permute(&s->fft, s->data);
ff_fft_calc(&s->fft, s->data);
if (s->inverse) {
for(i=0; i < n; i++)
data[i] = s->data[n-(i+1)].re / (2 * n);
}else {
for(i=0; i < n; i++)
data[i] = (float) (s->data[i].re / (2 * cos(ROTATE(i,n))));
}
#undef ROTATE
}
void ff_dct_calc(DCTContext *s, FFTSample *data)
{
ff_dct_calc_c(s, data);
}
av_cold void ff_dct_end(DCTContext *s)
{
ff_fft_end(&s->fft);
av_freep((void **) &s->data);
}

View File

@@ -0,0 +1,233 @@
/*
* DSP utils
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file libavcodec/dsputil.h
* DSP utils.
* note, many functions in here may use MMX which trashes the FPU state, it is
* absolutely necessary to call emms_c() between dsp & float/double code
*/
#ifndef AVCODEC_DSPUTIL_H
#define AVCODEC_DSPUTIL_H
#include "common.h"
/* dct code */
typedef short DCTELEM;
typedef int DWTELEM;
typedef short IDWTELEM;
/* pixel operations */
#define MAX_NEG_CROP 1024
/**
* Scantable.
*/
typedef struct ScanTable{
const uint8_t *scantable;
uint8_t permutated[64];
uint8_t raster_end[64];
} ScanTable;
void ff_init_scantable(uint8_t *, ScanTable *st, const uint8_t *src_scantable);
/**
* Empty mmx state.
* this must be called between any dsp function and float/double code.
* for example sin(); dsp->idct_put(); emms_c(); cos()
*/
#define emms_c()
/* should be defined by architectures supporting
one or more MultiMedia extension */
int mm_support(void);
extern int mm_flags;
#define DECLARE_ALIGNED_16(t, v) DECLARE_ALIGNED(16, t, v)
#define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(8, t, v)
#define mm_flags 0
#define mm_support() 0
#ifndef STRIDE_ALIGN
# define STRIDE_ALIGN 8
#endif
/* FFT computation */
/* NOTE: soon integer code will be added, so you must use the
FFTSample type */
typedef float FFTSample;
struct MDCTContext;
typedef struct FFTComplex {
FFTSample re, im;
} FFTComplex;
typedef struct FFTContext {
int nbits;
int inverse;
uint16_t *revtab;
FFTComplex *exptab;
FFTComplex *exptab1; /* only used by SSE code */
FFTComplex *tmp_buf;
void (*fft_permute)(struct FFTContext *s, FFTComplex *z);
void (*fft_calc)(struct FFTContext *s, FFTComplex *z);
int split_radix;
int permutation;
#define FF_MDCT_PERM_NONE 0
#define FF_MDCT_PERM_INTERLEAVE 1
} FFTContext;
extern FFTSample* const ff_cos_tabs[17];
#define COSTABLE_CONST
#define SINTABLE_CONST
#define COSTABLE(size) COSTABLE_CONST FFTSample ff_cos_##size[size/2]
#define SINTABLE(size) SINTABLE_CONST FFTSample ff_sin_##size[size/2]
extern COSTABLE(16);
extern COSTABLE(32);
extern COSTABLE(64);
extern COSTABLE(128);
extern COSTABLE(256);
extern COSTABLE(512);
extern COSTABLE(1024);
extern COSTABLE(2048);
extern COSTABLE(4096);
extern COSTABLE(8192);
extern COSTABLE(16384);
extern COSTABLE(32768);
extern COSTABLE(65536);
/**
* Initializes the cosine table in ff_cos_tabs[index]
* \param index index in ff_cos_tabs array of the table to initialize
*/
void ff_init_ff_cos_tabs(int index);
extern SINTABLE(16);
extern SINTABLE(32);
extern SINTABLE(64);
extern SINTABLE(128);
extern SINTABLE(256);
extern SINTABLE(512);
extern SINTABLE(1024);
extern SINTABLE(2048);
extern SINTABLE(4096);
extern SINTABLE(8192);
extern SINTABLE(16384);
extern SINTABLE(32768);
extern SINTABLE(65536);
/**
* Sets up a complex FFT.
* @param nbits log2 of the length of the input array
* @param inverse if 0 perform the forward transform, if 1 perform the inverse
*/
int ff_fft_init(FFTContext *s, int nbits, int inverse);
void ff_fft_permute_c(FFTContext *s, FFTComplex *z);
void ff_fft_calc_c(FFTContext *s, FFTComplex *z);
/**
* Do the permutation needed BEFORE calling ff_fft_calc().
*/
static inline void ff_fft_permute(FFTContext *s, FFTComplex *z)
{
s->fft_permute(s, z);
}
/**
* Do a complex FFT with the parameters defined in ff_fft_init(). The
* input data must be permuted before. No 1.0/sqrt(n) normalization is done.
*/
static inline void ff_fft_calc(FFTContext *s, FFTComplex *z)
{
s->fft_calc(s, z);
}
void ff_fft_end(FFTContext *s);
/**
* Generate a sine window.
* @param window pointer to half window
* @param n size of half window
*/
void ff_sine_window_init(float *window, int n);
extern float ff_sine_128 [ 128];
extern float ff_sine_256 [ 256];
extern float ff_sine_512 [ 512];
extern float ff_sine_1024[1024];
extern float ff_sine_2048[2048];
extern float ff_sine_4096[4096];
extern float * const ff_sine_windows[6];
/* Real Discrete Fourier Transform */
enum RDFTransformType {
RDFT,
IRDFT,
RIDFT,
IRIDFT
};
typedef struct {
int nbits;
int inverse;
int sign_convention;
/* pre/post rotation tables */
FFTSample *tcos;
FFTSample *tsin;
FFTContext fft;
} RDFTContext;
/**
* Sets up a real FFT.
* @param nbits log2 of the length of the input array
* @param trans the type of transform
*/
int ff_rdft_init(RDFTContext *s, int nbits, enum RDFTransformType trans);
void ff_rdft_calc(RDFTContext *s, FFTSample *data);
void ff_rdft_end(RDFTContext *s);
/* Discrete Cosine Transform */
typedef struct {
int nbits;
int inverse;
FFTComplex *data;
FFTContext fft;
} DCTContext;
/**
* Sets up (Inverse)DCT.
* @param nbits log2 of the length of the input array
* @param inverse >0 forward transform, <0 inverse transform
*/
int ff_dct_init(DCTContext *s, int nbits, int inverse);
void ff_dct_calc(DCTContext *s, FFTSample *data);
void ff_dct_end(DCTContext *s);
#endif /* AVCODEC_DSPUTIL_H */

View File

@@ -0,0 +1,358 @@
/*
* FFT/IFFT transforms
* Copyright (c) 2008 Loren Merritt
* Copyright (c) 2002 Fabrice Bellard
* Partly based on libdjbfft by D. J. Bernstein
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file libavcodec/fft.c
* FFT/IFFT transforms.
*/
#include <math.h>
#include "dsputil.h"
/* cos(2*pi*x/n) for 0<=x<=n/4, followed by its reverse */
COSTABLE(16);
COSTABLE(32);
COSTABLE(64);
COSTABLE(128);
COSTABLE(256);
COSTABLE(512);
COSTABLE(1024);
COSTABLE(2048);
COSTABLE(4096);
COSTABLE(8192);
COSTABLE(16384);
COSTABLE(32768);
COSTABLE(65536);
COSTABLE_CONST FFTSample * const ff_cos_tabs[] = {
NULL, NULL, NULL, NULL,
ff_cos_16, ff_cos_32, ff_cos_64, ff_cos_128, ff_cos_256, ff_cos_512, ff_cos_1024,
ff_cos_2048, ff_cos_4096, ff_cos_8192, ff_cos_16384, ff_cos_32768, ff_cos_65536,
};
static int split_radix_permutation(int i, int n, int inverse)
{
int m;
if(n <= 2) return i&1;
m = n >> 1;
if(!(i&m)) return split_radix_permutation(i, m, inverse)*2;
m >>= 1;
if(inverse == !(i&m)) return split_radix_permutation(i, m, inverse)*4 + 1;
else return split_radix_permutation(i, m, inverse)*4 - 1;
}
av_cold void ff_init_ff_cos_tabs(int index)
{
int i;
int m = 1<<index;
double freq = 2*M_PI/m;
FFTSample *tab = ff_cos_tabs[index];
for(i=0; i<=m/4; i++)
tab[i] = (float) cos(i*freq);
for(i=1; i<m/4; i++)
tab[m/2-i] = tab[i];
}
av_cold int ff_fft_init(FFTContext *s, int nbits, int inverse)
{
int i, j, m, n;
float alpha, c1, s1, s2;
//int av_unused has_vectors;
if (nbits < 2 || nbits > 16)
goto fail;
s->nbits = nbits;
n = 1 << nbits;
s->tmp_buf = NULL;
s->exptab = (struct FFTComplex *) av_malloc((n / 2) * sizeof(FFTComplex));
if (!s->exptab)
goto fail;
s->revtab = (unsigned short *) av_malloc(n * sizeof(uint16_t));
if (!s->revtab)
goto fail;
s->inverse = inverse;
s2 = (float) (inverse ? 1.0 : -1.0);
s->fft_permute = ff_fft_permute_c;
s->fft_calc = ff_fft_calc_c;
s->exptab1 = NULL;
s->split_radix = 1;
if (s->split_radix) {
for(j=4; j<=nbits; j++) {
ff_init_ff_cos_tabs(j);
}
for(i=0; i<n; i++)
s->revtab[-split_radix_permutation(i, n, s->inverse) & (n-1)] = i;
s->tmp_buf = (struct FFTComplex *) av_malloc(n * sizeof(FFTComplex));
if(!s->tmp_buf) {
goto fail;
}
} else {
int np, nblocks, np2, l;
FFTComplex *q;
for(i=0; i<(n/2); i++) {
alpha = (float) (2 * M_PI * (float)i / (float)n);
c1 = (float) cos(alpha);
s1 = (float) (sin(alpha) * s2);
s->exptab[i].re = c1;
s->exptab[i].im = s1;
}
np = 1 << nbits;
nblocks = np >> 3;
np2 = np >> 1;
s->exptab1 = (struct FFTComplex *) av_malloc(np * 2 * sizeof(FFTComplex));
if (!s->exptab1)
goto fail;
q = s->exptab1;
do {
for(l = 0; l < np2; l += 2 * nblocks) {
*q++ = s->exptab[l];
*q++ = s->exptab[l + nblocks];
q->re = -s->exptab[l].im;
q->im = s->exptab[l].re;
q++;
q->re = -s->exptab[l + nblocks].im;
q->im = s->exptab[l + nblocks].re;
q++;
}
nblocks = nblocks >> 1;
} while (nblocks != 0);
av_freep((void **) &s->exptab);
/* compute bit reverse table */
for(i=0;i<n;i++) {
m=0;
for(j=0;j<nbits;j++) {
m |= ((i >> j) & 1) << (nbits-j-1);
}
s->revtab[i]=m;
}
}
return 0;
fail:
av_freep((void **) &s->revtab);
av_freep((void **) &s->exptab);
av_freep((void **) &s->exptab1);
av_freep((void **) &s->tmp_buf);
return -1;
}
void ff_fft_permute_c(FFTContext *s, FFTComplex *z)
{
int j, k, np;
FFTComplex tmp;
const uint16_t *revtab = s->revtab;
np = 1 << s->nbits;
if (s->tmp_buf) {
/* TODO: handle split-radix permute in a more optimal way, probably in-place */
for(j=0;j<np;j++) s->tmp_buf[revtab[j]] = z[j];
memcpy(z, s->tmp_buf, np * sizeof(FFTComplex));
return;
}
/* reverse */
for(j=0;j<np;j++) {
k = revtab[j];
if (k < j) {
tmp = z[k];
z[k] = z[j];
z[j] = tmp;
}
}
}
av_cold void ff_fft_end(FFTContext *s)
{
av_freep((void **) &s->revtab);
av_freep((void **) &s->exptab);
av_freep((void **) &s->exptab1);
av_freep((void **) &s->tmp_buf);
}
#define sqrthalf (float)M_SQRT1_2
#define BF(x,y,a,b) {\
x = a - b;\
y = a + b;\
}
#define BUTTERFLIES(a0,a1,a2,a3) {\
BF(t3, t5, t5, t1);\
BF(a2.re, a0.re, a0.re, t5);\
BF(a3.im, a1.im, a1.im, t3);\
BF(t4, t6, t2, t6);\
BF(a3.re, a1.re, a1.re, t4);\
BF(a2.im, a0.im, a0.im, t6);\
}
// force loading all the inputs before storing any.
// this is slightly slower for small data, but avoids store->load aliasing
// for addresses separated by large powers of 2.
#define BUTTERFLIES_BIG(a0,a1,a2,a3) {\
FFTSample r0=a0.re, i0=a0.im, r1=a1.re, i1=a1.im;\
BF(t3, t5, t5, t1);\
BF(a2.re, a0.re, r0, t5);\
BF(a3.im, a1.im, i1, t3);\
BF(t4, t6, t2, t6);\
BF(a3.re, a1.re, r1, t4);\
BF(a2.im, a0.im, i0, t6);\
}
#define TRANSFORM(a0,a1,a2,a3,wre,wim) {\
t1 = a2.re * wre + a2.im * wim;\
t2 = a2.im * wre - a2.re * wim;\
t5 = a3.re * wre - a3.im * wim;\
t6 = a3.im * wre + a3.re * wim;\
BUTTERFLIES(a0,a1,a2,a3)\
}
#define TRANSFORM_ZERO(a0,a1,a2,a3) {\
t1 = a2.re;\
t2 = a2.im;\
t5 = a3.re;\
t6 = a3.im;\
BUTTERFLIES(a0,a1,a2,a3)\
}
/* z[0...8n-1], w[1...2n-1] */
#define PASS(name)\
static void name(FFTComplex *z, const FFTSample *wre, unsigned int n)\
{\
FFTSample t1, t2, t3, t4, t5, t6;\
int o1 = 2*n;\
int o2 = 4*n;\
int o3 = 6*n;\
const FFTSample *wim = wre+o1;\
n--;\
\
TRANSFORM_ZERO(z[0],z[o1],z[o2],z[o3]);\
TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\
do {\
z += 2;\
wre += 2;\
wim -= 2;\
TRANSFORM(z[0],z[o1],z[o2],z[o3],wre[0],wim[0]);\
TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\
} while(--n);\
}
PASS(pass)
#undef BUTTERFLIES
#define BUTTERFLIES BUTTERFLIES_BIG
PASS(pass_big)
#define DECL_FFT(n,n2,n4)\
static void fft##n(FFTComplex *z)\
{\
fft##n2(z);\
fft##n4(z+n4*2);\
fft##n4(z+n4*3);\
pass(z,ff_cos_##n,n4/2);\
}
static void fft4(FFTComplex *z)
{
FFTSample t1, t2, t3, t4, t5, t6, t7, t8;
BF(t3, t1, z[0].re, z[1].re);
BF(t8, t6, z[3].re, z[2].re);
BF(z[2].re, z[0].re, t1, t6);
BF(t4, t2, z[0].im, z[1].im);
BF(t7, t5, z[2].im, z[3].im);
BF(z[3].im, z[1].im, t4, t8);
BF(z[3].re, z[1].re, t3, t7);
BF(z[2].im, z[0].im, t2, t5);
}
static void fft8(FFTComplex *z)
{
FFTSample t1, t2, t3, t4, t5, t6, t7, t8;
fft4(z);
BF(t1, z[5].re, z[4].re, -z[5].re);
BF(t2, z[5].im, z[4].im, -z[5].im);
BF(t3, z[7].re, z[6].re, -z[7].re);
BF(t4, z[7].im, z[6].im, -z[7].im);
BF(t8, t1, t3, t1);
BF(t7, t2, t2, t4);
BF(z[4].re, z[0].re, z[0].re, t1);
BF(z[4].im, z[0].im, z[0].im, t2);
BF(z[6].re, z[2].re, z[2].re, t7);
BF(z[6].im, z[2].im, z[2].im, t8);
TRANSFORM(z[1],z[3],z[5],z[7],sqrthalf,sqrthalf);
}
#if !CONFIG_SMALL
static void fft16(FFTComplex *z)
{
FFTSample t1, t2, t3, t4, t5, t6;
fft8(z);
fft4(z+8);
fft4(z+12);
TRANSFORM_ZERO(z[0],z[4],z[8],z[12]);
TRANSFORM(z[2],z[6],z[10],z[14],sqrthalf,sqrthalf);
TRANSFORM(z[1],z[5],z[9],z[13],ff_cos_16[1],ff_cos_16[3]);
TRANSFORM(z[3],z[7],z[11],z[15],ff_cos_16[3],ff_cos_16[1]);
}
#else
DECL_FFT(16,8,4)
#endif
DECL_FFT(32,16,8)
DECL_FFT(64,32,16)
DECL_FFT(128,64,32)
DECL_FFT(256,128,64)
DECL_FFT(512,256,128)
#if !CONFIG_SMALL
#define pass pass_big
#endif
DECL_FFT(1024,512,256)
DECL_FFT(2048,1024,512)
DECL_FFT(4096,2048,1024)
DECL_FFT(8192,4096,2048)
DECL_FFT(16384,8192,4096)
DECL_FFT(32768,16384,8192)
DECL_FFT(65536,32768,16384)
static void (* const fft_dispatch[])(FFTComplex*) = {
fft4, fft8, fft16, fft32, fft64, fft128, fft256, fft512, fft1024,
fft2048, fft4096, fft8192, fft16384, fft32768, fft65536,
};
void ff_fft_calc_c(FFTContext *s, FFTComplex *z)
{
fft_dispatch[s->nbits-2](z);
}

View File

@@ -0,0 +1,68 @@
/*
* default memory allocator for libavutil
* Copyright (c) 2002 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file libavutil/mem.c
* default memory allocator for libavutil
*/
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#if HAVE_MALLOC_H
#include <malloc.h>
#endif
#include "common.h"
/* You can redefine av_malloc and av_free in your project to use your
memory allocator. You do not need to suppress this file because the
linker will do it automatically. */
void *av_malloc(unsigned int size)
{
void *ptr = NULL;
long diff;
/* let's disallow possible ambiguous cases */
if(size > (INT_MAX-16) )
return NULL;
ptr = malloc(size+16);
if(!ptr)
return ptr;
diff= ((-(long)ptr - 1)&15) + 1;
ptr = (char*)ptr + diff;
((char*)ptr)[-1]= diff;
return ptr;
}
void av_free(void *ptr)
{
/* XXX: this test should not be needed on most libcs */
if (ptr)
free((char*)ptr - ((char*)ptr)[-1]);
}
void av_freep(void **arg)
{
av_free(*arg);
*arg = NULL;
}

View File

@@ -0,0 +1,83 @@
/*
* rational numbers
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file libavutil/rational.c
* rational numbers
* @author Michael Niedermayer <michaelni@gmx.at>
*/
#include <assert.h>
#include <limits.h>
#include "common.h"
#include "rational.h"
int64_t av_gcd(int64_t a, int64_t b){
if(b) return av_gcd(b, a%b);
return a;
}
int av_reduce(int &dst_num, int &dst_den, int64_t num, int64_t den, int64_t max) {
AVRational a0={0,1}, a1={1,0};
int sign= (num<0) ^ (den<0);
int64_t gcd= av_gcd(FFABS(num), FFABS(den));
if(gcd){
num = FFABS(num)/gcd;
den = FFABS(den)/gcd;
}
if(num<=max && den<=max){
a1.num = num;
a1.den = den;
den=0;
}
while(den){
uint64_t x = num / den;
int64_t next_den= num - den*x;
int64_t a2n= x*a1.num + a0.num;
int64_t a2d= x*a1.den + a0.den;
if(a2n > max || a2d > max){
if(a1.num) x= (max - a0.num) / a1.num;
if(a1.den) x= FFMIN(x, (max - a0.den) / a1.den);
if (den*(2*x*a1.den + a0.den) > num*a1.den) {
a1.den =x*a1.den + a0.den;
a1.num =x*a1.num + a0.num;
}
break;
}
a0 = a1;
a1.den = a2d;
a1.num = a2n;
num = den;
den = next_den;
}
assert(av_gcd(a1.num, a1.den) <= 1U);
dst_num = sign ? -a1.num : a1.num;
dst_den = a1.den;
return den==0;
}

View File

@@ -0,0 +1,126 @@
/*
* rational numbers
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file libavutil/rational.h
* rational numbers
* @author Michael Niedermayer <michaelni@gmx.at>
*/
#ifndef AVUTIL_RATIONAL_H
#define AVUTIL_RATIONAL_H
/**
* rational number numerator/denominator
*/
typedef struct AVRational{
int num; ///< numerator
int den; ///< denominator
} AVRational;
/**
* Compares two rationals.
* @param a first rational
* @param b second rational
* @return 0 if a==b, 1 if a>b and -1 if a<b
*/
static inline int av_cmp_q(AVRational a, AVRational b){
const int64_t tmp= a.num * (int64_t)b.den - b.num * (int64_t)a.den;
if(tmp) return (int) ((tmp>>63)|1);
else return 0;
}
/**
* Converts rational to double.
* @param a rational to convert
* @return (double) a
*/
static inline double av_q2d(AVRational a){
return a.num / (double) a.den;
}
/**
* Reduces a fraction.
* This is useful for framerate calculations.
* @param dst_num destination numerator
* @param dst_den destination denominator
* @param num source numerator
* @param den source denominator
* @param max the maximum allowed for dst_num & dst_den
* @return 1 if exact, 0 otherwise
*/
int av_reduce(int &dst_num, int &dst_den, int64_t num, int64_t den, int64_t max);
/**
* Multiplies two rationals.
* @param b first rational
* @param c second rational
* @return b*c
*/
AVRational av_mul_q(AVRational b, AVRational c) av_const;
/**
* Divides one rational by another.
* @param b first rational
* @param c second rational
* @return b/c
*/
AVRational av_div_q(AVRational b, AVRational c) av_const;
/**
* Adds two rationals.
* @param b first rational
* @param c second rational
* @return b+c
*/
AVRational av_add_q(AVRational b, AVRational c) av_const;
/**
* Subtracts one rational from another.
* @param b first rational
* @param c second rational
* @return b-c
*/
AVRational av_sub_q(AVRational b, AVRational c) av_const;
/**
* Converts a double precision floating point number to a rational.
* @param d double to convert
* @param max the maximum allowed numerator and denominator
* @return (AVRational) d
*/
AVRational av_d2q(double d, int max) av_const;
/**
* @return 1 if q1 is nearer to q than q2, -1 if q2 is nearer
* than q1, 0 if they have the same distance.
*/
int av_nearer_q(AVRational q, AVRational q1, AVRational q2);
/**
* Finds the nearest value in q_list to q.
* @param q_list an array of rationals terminated by {0, 0}
* @return the index of the nearest value found in the array
*/
int av_find_nearest_q_idx(AVRational q, const AVRational* q_list);
#endif /* AVUTIL_RATIONAL_H */

View File

@@ -0,0 +1,130 @@
/*
* (I)RDFT transforms
* Copyright (c) 2009 Alex Converse <alex dot converse at gmail dot com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <math.h>
#include "dsputil.h"
/**
* @file libavcodec/rdft.c
* (Inverse) Real Discrete Fourier Transforms.
*/
/* sin(2*pi*x/n) for 0<=x<n/4, followed by n/2<=x<3n/4 */
SINTABLE(16);
SINTABLE(32);
SINTABLE(64);
SINTABLE(128);
SINTABLE(256);
SINTABLE(512);
SINTABLE(1024);
SINTABLE(2048);
SINTABLE(4096);
SINTABLE(8192);
SINTABLE(16384);
SINTABLE(32768);
SINTABLE(65536);
SINTABLE_CONST FFTSample * const ff_sin_tabs[] = {
NULL, NULL, NULL, NULL,
ff_sin_16, ff_sin_32, ff_sin_64, ff_sin_128, ff_sin_256, ff_sin_512, ff_sin_1024,
ff_sin_2048, ff_sin_4096, ff_sin_8192, ff_sin_16384, ff_sin_32768, ff_sin_65536,
};
av_cold int ff_rdft_init(RDFTContext *s, int nbits, enum RDFTransformType trans)
{
int n = 1 << nbits;
int i;
const double theta = (trans == RDFT || trans == IRIDFT ? -1 : 1)*2*M_PI/n;
s->nbits = nbits;
s->inverse = trans == IRDFT || trans == IRIDFT;
s->sign_convention = trans == RIDFT || trans == IRIDFT ? 1 : -1;
if (nbits < 4 || nbits > 16)
return -1;
if (ff_fft_init(&s->fft, nbits-1, trans == IRDFT || trans == RIDFT) < 0)
return -1;
ff_init_ff_cos_tabs(nbits);
s->tcos = ff_cos_tabs[nbits];
s->tsin = ff_sin_tabs[nbits]+(trans == RDFT || trans == IRIDFT)*(n>>2);
for (i = 0; i < (n>>2); i++) {
s->tsin[i] = (float) sin(i*theta);
}
return 0;
}
/** Map one real FFT into two parallel real even and odd FFTs. Then interleave
* the two real FFTs into one complex FFT. Unmangle the results.
* ref: http://www.engineeringproductivitytools.com/stuff/T0001/PT10.HTM
*/
void ff_rdft_calc_c(RDFTContext* s, FFTSample* data)
{
int i, i1, i2;
FFTComplex ev, od;
const int n = 1 << s->nbits;
const float k1 = 0.5;
const float k2 = (float) (0.5 - s->inverse);
const FFTSample *tcos = s->tcos;
const FFTSample *tsin = s->tsin;
if (!s->inverse) {
ff_fft_permute(&s->fft, (FFTComplex*)data);
ff_fft_calc(&s->fft, (FFTComplex*)data);
}
/* i=0 is a special case because of packing, the DC term is real, so we
are going to throw the N/2 term (also real) in with it. */
ev.re = data[0];
data[0] = ev.re+data[1];
data[1] = ev.re-data[1];
for (i = 1; i < (n>>2); i++) {
i1 = 2*i;
i2 = n-i1;
/* Separate even and odd FFTs */
ev.re = k1*(data[i1 ]+data[i2 ]);
od.im = -k2*(data[i1 ]-data[i2 ]);
ev.im = k1*(data[i1+1]-data[i2+1]);
od.re = k2*(data[i1+1]+data[i2+1]);
/* Apply twiddle factors to the odd FFT and add to the even FFT */
data[i1 ] = ev.re + od.re*tcos[i] - od.im*tsin[i];
data[i1+1] = ev.im + od.im*tcos[i] + od.re*tsin[i];
data[i2 ] = ev.re - od.re*tcos[i] + od.im*tsin[i];
data[i2+1] = -ev.im + od.im*tcos[i] + od.re*tsin[i];
}
data[2*i+1]=s->sign_convention*data[2*i+1];
if (s->inverse) {
data[0] *= k1;
data[1] *= k1;
ff_fft_permute(&s->fft, (FFTComplex*)data);
ff_fft_calc(&s->fft, (FFTComplex*)data);
}
}
void ff_rdft_calc(RDFTContext *s, FFTSample *data)
{
ff_rdft_calc_c(s, data);
}
av_cold void ff_rdft_end(RDFTContext *s)
{
ff_fft_end(&s->fft);
}

View File

@@ -0,0 +1,295 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#include "BMPImporter.h"
#include "RGBAColor.h"
#include "win32def.h"
#include "Interface.h"
#include "Video.h"
#define BMP_HEADER_SIZE 54
static ieDword red_mask = 0x00ff0000;
static ieDword green_mask = 0x0000ff00;
static ieDword blue_mask = 0x000000ff;
BMPImporter::BMPImporter(void)
{
Palette = NULL;
pixels = NULL;
if (DataStream::IsEndianSwitch()) {
red_mask = 0x000000ff;
green_mask = 0x0000ff00;
blue_mask = 0x00ff0000;
}
}
BMPImporter::~BMPImporter(void)
{
free( Palette );
free( pixels );
}
bool BMPImporter::Open(DataStream* stream)
{
str = stream;
//we release the previous pixel data
free( pixels );
pixels = NULL;
free( Palette );
Palette = NULL;
//BITMAPFILEHEADER
char Signature[2];
ieDword FileSize, DataOffset;
str->Read( Signature, 2 );
if (strncmp( Signature, "BM", 2 ) != 0) {
printMessage( "BMPImporter","Not a valid BMP File.\n",LIGHT_RED);
return false;
}
str->ReadDword( &FileSize );
str->Seek( 4, GEM_CURRENT_POS );
str->ReadDword( &DataOffset );
//BITMAPINFOHEADER
str->ReadDword( &Size );
//some IE palettes are of a different format (OS/2 BMP)!
if (Size < 24) {
printMessage( "BMPImporter","OS/2 Bitmap, not supported.\n", LIGHT_RED);
return false;
}
str->ReadDword( &Width );
str->ReadDword( &Height );
str->ReadWord( &Planes );
str->ReadWord( &BitCount );
str->ReadDword( &Compression );
str->ReadDword( &ImageSize );
//24 = the already read bytes 3x4+2x2+2x4
//this is normally 16
str->Seek( Size-24, GEM_CURRENT_POS );
//str->ReadDword(&Hres );
//str->ReadDword(&Vres );
//str->ReadDword(&ColorsUsed );
//str->ReadDword(&ColorsImportant );
if (Compression != 0) {
printMessage( "BMPImporter"," ", LIGHT_RED);
printf( "Compressed %d-bits Image, not supported.\n", BitCount );
return false;
}
//COLORTABLE
Palette = NULL;
if (BitCount <= 8) {
if (BitCount == 8)
NumColors = 256;
else
NumColors = 16;
Palette = ( Color * ) malloc( 4 * NumColors );
for (unsigned int i = 0; i < NumColors; i++) {
str->Read( &Palette[i].b, 1 );
str->Read( &Palette[i].g, 1 );
str->Read( &Palette[i].r, 1 );
str->Read( &Palette[i].a, 1 );
}
}
str->Seek( DataOffset, GEM_STREAM_START );
//no idea if we have to swap this or not
//RASTERDATA
switch (BitCount) {
case 32:
PaddedRowLength = Width * 4;
break;
case 24:
PaddedRowLength = Width * 3;
break;
case 16:
PaddedRowLength = Width * 2;
break;
case 8:
PaddedRowLength = Width;
break;
case 4:
PaddedRowLength = ( Width >> 1 );
break;
default:
printMessage( "BMPImporter"," ", LIGHT_RED);
printf( "BitCount %d is not supported.\n", BitCount );
return false;
}
//if(BitCount!=4)
//{
if (PaddedRowLength & 3) {
PaddedRowLength += 4 - ( PaddedRowLength & 3 );
}
//}
void* rpixels = malloc( PaddedRowLength* Height );
str->Read( rpixels, PaddedRowLength * Height );
if (BitCount == 32) {
//convert to 24 bits on the fly
int size = Width * Height * 3;
pixels = malloc( size );
unsigned char * dest = ( unsigned char * ) pixels;
dest += size;
unsigned char * src = ( unsigned char * ) rpixels;
for (int i = Height; i; i--) {
dest -= ( Width * 3 );
for (unsigned int j=0;j<Width;j++) {
dest[j*3]=src[j*4];
dest[j*3+1]=src[j*4+1];
dest[j*3+2]=src[j*4+2];
}
src += PaddedRowLength;
}
BitCount = 24;
} else if (BitCount == 24) {
int size = Width * Height * 3;
pixels = malloc( size );
unsigned char * dest = ( unsigned char * ) pixels;
dest += size;
unsigned char * src = ( unsigned char * ) rpixels;
for (int i = Height; i; i--) {
dest -= ( Width * 3 );
memcpy( dest, src, Width * 3 );
src += PaddedRowLength;
}
} else if (BitCount == 8) {
pixels = malloc( Width * Height );
unsigned char * dest = ( unsigned char * ) pixels;
dest += Height * Width;
unsigned char * src = ( unsigned char * ) rpixels;
for (int i = Height; i; i--) {
dest -= Width;
memcpy( dest, src, Width );
src += PaddedRowLength;
}
} else if (BitCount == 4) {
Read4To8(rpixels);
}
free( rpixels );
return true;
}
void BMPImporter::Read8To8(void *rpixels)
{
pixels = malloc( Width * Height );
unsigned char * dest = ( unsigned char * ) pixels;
dest += Height * Width;
unsigned char * src = ( unsigned char * ) rpixels;
for (int i = Height; i; i--) {
dest -= Width;
memcpy( dest, src, Width );
src += PaddedRowLength;
}
}
void BMPImporter::Read4To8(void *rpixels)
{
BitCount = 8;
pixels = malloc( Width * Height );
unsigned char * dest = ( unsigned char * ) pixels;
dest += Height * Width;
unsigned char * src = ( unsigned char * ) rpixels;
for (int i = Height; i; i--) {
dest -= Width;
for (unsigned int j=0;j<Width;j++) {
if (!(j&1)) {
dest[j] = ((unsigned) src[j/2])>>4;
} else {
dest[j] = src[j/2]&15;
}
}
src += PaddedRowLength;
}
}
Sprite2D* BMPImporter::GetSprite2D()
{
Sprite2D* spr = NULL;
if (BitCount == 24) {
void* p = malloc( Width * Height * 3 );
memcpy( p, pixels, Width * Height * 3 );
spr = core->GetVideoDriver()->CreateSprite( Width, Height, 24,
red_mask, green_mask, blue_mask, 0x00000000, p,
true, green_mask );
} else if (BitCount == 8) {
void* p = malloc( Width* Height );
memcpy( p, pixels, Width * Height );
spr = core->GetVideoDriver()->CreateSprite8( Width, Height, NumColors==16?4:8,
p, Palette, true, 0 );
}
return spr;
}
void BMPImporter::GetPalette(int colors, Color* pal)
{
if (BitCount > 8) {
ImageMgr::GetPalette(colors, pal);
return;
}
for (int i = 0; i < colors; i++) {
pal[i].r = Palette[i%NumColors].r;
pal[i].g = Palette[i%NumColors].g;
pal[i].b = Palette[i%NumColors].b;
pal[i].a = 0xff;
}
}
Bitmap* BMPImporter::GetBitmap()
{
Bitmap *data = new Bitmap(Width,Height);
unsigned char *p = ( unsigned char * ) pixels;
switch (BitCount) {
case 8:
unsigned int y;
for (y = 0; y < Height; y++) {
for (unsigned int x = 0; x < Width; x++) {
data->SetAt(x,y,p[y*Width + x]);
}
}
break;
case 24:
printMessage("BMPImporter", "Don't know how to handle 24bit bitmap from ", WHITE);
printf( "%s...", str->filename );
printStatus( "ERROR", LIGHT_RED );
for (y = 0; y < Height; y++) {
for (unsigned int x = 0; x < Width; x++) {
data->SetAt(x,y,p[3*(y*Width + x)]);
}
}
break;
}
return data;
}
#include "plugindef.h"
GEMRB_PLUGIN(0xD768B1, "BMP File Reader")
PLUGIN_IE_RESOURCE(BMPImporter, ".bmp", (ieWord)IE_BMP_CLASS_ID)
END_PLUGIN()

View File

@@ -0,0 +1,56 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#ifndef BMPIMP_H
#define BMPIMP_H
#include "ImageMgr.h"
class BMPImporter : public ImageMgr {
private:
//BITMAPINFOHEADER
ieDword Size, Width, Height, Compression, ImageSize, ColorsUsed, ColorsImportant;
ieWord Planes, BitCount;
//COLORTABLE
ieDword NumColors;
Color* Palette;
//RASTERDATA
void* pixels;
//OTHER
unsigned int PaddedRowLength;
public:
BMPImporter(void);
~BMPImporter(void);
bool Open(DataStream* stream);
Sprite2D* GetSprite2D();
virtual Bitmap* GetBitmap();
void GetPalette(int colors, Color* pal);
int GetWidth() { return (int) Width; }
int GetHeight() { return (int) Height; }
private:
void Read8To8(void *rpixels);
void Read4To8(void *rpixels);
};
#endif

View File

@@ -0,0 +1 @@
ADD_GEMRB_PLUGIN (BMPImporter BMPImporter.cpp)

View File

@@ -0,0 +1,3 @@
plugin_LTLIBRARIES = BMPImporter.la
BMPImporter_la_LDFLAGS = -module -avoid-version -shared
BMPImporter_la_SOURCES = BMPImporter.cpp BMPImporter.h

View File

@@ -0,0 +1,77 @@
#include "BMPWriter.h"
#include "Interface.h"
#include "Video.h"
#include <cstring>
#define BMP_HEADER_SIZE 54 //FIXME: duplicate
#define GET_SCANLINE_LENGTH(width, bitsperpixel) (((width)*(bitsperpixel)+7)/8)
BMPWriter::BMPWriter()
{
}
BMPWriter::~BMPWriter()
{
}
void BMPWriter::PutImage(DataStream *output, Sprite2D *spr)
{
ieDword tmpDword;
ieWord tmpWord;
// FIXME
ieDword Width = spr->Width;
ieDword Height = spr->Height;
char filling[3] = {'B','M'};
ieDword PaddedRowLength = GET_SCANLINE_LENGTH(Width,24);
int stuff = (4-(PaddedRowLength&3))&3; // rounding it up to 4 bytes boundary
PaddedRowLength+=stuff;
ieDword fullsize = PaddedRowLength*Height;
//always save in truecolor (24 bit), no palette
output->Write( filling, 2);
tmpDword = fullsize+BMP_HEADER_SIZE; // FileSize
output->WriteDword( &tmpDword);
tmpDword = 0;
output->WriteDword( &tmpDword); // ??
tmpDword = BMP_HEADER_SIZE; // DataOffset
output->WriteDword( &tmpDword);
tmpDword = 40; // Size
output->WriteDword( &tmpDword);
output->WriteDword( &Width);
output->WriteDword( &Height);
tmpWord = 1; // Planes
output->WriteWord( &tmpWord);
tmpWord = 24; //24 bits // BitCount
output->WriteWord( &tmpWord);
tmpDword = 0; // Compression
output->WriteDword( &tmpDword);
output->WriteDword( &tmpDword); // ImageSize
output->WriteDword( &tmpDword);
output->WriteDword( &tmpDword);
output->WriteDword( &tmpDword);
output->WriteDword( &tmpDword);
memset( filling,0,sizeof(filling) );
for (unsigned int y=0;y<Height;y++) {
for (unsigned int x=0;x<Width;x++) {
Color c = spr->GetPixel(x,Height-y-1);
output->Write( &c.b, 1);
output->Write( &c.g, 1);
output->Write( &c.r, 1);
}
output->Write( filling, stuff);
}
core->GetVideoDriver()->FreeSprite(spr);
}
#include "plugindef.h"
GEMRB_PLUGIN(0xD48051E, "BMP File Writer")
PLUGIN_CLASS(PLUGIN_IMAGE_WRITER_BMP, BMPWriter)
END_PLUGIN()

View File

@@ -0,0 +1,9 @@
#include "ImageWriter.h"
class BMPWriter : public ImageWriter {
public:
BMPWriter(void);
~BMPWriter(void);
void PutImage(DataStream *output, Sprite2D *sprite);
};

View File

@@ -0,0 +1 @@
ADD_GEMRB_PLUGIN (BMPWriter BMPWriter.cpp)

View File

@@ -0,0 +1,3 @@
plugin_LTLIBRARIES = BMPWriter.la
BMPWriter_la_LDFLAGS = -module -avoid-version -shared
BMPWriter_la_SOURCES = BMPWriter.cpp BMPWriter.h

View File

@@ -0,0 +1,518 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#include "CHUImporter.h"
#include "RGBAColor.h"
#include "win32def.h"
#include "AnimationFactory.h"
#include "GameData.h"
#include "ImageMgr.h"
#include "Interface.h"
#include "GUI/Button.h"
#include "GUI/Label.h"
#include "GUI/Progressbar.h"
#include "GUI/ScrollBar.h"
#include "GUI/Slider.h"
#include "GUI/TextArea.h"
#include "GUI/TextEdit.h"
CHUImporter::CHUImporter()
{
str = NULL;
autoFree = false;
}
CHUImporter::~CHUImporter()
{
if (autoFree) {
delete str;
}
}
/** This function loads all available windows from the 'stream' parameter. */
bool CHUImporter::Open(DataStream* stream, bool autoFree)
{
if (stream == NULL) {
return false;
}
if (this->autoFree) {
delete str;
}
str = stream;
this->autoFree = autoFree;
char Signature[8];
str->Read( Signature, 8 );
if (strncmp( Signature, "CHUIV1 ", 8 ) != 0) {
printMessage( "CHUImporter","Not a Valid CHU File\n",LIGHT_RED );
return false;
}
str->ReadDword( &WindowCount );
str->ReadDword( &CTOffset );
str->ReadDword( &WEOffset );
return true;
}
/** Returns the i-th window in the Previously Loaded Stream */
Window* CHUImporter::GetWindow(unsigned int wid)
{
ieWord WindowID, XPos, YPos, Width, Height, BackGround;
ieWord ControlsCount, FirstControl;
ieResRef MosFile;
unsigned int i;
bool found = false;
for (unsigned int c = 0; c < WindowCount; c++) {
str->Seek( WEOffset + ( 0x1c * c ), GEM_STREAM_START );
str->ReadWord( &WindowID );
if (WindowID == wid) {
found = true;
break;
}
}
if (!found) {
return NULL;
}
str->Seek( 2, GEM_CURRENT_POS );
str->ReadWord( &XPos );
str->ReadWord( &YPos );
str->ReadWord( &Width );
str->ReadWord( &Height );
str->ReadWord( &BackGround );
str->ReadWord( &ControlsCount );
str->ReadResRef( MosFile );
str->ReadWord( &FirstControl );
Window* win = new Window( WindowID, XPos, YPos, Width, Height );
if (BackGround == 1) {
ResourceHolder<ImageMgr> mos(MosFile);
if (mos != NULL) {
win->SetBackGround( mos->GetSprite2D(), true );
} else
printMessage( "CHUImporter","Cannot Load BackGround, skipping\n",YELLOW );
}
if (!core->IsAvailable( IE_BAM_CLASS_ID )) {
printMessage( "CHUImporter","No BAM Importer Available, skipping controls\n",LIGHT_RED );
return win;
}
for (i = 0; i < ControlsCount; i++) {
str->Seek( CTOffset + ( ( FirstControl + i ) * 8 ), GEM_STREAM_START );
ieDword COffset, CLength, ControlID;
ieWord XPos, YPos, Width, Height;
ieByte ControlType, temp;
str->ReadDword( &COffset );
str->ReadDword( &CLength );
str->Seek( COffset, GEM_STREAM_START );
str->ReadDword( &ControlID );
str->ReadWord( &XPos );
str->ReadWord( &YPos );
str->ReadWord( &Width );
str->ReadWord( &Height );
str->Read( &ControlType, 1 );
str->Read( &temp, 1 );
switch (ControlType) {
case IE_GUI_BUTTON:
{
//Button
Button* btn = new Button( );
btn->ControlID = ControlID;
btn->XPos = XPos;
btn->YPos = YPos;
btn->Width = Width;
btn->Height = Height;
btn->ControlType = ControlType;
ieResRef BAMFile;
ieByte Cycle, tmp;
ieDword Flags;
ieByte UnpressedIndex, x1;
ieByte PressedIndex, x2;
ieByte SelectedIndex, y1;
ieByte DisabledIndex, y2;
str->ReadResRef( BAMFile );
str->Read( &Cycle, 1 );
str->Read( &tmp, 1 );
Flags = ((ieDword) tmp)<<8;
str->Read( &UnpressedIndex, 1 );
str->Read( &x1, 1 );
str->Read( &PressedIndex, 1 );
str->Read( &x2, 1 );
str->Read( &SelectedIndex, 1 );
str->Read( &y1, 1 );
str->Read( &DisabledIndex, 1 );
str->Read( &y2, 1 );
btn->Owner = win;
/** Justification comes from the .chu, other bits are set by script */
if (!Width) {
btn->SetFlags(IE_GUI_BUTTON_NO_IMAGE, BM_OR);
}
if (core->HasFeature(GF_UPPER_BUTTON_TEXT)) {
btn->SetFlags(IE_GUI_BUTTON_CAPS, BM_OR);
}
btn->SetFlags( Flags, BM_OR );
if (Flags & IE_GUI_BUTTON_ANCHOR) {
btn->SetAnchor(x1 | (x2<<8), y1 | (y2<<8));
}
if (strnicmp( BAMFile, "guictrl\0", 8 ) == 0) {
if (UnpressedIndex == 0) {
//printMessage("CHUImporter", "Special Button Control, Skipping Image Loading\n",GREEN );
win->AddControl( btn );
break;
}
}
AnimationFactory* bam = ( AnimationFactory* )
gamedata->GetFactoryResource( BAMFile,
IE_BAM_CLASS_ID, IE_NORMAL );
if (!bam ) {
printMessage( "CHUImporter","Cannot Load Button Images, skipping control\n",LIGHT_RED );
/* IceWind Dale 2 has fake BAM ResRefs for some Buttons,
this will handle bad ResRefs */
win->AddControl( btn );
break;
}
/** Cycle is only a byte for buttons */
Sprite2D* tspr = bam->GetFrame( UnpressedIndex, (unsigned char) Cycle );
btn->SetImage( IE_GUI_BUTTON_UNPRESSED, tspr );
tspr = bam->GetFrame( PressedIndex, Cycle );
btn->SetImage( IE_GUI_BUTTON_PRESSED, tspr );
//ignorebuttonframes is a terrible hack
if (core->HasFeature( GF_IGNORE_BUTTON_FRAMES) ) {
if (bam->GetCycleSize(Cycle) == 4 )
SelectedIndex=2;
}
tspr = bam->GetFrame( SelectedIndex, (unsigned char) Cycle );
btn->SetImage( IE_GUI_BUTTON_SELECTED, tspr );
if (core->HasFeature( GF_IGNORE_BUTTON_FRAMES) ) {
if (bam->GetCycleSize( (unsigned char) Cycle) == 4 )
DisabledIndex=3;
}
tspr = bam->GetFrame( DisabledIndex, (unsigned char) Cycle );
btn->SetImage( IE_GUI_BUTTON_DISABLED, tspr );
win->AddControl( btn );
}
break;
case IE_GUI_PROGRESSBAR:
{
//GemRB specific, progressbar
ieResRef MOSFile, MOSFile2;
ieResRef BAMFile;
ieWord KnobXPos, KnobYPos;
ieWord CapXPos, CapYPos;
ieWord KnobStepsCount;
ieWord Cycle;
str->ReadResRef( MOSFile );
str->ReadResRef( MOSFile2 );
str->ReadResRef( BAMFile );
str->ReadWord( &KnobStepsCount );
str->ReadWord( &Cycle );
str->ReadWord( &KnobXPos );
str->ReadWord( &KnobYPos );
str->ReadWord( &CapXPos );
str->ReadWord( &CapYPos );
Progressbar* pbar = new Progressbar(KnobStepsCount, true );
pbar->ControlID = ControlID;
pbar->XPos = XPos;
pbar->YPos = YPos;
pbar->ControlType = ControlType;
pbar->Width = Width;
pbar->Height = Height;
pbar->SetSliderPos( KnobXPos, KnobYPos, CapXPos, CapYPos );
Sprite2D* img = NULL;
Sprite2D* img2 = NULL;
if ( MOSFile[0] ) {
ResourceHolder<ImageMgr> mos(MOSFile);
img = mos->GetSprite2D();
}
if ( MOSFile2[0] ) {
ResourceHolder<ImageMgr> mos(MOSFile2);
img2 = mos->GetSprite2D();
}
pbar->SetImage( img, img2 );
if( KnobStepsCount ) {
/* getting the bam */
AnimationFactory *af = (AnimationFactory *)
gamedata->GetFactoryResource(BAMFile, IE_BAM_CLASS_ID );
/* Getting the Cycle of the bam */
pbar->SetAnimation(af->GetCycle( Cycle & 0xff ) );
}
else {
ResourceHolder<ImageMgr> mos(BAMFile);
Sprite2D* img3 = mos->GetSprite2D();
pbar->SetBarCap( img3 );
}
win->AddControl( pbar );
}
break;
case IE_GUI_SLIDER:
{
//Slider
ieResRef MOSFile, BAMFile;
ieWord Cycle, Knob, GrabbedKnob;
ieWord KnobXPos, KnobYPos, KnobStep, KnobStepsCount;
str->ReadResRef( MOSFile );
str->ReadResRef( BAMFile );
str->ReadWord( &Cycle );
str->ReadWord( &Knob );
str->ReadWord( &GrabbedKnob );
str->ReadWord( &KnobXPos );
str->ReadWord( &KnobYPos );
str->ReadWord( &KnobStep );
str->ReadWord( &KnobStepsCount );
Slider* sldr = new Slider( KnobXPos, KnobYPos, KnobStep, KnobStepsCount, true );
sldr->ControlID = ControlID;
sldr->XPos = XPos;
sldr->YPos = YPos;
sldr->ControlType = ControlType;
sldr->Width = Width;
sldr->Height = Height;
ResourceHolder<ImageMgr> mos(MOSFile);
Sprite2D* img = mos->GetSprite2D();
sldr->SetImage( IE_GUI_SLIDER_BACKGROUND, img);
AnimationFactory* bam = ( AnimationFactory* )
gamedata->GetFactoryResource( BAMFile,
IE_BAM_CLASS_ID, IE_NORMAL );
if( bam ) {
img = bam->GetFrame( Knob, 0 );
sldr->SetImage( IE_GUI_SLIDER_KNOB, img );
img = bam->GetFrame( GrabbedKnob, 0 );
sldr->SetImage( IE_GUI_SLIDER_GRABBEDKNOB, img );
}
else {
sldr->SetState(IE_GUI_SLIDER_BACKGROUND);
}
win->AddControl( sldr );
}
break;
case IE_GUI_EDIT:
{
//Text Edit
ieResRef BGMos;
ieResRef FontResRef, CursorResRef;
ieWord maxInput;
ieWord CurCycle, CurFrame;
ieWord PosX, PosY;
str->ReadResRef( BGMos );
str->Seek( 16, GEM_CURRENT_POS );
str->ReadResRef( CursorResRef );
str->ReadWord( &CurCycle );
str->ReadWord( &CurFrame );
str->ReadWord( &PosX );
str->ReadWord( &PosY );
str->Seek( 4, GEM_CURRENT_POS );
str->ReadResRef( FontResRef );
str->Seek( 34, GEM_CURRENT_POS );
str->ReadWord( &maxInput );
Font* fnt = core->GetFont( FontResRef );
AnimationFactory* bam = ( AnimationFactory* )
gamedata->GetFactoryResource( CursorResRef,
IE_BAM_CLASS_ID,
IE_NORMAL );
Sprite2D *cursor = NULL;
if (bam) {
cursor = bam->GetFrame( CurCycle, CurFrame );
}
ResourceHolder<ImageMgr> mos(BGMos);
Sprite2D *img = NULL;
if(mos) {
img = mos->GetSprite2D();
}
TextEdit* te = new TextEdit( maxInput, PosX, PosY );
te->ControlID = ControlID;
te->XPos = XPos;
te->YPos = YPos;
te->Width = Width;
te->Height = Height;
te->ControlType = ControlType;
te->SetFont( fnt );
te->SetCursor( cursor );
te->SetBackGround( img );
win->AddControl( te );
}
break;
case IE_GUI_TEXTAREA:
{
//Text Area
ieResRef FontResRef, InitResRef;
Color fore, init, back;
ieWord SBID;
str->ReadResRef( FontResRef );
str->ReadResRef( InitResRef );
Font* fnt = core->GetFont( FontResRef );
Font* ini = core->GetFont( InitResRef );
str->Read( &fore, 4 );
str->Read( &init, 4 );
str->Read( &back, 4 );
str->ReadWord( &SBID );
TextArea* ta = new TextArea( fore, init, back );
ta->ControlID = ControlID;
ta->XPos = XPos;
ta->YPos = YPos;
ta->Width = Width;
ta->Height = Height;
ta->ControlType = ControlType;
ta->SetFonts( ini, fnt );
win->AddControl( ta );
if (SBID != 0xffff)
win->Link( SBID, ( unsigned short ) ControlID );
}
break;
case IE_GUI_LABEL:
{
//Label
ieResRef FontResRef;
ieStrRef StrRef;
RevColor fore, back;
ieWord alignment;
str->ReadDword( &StrRef );
str->ReadResRef( FontResRef );
Font* fnt = core->GetFont( FontResRef );
str->Read( &fore, 4 );
str->Read( &back, 4 );
str->ReadWord( &alignment );
Label* lab = new Label( fnt );
lab->ControlID = ControlID;
lab->XPos = XPos;
lab->YPos = YPos;
lab->Width = Width;
lab->Height = Height;
lab->ControlType = ControlType;
char* str = core->GetString( StrRef );
lab->SetText( str );
core->FreeString( str );
if (alignment & 1) {
lab->useRGB = true;
Color f, b;
f.r = fore.b;
f.g = fore.g;
f.b = fore.r;
f.a = 0;
b.r = back.b;
b.g = back.g;
b.b = back.r;
b.a = 0;
lab->SetColor( f, b );
}
int align = IE_FONT_ALIGN_CENTER;
if (( alignment & 0x10 ) != 0) {
align = IE_FONT_ALIGN_RIGHT;
goto endvertical;
}
if (( alignment & 0x04 ) != 0) {
goto endvertical;
}
if (( alignment & 0x08 ) != 0) {
align = IE_FONT_ALIGN_LEFT;
goto endvertical;
}
endvertical:
if (( alignment & 0x20 ) != 0) {
align |= IE_FONT_ALIGN_TOP;
goto endalign;
}
if (( alignment & 0x80 ) != 0) {
align |= IE_FONT_ALIGN_BOTTOM;
} else {
align |= IE_FONT_ALIGN_MIDDLE;
}
endalign:
lab->SetAlignment( align );
win->AddControl( lab );
}
break;
case IE_GUI_SCROLLBAR:
{
//ScrollBar
ieResRef BAMResRef;
ieWord Cycle, Trough, Slider, TAID;
ieWord UpUnPressed, UpPressed;
ieWord DownUnPressed, DownPressed;
str->ReadResRef( BAMResRef );
str->ReadWord( &Cycle );
str->ReadWord( &UpUnPressed );
str->ReadWord( &UpPressed );
str->ReadWord( &DownUnPressed );
str->ReadWord( &DownPressed );
str->ReadWord( &Trough );
str->ReadWord( &Slider );
str->ReadWord( &TAID );
ScrollBar* sbar = new ScrollBar();
sbar->ControlID = ControlID;
sbar->XPos = XPos;
sbar->YPos = YPos;
sbar->Width = Width;
sbar->Height = Height;
sbar->ControlType = ControlType;
AnimationFactory* bam = ( AnimationFactory* )
gamedata->GetFactoryResource( BAMResRef,
IE_BAM_CLASS_ID, IE_NORMAL );
if (bam) {
sbar->SetImage( IE_GUI_SCROLLBAR_UP_UNPRESSED,
bam->GetFrame( UpUnPressed, Cycle ) );
sbar->SetImage( IE_GUI_SCROLLBAR_UP_PRESSED,
bam->GetFrame( UpPressed, Cycle ) );
sbar->SetImage( IE_GUI_SCROLLBAR_DOWN_UNPRESSED,
bam->GetFrame( DownUnPressed, Cycle ) );
sbar->SetImage( IE_GUI_SCROLLBAR_DOWN_PRESSED,
bam->GetFrame( DownPressed, Cycle ) );
sbar->SetImage( IE_GUI_SCROLLBAR_TROUGH,
bam->GetFrame( Trough, Cycle ) );
sbar->SetImage( IE_GUI_SCROLLBAR_SLIDER,
bam->GetFrame( Slider, Cycle ) );
}
win->AddControl( sbar );
if (TAID != 0xffff)
win->Link( ( unsigned short ) ControlID, TAID );
}
break;
default:
printMessage( "CHUImporter","Control Not Supported\n",LIGHT_RED );
}
}
return win;
}
/** Returns the number of available windows */
unsigned int CHUImporter::GetWindowsCount()
{
return WindowCount;
}
#include "plugindef.h"
GEMRB_PLUGIN(0x23A7F6CA, "CHU File Importer")
PLUGIN_CLASS(IE_CHU_CLASS_ID, CHUImporter)
END_PLUGIN()

View File

@@ -0,0 +1,48 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#ifndef CHUIMPORTER_H
#define CHUIMPORTER_H
#include "WindowMgr.h"
#include "System/DataStream.h"
/**CHU File Importer Class
*@author GemRB Developement Team
*/
class CHUImporter : public WindowMgr {
private:
DataStream* str;
bool autoFree;
ieDword WindowCount, CTOffset, WEOffset;
public:
CHUImporter();
~CHUImporter();
/** Returns the number of available windows */
unsigned int GetWindowsCount();
/** Returns the i-th window in the Previously Loaded Stream */
Window* GetWindow(unsigned int i);
/** This function loads all available windows from the 'stream' parameter. */
bool Open(DataStream* stream, bool autoFree = true);
};
#endif

View File

@@ -0,0 +1 @@
ADD_GEMRB_PLUGIN (CHUImporter CHUImporter.cpp)

View File

@@ -0,0 +1,3 @@
plugin_LTLIBRARIES = CHUImporter.la
CHUImporter_la_LDFLAGS = -module -avoid-version -shared
CHUImporter_la_SOURCES = CHUImporter.cpp CHUImporter.h

View File

@@ -0,0 +1,45 @@
ADD_SUBDIRECTORY( 2DAImporter )
ADD_SUBDIRECTORY( ACMReader )
ADD_SUBDIRECTORY( AREImporter )
ADD_SUBDIRECTORY( BAMImporter )
ADD_SUBDIRECTORY( BIFImporter )
ADD_SUBDIRECTORY( BIKPlayer )
ADD_SUBDIRECTORY( BMPImporter )
ADD_SUBDIRECTORY( BMPWriter )
ADD_SUBDIRECTORY( CHUImporter )
ADD_SUBDIRECTORY( CREImporter )
ADD_SUBDIRECTORY( DLGImporter )
ADD_SUBDIRECTORY( DirectoryImporter )
ADD_SUBDIRECTORY( EFFImporter )
ADD_SUBDIRECTORY( FXOpcodes )
ADD_SUBDIRECTORY( GAMImporter )
ADD_SUBDIRECTORY( GUIScript )
ADD_SUBDIRECTORY( IDSImporter )
ADD_SUBDIRECTORY( INIImporter )
ADD_SUBDIRECTORY( ITMImporter )
ADD_SUBDIRECTORY( IWDOpcodes )
ADD_SUBDIRECTORY( KEYImporter )
ADD_SUBDIRECTORY( MOSImporter )
ADD_SUBDIRECTORY( MUSImporter )
ADD_SUBDIRECTORY( MVEPlayer )
ADD_SUBDIRECTORY( NullSound )
ADD_SUBDIRECTORY( OGGReader )
ADD_SUBDIRECTORY( OpenALAudio )
ADD_SUBDIRECTORY( PLTImporter )
ADD_SUBDIRECTORY( PNGImporter )
ADD_SUBDIRECTORY( PROImporter )
ADD_SUBDIRECTORY( PSTOpcodes )
ADD_SUBDIRECTORY( SDLAudio )
ADD_SUBDIRECTORY( SDLVideo )
ADD_SUBDIRECTORY( SPLImporter )
ADD_SUBDIRECTORY( STOImporter )
ADD_SUBDIRECTORY( TISImporter )
ADD_SUBDIRECTORY( TLKImporter )
ADD_SUBDIRECTORY( WAVReader )
ADD_SUBDIRECTORY( WEDImporter )
ADD_SUBDIRECTORY( WMPImporter )
ADD_SUBDIRECTORY( ZLibManager )
if (STATIC_LINK)
SET(plugins ${plugins} PARENT_SCOPE)
endif (STATIC_LINK)

View File

@@ -0,0 +1 @@
ADD_GEMRB_PLUGIN (CREImporter CREImporter.cpp)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,112 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#ifndef CREIMPORTER_H
#define CREIMPORTER_H
#include "ActorMgr.h"
#define IE_CRE_GEMRB 0
#define IE_CRE_V1_0 10 //bg1
#define IE_CRE_V1_1 11 //bg2 (still V1.0)
#define IE_CRE_V1_2 12
#define IE_CRE_V2_2 22
#define IE_CRE_V9_0 90
class CREImporter : public ActorMgr {
private:
DataStream* str;
bool autoFree;
unsigned char CREVersion;
ieDword KnownSpellsOffset;
ieDword KnownSpellsCount;
ieDword SpellMemorizationOffset;
ieDword SpellMemorizationCount;
ieDword MemorizedSpellsOffset;
ieDword MemorizedSpellsCount;
ieDword MemorizedIndex;
ieDword MemorizedCount;
ieDword ItemSlotsOffset;
ieDword ItemsOffset;
ieDword ItemsCount;
ieDword EffectsOffset;
ieDword EffectsCount;
ieByte TotSCEFF;
ieByte IsCharacter;
ieDword CREOffset;
ieDword VariablesCount;
ieDword OverlayOffset;
ieDword OverlayMemorySize;
//used in CHR header
int QWPCount; //weapons
int QSPCount; //spells
int QITCount; //items
public:
CREImporter(void);
~CREImporter(void);
bool Open(DataStream* stream, bool autoFree = true);
Actor* GetActor(unsigned char is_in_party);
//returns saved size, updates internal offsets before save
int GetStoredFileSize(Actor *ac);
//saves file
int PutActor(DataStream *stream, Actor *actor, bool chr=false);
private:
/** sets up some variables based on creature version for serializing the object */
void SetupSlotCounts();
/** writes out the chr header */
void WriteChrHeader(DataStream *stream, Actor *actor);
/** reads the chr header data (into PCStatStructs) */
void ReadChrHeader(Actor *actor);
/** skips the chr header */
bool SeekCreHeader(char *Signature);
void GetActorPST(Actor *actor);
ieDword GetActorGemRB(Actor *act);
void GetActorBG(Actor *actor);
void GetActorIWD1(Actor *actor);
void GetActorIWD2(Actor *actor);
void GetIWD2Spellpage(Actor *act, ieIWD2SpellType type, int level, int count);
void ReadInventory(Actor*, unsigned int);
void ReadEffects(Actor* actor);
void GetEffect(Effect *fx);
void ReadScript(Actor *actor, int ScriptLevel);
void ReadDialog(Actor *actor);
CREKnownSpell* GetKnownSpell();
CRESpellMemorization* GetSpellMemorization(Actor *act);
CREMemorizedSpell* GetMemorizedSpell();
CREItem* GetItem();
void SetupColor(ieDword&);
int GetHpAdjustment(Actor *actor);
int PutActorGemRB(DataStream *stream, Actor *actor, ieDword InvSize);
int PutActorPST(DataStream *stream, Actor *actor);
int PutActorBG(DataStream *stream, Actor *actor);
int PutActorIWD1(DataStream *stream, Actor *actor);
int PutActorIWD2(DataStream *stream, Actor *actor);
int PutKnownSpells(DataStream *stream, Actor *actor);
int PutSpellPages(DataStream *stream, Actor *actor);
int PutMemorizedSpells(DataStream *stream, Actor *actor);
int PutEffects(DataStream *stream, Actor *actor);
int PutVariables(DataStream *stream, Actor *actor);
int PutInventory(DataStream *stream, Actor *actor, unsigned int size);
int PutHeader(DataStream *stream, Actor *actor);
};
#endif

View File

@@ -0,0 +1,3 @@
plugin_LTLIBRARIES = CREImporter.la
CREImporter_la_LDFLAGS = -module -avoid-version -shared
CREImporter_la_SOURCES = CREImporter.cpp CREImporter.h

View File

@@ -0,0 +1 @@
ADD_GEMRB_PLUGIN (DLGImporter DLGImporter.cpp)

View File

@@ -0,0 +1,391 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#include "DLGImporter.h"
#include "win32def.h"
#include "Interface.h"
#include "System/FileStream.h"
DLGImporter::DLGImporter(void)
{
str = NULL;
autoFree = false;
Version = 0;
}
DLGImporter::~DLGImporter(void)
{
if (str && autoFree) {
delete( str );
}
}
bool DLGImporter::Open(DataStream* stream, bool autoFree)
{
if (stream == NULL) {
return false;
}
if (str && this->autoFree) {
delete( str );
}
str = stream;
this->autoFree = autoFree;
char Signature[8];
str->Read( Signature, 8 );
if (strnicmp( Signature, "DLG V1.0", 8 ) != 0) {
printMessage( "DLGImporter", "Not a valid DLG File...", WHITE );
printStatus( "ERROR", LIGHT_RED );
Version = 0;
return false;
}
str->ReadDword( &StatesCount );
str->ReadDword( &StatesOffset );
// bg2
if (StatesOffset == 0x34 ) {
Version = 104;
}
else {
Version = 100;
}
str->ReadDword( &TransitionsCount );
str->ReadDword( &TransitionsOffset );
str->ReadDword( &StateTriggersOffset );
str->ReadDword( &StateTriggersCount );
str->ReadDword( &TransitionTriggersOffset );
str->ReadDword( &TransitionTriggersCount );
str->ReadDword( &ActionsOffset );
str->ReadDword( &ActionsCount );
if (Version == 104) {
str->ReadDword( &Flags );
}
else {
Flags = 0;
}
return true;
}
Dialog* DLGImporter::GetDialog() const
{
if(!Version) {
return NULL;
}
Dialog* d = new Dialog();
d->Flags = Flags;
d->TopLevelCount = StatesCount;
d->Order = (unsigned int *) calloc (StatesCount, sizeof(unsigned int *) );
d->initialStates = (DialogState **) calloc (StatesCount, sizeof(DialogState *) );
for (unsigned int i = 0; i < StatesCount; i++) {
DialogState* ds = GetDialogState( d, i );
d->initialStates[i] = ds;
}
return d;
}
DialogState* DLGImporter::GetDialogState(Dialog *d, unsigned int index) const
{
DialogState* ds = new DialogState();
//16 = sizeof(State)
str->Seek( StatesOffset + ( index * 16 ), GEM_STREAM_START );
ieDword FirstTransitionIndex;
ieDword TriggerIndex;
str->ReadDword( &ds->StrRef );
str->ReadDword( &FirstTransitionIndex );
str->ReadDword( &ds->transitionsCount );
str->ReadDword( &TriggerIndex );
ds->condition = GetStateTrigger( TriggerIndex );
ds->transitions = GetTransitions( FirstTransitionIndex, ds->transitionsCount );
if (TriggerIndex<StatesCount)
d->Order[TriggerIndex] = index;
return ds;
}
DialogTransition** DLGImporter::GetTransitions(unsigned int firstIndex, unsigned int count) const
{
DialogTransition** trans = ( DialogTransition** )
malloc( count*sizeof( DialogTransition* ) );
for (unsigned int i = 0; i < count; i++) {
trans[i] = GetTransition( firstIndex + i );
}
return trans;
}
DialogTransition* DLGImporter::GetTransition(unsigned int index) const
{
if (index >= TransitionsCount) {
return NULL;
}
//32 = sizeof(Transition)
str->Seek( TransitionsOffset + ( index * 32 ), GEM_STREAM_START );
DialogTransition* dt = new DialogTransition();
str->ReadDword( &dt->Flags );
str->ReadDword( &dt->textStrRef );
if (!(dt->Flags & IE_DLG_TR_TEXT)) {
dt->textStrRef = 0xffffffff;
}
str->ReadDword( &dt->journalStrRef );
if (!(dt->Flags & IE_DLG_TR_JOURNAL)) {
dt->journalStrRef = 0xffffffff;
}
ieDword TriggerIndex;
ieDword ActionIndex;
str->ReadDword( &TriggerIndex );
str->ReadDword( &ActionIndex );
str->ReadResRef( dt->Dialog );
str->ReadDword( &dt->stateIndex );
if (dt->Flags &IE_DLG_TR_TRIGGER) {
dt->condition = GetTransitionTrigger( TriggerIndex );
}
else {
dt->condition = NULL;
}
if (dt->Flags & IE_DLG_TR_ACTION) {
dt->actions = GetAction( ActionIndex );
}
return dt;
}
static char** GetStrings(char* string, unsigned int& count);
Condition* GetCondition(char* string)
{
unsigned int count;
char **lines = GetStrings( string, count );
Condition *condition = new Condition();
for (size_t i = 0; i < count; ++i) {
Trigger *trigger = GenerateTrigger(lines[i]);
if (!trigger) {
printMessage( "DLGImporter", "Can't compile trigger: " ,YELLOW);
printf("%s\n", lines[i]);
} else {
condition->triggers.push_back(trigger);
}
free(lines[i]);
}
free(lines);
return condition;
}
Condition* DLGImporter::GetStateTrigger(unsigned int index) const
{
if (index >= StateTriggersCount) {
return NULL;
}
//8 = sizeof(VarOffset)
str->Seek( StateTriggersOffset + ( index * 8 ), GEM_STREAM_START );
ieDword Offset, Length;
str->ReadDword( &Offset );
str->ReadDword( &Length );
//a zero length trigger counts as no trigger
//a // comment counts as true(), so we simply ignore zero
//length trigger text like it isn't there
if (!Length) {
return NULL;
}
str->Seek( Offset, GEM_STREAM_START );
char* string = ( char* ) malloc( Length + 1 );
str->Read( string, Length );
string[Length] = 0;
Condition *condition = GetCondition(string);
free(string);
return condition;
}
Condition* DLGImporter::GetTransitionTrigger(unsigned int index) const
{
if (index >= TransitionTriggersCount) {
return NULL;
}
str->Seek( TransitionTriggersOffset + ( index * 8 ), GEM_STREAM_START );
ieDword Offset, Length;
str->ReadDword( &Offset );
str->ReadDword( &Length );
str->Seek( Offset, GEM_STREAM_START );
char* string = ( char* ) malloc( Length + 1 );
str->Read( string, Length );
string[Length] = 0;
Condition *condition = GetCondition(string);
free( string );
return condition;
}
std::vector<Action*> DLGImporter::GetAction(unsigned int index) const
{
if (index >= ActionsCount) {
return std::vector<Action*>();
}
str->Seek( ActionsOffset + ( index * 8 ), GEM_STREAM_START );
ieDword Offset, Length;
str->ReadDword( &Offset );
str->ReadDword( &Length );
str->Seek( Offset, GEM_STREAM_START );
char* string = ( char* ) malloc( Length + 1 );
str->Read( string, Length );
string[Length] = 0;
unsigned int count;
char ** lines = GetStrings( string, count );
std::vector<Action*> actions;
for (size_t i = 0; i < count; ++i) {
Action *action = GenerateAction(lines[i]);
if (!action) {
printMessage( "DLGImporter", "Can't compile action: " ,YELLOW);
printf("%s\n", lines[i]);
} else {
action->IncRef();
actions.push_back(action);
}
free(lines[i]);
}
return actions;
}
int GetActionLength(const char* string)
{
int i;
int level = 0;
bool quotes = true;
const char* poi = string;
for (i = 0; *poi; i++) {
switch (*poi++) {
case '"':
quotes = !quotes;
break;
case '(':
if (quotes) {
level++;
}
break;
case ')':
if (quotes && level) {
level--;
if (level == 0) {
return i + 1;
}
}
break;
case '\r':
case '\n':
// force reset on newline if quotes are open
if (!quotes) return i;
break;
default:
break;
}
}
return i;
}
#define MyIsSpace(c) (((c) == ' ') || ((c) == '\n') || ((c) == '\r'))
/* this function will break up faulty script strings that lack the CRLF
between commands, common in PST dialog */
/* misc test cases (just examples, there are more):
pst's FORGE.DLG (trigger split across two lines),
bg2's SAHIMP02.DLG (missing quotemark in string),
bg2's QUAYLE.DLG (missing closing bracket) */
char** GetStrings(char* string, unsigned int& count)
{
int col = 0;
int level = 0;
bool quotes = true;
bool ignore = false;
char* poi = string;
count = 0;
while (*poi) {
switch (*poi++) {
case '/':
if(col==0) {
if(*poi=='/') {
poi++;
ignore=true;
}
}
break;
case '"':
quotes = !quotes;
break;
case '(':
if (quotes) {
level++;
}
break;
case ')':
if (quotes && level) {
level--;
if (level == 0) {
if(!ignore) {
count++;
}
ignore=false;
}
}
break;
case '\r':
case '\n':
// force reset on newline if quotes are open, or we had a comment
if (!quotes || ignore) {
level = 0;
quotes = true;
ignore = false;
count++;
}
break;
default:
break;
}
}
if(!count) {
return NULL;
}
char** strings = ( char** ) calloc( count, sizeof( char* ) );
if (strings == NULL) {
count = 0;
return strings;
}
poi = string;
for (int i = 0; i < (int)count; i++) {
while (MyIsSpace( *poi ))
poi++;
int len = GetActionLength( poi );
if((*poi=='/') && (*(poi+1)=='/') ) {
poi+=len;
i--;
continue;
}
strings[i] = ( char * ) malloc( len + 1 );
int j;
for (j = 0; len; poi++,len--) {
if (isspace( *poi ))
continue;
strings[i][j++] = *poi;
}
strings[i][j] = 0;
}
return strings;
}
#include "plugindef.h"
GEMRB_PLUGIN(0x1970D894, "DLG File Importer")
PLUGIN_CLASS(IE_DLG_CLASS_ID, DLGImporter)
END_PLUGIN()

View File

@@ -0,0 +1,85 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#ifndef DLGIMPORTER_H
#define DLGIMPORTER_H
#include "DialogMgr.h"
#include "globals.h"
/*
struct State {
ieStrRef StrRef;
ieDword FirstTransitionIndex;
ieDword TransitionsCount;
ieDword TriggerIndex;
};
*/
/*
struct Transition {
ieDword Flags;
ieStrRef AnswerStrRef;
ieStrRef JournalStrRef;
ieDword TriggerIndex;
ieDword ActionIndex;
ieResRef DLGResRef;
ieDword NextStateIndex;
};
*/
/*
struct VarOffset {
ieDword Offset;
ieDword Length;
};
*/
class DLGImporter : public DialogMgr {
private:
DataStream* str;
bool autoFree;
ieDword StatesCount;
ieDword StatesOffset;
ieDword TransitionsCount;
ieDword TransitionsOffset;
ieDword StateTriggersCount;
ieDword StateTriggersOffset;
ieDword TransitionTriggersCount;
ieDword TransitionTriggersOffset;
ieDword ActionsCount;
ieDword ActionsOffset;
ieDword Flags;
ieDword Version;
public:
DLGImporter(void);
~DLGImporter(void);
bool Open(DataStream* stream, bool autoFree = true);
Dialog* GetDialog() const;
private:
DialogState* GetDialogState(Dialog *d, unsigned int index) const;
DialogTransition* GetTransition(unsigned int index) const;
Condition* GetStateTrigger(unsigned int index) const;
Condition* GetTransitionTrigger(unsigned int index) const;
std::vector<Action*> GetAction(unsigned int index) const;
DialogTransition** GetTransitions(unsigned int firstIndex,
unsigned int count) const;
};
#endif

View File

@@ -0,0 +1,3 @@
plugin_LTLIBRARIES = DLGImporter.la
DLGImporter_la_LDFLAGS = -module -avoid-version -shared
DLGImporter_la_SOURCES = DLGImporter.cpp DLGImporter.h

View File

@@ -0,0 +1 @@
ADD_GEMRB_PLUGIN (DirectoryImporter DirectoryImporter.cpp)

View File

@@ -0,0 +1,96 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "DirectoryImporter.h"
#include "globals.h"
#include "win32def.h"
#include "Interface.h"
#include "ResourceDesc.h"
#include "System/FileStream.h"
DirectoryImporter::DirectoryImporter(void)
{
}
DirectoryImporter::~DirectoryImporter(void)
{
}
bool DirectoryImporter::Open(const char *dir, const char *desc)
{
description = desc;
strcpy(path, dir);
return true;
}
static bool FindIn(const char *Path, const char *ResRef, const char *Type)
{
char p[_MAX_PATH], f[_MAX_PATH] = {0};
strcpy(f, ResRef);
strcat(f, Type);
strlwr(f);
return PathJoin(p, Path, f, NULL);
}
static FileStream *SearchIn(const char * Path,const char * ResRef, const char *Type)
{
char p[_MAX_PATH], f[_MAX_PATH] = {0};
strcpy(f, ResRef);
strcat(f, Type);
strlwr(f);
if (!PathJoin(p, Path, f, NULL))
return NULL;
FileStream * fs = new FileStream();
if(!fs) return NULL;
if(!fs->Open(p, true)) {
delete fs;
return NULL;
}
return fs;
}
bool DirectoryImporter::HasResource(const char* resname, SClass_ID type)
{
return FindIn( path, resname, core->TypeExt(type) );
}
bool DirectoryImporter::HasResource(const char* resname, const ResourceDesc &type)
{
return FindIn( path, resname, type.GetExt() );
}
DataStream* DirectoryImporter::GetResource(const char* resname, SClass_ID type)
{
return SearchIn( path, resname, core->TypeExt(type) );
}
DataStream* DirectoryImporter::GetResource(const char* resname, const ResourceDesc &type)
{
return SearchIn( path, resname, type.GetExt() );
}
#include "plugindef.h"
GEMRB_PLUGIN(0xAB4534, "Directory Importer")
PLUGIN_CLASS(PLUGIN_RESOURCE_DIRECTORY, DirectoryImporter)
END_PLUGIN()

View File

@@ -0,0 +1,46 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KEYIMP_H
#define KEYIMP_H
#include "ResourceSource.h"
#include <cstring>
#include <map>
#include <vector>
class Resource;
class ResourceDesc;
class DirectoryImporter : public ResourceSource {
private:
char path[_MAX_PATH];
public:
DirectoryImporter(void);
~DirectoryImporter(void);
bool Open(const char *dir, const char *desc);
/** predicts the availability of a resource */
bool HasResource(const char* resname, SClass_ID type);
bool HasResource(const char* resname, const ResourceDesc &type);
/** returns resource */
DataStream* GetResource(const char* resname, SClass_ID type);
DataStream* GetResource(const char* resname, const ResourceDesc &type);
};
#endif

View File

@@ -0,0 +1,3 @@
plugin_LTLIBRARIES = DirectoryImporter.la
DirectoryImporter_la_LDFLAGS = -module -avoid-version -shared
DirectoryImporter_la_SOURCES = DirectoryImporter.cpp DirectoryImporter.h

View File

@@ -0,0 +1 @@
ADD_GEMRB_PLUGIN (EFFImporter EFFImporter.cpp)

View File

@@ -0,0 +1,243 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2005 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#include "EFFImporter.h"
#include "win32def.h"
#include "Interface.h"
EFFImporter::EFFImporter(void)
{
str = NULL;
autoFree = false;
}
EFFImporter::~EFFImporter(void)
{
if (autoFree) {
delete str;
}
}
bool EFFImporter::Open(DataStream* stream, bool autoFree)
{
if (stream == NULL) {
return false;
}
if (this->autoFree) {
delete str;
}
str = stream;
this->autoFree = autoFree;
char Signature[8];
str->Read( Signature, 8 );
if (strncmp( Signature, "EFF V2.0", 8 ) == 0) {
version = 20;
} else {
version = 1;
}
str->Seek( -8, GEM_CURRENT_POS );
return true;
}
//level resistance is checked when DiceSides or DiceThrown
//are greater than 0 (sometimes they used -1 for our amusement)
//if level>than maximum affected or level<than minimum affected, then the
//effect is resisted
// copy the info into the EFFV2 fields (separate), so it is clearer
inline static void fixAffectedLevels(Effect *fx) {
if (fx->DiceSides > 0 || fx->DiceThrown > 0) {
fx->MinAffectedLevel = fx->DiceThrown;
fx->MaxAffectedLevel = fx->DiceSides;
}
}
Effect* EFFImporter::GetEffect(Effect *fx)
{
if (version == 1) {
return GetEffectV1( fx );
}
else {
// Skip over Signature1
str->Seek( 8, GEM_CURRENT_POS );
return GetEffectV20( fx );
}
}
Effect* EFFImporter::GetEffectV1(Effect *fx)
{
ieByte tmpByte;
ieWord tmpWord;
memset( fx, 0, sizeof( Effect ) );
str->ReadWord( &tmpWord );
fx->Opcode = tmpWord;
str->Read( &tmpByte, 1 );
fx->Target = tmpByte;
str->Read( &tmpByte, 1 );
fx->Power = tmpByte;
str->ReadDword( &fx->Parameter1 );
str->ReadDword( &fx->Parameter2 );
str->Read( &tmpByte, 1 );
fx->TimingMode = tmpByte;
str->Read( &tmpByte, 1 );
fx->Resistance = tmpByte;
str->ReadDword( &fx->Duration );
str->Read( &tmpByte, 1 );
fx->Probability1 = tmpByte;
str->Read( &tmpByte, 1 );
fx->Probability2 = tmpByte;
str->ReadResRef( fx->Resource );
str->ReadDword( &fx->DiceThrown );
str->ReadDword( &fx->DiceSides );
str->ReadDword( &fx->SavingThrowType );
str->ReadDword( &fx->SavingThrowBonus );
str->ReadWord( &fx->IsVariable );
str->ReadWord( &fx->IsSaveForHalfDamage );
fixAffectedLevels( fx );
fx->PosX=0xffffffff;
fx->PosY=0xffffffff;
return fx;
}
Effect* EFFImporter::GetEffectV20(Effect *fx)
{
ieDword tmp;
memset( fx, 0, sizeof( Effect ) );
str->Seek(8, GEM_CURRENT_POS);
str->ReadDword( &fx->Opcode );
str->ReadDword( &fx->Target );
str->ReadDword( &fx->Power );
str->ReadDword( &fx->Parameter1 );
str->ReadDword( &fx->Parameter2 );
str->ReadWord( &fx->TimingMode );
str->ReadWord( &fx->unknown2 );
str->ReadDword( &fx->Duration );
str->ReadWord( &fx->Probability1 );
str->ReadWord( &fx->Probability2 );
str->ReadResRef( fx->Resource );
str->ReadDword( &fx->DiceThrown );
str->ReadDword( &fx->DiceSides );
str->ReadDword( &fx->SavingThrowType );
str->ReadDword( &fx->SavingThrowBonus );
str->ReadWord( &fx->IsVariable ); //if this field was set to 1, this is a variable
str->ReadWord( &fx->IsSaveForHalfDamage ); //if this field was set to 1, save for half damage
str->ReadDword( &fx->PrimaryType );
str->Seek( 4, GEM_CURRENT_POS );
str->ReadDword( &fx->MinAffectedLevel );
str->ReadDword( &fx->MaxAffectedLevel );
str->ReadDword( &fx->Resistance );
str->ReadDword( &fx->Parameter3 );
str->ReadDword( &fx->Parameter4 );
str->Seek( 8, GEM_CURRENT_POS );
str->ReadResRef( fx->Resource2 );
str->ReadResRef( fx->Resource3 );
str->ReadDword( &fx->PosX);
str->ReadDword( &fx->PosY);
//FIXME: these two points are actually different
str->ReadDword( &fx->PosX);
str->ReadDword( &fx->PosY);
str->ReadDword( &fx->SourceType );
str->ReadResRef( fx->Source );
str->ReadDword( &fx->SourceFlags );
str->ReadDword( &fx->Projectile );
str->ReadDword( &tmp );
fx->InventorySlot=(ieDwordSigned) (tmp);
//Variable simply overwrites the resource fields (Keep them grouped)
//They have to be continuous
if (fx->IsVariable) {
str->Read( fx->Resource, 32 );
strnlwrcpy( fx->Resource, fx->Resource, 32 );
} else {
str->Seek( 32, GEM_CURRENT_POS);
}
str->ReadDword( &fx->CasterLevel );
str->Seek( 4, GEM_CURRENT_POS );
str->ReadDword( &fx->SecondaryType );
str->Seek( 60, GEM_CURRENT_POS );
return fx;
}
void EFFImporter::PutEffectV2(DataStream *stream, const Effect *fx) {
ieDword tmpDword1,tmpDword2;
char filling[60];
memset(filling,0,sizeof(filling) );
stream->Write( filling,8 ); //signature
stream->WriteDword( &fx->Opcode);
stream->WriteDword( &fx->Target);
stream->WriteDword( &fx->Power);
stream->WriteDword( &fx->Parameter1);
stream->WriteDword( &fx->Parameter2);
stream->WriteWord( &fx->TimingMode);
stream->WriteWord( &fx->unknown2);
stream->WriteDword( &fx->Duration);
stream->WriteWord( &fx->Probability1);
stream->WriteWord( &fx->Probability2);
stream->WriteResRef(fx->Resource);
stream->WriteDword( &fx->DiceThrown );
stream->WriteDword( &fx->DiceSides );
stream->WriteDword( &fx->SavingThrowType );
stream->WriteDword( &fx->SavingThrowBonus );
//isvariable
stream->Write( filling,4 );
stream->WriteDword( &fx->PrimaryType );
stream->Write( filling,12 );
stream->WriteDword( &fx->Resistance );
stream->WriteDword( &fx->Parameter3 );
stream->WriteDword( &fx->Parameter4 );
stream->Write( filling,8 );
if (fx->IsVariable) {
stream->Write(fx->Resource+8, 8);
//resource1-4 are used as a continuous memory
stream->Write(((ieByte *) fx->Resource)+16, 8);
} else {
stream->WriteResRef(fx->Resource2);
stream->WriteResRef(fx->Resource3);
}
tmpDword1 = (ieDword) fx->PosX;
tmpDword2 = (ieDword) fx->PosY;
stream->WriteDword( &tmpDword1 );
stream->WriteDword( &tmpDword2 );
//FIXME: these two points are actually different
stream->WriteDword( &tmpDword1 );
stream->WriteDword( &tmpDword2 );
stream->WriteDword( &fx->SourceType );
stream->WriteResRef( fx->Source );
stream->WriteDword( &fx->SourceFlags );
stream->WriteDword( &fx->Projectile );
tmpDword1 = (ieDword) fx->InventorySlot;
stream->WriteDword( &tmpDword1 );
stream->Write( filling,40 ); //12+32+8
stream->WriteDword( &fx->SecondaryType );
stream->Write( filling,60 );
}
#include "plugindef.h"
GEMRB_PLUGIN(0x14E81128, "EFF File Importer")
PLUGIN_CLASS(IE_EFF_CLASS_ID, EFFImporter)
END_PLUGIN()

View File

@@ -0,0 +1,47 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#ifndef EFFIMPORTER_H
#define EFFIMPORTER_H
#include "EffectMgr.h"
#include "ie_types.h"
#include "Effect.h"
class EFFImporter : public EffectMgr {
private:
DataStream* str;
bool autoFree;
int version;
public:
EFFImporter(void);
~EFFImporter(void);
bool Open(DataStream* stream, bool autoFree = true);
Effect* GetEffect(Effect *fx);
Effect* GetEffectV1(Effect *fx);
Effect* GetEffectV20(Effect *fx);
void PutEffectV2(DataStream *stream, const Effect *fx); // used in the area and cre importer
};
#endif

View File

@@ -0,0 +1,3 @@
plugin_LTLIBRARIES = EFFImporter.la
EFFImporter_la_LDFLAGS = -module -avoid-version -shared
EFFImporter_la_SOURCES = EFFImporter.cpp EFFImporter.h

View File

@@ -0,0 +1 @@
ADD_GEMRB_PLUGIN (FXOpcodes FXOpcodes.cpp)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
plugin_LTLIBRARIES = FXOpcodes.la
FXOpcodes_la_LDFLAGS = -module -avoid-version -shared
FXOpcodes_la_SOURCES = FXOpcodes.cpp

View File

@@ -0,0 +1 @@
ADD_GEMRB_PLUGIN (GAMImporter GAMImporter.cpp)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,79 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#ifndef GAMIMPORTER_H
#define GAMIMPORTER_H
#include "SaveGameMgr.h"
#include "ActorMgr.h"
#define GAM_VER_GEMRB 0
#define GAM_VER_BG 10
#define GAM_VER_IWD 11
#define GAM_VER_PST 12
#define GAM_VER_BG2 20
#define GAM_VER_TOB 21
#define GAM_VER_IWD2 22
class GAMImporter : public SaveGameMgr {
private:
DataStream* str;
bool autoFree;
int version;
unsigned int PCSize;
ieDword PCOffset, PCCount;
ieDword MazeOffset;
ieDword NPCOffset, NPCCount;
ieDword GlobalOffset, GlobalCount;
ieDword JournalOffset, JournalCount;
ieDword KillVarsOffset, KillVarsCount;
ieDword FamiliarsOffset;
ieDword SavedLocOffset, SavedLocCount;
ieDword PPLocOffset, PPLocCount;
public:
GAMImporter(void);
~GAMImporter(void);
bool Open(DataStream* stream, bool autoFree = true);
Game* LoadGame(Game *newGame, int ver_override = 0);
int GetStoredFileSize(Game *game);
/* stores a gane in the savegame folder */
int PutGame(DataStream *stream, Game *game);
private:
Actor* GetActor(Holder<ActorMgr> aM, bool is_in_party );
void GetPCStats(PCStatsStruct* ps);
GAMJournalEntry* GetJournalEntry();
int PutHeader(DataStream *stream, Game *game);
int PutActor(DataStream *stream, Actor *ac, ieDword CRESize, ieDword CREOffset, ieDword version);
int PutPCs(DataStream *stream, Game *game);
int PutNPCs(DataStream *stream, Game *game);
int PutJournals(DataStream *stream, Game *game);
int PutVariables( DataStream *stream, Game *game);
int PutKillVars(DataStream *stream, Game *game);
int PutMaze(DataStream *stream, Game *game);
int PutFamiliars(DataStream *stream, Game *game);
int PutSavedLocations(DataStream *stream, Game *game);
int PutPlaneLocations(DataStream *stream, Game *game);
};
#endif

View File

@@ -0,0 +1,3 @@
plugin_LTLIBRARIES = GAMImporter.la
GAMImporter_la_LDFLAGS = -module -avoid-version -shared
GAMImporter_la_SOURCES = GAMImporter.cpp GAMImporter.h

View File

@@ -0,0 +1,5 @@
INCLUDE(FindPythonLibs)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
ADD_GEMRB_PLUGIN (GUIScript GUIScript.cpp PythonHelpers.cpp)
TARGET_LINK_LIBRARIES(GUIScript ${PYTHON_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,66 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#ifndef GUISCRIPT_H
#define GUISCRIPT_H
// NOTE: Python.h has to be included first.
#if defined(WIN32) && defined(_DEBUG)
#undef _DEBUG
#include <Python.h>
#define _DEBUG
#else
#include <Python.h>
#endif
#include "ScriptEngine.h"
#define SV_BPP 0
#define SV_WIDTH 1
#define SV_HEIGHT 2
class GUIScript : public ScriptEngine {
public:
PyObject* pModule, * pDict;
PyObject* pMainDic;
PyObject* pGUIClasses;
public:
GUIScript(void);
~GUIScript(void);
/** Initialization Routine */
bool Init(void);
/** Load Script */
bool LoadScript(const char* filename);
/** Run Function */
bool RunFunction(const char *module, const char* fname, bool error=true, int intparam=-1);
/** Exec a single File */
void ExecFile(const char* file);
/** Exec a single String */
void ExecString(const char* string);
/** lets hope this one can be here without screwing up the general interface */
PyObject *CallbackFunction(const char* fname, PyObject* pArgs);
PyObject* ConstructObject(const char* classname, int arg);
PyObject* ConstructObject(const char* classname, PyObject* pArgs);
};
extern GUIScript *gs;
#endif

View File

@@ -0,0 +1,5 @@
plugin_LTLIBRARIES = GUIScript.la
INCLUDES = $(PYTHON_INCLUDES)
GUIScript_la_LDFLAGS = -module -avoid-version -shared
GUIScript_la_LIBADD = @PYTHON_LIBS@
GUIScript_la_SOURCES = GUIScript.cpp GUIScript.h PythonHelpers.cpp PythonHelpers.h

View File

@@ -0,0 +1,80 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#include "PythonHelpers.h"
static bool CallPython(PyObject *Function, PyObject *args = NULL)
{
if (!Function) {
return false;
}
PyObject *ret = PyObject_CallObject(Function, args);
Py_XDECREF( args );
if (ret == NULL) {
if (PyErr_Occurred()) {
PyErr_Print();
}
return false;
}
Py_DECREF(ret);
return true;
}
static bool CallPython(PyObject *Function, int arg)
{
if (!Function) {
return false;
}
PyObject *args = Py_BuildValue("(i)", arg);
return CallPython(Function, args);
}
PythonCallback::PythonCallback(PyObject *Function)
: Function(Function)
{
if (Function && PyCallable_Check(Function)) {
Py_INCREF(Function);
} else {
Function = NULL;
}
}
PythonCallback::~PythonCallback()
{
if (Py_IsInitialized()) {
Py_XDECREF(Function);
}
}
bool PythonCallback::call ()
{
if (!Function || !Py_IsInitialized()) {
return false;
}
return CallPython(Function);
}
bool PythonCallback::call (int arg)
{
if (!Function || !Py_IsInitialized()) {
return false;
}
return CallPython(Function, arg);
}

View File

@@ -0,0 +1,112 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef PYTHON_HELPERS_H
#define PYTHON_HELPERS_H
// Python.h needs to be included first.
#include "GUIScript.h"
#include "win32def.h" // For Logging
#include "Callback.h"
#include "Holder.h"
#include "Interface.h"
struct PythonCallback : public Callback {
public:
PythonCallback(PyObject *Function);
~PythonCallback();
bool call();
bool call(int);
private:
PyObject *Function;
};
template <typename T>
class CObject : public Holder<T> {
private:
public:
operator PyObject* () const
{
if (Holder<T>::ptr) {
Holder<T>::ptr->acquire();
GUIScript *gs = (GUIScript *) core->GetGUIScriptEngine();
PyObject *obj = PyCObject_FromVoidPtrAndDesc(Holder<T>::ptr,const_cast<TypeID*>(&T::ID),PyRelease);
PyObject *tuple = PyTuple_New(1);
PyTuple_SET_ITEM(tuple, 0, obj);
PyObject *ret = gs->ConstructObject(T::ID.description, tuple);
Py_DECREF(tuple);
return ret;
} else {
Py_INCREF( Py_None );
return Py_None;
}
}
CObject(PyObject *obj)
{
if (obj == Py_None)
return;
PyObject *id = PyObject_GetAttrString(obj, "ID");
if (id)
obj = id;
else
PyErr_Clear();
if (!PyCObject_Check(obj) || PyCObject_GetDesc(obj) != const_cast<TypeID*>(&T::ID)) {
printMessage("GUIScript","Bad CObject extracted.\n",LIGHT_RED);
Py_XDECREF(id);
return;
}
Holder<T>::ptr = static_cast<T*>(PyCObject_AsVoidPtr(obj));
Holder<T>::ptr->acquire();
Py_XDECREF(id);
}
CObject(const Holder<T>& ptr)
: Holder<T>(ptr)
{
}
// This is here because of lookup order issues.
operator bool () const
{
return Holder<T>::ptr;
}
private:
static void PyRelease(void *obj, void *desc)
{
if (desc != const_cast<TypeID*>(&T::ID)) {
printMessage("GUIScript","Bad CObject deleted.\n",LIGHT_RED);
return;
}
static_cast<T*>(obj)->release();
}
};
template <typename T, class Container>
PyObject* MakePyList(const Container &source)
{
size_t size = source.size();
PyObject *list = PyList_New(size);
for (size_t i = 0; i < size; ++i) {
// SET_ITEM might be preferable to SetItem here, but MSVC6 doesn't like it.
PyList_SetItem(list, i, CObject<T>(source[i]));
}
return list;
}
#endif

View File

@@ -0,0 +1 @@
ADD_GEMRB_PLUGIN (IDSImporter IDSImporter.cpp)

View File

@@ -0,0 +1,158 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#include "IDSImporter.h"
#include "IDSImporterDefs.h"
#include "globals.h"
#include "win32def.h"
#include <cstring>
IDSImporter::IDSImporter(void)
{
str = NULL;
autoFree = false;
}
IDSImporter::~IDSImporter(void)
{
if (str && autoFree) {
delete( str );
}
for (unsigned int i = 0; i < ptrs.size(); i++) {
free( ptrs[i] );
}
}
bool IDSImporter::Open(DataStream* stream, bool autoFree)
{
if (stream == NULL) {
return false;
}
if (str) {
return false;
}
str = stream;
this->autoFree = autoFree;
str->CheckEncrypted();
char tmp[11];
str->ReadLine( tmp, 10 );
tmp[10] = 0;
if (tmp[0] != 'I') {
str->Rewind();
}
while (true) {
char* line = ( char* ) malloc( 256 );
int len = str->ReadLine( line, 256 );
strlwr( line );
if (len == -1) {
free( line );
break;
}
if (len == 0) {
free( line );
continue;
}
if (len < 256)
line = ( char * ) realloc( line, len + 1 );
char* str = strtok( line, " " );
Pair p;
p.val = strtoul( str, NULL, 0 );
str = strtok( NULL, " " );
p.str = str;
if (str != NULL) {
ptrs.push_back( line );
pairs.push_back( p );
} else {
free( line );
}
}
return true;
}
int IDSImporter::GetValue(const char* txt) const
{
for (unsigned int i = 0; i < pairs.size(); i++) {
if (stricmp( pairs[i].str, txt ) == 0) {
return pairs[i].val;
}
}
return -1;
}
char* IDSImporter::GetValue(int val) const
{
for (unsigned int i = 0; i < pairs.size(); i++) {
if (pairs[i].val == val) {
return pairs[i].str;
}
}
return NULL;
}
char* IDSImporter::GetStringIndex(unsigned int Index) const
{
if (Index >= pairs.size()) {
return NULL;
}
return pairs[Index].str;
}
int IDSImporter::GetValueIndex(unsigned int Index) const
{
if (Index >= pairs.size()) {
return 0;
}
return pairs[Index].val;
}
int IDSImporter::FindString(char *str, int len) const
{
int i=pairs.size();
while(i--) {
if (strnicmp(pairs[i].str, str, len) == 0) {
return i;
}
}
return -1;
}
int IDSImporter::FindValue(int val) const
{
int i=pairs.size();
while(i--) {
if(pairs[i].val==val) {
return i;
}
}
return -1;
}
#include "plugindef.h"
GEMRB_PLUGIN(0x1F41B94C, "IDS File Importer")
PLUGIN_CLASS(IE_IDS_CLASS_ID, IDSImporter)
END_PLUGIN()

View File

@@ -0,0 +1,53 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#ifndef IDSIMPORTER_H
#define IDSIMPORTER_H
#include "SymbolMgr.h"
struct Pair {
int val;
char* str;
};
class IDSImporter : public SymbolMgr {
private:
DataStream* str;
bool autoFree;
std::vector< Pair> pairs;
std::vector< char*> ptrs;
public:
IDSImporter(void);
~IDSImporter(void);
bool Open(DataStream* stream, bool autoFree = true);
int GetValue(const char* txt) const;
char* GetValue(int val) const;
char* GetStringIndex(unsigned int Index) const;
int GetValueIndex(unsigned int Index) const;
int FindString(char *str, int len) const;
int FindValue(int val) const;
int GetSize() const { return pairs.size(); }
};
#endif

View File

@@ -0,0 +1,37 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#define MAX_LINES 400
#define MAX_VALUE_LENGTH 20
#define MAX_TEXT_LENGTH 60 // maximum text length in case IDS file doesn't specify
#define MAX_LINE_LENGTH MAX_VALUE_LENGTH + MAX_TEXT_LENGTH
#define MAX_HEADER_LENGTH 20
#define HEADER_IDS 1
#define HEADER_LENGTH 2
#define HEADER_BLANK 3
#define HEADER_RECORD 4
#define HEADER_ERROR -1
// need to transfer this to a header file in the includes dir:
//#define IDS_VALUE_NOT_LOCATED -65535 // GetValue returns this if text is not found in arrays ... this needs to be a unique number that does not exist in the value[] array
// need to transfer this to a header file in the includes dir too:
//#define GEM_ENCRYPTION_KEY "\x88\xa8\x8f\xba\x8a\xd3\xb9\xf5\xed\xb1\xcf\xea\xaa\xe4\xb5\xfb\xeb\x82\xf9\x90\xca\xc9\xb5\xe7\xdc\x8e\xb7\xac\xee\xf7\xe0\xca\x8e\xea\xca\x80\xce\xc5\xad\xb7\xc4\xd0\x84\x93\xd5\xf0\xeb\xc8\xb4\x9d\xcc\xaf\xa5\x95\xba\x99\x87\xd2\x9d\xe3\x91\xba\x90\xca"

View File

@@ -0,0 +1,3 @@
plugin_LTLIBRARIES = IDSImporter.la
IDSImporter_la_LDFLAGS = -module -avoid-version -shared
IDSImporter_la_SOURCES = IDSImporter.cpp IDSImporter.h IDSImporterDefs.h

View File

@@ -0,0 +1 @@
ADD_GEMRB_PLUGIN (INIImporter INIImporter.cpp)

View File

@@ -0,0 +1,165 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#include "INIImporter.h"
#include "win32def.h"
#include "Interface.h"
INIImporter::INIImporter(void)
{
str = NULL;
autoFree = false;
}
INIImporter::~INIImporter(void)
{
if (str && autoFree) {
delete( str );
}
for (unsigned int i = 0; i < tags.size(); i++)
delete( tags[i] );
}
bool INIImporter::Open(DataStream* stream, bool autoFree)
{
if (stream == NULL) {
return false;
}
if (str && this->autoFree) {
delete( str );
}
str = stream;
this->autoFree = autoFree;
int cnt = 0;
char* strbuf = ( char* ) malloc( 4097 );
INITag* lastTag = NULL;
do {
cnt = str->ReadLine( strbuf, 4096 );
if (cnt == -1)
break;
if (cnt == 0)
continue;
if (strbuf[0] == ';') //Rem
continue;
if (strbuf[0] == '[') {
// this is a tag
char* sbptr = strbuf + 1;
char* TagName = sbptr;
while (*sbptr != '\0') {
if (*sbptr == ']') {
*sbptr = 0;
break;
}
sbptr++;
}
INITag* it = new INITag( TagName );
tags.push_back( it );
lastTag = it;
continue;
}
if (lastTag == NULL)
continue;
if (lastTag->AddLine( strbuf )) {
printMessage("INIImporter","", LIGHT_RED);
printf("Bad Line in file: %s, Section: [%s], Entry: '%s'\n", stream->filename, lastTag->GetTagName(), strbuf);
}
} while (true);
free( strbuf );
return true;
}
int INIImporter::GetKeysCount(const char* Tag) const
{
for (unsigned int i = 0; i < tags.size(); i++) {
const char* TagName = tags[i]->GetTagName();
if (stricmp( TagName, Tag ) == 0) {
return tags[i]->GetKeyCount();
}
}
return 0;
}
const char* INIImporter::GetKeyNameByIndex(const char* Tag, int index) const
{
for (unsigned int i = 0; i < tags.size(); i++) {
const char* TagName = tags[i]->GetTagName();
if (stricmp( TagName, Tag ) == 0) {
return tags[i]->GetKeyNameByIndex(index);
}
}
return NULL;
}
const char* INIImporter::GetKeyAsString(const char* Tag, const char* Key,
const char* Default) const
{
for (unsigned int i = 0; i < tags.size(); i++) {
const char* TagName = tags[i]->GetTagName();
if (stricmp( TagName, Tag ) == 0) {
return tags[i]->GetKeyAsString( Key, Default );
}
}
return Default;
}
int INIImporter::GetKeyAsInt(const char* Tag, const char* Key,
const int Default) const
{
for (unsigned int i = 0; i < tags.size(); i++) {
const char* TagName = tags[i]->GetTagName();
if (stricmp( TagName, Tag ) == 0) {
return tags[i]->GetKeyAsInt( Key, Default );
}
}
return Default;
}
float INIImporter::GetKeyAsFloat(const char* Tag, const char* Key,
const float Default) const
{
for (unsigned int i = 0; i < tags.size(); i++) {
const char* TagName = tags[i]->GetTagName();
if (stricmp( TagName, Tag ) == 0) {
return tags[i]->GetKeyAsFloat( Key, Default );
}
}
return Default;
}
bool INIImporter::GetKeyAsBool(const char* Tag, const char* Key,
const bool Default) const
{
for (unsigned int i = 0; i < tags.size(); i++) {
const char* TagName = tags[i]->GetTagName();
if (stricmp( TagName, Tag ) == 0) {
return tags[i]->GetKeyAsBool( Key, Default );
}
}
return Default;
}
#include "plugindef.h"
GEMRB_PLUGIN(0xB62F6D7, "INI File Importer")
PLUGIN_CLASS(IE_INI_CLASS_ID, INIImporter)
END_PLUGIN()

View File

@@ -0,0 +1,212 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#ifndef INIIMPORTER_H
#define INIIMPORTER_H
#include "DataFileMgr.h"
#include "globals.h"
#include <cstring>
struct INIPair {
char* Name, * Value;
};
class INITag {
private:
std::vector< INIPair> pairs;
char* TagName;
public:
INITag(const char* Name)
{
int len = ( int ) strlen( Name ) + 1;
TagName = ( char * ) malloc( len );
memcpy( TagName, Name, len );
}
~INITag()
{
free( TagName );
for (unsigned int i = 0; i < pairs.size(); i++) {
free( pairs[i].Name );
free( pairs[i].Value );
}
}
const char* GetTagName() const
{
return TagName;
}
int GetKeyCount() const
{
return (int) pairs.size();
}
const char* GetKeyNameByIndex(int index) const
{
return pairs[index].Name;
}
bool AddLine(char* Line)
{
INIPair p;
char* equal = strchr( Line, '=' );
if(!equal) {
return true;
}
*equal = 0;
char* NameKey = Line;
char* ValueKey = equal + 1;
//Left Trimming
while (*NameKey != '\0') {
if (*NameKey != ' ')
break;
NameKey++;
}
while (*ValueKey != '\0') {
if (*ValueKey != ' ')
break;
ValueKey++;
}
//Right Trimming
int NameKeyLen = ( int ) strlen( NameKey );
int ValueKeyLen = ( int ) strlen( ValueKey );
char* endNameKey = NameKey + NameKeyLen - 1;
char* endValueKey = ValueKey + ValueKeyLen - 1;
while (endNameKey != NameKey) {
if (*endNameKey != ' ')
break;
*endNameKey-- = 0;
NameKeyLen--;
}
while (endValueKey != ValueKey) {
if (*endValueKey != ' ')
break;
*endValueKey-- = 0;
ValueKeyLen--;
}
//Allocating Buffers
p.Name = ( char * ) malloc( NameKeyLen + 1 );
p.Value = ( char * ) malloc( ValueKeyLen + 1 );
//Copying buffers
memcpy( p.Name, NameKey, NameKeyLen + 1 );
memcpy( p.Value, ValueKey, ValueKeyLen + 1 );
//Adding to Tag Pairs
pairs.push_back( p );
return false;
}
const char* GetKeyAsString(const char* Key, const char* Default) const
{
for (unsigned int i = 0; i < pairs.size(); i++) {
if (stricmp( Key, pairs[i].Name ) == 0) {
return pairs[i].Value;
}
}
return Default;
}
int GetKeyAsInt(const char* Key, const int Default) const
{
const char* ret = NULL;
for (unsigned int i = 0; i < pairs.size(); i++) {
if (stricmp( Key, pairs[i].Name ) == 0) {
ret = pairs[i].Value;
break;
}
}
if (!ret) {
return Default;
}
return atoi( ret );
}
float GetKeyAsFloat(const char* Key, const float Default) const
{
const char* ret = NULL;
for (unsigned int i = 0; i < pairs.size(); i++) {
if (stricmp( Key, pairs[i].Name ) == 0) {
ret = pairs[i].Value;
break;
}
}
if (!ret) {
return Default;
}
return atof( ret );
}
bool GetKeyAsBool(const char* Key, const bool Default) const
{
const char* ret = NULL;
for (unsigned int i = 0; i < pairs.size(); i++) {
if (stricmp( Key, pairs[i].Name ) == 0) {
ret = pairs[i].Value;
break;
}
}
if (!ret) {
return Default;
}
if (!stricmp( ret, "true") ) {
return true;
}
if (!stricmp( ret, "false") ) {
return false;
}
return (atoi( ret ) )!=0;
}
};
class INIImporter : public DataFileMgr {
private:
DataStream* str;
bool autoFree;
std::vector< INITag*> tags;
public:
INIImporter(void);
~INIImporter(void);
bool Open(DataStream* stream, bool autoFree = true);
int GetTagsCount() const
{
return ( int ) tags.size();
}
const char* GetTagNameByIndex(int index) const
{
return tags[index]->GetTagName();
}
int GetKeysCount(const char* Tag) const;
const char* GetKeyNameByIndex(const char* Tag, int index) const;
const char* GetKeyAsString(const char* Tag, const char* Key,
const char* Default) const;
int GetKeyAsInt(const char* Tag, const char* Key,
const int Default) const;
float GetKeyAsFloat(const char* Tag, const char* Key,
const float Default) const;
bool GetKeyAsBool(const char* Tag, const char* Key,
const bool Default) const;
};
#endif

View File

@@ -0,0 +1,3 @@
plugin_LTLIBRARIES = INIImporter.la
INIImporter_la_LDFLAGS = -module -avoid-version -shared
INIImporter_la_SOURCES = INIImporter.cpp INIImporter.h

View File

@@ -0,0 +1 @@
ADD_GEMRB_PLUGIN (ITMImporter ITMImporter.cpp)

View File

@@ -0,0 +1,255 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#include "ITMImporter.h"
#include "win32def.h"
#include "EffectMgr.h"
#include "Interface.h"
ITMImporter::ITMImporter(void)
{
str = NULL;
autoFree = false;
}
ITMImporter::~ITMImporter(void)
{
if (autoFree) {
delete str;
}
str = NULL;
}
bool ITMImporter::Open(DataStream* stream, bool autoFree)
{
if (stream == NULL) {
return false;
}
if (this->autoFree) {
delete str;
}
str = stream;
this->autoFree = autoFree;
char Signature[8];
str->Read( Signature, 8 );
if (strncmp( Signature, "ITM V1 ", 8 ) == 0) {
version = 10;
} else if (strncmp( Signature, "ITM V1.1", 8 ) == 0) {
version = 11;
} else if (strncmp( Signature, "ITM V2.0", 8 ) == 0) {
version = 20;
} else {
printf( "[ITMImporter]: This file is not a valid ITM File\n" );
return false;
}
return true;
}
Item* ITMImporter::GetItem(Item *s)
{
unsigned int i;
ieByte k1,k2,k3,k4;
if( !s) {
return NULL;
}
str->ReadDword( &s->ItemName );
str->ReadDword( &s->ItemNameIdentified );
str->ReadResRef( s->ReplacementItem );
str->ReadDword( &s->Flags );
str->ReadWord( &s->ItemType );
str->ReadDword( &s->UsabilityBitmask );
str->Read( s->AnimationType,2 ); //intentionally not reading word!
for (i=0;i<2;i++) {
if (s->AnimationType[i]==' ') {
s->AnimationType[i]=0;
}
}
str->Read( &s->MinLevel, 1 );
str->Read( &s->unknown1, 1 );
str->Read( &s->MinStrength,1 );
str->Read( &s->unknown2, 1 );
str->Read( &s->MinStrengthBonus, 1 );
str->Read( &k1,1 );
str->Read( &s->MinIntelligence, 1 );
str->Read( &k2,1 );
str->Read( &s->MinDexterity, 1 );
str->Read( &k3,1 );
str->Read( &s->MinWisdom, 1 );
str->Read( &k4,1 );
s->KitUsability=(k1<<24) | (k2<<16) | (k3<<8) | k4; //bg2/iwd2 specific
str->Read( &s->MinConstitution, 1 );
str->Read( &s->WeaProf, 1 ); //bg2 specific
str->Read( &s->MinCharisma, 1 );
str->Read( &s->unknown3, 1 );
str->ReadDword( &s->Price );
str->ReadWord( &s->StackAmount );
str->ReadResRef( s->ItemIcon );
str->ReadWord( &s->LoreToID );
str->ReadResRef( s->GroundIcon );
str->ReadDword( &s->Weight );
str->ReadDword( &s->ItemDesc );
str->ReadDword( &s->ItemDescIdentified );
str->ReadResRef( s->DescriptionIcon );
str->ReadDword( &s->Enchantment );
str->ReadDword( &s->ExtHeaderOffset );
str->ReadWord( &s->ExtHeaderCount );
str->ReadDword( &s->FeatureBlockOffset );
str->ReadWord( &s->EquippingFeatureOffset );
str->ReadWord( &s->EquippingFeatureCount );
s->Dialog[0] = 0;
s->DialogName = 0;
s->WieldColor = 0xffff;
memset( s->unknown, 0, 26 );
//skipping header data for iwd2
if (version == ITM_VER_IWD2) {
str->Read( s->unknown, 16 );
}
//pst data
if (version == ITM_VER_PST) {
str->ReadResRef( s->Dialog );
str->ReadDword( &s->DialogName );
ieWord WieldColor;
str->ReadWord( &WieldColor );
if (s->AnimationType[0]) {
s->WieldColor = WieldColor;
}
str->Read( s->unknown, 26 );
} else {
//all non pst
s->DialogName = core->GetItemDialStr(s->Name);
core->GetItemDialRes(s->Name, s->Dialog);
}
s->ItemExcl=core->GetItemExcl(s->Name);
s->ext_headers = core->GetITMExt( s->ExtHeaderCount );
for (i = 0; i < s->ExtHeaderCount; i++) {
str->Seek( s->ExtHeaderOffset + i * 56, GEM_STREAM_START );
GetExtHeader( s, s->ext_headers + i );
}
//48 is the size of the feature block
s->equipping_features = core->GetFeatures( s->EquippingFeatureCount);
str->Seek( s->FeatureBlockOffset + 48*s->EquippingFeatureOffset,
GEM_STREAM_START );
for (i = 0; i < s->EquippingFeatureCount; i++) {
GetFeature(s->equipping_features+i);
}
if (!core->IsAvailable( IE_BAM_CLASS_ID )) {
printf( "[ITMImporter]: No BAM Importer Available.\n" );
return NULL;
}
return s;
}
void ITMImporter::GetExtHeader(Item *s, ITMExtHeader* eh)
{
ieByte tmpByte;
ieWord ProjectileType;
str->Read( &eh->AttackType,1 );
str->Read( &eh->IDReq,1 );
str->Read( &eh->Location,1 );
str->Read( &eh->unknown1,1 );
str->ReadResRef( eh->UseIcon );
str->Read( &eh->Target,1 );
str->Read( &tmpByte,1 );
if (!tmpByte) {
tmpByte = 1;
}
eh->TargetNumber = tmpByte;
str->ReadWord( &eh->Range );
str->ReadWord( &ProjectileType );
str->ReadWord( &eh->Speed );
str->ReadWord( &eh->THAC0Bonus );
str->ReadWord( &eh->DiceSides );
str->ReadWord( &eh->DiceThrown );
//if your compiler doesn't like this, then we need a ReadWordSigned
str->ReadWord( (ieWord *) &eh->DamageBonus );
str->ReadWord( &eh->DamageType );
str->ReadWord( &eh->FeatureCount );
str->ReadWord( &eh->FeatureOffset );
str->ReadWord( &eh->Charges );
str->ReadWord( &eh->ChargeDepletion );
str->ReadDword( &eh->RechargeFlags );
str->ReadWord( &eh->ProjectileAnimation );
//for some odd reasons 0 and 1 are the same
if (eh->ProjectileAnimation) {
eh->ProjectileAnimation--;
}
unsigned int i; //msvc6.0 can't cope with index variable scope
for (i = 0; i < 3; i++) {
str->ReadWord( &eh->MeleeAnimation[i] );
}
ieWord tmp;
i = 0;
str->ReadWord( &tmp ); //arrow
if (tmp) i|=PROJ_ARROW;
str->ReadWord( &tmp ); //xbow
if (tmp) i|=PROJ_BOLT;
str->ReadWord( &tmp ); //bullet
if (tmp) i|=PROJ_BULLET;
//this hack is required for Nordom's crossbow in PST
if (!i && (eh->AttackType==ITEM_AT_BOW) ) {
i|=PROJ_BOLT;
}
//this hack is required for the practicing arrows in BG1
if (!i && (eh->AttackType==ITEM_AT_PROJECTILE) ) {
//0->0
//1->1
//2->2
//3->4
i|=(1<<ProjectileType)>>1;
}
eh->ProjectileQualifier=i;
//48 is the size of the feature block
eh->features = core->GetFeatures(eh->FeatureCount);
str->Seek( s->FeatureBlockOffset + 48*eh->FeatureOffset, GEM_STREAM_START );
for (i = 0; i < eh->FeatureCount; i++) {
GetFeature(eh->features+i);
}
}
void ITMImporter::GetFeature(Effect *fx)
{
PluginHolder<EffectMgr> eM(IE_EFF_CLASS_ID);
eM->Open( str, false );
eM->GetEffect( fx );
}
#include "plugindef.h"
GEMRB_PLUGIN(0xD913A54, "ITM File Importer")
PLUGIN_CLASS(IE_ITM_CLASS_ID, ITMImporter)
END_PLUGIN()

View File

@@ -0,0 +1,51 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#ifndef ITMIMPORTER_H
#define ITMIMPORTER_H
#include "ItemMgr.h"
#include "ie_types.h"
#include "Item.h"
#define ITM_VER_BG 10
#define ITM_VER_PST 11
#define ITM_VER_IWD2 20
class ITMImporter : public ItemMgr {
private:
DataStream* str;
bool autoFree;
int version;
public:
ITMImporter(void);
~ITMImporter(void);
bool Open(DataStream* stream, bool autoFree = true);
Item* GetItem(Item *s);
private:
void GetExtHeader(Item *s, ITMExtHeader* eh);
void GetFeature(Effect *f);
};
#endif

View File

@@ -0,0 +1,3 @@
plugin_LTLIBRARIES = ITMImporter.la
ITMImporter_la_LDFLAGS = -module -avoid-version -shared
ITMImporter_la_SOURCES = ITMImporter.cpp ITMImporter.h

View File

@@ -0,0 +1 @@
ADD_GEMRB_PLUGIN (IWDOpcodes IWDOpcodes.cpp)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
plugin_LTLIBRARIES = IWDOpcodes.la
IWDOpcodes_la_LDFLAGS = -module -avoid-version -shared
IWDOpcodes_la_SOURCES = IWDOpcodes.cpp

View File

@@ -0,0 +1 @@
ADD_GEMRB_PLUGIN (KEYImporter KEYImporter.cpp Dictionary.cpp)

View File

@@ -0,0 +1,226 @@
/* GemRB - Infinity Engine Emulator
* Copyright (C) 2003 The GemRB Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#include "Dictionary.h"
#include "globals.h"
#include "win32def.h"
#include <ctype.h>
/////////////////////////////////////////////////////////////////////////////
// inlines
inline unsigned int Dictionary::MyHashKey(const char* key, unsigned int type) const
{
unsigned int nHash = type;
for (int i = 0; i < KEYSIZE && key[i]; i++) {
nHash = ( nHash << 5 ) + nHash + tolower( key[i] );
}
return nHash;
}
inline int Dictionary::GetCount() const
{
return m_nCount;
}
inline bool Dictionary::IsEmpty() const
{
return m_nCount == 0;
}
/////////////////////////////////////////////////////////////////////////////
// out of lines
Dictionary::Dictionary(int nBlockSize, int nHashTableSize)
{
assert( nBlockSize > 0 );
assert( nHashTableSize > 16 );
m_pHashTable = NULL;
m_nHashTableSize = nHashTableSize; // default size
m_nCount = 0;
m_pFreeList = NULL;
m_pBlocks = NULL;
m_nBlockSize = nBlockSize;
}
void Dictionary::InitHashTable(unsigned int nHashSize, bool bAllocNow)
//Used to force allocation of a hash table or to override the default
//hash table size of (which is fairly small)
{
assert( m_nCount == 0 );
assert( nHashSize > 16 );
if (m_pHashTable != NULL) {
// free hash table
free( m_pHashTable);
m_pHashTable = NULL;
}
if (bAllocNow) {
m_pHashTable = (Dictionary::MyAssoc **) malloc( sizeof( MyAssoc * ) * nHashSize );
memset( m_pHashTable, 0, sizeof( MyAssoc * ) * nHashSize );
}
m_nHashTableSize = nHashSize;
}
void Dictionary::RemoveAll()
{
//removed the part about freeing values/keys
//because the complete value/key pair is stored in the
//node which is freed in the memblocks
// free hash table
free( m_pHashTable );
m_pHashTable = NULL;
m_nCount = 0;
m_pFreeList = NULL;
// free memory blocks
MemBlock* p = m_pBlocks;
while (p != NULL) {
MemBlock* pNext = p->pNext;
free( p );
p = pNext;
}
m_pBlocks = NULL;
}
Dictionary::~Dictionary()
{
RemoveAll();
}
Dictionary::MyAssoc* Dictionary::NewAssoc()
{
if (m_pFreeList == NULL) {
// add another block
Dictionary::MemBlock* newBlock = ( Dictionary::MemBlock* ) malloc(m_nBlockSize * sizeof( Dictionary::MyAssoc ) + sizeof( Dictionary::MemBlock ));
assert( newBlock != NULL ); // we must have something
newBlock->pNext = m_pBlocks;
m_pBlocks = newBlock;
// chain them into free list
Dictionary::MyAssoc* pAssoc = ( Dictionary::MyAssoc* )
( newBlock + 1 );
for (int i = 0; i < m_nBlockSize; i++) {
pAssoc->pNext = m_pFreeList;
m_pFreeList = pAssoc++;
}
}
Dictionary::MyAssoc* pAssoc = m_pFreeList;
m_pFreeList = m_pFreeList->pNext;
m_nCount++;
assert( m_nCount > 0 ); // make sure we don't overflow
#ifdef _DEBUG
pAssoc->key[0] = 0;
pAssoc->value = 0xcccccccc;
#endif
return pAssoc;
}
void Dictionary::FreeAssoc(Dictionary::MyAssoc* pAssoc)
{
pAssoc->pNext = m_pFreeList;
m_pFreeList = pAssoc;
m_nCount--;
assert( m_nCount >= 0 ); // make sure we don't underflow
// if no more elements, cleanup completely
if (m_nCount == 0) {
RemoveAll();
}
}
Dictionary::MyAssoc* Dictionary::GetAssocAt(const ieResRef key,
unsigned int type, unsigned int& nHash) const
// find association (or return NULL)
{
nHash = MyHashKey( key, type ) % m_nHashTableSize;
if (m_pHashTable == NULL) {
return NULL;
}
// see if it exists
MyAssoc* pAssoc;
for (pAssoc = m_pHashTable[nHash];
pAssoc != NULL;
pAssoc = pAssoc->pNext) {
if (type == pAssoc->type) {
if (!strnicmp( pAssoc->key, key, KEYSIZE )) {
return pAssoc;
}
}
}
return NULL;
}
bool Dictionary::Lookup(const ieResRef key, unsigned int type,
unsigned int& rValue) const
{
unsigned int nHash;
MyAssoc* pAssoc = GetAssocAt( key, type, nHash );
if (pAssoc == NULL) {
return false;
} // not in map
rValue = pAssoc->value;
return true;
}
void Dictionary::RemoveAt(const ieResRef key, unsigned int type)
{
unsigned int nHash;
MyAssoc* pAssoc = GetAssocAt( key, type, nHash );
if (pAssoc != NULL) {
FreeAssoc(pAssoc);
}
}
void Dictionary::SetAt(const ieResRef key, unsigned int type, unsigned int value)
{
int i;
unsigned int nHash;
MyAssoc* pAssoc=GetAssocAt( key, type, nHash );
if (pAssoc == NULL) {
if (m_pHashTable == NULL)
InitHashTable( m_nHashTableSize );
// it doesn't exist, add a new Association
pAssoc = NewAssoc();
// put into hash table
pAssoc->pNext = m_pHashTable[nHash];
m_pHashTable[nHash] = pAssoc;
}
for(i=0;i<KEYSIZE && key[i];i++) {
pAssoc->key[i]=tolower(key[i]);
}
for(;i<KEYSIZE;i++) {
pAssoc->key[i]=0;
}
pAssoc->type = type;
pAssoc->value = value;
}

Some files were not shown because too many files have changed in this diff Show More