From 7c728c4632d9f2899449a7fa6b95d9c661dbcbfc Mon Sep 17 00:00:00 2001 From: Timur Gagiev Date: Fri, 21 Aug 2020 01:04:51 +0300 Subject: [PATCH] GBA scaling (optional) --- src/platform/gba/common.h | 35 ++++++++++++++++++++++----- src/platform/gba/main.cpp | 10 +++++++- src/platform/gba/render.iwram.cpp | 40 +++++++++++++++++++------------ 3 files changed, 63 insertions(+), 22 deletions(-) diff --git a/src/platform/gba/common.h b/src/platform/gba/common.h index 8607d25..464fcb5 100644 --- a/src/platform/gba/common.h +++ b/src/platform/gba/common.h @@ -23,6 +23,9 @@ #include //#define USE_MODE_5 +//#define DEBUG_OVERDRAW + +#define SCALE 1 #ifdef USE_MODE_5 #define WIDTH 160 @@ -33,8 +36,8 @@ #else // MODE_4 #define WIDTH 240 #define HEIGHT 160 - #define FRAME_WIDTH 240 - #define FRAME_HEIGHT 160 + #define FRAME_WIDTH (240/SCALE) + #define FRAME_HEIGHT (160/SCALE) #define PIXEL_SIZE 2 #endif @@ -198,6 +201,25 @@ struct Entity { uint16 flags; }; +struct EntityDesc { // 32 bytes + uint16 type; + uint16 flags; + + vec3i pos; + + vec3s rot; + uint8 state; + uint8 targetState; + + uint8 vSpeed; + uint8 hSpeed; + uint8 room; + uint8 modelIndex; + + uint16 animIndex; + uint16 frameIndex; +}; + struct Texture { uint16 attribute; uint16 tile:14, :2; @@ -242,16 +264,17 @@ struct Face { }; #define FIXED_SHIFT 14 -#define FOV_SHIFT 7 +#define FOV_SHIFT (7 - (SCALE - 1)) #define MAX_MATRICES 8 #define MAX_MODELS 64 #define MAX_ENTITY 190 #define MAX_VERTICES 1024 #define MAX_FACES 384 -#define FOG_MAX (16 * 1024) -#define FOG_MIN (FOG_MAX - 8192) -#define VIEW_MIN_F ((32) << FIXED_SHIFT) +#define FOG_SHIFT 2 +#define FOG_MAX (10 * 1024) +#define FOG_MIN (FOG_MAX - (8192 >> FOG_SHIFT)) +#define VIEW_MIN_F (32 << FIXED_SHIFT) #define VIEW_MAX_F (FOG_MAX << FIXED_SHIFT) #define FACE_TRIANGLE 0x8000 diff --git a/src/platform/gba/main.cpp b/src/platform/gba/main.cpp index 7165e6e..d1d4ef2 100644 --- a/src/platform/gba/main.cpp +++ b/src/platform/gba/main.cpp @@ -47,7 +47,7 @@ void render() { drawRooms(); - drawNumber(fps, WIDTH, 16); + drawNumber(fps, FRAME_WIDTH, 16); } #ifdef _WIN32 @@ -61,8 +61,13 @@ void blit() { } #else for (int i = 0; i < WIDTH * HEIGHT; i++) { + #ifdef DEBUG_OVERDRAW + uint8 c = ((uint8*)fb)[i]; + SCREEN[i] = c | (c << 8) | (c << 16) | 0xFF000000; + #else uint16 c = palette[((uint8*)fb)[i]]; SCREEN[i] = (((c << 3) & 0xFF) << 16) | ((((c >> 5) << 3) & 0xFF) << 8) | ((c >> 10 << 3) & 0xFF) | 0xFF000000; + #endif } #endif @@ -175,6 +180,9 @@ int main(void) { REG_BG2PD = 256 - 48 - 2; #else mode |= MODE_4; + + REG_BG2PA = 256 / SCALE; + REG_BG2PD = 256 / SCALE; #endif int32 lastFrameIndex = -1; diff --git a/src/platform/gba/render.iwram.cpp b/src/platform/gba/render.iwram.cpp index 10ea8bc..c3d42fd 100644 --- a/src/platform/gba/render.iwram.cpp +++ b/src/platform/gba/render.iwram.cpp @@ -268,13 +268,13 @@ int32 clamp(int32 x, int32 a, int32 b) { } template -inline void swap(T &a, T &b) { +INLINE void swap(T &a, T &b) { T tmp = a; a = b; b = tmp; } -bool checkBackface(const Vertex *a, const Vertex *b, const Vertex *c) { +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; } @@ -314,6 +314,7 @@ void transform(const vec3s &v, int32 vg) { int32 z = DP43(m[2], v); if (z < VIEW_MIN_F || z >= VIEW_MAX_F) { // TODO znear clip + res.clip = 16; res.z = -1; return; } @@ -325,7 +326,7 @@ void transform(const vec3s &v, int32 vg) { if (fogZ > FOG_MAX) { vg = 8191; } else if (fogZ > FOG_MIN) { - vg += fogZ - FOG_MIN; + vg += (fogZ - FOG_MIN) << FOG_SHIFT; if (vg > 8191) { vg = 8191; } @@ -335,21 +336,25 @@ void transform(const vec3s &v, int32 vg) { z >>= FOV_SHIFT; x = (x / z) + (FRAME_WIDTH / 2); y = (y / z) + (FRAME_HEIGHT / 2); - z >>= (FIXED_SHIFT - FOV_SHIFT - 1); //x = clamp(x, -0x7FFF, 0x7FFF); //y = clamp(y, -0x7FFF, 0x7FFF); res.x = x; res.y = y; - res.z = z; + res.z = fogZ; res.clip = classify(&res); } +#ifdef DEBUG_OVERDRAW +#define FETCH_GT() 32 +#define FETCH_G(palIndex) 32 +#else #define FETCH_T() curTile[(t & 0xFF00) | (t >> 24)] #define FETCH_T_MIP() curTile[(t & 0xFF00) | (t >> 24) & mipMask] #define FETCH_GT() lightmap[(g & 0x1F00) | FETCH_T()] #define FETCH_G(palIndex) lightmap[(g & 0x1F00) | palIndex] +#endif #define FETCH_GT_PAL() palette[FETCH_GT()] #define FETCH_G_PAL(palIndex) palette[FETCH_G(palIndex)] @@ -581,7 +586,10 @@ INLINE void scanlineGT(uint16* buffer, int32 x1, int32 x2, uint32 g, uint32 t, i #endif } -void rasterizeG(uint16* buffer, int32 palIndex, Edge &L, Edge &R) { +void rasterizeG(int16 y, int32 palIndex, Edge &L, Edge &R) +{ + uint16 *buffer = (uint16*)fb + y * (WIDTH / PIXEL_SIZE); + while (1) { while (L.h <= 0) @@ -626,8 +634,10 @@ void rasterizeG(uint16* buffer, int32 palIndex, Edge &L, Edge &R) { } } -void rasterizeGT(uint16* buffer, Edge &L, Edge &R) +void rasterizeGT(int16 y, Edge &L, Edge &R) { + uint16 *buffer = (uint16*)fb + y * (WIDTH / PIXEL_SIZE); + while (1) { while (L.h <= 0) @@ -741,9 +751,9 @@ void drawTriangle(const Face* face) { } if (palIndex != 0xFFFF) { - rasterizeG((uint16*)fb + v1->y * (WIDTH / PIXEL_SIZE), palIndex, L, R); + rasterizeG(v1->y, palIndex, L, R); } else { - rasterizeGT((uint16*)fb + v1->y * (WIDTH / PIXEL_SIZE), L, R); + rasterizeGT(v1->y, L, R); } } @@ -819,9 +829,9 @@ void drawQuad(const Face* face) { } while (poly[b] != v1); if (palIndex != 0xFFFF) { - rasterizeG((uint16*)fb + v1->y * (WIDTH / PIXEL_SIZE), palIndex, L, R); + rasterizeG(v1->y, palIndex, L, R); } else { - rasterizeGT((uint16*)fb + v1->y * (WIDTH / PIXEL_SIZE), L, R); + rasterizeGT(v1->y, L, R); } } @@ -863,9 +873,9 @@ void drawPoly(const Face* face) { Vertex *v1 = gVertices + start + t; if (palIndex != 0xFFFF) { - rasterizeG((uint16*)fb + v1->y * (WIDTH / PIXEL_SIZE), palIndex, L, R); + rasterizeG(v1->y, palIndex, L, R); } else { - rasterizeGT((uint16*)fb + v1->y * (WIDTH / PIXEL_SIZE), L, R); + rasterizeGT(v1->y, L, R); } } @@ -1012,7 +1022,7 @@ void faceAddQuad(uint16 flags, const Index* indices, int32 startVertex) { Vertex* v3 = gVertices + startVertex + indices[2]; Vertex* v4 = gVertices + startVertex + indices[3]; - if (v1->z < 0 || v2->z < 0 || v3->z < 0 || v4->z < 0) + if ((v1->clip | v2->clip | v3->clip | v4->clip) & 16) return; if (checkBackface(v1, v2, v3)) @@ -1049,7 +1059,7 @@ void faceAddTriangle(uint16 flags, const Index* indices, int32 startVertex) { Vertex* v2 = gVertices + startVertex + indices[1]; Vertex* v3 = gVertices + startVertex + indices[2]; - if (v1->z < 0 || v2->z < 0 || v3->z < 0) + if ((v1->clip | v2->clip | v3->clip) & 16) return; if (checkBackface(v1, v2, v3))