From 5728b25d5ff86edd15887ff1f366932f1a2c9ae0 Mon Sep 17 00:00:00 2001 From: XProger Date: Sat, 6 Nov 2021 10:00:18 +0300 Subject: [PATCH] #370 3DO add one mip level and flat shading for room polygons, disable per-poly clipping for object meshes --- src/fixed/common.h | 20 +++- src/fixed/draw.h | 2 - src/fixed/game.h | 14 +-- src/platform/3do/Makefile | 1 - src/platform/3do/main.cpp | 28 ++++-- src/platform/3do/render_cel.cpp | 156 ++++++++++++++++++-------------- src/platform/3do/sound.cpp | 34 +++++++ 7 files changed, 159 insertions(+), 96 deletions(-) diff --git a/src/fixed/common.h b/src/fixed/common.h index fbbd37a..bfbc7b8 100644 --- a/src/fixed/common.h +++ b/src/fixed/common.h @@ -427,12 +427,14 @@ extern int32 fps; #define FACE_TRIANGLE 0x8000 #define FACE_COLORED 0x4000 #define FACE_CLIPPED 0x2000 -#define FACE_CCW FACE_CLIPPED // 3DO only #define FACE_FLAT 0x1000 #define FACE_SPRITE 0x0800 #define FACE_SHADOW (FACE_COLORED | FACE_FLAT | FACE_SPRITE) #define FACE_TEXTURE 0x07FF +#define FACE_CCW (1 << 31) // 3DO only +#define FACE_MIP_SHIFT 11 // 3DO only + #define NOT_ENEMY -0x4000 // default hp for non enemies #define NO_ROOM 0xFF #define NO_MODEL 0xFF @@ -583,7 +585,8 @@ struct Matrix #endif }; -struct Quad { +struct Quad +{ #ifdef __3DO__ Index indices[4]; uint32 flags; @@ -593,12 +596,20 @@ struct Quad { #endif }; -struct Triangle { +struct Triangle +{ +#ifdef __3DO__ + Index indices[3]; + uint16 _unused; + uint32 flags; +#else Index indices[3]; uint16 flags; +#endif }; -struct RectMinMax { +struct RectMinMax +{ int32 x0; int32 y0; int32 x1; @@ -2007,7 +2018,6 @@ extern ItemObj items[MAX_ITEMS]; // level data extern bool enableClipping; -extern bool enableMaxSort; template X_INLINE void swap(T &a, T &b) { diff --git a/src/fixed/draw.h b/src/fixed/draw.h index 944fb44..1d1fed6 100644 --- a/src/fixed/draw.h +++ b/src/fixed/draw.h @@ -802,9 +802,7 @@ void drawRoom(const Room* room, Camera* camera) { PROFILE(CNT_ADD); - enableMaxSort = true; faceAddRoom(data.quads, info->quadsCount, data.triangles, info->trianglesCount, startVertex); - enableMaxSort = false; } matrixPop(); diff --git a/src/fixed/game.h b/src/fixed/game.h index e85bf48..d9b7e52 100644 --- a/src/fixed/game.h +++ b/src/fixed/game.h @@ -109,18 +109,8 @@ struct Game drawInit(); #ifdef __3DO__ -/* - if (gLevelID == 0) - { - players[0]->angle.y += ANGLE_180; - players[0]->pos.x += 1024; - } - - if (gLevelID == 1) - { - players[0]->pos.z += 1024; - } -*/ + //players[0]->angle.y += ANGLE_180; + //players[0]->pos.x += 1024; #endif } diff --git a/src/platform/3do/Makefile b/src/platform/3do/Makefile index a847735..34a538f 100644 --- a/src/platform/3do/Makefile +++ b/src/platform/3do/Makefile @@ -34,7 +34,6 @@ LIBS = \ $(LIBPATH)/filesystem.lib \ $(LIBPATH)/graphics.lib \ $(LIBPATH)/input.lib \ - $(LIBPATH)/exampleslib.lib \ SRC_S = $(wildcard *.s) SRC_C = $(wildcard *.c) diff --git a/src/platform/3do/main.cpp b/src/platform/3do/main.cpp index f536191..f525fdc 100644 --- a/src/platform/3do/main.cpp +++ b/src/platform/3do/main.cpp @@ -253,15 +253,17 @@ void* osLoadLevel(const char* name) { char buf[32]; - sprintf(buf, "data/%s.3DO", name); + sprintf(buf, "data/%s.D", name); readFile(buf, RAM_LVL, MAX_RAM_LVL); - sprintf(buf, "data/%s.TEX", name); + sprintf(buf, "data/%s.V", name); readFile(buf, RAM_TEX, MAX_RAM_TEX); return RAM_LVL; } +bool useMips = true; + int main(int argc, char *argv[]) { printf("OpenLara 3DO\n"); @@ -297,9 +299,9 @@ int main(int argc, char *argv[]) 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; + uint8* memDRAM = (uint8*)AllocMem(MAX_RAM_LVL + MAX_RAM_CEL, MEMTYPE_DRAM); + RAM_LVL = memDRAM; + RAM_CEL = memDRAM + MAX_RAM_LVL; if (!RAM_LVL) printf("RAM_LVL failed!\n"); if (!RAM_TEX) printf("RAM_TEX failed!\n"); @@ -307,6 +309,11 @@ int main(int argc, char *argv[]) game.init(gLevelNames[gLevelID]); + AvailMem(&memInfoVRAM, MEMTYPE_DRAM); + printf("DRAM: %d\n", memInfoVRAM.minfo_SysFree); + AvailMem(&memInfoVRAM, MEMTYPE_VRAM); + printf("VRAM: %d\n", memInfoVRAM.minfo_SysFree); + GetVBLTime(irqVBL, NULL, &lastFrame); lastFrame /= 2; lastFrame--; @@ -338,9 +345,14 @@ int main(int argc, char *argv[]) if ((keys & IK_SELECT) && !(oldKeys & IK_SELECT)) { - gLevelID = (gLevelID + 1) % (sizeof(gLevelNames) / sizeof(gLevelNames[0])); - game.startLevel(gLevelNames[gLevelID]); - lastFrame = frame - 1; + if (useMips) { + useMips = false; + } else { + useMips = true; +// gLevelID = (gLevelID + 1) % (sizeof(gLevelNames) / sizeof(gLevelNames[0])); +// game.startLevel(gLevelNames[gLevelID]); +// lastFrame = frame - 1; + } } int32 updateTime = osGetSystemTimeMS(); diff --git a/src/platform/3do/render_cel.cpp b/src/platform/3do/render_cel.cpp index bf727ec..60aedb0 100644 --- a/src/platform/3do/render_cel.cpp +++ b/src/platform/3do/render_cel.cpp @@ -8,18 +8,12 @@ struct Vertex uint16* gPalette; int32 gPaletteOffset; // offset to the default or underwater PLUTs -extern uint8 lightmap[256 * 32]; extern Level level; -extern const Sprite* sprites; -extern const uint8* tiles; extern int32 lightAmbient; extern int32 randTable[MAX_RAND_TABLE]; extern int32 caustics[MAX_CAUSTICS]; extern int32 causticsFrame; -const uint8* tile; -const Sprite* sprite; - int32 gVerticesCount; int32 gFacesCount; @@ -39,10 +33,10 @@ RectMinMax viewportRel; bool enableAlphaTest; bool enableClipping; -bool enableMaxSort; bool secondPalette; #define SHADOW_OPACITY 3 // 50% +#define MIP_DIST (1024 * 5) extern Item screenItem; @@ -67,9 +61,33 @@ enum ShadeValue SHADE_14 = DUP16( PPMPC_MF_6 | PPMPC_SF_8 | PPMPC_2D_2 | PPMPC_2S_PDC ), // 14/16 SHADE_15 = DUP16( PPMPC_MF_7 | PPMPC_SF_8 | PPMPC_2D_2 | PPMPC_2S_PDC ), // 15/16 SHADE_16 = DUP16( PPMPC_MF_8 | PPMPC_SF_8 ), // 1 + SHADE_17 = DUP16( PPMPC_MF_1 | PPMPC_SF_16 | PPMPC_2S_PDC ), // 1 + 1/16 + SHADE_18 = DUP16( PPMPC_MF_2 | PPMPC_SF_16 | PPMPC_2S_PDC ), // 1 + 2/16 + SHADE_19 = DUP16( PPMPC_MF_3 | PPMPC_SF_16 | PPMPC_2S_PDC ), // 1 + 3/16 + SHADE_20 = DUP16( PPMPC_MF_4 | PPMPC_SF_16 | PPMPC_2S_PDC ), // 1 + 4/16 + SHADE_21 = DUP16( PPMPC_MF_5 | PPMPC_SF_16 | PPMPC_2S_PDC ), // 1 + 5/16 + SHADE_22 = DUP16( PPMPC_MF_6 | PPMPC_SF_16 | PPMPC_2S_PDC ), // 1 + 6/16 + SHADE_23 = DUP16( PPMPC_MF_7 | PPMPC_SF_16 | PPMPC_2S_PDC ), // 1 + 7/16 + SHADE_24 = DUP16( PPMPC_MF_8 | PPMPC_SF_16 | PPMPC_2S_PDC ), // 1 + 8/16 }; -static const uint32 shadeTable[16] = { +static const uint32 shadeTable[32] = { + SHADE_24, + SHADE_24, + SHADE_23, + SHADE_23, + SHADE_22, + SHADE_22, + SHADE_21, + SHADE_21, + SHADE_20, + SHADE_20, + SHADE_19, + SHADE_19, + SHADE_18, + SHADE_18, + SHADE_17, + SHADE_17, SHADE_16, SHADE_15, SHADE_14, @@ -197,9 +215,11 @@ bool transformBoxRect(const AABBs* box, RectMinMax* rect) for (int32 i = 0; i < 8; i++) { - if (v[i].z < (VIEW_MIN_F >> FIXED_SHIFT) || v[i].z >= (VIEW_MAX_F >> FIXED_SHIFT)) { + if (v[i].z <= 0) + return false; + + if (v[i].z >= (VIEW_MAX_F >> FIXED_SHIFT)) continue; - } if (v[i].x < rect->x0) rect->x0 = v[i].x; if (v[i].x > rect->x1) rect->x1 = v[i].x; @@ -298,7 +318,7 @@ void transformMesh(const MeshVertex* vertices, int32 vCount, const uint16* vInte int32 y0 = viewportRel.y0; int32 x1 = viewportRel.x1; int32 y1 = viewportRel.y1; - +/* res = &gVertices[gVerticesCount]; uint8* clip = &gClip[gVerticesCount]; @@ -310,7 +330,7 @@ void transformMesh(const MeshVertex* vertices, int32 vCount, const uint16* vInte *clip = enableClipping ? classify(res, x0, y0, x1, y1) : 0; } } - +*/ gVerticesCount += vCount; } @@ -321,6 +341,9 @@ void transformMesh(const MeshVertex* vertices, int32 vCount, const uint16* vInte X_INLINE Face* faceAdd(int32 depth) { + if (depth < 0) depth = 0; + if (depth > OT_SIZE - 1) depth = OT_SIZE - 1; + if (depth < otMin) otMin = depth; if (depth > otMax) otMax = depth; @@ -391,7 +414,9 @@ X_INLINE void ccbSetColor(Face* face, uint32 flags) face->ccb_SourcePtr = (CelData*)&gPalette[flags & 0xFF]; } -void faceAddRoomQuad(uint32 flags, const Index* indices, int32 startVertex32) +extern bool useMips; + +X_INLINE void faceAddRoomQuad(uint32 flags, const Index* indices, int32 startVertex32) { uint32 i01 = startVertex32 + ((uint32*)indices)[0]; uint32 i23 = startVertex32 + ((uint32*)indices)[1]; @@ -446,22 +471,20 @@ 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) - { - fade = (fade - FOG_MIN) >> 8; - if (fade > 15) { - fade = 15; - } - f->ccb_PIXC = shadeTable[fade]; - } else { - f->ccb_PIXC = SHADE_16; + uint32 intensity = (flags >> (FACE_MIP_SHIFT + FACE_MIP_SHIFT)) & 0xFF; + if (depth > (FOG_MIN >> OT_SHIFT)) { + intensity += (depth - (FOG_MIN >> OT_SHIFT)) >> 1; + intensity = X_MIN(intensity, 255); } - gTexture = level.textures + (flags & FACE_TEXTURE); + f->ccb_PIXC = shadeTable[intensity >> 3]; + + uint32 texIndex = flags; + if (useMips) + if (depth > (MIP_DIST >> OT_SHIFT)) { + texIndex >>= FACE_MIP_SHIFT; + } + gTexture = level.textures + (texIndex & FACE_TEXTURE); ccbSetTexture(f, gTexture); int32 x0 = v0->x; @@ -495,7 +518,7 @@ void faceAddRoomQuad(uint32 flags, const Index* indices, int32 startVertex32) f->ccb_HDDY = (hdy1 - hdy0) >> (16 - hs); } -void faceAddRoomTriangle(uint32 flags, const Index* indices, int32 startVertex32) +X_INLINE void faceAddRoomTriangle(uint32 flags, const Index* indices, int32 startVertex32) { uint32 i01 = ((uint32*)indices)[0] + startVertex32; uint32 i23 = ((uint32*)indices)[1] + startVertex32; @@ -524,20 +547,21 @@ void faceAddRoomTriangle(uint32 flags, const Index* indices, int32 startVertex32 int32 depth = DEPTH_T_MAX(); Face* f = faceAdd(depth); - - int32 fade = depth << OT_SHIFT; - if (fade > FOG_MIN) - { - fade = (fade - FOG_MIN) >> 8; - if (fade > 15) { - fade = 15; - } - f->ccb_PIXC = shadeTable[fade]; - } else { - f->ccb_PIXC = SHADE_16; + + uint32 intensity = (flags >> (FACE_MIP_SHIFT + FACE_MIP_SHIFT)) & 0xFF; + if (depth > (FOG_MIN >> OT_SHIFT)) { + intensity += (depth - (FOG_MIN >> OT_SHIFT)) >> 1; + intensity = X_MIN(intensity, 255); } - gTexture = level.textures + (flags & FACE_TEXTURE); + f->ccb_PIXC = shadeTable[intensity >> 3]; + + uint32 texIndex = flags; + if (useMips) + if (depth > (MIP_DIST >> OT_SHIFT)) { + texIndex >>= FACE_MIP_SHIFT; + } + gTexture = level.textures + (texIndex & FACE_TEXTURE); ccbSetTexture(f, gTexture); int32 x0 = v0->x; @@ -567,7 +591,7 @@ void faceAddRoomTriangle(uint32 flags, const Index* indices, int32 startVertex32 f->ccb_HDDY = -hdy0 >> (16 - hs); } -void faceAddMeshQuad(uint32 flags, const Index* indices, int32 startVertex32, uint32 shade) +X_INLINE void faceAddMeshQuad(uint32 flags, const Index* indices, int32 startVertex32, uint32 shade) { uint32 i01 = startVertex32 + ((uint32*)indices)[0]; uint32 i23 = startVertex32 + ((uint32*)indices)[1]; @@ -576,7 +600,7 @@ void faceAddMeshQuad(uint32 flags, const Index* indices, int32 startVertex32, ui uint32 i1 = (i01 & 0xFFFF); uint32 i2 = (i23 >> 16); uint32 i3 = (i23 & 0xFFFF); - +/* uint8 c0 = gClip[i0]; uint8 c1 = gClip[i1]; uint8 c2 = gClip[i2]; @@ -587,7 +611,7 @@ void faceAddMeshQuad(uint32 flags, const Index* indices, int32 startVertex32, ui if (c0 == 32 || c1 == 32 || c2 == 32 || c3 == 32) return; - +*/ const Vertex* v0 = gVertices + i0; const Vertex* v1 = gVertices + i1; const Vertex* v2 = gVertices + i2; @@ -635,7 +659,7 @@ void faceAddMeshQuad(uint32 flags, const Index* indices, int32 startVertex32, ui f->ccb_HDDY = (hdy1 - hdy0) >> (16 - hs); } -void faceAddMeshTriangle(uint32 flags, const Index* indices, int32 startVertex32, uint32 shade) +X_INLINE void faceAddMeshTriangle(uint32 flags, const Index* indices, int32 startVertex32, uint32 shade) { uint32 i01 = ((uint32*)indices)[0] + startVertex32; uint32 i23 = ((uint32*)indices)[1] + startVertex32; @@ -643,7 +667,7 @@ void faceAddMeshTriangle(uint32 flags, const Index* indices, int32 startVertex32 uint32 i0 = (i01 >> 16); uint32 i1 = (i01 & 0xFFFF); uint32 i2 = (i23 >> 16); - +/* uint8 c0 = gClip[i0]; uint8 c1 = gClip[i1]; uint8 c2 = gClip[i2]; @@ -653,7 +677,7 @@ void faceAddMeshTriangle(uint32 flags, const Index* indices, int32 startVertex32 if (c0 == 32 || c1 == 32 || c2 == 32) return; - +*/ const Vertex* v0 = gVertices + i0; const Vertex* v1 = gVertices + i1; const Vertex* v2 = gVertices + i2; @@ -696,7 +720,7 @@ void faceAddMeshTriangle(uint32 flags, const Index* indices, int32 startVertex32 f->ccb_HDDY = -hdy0 >> (16 - hs); } -void faceAddMeshQuadFlat(uint32 flags, const Index* indices, int32 startVertex32, uint32 shade) +X_INLINE void faceAddMeshQuadFlat(uint32 flags, const Index* indices, int32 startVertex32, uint32 shade) { uint32 i01 = startVertex32 + ((uint32*)indices)[0]; uint32 i23 = startVertex32 + ((uint32*)indices)[1]; @@ -705,7 +729,7 @@ void faceAddMeshQuadFlat(uint32 flags, const Index* indices, int32 startVertex32 uint32 i1 = (i01 & 0xFFFF); uint32 i2 = (i23 >> 16); uint32 i3 = (i23 & 0xFFFF); - +/* uint8 c0 = gClip[i0]; uint8 c1 = gClip[i1]; uint8 c2 = gClip[i2]; @@ -716,13 +740,13 @@ void faceAddMeshQuadFlat(uint32 flags, const Index* indices, int32 startVertex32 if (c0 == 32 || c1 == 32 || c2 == 32 || c3 == 32) return; - +*/ const Vertex* v0 = gVertices + i0; const Vertex* v1 = gVertices + i1; const Vertex* v2 = gVertices + i2; const Vertex* v3 = gVertices + i3; - if (checkBackface(v0, v1, v2) == !(flags & FACE_CCW)) + if (checkBackface(v0, v1, v2)) return; int32 depth = DEPTH_Q_AVG(); @@ -760,7 +784,7 @@ void faceAddMeshQuadFlat(uint32 flags, const Index* indices, int32 startVertex32 f->ccb_HDDY = (hdy1 - hdy0); } -void faceAddMeshTriangleFlat(uint32 flags, const Index* indices, int32 startVertex32, uint32 shade) +X_INLINE void faceAddMeshTriangleFlat(uint32 flags, const Index* indices, int32 startVertex32, uint32 shade) { uint32 i01 = ((uint32*)indices)[0] + startVertex32; uint32 i23 = ((uint32*)indices)[1] + startVertex32; @@ -768,7 +792,7 @@ void faceAddMeshTriangleFlat(uint32 flags, const Index* indices, int32 startVert uint32 i0 = (i01 >> 16); uint32 i1 = (i01 & 0xFFFF); uint32 i2 = (i23 >> 16); - +/* uint8 c0 = gClip[i0]; uint8 c1 = gClip[i1]; uint8 c2 = gClip[i2]; @@ -778,7 +802,7 @@ void faceAddMeshTriangleFlat(uint32 flags, const Index* indices, int32 startVert if (c0 == 32 || c1 == 32 || c2 == 32) return; - +*/ const Vertex* v0 = gVertices + i0; const Vertex* v1 = gVertices + i1; const Vertex* v2 = gVertices + i2; @@ -895,18 +919,14 @@ void faceAddSprite(int32 vx, int32 vy, int32 vz, int32 vg, int32 index) Face* f = faceAdd(depth); - int32 fade = depth << OT_SHIFT; - if (fade > FOG_MIN) - { - fade = (fade - FOG_MIN) >> 8; - if (fade > 15) { - fade = 15; - } - f->ccb_PIXC = shadeTable[fade]; - } else { - f->ccb_PIXC = SHADE_16; + if (depth > (FOG_MIN >> OT_SHIFT)) { + vg += (depth - (FOG_MIN >> OT_SHIFT)) << 4; + vg = X_MIN(vg, 8191); } + vg >>= 8; + f->ccb_PIXC = shadeTable[vg]; + Texture* texture = level.textures + sprite->texture; ccbSetTexture(f, texture); @@ -948,12 +968,12 @@ void faceAddRoom(const Quad* quads, int32 qCount, const Triangle* triangles, int { startVertex |= startVertex << 16; - for (int32 i = 0; i < qCount; i++) { - faceAddRoomQuad(quads[i].flags, quads[i].indices, startVertex); + for (int32 i = 0; i < qCount; i++, quads++) { + faceAddRoomQuad(quads->flags, quads->indices, startVertex); } - for (int32 i = 0; i < tCount; i++) { - faceAddRoomTriangle(triangles[i].flags, triangles[i].indices, startVertex); + for (int32 i = 0; i < tCount; i++, triangles++) { + faceAddRoomTriangle(triangles->flags, triangles->indices, startVertex); } } @@ -963,7 +983,7 @@ void faceAddMesh(const Quad* rFaces, const Quad* crFaces, const Triangle* tFaces uint32 shade; if (lightAmbient > 4096) { - shade = shadeTable[(lightAmbient - 4096) >> 8]; + shade = shadeTable[lightAmbient >> 8]; } else { shade = SHADE_16; } diff --git a/src/platform/3do/sound.cpp b/src/platform/3do/sound.cpp index c55d543..2732a2a 100644 --- a/src/platform/3do/sound.cpp +++ b/src/platform/3do/sound.cpp @@ -11,6 +11,8 @@ struct Channel Item frequency; Item amplitude; + Item playing; // TODO + void setPitch(uint32 value) { TweakKnob(frequency, value); @@ -66,6 +68,15 @@ void sndInit() void sndInitSamples() { + for (int32 i = 0; i < SND_CHANNELS; i++) + { + StopInstrument(channels[i].sample, NULL); + if (channels[i].attach) { + DetachSample(channels[i].attach); + } + channels[i].playing = NULL; + } + for (int32 i = 0; i < level.soundOffsetsCount; i++) { uint8* data = (uint8*)level.soundData + level.soundOffsets[i]; @@ -86,6 +97,27 @@ int32 idx = 0; void* sndPlaySample(int32 index, int32 volume, int32 pitch, int32 mode) { + if (mode == UNIQUE || mode == REPLAY) + { + for (int32 i = 0; i < SND_CHANNELS; i++) + { + if (channels[i].playing != samples[index]) + continue; + + channels[i].setVolume(0x7FFF * volume >> SND_VOL_SHIFT); + channels[i].setPitch(0x2000 * pitch >> SND_PITCH_SHIFT); + + //if (mode == REPLAY) TODO + { + StopInstrument(channels[i].sample, NULL); + StartInstrument(channels[i].sample, NULL); + } + + return (void*)channels[i].sample; + } + } + + // TODO idx = (idx + 1) % SND_CHANNELS; StopInstrument(channels[idx].sample, NULL); @@ -94,6 +126,8 @@ void* sndPlaySample(int32 index, int32 volume, int32 pitch, int32 mode) } channels[idx].attach = AttachSample(channels[idx].sample, samples[index], NULL); + channels[idx].playing = samples[index]; + StartInstrument(channels[idx].sample, NULL); channels[idx].setVolume(0x7FFF * volume >> SND_VOL_SHIFT);