1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-05-03 17:17:55 +02:00

GBA precise UVs, reduce buffers size

This commit is contained in:
Timur Gagiev 2020-08-23 07:11:11 +03:00
parent 20678ce60c
commit 1b1cef1490
5 changed files with 159 additions and 73 deletions

View File

@ -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))

Binary file not shown.

View File

@ -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;

View File

@ -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);

View File

@ -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;
}
}