mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-22 04:43:08 +02:00
#370 add ADP4 audio support (Intel DVI ADPCM)
This commit is contained in:
@@ -40,8 +40,8 @@
|
|||||||
#define USE_DIV_TABLE // TODO_3DO remove
|
#define USE_DIV_TABLE // TODO_3DO remove
|
||||||
#define CPU_BIG_ENDIAN
|
#define CPU_BIG_ENDIAN
|
||||||
|
|
||||||
#define MAX_RAM_LVL (800 * 1024)
|
#define MAX_RAM_LVL (32 * 1024 * 30) // 38 for LEVEL10C! >_<
|
||||||
#define MAX_RAM_TEX (640 * 1024)
|
#define MAX_RAM_TEX (16 * 1024 * 44)
|
||||||
#define MAX_RAM_CEL (MAX_FACES * sizeof(CCB))
|
#define MAX_RAM_CEL (MAX_FACES * sizeof(CCB))
|
||||||
|
|
||||||
extern void* RAM_LVL;
|
extern void* RAM_LVL;
|
||||||
@@ -115,9 +115,9 @@
|
|||||||
// use IWRAM_CODE section that faster for matrix interpolation (GBA only)
|
// use IWRAM_CODE section that faster for matrix interpolation (GBA only)
|
||||||
#define IWRAM_MATRIX_LERP
|
#define IWRAM_MATRIX_LERP
|
||||||
// the maximum of active enemies
|
// the maximum of active enemies
|
||||||
#define MAX_ENEMIES 3
|
// #define MAX_ENEMIES 3
|
||||||
#endif
|
#endif
|
||||||
#define MAX_ENEMIES 3
|
|
||||||
#ifdef __3DO__
|
#ifdef __3DO__
|
||||||
// hide dead enemies after a while to reduce the number of polygons on the screen
|
// hide dead enemies after a while to reduce the number of polygons on the screen
|
||||||
#define HIDE_CORPSES (30*10) // 10 sec
|
#define HIDE_CORPSES (30*10) // 10 sec
|
||||||
@@ -406,7 +406,7 @@ extern int32 fps;
|
|||||||
#define MAX_BOXES 1024
|
#define MAX_BOXES 1024
|
||||||
#define MAX_VERTICES (5*1024)
|
#define MAX_VERTICES (5*1024)
|
||||||
#define MAX_TEXTURES 1536
|
#define MAX_TEXTURES 1536
|
||||||
#define MAX_FACES 2048
|
#define MAX_FACES 1920
|
||||||
#define MAX_ROOM_LIST 16
|
#define MAX_ROOM_LIST 16
|
||||||
#define MAX_PORTALS 16
|
#define MAX_PORTALS 16
|
||||||
#define MAX_CAUSTICS 32
|
#define MAX_CAUSTICS 32
|
||||||
@@ -851,14 +851,18 @@ struct StaticMesh {
|
|||||||
AABBs cbox;
|
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
|
struct SoundInfo
|
||||||
{
|
{
|
||||||
uint16 index;
|
uint16 index;
|
||||||
uint16 volume;
|
uint16 volume;
|
||||||
uint16 chance;
|
uint16 chance;
|
||||||
struct {
|
uint16 flags;
|
||||||
uint16 mode:2, count:4, unused:6, camera:1, pitch:1, gain:1, :1;
|
|
||||||
} flags;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Anim {
|
struct Anim {
|
||||||
|
@@ -28,7 +28,6 @@ struct Game
|
|||||||
set_seed_draw(osGetSystemTimeMS() * 7);
|
set_seed_draw(osGetSystemTimeMS() * 7);
|
||||||
|
|
||||||
animTexFrame = 0;
|
animTexFrame = 0;
|
||||||
dynSectorsCount = 0;
|
|
||||||
|
|
||||||
void* data = osLoadLevel(name);
|
void* data = osLoadLevel(name);
|
||||||
loadLevel(data);
|
loadLevel(data);
|
||||||
@@ -45,10 +44,6 @@ struct Game
|
|||||||
|
|
||||||
gCurTrack = -1;
|
gCurTrack = -1;
|
||||||
|
|
||||||
#ifdef ROM_READ
|
|
||||||
dynSectorsCount = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
readLevel((uint8*)data);
|
readLevel((uint8*)data);
|
||||||
|
|
||||||
// prepare rooms
|
// prepare rooms
|
||||||
@@ -114,8 +109,18 @@ struct Game
|
|||||||
drawInit();
|
drawInit();
|
||||||
|
|
||||||
#ifdef __3DO__
|
#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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -50,7 +50,7 @@ void* soundPlay(int16 id, const vec3i &pos)
|
|||||||
|
|
||||||
int32 volume = b->volume - (phd_sqrt(dot(d, d)) << 2);
|
int32 volume = b->volume - (phd_sqrt(dot(d, d)) << 2);
|
||||||
|
|
||||||
if (b->flags.gain) {
|
if (SI_GAIN(b->flags)) {
|
||||||
volume -= rand_draw() >> 2;
|
volume -= rand_draw() >> 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,16 +63,16 @@ void* soundPlay(int16 id, const vec3i &pos)
|
|||||||
|
|
||||||
int32 pitch = 128;
|
int32 pitch = 128;
|
||||||
|
|
||||||
if (b->flags.pitch) {
|
if (SI_PITCH(b->flags)) {
|
||||||
pitch += ((rand_draw() * 13) >> 14) - 13;
|
pitch += ((rand_draw() * 13) >> 14) - 13;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 index = b->index;
|
int32 index = b->index;
|
||||||
if (b->flags.count > 1) {
|
if (SI_COUNT(b->flags) > 1) {
|
||||||
index += (rand_draw() * b->flags.count) >> 15;
|
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)
|
void soundStop(int16 id)
|
||||||
@@ -84,7 +84,7 @@ void soundStop(int16 id)
|
|||||||
|
|
||||||
const SoundInfo* b = level.soundsInfo + a;
|
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);
|
sndStopSample(b->index + i);
|
||||||
}
|
}
|
||||||
|
@@ -130,6 +130,10 @@ void readLevel_GBA(const uint8* data)
|
|||||||
|
|
||||||
void readLevel(const uint8* data)
|
void readLevel(const uint8* data)
|
||||||
{
|
{
|
||||||
|
//#ifdef ROM_READ
|
||||||
|
dynSectorsCount = 0;
|
||||||
|
//#endif
|
||||||
|
|
||||||
readLevel_GBA(data);
|
readLevel_GBA(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,13 +1,3 @@
|
|||||||
#
|
#minmem
|
||||||
# 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
|
|
||||||
|
|
||||||
# show CPU, DRAM, VRAM and DSP usage
|
# show CPU, DRAM, VRAM and DSP usage
|
||||||
#$c/sysload
|
#$c/sysload
|
||||||
|
@@ -265,12 +265,11 @@ void* osLoadLevel(const char* name)
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
printf("OpenLara 3DO\n");
|
printf("OpenLara 3DO\n");
|
||||||
|
|
||||||
/*
|
|
||||||
MemInfo memInfoVRAM;
|
MemInfo memInfoVRAM;
|
||||||
AvailMem(&memInfoVRAM, MEMTYPE_DMA);
|
AvailMem(&memInfoVRAM, MEMTYPE_DRAM);
|
||||||
printf("RAM: %d\n", memInfoVRAM.minfo_SysFree);
|
printf("DRAM: %d\n", memInfoVRAM.minfo_SysFree);
|
||||||
*/
|
AvailMem(&memInfoVRAM, MEMTYPE_VRAM);
|
||||||
|
printf("VRAM: %d\n", memInfoVRAM.minfo_SysFree);
|
||||||
|
|
||||||
uint32 lastFrame;
|
uint32 lastFrame;
|
||||||
uint32 frame;
|
uint32 frame;
|
||||||
@@ -296,9 +295,11 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
sndInit();
|
sndInit();
|
||||||
|
|
||||||
RAM_LVL = AllocMem(MAX_RAM_LVL, MEMTYPE_DMA | MEMTYPE_AUDIO);
|
RAM_TEX = AllocMem(MAX_RAM_TEX, MEMTYPE_VRAM);
|
||||||
RAM_TEX = AllocMem(MAX_RAM_TEX, MEMTYPE_VRAM | MEMTYPE_CEL);
|
|
||||||
RAM_CEL = AllocMem(MAX_RAM_CEL, MEMTYPE_CEL);
|
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_LVL) printf("RAM_LVL failed!\n");
|
||||||
if (!RAM_TEX) printf("RAM_TEX failed!\n");
|
if (!RAM_TEX) printf("RAM_TEX failed!\n");
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
Item sndMixer;
|
Item sndMixer;
|
||||||
Item testSample;
|
|
||||||
|
|
||||||
struct Channel
|
struct Channel
|
||||||
{
|
{
|
||||||
@@ -35,6 +34,8 @@ void sndInit()
|
|||||||
|
|
||||||
sndMixer = LoadInstrument("mixer4x2.dsp", 0, 100);
|
sndMixer = LoadInstrument("mixer4x2.dsp", 0, 100);
|
||||||
|
|
||||||
|
LoadInstrument("decodeadpcm.dsp", 0, 100);
|
||||||
|
|
||||||
char* LGainName = "LeftGain0";
|
char* LGainName = "LeftGain0";
|
||||||
char* RGainName = "RightGain0";
|
char* RGainName = "RightGain0";
|
||||||
char* InputName = "Input0";
|
char* InputName = "Input0";
|
||||||
@@ -51,13 +52,13 @@ void sndInit()
|
|||||||
TweakKnob(channels[i].gainL, 255 << 6);
|
TweakKnob(channels[i].gainL, 255 << 6);
|
||||||
TweakKnob(channels[i].gainR, 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].frequency = GrabKnob(channels[i].sample, "Frequency");
|
||||||
channels[i].amplitude = GrabKnob(channels[i].sample, "Amplitude");
|
channels[i].amplitude = GrabKnob(channels[i].sample, "Amplitude");
|
||||||
ConnectInstruments(channels[i].sample, "Output", sndMixer, InputName);
|
ConnectInstruments(channels[i].sample, "Output", sndMixer, InputName);
|
||||||
|
|
||||||
channels[i].setVolume(0x7FFF);
|
channels[i].setVolume(0x7FFF);
|
||||||
channels[i].setPitch(0x8000 / 10);
|
channels[i].setPitch(0x2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
StartInstrument(sndMixer, NULL);
|
StartInstrument(sndMixer, NULL);
|
||||||
@@ -69,14 +70,13 @@ void sndInitSamples()
|
|||||||
{
|
{
|
||||||
uint8* data = (uint8*)level.soundData + level.soundOffsets[i];
|
uint8* data = (uint8*)level.soundData + level.soundOffsets[i];
|
||||||
|
|
||||||
uint32 size;
|
|
||||||
memcpy(&size, data + 4, sizeof(size));
|
|
||||||
size += 8;
|
|
||||||
|
|
||||||
samples[i] = CreateSampleVA(
|
samples[i] = CreateSampleVA(
|
||||||
AF_TAG_IMAGE_ADDRESS, data,
|
AF_TAG_FRAMES, *(uint32*)data,
|
||||||
AF_TAG_IMAGE_LENGTH, size,
|
AF_TAG_ADDRESS, (uint8*)data + 4,
|
||||||
AF_TAG_LEAVE_IN_PLACE, TRUE,
|
AF_TAG_CHANNELS, 1,
|
||||||
|
AF_TAG_WIDTH, 2,
|
||||||
|
AF_TAG_COMPRESSIONTYPE, ID_ADP4,
|
||||||
|
AF_TAG_COMPRESSIONRATIO, 4,
|
||||||
TAG_END
|
TAG_END
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -93,13 +93,12 @@ void* sndPlaySample(int32 index, int32 volume, int32 pitch, int32 mode)
|
|||||||
DetachSample(channels[idx].attach);
|
DetachSample(channels[idx].attach);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (samples[index] < 0) {
|
|
||||||
printf("fuck!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
channels[idx].attach = AttachSample(channels[idx].sample, samples[index], NULL);
|
channels[idx].attach = AttachSample(channels[idx].sample, samples[index], NULL);
|
||||||
StartInstrument(channels[idx].sample, 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;
|
return (void*)channels[idx].sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -635,6 +635,34 @@ void fixTexCoord(uint32 uv0, uint32 &uv1)
|
|||||||
#define MAX_ITEMS 240
|
#define MAX_ITEMS 240
|
||||||
#define MAX_NODES 32
|
#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)
|
#pragma pack(1)
|
||||||
struct LevelPC
|
struct LevelPC
|
||||||
{
|
{
|
||||||
@@ -1411,16 +1439,21 @@ struct LevelPC
|
|||||||
uint16 index;
|
uint16 index;
|
||||||
uint16 volume;
|
uint16 volume;
|
||||||
uint16 chance;
|
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
|
void write(FileStream &f) const
|
||||||
{
|
{
|
||||||
f.write(index);
|
f.write(index);
|
||||||
f.write(volume);
|
f.write(volume);
|
||||||
f.write(chance);
|
f.write(chance);
|
||||||
f.write(flagsA);
|
f.write(flags.value);
|
||||||
f.write(flagsB);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2721,6 +2754,7 @@ struct LevelPC
|
|||||||
int32 w;
|
int32 w;
|
||||||
int32 h;
|
int32 h;
|
||||||
uint16 flip;
|
uint16 flip;
|
||||||
|
bool mips;
|
||||||
|
|
||||||
void write(FileStream &f) const
|
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 PRE1_WOFFSET_PREFETCH 2
|
||||||
#define PRE0_VCNT_PREFETCH 1
|
#define PRE0_VCNT_PREFETCH 1
|
||||||
@@ -2824,7 +2858,7 @@ struct LevelPC
|
|||||||
|
|
||||||
FileStream f(fileName, true);
|
FileStream f(fileName, true);
|
||||||
|
|
||||||
if (!f.isValid()) return;
|
if (!f.isValid()) return 0;
|
||||||
|
|
||||||
f.bigEndian = true;
|
f.bigEndian = true;
|
||||||
|
|
||||||
@@ -2923,6 +2957,7 @@ struct LevelPC
|
|||||||
int32 y1 = MAX(MAX(objectTexture->y0, objectTexture->y1), objectTexture->y2);
|
int32 y1 = MAX(MAX(objectTexture->y0, objectTexture->y1), objectTexture->y2);
|
||||||
|
|
||||||
textures3DO[i].flip = 0;
|
textures3DO[i].flip = 0;
|
||||||
|
textures3DO[i].mips = false;
|
||||||
|
|
||||||
if (objectTexture->isQuad)
|
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
|
{ // copy tile to 32-bit image and calculate average tile color
|
||||||
uint8* src = textures3DO[i].src;
|
uint8* src = textures3DO[i].src;
|
||||||
@@ -3044,8 +3013,6 @@ struct LevelPC
|
|||||||
{
|
{
|
||||||
for (int32 x = 0; x < w; x++)
|
for (int32 x = 0; x < w; x++)
|
||||||
{
|
{
|
||||||
uint32 index;
|
|
||||||
|
|
||||||
if (!objectTexture->isQuad)
|
if (!objectTexture->isQuad)
|
||||||
{
|
{
|
||||||
float u = float(x) / float(w - 1);
|
float u = float(x) / float(w - 1);
|
||||||
@@ -3104,6 +3071,14 @@ struct LevelPC
|
|||||||
hp /= 2;
|
hp /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wp > 64) {
|
||||||
|
wp = 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hp > 64) {
|
||||||
|
hp = 64;
|
||||||
|
}
|
||||||
|
|
||||||
ASSERT(wp != 0 && hp != 0);
|
ASSERT(wp != 0 && hp != 0);
|
||||||
|
|
||||||
if (w != wp || h != hp)
|
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);
|
textures3DO[i].plut = addPalette(plut);
|
||||||
#endif
|
|
||||||
|
|
||||||
liq_result_destroy(res);
|
liq_result_destroy(res);
|
||||||
liq_image_destroy(image);
|
liq_image_destroy(image);
|
||||||
@@ -3237,81 +3179,6 @@ struct LevelPC
|
|||||||
f.write(bitmap8_tmp, w * h / 2);
|
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
|
// fix PLUT offsets
|
||||||
int32 plutsOffset = f.getPos();
|
int32 plutsOffset = f.getPos();
|
||||||
@@ -3345,6 +3212,8 @@ struct LevelPC
|
|||||||
}
|
}
|
||||||
f.write((uint16*)PLUTs, sizeof(PLUT) / 2 * plutsCount);
|
f.write((uint16*)PLUTs, sizeof(PLUT) / 2 * plutsCount);
|
||||||
|
|
||||||
|
int32 texFileSize = f.getPos();
|
||||||
|
|
||||||
// write palette offset at the file start
|
// write palette offset at the file start
|
||||||
f.setPos(0);
|
f.setPos(0);
|
||||||
f.write(paletteOffset);
|
f.write(paletteOffset);
|
||||||
@@ -3353,13 +3222,230 @@ struct LevelPC
|
|||||||
delete[] bitmap32_tmp;
|
delete[] bitmap32_tmp;
|
||||||
delete[] bitmap8;
|
delete[] bitmap8;
|
||||||
delete[] bitmap8_tmp;
|
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)
|
void convert3DO(const char* name)
|
||||||
{
|
{
|
||||||
char path[256];
|
char path[256];
|
||||||
sprintf(path, "../../3do/CD/data/%s.TEX", name);
|
sprintf(path, "../../3do/CD/data/%s.TEX", name);
|
||||||
convertTextures3DO(path);
|
int32 texFileSize = convertTextures3DO(path);
|
||||||
|
|
||||||
sprintf(path, "../../3do/CD/data/%s.3DO", name);
|
sprintf(path, "../../3do/CD/data/%s.3DO", name);
|
||||||
|
|
||||||
@@ -3502,6 +3588,8 @@ struct LevelPC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
textures3DO[q.flags & FACE_TEXTURE].mips = true;
|
||||||
|
|
||||||
Quad3DO comp;
|
Quad3DO comp;
|
||||||
comp.indices[0] = q.indices[0];
|
comp.indices[0] = q.indices[0];
|
||||||
comp.indices[1] = q.indices[1];
|
comp.indices[1] = q.indices[1];
|
||||||
@@ -3520,6 +3608,8 @@ struct LevelPC
|
|||||||
t.indices[1] = addRoomVertex(room->vertices[t.indices[1]]);
|
t.indices[1] = addRoomVertex(room->vertices[t.indices[1]]);
|
||||||
t.indices[2] = addRoomVertex(room->vertices[t.indices[2]]);
|
t.indices[2] = addRoomVertex(room->vertices[t.indices[2]]);
|
||||||
|
|
||||||
|
textures3DO[t.flags & FACE_TEXTURE].mips = true;
|
||||||
|
|
||||||
t.write3DO(f);
|
t.write3DO(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3528,17 +3618,6 @@ struct LevelPC
|
|||||||
for (int32 i = 0; i < roomVerticesCount; i++)
|
for (int32 i = 0; i < roomVerticesCount; i++)
|
||||||
{
|
{
|
||||||
roomVertices[i].write(f);
|
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();
|
info.sprites = f.align4();
|
||||||
@@ -3877,6 +3956,16 @@ struct LevelPC
|
|||||||
for (int32 i = 0; i < objectTexturesCount; i++)
|
for (int32 i = 0; i < objectTexturesCount; i++)
|
||||||
{
|
{
|
||||||
textures3DO[i].write(f);
|
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();
|
header.spriteTextures = f.align4();
|
||||||
@@ -3974,39 +4063,26 @@ struct LevelPC
|
|||||||
|
|
||||||
uint8* soundBuf = new uint8[2 * 1024 * 1024];
|
uint8* soundBuf = new uint8[2 * 1024 * 1024];
|
||||||
|
|
||||||
|
bool isHome = strcmp(name, "GYM") == 0;
|
||||||
|
|
||||||
for (int32 i = 0; i < soundOffsetsCount; i++)
|
for (int32 i = 0; i < soundOffsetsCount; i++)
|
||||||
{
|
{
|
||||||
{ // save wav to the temporary file
|
soundOffsets[i] = f.align4() - header.soundData;
|
||||||
uint8* data = soundData + soundOffsets[i];
|
|
||||||
int32 size = *(int32*)(data + 4) + 8;
|
|
||||||
|
|
||||||
FILE* f = fopen("tmp.wav", "wb");
|
int32 id, sub, size;
|
||||||
fwrite(data, 1, size, f);
|
if (getSoundID(i, id, sub))
|
||||||
fclose(f);
|
{
|
||||||
|
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;
|
if (size) {
|
||||||
{ // read converted aiff
|
f.write(soundBuf, size);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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;
|
delete[] soundBuf;
|
||||||
|
Reference in New Issue
Block a user