mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-10 07:06:52 +02:00
GBA refactoring, optimizations
This commit is contained in:
@@ -19,11 +19,13 @@
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="common.iwram.cpp" />
|
||||
<ClCompile Include="render.iwram.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="camera.h" />
|
||||
<ClInclude Include="common.h" />
|
||||
<ClInclude Include="level.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
|
78
src/platform/gba/camera.h
Normal file
78
src/platform/gba/camera.h
Normal file
@@ -0,0 +1,78 @@
|
||||
#ifndef H_CAMERA
|
||||
#define H_CAMERA
|
||||
|
||||
#include "common.h"
|
||||
|
||||
uint16 camRotY = 16 << 8;
|
||||
|
||||
int32 camSinY;
|
||||
int32 camCosY;
|
||||
|
||||
int32 camX = 75162;
|
||||
int32 camY = 3072 - 1024;
|
||||
int32 camZ = 5000;
|
||||
|
||||
Rect clip;
|
||||
|
||||
#ifdef _WIN32
|
||||
#define CAM_SPEED (1 << 2)
|
||||
#define CAM_ROT_SPEED (1 << 2)
|
||||
#else
|
||||
#define CAM_SPEED (1 << 6)
|
||||
#define CAM_ROT_SPEED (1 << 8)
|
||||
#endif
|
||||
|
||||
void updateCamera() {
|
||||
if (keys[IK_LEFT]) camRotY -= CAM_ROT_SPEED;
|
||||
if (keys[IK_RIGHT]) camRotY += CAM_ROT_SPEED;
|
||||
|
||||
{
|
||||
ALIGN4 ObjAffineSource src;
|
||||
ALIGN4 ObjAffineDest dst;
|
||||
|
||||
src.sX = 0x0100;
|
||||
src.sY = 0x0100;
|
||||
src.theta = camRotY;
|
||||
|
||||
ObjAffineSet(&src, &dst, 1, 2);
|
||||
|
||||
camCosY = dst.pd << 8;
|
||||
camSinY = dst.pc << 8;
|
||||
}
|
||||
|
||||
int32 dx = camSinY;
|
||||
int32 dz = camCosY;
|
||||
|
||||
dx *= CAM_SPEED;
|
||||
dz *= CAM_SPEED;
|
||||
|
||||
dx >>= 16;
|
||||
dz >>= 16;
|
||||
|
||||
if (keys[IK_UP]) {
|
||||
camX += int32(dx);
|
||||
camZ += int32(dz);
|
||||
}
|
||||
|
||||
if (keys[IK_DOWN]) {
|
||||
camX -= int32(dx);
|
||||
camZ -= int32(dz);
|
||||
}
|
||||
|
||||
if (keys[IK_L]) {
|
||||
camX -= int32(dz);
|
||||
camZ += int32(dx);
|
||||
}
|
||||
|
||||
if (keys[IK_R]) {
|
||||
camX += int32(dz);
|
||||
camZ -= int32(dx);
|
||||
}
|
||||
|
||||
if (keys[IK_A]) camY -= CAM_SPEED;
|
||||
if (keys[IK_B]) camY += CAM_SPEED;
|
||||
|
||||
clip = { 0, 0, FRAME_WIDTH, FRAME_HEIGHT };
|
||||
}
|
||||
|
||||
#endif
|
@@ -38,7 +38,16 @@
|
||||
#define PIXEL_SIZE 2
|
||||
#endif
|
||||
|
||||
#define WND_SCALE 4
|
||||
#ifdef _WIN32
|
||||
#define INLINE inline
|
||||
|
||||
#define MyDiv(Number, Divisor) ((Number) / (Divisor))
|
||||
#else
|
||||
#define INLINE __attribute__((always_inline)) inline
|
||||
|
||||
#define MyDiv(Number, Divisor) ((Number) / (Divisor))
|
||||
//#define MyDiv(Number, Divisor) Div(Number, Divisor)
|
||||
#endif
|
||||
|
||||
typedef signed char int8;
|
||||
typedef signed short int16;
|
||||
@@ -56,16 +65,6 @@ typedef int16 Index;
|
||||
#define RAD2DEG (180.0f / PI)
|
||||
|
||||
#ifdef _WIN32
|
||||
extern uint8* LEVEL1_PHD;
|
||||
|
||||
extern uint32 VRAM[WIDTH * HEIGHT];
|
||||
|
||||
#ifdef USE_MODE_5
|
||||
extern uint16 fb[WIDTH * HEIGHT];
|
||||
#else
|
||||
extern uint8 fb[WIDTH * HEIGHT];
|
||||
#endif
|
||||
|
||||
#define IWRAM_CODE
|
||||
#define EWRAM_DATA
|
||||
|
||||
@@ -99,8 +98,6 @@ typedef int16 Index;
|
||||
|
||||
#else
|
||||
#define ALIGN4 __attribute__ ((aligned (4)))
|
||||
|
||||
extern uint32 fb;
|
||||
#endif
|
||||
|
||||
enum InputKey {
|
||||
@@ -225,7 +222,7 @@ struct Sprite {
|
||||
int16 l, t, r, b;
|
||||
};
|
||||
|
||||
struct SpriteSequence {
|
||||
struct SpriteSeq {
|
||||
uint16 type;
|
||||
uint16 unused;
|
||||
int16 sCount;
|
||||
@@ -240,9 +237,9 @@ struct Rect {
|
||||
};
|
||||
|
||||
struct Vertex {
|
||||
int16 x, y;
|
||||
int16 z;
|
||||
uint8 u, v, g, clip;
|
||||
int16 x, y, z;
|
||||
uint8 g, clip;
|
||||
uint8 u, v;
|
||||
};
|
||||
|
||||
struct Face {
|
||||
@@ -263,7 +260,16 @@ struct Face {
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
void drawGlyph(int32 index, int32 x, int32 y);
|
||||
void drawGlyph(const Sprite *sprite, int32 x, int32 y);
|
||||
void drawNumber(int32 number, int32 x, int32 y);
|
||||
|
||||
void clear();
|
||||
void transform(int32 vx, int32 vy, int32 vz, int32 vg, int32 x, int32 y, int32 z);
|
||||
void faceAddTriangle(uint16 flags, const Index* indices, int32 startVertex);
|
||||
void faceAddQuad(uint16 flags, const Index* indices, int32 startVertex);
|
||||
void flush();
|
||||
void initRender();
|
||||
|
||||
void readLevel(const uint8 *data);
|
||||
|
||||
#endif
|
317
src/platform/gba/level.h
Normal file
317
src/platform/gba/level.h
Normal file
@@ -0,0 +1,317 @@
|
||||
#ifndef H_LEVEL
|
||||
#define H_LEVEL
|
||||
|
||||
#include "common.h"
|
||||
#include "camera.h"
|
||||
|
||||
// level file data -------------------
|
||||
uint32 tilesCount;
|
||||
const uint8* tiles[15];
|
||||
|
||||
#if defined(USE_MODE_5) || defined(_WIN32)
|
||||
ALIGN4 uint16 palette[256];
|
||||
#endif
|
||||
|
||||
ALIGN4 uint8 lightmap[256 * 32];
|
||||
|
||||
uint16 roomsCount;
|
||||
const Room* rooms;
|
||||
|
||||
uint32 texturesCount;
|
||||
const Texture* textures;
|
||||
|
||||
const Sprite* sprites;
|
||||
|
||||
uint32 spritesSeqCount;
|
||||
const SpriteSeq* spritesSeq;
|
||||
|
||||
const uint8* meshData;
|
||||
const uint32* meshOffsets;
|
||||
|
||||
const int32* nodes;
|
||||
const Model* models;
|
||||
// -----------------------------------
|
||||
|
||||
struct RoomDesc {
|
||||
int32 x, z;
|
||||
uint16 vCount;
|
||||
uint16 qCount;
|
||||
uint16 tCount;
|
||||
uint16 pCount;
|
||||
const Room::Vertex* vertices;
|
||||
const Quad* quads;
|
||||
const Triangle* triangles;
|
||||
const Room::Portal* portals;
|
||||
};
|
||||
|
||||
EWRAM_DATA RoomDesc roomDescs[64];
|
||||
|
||||
#define SEQ_GLYPH_ID 190
|
||||
int32 seqGlyphs;
|
||||
|
||||
extern uint32 gVerticesCount;
|
||||
|
||||
void readLevel(const uint8 *data) { // TODO non-hardcode level loader
|
||||
tilesCount = *((uint32*)(data + 4));
|
||||
for (uint32 i = 0; i < tilesCount; i++) {
|
||||
tiles[i] = data + 8 + 256 * 256 * i;
|
||||
}
|
||||
|
||||
roomsCount = *((uint16*)(data + 720908));
|
||||
rooms = (Room*)(data + 720908 + 2);
|
||||
|
||||
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);
|
||||
|
||||
models = (Model*)(data + 1270670);
|
||||
|
||||
// prepare lightmap
|
||||
const uint8* f_lightmap = data + 1320576;
|
||||
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* p = f_palette;
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
palette[i] = (p[0] >> 1) | ((p[1] >> 1) << 5) | ((p[2] >> 1) << 10);
|
||||
p += 3;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
#ifndef USE_MODE_5
|
||||
SetPalette(palette);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// prepare glyphs
|
||||
for (uint32 i = 0; i < spritesSeqCount; i++) {
|
||||
if (spritesSeq[i].type == SEQ_GLYPH_ID) {
|
||||
seqGlyphs = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// prepare rooms
|
||||
uint8 *ptr = (uint8*)rooms;
|
||||
|
||||
for (uint16 roomIndex = 0; roomIndex < roomsCount; roomIndex++) {
|
||||
const Room *room = (Room*)ptr;
|
||||
ptr += sizeof(Room);
|
||||
|
||||
uint32 dataSize;
|
||||
memcpy(&dataSize, &room->dataSize, sizeof(dataSize));
|
||||
uint8* skipPtr = ptr + dataSize * 2;
|
||||
|
||||
RoomDesc &desc = roomDescs[roomIndex];
|
||||
|
||||
// offset
|
||||
memcpy(&desc.x, &room->info.x, sizeof(room->info.x));
|
||||
memcpy(&desc.z, &room->info.z, sizeof(room->info.z));
|
||||
|
||||
// vertices
|
||||
desc.vCount = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
desc.vertices = (Room::Vertex*)ptr;
|
||||
ptr += sizeof(Room::Vertex) * desc.vCount;
|
||||
|
||||
// quads
|
||||
desc.qCount = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
desc.quads = (Quad*)ptr;
|
||||
ptr += sizeof(Quad) * desc.qCount;
|
||||
|
||||
// triangles
|
||||
desc.tCount = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
desc.triangles = (Triangle*)ptr;
|
||||
ptr += sizeof(Triangle) * desc.tCount;
|
||||
|
||||
ptr = skipPtr;
|
||||
|
||||
// portals
|
||||
desc.pCount = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
desc.portals = (Room::Portal*)ptr;
|
||||
ptr += sizeof(Room::Portal) * desc.pCount;
|
||||
|
||||
uint16 zSectors = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
uint16 xSectors = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
//sectors = (Room::Sector*)sectors;
|
||||
ptr += sizeof(Room::Sector) * zSectors * xSectors;
|
||||
|
||||
//ambient = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
|
||||
uint16 lightsCount = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
//lights = (Room::Light*)ptr;
|
||||
ptr += sizeof(Room::Light) * lightsCount;
|
||||
|
||||
uint16 meshesCount = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
//meshes = (Room::Mesh*)ptr;
|
||||
ptr += sizeof(Room::Mesh) * meshesCount;
|
||||
|
||||
ptr += 2 + 2; // skip alternateRoom and flags
|
||||
}
|
||||
}
|
||||
|
||||
void drawRoom(int16 roomIndex) {
|
||||
RoomDesc &room = roomDescs[roomIndex];
|
||||
|
||||
int32 dx = -camX + room.x;
|
||||
int32 dy = -camY;
|
||||
int32 dz = -camZ + room.z;
|
||||
|
||||
int32 startVertex = gVerticesCount;
|
||||
|
||||
const Room::Vertex* vertices = room.vertices;
|
||||
for (uint16 i = 0; i < room.vCount; i++) {
|
||||
const Room::Vertex &v = vertices[i];
|
||||
transform(v.x, v.y, v.z, v.lighting, dx, dy, dz);
|
||||
}
|
||||
|
||||
const Quad* quads = room.quads;
|
||||
for (uint16 i = 0; i < room.qCount; i++) {
|
||||
faceAddQuad(quads[i].flags, quads[i].indices, startVertex);
|
||||
}
|
||||
|
||||
const Triangle* triangles = room.triangles;
|
||||
for (uint16 i = 0; i < room.tCount; i++) {
|
||||
faceAddTriangle(triangles[i].flags, triangles[i].indices, startVertex);
|
||||
}
|
||||
}
|
||||
|
||||
void drawMesh(int16 meshIndex, int32 x, int32 y, int32 z) {
|
||||
uint32 offset = meshOffsets[meshIndex];
|
||||
const uint8* ptr = meshData + offset;
|
||||
|
||||
ptr += 2 * 5; // skip [cx, cy, cz, radius, flags]
|
||||
|
||||
int16 vCount = *(int16*)ptr; ptr += 2;
|
||||
const int16* vertices = (int16*)ptr;
|
||||
ptr += vCount * 3 * sizeof(int16);
|
||||
|
||||
int16 nCount = *(int16*)ptr; ptr += 2;
|
||||
//const int16* normals = (int16*)ptr;
|
||||
if (nCount > 0) { // normals
|
||||
ptr += nCount * 3 * sizeof(int16);
|
||||
} else { // intensity
|
||||
ptr += vCount * sizeof(int16);
|
||||
}
|
||||
|
||||
int16 rCount = *(int16*)ptr; ptr += 2;
|
||||
Quad* rFaces = (Quad*)ptr; ptr += rCount * sizeof(Quad);
|
||||
|
||||
int16 tCount = *(int16*)ptr; ptr += 2;
|
||||
Triangle* tFaces = (Triangle*)ptr; ptr += tCount * sizeof(Triangle);
|
||||
|
||||
int16 crCount = *(int16*)ptr; ptr += 2;
|
||||
Quad* crFaces = (Quad*)ptr; ptr += crCount * sizeof(Quad);
|
||||
|
||||
int16 ctCount = *(int16*)ptr; ptr += 2;
|
||||
Triangle* ctFaces = (Triangle*)ptr; ptr += ctCount * sizeof(Triangle);
|
||||
|
||||
int32 startVertex = gVerticesCount;
|
||||
|
||||
int32 dx = x - camX;
|
||||
int32 dy = y - camY;
|
||||
int32 dz = z - camZ;
|
||||
|
||||
const int16* v = vertices;
|
||||
for (uint16 i = 0; i < vCount; i++) {
|
||||
transform(v[0], v[1], v[2], 4096, dx, dy, dz);
|
||||
v += 3;
|
||||
}
|
||||
|
||||
for (int i = 0; i < rCount; i++) {
|
||||
faceAddQuad(rFaces[i].flags, rFaces[i].indices, startVertex);
|
||||
}
|
||||
|
||||
for (int i = 0; i < crCount; i++) {
|
||||
faceAddQuad(crFaces[i].flags | FACE_COLORED, crFaces[i].indices, startVertex);
|
||||
}
|
||||
|
||||
for (int i = 0; i < tCount; i++) {
|
||||
faceAddTriangle(tFaces[i].flags, tFaces[i].indices, startVertex);
|
||||
}
|
||||
|
||||
for (int i = 0; i < ctCount; i++) {
|
||||
faceAddTriangle(ctFaces[i].flags | FACE_COLORED, ctFaces[i].indices, startVertex);
|
||||
}
|
||||
}
|
||||
|
||||
void drawModel(int32 modelIndex, int32 x, int32 y, int32 z) {
|
||||
const Model* model = models + modelIndex;
|
||||
|
||||
// non-aligned access
|
||||
uint32 node, frame;
|
||||
memcpy(&node, &model->node, sizeof(node));
|
||||
memcpy(&frame, &model->frame, sizeof(frame));
|
||||
|
||||
Node bones[32];
|
||||
memcpy(bones, nodes + node, (model->mCount - 1) * sizeof(Node));
|
||||
|
||||
const Node* n = bones;
|
||||
|
||||
struct StackItem {
|
||||
int32 x, y, z;
|
||||
} stack[4];
|
||||
StackItem *s = stack;
|
||||
|
||||
drawMesh(model->mStart, x, y, z);
|
||||
|
||||
for (int i = 1; i < model->mCount; i++) {
|
||||
if (n->flags & 1) {
|
||||
s--;
|
||||
x = s->x;
|
||||
y = s->y;
|
||||
z = s->z;
|
||||
}
|
||||
|
||||
if (n->flags & 2) {
|
||||
s->x = x;
|
||||
s->y = y;
|
||||
s->z = z;
|
||||
s++;
|
||||
}
|
||||
|
||||
x += n->x;
|
||||
y += n->y;
|
||||
z += n->z;
|
||||
n++;
|
||||
|
||||
drawMesh(model->mStart + i, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
void drawNumber(int32 number, int32 x, int32 y) {
|
||||
const int32 widths[] = { 12, 8, 10, 10, 10, 10, 10, 10, 10, 10 };
|
||||
|
||||
const Sprite *glyphSprites = sprites + spritesSeq[seqGlyphs].sStart;
|
||||
|
||||
while (number > 0) {
|
||||
x -= widths[number % 10];
|
||||
drawGlyph(glyphSprites + 52 + (number % 10), x, y);
|
||||
number /= 10;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@@ -12,397 +12,28 @@
|
||||
#include "LEVEL1_PHD.h"
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
|
||||
//#define PROFILE
|
||||
|
||||
#if defined(USE_MODE_5) || defined(_WIN32)
|
||||
extern uint16 palette[256];
|
||||
#endif
|
||||
|
||||
extern uint8 lightmap[256 * 32];
|
||||
|
||||
extern Vertex gVertices[MAX_VERTICES];
|
||||
extern uint32 gVerticesCount;
|
||||
|
||||
extern Face gFaces[MAX_FACES];
|
||||
extern int32 gFacesCount;
|
||||
|
||||
extern Rect clip;
|
||||
|
||||
extern const uint8* tiles[15];
|
||||
|
||||
extern const uint8* curTile;
|
||||
uint32 tilesCount;
|
||||
|
||||
extern int32 fps;
|
||||
|
||||
uint16 camRotY = 16 << 8;
|
||||
|
||||
extern int32 camSinY;
|
||||
extern int32 camCosY;
|
||||
|
||||
extern int32 camX;
|
||||
extern int32 camY;
|
||||
extern int32 camZ;
|
||||
|
||||
extern uint16 roomsCount;
|
||||
extern const Room* rooms;
|
||||
|
||||
extern uint32 texturesCount;
|
||||
extern const Texture* textures;
|
||||
|
||||
extern const Sprite* sprites;
|
||||
|
||||
extern uint32 spriteSequencesCount;
|
||||
extern const SpriteSequence* spriteSequences;
|
||||
|
||||
extern int32 seqGlyphs;
|
||||
|
||||
extern const uint8* meshData;
|
||||
extern const uint32* meshOffsets;
|
||||
|
||||
extern const int32* nodes;
|
||||
extern const Model* models;
|
||||
|
||||
extern void transform(int32 vx, int32 vy, int32 vz, int32 vg, int32 x, int32 y, int32 z);
|
||||
extern void faceAddTriangle(uint16 flags, const Index* indices, int32 startVertex);
|
||||
extern void faceAddQuad(uint16 flags, const Index* indices, int32 startVertex);
|
||||
extern void flush();
|
||||
extern void initRender();
|
||||
|
||||
void drawRoom(int16 roomIndex) {
|
||||
const Room *room = rooms;
|
||||
|
||||
//Room::Portal *portals;
|
||||
uint16 portalsCount;
|
||||
|
||||
//Room::Sector* sectors;
|
||||
uint16 zSectors, xSectors;
|
||||
|
||||
//uint16 ambient;
|
||||
|
||||
//Room::Light* lights;
|
||||
uint16 lightsCount;
|
||||
|
||||
//Room::Mesh* meshes;
|
||||
uint16 meshesCount;
|
||||
|
||||
uint8 *ptr = (uint8*)room;
|
||||
|
||||
while (roomIndex--) {
|
||||
uint32 dataSize;
|
||||
memcpy(&dataSize, &room->dataSize, sizeof(dataSize));
|
||||
ptr += sizeof(Room) + dataSize * 2;
|
||||
|
||||
portalsCount = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
//portals = (Room::Portal*)ptr;
|
||||
ptr += sizeof(Room::Portal) * portalsCount;
|
||||
|
||||
zSectors = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
xSectors = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
//sectors = (Room::Sector*)sectors;
|
||||
ptr += sizeof(Room::Sector) * zSectors * xSectors;
|
||||
|
||||
//ambient = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
|
||||
lightsCount = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
//lights = (Room::Light*)ptr;
|
||||
ptr += sizeof(Room::Light) * lightsCount;
|
||||
|
||||
meshesCount = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
//meshes = (Room::Mesh*)ptr;
|
||||
ptr += sizeof(Room::Mesh) * meshesCount;
|
||||
|
||||
ptr += 2 + 2; // skip alternateRoom and flags
|
||||
|
||||
room = (Room*)ptr;
|
||||
}
|
||||
|
||||
ptr += sizeof(Room);
|
||||
|
||||
uint16 vCount = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
Room::Vertex* vertices = (Room::Vertex*)ptr;
|
||||
ptr += sizeof(Room::Vertex) * vCount;
|
||||
|
||||
// non-aligned data
|
||||
int32 roomX;
|
||||
int32 roomZ;
|
||||
memcpy(&roomX, &room->info.x, sizeof(roomX));
|
||||
memcpy(&roomZ, &room->info.z, sizeof(roomZ));
|
||||
|
||||
int32 dx = -camX + roomX;
|
||||
int32 dy = -camY;
|
||||
int32 dz = -camZ + roomZ;
|
||||
|
||||
int32 startVertex = gVerticesCount;
|
||||
|
||||
for (uint16 i = 0; i < vCount; i++) {
|
||||
const Room::Vertex &v = vertices[i];
|
||||
transform(v.x, v.y, v.z, v.lighting, dx, dy, dz);
|
||||
}
|
||||
|
||||
uint16 qCount = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
Quad* quads = (Quad*)ptr;
|
||||
ptr += sizeof(Quad) * qCount;
|
||||
|
||||
for (uint16 i = 0; i < qCount; i++) {
|
||||
faceAddQuad(quads[i].flags, quads[i].indices, startVertex);
|
||||
}
|
||||
|
||||
uint16 tCount = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
Triangle* triangles = (Triangle*)ptr;
|
||||
ptr += sizeof(Triangle) * tCount;
|
||||
|
||||
for (uint16 i = 0; i < tCount; i++) {
|
||||
faceAddTriangle(triangles[i].flags, triangles[i].indices, startVertex);
|
||||
}
|
||||
}
|
||||
|
||||
void drawMesh(int16 meshIndex, int32 x, int32 y, int32 z) {
|
||||
uint32 offset = meshOffsets[meshIndex];
|
||||
const uint8* ptr = meshData + offset;
|
||||
|
||||
//int16 cx = *(int16*)ptr; ptr += 2;
|
||||
//int16 cy = *(int16*)ptr; ptr += 2;
|
||||
//int16 cz = *(int16*)ptr; ptr += 2;
|
||||
//int16 r = *(int16*)ptr; ptr += 2;
|
||||
//ptr += 2; // skip flags
|
||||
ptr += 2 * 5;
|
||||
|
||||
int16 vCount = *(int16*)ptr; ptr += 2;
|
||||
const int16* vertices = (int16*)ptr;
|
||||
ptr += vCount * 3 * sizeof(int16);
|
||||
|
||||
int16 nCount = *(int16*)ptr; ptr += 2;
|
||||
//const int16* normals = (int16*)ptr;
|
||||
if (nCount > 0) { // normals
|
||||
ptr += nCount * 3 * sizeof(int16);
|
||||
} else { // intensity
|
||||
ptr += vCount * sizeof(int16);
|
||||
}
|
||||
|
||||
int16 rCount = *(int16*)ptr; ptr += 2;
|
||||
Quad* rFaces = (Quad*)ptr; ptr += rCount * sizeof(Quad);
|
||||
|
||||
int16 tCount = *(int16*)ptr; ptr += 2;
|
||||
Triangle* tFaces = (Triangle*)ptr; ptr += tCount * sizeof(Triangle);
|
||||
|
||||
int16 crCount = *(int16*)ptr; ptr += 2;
|
||||
Quad* crFaces = (Quad*)ptr; ptr += crCount * sizeof(Quad);
|
||||
|
||||
int16 ctCount = *(int16*)ptr; ptr += 2;
|
||||
Triangle* ctFaces = (Triangle*)ptr; ptr += ctCount * sizeof(Triangle);
|
||||
|
||||
int32 startVertex = gVerticesCount;
|
||||
|
||||
int32 dx = x - camX;
|
||||
int32 dy = y - camY;
|
||||
int32 dz = z - camZ;
|
||||
|
||||
const int16* v = vertices;
|
||||
for (uint16 i = 0; i < vCount; i++) {
|
||||
transform(v[0], v[1], v[2], 4096, dx, dy, dz);
|
||||
v += 3;
|
||||
}
|
||||
|
||||
for (int i = 0; i < rCount; i++) {
|
||||
faceAddQuad(rFaces[i].flags, rFaces[i].indices, startVertex);
|
||||
}
|
||||
|
||||
for (int i = 0; i < crCount; i++) {
|
||||
faceAddQuad(crFaces[i].flags | FACE_COLORED, crFaces[i].indices, startVertex);
|
||||
}
|
||||
|
||||
for (int i = 0; i < tCount; i++) {
|
||||
faceAddTriangle(tFaces[i].flags, tFaces[i].indices, startVertex);
|
||||
}
|
||||
|
||||
for (int i = 0; i < ctCount; i++) {
|
||||
faceAddTriangle(ctFaces[i].flags | FACE_COLORED, ctFaces[i].indices, startVertex);
|
||||
}
|
||||
}
|
||||
|
||||
void drawModel(int32 modelIndex, int32 x, int32 y, int32 z) {
|
||||
const Model* model = models + modelIndex;
|
||||
|
||||
// non-aligned access
|
||||
uint32 node, frame;
|
||||
memcpy(&node, &model->node, sizeof(node));
|
||||
memcpy(&frame, &model->frame, sizeof(frame));
|
||||
|
||||
Node bones[32];
|
||||
memcpy(bones, nodes + node, (model->mCount - 1) * sizeof(Node));
|
||||
|
||||
const Node* n = bones;
|
||||
|
||||
struct StackItem {
|
||||
int32 x, y, z;
|
||||
} stack[4];
|
||||
StackItem *s = stack;
|
||||
|
||||
drawMesh(model->mStart, x, y, z);
|
||||
|
||||
for (int i = 1; i < model->mCount; i++) {
|
||||
if (n->flags & 1) {
|
||||
s--;
|
||||
x = s->x;
|
||||
y = s->y;
|
||||
z = s->z;
|
||||
}
|
||||
|
||||
if (n->flags & 2) {
|
||||
s->x = x;
|
||||
s->y = y;
|
||||
s->z = z;
|
||||
s++;
|
||||
}
|
||||
|
||||
x += n->x;
|
||||
y += n->y;
|
||||
z += n->z;
|
||||
n++;
|
||||
|
||||
drawMesh(model->mStart + i, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
void readLevel(const uint8 *data) {
|
||||
tilesCount = *((uint32*)(data + 4));
|
||||
for (uint32 i = 0; i < tilesCount; i++) {
|
||||
tiles[i] = data + 8 + 256 * 256 * i;
|
||||
}
|
||||
|
||||
roomsCount = *((uint16*)(data + 720908));
|
||||
rooms = (Room*)(data + 720908 + 2);
|
||||
|
||||
texturesCount = *((uint32*)(data + 1271686));
|
||||
textures = (Texture*)(data + 1271686 + 4);
|
||||
|
||||
sprites = (Sprite*)(data + 1289634);
|
||||
|
||||
spriteSequencesCount = *((uint32*)(data + 1292130));
|
||||
spriteSequences = (SpriteSequence*)(data + 1292130 + 4);
|
||||
|
||||
for (uint32 i = 0; i < spriteSequencesCount; i++) {
|
||||
if (spriteSequences[i].type == 190) {
|
||||
seqGlyphs = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
meshData = data + 908172 + 4;
|
||||
meshOffsets = (uint32*)(data + 975724 + 4);
|
||||
|
||||
nodes = (int32*)(data + 990318);
|
||||
|
||||
models = (Model*)(data + 1270670);
|
||||
|
||||
const uint8* f_lightmap = data + 1320576;
|
||||
memcpy(lightmap, f_lightmap, sizeof(lightmap));
|
||||
|
||||
#if !(defined(USE_MODE_5) || defined(_WIN32))
|
||||
uint16 palette[256];
|
||||
#endif
|
||||
|
||||
const uint8* f_palette = data + 1328768;
|
||||
|
||||
const uint8* p = f_palette;
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
palette[i] = (p[0] >> 1) | ((p[1] >> 1) << 5) | ((p[2] >> 1) << 10);
|
||||
p += 3;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
palette[1] = RGB8(0, 255, 0);
|
||||
|
||||
#ifndef USE_MODE_5
|
||||
SetPalette(palette);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#include "common.h"
|
||||
#include "level.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define CAM_SPEED (1 << 3)
|
||||
#define CAM_ROT_SPEED (1 << 3)
|
||||
uint8* LEVEL1_PHD;
|
||||
|
||||
uint32 SCREEN[WIDTH * HEIGHT];
|
||||
|
||||
extern uint8 fb[WIDTH * HEIGHT * 2];
|
||||
|
||||
#define WND_SCALE 4
|
||||
#else
|
||||
#define CAM_SPEED (1 << 6)
|
||||
#define CAM_ROT_SPEED (1 << 8)
|
||||
extern uint32 fb;
|
||||
#endif
|
||||
|
||||
bool keys[IK_MAX] = {};
|
||||
|
||||
void updateCamera() {
|
||||
if (keys[IK_LEFT]) camRotY -= CAM_ROT_SPEED;
|
||||
if (keys[IK_RIGHT]) camRotY += CAM_ROT_SPEED;
|
||||
|
||||
{
|
||||
ALIGN4 ObjAffineSource src;
|
||||
ALIGN4 ObjAffineDest dst;
|
||||
|
||||
src.sX = 0x0100;
|
||||
src.sY = 0x0100;
|
||||
src.theta = camRotY;
|
||||
|
||||
ObjAffineSet(&src, &dst, 1, 2);
|
||||
|
||||
camCosY = dst.pd << 8;
|
||||
camSinY = dst.pc << 8;
|
||||
}
|
||||
|
||||
int32 dx = camSinY;
|
||||
int32 dz = camCosY;
|
||||
|
||||
dx *= CAM_SPEED;
|
||||
dz *= CAM_SPEED;
|
||||
|
||||
dx >>= 16;
|
||||
dz >>= 16;
|
||||
|
||||
if (keys[IK_UP]) {
|
||||
camX += int32(dx);
|
||||
camZ += int32(dz);
|
||||
}
|
||||
|
||||
if (keys[IK_DOWN]) {
|
||||
camX -= int32(dx);
|
||||
camZ -= int32(dz);
|
||||
}
|
||||
|
||||
if (keys[IK_L]) {
|
||||
camX -= int32(dz);
|
||||
camZ += int32(dx);
|
||||
}
|
||||
|
||||
if (keys[IK_R]) {
|
||||
camX += int32(dz);
|
||||
camZ -= int32(dx);
|
||||
}
|
||||
|
||||
if (keys[IK_A]) camY -= CAM_SPEED;
|
||||
if (keys[IK_B]) camY += CAM_SPEED;
|
||||
|
||||
clip = { 0, 0, FRAME_WIDTH, FRAME_HEIGHT };
|
||||
}
|
||||
|
||||
void drawNumber(int32 number, int32 x, int32 y) {
|
||||
const int32 widths[] = { 12, 8, 10, 10, 10, 10, 10, 10, 10, 10 };
|
||||
|
||||
while (number > 0) {
|
||||
x -= widths[number % 10];
|
||||
drawGlyph(52 + (number % 10), x, y);
|
||||
number /= 10;
|
||||
}
|
||||
}
|
||||
int32 fps;
|
||||
int32 frameIndex = 0;
|
||||
int32 fpsCounter = 0;
|
||||
|
||||
void update(int32 frames) {
|
||||
for (int32 i = 0; i < frames; i++) {
|
||||
@@ -429,18 +60,18 @@ HDC hDC;
|
||||
void VBlankIntrWait() {
|
||||
#ifdef USE_MODE_5
|
||||
for (int i = 0; i < WIDTH * HEIGHT; i++) {
|
||||
uint16 c = fb[i];
|
||||
VRAM[i] = (((c << 3) & 0xFF) << 16) | ((((c >> 5) << 3) & 0xFF) << 8) | ((c >> 10 << 3) & 0xFF) | 0xFF000000;
|
||||
uint16 c = ((uint16*)fb)[i];
|
||||
SCREEN[i] = (((c << 3) & 0xFF) << 16) | ((((c >> 5) << 3) & 0xFF) << 8) | ((c >> 10 << 3) & 0xFF) | 0xFF000000;
|
||||
}
|
||||
#else
|
||||
for (int i = 0; i < WIDTH * HEIGHT; i++) {
|
||||
uint16 c = palette[fb[i]];
|
||||
VRAM[i] = (((c << 3) & 0xFF) << 16) | ((((c >> 5) << 3) & 0xFF) << 8) | ((c >> 10 << 3) & 0xFF) | 0xFF000000;
|
||||
uint16 c = palette[((uint8*)fb)[i]];
|
||||
SCREEN[i] = (((c << 3) & 0xFF) << 16) | ((((c >> 5) << 3) & 0xFF) << 8) | ((c >> 10 << 3) & 0xFF) | 0xFF000000;
|
||||
}
|
||||
#endif
|
||||
|
||||
const BITMAPINFO bmi = { sizeof(BITMAPINFOHEADER), WIDTH, -HEIGHT, 1, 32, BI_RGB, 0, 0, 0, 0, 0 };
|
||||
StretchDIBits(hDC, 0, 0, 240 * WND_SCALE, 160 * WND_SCALE, 0, 0, WIDTH, HEIGHT, VRAM, &bmi, DIB_RGB_COLORS, SRCCOPY);
|
||||
StretchDIBits(hDC, 0, 0, 240 * WND_SCALE, 160 * WND_SCALE, 0, 0, WIDTH, HEIGHT, SCREEN, &bmi, DIB_RGB_COLORS, SRCCOPY);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
@@ -473,9 +104,6 @@ LRESULT CALLBACK wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
}
|
||||
#endif
|
||||
|
||||
int32 frameIndex = 0;
|
||||
int32 fpsCounter = 0;
|
||||
|
||||
void vblank() {
|
||||
frameIndex++;
|
||||
}
|
||||
|
@@ -5,87 +5,36 @@
|
||||
uint16 divTable[DIV_TABLE_SIZE];
|
||||
|
||||
#ifdef _WIN32
|
||||
uint8* LEVEL1_PHD;
|
||||
|
||||
uint32 VRAM[WIDTH * HEIGHT];
|
||||
|
||||
#ifdef USE_MODE_5
|
||||
uint16 fb[WIDTH * HEIGHT];
|
||||
#else
|
||||
uint8 fb[WIDTH * HEIGHT];
|
||||
#endif
|
||||
|
||||
#define MyDiv(Number, Divisor) ((Number) / (Divisor))
|
||||
uint8 fb[WIDTH * HEIGHT * 2];
|
||||
#else
|
||||
uint32 fb = VRAM;
|
||||
|
||||
#define MyDiv(Number, Divisor) ((Number) / (Divisor))
|
||||
//#define MyDiv(Number, Divisor) Div(Number, Divisor)
|
||||
#endif
|
||||
|
||||
#define FixedInvS(x) ((x < 0) ? -divTable[abs(x)] : divTable[x])
|
||||
#define FixedInvU(x) divTable[x]
|
||||
|
||||
bool keys[IK_MAX] = {};
|
||||
|
||||
#if defined(USE_MODE_5) || defined(_WIN32)
|
||||
uint16 palette[256];
|
||||
extern uint16 palette[256];
|
||||
#endif
|
||||
|
||||
uint8 lightmap[256 * 32];
|
||||
extern uint8 lightmap[256 * 32];
|
||||
extern const uint8* tiles[15];
|
||||
extern const Texture* textures;
|
||||
|
||||
extern Rect clip;
|
||||
extern int32 camSinY;
|
||||
extern int32 camCosY;
|
||||
|
||||
Vertex gVertices[MAX_VERTICES];
|
||||
uint32 gVerticesCount = 0;
|
||||
EWRAM_DATA Vertex gVertices[MAX_VERTICES];
|
||||
|
||||
EWRAM_DATA Face gFaces[MAX_FACES];
|
||||
int32 gFacesCount = 0;
|
||||
|
||||
Rect clip;
|
||||
|
||||
const uint8* tiles[15];
|
||||
Face gFaces[MAX_FACES];
|
||||
Face* gFacesSorted[MAX_FACES];
|
||||
|
||||
const uint8* curTile;
|
||||
|
||||
uint16 mipMask;
|
||||
|
||||
int32 fps;
|
||||
|
||||
int32 camSinY;
|
||||
int32 camCosY;
|
||||
|
||||
int32 camX = 75162;
|
||||
int32 camY = 3072 - 1024;
|
||||
int32 camZ = 5000;
|
||||
|
||||
Vertex* Ledges[4];
|
||||
Vertex* Redges[4];
|
||||
int32 Lindex, Rindex;
|
||||
|
||||
uint16 roomsCount;
|
||||
const Room* rooms;
|
||||
|
||||
uint32 texturesCount;
|
||||
const Texture* textures;
|
||||
|
||||
const Sprite* sprites;
|
||||
|
||||
uint32 spriteSequencesCount;
|
||||
const SpriteSequence* spriteSequences;
|
||||
|
||||
int32 seqGlyphs;
|
||||
|
||||
const uint8* meshData;
|
||||
const uint32* meshOffsets;
|
||||
|
||||
const int32* nodes;
|
||||
const Model* models;
|
||||
|
||||
#ifdef WIN32
|
||||
#define INLINE inline
|
||||
#else
|
||||
#define INLINE __attribute__((always_inline)) inline
|
||||
#endif
|
||||
|
||||
int32 clamp(int32 x, int32 a, int32 b) {
|
||||
return x < a ? a : (x > b ? b : x);
|
||||
}
|
||||
@@ -261,6 +210,24 @@ struct Edge {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void build(int32 start, int32 count, int32 t, int32 b, int32 incr) {
|
||||
vert[index = 0] = gVertices + start + b;
|
||||
|
||||
for (int i = 1; i < count; i++) {
|
||||
b = (b + incr) % count;
|
||||
|
||||
Vertex *v = gVertices + start + b;
|
||||
|
||||
if (vert[index]->x != v->x || vert[index]->y != v->y) {
|
||||
vert[++index] = v;
|
||||
}
|
||||
|
||||
if (b == t) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
INLINE void scanlineG(uint16* buffer, int32 x1, int32 x2, uint8 palIndex, uint32 g, int32 dgdx) {
|
||||
@@ -317,6 +284,8 @@ INLINE void scanlineG(uint16* buffer, int32 x1, int32 x2, uint8 palIndex, uint32
|
||||
*(uint16*)pixel = p;
|
||||
pixel += 1;
|
||||
}
|
||||
|
||||
if (p == 0xFFFFFFFF) return;
|
||||
}
|
||||
|
||||
if (x2 & 1)
|
||||
@@ -388,6 +357,8 @@ INLINE void scanlineGT(uint16* buffer, int32 x1, int32 x2, uint32 g, uint32 t, i
|
||||
*(uint16*)pixel = p;
|
||||
pixel += 1;
|
||||
}
|
||||
|
||||
if (p == 0xFFFFFFFF) return;
|
||||
}
|
||||
|
||||
if (x2 & 1)
|
||||
@@ -565,7 +536,6 @@ void drawTriangle(uint16 flags, int32 start, const int8* indices)
|
||||
|
||||
void drawQuad(uint16 flags, int32 start, const int8* indices) {
|
||||
Vertex *v1, *v2, *v3, *v4;
|
||||
|
||||
bool clipped = indices[0] == indices[1];
|
||||
|
||||
if (clipped) {
|
||||
@@ -587,14 +557,14 @@ void drawQuad(uint16 flags, int32 start, const int8* indices) {
|
||||
palIndex = 0xFFFF;
|
||||
curTile = tiles[tex.tile];
|
||||
if (!clipped) {
|
||||
v1->u = int32(tex.x0);
|
||||
v1->v = int32(tex.y0);
|
||||
v2->u = int32(tex.x1);
|
||||
v2->v = int32(tex.y1);
|
||||
v3->u = int32(tex.x2);
|
||||
v3->v = int32(tex.y2);
|
||||
v4->u = int32(tex.x3);
|
||||
v4->v = int32(tex.y3);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -687,28 +657,9 @@ void drawPoly(uint16 flags, int32 start, int32 count) {
|
||||
}
|
||||
|
||||
Edge L, R;
|
||||
L.vert[L.index = 0] = gVertices + start + b;
|
||||
R.vert[R.index = 0] = gVertices + start + b;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
int32 idx = (b + count + i) % count;
|
||||
|
||||
L.vert[++L.index] = gVertices + start + idx;
|
||||
|
||||
if (idx == t) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
int32 idx = (b + count - i) % count;
|
||||
|
||||
R.vert[++R.index] = gVertices + start + idx;
|
||||
|
||||
if (idx == t) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
L.build(start, count, t, b, count + 1);
|
||||
R.build(start, count, t, b, count - 1);
|
||||
|
||||
Vertex *v1 = gVertices + start + t;
|
||||
|
||||
@@ -719,9 +670,7 @@ void drawPoly(uint16 flags, int32 start, int32 count) {
|
||||
}
|
||||
}
|
||||
|
||||
void drawGlyph(int32 index, int32 x, int32 y) {
|
||||
const Sprite* sprite = sprites + spriteSequences[seqGlyphs].sStart + index;
|
||||
|
||||
void drawGlyph(const Sprite *sprite, int32 x, int32 y) {
|
||||
int32 w = sprite->r - sprite->l;
|
||||
int32 h = sprite->b - sprite->t;
|
||||
|
||||
@@ -730,12 +679,25 @@ void drawGlyph(int32 index, int32 x, int32 y) {
|
||||
int32 ix = x + sprite->l;
|
||||
int32 iy = y + sprite->t;
|
||||
|
||||
uint16* ptr = (uint16*)fb + iy * (WIDTH / PIXEL_SIZE) + (ix >> 1);
|
||||
uint16* ptr = (uint16*)fb + iy * (WIDTH / PIXEL_SIZE);
|
||||
|
||||
#ifdef USE_MODE_5
|
||||
ptr += ix;
|
||||
#else
|
||||
ptr += ix >> 1;
|
||||
#endif
|
||||
|
||||
const uint8* glyphData = tiles[sprite->tile] + 256 * sprite->v + sprite->u;
|
||||
|
||||
while (h--)
|
||||
{
|
||||
#ifdef USE_MODE_5
|
||||
for (int i = 0; i < w; i++) {
|
||||
if (glyphData[i] == 0) continue;
|
||||
|
||||
ptr[i] = palette[glyphData[i]];
|
||||
}
|
||||
#else
|
||||
const uint8* p = glyphData;
|
||||
|
||||
for (int i = 0; i < (w / 2); i++) {
|
||||
@@ -751,14 +713,14 @@ void drawGlyph(int32 index, int32 x, int32 y) {
|
||||
|
||||
p += 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
ptr += WIDTH / PIXEL_SIZE;
|
||||
glyphData += 256;
|
||||
}
|
||||
}
|
||||
|
||||
void faceAddPolyClip(uint16 flags, Vertex** poly, int32 pCount)
|
||||
{
|
||||
void faceAddPolyClip(uint16 flags, Vertex** poly, int32 pCount) {
|
||||
#define LERP(a,b,t) (b + ((a - b) * t >> 16))
|
||||
|
||||
#define CLIP_AXIS(x, y, edge, output) {\
|
||||
@@ -798,15 +760,15 @@ void faceAddPolyClip(uint16 flags, Vertex** poly, int32 pCount)
|
||||
if (!(flags & FACE_COLORED)) {
|
||||
const Texture &tex = textures[flags & FACE_TEXTURE];
|
||||
curTile = tiles[tex.tile];
|
||||
poly[0]->u = int32(tex.x0);
|
||||
poly[0]->v = int32(tex.y0);
|
||||
poly[1]->u = int32(tex.x1);
|
||||
poly[1]->v = int32(tex.y1);
|
||||
poly[2]->u = int32(tex.x2);
|
||||
poly[2]->v = int32(tex.y2);
|
||||
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;
|
||||
if (pCount == 4) {
|
||||
poly[3]->u = int32(tex.x3);
|
||||
poly[3]->v = int32(tex.y3);
|
||||
poly[3]->u = tex.x3;
|
||||
poly[3]->v = tex.y3;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -828,23 +790,24 @@ void faceAddPolyClip(uint16 flags, Vertex** poly, int32 pCount)
|
||||
int32 y1 = clip.y1;
|
||||
CLIP_VERTEX(y, x, y0, y1, &tmp, output);
|
||||
|
||||
Face &f = gFaces[gFacesCount++];
|
||||
f.flags = flags;
|
||||
f.start = gVerticesCount;
|
||||
f.indices[0] = count;
|
||||
f.indices[1] = count;
|
||||
/*
|
||||
Face *f = gFaces + gFacesCount;
|
||||
gFacesSorted[gFacesCount++] = f;
|
||||
f->flags = flags;
|
||||
f->start = gVerticesCount;
|
||||
f->indices[0] = count;
|
||||
f->indices[1] = count;
|
||||
|
||||
if (count == 3) {
|
||||
f.flags |= FACE_TRIANGLE;
|
||||
f.depth = (output[0].z + output[1].z + output[2].z) / 3;
|
||||
f->flags |= FACE_TRIANGLE;
|
||||
f->depth = (output[0].z + output[1].z + output[2].z) / 3;
|
||||
} else if (count == 4) {
|
||||
f.depth = (output[0].z + output[1].z + output[2].z + output[3].z) >> 2;
|
||||
} else*/ {
|
||||
f->depth = (output[0].z + output[1].z + output[2].z + output[3].z) >> 2;
|
||||
} else {
|
||||
int32 depth = output[0].z;
|
||||
for (int32 i = 1; i < count; i++) {
|
||||
depth = (depth + output[i].z) >> 1;
|
||||
}
|
||||
f.depth = depth;
|
||||
f->depth = depth;
|
||||
}
|
||||
|
||||
gVerticesCount += count;
|
||||
@@ -874,14 +837,15 @@ void faceAddQuad(uint16 flags, const Index* indices, int32 startVertex) {
|
||||
Vertex* poly[4] = { v1, v2, v3, v4 };
|
||||
faceAddPolyClip(flags, poly, 4);
|
||||
} else {
|
||||
Face &f = gFaces[gFacesCount++];
|
||||
f.flags = flags;
|
||||
f.depth = (v1->z + v2->z + v3->z + v4->z) >> 2;
|
||||
f.start = startVertex + indices[0];
|
||||
f.indices[0] = 0;
|
||||
f.indices[1] = indices[1] - indices[0];
|
||||
f.indices[2] = indices[2] - indices[0];
|
||||
f.indices[3] = indices[3] - indices[0];
|
||||
Face *f = gFaces + gFacesCount;
|
||||
gFacesSorted[gFacesCount++] = f;
|
||||
f->flags = flags;
|
||||
f->depth = (v1->z + v2->z + v3->z + v4->z) >> 2;
|
||||
f->start = startVertex + indices[0];
|
||||
f->indices[0] = 0;
|
||||
f->indices[1] = indices[1] - indices[0];
|
||||
f->indices[2] = indices[2] - indices[0];
|
||||
f->indices[3] = indices[3] - indices[0];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -908,41 +872,56 @@ void faceAddTriangle(uint16 flags, const Index* indices, int32 startVertex) {
|
||||
Vertex* poly[3] = { v1, v2, v3 };
|
||||
faceAddPolyClip(flags, poly, 3);
|
||||
} else {
|
||||
Face &f = gFaces[gFacesCount++];
|
||||
f.flags = flags | FACE_TRIANGLE;
|
||||
f.depth = (v1->z + v2->z + v3->z) / 3;
|
||||
f.start = startVertex + indices[0];
|
||||
f.indices[0] = 0;
|
||||
f.indices[1] = indices[1] - indices[0];
|
||||
f.indices[2] = indices[2] - indices[0];
|
||||
Face *f = gFaces + gFacesCount;
|
||||
gFacesSorted[gFacesCount++] = f;
|
||||
f->flags = flags | FACE_TRIANGLE;
|
||||
f->depth = (v1->z + v2->z + v3->z) / 3;
|
||||
f->start = startVertex + indices[0];
|
||||
f->indices[0] = 0;
|
||||
f->indices[1] = indices[1] - indices[0];
|
||||
f->indices[2] = indices[2] - indices[0];
|
||||
}
|
||||
}
|
||||
|
||||
int faceCmp(const void *a, const void *b) {
|
||||
return ((Face*)b)->depth - ((Face*)a)->depth;
|
||||
void faceSort(Face** faces, int32 L, int32 R) {
|
||||
int32 i = L;
|
||||
int32 j = R;
|
||||
int16 depth = faces[(i + j) >> 1]->depth;
|
||||
|
||||
while (i <= j) {
|
||||
while (faces[i]->depth > depth) i++;
|
||||
while (faces[j]->depth < depth) j--;
|
||||
|
||||
if (i <= j) {
|
||||
swap(faces[i++], faces[j--]);
|
||||
}
|
||||
};
|
||||
|
||||
if (L < j) faceSort(faces, L, j);
|
||||
if (R > i) faceSort(faces, i, R);
|
||||
}
|
||||
|
||||
//int32 gFacesCountMax, gVerticesCountMax;
|
||||
|
||||
void flush() {
|
||||
if (gFacesCount) {
|
||||
qsort(gFaces, gFacesCount, sizeof(Face), faceCmp);
|
||||
faceSort(gFacesSorted, 0, gFacesCount - 1);
|
||||
|
||||
//const uint16 mips[] = { 0xFFFF, 0xFEFE, 0xFCFC, 0xF8F8 };
|
||||
|
||||
for (int32 i = 0; i < gFacesCount; i++) {
|
||||
const Face &f = gFaces[i];
|
||||
const Face *f = gFacesSorted[i];
|
||||
|
||||
// TODO
|
||||
//mipMask = mips[MIN(3, f.depth / 2048)];
|
||||
|
||||
if (f.flags & FACE_TRIANGLE) {
|
||||
drawTriangle(f.flags, f.start, f.indices);
|
||||
if (f->flags & FACE_TRIANGLE) {
|
||||
drawTriangle(f->flags, f->start, f->indices);
|
||||
} else {
|
||||
if (f.indices[0] == f.indices[1] /* && f.indices[0] > 4 */) {
|
||||
drawPoly(f.flags, f.start, f.indices[0]);
|
||||
if (f->indices[0] == f->indices[1] /* && f.indices[0] > 4 */) {
|
||||
drawPoly(f->flags, f->start, f->indices[0]);
|
||||
} else {
|
||||
drawQuad(f.flags, f.start, f.indices);
|
||||
drawQuad(f->flags, f->start, f->indices);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user