diff --git a/src/platform/gba/common.h b/src/platform/gba/common.h index 464fcb5..2e0bd81 100644 --- a/src/platform/gba/common.h +++ b/src/platform/gba/common.h @@ -24,6 +24,7 @@ //#define USE_MODE_5 //#define DEBUG_OVERDRAW +//#define DEBUG_FACES #define SCALE 1 @@ -223,10 +224,10 @@ struct EntityDesc { // 32 bytes struct Texture { uint16 attribute; uint16 tile:14, :2; - uint8 xh0, x0, yh0, y0; - uint8 xh1, x1, yh1, y1; - uint8 xh2, x2, yh2, y2; - uint8 xh3, x3, yh3, y3; + uint32 uv0; + uint32 uv1; + uint32 uv2; + uint32 uv3; }; struct Sprite { @@ -253,7 +254,7 @@ struct Rect { struct Vertex { int16 x, y, z; uint8 g, clip; - uint8 u, v; + uint32 uv; }; struct Face { @@ -269,8 +270,8 @@ struct Face { #define MAX_MATRICES 8 #define MAX_MODELS 64 #define MAX_ENTITY 190 -#define MAX_VERTICES 1024 -#define MAX_FACES 384 +#define MAX_VERTICES 850 +#define MAX_FACES 220 #define FOG_SHIFT 2 #define FOG_MAX (10 * 1024) #define FOG_MIN (FOG_MAX - (8192 >> FOG_SHIFT)) diff --git a/src/platform/gba/data/LEVEL1.PHD b/src/platform/gba/data/LEVEL1.PHD new file mode 100644 index 0000000..b9ae563 Binary files /dev/null and b/src/platform/gba/data/LEVEL1.PHD differ diff --git a/src/platform/gba/level.h b/src/platform/gba/level.h index 0d2d222..6ef0a92 100644 --- a/src/platform/gba/level.h +++ b/src/platform/gba/level.h @@ -5,21 +5,21 @@ #include "camera.h" // level file data ------------------- -uint32 tilesCount; -const uint8* tiles[15]; +uint32 tilesCount; +extern const uint8* tiles[15]; #if defined(USE_MODE_5) || defined(_WIN32) ALIGN4 uint16 palette[256]; #endif -ALIGN4 uint8 lightmap[256 * 32]; +extern uint8 lightmap[256 * 32]; uint16 roomsCount; const uint16* floors; -uint32 texturesCount; -const Texture* textures; +uint32 texturesCount; +extern const Texture* textures; const Sprite* sprites; @@ -85,45 +85,48 @@ int32 entityLara; extern uint32 gVerticesCount; extern Rect clip; -void readLevel(const uint8 *data) { // TODO non-hardcode level loader +void readLevel(const uint8 *data) { // TODO non-hardcode level loader, added *_OFF alignment bytes tilesCount = *((uint32*)(data + 4)); for (uint32 i = 0; i < tilesCount; i++) { tiles[i] = data + 8 + 256 * 256 * i; } + #define MDL_OFF 2 + #define ENT_OFF 2 + roomsCount = *((uint16*)(data + 720908)); const Room* roomsPtr = (Room*)(data + 720908 + 2); floors = (uint16*)(data + 899492 + 4); - texturesCount = *((uint32*)(data + 1271686)); - textures = (Texture*)(data + 1271686 + 4); - - sprites = (Sprite*)(data + 1289634); - - spritesSeqCount = *((uint32*)(data + 1292130)); - spritesSeq = (SpriteSeq*)(data + 1292130 + 4); - meshData = data + 908172 + 4; meshOffsets = (uint32*)(data + 975724 + 4); nodes = (int32*)(data + 990318); - modelsCount = *((uint32*)(data + 1270666)); - const uint8* modelsPtr = (uint8*)(data + 1270666 + 4); + modelsCount = *((uint32*)(data + 1270666 + MDL_OFF)); + const uint8* modelsPtr = (uint8*)(data + 1270666 + 4 + MDL_OFF); - entitiesCount = *((uint32*)(data + 1319252)); - entities = (Entity*)(data + 1319252 + 4); + texturesCount = *((uint32*)(data + 1271686 + MDL_OFF)); + textures = (Texture*)(data + 1271686 + 4 + MDL_OFF); + + sprites = (Sprite*)(data + 1289634 + MDL_OFF); + + spritesSeqCount = *((uint32*)(data + 1292130 + MDL_OFF)); + spritesSeq = (SpriteSeq*)(data + 1292130 + 4 + MDL_OFF); + + entitiesCount = *((uint32*)(data + 1319252 + MDL_OFF + ENT_OFF)); + entities = (Entity*)(data + 1319252 + 4 + MDL_OFF + ENT_OFF); // prepare lightmap - const uint8* f_lightmap = data + 1320576; + const uint8* f_lightmap = data + 1320576 + MDL_OFF + ENT_OFF; memcpy(lightmap, f_lightmap, sizeof(lightmap)); // prepare palette #if !(defined(USE_MODE_5) || defined(_WIN32)) uint16 palette[256]; #endif - const uint8* f_palette = data + 1328768; + const uint8* f_palette = data + 1328768 + MDL_OFF + ENT_OFF; const uint8* p = f_palette; diff --git a/src/platform/gba/main.cpp b/src/platform/gba/main.cpp index d1d4ef2..b379c72 100644 --- a/src/platform/gba/main.cpp +++ b/src/platform/gba/main.cpp @@ -42,10 +42,87 @@ void update(int32 frames) { } } +#ifdef WIN32 +extern Vertex gVertices[MAX_VERTICES]; + +INLINE int32 classify(const Vertex* v) { + return (v->x < clip.x0 ? 1 : 0) | + (v->x > clip.x1 ? 2 : 0) | + (v->y < clip.y0 ? 4 : 0) | + (v->y > clip.y1 ? 8 : 0); +} + +void drawTest() { + static Rect testClip = { 0, 0, FRAME_WIDTH, FRAME_HEIGHT }; + static int32 testTile = 707; // 712 + + int dx = 0; + int dy = 0; + + if (GetAsyncKeyState(VK_LEFT)) dx--; + if (GetAsyncKeyState(VK_RIGHT)) dx++; + if (GetAsyncKeyState(VK_UP)) dy--; + if (GetAsyncKeyState(VK_DOWN)) dy++; + + if (GetAsyncKeyState('T')) { + testClip.x0 += dx; + testClip.y0 += dy; + } + + if (GetAsyncKeyState('B')) { + testClip.x1 += dx; + testClip.y1 += dy; + } + + if (GetAsyncKeyState('U')) { + testTile += dx; + if (testTile < 0) testTile = 0; + if (testTile >= texturesCount) testTile = texturesCount - 1; + } + + clip = testClip; + + gVertices[0].x = 50 + 50; + gVertices[0].y = 50; + + gVertices[1].x = FRAME_WIDTH - 50 - 50; + gVertices[1].y = 50; + + gVertices[2].x = FRAME_WIDTH - 50; + gVertices[2].y = FRAME_HEIGHT - 50; + + gVertices[3].x = 50; + gVertices[3].y = FRAME_HEIGHT - 50; + + for (int i = 0; i < 4; i++) { + gVertices[i].z = 100; + gVertices[i].g = 128; + gVertices[i].clip = classify(gVertices + i); + } + gVerticesCount = 4; + + Index indices[] = { 0, 1, 2, 3, 0, 2, 3 }; + + faceAddQuad(testTile, indices, 0); + + for (int y = 0; y < FRAME_HEIGHT; y++) { + for (int x = 0; x < FRAME_WIDTH; x++) { + if (x == clip.x0 || x == clip.x1 - 1 || y == clip.y0 || y == clip.y1 - 1) + fb[y * FRAME_WIDTH + x] = 255; + } + } + + flush(); + + Sleep(16); +} +#endif + void render() { clear(); drawRooms(); + //drawTest(); drawNumber(fps, FRAME_WIDTH, 16); } @@ -112,7 +189,7 @@ void vblank() { int main(void) { #ifdef _WIN32 { - FILE *f = fopen("C:/Projects/TR/TR1_ANDROID/LEVEL1.PHD", "rb"); + FILE *f = fopen("data/LEVEL1.PHD", "rb"); fseek(f, 0, SEEK_END); int32 size = ftell(f); fseek(f, 0, SEEK_SET); diff --git a/src/platform/gba/render.iwram.cpp b/src/platform/gba/render.iwram.cpp index c3d42fd..5327663 100644 --- a/src/platform/gba/render.iwram.cpp +++ b/src/platform/gba/render.iwram.cpp @@ -17,9 +17,11 @@ uint16 divTable[DIV_TABLE_SIZE]; extern uint16 palette[256]; #endif -extern uint8 lightmap[256 * 32]; -extern const uint8* tiles[15]; -extern const Texture* textures; +uint8 lightmap[256 * 32]; + +const uint8* tiles[15]; + +const Texture* textures; uint32 gVerticesCount = 0; Vertex gVertices[MAX_VERTICES]; @@ -33,7 +35,6 @@ uint16 mipMask; Rect clip; - const int16 sin_table[] = { // 1025 0x0000, 0x0019, 0x0032, 0x004B, 0x0065, 0x007E, 0x0097, 0x00B0, 0x00C9, 0x00E2, 0x00FB, 0x0114, 0x012E, 0x0147, 0x0160, 0x0179, @@ -275,8 +276,7 @@ INLINE void swap(T &a, T &b) { } INLINE bool checkBackface(const Vertex *a, const Vertex *b, const Vertex *c) { - return (b->x - a->x) * (c->y - a->y) - - (c->x - a->x) * (b->y - a->y) <= 0; + return (b->x - a->x) * (c->y - a->y) <= (c->x - a->x) * (b->y - a->y); } INLINE void sortVertices(Vertex *&t, Vertex *&m, Vertex *&b) { @@ -334,14 +334,25 @@ void transform(const vec3s &v, int32 vg) { res.g = vg >> 8; z >>= FOV_SHIFT; - x = (x / z) + (FRAME_WIDTH / 2); - y = (y / z) + (FRAME_HEIGHT / 2); + +#if 0 + x >>= 12; + y >>= 12; + z >>= 12; + uint32 iz = FixedInvU(z); + + x = (x * iz) >> 16; + y = (y * iz) >> 16; +#else + x = (x / z); + y = (y / z); +#endif //x = clamp(x, -0x7FFF, 0x7FFF); //y = clamp(y, -0x7FFF, 0x7FFF); - res.x = x; - res.y = y; + res.x = x + (FRAME_WIDTH / 2); + res.y = y + (FRAME_HEIGHT / 2); res.z = fogZ; res.clip = classify(&res); } @@ -416,7 +427,7 @@ struct Edge { h = v2->y - v1->y; x = v1->x << 16; g = v1->g << 16; - t = (v1->u << 24) | (v1->v << 8); + t = (v1->uv >> 16) | (v1->uv << 16); // TODO preprocess if (h > 1) { uint32 d = FixedInvU(h); @@ -424,10 +435,10 @@ struct Edge { dx = d * (v2->x - v1->x); dg = d * (v2->g - v1->g); - int32 du = d * (v2->u - v1->u); - int32 dv = d * (v2->v - v1->v); + int32 du = d * ((v2->uv & 0xFFFF) - (v1->uv & 0xFFFF)); + int32 dv = d * ((v2->uv >> 16) - (v1->uv >> 16)); - dt = ((du << 8) & 0xFFFF0000) | int16(dv >> 8); + dt = (du & 0xFFFF0000) | int16(dv >> 16); } return true; @@ -708,12 +719,9 @@ void drawTriangle(const Face* face) { palIndex = 0xFFFF; curTile = tiles[tex.tile]; if (!clipped) { - v1->u = tex.x0; - v1->v = tex.y0; - v2->u = tex.x1; - v2->v = tex.y1; - v3->u = tex.x2; - v3->v = tex.y2; + v1->uv = tex.uv0; + v2->uv = tex.uv1; + v3->uv = tex.uv2; } } @@ -779,15 +787,12 @@ void drawQuad(const Face* face) { const Texture &tex = textures[palIndex]; palIndex = 0xFFFF; curTile = tiles[tex.tile]; + if (!clipped) { - v1->u = tex.x0; - v1->v = tex.y0; - v2->u = tex.x1; - v2->v = tex.y1; - v3->u = tex.x2; - v3->v = tex.y2; - v4->u = tex.x3; - v4->v = tex.y3; + v1->uv = tex.uv0; + v2->uv = tex.uv1; + v3->uv = tex.uv2; + v4->uv = tex.uv3; } } @@ -930,7 +935,7 @@ void drawGlyph(const Sprite *sprite, int32 x, int32 y) { } void faceAddPolyClip(uint16 flags, Vertex** poly, int32 pCount, int32 depth) { - #define LERP(a,b,t) (b + ((a - b) * t >> 16)) + #define LERP(a,b,t) ((b) + (((a) - (b)) * t >> 16)) #define CLIP_AXIS(X, Y, edge, output) {\ uint32 t = ((edge - b->X) << 16) / (a->X - b->X);\ @@ -938,8 +943,7 @@ void faceAddPolyClip(uint16 flags, Vertex** poly, int32 pCount, int32 depth) { v->X = edge;\ v->Y = LERP(a->Y, b->Y, t);\ v->z = LERP(a->z, b->z, t);\ - v->u = LERP(a->u, b->u, t);\ - v->v = LERP(a->v, b->v, t);\ + v->uv = (LERP(a->uv & 0xFFFF, b->uv & 0xFFFF, t)) | (LERP(a->uv >> 16, b->uv >> 16, t) << 16);\ v->g = LERP(a->g, b->g, t);\ } @@ -969,15 +973,11 @@ void faceAddPolyClip(uint16 flags, Vertex** poly, int32 pCount, int32 depth) { if (!(flags & FACE_COLORED)) { const Texture &tex = textures[flags & FACE_TEXTURE]; curTile = tiles[tex.tile]; - poly[0]->u = tex.x0; - poly[0]->v = tex.y0; - poly[1]->u = tex.x1; - poly[1]->v = tex.y1; - poly[2]->u = tex.x2; - poly[2]->v = tex.y2; + poly[0]->uv = tex.uv0; + poly[1]->uv = tex.uv1; + poly[2]->uv = tex.uv2; if (pCount == 4) { - poly[3]->u = tex.x3; - poly[3]->v = tex.y3; + poly[3]->uv = tex.uv3; } } @@ -1103,7 +1103,9 @@ void faceSort(Face** faces, int32 L, int32 R) { if (R > i) faceSort(faces, i, R); } -//int32 gFacesCountMax, gVerticesCountMax; +#ifdef DEBUG_FACES + int32 gFacesCountMax, gVerticesCountMax; +#endif void flush() { if (gFacesCount) { @@ -1129,17 +1131,20 @@ void flush() { } } - //if (gFacesCount > gFacesCountMax) gFacesCountMax = gFacesCount; - //if (gVerticesCount > gVerticesCountMax) gVerticesCountMax = gVerticesCount; - //printf("%d %d\n", gFacesCountMax, gVerticesCountMax); +#ifdef DEBUG_FACES + if (gFacesCount > gFacesCountMax) gFacesCountMax = gFacesCount; + if (gVerticesCount > gVerticesCountMax) gVerticesCountMax = gVerticesCount; + printf("%d %d\n", gFacesCountMax, gVerticesCountMax); +#endif gVerticesCount = 0; gFacesCount = 0; } void initRender() { - divTable[0] = 0; - for (uint32 i = 1; i < DIV_TABLE_SIZE; i++) { + divTable[0] = 0xFFFF; + divTable[1] = 0xFFFF; + for (uint32 i = 2; i < DIV_TABLE_SIZE; i++) { divTable[i] = (1 << 16) / i; } }