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:
parent
20678ce60c
commit
1b1cef1490
@ -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))
|
||||
|
BIN
src/platform/gba/data/LEVEL1.PHD
Normal file
BIN
src/platform/gba/data/LEVEL1.PHD
Normal file
Binary file not shown.
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user