diff --git a/src/fixed/camera.h b/src/fixed/camera.h index a2a0480..360f7c7 100644 --- a/src/fixed/camera.h +++ b/src/fixed/camera.h @@ -383,6 +383,7 @@ void Camera::update() void Camera::prepareFrustum() { +#ifndef MODEHW matrixSetIdentity(); matrixRotateYXZ(angle.x, angle.y, angle.z); @@ -425,16 +426,19 @@ void Camera::prepareFrustum() frustumBase.maxY += view.pos.y + 1024; frustumBase.minZ += view.pos.z - 1024; frustumBase.maxZ += view.pos.z + 1024; +#endif } void Camera::updateFrustum(int32 offsetX, int32 offsetY, int32 offsetZ) { +#ifndef MODEHW frustumAABB.minX = frustumBase.minX - offsetX; frustumAABB.maxX = frustumBase.maxX - offsetX; frustumAABB.minY = frustumBase.minY - offsetY; frustumAABB.maxY = frustumBase.maxY - offsetY; frustumAABB.minZ = frustumBase.minZ - offsetZ; frustumAABB.maxZ = frustumBase.maxZ - offsetZ; +#endif } void Camera::toCombat() diff --git a/src/fixed/common.cpp b/src/fixed/common.cpp index 1e51f6b..01cc632 100644 --- a/src/fixed/common.cpp +++ b/src/fixed/common.cpp @@ -1,13 +1,16 @@ #include "common.h" uint32 keys; -AABBi frustumAABB; RectMinMax viewport; vec3i cameraViewPos; vec3i cameraViewOffset; Matrix matrixStack[MAX_MATRICES]; Matrix* matrixPtr = matrixStack; +#ifndef MODEHW + AABBi frustumAABB; +#endif + const FloorData* gLastFloorData; FloorData gLastFloorSlant; TargetInfo tinfo; diff --git a/src/fixed/common.h b/src/fixed/common.h index ddb2133..92bc754 100644 --- a/src/fixed/common.h +++ b/src/fixed/common.h @@ -37,7 +37,7 @@ #include #elif defined(__3DO__) #define MODEHW - #define USE_DIV_TABLE // 4k of DRAM + //#define USE_DIV_TABLE // 4k of DRAM #define CPU_BIG_ENDIAN #define BLOCK_SIZE_DRAM (32 * 1024) @@ -47,7 +47,7 @@ #define SND_BUFFER_SIZE (4 * BLOCK_SIZE_CD) #define SND_BUFFERS 4 - #define MAX_RAM_LVL (BLOCK_SIZE_DRAM * 30) // 38 for LEVEL10C! >_< + #define MAX_RAM_LVL (BLOCK_SIZE_DRAM * 31) // 35 for LEVEL10C! >_< #define MAX_RAM_TEX (BLOCK_SIZE_VRAM * 44) #define MAX_RAM_CEL (MAX_FACES * sizeof(CCB)) #define MAX_RAM_SND (SND_BUFFERS * SND_BUFFER_SIZE) @@ -401,6 +401,12 @@ extern int32 fps; #define SND_MAX 127 #endif +#ifdef __3DO__ + #define MAX_VERTICES (1024 + 32) // for mesh (max = LEVEL10A room:58) +#else + #define MAX_VERTICES (5*1024) // for frame +#endif + #define MAX_UPDATE_FRAMES 10 #define MAX_PLAYERS 1 // TODO 2 players for non-potato platforms @@ -413,7 +419,6 @@ extern int32 fps; #define MAX_STATIC_MESHES 50 #define MAX_CAMERAS 16 #define MAX_BOXES 1024 -#define MAX_VERTICES (3*1024) #define MAX_TEXTURES 1536 #define MAX_FACES 1920 #define MAX_ROOM_LIST 16 @@ -952,10 +957,7 @@ struct Texture #ifdef __3DO__ uint8* data; uint8* plut; - uint8 wShift; - uint8 hShift; - uint16 color; - uint32 _unused; + uint32 shift; #else uint16 attribute; uint16 tile; @@ -2031,7 +2033,6 @@ struct IMA_STATE // renderer internal extern uint32 keys; -extern AABBi frustumAABB; extern RectMinMax viewport; extern vec3i cameraViewPos; extern vec3i cameraViewOffset; @@ -2040,6 +2041,10 @@ extern Matrix matrixStack[MAX_MATRICES]; extern int32 gVerticesCount; extern int32 gFacesCount; +#ifndef MODEHW + extern AABBi frustumAABB; +#endif + extern SaveGame gSaveGame; extern Settings gSettings; extern int32 gCurTrack; diff --git a/src/fixed/room.h b/src/fixed/room.h index b2385ef..839b07e 100644 --- a/src/fixed/room.h +++ b/src/fixed/room.h @@ -473,13 +473,13 @@ Room** Room::addVisibleRoom(Room** list) { int32 axis = 0; int32 x = (portal->v[0].x - cx) << F16_SHIFT; - if (x > 0) axis |= (2 << 0); + if (x >= 0) axis |= (2 << 0); if (x < 0) axis |= (1 << 0); int32 y = (portal->v[0].y - cy) << F16_SHIFT; - if (y > 0) axis |= (2 << 2); + if (y >= 0) axis |= (2 << 2); if (y < 0) axis |= (1 << 2); int32 z = (portal->v[0].z - cz) << F16_SHIFT; - if (z > 0) axis |= (2 << 4); + if (z >= 0) axis |= (2 << 4); if (z < 0) axis |= (1 << 4); vis[i] = (portal->normalMask & axis); diff --git a/src/platform/3do/main.cpp b/src/platform/3do/main.cpp index 2e66f63..6dfe453 100644 --- a/src/platform/3do/main.cpp +++ b/src/platform/3do/main.cpp @@ -379,7 +379,7 @@ updateTime = osGetSystemTimeMS() - updateTime; lastFrame = frame; - screenItem = screen.sc_BitmapItems[screenPage]; + screenItem = screen.sc_ScreenItems[screenPage]; int32 renderTime = osGetSystemTimeMS(); game.render(); diff --git a/src/platform/3do/render_cel.cpp b/src/platform/3do/render_cel.cpp index 45dcc01..603046f 100644 --- a/src/platform/3do/render_cel.cpp +++ b/src/platform/3do/render_cel.cpp @@ -2,7 +2,7 @@ struct Vertex { - int32 x, y, z; + int32 x, y, z; // for rooms z = (depth << CLIP_SHIFT) | ClipFlags }; uint16* gPalette; @@ -18,10 +18,7 @@ int32 gVerticesCount; int32 gFacesCount; Vertex gVertices[MAX_VERTICES]; -uint8 gClip[MAX_VERTICES]; - Vertex* gVerticesBase = NULL; -uint8* gClipBase = NULL; Face* gFaces; // MAX_FACES Face* otFacesHead[OT_SIZE]; @@ -121,13 +118,11 @@ void renderInit() } gVerticesBase = gVertices; - gClipBase = gClip; } X_INLINE void resetBase() { gVerticesBase = gVertices + gVerticesCount; - gClipBase = gClip + gVerticesCount; } void setViewport(const RectMinMax &vp) @@ -176,12 +171,23 @@ X_INLINE bool checkBackface(const Vertex *a, const Vertex *b, const Vertex *c) (c->x - a->x) * (b->y - a->y) <= 0; } +enum ClipFlags { + CLIP_SHIFT = 8, + CLIP_MASK = (1 << CLIP_SHIFT) - 1, + CLIP_LEFT = 1 << 0, + CLIP_RIGHT = 1 << 1, + CLIP_TOP = 1 << 2, + CLIP_BOTTOM = 1 << 3, + CLIP_FAR = 1 << 4, + CLIP_NEAR = 1 << 5 +}; + X_INLINE int32 classify(const Vertex* v, int32 x0, int32 y0, int32 x1, int32 y1) { - return (v->x < x0 ? 1 : 0) | - (v->x > x1 ? 2 : 0) | - (v->y < y0 ? 4 : 0) | - (v->y > y1 ? 8 : 0); + return (v->x < x0 ? CLIP_LEFT : 0) | + (v->x > x1 ? CLIP_RIGHT : 0) | + (v->y < y0 ? CLIP_TOP : 0) | + (v->y > y1 ? CLIP_BOTTOM : 0); } void transform(vec3i* points, int32 count) @@ -286,18 +292,15 @@ void transformRoom(const RoomVertex* vertices, int32 vCount, bool underwater) int32 y1 = viewportRel.y1; res = gVerticesBase; - uint8* clip = gClipBase; - for (int32 i = 0; i < vCount; i++, res++, clip++) + for (int32 i = 0; i < vCount; i++, res++) { if (res->z < (VIEW_MIN_F >> FIXED_SHIFT)) { - res->z = (VIEW_MIN_F >> FIXED_SHIFT); - *clip = 32; + res->z = ((VIEW_MIN_F >> FIXED_SHIFT) << CLIP_SHIFT) | CLIP_NEAR; } else if (res->z >= (VIEW_MAX_F >> FIXED_SHIFT)) { - res->z = (VIEW_MAX_F >> FIXED_SHIFT); - *clip = 16; + res->z = ((VIEW_MAX_F >> FIXED_SHIFT) << CLIP_SHIFT) | CLIP_FAR; } else { - *clip = classify(res, x0, y0, x1, y1); + res->z = (res->z << CLIP_SHIFT) | classify(res, x0, y0, x1, y1); } } @@ -319,15 +322,13 @@ void transformMesh(const MeshVertex* vertices, int32 vCount, const uint16* vInte int32 cy = Dot3_F16(*(vec3f16*)&m.e03, *(vec3f16*)&m.e01) >> DOT_SHIFT; // dot(pos, up) int32 cz = Dot3_F16(*(vec3f16*)&m.e03, *(vec3f16*)&m.e02) >> DOT_SHIFT; // dot(pos, dir) - Vertex* res = gVerticesBase; - uint32 *v32 = (uint32*)vertices; + Vertex* res = gVerticesBase; for (int32 i = 0; i < vCount; i++, res++) { // << F16_SHIFT should be already applied uint32 p = *v32++; - //p += cxy; res->x = cx + int16(p); res->y = cy + int16(p >> 16); p = *v32++; @@ -339,10 +340,10 @@ void transformMesh(const MeshVertex* vertices, int32 vCount, const uint16* vInte gVerticesCount += vCount; } -#define DEPTH_T_AVG() ((v0->z + v1->z + v2->z + v2->z) >> (2 + OT_SHIFT)) -#define DEPTH_T_MAX() (X_MAX(v0->z, X_MAX(v1->z, v2->z)) >> OT_SHIFT) -#define DEPTH_Q_AVG() ((v0->z + v1->z + v2->z + v3->z) >> (2 + OT_SHIFT)) -#define DEPTH_Q_MAX() (X_MAX(v0->z, X_MAX(v1->z, X_MAX(v2->z, v3->z))) >> OT_SHIFT) +#define DEPTH_T_AVG(z0,z1,z2) ((z0 + z1 + z2 + z2) >> (2 + OT_SHIFT)) +#define DEPTH_Q_AVG(z0,z1,z2,z3) ((z0 + z1 + z2 + z3) >> (2 + OT_SHIFT)) +#define DEPTH_T_MAX(z0,z1,z2) (X_MAX(z0, X_MAX(z1, z2)) >> (CLIP_SHIFT + OT_SHIFT)) +#define DEPTH_Q_MAX(z0,z1,z2,z3) (X_MAX(z0, X_MAX(z1, X_MAX(z2, z3))) >> (CLIP_SHIFT + OT_SHIFT)) X_INLINE Face* faceAdd(int32 depth) { @@ -407,54 +408,8 @@ X_INLINE void ccbSetColor(uint32 flags, Face* face) face->ccb_SourcePtr = (CelData*)&gPalette[flags & 0xFF]; } -X_INLINE void faceAddRoomQuad(uint32 flags, const Index* indices) +X_INLINE void ccbMap4(Face* f, const Vertex* v0, const Vertex* v1, const Vertex* v2, const Vertex* v3, uint32 shift) { - uint32 i01 = ((uint32*)indices)[0]; - uint32 i23 = ((uint32*)indices)[1]; - - uint32 i0 = (i01 >> 16); - uint32 i1 = (i01 & 0xFFFF); - uint32 i2 = (i23 >> 16); - uint32 i3 = (i23 & 0xFFFF); - - uint8 c0 = gClipBase[i0]; - uint8 c1 = gClipBase[i1]; - uint8 c2 = gClipBase[i2]; - uint8 c3 = gClipBase[i3]; - - if (c0 & c1 & c2 & c3) - return; - - if (c0 == 32 || c1 == 32 || c2 == 32 || c3 == 32) - return; - - const Vertex* v0 = gVerticesBase + i0; - const Vertex* v1 = gVerticesBase + i1; - const Vertex* v2 = gVerticesBase + i2; - const Vertex* v3 = gVerticesBase + i3; - - if (checkBackface(v0, v1, v3) == !(flags & FACE_CCW)) - return; - - int32 depth = DEPTH_Q_MAX(); - - Face* f = faceAdd(depth); - - 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); - } - - f->ccb_PIXC = shadeTable[intensity >> 3]; - - uint32 texIndex = flags; - if (depth > (MIP_DIST >> OT_SHIFT)) { - texIndex >>= FACE_MIP_SHIFT; - } - const Texture* texture = level.textures + (texIndex & FACE_TEXTURE); - ccbSetTexture(flags, f, texture); - int32 x0 = v0->x; int32 y0 = v0->y; int32 x1 = v1->x; @@ -464,8 +419,8 @@ X_INLINE void faceAddRoomQuad(uint32 flags, const Index* indices) int32 x3 = v3->x; int32 y3 = v3->y; - int32 ws = texture->wShift; - int32 hs = texture->hShift; + uint32 ws = shift & 0xFF; + uint32 hs = shift >> 8; int32 hdx0 = (x1 - x0) << ws; int32 hdy0 = (y1 - y0) << ws; @@ -487,6 +442,87 @@ X_INLINE void faceAddRoomQuad(uint32 flags, const Index* indices) f->ccb_HDDY = (hdy1 - hdy0) >> hs; } +X_INLINE void ccbMap3(Face* f, const Vertex* v0, const Vertex* v1, const Vertex* v2, uint32 shift) +{ + int32 x0 = v0->x; + int32 y0 = v0->y; + int32 x1 = v1->x; + int32 y1 = v1->y; + int32 x2 = v2->x; + int32 y2 = v2->y; + + uint32 ws = shift & 0xFF; + uint32 hs = shift >> 8; + + int32 hdx0 = (x1 - x0) << ws; + int32 hdy0 = (y1 - y0) << ws; + int32 vdx0 = (x2 - x0) << hs; + int32 vdy0 = (y2 - y0) << hs; + + f->ccb_HDX = hdx0; + f->ccb_HDY = hdy0; + f->ccb_VDX = vdx0; + f->ccb_VDY = vdy0; + + f->ccb_XPos = (x0 + (FRAME_WIDTH >> 1)) << 16; + f->ccb_YPos = (y0 + (FRAME_HEIGHT >> 1)) << 16; + + hs = 16 - hs; + f->ccb_HDDX = -hdx0 >> hs; + f->ccb_HDDY = -hdy0 >> hs; +} + +X_INLINE void faceAddRoomQuad(uint32 flags, const Index* indices) +{ + uint32 i01 = ((uint32*)indices)[0]; + uint32 i23 = ((uint32*)indices)[1]; + + uint32 i0 = (i01 >> 16); + uint32 i1 = (i01 & 0xFFFF); + uint32 i2 = (i23 >> 16); + uint32 i3 = (i23 & 0xFFFF); + + const Vertex* v0 = gVerticesBase + i0; + const Vertex* v1 = gVerticesBase + i1; + const Vertex* v2 = gVerticesBase + i2; + const Vertex* v3 = gVerticesBase + i3; + + uint32 c0 = v0->z; + uint32 c1 = v1->z; + uint32 c2 = v2->z; + uint32 c3 = v3->z; + + if ((c0 & c1 & c2 & c3) & CLIP_MASK) + return; + + if ((c0 & CLIP_NEAR) || (c1 & CLIP_NEAR) || (c2 & CLIP_NEAR) || (c3 & CLIP_NEAR)) + return; + + int32 depth = DEPTH_Q_MAX(c0, c1, c2, c3); + + if (checkBackface(v0, v1, v3) == !(flags & FACE_CCW)) + return; + + Face* f = faceAdd(depth); + + 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); + } + + f->ccb_PIXC = shadeTable[intensity >> 3]; + + uint32 texIndex = flags; + if (depth > (MIP_DIST >> OT_SHIFT)) { + texIndex >>= FACE_MIP_SHIFT; + } + const Texture* texture = level.textures + (texIndex & FACE_TEXTURE); + ccbSetTexture(flags, f, texture); + + ccbMap4(f, v0, v1, v2, v3, texture->shift); +} + X_INLINE void faceAddRoomTriangle(uint32 flags, const Index* indices) { uint32 i01 = ((uint32*)indices)[0]; @@ -496,24 +532,24 @@ X_INLINE void faceAddRoomTriangle(uint32 flags, const Index* indices) uint32 i1 = (i01 & 0xFFFF); uint32 i2 = (i23 >> 16); - uint8 c0 = gClipBase[i0]; - uint8 c1 = gClipBase[i1]; - uint8 c2 = gClipBase[i2]; - - if (c0 & c1 & c2) - return; - - if (c0 == 32 || c1 == 32 || c2 == 32) - return; - const Vertex* v0 = gVerticesBase + i0; const Vertex* v1 = gVerticesBase + i1; const Vertex* v2 = gVerticesBase + i2; - if (checkBackface(v0, v1, v2)) + uint32 c0 = v0->z; + uint32 c1 = v1->z; + uint32 c2 = v2->z; + + if ((c0 & c1 & c2) & CLIP_MASK) return; - int32 depth = DEPTH_T_MAX(); + if ((c0 & CLIP_NEAR) || (c1 & CLIP_NEAR) || (c2 & CLIP_NEAR)) + return; + + int32 depth = DEPTH_T_MAX(c0, c1, c2); + + if (checkBackface(v0, v1, v2) == !(flags & FACE_CCW)) + return; Face* f = faceAdd(depth); @@ -532,32 +568,7 @@ X_INLINE void faceAddRoomTriangle(uint32 flags, const Index* indices) const Texture* texture = level.textures + (texIndex & FACE_TEXTURE); ccbSetTexture(flags, f, texture); - int32 x0 = v0->x; - int32 y0 = v0->y; - int32 x1 = v1->x; - int32 y1 = v1->y; - int32 x2 = v2->x; - int32 y2 = v2->y; - - int32 ws = texture->wShift; - int32 hs = texture->hShift; - - int32 hdx0 = (x1 - x0) << ws; - int32 hdy0 = (y1 - y0) << ws; - int32 vdx0 = (x2 - x0) << hs; - int32 vdy0 = (y2 - y0) << hs; - - f->ccb_HDX = hdx0; - f->ccb_HDY = hdy0; - f->ccb_VDX = vdx0; - f->ccb_VDY = vdy0; - - f->ccb_XPos = (x0 + (FRAME_WIDTH >> 1)) << 16; - f->ccb_YPos = (y0 + (FRAME_HEIGHT >> 1)) << 16; - - hs = 16 - hs; - f->ccb_HDDX = -hdx0 >> hs; - f->ccb_HDDY = -hdy0 >> hs; + ccbMap3(f, v0, v1, v2, texture->shift); } X_INLINE void faceAddMeshQuad(uint32 flags, uint32 indices, uint32 shade) @@ -575,7 +586,7 @@ X_INLINE void faceAddMeshQuad(uint32 flags, uint32 indices, uint32 shade) if (checkBackface(v0, v1, v3) == !(flags & FACE_CCW)) // TODO (hdx0 * vdy0 - vdx0 * hdy0) <= 0 return; - int32 depth = DEPTH_Q_AVG(); + int32 depth = DEPTH_Q_AVG(v0->z, v1->z, v2->z, v3->z); Face* f = faceAdd(depth); f->ccb_PIXC = shade; @@ -583,36 +594,7 @@ X_INLINE void faceAddMeshQuad(uint32 flags, uint32 indices, uint32 shade) const Texture* texture = level.textures + (flags & FACE_TEXTURE); ccbSetTexture(flags, f, texture); - int32 x0 = v0->x; - int32 y0 = v0->y; - int32 x1 = v1->x; - int32 y1 = v1->y; - int32 x2 = v2->x; - int32 y2 = v2->y; - int32 x3 = v3->x; - int32 y3 = v3->y; - - int32 ws = texture->wShift; - int32 hs = texture->hShift; - - int32 hdx0 = (x1 - x0) << ws; - int32 hdy0 = (y1 - y0) << ws; - int32 hdx1 = (x2 - x3) << ws; - int32 hdy1 = (y2 - y3) << ws; - int32 vdx0 = (x3 - x0) << hs; - int32 vdy0 = (y3 - y0) << hs; - - f->ccb_HDX = hdx0; - f->ccb_HDY = hdy0; - f->ccb_VDX = vdx0; - f->ccb_VDY = vdy0; - - f->ccb_XPos = (x0 + (FRAME_WIDTH >> 1)) << 16; - f->ccb_YPos = (y0 + (FRAME_HEIGHT >> 1)) << 16; - - hs = 16 - hs; - f->ccb_HDDX = (hdx1 - hdx0) >> hs; - f->ccb_HDDY = (hdy1 - hdy0) >> hs; + ccbMap4(f, v0, v1, v2, v3, texture->shift); } X_INLINE void faceAddMeshTriangle(uint32 flags, uint32 indices, uint32 shade) @@ -628,7 +610,7 @@ X_INLINE void faceAddMeshTriangle(uint32 flags, uint32 indices, uint32 shade) if (checkBackface(v0, v1, v2)) return; - int32 depth = DEPTH_T_AVG(); + int32 depth = DEPTH_T_AVG(v0->z, v1->z, v2->z); Face* f = faceAdd(depth); f->ccb_PIXC = shade; @@ -636,32 +618,7 @@ X_INLINE void faceAddMeshTriangle(uint32 flags, uint32 indices, uint32 shade) const Texture* texture = level.textures + (flags & FACE_TEXTURE); ccbSetTexture(flags, f, texture); - int32 x0 = v0->x; - int32 y0 = v0->y; - int32 x1 = v1->x; - int32 y1 = v1->y; - int32 x2 = v2->x; - int32 y2 = v2->y; - - int32 ws = texture->wShift; - int32 hs = texture->hShift; - - int32 hdx0 = (x1 - x0) << ws; - int32 hdy0 = (y1 - y0) << ws; - int32 vdx0 = (x2 - x0) << hs; - int32 vdy0 = (y2 - y0) << hs; - - f->ccb_HDX = hdx0; - f->ccb_HDY = hdy0; - f->ccb_VDX = vdx0; - f->ccb_VDY = vdy0; - - f->ccb_XPos = (x0 + (FRAME_WIDTH >> 1)) << 16; - f->ccb_YPos = (y0 + (FRAME_HEIGHT >> 1)) << 16; - - hs = 16 - hs; - f->ccb_HDDX = -hdx0 >> hs; - f->ccb_HDDY = -hdy0 >> hs; + ccbMap3(f, v0, v1, v2, texture->shift); } X_INLINE void faceAddMeshQuadFlat(uint32 flags, uint32 indices, uint32 shade) @@ -679,39 +636,14 @@ X_INLINE void faceAddMeshQuadFlat(uint32 flags, uint32 indices, uint32 shade) if (checkBackface(v0, v1, v3)) return; - int32 depth = DEPTH_Q_AVG(); + int32 depth = DEPTH_Q_AVG(v0->z, v1->z, v2->z, v3->z); Face* f = faceAdd(depth); f->ccb_PIXC = shade; ccbSetColor(flags, f); - int32 x0 = v0->x; - int32 y0 = v0->y; - int32 x1 = v1->x; - int32 y1 = v1->y; - int32 x2 = v2->x; - int32 y2 = v2->y; - int32 x3 = v3->x; - int32 y3 = v3->y; - - int32 hdx0 = (x1 - x0) << 20; - int32 hdy0 = (y1 - y0) << 20; - int32 hdx1 = (x2 - x3) << 20; - int32 hdy1 = (y2 - y3) << 20; - int32 vdx0 = (x3 - x0) << 16; - int32 vdy0 = (y3 - y0) << 16; - - f->ccb_HDX = hdx0; - f->ccb_HDY = hdy0; - f->ccb_VDX = vdx0; - f->ccb_VDY = vdy0; - - f->ccb_XPos = (x0 + (FRAME_WIDTH >> 1)) << 16; - f->ccb_YPos = (y0 + (FRAME_HEIGHT >> 1)) << 16; - - f->ccb_HDDX = (hdx1 - hdx0); - f->ccb_HDDY = (hdy1 - hdy0); + ccbMap4(f, v0, v1, v2, v3, 20 | (16 << 8)); } X_INLINE void faceAddMeshTriangleFlat(uint32 flags, uint32 indices, uint32 shade) @@ -727,35 +659,14 @@ X_INLINE void faceAddMeshTriangleFlat(uint32 flags, uint32 indices, uint32 shade if (checkBackface(v0, v1, v2)) return; - int32 depth = DEPTH_T_AVG(); + int32 depth = DEPTH_T_AVG(v0->z, v1->z, v2->z); Face* f = faceAdd(depth); f->ccb_PIXC = shade; ccbSetColor(flags, f); - int32 x0 = v0->x; - int32 y0 = v0->y; - int32 x1 = v1->x; - int32 y1 = v1->y; - int32 x2 = v2->x; - int32 y2 = v2->y; - - int32 hdx0 = (x1 - x0) << 20; - int32 hdy0 = (y1 - y0) << 20; - int32 vdx0 = (x2 - x0) << 16; - int32 vdy0 = (y2 - y0) << 16; - - f->ccb_HDX = hdx0; - f->ccb_HDY = hdy0; - f->ccb_VDX = vdx0; - f->ccb_VDY = vdy0; - - f->ccb_XPos = (x0 + (FRAME_WIDTH >> 1)) << 16; - f->ccb_YPos = (y0 + (FRAME_HEIGHT >> 1)) << 16; - - f->ccb_HDDX = -hdx0; - f->ccb_HDDY = -hdy0; + ccbMap3(f, v0, v1, v2, 20 | (16 << 8)); } void faceAddShadow(int32 x, int32 z, int32 sx, int32 sz) @@ -784,6 +695,8 @@ void faceAddShadow(int32 x, int32 z, int32 sx, int32 sz) faceAddMeshQuadFlat(0, (0 | (1 << 8) | (2 << 16) | (7 << 24)), SHADE_SHADOW); faceAddMeshQuadFlat(0, (7 | (2 << 8) | (3 << 16) | (6 << 24)), SHADE_SHADOW); faceAddMeshQuadFlat(0, (6 | (3 << 8) | (4 << 16) | (5 << 24)), SHADE_SHADOW); + + gVerticesCount = 0; } void faceAddSprite(int32 vx, int32 vy, int32 vz, int32 vg, int32 index) @@ -839,10 +752,14 @@ void faceAddSprite(int32 vx, int32 vy, int32 vz, int32 vg, int32 index) Texture* texture = level.textures + sprite->texture; ccbSetTexture(0, f, texture); - f->ccb_HDX = (x1 - x0) << texture->wShift; + uint32 shift = texture->shift; + uint32 ws = shift & 0xFF; + uint32 hs = shift >> 8; + + f->ccb_HDX = (x1 - x0) << ws; f->ccb_HDY = 0; f->ccb_VDX = 0; - f->ccb_VDY = (y1 - y0) << texture->hShift; + f->ccb_VDY = (y1 - y0) << hs; f->ccb_XPos = (x0 + (FRAME_WIDTH >> 1)) << 16; f->ccb_YPos = (y0 + (FRAME_HEIGHT >> 1)) << 16; @@ -861,10 +778,14 @@ void faceAddGlyph(int32 vx, int32 vy, int32 index) Texture* texture = level.textures + sprite->texture; ccbSetTexture(0, f, texture); - f->ccb_HDX = (sprite->r - sprite->l) << texture->wShift; + uint32 shift = texture->shift; + uint32 ws = shift & 0xFF; + uint32 hs = shift >> 8; + + f->ccb_HDX = (sprite->r - sprite->l) << ws; f->ccb_HDY = 0; f->ccb_VDX = 0; - f->ccb_VDY = (sprite->b - sprite->t) << texture->hShift; + f->ccb_VDY = (sprite->b - sprite->t) << hs; f->ccb_XPos = (vx + sprite->l) << 16; f->ccb_YPos = (vy + sprite->t) << 16; @@ -882,6 +803,8 @@ void faceAddRoom(const RoomQuad* quads, int32 qCount, const RoomTriangle* triang for (int32 i = 0; i < tCount; i++, triangles++) { faceAddRoomTriangle(triangles->flags, triangles->indices); } + + gVerticesCount = 0; } void faceAddMesh(const MeshQuad* rFaces, const MeshQuad* crFaces, const MeshTriangle* tFaces, const MeshTriangle* ctFaces, int32 rCount, int32 crCount, int32 tCount, int32 ctCount) @@ -908,6 +831,8 @@ void faceAddMesh(const MeshQuad* rFaces, const MeshQuad* crFaces, const MeshTria for (int32 i = 0; i < ctCount; i++) { faceAddMeshTriangleFlat(ctFaces[i].flags, ctFaces[i].indices, shade); } + + gVerticesCount = 0; } void flush() @@ -945,7 +870,7 @@ void flush() if (facesHead) { LAST_CEL(facesTail); - DrawCels(screenItem, facesHead); + DrawScreenCels(screenItem, facesHead); UNLAST_CEL(facesTail); } } diff --git a/src/platform/gba/packer/main.cpp b/src/platform/gba/packer/main.cpp index 3afa719..7d0f383 100644 --- a/src/platform/gba/packer/main.cpp +++ b/src/platform/gba/packer/main.cpp @@ -2928,17 +2928,24 @@ struct LevelPC int32 h; uint16 flip; int16 mip; + uint8* image; void write(FileStream &f) const { - uint32 unused = 0; f.write(data); f.write(plut); - f.write(wShift); - f.write(hShift); - f.write(color); - f.write(unused); + uint32 shift = wShift | (hShift << 8); + f.write(shift); } + + bool cmp(const Texture3DO &t) + { + if (wShift != t.wShift || hShift != t.hShift || plut != t.plut) + return false; + + return memcmp(image, t.image, (1 << (20 - wShift)) * (1 << (16 - hShift)) / 2) == 0; + } + } textures3DO[MAX_TEXTURES]; int32 spritesBaseIndex; @@ -3117,6 +3124,8 @@ struct LevelPC int32 mipIndex = objectTexturesCount; + int32 dupSize = 0; + for (int32 i = 0; i < objectTexturesCount; i++) { const LevelPC::ObjectTexture* objectTexture = objectTextures + i; @@ -3252,7 +3261,6 @@ struct LevelPC if (w != wp || h != hp) { - //stbir_resize_uint8((uint8*)bitmap32, w, h, 0, (uint8*)bitmap32_tmp, wp, hp, 0, 4); stbir_resize_uint8_generic((uint8*)bitmap32, w, h, 0, (uint8*)bitmap32_tmp, wp, hp, 0, 4, 3, 0, STBIR_EDGE_CLAMP, STBIR_FILTER_BOX, STBIR_COLORSPACE_LINEAR, NULL); swap(bitmap32, bitmap32_tmp); @@ -3330,8 +3338,10 @@ struct LevelPC } { // encode to 4-bit image + textures3DO[i].image = new uint8[rowBytes * h]; + uint8* src = bitmap8; - uint8* dst = bitmap8_tmp; + uint8* dst = textures3DO[i].image; for (int32 y = 0; y < h; y++) { for (int32 x = 0; x < rowBytes; x++, src += 2) @@ -3340,11 +3350,29 @@ struct LevelPC } } + textures3DO[i].data = 0; +/* + for (int32 j = 0; j < i; j++) + { + if (textures3DO[i].cmp(textures3DO[j])) + { + textures3DO[i].data = textures3DO[j].data; + + //ASSERT((objectTextures[i].attribute & TEX_ATTR_MIPS) == (objectTextures[j].attribute & TEX_ATTR_MIPS)); + + dupSize += rowBytes * h; + break; + } + } + */ // write image - textures3DO[i].data = f.getPos(); - f.write(textures3DO[i].pre0); - f.write(textures3DO[i].pre1); - f.write(bitmap8_tmp, rowBytes * h); + if (!textures3DO[i].data) { + textures3DO[i].data = f.getPos(); + + f.write(textures3DO[i].pre0); + f.write(textures3DO[i].pre1); + f.write(textures3DO[i].image, rowBytes * h); + } } // generate mip level @@ -3364,7 +3392,6 @@ struct LevelPC ASSERT(h > 0); { - //stbir_resize_uint8((uint8*)bitmap32, w, h, 0, (uint8*)bitmap32_tmp, wp, hp, 0, 4); stbir_resize_uint8_generic((uint8*)bitmap32, w << 1, h << 1, 0, (uint8*)bitmap32_tmp, w, h, 0, 4, 3, 0, STBIR_EDGE_CLAMP, STBIR_FILTER_BOX, STBIR_COLORSPACE_LINEAR, NULL); swap(bitmap32, bitmap32_tmp); @@ -3452,6 +3479,9 @@ struct LevelPC objectTexturesCount = mipIndex; + printf("duplicate size: %d\n", dupSize); + + // fix PLUT offsets int32 plutsOffset = f.getPos(); for (int32 i = 0; i < objectTexturesCount; i++) @@ -3500,6 +3530,7 @@ struct LevelPC void getSample(const char* base, const char* prefix, int32 id, int32 sub, uint8* buffer, int32 &size) { + // 57 == 38? size = 0; char path[256]; @@ -3850,7 +3881,7 @@ struct LevelPC f.writeObj(floors, floorsCount); header.meshData = f.align4(); - #if 1 + int32 mOffsets[2048]; for (int32 i = 0; i < 2048; i++) { mOffsets[i] = -1; @@ -4039,13 +4070,6 @@ struct LevelPC header.meshOffsets = f.align4(); f.write(mOffsets, meshOffsetsCount); - #else - f.write(meshData, meshDataSize); - - header.meshOffsets = f.align4(); - f.write(meshOffsets, meshOffsetsCount); - #endif - header.anims = f.align4(); f.writeObj(anims, animsCount); @@ -4315,8 +4339,6 @@ struct LevelPC const char* levelNames[] = { #if 0 "GYM", - "LEVEL1", - "LEVEL2", #else "TITLE", "GYM",