From 3b368ac6a4a5bd25a9cbc6d9ea4d91000ed605a3 Mon Sep 17 00:00:00 2001 From: XProger Date: Mon, 1 Nov 2021 07:56:07 +0300 Subject: [PATCH] #370 3DO audio support (PCM 8 4kHz), fix for PAL systems --- src/platform/3do/main.cpp | 84 ++++++++++------------ src/platform/3do/render_cel.cpp | 40 ++++++++--- src/platform/3do/sound.cpp | 124 ++++++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+), 56 deletions(-) create mode 100644 src/platform/3do/sound.cpp diff --git a/src/platform/3do/main.cpp b/src/platform/3do/main.cpp index 68b3693..37ca679 100644 --- a/src/platform/3do/main.cpp +++ b/src/platform/3do/main.cpp @@ -1,5 +1,8 @@ const void* TRACKS_IMA; -void* levelData; + +void* RAM_LVL; +void* RAM_TEX; +void* RAM_CEL; #include "game.h" @@ -197,14 +200,11 @@ void* readFile(char* fileName, void* buffer, int32 bufferSize) if (DoIO(req, ¶ms) >= 0) { int32 size = ds.ds_DeviceBlockCount * ds.ds_DeviceBlockSize; - if (ptr) { - if (bufferSize < size) - { - printf("not enough buffer size %d bytes required!\n", size); - ptr = NULL; - } - } else { - ptr = malloc(size); + + if (bufferSize < size) + { + printf("not enough buffer size for %s. %d bytes required!\n", fileName, size); + ptr = NULL; } if (ptr != NULL) @@ -217,13 +217,8 @@ void* readFile(char* fileName, void* buffer, int32 bufferSize) if (DoIO(req, ¶ms) < 0) { printf("can't get file content!\n"); - if (!buffer) { - free(ptr); - } ptr = NULL; } - } else { - printf("can't allocate %d bytes!\n", size); } } @@ -233,34 +228,12 @@ void* readFile(char* fileName, void* buffer, int32 bufferSize) return ptr; } -void soundInit() -{ - // TODO -} - -void checkRAM() -{ - for (int32 i = 1; i < 2 * 1024 * 1024; i += 16 * 1024) - { - void* ptr = malloc(i); - if (ptr == NULL) { - printf("RAM: %d kb\n", i / 1024 - 16); - break; - } - free(ptr); - } - - MemInfo memInfoVRAM; - AvailMem(&memInfoVRAM, MEMTYPE_VRAM); - printf("VRAM: %d\n", memInfoVRAM.minfo_SysFree); -} - -int32 gLevelID = 2; +int32 gLevelID = 1; static const char* gLevelNames[] = { "GYM", "LEVEL1", - "LEVEL2", +// "LEVEL2", // "LEVEL3A", // "LEVEL3B", // "LEVEL4", @@ -276,24 +249,28 @@ static const char* gLevelNames[] = { // "LEVEL10C" }; -void osLoadLevel(const char* name) +void* osLoadLevel(const char* name) { char buf[32]; sprintf(buf, "data/%s.3DO", name); - readFile(buf, levelData, MAX_RAM); + readFile(buf, RAM_LVL, MAX_RAM_LVL); sprintf(buf, "data/%s.TEX", name); - readFile(buf, VRAM_TEX, MAX_VRAM); + readFile(buf, RAM_TEX, MAX_RAM_TEX); + + return RAM_LVL; } int main(int argc, char *argv[]) { printf("OpenLara 3DO\n"); - levelData = AllocMem(MAX_RAM, MEMTYPE_DMA); - - //checkRAM(); +/* + MemInfo memInfoVRAM; + AvailMem(&memInfoVRAM, MEMTYPE_DMA); + printf("RAM: %d\n", memInfoVRAM.minfo_SysFree); +*/ uint32 lastFrame; uint32 frame; @@ -304,7 +281,7 @@ int main(int argc, char *argv[]) OpenGraphicsFolio(); OpenAudioFolio(); InitEventUtility(1, 0, LC_Observer); - CreateBasicDisplay(&screen, DI_TYPE_NTSC, 2); + CreateBasicDisplay(&screen, DI_TYPE_DEFAULT, 2); for (int32 i = 0; i < 2; i++) { @@ -317,12 +294,18 @@ int main(int argc, char *argv[]) irqVRAM = GetVRAMIOReq(); irqTimer = GetTimerIOReq(); - soundInit(); + 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); + + if (!RAM_LVL) printf("RAM_LVL failed!\n"); + if (!RAM_TEX) printf("RAM_TEX failed!\n"); + if (!RAM_CEL) printf("RAM_CEL failed!\n"); game.init(gLevelNames[gLevelID]); - //checkRAM(); - GetVBLTime(irqVBL, NULL, &lastFrame); lastFrame /= 2; lastFrame--; @@ -339,6 +322,11 @@ int main(int argc, char *argv[]) //GetVBLTime(irqVBL, NULL, &frame); // slower QueryGraphics(QUERYGRAF_TAG_FIELDCOUNT, &frame); + if (screen.sc_DisplayType != DI_TYPE_NTSC) + { + frame = frame * 6 / 5; // PAL fix + } + if (frame/60 != lastSec) { lastSec = frame/60; fps = frameIndex; diff --git a/src/platform/3do/render_cel.cpp b/src/platform/3do/render_cel.cpp index 4b98509..bf727ec 100644 --- a/src/platform/3do/render_cel.cpp +++ b/src/platform/3do/render_cel.cpp @@ -44,8 +44,6 @@ bool secondPalette; #define SHADOW_OPACITY 3 // 50% -uint8* VRAM_TEX; - extern Item screenItem; #define DUP16(value) value | (value << 16) @@ -92,11 +90,8 @@ static const uint32 shadeTable[16] = { void renderInit() { - VRAM_TEX = (uint8*)AllocMem(MAX_VRAM, MEMTYPE_VRAM | MEMTYPE_CEL); - - gPalette = (uint16*)VRAM_TEX; - - gFaces = (Face*)AllocMem(MAX_FACES * sizeof(Face), MEMTYPE_CEL); + gPalette = (uint16*)RAM_TEX; + gFaces = (Face*)RAM_CEL; } void setViewport(const RectMinMax &vp) @@ -112,7 +107,7 @@ void setViewport(const RectMinMax &vp) void setPaletteIndex(int32 index) { gPaletteOffset = index * level.tilesCount * sizeof(uint16) * 16; - gPalette = (uint16*)(VRAM_TEX + (*(uint32*)VRAM_TEX) + gPaletteOffset); + gPalette = (uint16*)((uint8*)RAM_TEX + (*(uint32*)RAM_TEX) + gPaletteOffset); } int32 rectIsVisible(const RectMinMax* rect) @@ -220,8 +215,12 @@ bool transformBoxRect(const AABBs* box, RectMinMax* rect) return true; } +const RoomVertex* gRoomVertices; + void transformRoom(const RoomVertex* vertices, int32 vCount, bool underwater) { + gRoomVertices = vertices; + int32 cx = cameraViewOffset.x << F16_SHIFT; int32 cy = cameraViewOffset.y << F16_SHIFT; int32 cz = cameraViewOffset.z << F16_SHIFT; @@ -401,7 +400,29 @@ void faceAddRoomQuad(uint32 flags, const Index* indices, int32 startVertex32) uint32 i1 = (i01 & 0xFFFF); uint32 i2 = (i23 >> 16); uint32 i3 = (i23 & 0xFFFF); +/* + uint32 normalMask = flags >> 16; + if (normalMask != 255) { + uint32 p = *(uint32*)(gRoomVertices + indices[0]); + uint32 axis; + + int32 x = cameraViewOffset.x + ((p >> 24) << 10); + if (x > 0) axis |= (2 << 0); + if (x < 0) axis |= (1 << 0); + + int32 y = cameraViewOffset.y + (int8(p >> 16) << 8); + if (y > 0) axis |= (2 << 2); + if (y < 0) axis |= (1 << 2); + + int32 z = cameraViewOffset.z + (((p >> 8) & 0xFF) << 10); + if (z > 0) axis |= (2 << 4); + if (z < 0) axis |= (1 << 4); + + if (!(normalMask & axis)) + return; + } +*/ uint8 c0 = gClip[i0]; uint8 c1 = gClip[i1]; uint8 c2 = gClip[i2]; @@ -425,6 +446,9 @@ void faceAddRoomQuad(uint32 flags, const Index* indices, int32 startVertex32) Face* f = faceAdd(depth); + //int32 fade = flags >> (24 + 4); + //f->ccb_PIXC = shadeTable[fade]; + int32 fade = depth << OT_SHIFT; if (fade > FOG_MIN) { diff --git a/src/platform/3do/sound.cpp b/src/platform/3do/sound.cpp new file mode 100644 index 0000000..3bc60ef --- /dev/null +++ b/src/platform/3do/sound.cpp @@ -0,0 +1,124 @@ +#include "common.h" + +Item sndMixer; +Item testSample; + +struct Channel +{ + Item gainL; + Item gainR; + Item sample; + Item attach; + Item frequency; + Item amplitude; + + void setPitch(uint32 value) + { + TweakKnob(frequency, value); + } + + void setVolume(uint32 value) + { + TweakKnob(amplitude, value); + } +}; + +Channel channels[SND_CHANNELS]; + +Item samples[SND_SAMPLES]; + +void sndInit() +{ + #if SND_CHANNELS != 4 + #error change the sound mixer or channels count + #endif + + sndMixer = LoadInstrument("mixer4x2.dsp", 0, 100); + + char* LGainName = "LeftGain0"; + char* RGainName = "RightGain0"; + char* InputName = "Input0"; + + for (int32 i = 0; i < SND_CHANNELS; i++) + { + LGainName[8] = '0' + i; + RGainName[9] = '0' + i; + InputName[5] = '0' + i; + + channels[i].gainL = GrabKnob(sndMixer, LGainName); + channels[i].gainR = GrabKnob(sndMixer, RGainName); + + TweakKnob(channels[i].gainL, 255 << 6); + TweakKnob(channels[i].gainR, 255 << 6); + + channels[i].sample = LoadInstrument("varmono8.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); + } + + StartInstrument(sndMixer, NULL); +} + +void sndInitSamples() +{ + for (int32 i = 0; i < level.soundOffsetsCount; i++) + { + 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, + TAG_END + ); + } +} + +int32 idx = 0; + +void* sndPlaySample(int32 index, int32 volume, int32 pitch, int32 mode) +{ + idx = (idx + 1) % SND_CHANNELS; + + StopInstrument(channels[idx].sample, NULL); + if (channels[idx].attach) { + 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); + + return (void*)channels[idx].sample; +} + +void sndPlayTrack(int32 track) +{ + +} + +void sndStopTrack() +{ + +} + +void sndStopSample(int32 index) +{ + +} + +void sndStop() +{ + +} \ No newline at end of file