1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-08 14:16:52 +02:00

GBA scaling (optional)

This commit is contained in:
Timur Gagiev
2020-08-21 01:04:51 +03:00
parent 645b58669c
commit 7c728c4632
3 changed files with 63 additions and 22 deletions

View File

@@ -23,6 +23,9 @@
#include <assert.h> #include <assert.h>
//#define USE_MODE_5 //#define USE_MODE_5
//#define DEBUG_OVERDRAW
#define SCALE 1
#ifdef USE_MODE_5 #ifdef USE_MODE_5
#define WIDTH 160 #define WIDTH 160
@@ -33,8 +36,8 @@
#else // MODE_4 #else // MODE_4
#define WIDTH 240 #define WIDTH 240
#define HEIGHT 160 #define HEIGHT 160
#define FRAME_WIDTH 240 #define FRAME_WIDTH (240/SCALE)
#define FRAME_HEIGHT 160 #define FRAME_HEIGHT (160/SCALE)
#define PIXEL_SIZE 2 #define PIXEL_SIZE 2
#endif #endif
@@ -198,6 +201,25 @@ struct Entity {
uint16 flags; 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 { struct Texture {
uint16 attribute; uint16 attribute;
uint16 tile:14, :2; uint16 tile:14, :2;
@@ -242,16 +264,17 @@ struct Face {
}; };
#define FIXED_SHIFT 14 #define FIXED_SHIFT 14
#define FOV_SHIFT 7 #define FOV_SHIFT (7 - (SCALE - 1))
#define MAX_MATRICES 8 #define MAX_MATRICES 8
#define MAX_MODELS 64 #define MAX_MODELS 64
#define MAX_ENTITY 190 #define MAX_ENTITY 190
#define MAX_VERTICES 1024 #define MAX_VERTICES 1024
#define MAX_FACES 384 #define MAX_FACES 384
#define FOG_MAX (16 * 1024) #define FOG_SHIFT 2
#define FOG_MIN (FOG_MAX - 8192) #define FOG_MAX (10 * 1024)
#define VIEW_MIN_F ((32) << FIXED_SHIFT) #define FOG_MIN (FOG_MAX - (8192 >> FOG_SHIFT))
#define VIEW_MIN_F (32 << FIXED_SHIFT)
#define VIEW_MAX_F (FOG_MAX << FIXED_SHIFT) #define VIEW_MAX_F (FOG_MAX << FIXED_SHIFT)
#define FACE_TRIANGLE 0x8000 #define FACE_TRIANGLE 0x8000

View File

@@ -47,7 +47,7 @@ void render() {
drawRooms(); drawRooms();
drawNumber(fps, WIDTH, 16); drawNumber(fps, FRAME_WIDTH, 16);
} }
#ifdef _WIN32 #ifdef _WIN32
@@ -61,8 +61,13 @@ void blit() {
} }
#else #else
for (int i = 0; i < WIDTH * HEIGHT; i++) { 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]]; uint16 c = palette[((uint8*)fb)[i]];
SCREEN[i] = (((c << 3) & 0xFF) << 16) | ((((c >> 5) << 3) & 0xFF) << 8) | ((c >> 10 << 3) & 0xFF) | 0xFF000000; SCREEN[i] = (((c << 3) & 0xFF) << 16) | ((((c >> 5) << 3) & 0xFF) << 8) | ((c >> 10 << 3) & 0xFF) | 0xFF000000;
#endif
} }
#endif #endif
@@ -175,6 +180,9 @@ int main(void) {
REG_BG2PD = 256 - 48 - 2; REG_BG2PD = 256 - 48 - 2;
#else #else
mode |= MODE_4; mode |= MODE_4;
REG_BG2PA = 256 / SCALE;
REG_BG2PD = 256 / SCALE;
#endif #endif
int32 lastFrameIndex = -1; int32 lastFrameIndex = -1;

View File

@@ -268,13 +268,13 @@ int32 clamp(int32 x, int32 a, int32 b) {
} }
template <class T> template <class T>
inline void swap(T &a, T &b) { INLINE void swap(T &a, T &b) {
T tmp = a; T tmp = a;
a = b; a = b;
b = tmp; 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) - return (b->x - a->x) * (c->y - a->y) -
(c->x - a->x) * (b->y - a->y) <= 0; (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); int32 z = DP43(m[2], v);
if (z < VIEW_MIN_F || z >= VIEW_MAX_F) { // TODO znear clip if (z < VIEW_MIN_F || z >= VIEW_MAX_F) { // TODO znear clip
res.clip = 16;
res.z = -1; res.z = -1;
return; return;
} }
@@ -325,7 +326,7 @@ void transform(const vec3s &v, int32 vg) {
if (fogZ > FOG_MAX) { if (fogZ > FOG_MAX) {
vg = 8191; vg = 8191;
} else if (fogZ > FOG_MIN) { } else if (fogZ > FOG_MIN) {
vg += fogZ - FOG_MIN; vg += (fogZ - FOG_MIN) << FOG_SHIFT;
if (vg > 8191) { if (vg > 8191) {
vg = 8191; vg = 8191;
} }
@@ -335,21 +336,25 @@ void transform(const vec3s &v, int32 vg) {
z >>= FOV_SHIFT; z >>= FOV_SHIFT;
x = (x / z) + (FRAME_WIDTH / 2); x = (x / z) + (FRAME_WIDTH / 2);
y = (y / z) + (FRAME_HEIGHT / 2); y = (y / z) + (FRAME_HEIGHT / 2);
z >>= (FIXED_SHIFT - FOV_SHIFT - 1);
//x = clamp(x, -0x7FFF, 0x7FFF); //x = clamp(x, -0x7FFF, 0x7FFF);
//y = clamp(y, -0x7FFF, 0x7FFF); //y = clamp(y, -0x7FFF, 0x7FFF);
res.x = x; res.x = x;
res.y = y; res.y = y;
res.z = z; res.z = fogZ;
res.clip = classify(&res); 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() curTile[(t & 0xFF00) | (t >> 24)]
#define FETCH_T_MIP() curTile[(t & 0xFF00) | (t >> 24) & mipMask] #define FETCH_T_MIP() curTile[(t & 0xFF00) | (t >> 24) & mipMask]
#define FETCH_GT() lightmap[(g & 0x1F00) | FETCH_T()] #define FETCH_GT() lightmap[(g & 0x1F00) | FETCH_T()]
#define FETCH_G(palIndex) lightmap[(g & 0x1F00) | palIndex] #define FETCH_G(palIndex) lightmap[(g & 0x1F00) | palIndex]
#endif
#define FETCH_GT_PAL() palette[FETCH_GT()] #define FETCH_GT_PAL() palette[FETCH_GT()]
#define FETCH_G_PAL(palIndex) palette[FETCH_G(palIndex)] #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 #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 (1)
{ {
while (L.h <= 0) 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 (1)
{ {
while (L.h <= 0) while (L.h <= 0)
@@ -741,9 +751,9 @@ void drawTriangle(const Face* face) {
} }
if (palIndex != 0xFFFF) { if (palIndex != 0xFFFF) {
rasterizeG((uint16*)fb + v1->y * (WIDTH / PIXEL_SIZE), palIndex, L, R); rasterizeG(v1->y, palIndex, L, R);
} else { } 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); } while (poly[b] != v1);
if (palIndex != 0xFFFF) { if (palIndex != 0xFFFF) {
rasterizeG((uint16*)fb + v1->y * (WIDTH / PIXEL_SIZE), palIndex, L, R); rasterizeG(v1->y, palIndex, L, R);
} else { } 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; Vertex *v1 = gVertices + start + t;
if (palIndex != 0xFFFF) { if (palIndex != 0xFFFF) {
rasterizeG((uint16*)fb + v1->y * (WIDTH / PIXEL_SIZE), palIndex, L, R); rasterizeG(v1->y, palIndex, L, R);
} else { } 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* v3 = gVertices + startVertex + indices[2];
Vertex* v4 = gVertices + startVertex + indices[3]; 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; return;
if (checkBackface(v1, v2, v3)) 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* v2 = gVertices + startVertex + indices[1];
Vertex* v3 = gVertices + startVertex + indices[2]; 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; return;
if (checkBackface(v1, v2, v3)) if (checkBackface(v1, v2, v3))