diff --git a/src/cache.h b/src/cache.h index 820bd01..a8b15fc 100644 --- a/src/cache.h +++ b/src/cache.h @@ -118,7 +118,7 @@ struct ShaderCache { } } - const char *passNames[] = { "COMPOSE", "SHADOW", "AMBIENT", "WATER", "FILTER", "VOLUME", "GUI" }; + const char *passNames[] = { "COMPOSE", "SHADOW", "AMBIENT", "WATER", "FILTER", "GUI" }; const char *src = NULL; const char *typ = NULL; switch (pass) { diff --git a/src/mesh.h b/src/mesh.h index 14fadc2..5b70524 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -16,7 +16,7 @@ struct MeshRange { int vStart; int aIndex; - MeshRange() : aIndex(-1) {} + MeshRange() : iStart(0), iCount(0), vStart(0), aIndex(-1) {} void setup() const { glEnableVertexAttribArray(aCoord); @@ -224,14 +224,8 @@ struct MeshBuilder { vCount += mesh.rCount * 4 + mesh.tCount * 3; } - RoomRange &range = rooms[i]; - range.sprites.vStart = vCount; - range.sprites.iStart = iCount; iCount += d.sCount * 6; vCount += d.sCount * 4; - range.sprites.iCount = iCount - range.sprites.iStart; - - ASSERT(vCount - range.sprites.vStart < 0xFFFF); } // get models info @@ -251,39 +245,24 @@ struct MeshBuilder { // get size of mesh for sprite sequences sequences = new MeshRange[level.spriteSequencesCount]; for (int i = 0; i < level.spriteSequencesCount; i++) { - sequences[i].vStart = vCount; - sequences[i].iStart = iCount; - sequences[i].iCount = level.spriteSequences[i].sCount * 6; iCount += level.spriteSequences[i].sCount * 6; vCount += level.spriteSequences[i].sCount * 4; } // shadow blob mesh (8 triangles, 8 vertices) - shadowBlob.vStart = vCount; - shadowBlob.iStart = iCount; - shadowBlob.iCount = 8 * 3 * 3; - iCount += shadowBlob.iCount; + iCount += 8 * 3 * 3; vCount += 8 * 2 + 1; // quad (post effect filter) - quad.vStart = vCount; - quad.iStart = iCount; - quad.iCount = 2 * 3; - iCount += quad.iCount; + iCount += 2 * 3; vCount += 4; // circle - circle.vStart = vCount; - circle.iStart = iCount; - circle.iCount = CIRCLE_SEGS * 3; - iCount += circle.iCount; + iCount += CIRCLE_SEGS * 3; vCount += CIRCLE_SEGS + 1; // detailed plane - plane.vStart = vCount; - plane.iStart = iCount; - plane.iCount = PLANE_DETAIL * 2 * PLANE_DETAIL * 2 * (2 * 3); - iCount += plane.iCount; + iCount += PLANE_DETAIL * 2 * PLANE_DETAIL * 2 * (2 * 3); vCount += (PLANE_DETAIL * 2 + 1) * (PLANE_DETAIL * 2 + 1); // make meshes buffer (single vertex buffer object for all geometry & sprites on level) @@ -293,20 +272,20 @@ struct MeshBuilder { int aCount = 0; // build rooms + int vStartRoom = vCount; + aCount++; + for (int i = 0; i < level.roomsCount; i++) { TR::Room &room = level.rooms[i]; TR::Room::Data &d = room.data; RoomRange &range = rooms[i]; - int vStart; - for (int transp = 0; transp < 2; transp++) { // opaque, opacity - range.geometry[transp].vStart = vCount; + range.geometry[transp].vStart = vStartRoom; range.geometry[transp].iStart = iCount; - vStart = vCount; // rooms geometry - buildRoom(!transp, room, level, indices, vertices, iCount, vCount, vStart); + buildRoom(!transp, room, level, indices, vertices, iCount, vCount, vStartRoom); // static meshes for (int j = 0; j < room.meshesCount; j++) { @@ -319,44 +298,44 @@ struct MeshBuilder { int y = m.y; int z = m.z - room.info.z; int d = m.rotation.value / 0x4000; - buildMesh(!transp, mesh, level, indices, vertices, iCount, vCount, vStart, 0, x, y, z, d); + buildMesh(!transp, mesh, level, indices, vertices, iCount, vCount, vStartRoom, 0, x, y, z, d); } range.geometry[transp].iCount = iCount - range.geometry[transp].iStart; - - if (range.geometry[transp].iCount) - aCount++; } // rooms sprites - vStart = vCount; + range.sprites.vStart = vStartRoom; + range.sprites.iStart = iCount; for (int j = 0; j < d.sCount; j++) { TR::Room::Data::Sprite &f = d.sprites[j]; TR::Room::Data::Vertex &v = d.vertices[f.vertex]; TR::SpriteTexture &sprite = level.spriteTextures[f.texture]; - addSprite(indices, vertices, iCount, vCount, vStart, v.vertex.x, v.vertex.y, v.vertex.z, sprite, intensity(v.lighting)); + addSprite(indices, vertices, iCount, vCount, vStartRoom, v.vertex.x, v.vertex.y, v.vertex.z, sprite, intensity(v.lighting)); } - - if (d.sCount) aCount++; + range.sprites.iCount = iCount - range.sprites.iStart; } // build models geometry + int vStartModel = vCount; + aCount++; + for (int i = 0; i < level.modelsCount; i++) { TR::Model &model = level.models[i]; ModelRange &range = models[i]; - int vStart = vCount; - range.geometry.vStart = vStart; + + range.geometry.vStart = vStartModel; range.geometry.iStart = iCount; range.opaque = true; for (int j = 0; j < model.mCount; j++) { int index = level.meshOffsets[model.mStart + j]; if (!index && model.mStart + j > 0) continue; - aCount++; + TR::Mesh &mesh = level.meshes[index]; - bool opaque = buildMesh(true, mesh, level, indices, vertices, iCount, vCount, vStart, j, 0, 0, 0, 0); + bool opaque = buildMesh(true, mesh, level, indices, vertices, iCount, vCount, vStartModel, j, 0, 0, 0, 0); if (!opaque) - buildMesh(false, mesh, level, indices, vertices, iCount, vCount, vStart, j, 0, 0, 0, 0); + buildMesh(false, mesh, level, indices, vertices, iCount, vCount, vStartModel, j, 0, 0, 0, 0); TR::Entity::fixOpaque(model.type, opaque); range.opaque &= opaque; } @@ -364,14 +343,27 @@ struct MeshBuilder { } // build sprite sequences - for (int i = 0; i < level.spriteSequencesCount; i++) + int vStartSprite = vCount; + aCount++; + + for (int i = 0; i < level.spriteSequencesCount; i++) { + MeshRange &range = sequences[i]; + range.vStart = vStartSprite; + range.iStart = iCount; for (int j = 0; j < level.spriteSequences[i].sCount; j++) { TR::SpriteTexture &sprite = level.spriteTextures[level.spriteSequences[i].sStart + j]; - addSprite(indices, vertices, iCount, vCount, sequences[i].vStart, 0, 0, 0, sprite, 255); + addSprite(indices, vertices, iCount, vCount, vStartSprite, 0, 0, 0, sprite, 255); } - aCount += level.spriteSequencesCount; + range.iCount = iCount - range.iStart; + } - // build shadow blob + // build common primitives + int vStartCommon = vCount; + aCount++; + + shadowBlob.vStart = vStartCommon; + shadowBlob.iStart = iCount; + shadowBlob.iCount = 8 * 3 * 3; for (int i = 0; i < 9; i++) { Vertex &v0 = vertices[vCount + i * 2 + 0]; v0.normal = { 0, -1, 0, 0 }; @@ -414,10 +406,13 @@ struct MeshBuilder { } vCount += 8 * 2 + 1; iCount += shadowBlob.iCount; - aCount++; // quad - addQuad(indices, iCount, vCount, quad.vStart, vertices, &whiteTile); + quad.vStart = vStartCommon; + quad.iStart = iCount; + quad.iCount = 2 * 3; + + addQuad(indices, iCount, vCount, vStartCommon, vertices, &whiteTile); vertices[vCount + 3].coord = { -1, -1, 0, 0 }; vertices[vCount + 2].coord = { 1, -1, 1, 0 }; vertices[vCount + 1].coord = { 1, 1, 1, 1 }; @@ -431,12 +426,16 @@ struct MeshBuilder { v.param = { 0, 0, 0, 0 }; } vCount += 4; - aCount++; // circle + circle.vStart = vStartCommon; + circle.iStart = iCount; + circle.iCount = CIRCLE_SEGS * 3; + vec2 pos(32767.0f, 0.0f); vec2 cs(cosf(PI2 / CIRCLE_SEGS), sinf(PI2 / CIRCLE_SEGS)); + int baseIdx = vCount - vStartCommon; for (int i = 0; i < CIRCLE_SEGS; i++) { Vertex &v = vertices[vCount + i]; pos.rotate(cs); @@ -446,22 +445,25 @@ struct MeshBuilder { v.texCoord = { 32688, 32688, 32767, 32767 }; v.param = { 0, 0, 0, 0 }; - indices[iCount++] = i; - indices[iCount++] = (i + 1) % CIRCLE_SEGS; - indices[iCount++] = CIRCLE_SEGS; + indices[iCount++] = baseIdx + i; + indices[iCount++] = baseIdx + (i + 1) % CIRCLE_SEGS; + indices[iCount++] = baseIdx + CIRCLE_SEGS; } vertices[vCount + CIRCLE_SEGS] = vertices[vCount]; vertices[vCount + CIRCLE_SEGS].coord = { 0, 0, 0, 0 }; - vCount += CIRCLE_SEGS + 1; - aCount++; // plane + plane.vStart = vStartCommon; + plane.iStart = iCount; + plane.iCount = PLANE_DETAIL * 2 * PLANE_DETAIL * 2 * (2 * 3); + + baseIdx = vCount - vStartCommon; for (int16 j = -PLANE_DETAIL; j <= PLANE_DETAIL; j++) for (int16 i = -PLANE_DETAIL; i <= PLANE_DETAIL; i++) { vertices[vCount++].coord = { i, j, 0, 0 }; if (j < PLANE_DETAIL && i < PLANE_DETAIL) { - int idx = (j + PLANE_DETAIL) * (PLANE_DETAIL * 2 + 1) + i + PLANE_DETAIL; + int idx = baseIdx + (j + PLANE_DETAIL) * (PLANE_DETAIL * 2 + 1) + i + PLANE_DETAIL; indices[iCount + 0] = idx + PLANE_DETAIL * 2 + 1; indices[iCount + 1] = idx + 1; indices[iCount + 2] = idx; @@ -471,7 +473,7 @@ struct MeshBuilder { iCount += 6; } } - aCount++; + LOG("MegaMesh: %d %d %d\n", iCount, vCount, aCount); // compile buffer and ranges @@ -483,24 +485,35 @@ struct MeshBuilder { PROFILE_LABEL(BUFFER, mesh->ID[1], "Geometry vertices"); // initialize Vertex Arrays + MeshRange rangeRoom; + rangeRoom.vStart = vStartRoom; + mesh->initRange(rangeRoom); for (int i = 0; i < level.roomsCount; i++) { RoomRange &r = rooms[i]; - if (r.geometry[0].iCount) - mesh->initRange(r.geometry[0]); - if (r.geometry[1].iCount) - mesh->initRange(r.geometry[1]); - if (r.sprites.iCount) - mesh->initRange(r.sprites); + r.geometry[0].aIndex = rangeRoom.aIndex; + r.geometry[1].aIndex = rangeRoom.aIndex; + r.sprites.aIndex = rangeRoom.aIndex; } - for (int i = 0; i < level.spriteSequencesCount; i++) - mesh->initRange(sequences[i]); + MeshRange rangeModel; + rangeModel.vStart = vStartModel; + mesh->initRange(rangeModel); for (int i = 0; i < level.modelsCount; i++) - mesh->initRange(models[i].geometry); - mesh->initRange(shadowBlob); - mesh->initRange(quad); - mesh->initRange(circle); - mesh->initRange(plane); + models[i].geometry.aIndex = rangeModel.aIndex; + + MeshRange rangeSprite; + rangeSprite.vStart = vStartSprite; + mesh->initRange(rangeSprite); + for (int i = 0; i < level.spriteSequencesCount; i++) + sequences[i].aIndex = rangeSprite.aIndex; + + MeshRange rangeCommon; + rangeCommon.vStart = vStartCommon; + mesh->initRange(rangeCommon); + shadowBlob.aIndex = rangeCommon.aIndex; + quad.aIndex = rangeCommon.aIndex; + circle.aIndex = rangeCommon.aIndex; + plane.aIndex = rangeCommon.aIndex; } ~MeshBuilder() { @@ -808,8 +821,8 @@ struct MeshBuilder { int count = triangle ? 3 : 4; for (int i = 0; i < count; i++) { Vertex &v = vertices[vCount + i]; - v.texCoord.x = ((tx + tex->texCoord[i].x) << 5) + 16; - v.texCoord.y = ((ty + tex->texCoord[i].y) << 5) + 16; + v.texCoord.x = ((tx + tex->texCoord[i].x) * 32767) / 1024 + 16; + v.texCoord.y = ((ty + tex->texCoord[i].y) * 32767) / 1024 + 16; v.texCoord.z = 32767; v.texCoord.w = 32767; v.param = { range, frame, 0, 0 }; @@ -924,10 +937,10 @@ struct MeshBuilder { int tx = (sprite.tile % 4) * 256; int ty = (sprite.tile / 4) * 256; - int16 u0 = (((tx + sprite.texCoord[0].x) << 5)); - int16 v0 = (((ty + sprite.texCoord[0].y) << 5)); - int16 u1 = (((tx + sprite.texCoord[1].x) << 5)); - int16 v1 = (((ty + sprite.texCoord[1].y) << 5)); + int16 u0 = (((tx + sprite.texCoord[0].x) * 32767) / 1024) + 16; + int16 v0 = (((ty + sprite.texCoord[0].y) * 32767) / 1024) + 16; + int16 u1 = (((tx + sprite.texCoord[1].x) * 32767) / 1024) + 24; + int16 v1 = (((ty + sprite.texCoord[1].y) * 32767) / 1024) + 24; quad[0].texCoord = { u0, v0, sprite.l, sprite.t }; quad[1].texCoord = { u1, v0, sprite.r, sprite.t }; diff --git a/src/sound.h b/src/sound.h index 05e6eab..fe95aef 100644 --- a/src/sound.h +++ b/src/sound.h @@ -259,16 +259,16 @@ namespace Sound { int s = (s1 * inc[pred] + s2 * dec[pred]) >> 6; s = clamp((value >> shift) + s, -32768, 32767); - s2 = s1; + s2 = s1; s1 = s; } void resample(Frame *frames, short value) { predicate(value); - frames[0].L = frames[0].R = s2 + (s1 - s2) / 4; // 0.25 - frames[1].L = frames[1].R = s2 + (s1 - s2) / 2; // 0.50 - frames[2].L = frames[2].R = s2 + (s1 - s2) * 3 / 4; // 0.75 - frames[3].L = frames[3].R = s1; // 1.00 + frames[0].L = frames[0].R = s2 + (s1 - s2) / 4; // 0.25 + frames[1].L = frames[1].R = s2 + (s1 - s2) / 2; // 0.50 + frames[2].L = frames[2].R = s2 + (s1 - s2) * 3 / 4; // 0.75 + frames[3].L = frames[3].R = s1; // 1.00 } int processBlock() { @@ -472,7 +472,7 @@ namespace Sound { decoder = new VAG(stream); } #endif - + isPlaying = decoder != NULL; ASSERT(isPlaying); }