mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-07 21:56:37 +02:00
GBA scaling (optional)
This commit is contained in:
@@ -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
|
||||||
|
@@ -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;
|
||||||
|
@@ -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))
|
||||||
|
Reference in New Issue
Block a user