1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-21 20:35:17 +02:00

#370 add ADP4 audio support (Intel DVI ADPCM)

This commit is contained in:
XProger
2021-11-05 07:52:37 +03:00
parent f961161ff6
commit d9c1001fbd
8 changed files with 353 additions and 274 deletions

View File

@@ -40,8 +40,8 @@
#define USE_DIV_TABLE // TODO_3DO remove
#define CPU_BIG_ENDIAN
#define MAX_RAM_LVL (800 * 1024)
#define MAX_RAM_TEX (640 * 1024)
#define MAX_RAM_LVL (32 * 1024 * 30) // 38 for LEVEL10C! >_<
#define MAX_RAM_TEX (16 * 1024 * 44)
#define MAX_RAM_CEL (MAX_FACES * sizeof(CCB))
extern void* RAM_LVL;
@@ -115,9 +115,9 @@
// use IWRAM_CODE section that faster for matrix interpolation (GBA only)
#define IWRAM_MATRIX_LERP
// the maximum of active enemies
#define MAX_ENEMIES 3
// #define MAX_ENEMIES 3
#endif
#define MAX_ENEMIES 3
#ifdef __3DO__
// hide dead enemies after a while to reduce the number of polygons on the screen
#define HIDE_CORPSES (30*10) // 10 sec
@@ -406,7 +406,7 @@ extern int32 fps;
#define MAX_BOXES 1024
#define MAX_VERTICES (5*1024)
#define MAX_TEXTURES 1536
#define MAX_FACES 2048
#define MAX_FACES 1920
#define MAX_ROOM_LIST 16
#define MAX_PORTALS 16
#define MAX_CAUSTICS 32
@@ -851,14 +851,18 @@ struct StaticMesh {
AABBs cbox;
};
#define SI_MODE(x) (x & 3)
#define SI_COUNT(x) ((x >> 2) & 15)
#define SI_CAMERA(x) ((x >> 12) & 1)
#define SI_PITCH(x) ((x >> 13) & 1)
#define SI_GAIN(x) ((x >> 14) & 1)
struct SoundInfo
{
uint16 index;
uint16 volume;
uint16 chance;
struct {
uint16 mode:2, count:4, unused:6, camera:1, pitch:1, gain:1, :1;
} flags;
uint16 flags;
};
struct Anim {

View File

@@ -28,7 +28,6 @@ struct Game
set_seed_draw(osGetSystemTimeMS() * 7);
animTexFrame = 0;
dynSectorsCount = 0;
void* data = osLoadLevel(name);
loadLevel(data);
@@ -45,10 +44,6 @@ struct Game
gCurTrack = -1;
#ifdef ROM_READ
dynSectorsCount = 0;
#endif
readLevel((uint8*)data);
// prepare rooms
@@ -114,8 +109,18 @@ struct Game
drawInit();
#ifdef __3DO__
//players[0]->angle.y += ANGLE_180;
//players[0]->pos.x += 1024;
/*
if (gLevelID == 0)
{
players[0]->angle.y += ANGLE_180;
players[0]->pos.x += 1024;
}
if (gLevelID == 1)
{
players[0]->pos.z += 1024;
}
*/
#endif
}

View File

@@ -50,7 +50,7 @@ void* soundPlay(int16 id, const vec3i &pos)
int32 volume = b->volume - (phd_sqrt(dot(d, d)) << 2);
if (b->flags.gain) {
if (SI_GAIN(b->flags)) {
volume -= rand_draw() >> 2;
}
@@ -63,16 +63,16 @@ void* soundPlay(int16 id, const vec3i &pos)
int32 pitch = 128;
if (b->flags.pitch) {
if (SI_PITCH(b->flags)) {
pitch += ((rand_draw() * 13) >> 14) - 13;
}
int32 index = b->index;
if (b->flags.count > 1) {
index += (rand_draw() * b->flags.count) >> 15;
if (SI_COUNT(b->flags) > 1) {
index += (rand_draw() * SI_COUNT(b->flags)) >> 15;
}
return sndPlaySample(index, volume, pitch, b->flags.mode);
return sndPlaySample(index, volume, pitch, SI_MODE(b->flags));
}
void soundStop(int16 id)
@@ -84,7 +84,7 @@ void soundStop(int16 id)
const SoundInfo* b = level.soundsInfo + a;
for (int32 i = 0; i < b->flags.count; i++)
for (int32 i = 0; i < SI_COUNT(b->flags); i++)
{
sndStopSample(b->index + i);
}

View File

@@ -130,6 +130,10 @@ void readLevel_GBA(const uint8* data)
void readLevel(const uint8* data)
{
//#ifdef ROM_READ
dynSectorsCount = 0;
//#endif
readLevel_GBA(data);
}

View File

@@ -1,13 +1,3 @@
#
# This is the application startup script, and should contain your
# aliases, and anything else you need to prepare to run your title.
#
# After this script is run, the system will start $boot/LaunchMe
#
# The following command is intentionally left in. After performing
# your minmem testing, you can remove this command.
#
minmem
#minmem
# show CPU, DRAM, VRAM and DSP usage
#$c/sysload

View File

@@ -265,12 +265,11 @@ void* osLoadLevel(const char* name)
int main(int argc, char *argv[])
{
printf("OpenLara 3DO\n");
/*
MemInfo memInfoVRAM;
AvailMem(&memInfoVRAM, MEMTYPE_DMA);
printf("RAM: %d\n", memInfoVRAM.minfo_SysFree);
*/
AvailMem(&memInfoVRAM, MEMTYPE_DRAM);
printf("DRAM: %d\n", memInfoVRAM.minfo_SysFree);
AvailMem(&memInfoVRAM, MEMTYPE_VRAM);
printf("VRAM: %d\n", memInfoVRAM.minfo_SysFree);
uint32 lastFrame;
uint32 frame;
@@ -296,9 +295,11 @@ int main(int argc, char *argv[])
sndInit();
RAM_LVL = AllocMem(MAX_RAM_LVL, MEMTYPE_DMA | MEMTYPE_AUDIO);
RAM_TEX = AllocMem(MAX_RAM_TEX, MEMTYPE_VRAM | MEMTYPE_CEL);
RAM_CEL = AllocMem(MAX_RAM_CEL, MEMTYPE_CEL);
RAM_TEX = AllocMem(MAX_RAM_TEX, MEMTYPE_VRAM);
uint8* mem = (uint8*)AllocMem(MAX_RAM_LVL + MAX_RAM_CEL, MEMTYPE_DRAM);
RAM_LVL = mem;
RAM_CEL = mem + MAX_RAM_LVL;
if (!RAM_LVL) printf("RAM_LVL failed!\n");
if (!RAM_TEX) printf("RAM_TEX failed!\n");

View File

@@ -1,7 +1,6 @@
#include "common.h"
Item sndMixer;
Item testSample;
struct Channel
{
@@ -35,6 +34,8 @@ void sndInit()
sndMixer = LoadInstrument("mixer4x2.dsp", 0, 100);
LoadInstrument("decodeadpcm.dsp", 0, 100);
char* LGainName = "LeftGain0";
char* RGainName = "RightGain0";
char* InputName = "Input0";
@@ -51,13 +52,13 @@ void sndInit()
TweakKnob(channels[i].gainL, 255 << 6);
TweakKnob(channels[i].gainR, 255 << 6);
channels[i].sample = LoadInstrument("varmono8.dsp", 0, 100);
channels[i].sample = LoadInstrument("adpcmvarmono.dsp", 0, 100);
channels[i].frequency = GrabKnob(channels[i].sample, "Frequency");
channels[i].amplitude = GrabKnob(channels[i].sample, "Amplitude");
ConnectInstruments(channels[i].sample, "Output", sndMixer, InputName);
channels[i].setVolume(0x7FFF);
channels[i].setPitch(0x8000 / 10);
channels[i].setPitch(0x2000);
}
StartInstrument(sndMixer, NULL);
@@ -69,14 +70,13 @@ void sndInitSamples()
{
uint8* data = (uint8*)level.soundData + level.soundOffsets[i];
uint32 size;
memcpy(&size, data + 4, sizeof(size));
size += 8;
samples[i] = CreateSampleVA(
AF_TAG_IMAGE_ADDRESS, data,
AF_TAG_IMAGE_LENGTH, size,
AF_TAG_LEAVE_IN_PLACE, TRUE,
AF_TAG_FRAMES, *(uint32*)data,
AF_TAG_ADDRESS, (uint8*)data + 4,
AF_TAG_CHANNELS, 1,
AF_TAG_WIDTH, 2,
AF_TAG_COMPRESSIONTYPE, ID_ADP4,
AF_TAG_COMPRESSIONRATIO, 4,
TAG_END
);
}
@@ -93,13 +93,12 @@ void* sndPlaySample(int32 index, int32 volume, int32 pitch, int32 mode)
DetachSample(channels[idx].attach);
}
if (samples[index] < 0) {
printf("fuck!\n");
}
channels[idx].attach = AttachSample(channels[idx].sample, samples[index], NULL);
StartInstrument(channels[idx].sample, NULL);
channels[idx].setVolume(0x7FFF * volume >> SND_VOL_SHIFT);
channels[idx].setPitch(0x2000 * pitch >> SND_PITCH_SHIFT);
return (void*)channels[idx].sample;
}

View File

@@ -635,6 +635,34 @@ void fixTexCoord(uint32 uv0, uint32 &uv1)
#define MAX_ITEMS 240
#define MAX_NODES 32
#define CLIP(x,lo,hi) \
if ( x < lo ) \
{ \
x = lo; \
} \
else if ( x > hi ) \
{ \
x = hi; \
}
// ADPCM.h - Common ADPCM definitions
static short gIndexDeltas[16] = {
-1,-1,-1,-1, 2, 4, 6, 8,
-1,-1,-1,-1, 2, 4, 6, 8
};
/* DVI ADPCM step table */
static short gStepSizes[89] = {
7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19,
21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55,
60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157,
173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449,
494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282,
1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660,
4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442,
11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
32767 };
#pragma pack(1)
struct LevelPC
{
@@ -1411,16 +1439,21 @@ struct LevelPC
uint16 index;
uint16 volume;
uint16 chance;
uint8 flagsA;
uint8 flagsB;
union {
struct {
uint16 mode:2, count:4, unused:6, camera:1, pitch:1, gain:1, :1;
};
uint16 value;
} flags;
void write(FileStream &f) const
{
f.write(index);
f.write(volume);
f.write(chance);
f.write(flagsA);
f.write(flagsB);
f.write(flags.value);
}
};
@@ -2721,6 +2754,7 @@ struct LevelPC
int32 w;
int32 h;
uint16 flip;
bool mips;
void write(FileStream &f) const
{
@@ -2806,7 +2840,7 @@ struct LevelPC
//
}
void convertTextures3DO(const char* fileName)
int32 convertTextures3DO(const char* fileName)
{
#define PRE1_WOFFSET_PREFETCH 2
#define PRE0_VCNT_PREFETCH 1
@@ -2824,7 +2858,7 @@ struct LevelPC
FileStream f(fileName, true);
if (!f.isValid()) return;
if (!f.isValid()) return 0;
f.bigEndian = true;
@@ -2923,6 +2957,7 @@ struct LevelPC
int32 y1 = MAX(MAX(objectTexture->y0, objectTexture->y1), objectTexture->y2);
textures3DO[i].flip = 0;
textures3DO[i].mips = false;
if (objectTexture->isQuad)
{
@@ -2965,72 +3000,6 @@ struct LevelPC
}
}
#if 0
if (!objectTexture->isQuad) // triangle->quad! 8)
{
if (1) { // test pattern
uint32* src = bitmap32;
for (int32 y = 0; y < h; y++)
{
for (int32 x = 0; x < w; x++)
{
*src++ += (x % 2) ? 0x000A0A0A : 0x00000000;
}
}
}
uint32* src = bitmap32;
uint32* dst = bitmap32_tmp;
for (int32 y = 0; y < h; y++)
{
for (int32 x = 0; x < w; x++)
{
objectTexture->x1 - objectTexture->x0
float ty = float(y) / float(y);
/*
int32 px = 0;
if (textures3DO[i].flip & TEX_FLIP_X)
{
if (textures3DO[i].flip & TEX_FLIP_Y)
{
px = int32(x * float(float(y) / float(h)));
} else {
px = int32(x * float(1.0f - float(y) / float(h)));
}
} else {
if (textures3DO[i].flip & TEX_FLIP_Y)
{
px = int32((w - x - 1) * float(float(y) / float(h)));
} else {
px = int32((w - x - 1) * float(1.0f - float(y) / float(h)));
}
}
*dst++ = src[px];
*/
}
src += w;
}
swap(bitmap32, bitmap32_tmp);
{
char buf[128];
sprintf(buf, "tex%d.bmp", i);
saveBitmap(buf, (uint8*)bitmap32, w, h, 32);
}
}
#endif
{ // copy tile to 32-bit image and calculate average tile color
uint8* src = textures3DO[i].src;
@@ -3044,8 +3013,6 @@ struct LevelPC
{
for (int32 x = 0; x < w; x++)
{
uint32 index;
if (!objectTexture->isQuad)
{
float u = float(x) / float(w - 1);
@@ -3104,6 +3071,14 @@ struct LevelPC
hp /= 2;
}
if (wp > 64) {
wp = 64;
}
if (hp > 64) {
hp = 64;
}
ASSERT(wp != 0 && hp != 0);
if (w != wp || h != hp)
@@ -3163,40 +3138,7 @@ struct LevelPC
}
}
#if 0
int32 reindex[16];
for (int32 j = 0; j < 16; j++)
reindex[j] = j;
for (int32 j = 0; j < 16; j++)
{
for (int32 k = j + 1; k < 16; k++)
{
if (plut.colors[reindex[j]] > plut.colors[reindex[k]]) {
swap(reindex[j], reindex[k]);
}
}
}
PLUT plut_opt;
for (int32 j = 0; j < 16; j++)
{
plut_opt.colors[j] = plut.colors[reindex[j]];
}
int32 reindex_back[16];
for (int32 j = 0; j < 16; j++)
reindex_back[reindex[j]] = j;
for (int32 j = 0; j < w * h; j++)
{
bitmap8[j] = reindex_back[bitmap8[j]];
}
textures3DO[i].plut = addPalette(plut_opt);
#else
textures3DO[i].plut = addPalette(plut);
#endif
liq_result_destroy(res);
liq_image_destroy(image);
@@ -3237,81 +3179,6 @@ struct LevelPC
f.write(bitmap8_tmp, w * h / 2);
}
}
#if 0
{
LevelPC::ObjectTexture* tmp = new LevelPC::ObjectTexture[objectTexturesCount + 256];
memcpy(tmp, objectTextures, sizeof(LevelPC::ObjectTexture) * objectTexturesCount);
for (int32 i = 0; i < 256; i++)
{
int32 plut = i / 16;
int32 index = i % 16;
Texture3DO* tex = textures3DO + objectTexturesCount + i;
tex->flip = 0;
tex->w = 32;
tex->h = 32;
tex->wShift = shiftPow2(tex->w);
tex->hShift = shiftPow2(tex->h);
tex->color = PLUTs[plut].colors[index];
int32 rowBytes = (((tex->w * 4) + 31) >> 5) << 2;
if (rowBytes < 8) {
rowBytes = 8;
}
int32 rowWOFFSET = (rowBytes >> 2) - PRE1_WOFFSET_PREFETCH;
tex->pre0 = ((tex->h - PRE0_VCNT_PREFETCH) << PRE0_VCNT_SHIFT) | PRE0_BPP_4;
tex->pre1 = ((tex->w - PRE1_TLHPCNT_PREFETCH) << PRE1_TLHPCNT_SHIFT) | PRE1_TLLSB_PDC0 | (rowWOFFSET << PRE1_WOFFSET8_SHIFT);
tex->plut = sizeof(PLUT) * plut;
tex->data = f.getPos();
int32 w = tex->w;
for (int32 j = 0; j < tex->w * tex->h; j++)
bitmap8[j] = index;
if (rowBytes * 2 != tex->w) // adjust row pitch
{
uint8* src = bitmap8;
uint8* dst = bitmap8_tmp;
memset(dst, 0, (rowBytes * 2) * tex->h);
for (int32 y = 0; y < tex->h; y++) {
memcpy(dst, src, tex->w);
dst += rowBytes * 2;
src += tex->w;
}
swap(bitmap8, bitmap8_tmp);
w = rowBytes * 2;
}
{ // encode to 4-bit image
uint8* src = bitmap8;
uint8* dst = bitmap8_tmp;
for (int32 y = 0; y < tex->h; y++)
{
for (int32 x = 0; x < w/2; x++, src += 2)
{
*dst++ = (src[0] << 4) | src[1];
}
}
// write image
f.write(bitmap8_tmp, w * tex->h / 2);
}
}
delete[] objectTextures;
objectTextures = tmp;
objectTexturesCount += 256;
}
#endif
// fix PLUT offsets
int32 plutsOffset = f.getPos();
@@ -3345,6 +3212,8 @@ struct LevelPC
}
f.write((uint16*)PLUTs, sizeof(PLUT) / 2 * plutsCount);
int32 texFileSize = f.getPos();
// write palette offset at the file start
f.setPos(0);
f.write(paletteOffset);
@@ -3353,13 +3222,230 @@ struct LevelPC
delete[] bitmap32_tmp;
delete[] bitmap8;
delete[] bitmap8_tmp;
return texFileSize;
}
// Intel DVI ADPCM (ADP4) encoder based on the original SoundHack code https://github.com/tomerbe/SoundHack
long lastEstimateL, stepSizeL, stepIndexL;
long lastEstimateR, stepSizeR, stepIndexR;
char EncodeDelta( long stepSize, long delta )
{
char encodedSample = 0;
if ( delta < 0L )
{
encodedSample = 8;
delta = -delta;
}
if ( delta >= stepSize )
{
encodedSample |= 4;
delta -= stepSize;
}
stepSize = stepSize >> 1;
if ( delta >= stepSize )
{
encodedSample |= 2;
delta -= stepSize;
}
stepSize = stepSize >> 1;
if ( delta >= stepSize ) encodedSample |= 1;
return ( encodedSample );
}
long DecodeDelta( long stepSize, char encodedSample )
{
long delta = 0;
if( encodedSample & 4) delta = stepSize;
if( encodedSample & 2) delta += (stepSize >> 1);
if( encodedSample & 1) delta += (stepSize >> 2);
delta += (stepSize >> 3);
if (encodedSample & 8) delta = -delta;
return( delta );
}
char ADDVIEncode(short shortOne, short shortTwo, long channels)
{
long delta;
unsigned char encodedSample, outputByte;
outputByte = 0;
/* First sample or left sample to be packed in first nibble */
/* calculate delta */
delta = shortOne - lastEstimateL;
CLIP(delta, -32768L, 32767L);
/* encode delta relative to the current stepsize */
encodedSample = EncodeDelta(stepSizeL, delta);
/* pack first nibble */
outputByte = 0x00F0 & (encodedSample<<4);
/* decode ADPCM code value to reproduce delta and generate an estimated InputSample */
lastEstimateL += DecodeDelta(stepSizeL, encodedSample);
CLIP(lastEstimateL, -32768L, 32767L);
/* adapt stepsize */
stepIndexL += gIndexDeltas[encodedSample];
CLIP(stepIndexL, 0, 88);
stepSizeL = gStepSizes[stepIndexL];
if(channels == 2L)
{
/* calculate delta for second sample */
delta = shortTwo - lastEstimateR;
CLIP(delta, -32768L, 32767L);
/* encode delta relative to the current stepsize */
encodedSample = EncodeDelta(stepSizeR, delta);
/* pack second nibble */
outputByte |= 0x000F & encodedSample;
/* decode ADPCM code value to reproduce delta and generate an estimated InputSample */
lastEstimateR += DecodeDelta(stepSizeR, encodedSample);
CLIP(lastEstimateR, -32768L, 32767L);
/* adapt stepsize */
stepIndexR += gIndexDeltas[encodedSample];
CLIP(stepIndexR, 0, 88);
stepSizeR = gStepSizes[stepIndexR];
}
else
{
/* calculate delta for second sample */
delta = shortTwo - lastEstimateL;
CLIP(delta, -32768L, 32767L);
/* encode delta relative to the current stepsize */
encodedSample = EncodeDelta(stepSizeL, delta);
/* pack second nibble */
outputByte |= 0x000F & encodedSample;
/* decode ADPCM code value to reproduce delta and generate an estimated InputSample */
lastEstimateL += DecodeDelta(stepSizeL, encodedSample);
CLIP(lastEstimateL, -32768L, 32767L);
/* adapt stepsize */
stepIndexL += gIndexDeltas[encodedSample];
CLIP(stepIndexL, 0, 88);
stepSizeL = gStepSizes[stepIndexL];
}
return(outputByte);
}
void BlockADDVIEncode(uint8 *buffer, short *blockL, short *blockR, long numSamples, long channels)
{
short shortOne, shortTwo;
long i, j;
lastEstimateL = lastEstimateR = 0L;
stepSizeL = stepSizeR = 7L;
stepIndexL = stepIndexR = 0L;
for(i = j = 0; i < numSamples; i += 2, j++)
{
if(channels == 2)
{
shortOne = (blockL[j]);
shortTwo = (blockR[j]);
}
else
{
shortOne = (blockL[i]);
shortTwo = (blockL[i+1]);
}
buffer[j] = ADDVIEncode(shortOne, shortTwo, channels);
}
}
void getSample(const char* base, const char* prefix, int32 id, int32 sub, uint8* buffer, int32 &size)
{
size = 0;
char path[256];
sprintf(path, "%s\\%s%03d_%d.wav", base, prefix, id, sub);
FILE* f = fopen(path, "rb");
if (!f)
{
if (prefix[0] == '_') // try to open file without the prefix
{
sprintf(path, "%s\\%s%03d_%d.wav", base, "", id, sub);
f = fopen(path, "rb");
if (!f)
{
printf("%s not found!\n", path);
return;
}
} else {
printf("%s not found!\n", path);
return;
}
}
fseek(f, 12, SEEK_SET); // skip RIFF header
struct {
unsigned int id;
unsigned int size;
} chunk;
while (1)
{
fread(&chunk, sizeof(chunk), 1, f);
if (chunk.id == 0x61746164) // data
{
int numSamples = chunk.size / (1 * sizeof(short));
size = numSamples / 2; // 4 bits per sample
short* data = new short[chunk.size / sizeof(short)];
fread(data, 1, chunk.size, f);
BlockADDVIEncode(buffer, data, NULL, numSamples, 1); // mono block
delete[] data;
break;
} else {
fseek(f, chunk.size, SEEK_CUR);
}
}
fclose(f);
}
bool getSoundID(int32 index, int32 &id, int32 &sub)
{
for (int32 i = 0; i < 256; i++)
{
SoundInfo &s = soundInfo[soundMap[i]];
if (s.index <= index && s.index + s.flags.count > index)
{
id = i;
sub = index - s.index;
return true;
}
}
return false;
}
void convert3DO(const char* name)
{
char path[256];
sprintf(path, "../../3do/CD/data/%s.TEX", name);
convertTextures3DO(path);
int32 texFileSize = convertTextures3DO(path);
sprintf(path, "../../3do/CD/data/%s.3DO", name);
@@ -3502,6 +3588,8 @@ struct LevelPC
}
}
textures3DO[q.flags & FACE_TEXTURE].mips = true;
Quad3DO comp;
comp.indices[0] = q.indices[0];
comp.indices[1] = q.indices[1];
@@ -3520,6 +3608,8 @@ struct LevelPC
t.indices[1] = addRoomVertex(room->vertices[t.indices[1]]);
t.indices[2] = addRoomVertex(room->vertices[t.indices[2]]);
textures3DO[t.flags & FACE_TEXTURE].mips = true;
t.write3DO(f);
}
@@ -3528,17 +3618,6 @@ struct LevelPC
for (int32 i = 0; i < roomVerticesCount; i++)
{
roomVertices[i].write(f);
/*
// write vertex coords in fixed16:16 format
int8 x = (roomVertices[i].x);// << 10);
int8 y = (roomVertices[i].y);// << 8);
int8 z = (roomVertices[i].z);// << 10);
uint8 g = (roomVertices[i].g);
f.write(x);
f.write(y);
f.write(z);
f.write(g);*/
}
info.sprites = f.align4();
@@ -3877,6 +3956,16 @@ struct LevelPC
for (int32 i = 0; i < objectTexturesCount; i++)
{
textures3DO[i].write(f);
if (textures3DO[i].mips) {
texFileSize += (textures3DO[i].w / 2) * (textures3DO[i].h / 2) / 2;
}
}
static int32 maxTexFileSize = 0;
if (texFileSize > maxTexFileSize) {
maxTexFileSize = texFileSize;
printf("texSize: %d\n", texFileSize);
}
header.spriteTextures = f.align4();
@@ -3974,39 +4063,26 @@ struct LevelPC
uint8* soundBuf = new uint8[2 * 1024 * 1024];
bool isHome = strcmp(name, "GYM") == 0;
for (int32 i = 0; i < soundOffsetsCount; i++)
{
{ // save wav to the temporary file
uint8* data = soundData + soundOffsets[i];
int32 size = *(int32*)(data + 4) + 8;
soundOffsets[i] = f.align4() - header.soundData;
FILE* f = fopen("tmp.wav", "wb");
fwrite(data, 1, size, f);
fclose(f);
int32 id, sub, size;
if (getSoundID(i, id, sub))
{
getSample("C:\\Projects\\OpenLara\\src\\platform\\gba\\packer\\sounds\\conv_3do", isHome ? "_" : "", id, sub, soundBuf, size);
} else {
ASSERT(false);
}
launchApp("C:\\Program Files\\ffmpeg\\ffmpeg.exe -y -i tmp.wav -ac 1 -ar 4000 -acodec pcm_s8 tmp.aiff");
int32 numSamples = size * 2;
f.write(numSamples);
int32 soundSize;
{ // read converted aiff
FILE* f = fopen("tmp.aiff", "rb");
fseek(f, 0, SEEK_END);
soundSize = ftell(f);
fseek(f, 0, SEEK_SET);
fread(soundBuf, 1, soundSize, f);
fclose(f);
if (size) {
f.write(soundBuf, size);
}
// update sound sample offset
soundOffsets[i] = f.align4() - header.soundData + 2;
uint16 zero = 0;
f.write(zero);
//ASSERT(soundOffsets[i] % 16 == 0);
// write aiff sound data
f.write(soundBuf, soundSize);
}
delete[] soundBuf;