mirror of
https://github.com/XProger/OpenLara.git
synced 2025-03-13 23:59:41 +01:00
GBA objects and animations, remove MODE4 code
This commit is contained in:
parent
5690d64901
commit
310e8c9dc0
@ -3,8 +3,8 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define CAM_SPEED (1 << 2)
|
||||
#define CAM_ROT_SPEED (1 << 8)
|
||||
#define CAM_SPEED (1 << 3)
|
||||
#define CAM_ROT_SPEED (1 << 9)
|
||||
#define CAM_ROT_X_MAX int16(85 * 0x8000 / 180)
|
||||
|
||||
struct Camera {
|
||||
@ -19,6 +19,9 @@ struct Camera {
|
||||
|
||||
rotX = 0;
|
||||
rotY = 16 << 8;
|
||||
|
||||
//rotX = -0x1000;
|
||||
//rotY = int16(0x8000);
|
||||
}
|
||||
|
||||
void update() {
|
||||
@ -29,7 +32,7 @@ struct Camera {
|
||||
|
||||
rotX = clamp(rotX, -CAM_ROT_X_MAX, CAM_ROT_X_MAX);
|
||||
|
||||
matrixSetView(pos, rotX, rotY);
|
||||
matrixSetView(pos.x, pos.y, pos.z, rotX, rotY);
|
||||
|
||||
Matrix &m = matrixGet();
|
||||
|
||||
@ -57,7 +60,7 @@ struct Camera {
|
||||
pos.z -= m[2].z * CAM_SPEED >> 10;
|
||||
}
|
||||
|
||||
room = getRoomIndex(room, pos);
|
||||
room = getRoomIndex(room, &pos);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
#include "common.h"
|
||||
|
||||
vec3i viewPos;
|
||||
|
||||
extern Matrix matrixStack[MAX_MATRICES];
|
||||
extern int32 matrixStackIndex;
|
||||
uint16 divTable[DIV_TABLE_SIZE]; // IWRAM 0.5 kb
|
||||
vec3i viewPos;
|
||||
Matrix matrixStack[MAX_MATRICES];
|
||||
int32 matrixStackIndex = 0;
|
||||
|
||||
const int16 sin_table[1025] = { // IWRAM 2 kb
|
||||
0x0000, 0x0019, 0x0032, 0x004B, 0x0065, 0x007E, 0x0097, 0x00B0,
|
||||
@ -160,76 +160,171 @@ int32 clamp(int32 x, int32 a, int32 b) {
|
||||
return x < a ? a : (x > b ? b : x);
|
||||
}
|
||||
|
||||
Matrix& matrixGet() {
|
||||
void initLUT() {
|
||||
divTable[0] = 0xFFFF;
|
||||
divTable[1] = 0xFFFF;
|
||||
for (uint32 i = 2; i < DIV_TABLE_SIZE; i++) {
|
||||
divTable[i] = (1 << 16) / i;
|
||||
}
|
||||
}
|
||||
|
||||
Matrix& matrixGet()
|
||||
{
|
||||
return matrixStack[matrixStackIndex];
|
||||
}
|
||||
|
||||
void matrixPush() {
|
||||
#if defined(_WIN32)
|
||||
if (matrixStackIndex >= MAX_MATRICES - 1) {
|
||||
DebugBreak();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
void matrixPush()
|
||||
{
|
||||
ASSERT(matrixStackIndex < MAX_MATRICES - 1);
|
||||
|
||||
Matrix &a = matrixStack[matrixStackIndex++];
|
||||
Matrix &b = matrixStack[matrixStackIndex];
|
||||
memcpy(b, a, sizeof(Matrix));
|
||||
}
|
||||
|
||||
void matrixPop() {
|
||||
#if defined(_WIN32)
|
||||
if (matrixStackIndex <= 0) {
|
||||
DebugBreak();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
void matrixPop()
|
||||
{
|
||||
ASSERT(matrixStackIndex > 0);
|
||||
matrixStackIndex--;
|
||||
}
|
||||
|
||||
void matrixTranslate(const vec3i &offset) {
|
||||
void matrixTranslate(int32 x, int32 y, int32 z)
|
||||
{
|
||||
Matrix &m = matrixGet();
|
||||
|
||||
m[0].w += DP33(m[0], offset);
|
||||
m[1].w += DP33(m[1], offset);
|
||||
m[2].w += DP33(m[2], offset);
|
||||
vec3i offset(x, y, z);
|
||||
m[0][3] += DP33(m[0], offset);
|
||||
m[1][3] += DP33(m[1], offset);
|
||||
m[2][3] += DP33(m[2], offset);
|
||||
}
|
||||
|
||||
void matrixTranslateAbs(const vec3i &offset) {
|
||||
void matrixTranslateAbs(int32 x, int32 y, int32 z)
|
||||
{
|
||||
vec3i d;
|
||||
d.x = offset.x - viewPos.x;
|
||||
d.y = offset.y - viewPos.y;
|
||||
d.z = offset.z - viewPos.z;
|
||||
d.x = x - viewPos.x;
|
||||
d.y = y - viewPos.y;
|
||||
d.z = z - viewPos.z;
|
||||
|
||||
Matrix &m = matrixGet();
|
||||
m[0].w = DP33(m[0], d);
|
||||
m[1].w = DP33(m[1], d);
|
||||
m[2].w = DP33(m[2], d);
|
||||
m[0][3] = DP33(m[0], d);
|
||||
m[1][3] = DP33(m[1], d);
|
||||
m[2][3] = DP33(m[2], d);
|
||||
}
|
||||
|
||||
void matrixRotate(int16 rotX, int16 rotY, int16 rotZ) {}
|
||||
void matrixRotateX(int32 angle)
|
||||
{
|
||||
int32 s = phd_sin(angle);
|
||||
int32 c = phd_cos(angle);
|
||||
|
||||
void matrixSetView(const vec3i &pos, int16 rotX, int16 rotY) {
|
||||
int32 sx = phd_sin(rotX);
|
||||
int32 cx = phd_cos(rotX);
|
||||
int32 sy = phd_sin(rotY);
|
||||
int32 cy = phd_cos(rotY);
|
||||
Matrix &m = matrixGet();
|
||||
int32 a, b;
|
||||
|
||||
a = c * m[0][1] + s * m[0][2];
|
||||
b = c * m[0][2] - s * m[0][1];
|
||||
m[0][1] = a >> FIXED_SHIFT;
|
||||
m[0][2] = b >> FIXED_SHIFT;
|
||||
|
||||
a = c * m[1][1] + s * m[1][2];
|
||||
b = c * m[1][2] - s * m[1][1];
|
||||
m[1][1] = a >> FIXED_SHIFT;
|
||||
m[1][2] = b >> FIXED_SHIFT;
|
||||
|
||||
a = c * m[2][1] + s * m[2][2];
|
||||
b = c * m[2][2] - s * m[2][1];
|
||||
m[2][1] = a >> FIXED_SHIFT;
|
||||
m[2][2] = b >> FIXED_SHIFT;
|
||||
}
|
||||
|
||||
void matrixRotateY(int32 angle)
|
||||
{
|
||||
int32 s = phd_sin(angle);
|
||||
int32 c = phd_cos(angle);
|
||||
|
||||
Matrix &m = matrixGet();
|
||||
int32 a, b;
|
||||
|
||||
a = c * m[0][0] - s * m[0][2];
|
||||
b = c * m[0][2] + s * m[0][0];
|
||||
m[0][0] = a >> FIXED_SHIFT;
|
||||
m[0][2] = b >> FIXED_SHIFT;
|
||||
|
||||
a = c * m[1][0] - s * m[1][2];
|
||||
b = c * m[1][2] + s * m[1][0];
|
||||
m[1][0] = a >> FIXED_SHIFT;
|
||||
m[1][2] = b >> FIXED_SHIFT;
|
||||
|
||||
a = c * m[2][0] - s * m[2][2];
|
||||
b = c * m[2][2] + s * m[2][0];
|
||||
m[2][0] = a >> FIXED_SHIFT;
|
||||
m[2][2] = b >> FIXED_SHIFT;
|
||||
}
|
||||
|
||||
void matrixRotateZ(int32 angle)
|
||||
{
|
||||
int32 s = phd_sin(angle);
|
||||
int32 c = phd_cos(angle);
|
||||
|
||||
Matrix &m = matrixGet();
|
||||
int32 a, b;
|
||||
|
||||
a = c * m[0][0] + s * m[0][1];
|
||||
b = c * m[0][1] - s * m[0][0];
|
||||
m[0][0] = a >> FIXED_SHIFT;
|
||||
m[0][1] = b >> FIXED_SHIFT;
|
||||
|
||||
a = c * m[1][0] + s * m[1][1];
|
||||
b = c * m[1][1] - s * m[1][0];
|
||||
m[1][0] = a >> FIXED_SHIFT;
|
||||
m[1][1] = b >> FIXED_SHIFT;
|
||||
|
||||
a = c * m[2][0] + s * m[2][1];
|
||||
b = c * m[2][1] - s * m[2][0];
|
||||
m[2][0] = a >> FIXED_SHIFT;
|
||||
m[2][1] = b >> FIXED_SHIFT;
|
||||
}
|
||||
|
||||
void matrixRotateYXZ(int32 angleX, int32 angleY, int32 angleZ)
|
||||
{
|
||||
if (angleY) matrixRotateY(angleY);
|
||||
if (angleX) matrixRotateX(angleX);
|
||||
if (angleZ) matrixRotateZ(angleZ);
|
||||
}
|
||||
|
||||
void matrixFrame(int32 x, int32 y, int32 z, uint16* angles)
|
||||
{
|
||||
int32 angleX = (angles[1] & 0x3FF0) << 2;
|
||||
int32 angleY = (angles[1] & 0x000F) << 12 | (angles[0] & 0xFC00) >> 4;
|
||||
int32 angleZ = (angles[0] & 0x03FF) << 6;
|
||||
|
||||
matrixTranslate(x, y, z);
|
||||
matrixRotateYXZ(angleX, angleY, angleZ);
|
||||
}
|
||||
|
||||
void matrixSetView(int32 x, int32 y, int32 z, int32 angleX, int32 angleY)
|
||||
{
|
||||
int32 sx = phd_sin(angleX);
|
||||
int32 cx = phd_cos(angleX);
|
||||
int32 sy = phd_sin(angleY);
|
||||
int32 cy = phd_cos(angleY);
|
||||
|
||||
Matrix &m = matrixGet();
|
||||
|
||||
m[0].x = cy;
|
||||
m[0].y = 0;
|
||||
m[0].z = -sy;
|
||||
m[0].w = pos.x;
|
||||
m[0][0] = cy;
|
||||
m[0][1] = 0;
|
||||
m[0][2] = -sy;
|
||||
m[0][3] = x;
|
||||
|
||||
m[1].x = (sx * sy) >> FIXED_SHIFT;
|
||||
m[1].y = cx;
|
||||
m[1].z = (sx * cy) >> FIXED_SHIFT;
|
||||
m[1].w = pos.y;
|
||||
m[1][0] = (sx * sy) >> FIXED_SHIFT;
|
||||
m[1][1] = cx;
|
||||
m[1][2] = (sx * cy) >> FIXED_SHIFT;
|
||||
m[1][3] = y;
|
||||
|
||||
m[2].x = (cx * sy) >> FIXED_SHIFT;
|
||||
m[2].y = -sx;
|
||||
m[2].z = (cx * cy) >> FIXED_SHIFT;
|
||||
m[2].w = pos.z;
|
||||
m[2][0] = (cx * sy) >> FIXED_SHIFT;
|
||||
m[2][1] = -sx;
|
||||
m[2][2] = (cx * cy) >> FIXED_SHIFT;
|
||||
m[2][3] = z;
|
||||
|
||||
viewPos = pos;
|
||||
viewPos.x = x;
|
||||
viewPos.y = y;
|
||||
viewPos.z = z;
|
||||
}
|
@ -22,47 +22,25 @@
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
//#define DEBUG_OVERDRAW
|
||||
//#define DEBUG_FACES
|
||||
|
||||
//#define USE_MODE_5 1
|
||||
#define USE_MODE_4 1
|
||||
|
||||
#define SCALE 1
|
||||
|
||||
#if defined(__TNS__)
|
||||
#define WIDTH SCREEN_WIDTH
|
||||
#define HEIGHT SCREEN_HEIGHT
|
||||
#define FRAME_WIDTH (WIDTH/SCALE)
|
||||
#define FRAME_HEIGHT (HEIGHT/SCALE)
|
||||
#define FRAME_WIDTH WIDTH
|
||||
#define FRAME_HEIGHT HEIGHT
|
||||
#define FOV_SHIFT 8
|
||||
#else
|
||||
#ifdef USE_MODE_5
|
||||
#define WIDTH 160
|
||||
#define HEIGHT 128
|
||||
#define FRAME_WIDTH 160
|
||||
#define FRAME_HEIGHT 128
|
||||
#define FOV_SHIFT 7
|
||||
#elif USE_MODE_4
|
||||
#define WIDTH 240
|
||||
#define HEIGHT 160
|
||||
#define FRAME_WIDTH (WIDTH/SCALE)
|
||||
#define FRAME_HEIGHT (HEIGHT/SCALE)
|
||||
#define FOV_SHIFT 7
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_MODE_5
|
||||
#define PIXEL_SIZE 1
|
||||
#else
|
||||
#define PIXEL_SIZE 2
|
||||
#define WIDTH 160
|
||||
#define HEIGHT 128
|
||||
#define FRAME_WIDTH 160
|
||||
#define FRAME_HEIGHT 128
|
||||
#define FOV_SHIFT 7
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
@ -116,6 +94,12 @@ typedef int16 Index;
|
||||
#define ALIGN4 __attribute__((aligned(4)))
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define ASSERT(x) { if (!(x)) { DebugBreak(); } }
|
||||
#else
|
||||
#define ASSERT(x)
|
||||
#endif
|
||||
|
||||
#ifdef PROFILE
|
||||
#if defined(_WIN32)
|
||||
|
||||
@ -189,6 +173,11 @@ struct vec3s {
|
||||
|
||||
struct vec4i {
|
||||
int32 x, y, z, w;
|
||||
|
||||
INLINE int32& operator [] (int32 index) const {
|
||||
ASSERT(index >= 0 && index <= 3);
|
||||
return ((int32*)this)[index];
|
||||
}
|
||||
};
|
||||
|
||||
typedef vec4i Matrix[3];
|
||||
@ -203,12 +192,16 @@ struct Triangle {
|
||||
uint16 flags;
|
||||
};
|
||||
|
||||
struct Room {
|
||||
struct Info {
|
||||
int32 x, z;
|
||||
int32 yBottom, yTop;
|
||||
};
|
||||
struct Box {
|
||||
int16 minX;
|
||||
int16 maxX;
|
||||
int16 minY;
|
||||
int16 maxY;
|
||||
int16 minZ;
|
||||
int16 maxZ;
|
||||
};
|
||||
|
||||
struct RoomInfo {
|
||||
struct Vertex {
|
||||
vec3s pos;
|
||||
uint16 lighting;
|
||||
@ -242,14 +235,17 @@ struct Room {
|
||||
};
|
||||
|
||||
struct Mesh {
|
||||
// int32 x, y, z;
|
||||
// uint16 rotation;
|
||||
// uint16 intensity;
|
||||
// uint16 meshID;
|
||||
uint8 dummy[18];
|
||||
int16 pos[6]; // TODO align struct (int32 x, y, z)
|
||||
int16 rotation;
|
||||
uint16 intensity;
|
||||
uint16 staticMeshId;
|
||||
};
|
||||
|
||||
Info info;
|
||||
int32 x;
|
||||
int32 z;
|
||||
int32 yBottom;
|
||||
int32 yTop;
|
||||
|
||||
uint32 dataSize;
|
||||
/*
|
||||
uint16 vCount;
|
||||
@ -275,39 +271,89 @@ struct Model {
|
||||
uint32 type;
|
||||
uint16 mCount;
|
||||
uint16 mStart;
|
||||
uint32 node;
|
||||
uint32 frame;
|
||||
uint16 animation;
|
||||
uint16 paddding;
|
||||
uint32 nodeIndex;
|
||||
uint32 frameIndex;
|
||||
uint16 animIndex;
|
||||
uint16 _padding;
|
||||
};
|
||||
|
||||
#define FILE_MODEL_SIZE (sizeof(Model) - 2) // -padding
|
||||
|
||||
struct Entity {
|
||||
uint16 type;
|
||||
uint16 room;
|
||||
vec3i pos;
|
||||
int16 rotation;
|
||||
uint16 flags;
|
||||
struct StaticMesh {
|
||||
int32 id;
|
||||
uint16 meshIndex;
|
||||
Box vbox;
|
||||
Box cbox;
|
||||
uint16 flags;
|
||||
};
|
||||
|
||||
struct EntityDesc { // 32 bytes
|
||||
struct ItemInfo { // 24
|
||||
uint16 type;
|
||||
uint16 flags;
|
||||
|
||||
int16 room;
|
||||
vec3i pos;
|
||||
int16 angleY;
|
||||
uint16 intensity;
|
||||
|
||||
vec3s rot;
|
||||
uint8 state;
|
||||
uint8 targetState;
|
||||
union {
|
||||
struct {
|
||||
uint16 gravity:1; // TODO
|
||||
};
|
||||
uint16 value;
|
||||
} flags;
|
||||
|
||||
uint8 vSpeed;
|
||||
uint8 hSpeed;
|
||||
uint8 room;
|
||||
uint8 modelIndex;
|
||||
uint16 _padding;
|
||||
};
|
||||
|
||||
#define FILE_ITEM_SIZE (sizeof(ItemInfo) - 2)
|
||||
|
||||
struct Item : ItemInfo { // 24 + 20 = 44
|
||||
int16 angleX;
|
||||
int16 angleZ;
|
||||
|
||||
uint16 vSpeed;
|
||||
uint16 hSpeed;
|
||||
|
||||
uint16 animIndex;
|
||||
uint16 frameIndex;
|
||||
|
||||
uint8 state;
|
||||
uint8 nextState;
|
||||
uint8 goalState;
|
||||
uint8 timer;
|
||||
|
||||
uint16 health;
|
||||
uint8 nextItem;
|
||||
uint8 nextActive;
|
||||
};
|
||||
|
||||
struct Anim {
|
||||
uint32 frameOffset;
|
||||
|
||||
uint8 frameRate;
|
||||
uint8 frameSize;
|
||||
uint16 state;
|
||||
|
||||
int32 speed;
|
||||
|
||||
int32 accel;
|
||||
|
||||
uint16 frameBegin;
|
||||
uint16 frameEnd;
|
||||
|
||||
uint16 nextAnimIndex;
|
||||
uint16 nextFrameIndex;
|
||||
|
||||
uint16 scCount;
|
||||
uint16 scOffset;
|
||||
|
||||
uint16 acCount;
|
||||
uint16 animCommand;
|
||||
};
|
||||
|
||||
struct Frame {
|
||||
Box box;
|
||||
vec3s pos;
|
||||
uint16 angles[1];
|
||||
};
|
||||
|
||||
struct Texture {
|
||||
@ -352,7 +398,7 @@ union UV {
|
||||
|
||||
struct VertexUV {
|
||||
Vertex v;
|
||||
UV t;
|
||||
UV t;
|
||||
};
|
||||
|
||||
struct Face {
|
||||
@ -371,12 +417,19 @@ struct Face {
|
||||
extern uint32 dbg_poly_count;
|
||||
#endif
|
||||
|
||||
#define DIV_TABLE_SIZE 256
|
||||
#define FixedInvS(x) ((x < 0) ? -divTable[abs(x)] : divTable[x])
|
||||
#define FixedInvU(x) divTable[x]
|
||||
|
||||
extern uint16 divTable[DIV_TABLE_SIZE];
|
||||
|
||||
#define FIXED_SHIFT 14
|
||||
|
||||
#define MAX_MATRICES 8
|
||||
#define MAX_MODELS 64
|
||||
#define MAX_ENTITY 190
|
||||
#define MAX_VERTICES 1024
|
||||
#define MAX_ITEMS 256
|
||||
#define MAX_MESHES 50
|
||||
#define MAX_VERTICES 2048
|
||||
#define MAX_FACES 512
|
||||
#define FOG_SHIFT 1
|
||||
#define FOG_MAX (10 * 1024)
|
||||
@ -390,6 +443,10 @@ struct Face {
|
||||
#define FACE_FLAT 0x1000
|
||||
#define FACE_TEXTURE 0x0FFF
|
||||
|
||||
#define NO_ROOM 0xFF
|
||||
#define NO_ITEM 0xFF
|
||||
#define NO_MODEL 0xFF
|
||||
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#define SQR(x) ((x) * (x))
|
||||
@ -397,31 +454,47 @@ struct Face {
|
||||
#define DP43(a,b) ((a).x * (b).x + (a).y * (b).y + (a).z * (b).z + (a).w)
|
||||
#define DP33(a,b) ((a).x * (b).x + (a).y * (b).y + (a).z * (b).z)
|
||||
|
||||
#define ITEM_LARA 0
|
||||
#define ITEM_WOLF 7
|
||||
#define ITEM_BEAR 8
|
||||
#define ITEM_BAT 9
|
||||
#define ITEM_CRYSTAL 83
|
||||
|
||||
extern vec3i viewPos;
|
||||
extern Matrix matrixStack[MAX_MATRICES];
|
||||
extern int32 matrixStackIndex;
|
||||
|
||||
int32 clamp(int32 x, int32 a, int32 b);
|
||||
int32 phd_sin(int32 x);
|
||||
int32 phd_cos(int32 x);
|
||||
|
||||
void initLUT();
|
||||
|
||||
Matrix& matrixGet();
|
||||
void matrixPush();
|
||||
void matrixPop();
|
||||
void matrixTranslate(const vec3i &offset);
|
||||
void matrixTranslateAbs(const vec3i &offset);
|
||||
void matrixRotate(int16 rotX, int16 rotY, int16 rotZ);
|
||||
void matrixSetView(const vec3i &pos, int16 rotX, int16 rotY);
|
||||
void matrixTranslate(int32 x, int32 y, int32 z);
|
||||
void matrixTranslateAbs(int32 x, int32 y, int32 z);
|
||||
void matrixRotateX(int32 angle);
|
||||
void matrixRotateY(int32 angle);
|
||||
void matrixRotateZ(int32 angle);
|
||||
void matrixRotateYXZ(int32 angleX, int32 angleY, int32 angleZ);
|
||||
void matrixFrame(int32 x, int32 y, int32 z, uint16* angles);
|
||||
void matrixSetView(int32 x, int32 y, int32 z, int32 angleX, int32 angleY);
|
||||
|
||||
void drawGlyph(const Sprite *sprite, int32 x, int32 y);
|
||||
|
||||
void clear();
|
||||
void transform_room(const Room::Vertex* vertices, int32 vCount);
|
||||
void transform_mesh(const vec3s* vertices, int32 vCount);
|
||||
void faceAdd_room(const Quad* quads, int32 qCount, const Triangle* triangles, int32 tCount, int32 startVertex);
|
||||
void faceAdd_mesh(const Quad* rFaces, const Quad* crFaces, const Triangle* tFaces, const Triangle* ctFaces, int32 rCount, int32 crCount, int32 tCount, int32 ctCount, int32 startVertex);
|
||||
bool boxIsVisible(const Box* box);
|
||||
void transformRoom(const RoomInfo::Vertex* vertices, int32 vCount);
|
||||
void transformMesh(const vec3s* vertices, int32 vCount, uint16 intensity);
|
||||
void faceAddRoom(const Quad* quads, int32 qCount, const Triangle* triangles, int32 tCount, int32 startVertex);
|
||||
void faceAddMesh(const Quad* rFaces, const Quad* crFaces, const Triangle* tFaces, const Triangle* ctFaces, int32 rCount, int32 crCount, int32 tCount, int32 ctCount, int32 startVertex);
|
||||
|
||||
void flush();
|
||||
void initRender();
|
||||
|
||||
void readLevel(const uint8 *data);
|
||||
const Room::Sector* getSector(int32 roomIndex, int32 x, int32 z);
|
||||
int32 getRoomIndex(int32 roomIndex, const vec3i &pos);
|
||||
const RoomInfo::Sector* getSector(int32 roomIndex, int32 x, int32 z);
|
||||
int32 getRoomIndex(int32 roomIndex, const vec3i* pos);
|
||||
|
||||
#endif
|
||||
|
@ -4,72 +4,82 @@
|
||||
#include "common.h"
|
||||
#include "camera.h"
|
||||
|
||||
#define GRAVITY 6
|
||||
|
||||
// level file data -------------------
|
||||
uint32 tilesCount;
|
||||
int32 tilesCount;
|
||||
extern const uint8* tiles;
|
||||
|
||||
#if defined(USE_MODE_5) || defined(_WIN32)
|
||||
extern uint16 palette[256];
|
||||
#endif
|
||||
|
||||
extern uint16 palette[256];
|
||||
extern uint8 lightmap[256 * 32];
|
||||
|
||||
uint16 roomsCount;
|
||||
|
||||
const uint16* floors;
|
||||
|
||||
uint32 texturesCount;
|
||||
int32 texturesCount;
|
||||
extern const Texture* textures;
|
||||
|
||||
const Sprite* sprites;
|
||||
|
||||
uint32 spritesSeqCount;
|
||||
int32 spritesSeqCount;
|
||||
const SpriteSeq* spritesSeq;
|
||||
|
||||
const uint8* meshData;
|
||||
const uint32* meshOffsets;
|
||||
const int32* meshOffsets;
|
||||
|
||||
const int32* nodes;
|
||||
const int32* nodesPtr;
|
||||
|
||||
uint32 modelsCount;
|
||||
int32 animsCount;
|
||||
const Anim* anims;
|
||||
|
||||
int32 framesCount;
|
||||
const uint16* frames;
|
||||
|
||||
int32 modelsCount;
|
||||
EWRAM_DATA Model models[MAX_MODELS];
|
||||
EWRAM_DATA int16 modelsMap[MAX_ENTITY];
|
||||
EWRAM_DATA uint8 modelsMap[MAX_ITEMS];
|
||||
EWRAM_DATA uint8 staticMeshesMap[MAX_MESHES];
|
||||
|
||||
uint32 entitiesCount;
|
||||
const Entity* entities;
|
||||
int32 staticMeshesCount;
|
||||
const StaticMesh* staticMeshes;
|
||||
|
||||
int32 itemsCount;
|
||||
EWRAM_DATA Item items[MAX_ITEMS];
|
||||
// -----------------------------------
|
||||
|
||||
struct RoomDesc {
|
||||
struct Room {
|
||||
Rect clip;
|
||||
uint8 firstItem;
|
||||
bool visible;
|
||||
|
||||
// TODO leave in ROM
|
||||
int32 x, z;
|
||||
uint16 vCount;
|
||||
uint16 qCount;
|
||||
uint16 tCount;
|
||||
uint16 pCount;
|
||||
uint16 lCount;
|
||||
uint16 mCount;
|
||||
uint16 zSectors;
|
||||
uint16 xSectors;
|
||||
const Room::Vertex* vertices;
|
||||
const Quad* quads;
|
||||
const Triangle* triangles;
|
||||
const Room::Portal* portals;
|
||||
const Room::Sector* sectors;
|
||||
uint16 ambient;
|
||||
|
||||
INLINE void reset() {
|
||||
visible = false;
|
||||
clip = { FRAME_WIDTH, FRAME_HEIGHT, 0, 0 };
|
||||
}
|
||||
const RoomInfo::Vertex* vertices;
|
||||
const Quad* quads;
|
||||
const Triangle* triangles;
|
||||
const RoomInfo::Portal* portals;
|
||||
const RoomInfo::Sector* sectors;
|
||||
const RoomInfo::Light* lights;
|
||||
const RoomInfo::Mesh* meshes;
|
||||
};
|
||||
|
||||
EWRAM_DATA RoomDesc rooms[64];
|
||||
int16 roomsCount;
|
||||
EWRAM_DATA Room rooms[64];
|
||||
|
||||
int32 firstActive = NO_ITEM;
|
||||
|
||||
int32 visRoomsCount;
|
||||
int32 visRooms[16];
|
||||
|
||||
#define ROOM_VISIBLE (1 << 15)
|
||||
|
||||
#define ENTITY_LARA 0
|
||||
|
||||
#define SEQ_GLYPH 190
|
||||
|
||||
enum FloorType {
|
||||
@ -80,51 +90,145 @@ enum FloorType {
|
||||
};
|
||||
|
||||
int32 seqGlyphs;
|
||||
int32 entityLara;
|
||||
|
||||
extern uint32 gVerticesCount;
|
||||
extern Rect clip;
|
||||
|
||||
void roomReset(int32 roomIndex)
|
||||
{
|
||||
Room* room = rooms + roomIndex;
|
||||
|
||||
room->visible = false;
|
||||
room->clip = { FRAME_WIDTH, FRAME_HEIGHT, 0, 0 };
|
||||
}
|
||||
|
||||
void roomItemAdd(int32 roomIndex, int32 itemIndex)
|
||||
{
|
||||
ASSERT(items[itemIndex].nextItem == NO_ITEM);
|
||||
|
||||
Room* room = rooms + roomIndex;
|
||||
|
||||
items[itemIndex].nextItem = room->firstItem;
|
||||
room->firstItem = itemIndex;
|
||||
}
|
||||
|
||||
void roomItemRemove(int32 roomIndex, int32 itemIndex)
|
||||
{
|
||||
Room* room = rooms + roomIndex;
|
||||
|
||||
int32 prevIndex = NO_ITEM;
|
||||
int32 index = room->firstItem;
|
||||
|
||||
while (index != NO_ITEM)
|
||||
{
|
||||
int32 next = items[index].nextItem;
|
||||
|
||||
if (index == itemIndex)
|
||||
{
|
||||
items[index].nextItem = NO_ITEM;
|
||||
|
||||
if (prevIndex == NO_ITEM) {
|
||||
room->firstItem = next;
|
||||
} else {
|
||||
items[prevIndex].nextItem = next;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
prevIndex = index;
|
||||
index = next;
|
||||
}
|
||||
}
|
||||
|
||||
void activateItem(int32 itemIndex)
|
||||
{
|
||||
items[itemIndex].nextActive = firstActive;
|
||||
firstActive = itemIndex;
|
||||
}
|
||||
|
||||
void deactivateItem(int32 itemIndex)
|
||||
{
|
||||
int32 prevIndex = NO_ITEM;
|
||||
int32 index = firstActive;
|
||||
|
||||
while (index != NO_ITEM)
|
||||
{
|
||||
int32 next = items[index].nextActive;
|
||||
|
||||
if (index == itemIndex)
|
||||
{
|
||||
items[index].nextItem = NO_ITEM;
|
||||
|
||||
if (prevIndex == NO_ITEM) {
|
||||
firstActive = next;
|
||||
} else {
|
||||
items[prevIndex].nextActive = next;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
prevIndex = index;
|
||||
index = next;
|
||||
}
|
||||
}
|
||||
|
||||
void readLevel(const uint8 *data) { // TODO non-hardcode level loader, added *_OFF alignment bytes
|
||||
tilesCount = *((uint32*)(data + 4));
|
||||
tilesCount = *((int32*)(data + 4));
|
||||
tiles = data + 8;
|
||||
|
||||
#define MDL_OFF 2
|
||||
#define ENT_OFF 2
|
||||
#define ITM_OFF 2
|
||||
|
||||
roomsCount = *((uint16*)(data + 720908));
|
||||
const Room* roomsPtr = (Room*)(data + 720908 + 2);
|
||||
roomsCount = *((int16*)(data + 720908));
|
||||
const RoomInfo* roomsPtr = (RoomInfo*)(data + 720908 + 2);
|
||||
|
||||
floors = (uint16*)(data + 899492 + 4);
|
||||
|
||||
meshData = data + 908172 + 4;
|
||||
meshOffsets = (uint32*)(data + 975724 + 4);
|
||||
meshOffsets = (int32*)(data + 975724 + 4);
|
||||
|
||||
nodes = (int32*)(data + 990318);
|
||||
animsCount = *((int32*)(data + 976596));
|
||||
anims = (Anim*)(data + 976596 + 4);
|
||||
ASSERT((intptr_t)anims % 4 == 0);
|
||||
|
||||
modelsCount = *((uint32*)(data + 1270666 + MDL_OFF));
|
||||
framesCount = *((int32*)(data + 992990));
|
||||
frames = (uint16*)(data + 992990 + 4);
|
||||
ASSERT((intptr_t)frames % 2 == 0);
|
||||
|
||||
nodesPtr = (int32*)(data + 990318);
|
||||
|
||||
modelsCount = *((int32*)(data + 1270666 + MDL_OFF));
|
||||
const uint8* modelsPtr = (uint8*)(data + 1270666 + 4 + MDL_OFF);
|
||||
ASSERT((intptr_t)modelsPtr % 4 == 0);
|
||||
|
||||
texturesCount = *((uint32*)(data + 1271686 + MDL_OFF));
|
||||
staticMeshesCount = *((int32*)(data + 1271426 + MDL_OFF));
|
||||
staticMeshes = (StaticMesh*)(data + 1271426 + 4 + MDL_OFF);
|
||||
ASSERT((intptr_t)staticMeshes % 4 == 0);
|
||||
|
||||
texturesCount = *((int32*)(data + 1271686 + MDL_OFF));
|
||||
textures = (Texture*)(data + 1271686 + 4 + MDL_OFF);
|
||||
|
||||
sprites = (Sprite*)(data + 1289634 + MDL_OFF);
|
||||
|
||||
spritesSeqCount = *((uint32*)(data + 1292130 + MDL_OFF));
|
||||
spritesSeqCount = *((int32*)(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);
|
||||
itemsCount = *((int32*)(data + 1319252 + MDL_OFF + ITM_OFF));
|
||||
const uint8* itemsPtr = (data + 1319252 + 4 + MDL_OFF + ITM_OFF);
|
||||
|
||||
for (int32 i = 0; i < itemsCount; i++) {
|
||||
memcpy(items + i, itemsPtr, FILE_ITEM_SIZE);
|
||||
itemsPtr += FILE_ITEM_SIZE;
|
||||
}
|
||||
|
||||
// prepare lightmap
|
||||
const uint8* f_lightmap = data + 1320576 + MDL_OFF + ENT_OFF;
|
||||
const uint8* f_lightmap = data + 1320576 + MDL_OFF + ITM_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 + MDL_OFF + ENT_OFF;
|
||||
const uint8* f_palette = data + 1328768 + MDL_OFF + ITM_OFF;
|
||||
|
||||
const uint8* p = f_palette;
|
||||
|
||||
@ -137,59 +241,33 @@ void readLevel(const uint8 *data) { // TODO non-hardcode level loader, added *_O
|
||||
#endif
|
||||
p += 3;
|
||||
}
|
||||
|
||||
#if defined(__GBA__) || defined(__TNS__)
|
||||
#ifndef USE_MODE_5
|
||||
SetPalette(palette);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// prepare models
|
||||
for (uint32 i = 0; i < modelsCount; i++) {
|
||||
dmaCopy(modelsPtr, models + i, sizeof(Model)); // sizeof(Model) is faster than FILE_MODEL_SIZE
|
||||
modelsPtr += FILE_MODEL_SIZE;
|
||||
modelsMap[models[i].type] = i;
|
||||
}
|
||||
|
||||
// prepare entities
|
||||
for (uint32 i = 0; i < entitiesCount; i++) {
|
||||
if (entities[i].type == ENTITY_LARA) {
|
||||
entityLara = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// prepare glyphs
|
||||
for (uint32 i = 0; i < spritesSeqCount; i++) {
|
||||
if (spritesSeq[i].type == SEQ_GLYPH) {
|
||||
seqGlyphs = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// prepare rooms
|
||||
uint8 *ptr = (uint8*)roomsPtr;
|
||||
|
||||
for (uint16 roomIndex = 0; roomIndex < roomsCount; roomIndex++) {
|
||||
const Room *room = (Room*)ptr;
|
||||
ptr += sizeof(Room);
|
||||
for (int32 roomIndex = 0; roomIndex < roomsCount; roomIndex++)
|
||||
{
|
||||
const RoomInfo *room = (RoomInfo*)ptr;
|
||||
ptr += sizeof(RoomInfo);
|
||||
|
||||
uint32 dataSize;
|
||||
memcpy(&dataSize, &room->dataSize, sizeof(dataSize));
|
||||
uint8* skipPtr = ptr + dataSize * 2;
|
||||
|
||||
RoomDesc &desc = rooms[roomIndex];
|
||||
desc.reset();
|
||||
Room &desc = rooms[roomIndex];
|
||||
roomReset(roomIndex);
|
||||
|
||||
desc.firstItem = NO_ITEM;
|
||||
|
||||
// offset
|
||||
memcpy(&desc.x, &room->info.x, sizeof(room->info.x));
|
||||
memcpy(&desc.z, &room->info.z, sizeof(room->info.z));
|
||||
memcpy(&desc.x, &room->x, sizeof(room->x));
|
||||
memcpy(&desc.z, &room->z, sizeof(room->z));
|
||||
|
||||
// vertices
|
||||
desc.vCount = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
desc.vertices = (Room::Vertex*)ptr;
|
||||
ptr += sizeof(Room::Vertex) * desc.vCount;
|
||||
desc.vertices = (RoomInfo::Vertex*)ptr;
|
||||
ptr += sizeof(RoomInfo::Vertex) * desc.vCount;
|
||||
|
||||
// quads
|
||||
desc.qCount = *((uint16*)ptr);
|
||||
@ -208,38 +286,99 @@ void readLevel(const uint8 *data) { // TODO non-hardcode level loader, added *_O
|
||||
// portals
|
||||
desc.pCount = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
desc.portals = (Room::Portal*)ptr;
|
||||
ptr += sizeof(Room::Portal) * desc.pCount;
|
||||
desc.portals = (RoomInfo::Portal*)ptr;
|
||||
ptr += sizeof(RoomInfo::Portal) * desc.pCount;
|
||||
|
||||
desc.zSectors = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
desc.xSectors = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
desc.sectors = (Room::Sector*)ptr;
|
||||
ptr += sizeof(Room::Sector) * desc.zSectors * desc.xSectors;
|
||||
desc.sectors = (RoomInfo::Sector*)ptr;
|
||||
ptr += sizeof(RoomInfo::Sector) * desc.zSectors * desc.xSectors;
|
||||
|
||||
//ambient = *((uint16*)ptr);
|
||||
desc.ambient = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
|
||||
uint16 lightsCount = *((uint16*)ptr);
|
||||
desc.lCount = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
//lights = (Room::Light*)ptr;
|
||||
ptr += sizeof(Room::Light) * lightsCount;
|
||||
desc.lights = (RoomInfo::Light*)ptr;
|
||||
ptr += sizeof(RoomInfo::Light) * desc.lCount;
|
||||
|
||||
uint16 meshesCount = *((uint16*)ptr);
|
||||
desc.mCount = *((uint16*)ptr);
|
||||
ptr += 2;
|
||||
//meshes = (Room::Mesh*)ptr;
|
||||
ptr += sizeof(Room::Mesh) * meshesCount;
|
||||
desc.meshes = (RoomInfo::Mesh*)ptr;
|
||||
ptr += sizeof(RoomInfo::Mesh) * desc.mCount;
|
||||
|
||||
ptr += 2 + 2; // skip alternateRoom and flags
|
||||
}
|
||||
|
||||
// prepare models
|
||||
memset(modelsMap, 0xFF, sizeof(modelsMap));
|
||||
for (int32 i = 0; i < modelsCount; i++)
|
||||
{
|
||||
memcpy(models + i, modelsPtr, sizeof(Model)); // sizeof(Model) is faster than FILE_MODEL_SIZE
|
||||
modelsPtr += FILE_MODEL_SIZE;
|
||||
modelsMap[models[i].type] = i;
|
||||
}
|
||||
|
||||
// prepare static meshes
|
||||
memset(staticMeshesMap, 0xFF, sizeof(staticMeshesMap));
|
||||
for (int32 i = 0; i < staticMeshesCount; i++)
|
||||
{
|
||||
staticMeshesMap[staticMeshes[i].id] = i;
|
||||
}
|
||||
|
||||
// prepare items
|
||||
for (int32 i = 0; i < itemsCount; i++) {
|
||||
Item* item = items + i;
|
||||
|
||||
item->angleX = 0;
|
||||
item->angleZ = 0;
|
||||
item->vSpeed = 0;
|
||||
item->hSpeed = 0;
|
||||
item->nextItem = NO_ITEM;
|
||||
item->nextActive = NO_ITEM;
|
||||
item->animIndex = models[modelsMap[item->type]].animIndex;
|
||||
item->frameIndex = anims[item->animIndex].frameBegin;
|
||||
item->state = anims[item->animIndex].state;
|
||||
item->nextState = item->state;
|
||||
item->goalState = item->state;
|
||||
item->intensity = 4096; // TODO lighting
|
||||
|
||||
item->flags.gravity = 0;
|
||||
|
||||
if (item->room > -1) {
|
||||
roomItemAdd(item->room, i);
|
||||
}
|
||||
|
||||
if (item->type == ITEM_LARA) {
|
||||
activateItem(i);
|
||||
}
|
||||
|
||||
// TODO remove
|
||||
if (item->type == ITEM_WOLF ||
|
||||
item->type == ITEM_BEAR ||
|
||||
item->type == ITEM_BAT ||
|
||||
item->type == ITEM_CRYSTAL)
|
||||
{
|
||||
activateItem(i);
|
||||
}
|
||||
}
|
||||
|
||||
// prepare glyphs
|
||||
for (int32 i = 0; i < spritesSeqCount; i++) {
|
||||
if (spritesSeq[i].type == SEQ_GLYPH) {
|
||||
seqGlyphs = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
camera.init();
|
||||
camera.room = entities[entityLara].room;
|
||||
camera.room = 0;
|
||||
}
|
||||
|
||||
void drawMesh(int16 meshIndex) {
|
||||
uint32 offset = meshOffsets[meshIndex];
|
||||
void drawMesh(int16 meshIndex, uint16 intensity) {
|
||||
int32 offset = meshOffsets[meshIndex];
|
||||
const uint8* ptr = meshData + offset;
|
||||
|
||||
ptr += 2 * 5; // skip [cx, cy, cz, radius, flags]
|
||||
@ -271,52 +410,67 @@ void drawMesh(int16 meshIndex) {
|
||||
int32 startVertex = gVerticesCount;
|
||||
|
||||
PROFILE_START();
|
||||
transform_mesh(vertices, vCount);
|
||||
transformMesh(vertices, vCount, intensity);
|
||||
PROFILE_STOP(dbg_transform);
|
||||
|
||||
PROFILE_START();
|
||||
faceAdd_mesh(rFaces, crFaces, tFaces, ctFaces, rCount, crCount, tCount, ctCount, startVertex);
|
||||
faceAddMesh(rFaces, crFaces, tFaces, ctFaces, rCount, crCount, tCount, ctCount, startVertex);
|
||||
PROFILE_STOP(dbg_poly);
|
||||
}
|
||||
|
||||
void drawModel(int32 modelIndex) {
|
||||
const Model* model = models + modelIndex;
|
||||
Frame* getFrame(const Item* item, const Model* model)
|
||||
{
|
||||
const Anim* anim = anims + item->animIndex;
|
||||
|
||||
// non-aligned access
|
||||
uint32 node, frame;
|
||||
memcpy(&node, &model->node, sizeof(node));
|
||||
memcpy(&frame, &model->frame, sizeof(frame));
|
||||
int32 frameSize = sizeof(Frame) / 2 + model->mCount * 2;
|
||||
int32 frameIndex = (item->frameIndex - anim->frameBegin) / anim->frameRate;//* FixedInvU(anim->frameRate) >> 16;
|
||||
|
||||
Node bones[32];
|
||||
memcpy(bones, nodes + node, (model->mCount - 1) * sizeof(Node));
|
||||
|
||||
const Node* n = bones;
|
||||
|
||||
drawMesh(model->mStart);
|
||||
|
||||
for (int i = 1; i < model->mCount; i++) {
|
||||
if (n->flags & 1) {
|
||||
matrixPop();
|
||||
}
|
||||
|
||||
if (n->flags & 2) {
|
||||
matrixPush();
|
||||
}
|
||||
|
||||
matrixTranslate(n->pos);
|
||||
n++;
|
||||
|
||||
drawMesh(model->mStart + i);
|
||||
}
|
||||
return (Frame*)(frames + anim->frameOffset / 2 + frameIndex * frameSize);
|
||||
}
|
||||
|
||||
void drawEntity(int32 entityIndex) {
|
||||
const Entity &e = entities[entityIndex];
|
||||
void drawItem(const Item* item) {
|
||||
int32 modelIndex = modelsMap[item->type];
|
||||
if (modelIndex == NO_MODEL) {
|
||||
return; // TODO sprite items
|
||||
}
|
||||
|
||||
const Model* model = models + modelIndex;
|
||||
|
||||
if (model->mCount == 1 && meshOffsets[model->mStart] == 0) return;
|
||||
|
||||
Frame* frame = getFrame(item, model);
|
||||
uint16* frameAngles = frame->angles + 1;
|
||||
|
||||
matrixPush();
|
||||
matrixTranslateAbs(vec3i(e.pos.x, e.pos.y - 512, e.pos.z)); // TODO animation
|
||||
matrixTranslateAbs(item->pos.x, item->pos.y, item->pos.z);
|
||||
matrixRotateYXZ(item->angleX, item->angleY, item->angleZ);
|
||||
|
||||
drawModel(modelsMap[e.type]);
|
||||
if (boxIsVisible(&frame->box)) {
|
||||
// non-aligned access (TODO)
|
||||
uint32 nodeIndex;
|
||||
memcpy(&nodeIndex, &model->nodeIndex, sizeof(nodeIndex));
|
||||
Node nodes[32];
|
||||
memcpy(nodes, nodesPtr + nodeIndex, (model->mCount - 1) * sizeof(Node));
|
||||
|
||||
const Node* node = nodes;
|
||||
|
||||
matrixFrame(frame->pos.x, frame->pos.y, frame->pos.z, frameAngles);
|
||||
|
||||
drawMesh(model->mStart, item->intensity);
|
||||
|
||||
for (int32 i = 1; i < model->mCount; i++)
|
||||
{
|
||||
if (node->flags & 1) matrixPop();
|
||||
if (node->flags & 2) matrixPush();
|
||||
|
||||
frameAngles += 2;
|
||||
matrixFrame(node->pos.x, node->pos.y, node->pos.z, frameAngles);
|
||||
|
||||
drawMesh(model->mStart + i, item->intensity);
|
||||
|
||||
node++;
|
||||
}
|
||||
}
|
||||
|
||||
matrixPop();
|
||||
}
|
||||
@ -333,39 +487,62 @@ void drawNumber(int32 number, int32 x, int32 y) {
|
||||
}
|
||||
}
|
||||
|
||||
extern vec3i viewPos;
|
||||
extern Vertex gVertices[MAX_VERTICES];
|
||||
void drawRoom(int32 roomIndex) {
|
||||
const Room* room = rooms + roomIndex;
|
||||
|
||||
void drawRoom(int16 roomIndex) {
|
||||
RoomDesc &room = rooms[roomIndex];
|
||||
|
||||
clip = room.clip;
|
||||
clip = room->clip;
|
||||
|
||||
int32 startVertex = gVerticesCount;
|
||||
|
||||
matrixPush();
|
||||
matrixTranslateAbs(vec3i(room.x, 0, room.z));
|
||||
matrixTranslateAbs(room->x, 0, room->z);
|
||||
|
||||
PROFILE_START();
|
||||
transform_room(room.vertices, room.vCount);
|
||||
transformRoom(room->vertices, room->vCount);
|
||||
PROFILE_STOP(dbg_transform);
|
||||
|
||||
matrixPop();
|
||||
|
||||
PROFILE_START();
|
||||
faceAdd_room(room.quads, room.qCount, room.triangles, room.tCount, startVertex);
|
||||
if (roomIndex == entityLara) { // TODO draw all entities in the room
|
||||
drawEntity(entityLara);
|
||||
faceAddRoom(room->quads, room->qCount, room->triangles, room->tCount, startVertex);
|
||||
|
||||
for (int32 i = 0; i < room->mCount; i++)
|
||||
{
|
||||
const RoomInfo::Mesh* mesh = room->meshes + i;
|
||||
const StaticMesh* staticMesh = staticMeshes + staticMeshesMap[mesh->staticMeshId];
|
||||
|
||||
if (!(staticMesh->flags & 2)) continue; // invisible
|
||||
|
||||
// TODO align RoomInfo::Mesh (room relative int16?)
|
||||
vec3i pos;
|
||||
memcpy(&pos, &mesh->pos, sizeof(pos));
|
||||
|
||||
matrixPush();
|
||||
matrixTranslateAbs(pos.x, pos.y, pos.z);
|
||||
matrixRotateY(mesh->rotation);
|
||||
|
||||
if (boxIsVisible(&staticMesh->vbox)) {
|
||||
drawMesh(staticMesh->meshIndex, mesh->intensity);
|
||||
}
|
||||
|
||||
matrixPop();
|
||||
}
|
||||
|
||||
int32 itemIndex = room->firstItem;
|
||||
while (itemIndex != NO_ITEM)
|
||||
{
|
||||
drawItem(items + itemIndex);
|
||||
itemIndex = items[itemIndex].nextItem;
|
||||
}
|
||||
PROFILE_STOP(dbg_poly);
|
||||
|
||||
room.reset();
|
||||
roomReset(roomIndex);
|
||||
|
||||
flush();
|
||||
}
|
||||
|
||||
const Room::Sector* getSector(int32 roomIndex, int32 x, int32 z) {
|
||||
RoomDesc &room = rooms[roomIndex];
|
||||
const RoomInfo::Sector* getSector(int32 roomIndex, int32 x, int32 z) {
|
||||
Room &room = rooms[roomIndex];
|
||||
|
||||
int32 sx = clamp((x - room.x) >> 10, 0, room.xSectors - 1);
|
||||
int32 sz = clamp((z - room.z) >> 10, 0, room.zSectors - 1);
|
||||
@ -373,8 +550,8 @@ const Room::Sector* getSector(int32 roomIndex, int32 x, int32 z) {
|
||||
return room.sectors + sx * room.zSectors + sz;
|
||||
}
|
||||
|
||||
int32 getRoomIndex(int32 roomIndex, const vec3i &pos) {
|
||||
const Room::Sector *sector = getSector(roomIndex, pos.x, pos.z);
|
||||
int32 getRoomIndex(int32 roomIndex, const vec3i* pos) {
|
||||
const RoomInfo::Sector *sector = getSector(roomIndex, pos->x, pos->z);
|
||||
|
||||
if (sector->floorIndex) {
|
||||
const uint16 *data = floors + sector->floorIndex;
|
||||
@ -395,28 +572,28 @@ int32 getRoomIndex(int32 roomIndex, const vec3i &pos) {
|
||||
}
|
||||
}
|
||||
|
||||
while (sector->roomAbove != 0xFF && pos.y < (sector->ceiling << 8)) {
|
||||
while (sector->roomAbove != NO_ROOM && pos->y < (sector->ceiling << 8)) {
|
||||
roomIndex = sector->roomAbove;
|
||||
sector = getSector(roomIndex, pos.x, pos.z);
|
||||
sector = getSector(roomIndex, pos->x, pos->z);
|
||||
}
|
||||
|
||||
while (sector->roomBelow != 0xFF && pos.y >= (sector->floor << 8)) {
|
||||
while (sector->roomBelow != 0xFF && pos->y >= (sector->floor << 8)) {
|
||||
roomIndex = sector->roomBelow;
|
||||
sector = getSector(roomIndex, pos.x, pos.z);
|
||||
sector = getSector(roomIndex, pos->x, pos->z);
|
||||
}
|
||||
|
||||
return roomIndex;
|
||||
}
|
||||
|
||||
bool checkPortal(int32 roomIndex, const Room::Portal &portal) {
|
||||
RoomDesc &room = rooms[roomIndex];
|
||||
bool checkPortal(int32 roomIndex, const RoomInfo::Portal* portal) {
|
||||
Room &room = rooms[roomIndex];
|
||||
|
||||
vec3i d;
|
||||
d.x = portal.v[0].x - camera.pos.x + room.x;
|
||||
d.y = portal.v[0].y - camera.pos.y;
|
||||
d.z = portal.v[0].z - camera.pos.z + room.z;
|
||||
d.x = portal->v[0].x - camera.pos.x + room.x;
|
||||
d.y = portal->v[0].y - camera.pos.y;
|
||||
d.z = portal->v[0].z - camera.pos.z + room.z;
|
||||
|
||||
if (DP33(portal.n, d) >= 0) {
|
||||
if (DP33(portal->n, d) >= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -432,7 +609,7 @@ bool checkPortal(int32 roomIndex, const Room::Portal &portal) {
|
||||
vec3i pv[4];
|
||||
|
||||
for (int32 i = 0; i < 4; i++) {
|
||||
const vec3s &v = portal.v[i];
|
||||
const vec3s &v = portal->v[i];
|
||||
|
||||
int32 x = DP43(m[0], v);
|
||||
int32 y = DP43(m[1], v);
|
||||
@ -503,7 +680,7 @@ bool checkPortal(int32 roomIndex, const Room::Portal &portal) {
|
||||
|
||||
if (x0 >= x1 || y0 >= y1) return false;
|
||||
|
||||
RoomDesc &nextRoom = rooms[portal.roomIndex];
|
||||
Room &nextRoom = rooms[portal->roomIndex];
|
||||
|
||||
if (x0 < nextRoom.clip.x0) nextRoom.clip.x0 = x0;
|
||||
if (x1 > nextRoom.clip.x1) nextRoom.clip.x1 = x1;
|
||||
@ -512,38 +689,123 @@ bool checkPortal(int32 roomIndex, const Room::Portal &portal) {
|
||||
|
||||
if (!nextRoom.visible) {
|
||||
nextRoom.visible = true;
|
||||
visRooms[visRoomsCount++] = portal.roomIndex;
|
||||
visRooms[visRoomsCount++] = portal->roomIndex;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void getVisibleRooms(int32 roomIndex) {
|
||||
RoomDesc &room = rooms[roomIndex];
|
||||
void getVisibleRooms(int32 roomIndex)
|
||||
{
|
||||
const Room* room = rooms + roomIndex;
|
||||
|
||||
matrixPush();
|
||||
matrixTranslateAbs(vec3i(room.x, 0, room.z));
|
||||
matrixTranslateAbs(room->x, 0, room->z);
|
||||
|
||||
for (int32 i = 0; i < room.pCount; i++) {
|
||||
const Room::Portal &portal = room.portals[i];
|
||||
if (checkPortal(roomIndex, portal)) {
|
||||
getVisibleRooms(portal.roomIndex);
|
||||
for (int32 i = 0; i < room->pCount; i++)
|
||||
{
|
||||
const RoomInfo::Portal* portal = room->portals + i;
|
||||
|
||||
if (checkPortal(roomIndex, portal))
|
||||
{
|
||||
getVisibleRooms(portal->roomIndex);
|
||||
}
|
||||
}
|
||||
|
||||
matrixPop();
|
||||
}
|
||||
|
||||
void drawRooms() {
|
||||
void drawRooms()
|
||||
{
|
||||
rooms[camera.room].clip = { 0, 0, FRAME_WIDTH, FRAME_HEIGHT };
|
||||
visRoomsCount = 0;
|
||||
visRooms[visRoomsCount++] = camera.room;
|
||||
|
||||
getVisibleRooms(camera.room);
|
||||
|
||||
while (visRoomsCount--) {
|
||||
while (visRoomsCount--)
|
||||
{
|
||||
drawRoom(visRooms[visRoomsCount]);
|
||||
}
|
||||
}
|
||||
|
||||
void move(Item* item, const Anim* anim)
|
||||
{
|
||||
int32 speed = anim->speed;
|
||||
|
||||
if (item->flags.gravity)
|
||||
{
|
||||
speed += anim->accel * (item->frameIndex - anim->frameBegin - 1);
|
||||
item->hSpeed -= speed >> 16;
|
||||
speed += anim->accel;
|
||||
item->hSpeed += speed >> 16;
|
||||
|
||||
item->vSpeed += (item->vSpeed < 128) ? GRAVITY : 1;
|
||||
|
||||
item->pos.y += item->vSpeed;
|
||||
} else {
|
||||
speed += anim->accel * (item->frameIndex - anim->frameBegin);
|
||||
|
||||
item->hSpeed = speed >> 16;
|
||||
}
|
||||
|
||||
item->pos.x += phd_sin(item->angleY) * item->hSpeed >> FIXED_SHIFT;
|
||||
item->pos.z += phd_cos(item->angleY) * item->hSpeed >> FIXED_SHIFT;
|
||||
}
|
||||
|
||||
void animChange(Item* item, const Anim* anim)
|
||||
{
|
||||
if (!anim->scCount) return;
|
||||
// check state change
|
||||
}
|
||||
|
||||
void animCommand(bool fx, Item* item, const Anim* anim)
|
||||
{
|
||||
if (!anim->acCount) return;
|
||||
// check animation command
|
||||
}
|
||||
|
||||
const Anim* animSet(Item* item, int32 animIndex, int32 frameIndex)
|
||||
{
|
||||
item->animIndex = animIndex;
|
||||
item->frameIndex = frameIndex;
|
||||
item->state = anims[animIndex].state;
|
||||
|
||||
return anims + animIndex;
|
||||
}
|
||||
|
||||
void animUpdate(Item* item)
|
||||
{
|
||||
const Anim* anim = anims + item->animIndex;
|
||||
|
||||
item->frameIndex++;
|
||||
|
||||
animChange(item, anim);
|
||||
|
||||
if (item->frameIndex > anim->frameEnd)
|
||||
{
|
||||
animCommand(false, item, anim);
|
||||
anim = animSet(item, anim->nextAnimIndex, anim->nextFrameIndex);
|
||||
}
|
||||
|
||||
animCommand(true, item, anim);
|
||||
|
||||
//move(item, anim);
|
||||
}
|
||||
|
||||
void updateItems()
|
||||
{
|
||||
int32 itemIndex = firstActive;
|
||||
while (itemIndex != NO_ITEM)
|
||||
{
|
||||
Item* item = items + itemIndex;
|
||||
|
||||
if (modelsMap[item->type] != NO_MODEL) {
|
||||
animUpdate(item);
|
||||
}
|
||||
|
||||
itemIndex = item->nextActive;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
uint32 SCREEN[WIDTH * HEIGHT];
|
||||
|
||||
extern uint8 fb[WIDTH * HEIGHT * 2];
|
||||
extern uint16 fb[WIDTH * HEIGHT];
|
||||
|
||||
LARGE_INTEGER g_timer;
|
||||
LARGE_INTEGER g_current;
|
||||
@ -20,7 +20,7 @@
|
||||
#elif defined(__TNS__)
|
||||
uint8* LEVEL1_PHD;
|
||||
|
||||
extern uint8 fb[WIDTH * HEIGHT];
|
||||
extern uint16 fb[WIDTH * HEIGHT];
|
||||
|
||||
unsigned int osTime;
|
||||
volatile unsigned int *timerBUS;
|
||||
@ -95,6 +95,7 @@ int32 fpsCounter = 0;
|
||||
|
||||
void update(int32 frames) {
|
||||
for (int32 i = 0; i < frames; i++) {
|
||||
updateItems();
|
||||
camera.update();
|
||||
}
|
||||
}
|
||||
@ -212,9 +213,8 @@ void render() {
|
||||
drawNumber(dbg_poly, FRAME_WIDTH, 48);
|
||||
drawNumber(dbg_sort, FRAME_WIDTH, 64);
|
||||
drawNumber(dbg_flush, FRAME_WIDTH, 80);
|
||||
drawNumber(dbg_transform + dbg_poly + dbg_sort + dbg_flush, FRAME_WIDTH, 96);
|
||||
drawNumber(dbg_vert_count, FRAME_WIDTH, 120);
|
||||
drawNumber(dbg_poly_count, FRAME_WIDTH, 136);
|
||||
drawNumber(dbg_vert_count, FRAME_WIDTH, 96);
|
||||
drawNumber(dbg_poly_count, FRAME_WIDTH, 112);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -226,22 +226,10 @@ void render() {
|
||||
HDC hDC;
|
||||
|
||||
void blit() {
|
||||
#ifdef USE_MODE_5
|
||||
for (int i = 0; i < WIDTH * HEIGHT; i++) {
|
||||
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++) {
|
||||
#ifdef DEBUG_OVERDRAW
|
||||
uint8 c = ((uint8*)fb)[i];
|
||||
SCREEN[i] = c | (c << 8) | (c << 16) | 0xFF000000;
|
||||
#else
|
||||
uint16 c = palette[((uint8*)fb)[i]];
|
||||
SCREEN[i] = (((c << 3) & 0xFF) << 16) | ((((c >> 5) << 3) & 0xFF) << 8) | ((c >> 10 << 3) & 0xFF) | 0xFF000000;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
for (int i = 0; i < WIDTH * HEIGHT; i++) {
|
||||
uint16 c = ((uint16*)fb)[i];
|
||||
SCREEN[i] = (((c << 3) & 0xFF) << 16) | ((((c >> 5) << 3) & 0xFF) << 8) | ((c >> 10 << 3) & 0xFF) | 0xFF000000;
|
||||
}
|
||||
|
||||
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, SCREEN, &bmi, DIB_RGB_COLORS, SRCCOPY);
|
||||
@ -305,13 +293,11 @@ int main(void) {
|
||||
}
|
||||
#elif defined(__GBA__)
|
||||
// set low latency mode via WAITCNT register (thanks to GValiente)
|
||||
#define BIT_SET(y, flag) (y |= (flag))
|
||||
#define REG_WAITCNT_NV *(u16*)(REG_BASE + 0x0204)
|
||||
|
||||
BIT_SET(REG_WAITCNT_NV, 0x0008 | 0x0010 | 0x4000);
|
||||
#define REG_WAITCNT_NV *(u16*)(REG_BASE + 0x0204)
|
||||
REG_WAITCNT_NV |= (0x0008 | 0x0010 | 0x4000);
|
||||
#endif
|
||||
|
||||
initRender();
|
||||
initLUT();
|
||||
|
||||
readLevel(LEVEL1_PHD);
|
||||
|
||||
@ -330,8 +316,8 @@ int main(void) {
|
||||
|
||||
MSG msg;
|
||||
|
||||
int startTime = GetTickCount();
|
||||
int lastTime = -16;
|
||||
int startTime = GetTickCount() - 33;
|
||||
int lastFrame = 0;
|
||||
|
||||
do {
|
||||
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
|
||||
@ -339,9 +325,9 @@ int main(void) {
|
||||
DispatchMessage(&msg);
|
||||
} else {
|
||||
|
||||
int time = GetTickCount() - startTime;
|
||||
update((time - lastTime) / 16);
|
||||
lastTime = time;
|
||||
int frame = (GetTickCount() - startTime) / 33;
|
||||
update(frame - lastFrame);
|
||||
lastFrame = frame;
|
||||
|
||||
render();
|
||||
|
||||
@ -356,17 +342,10 @@ int main(void) {
|
||||
|
||||
uint16 mode = BG2_ON | BACKBUFFER;
|
||||
|
||||
#ifdef USE_MODE_5
|
||||
mode |= MODE_5;
|
||||
mode |= MODE_5;
|
||||
|
||||
REG_BG2PA = 256 - 64 - 16 - 4 - 1;
|
||||
REG_BG2PD = 256 - 48 - 2;
|
||||
#else
|
||||
mode |= MODE_4;
|
||||
|
||||
REG_BG2PA = 256 / SCALE;
|
||||
REG_BG2PD = 256 / SCALE;
|
||||
#endif
|
||||
REG_BG2PA = 256 - 64 - 16 - 4 - 1;
|
||||
REG_BG2PD = 256 - 48 - 2;
|
||||
|
||||
int32 lastFrameIndex = -1;
|
||||
|
||||
@ -387,7 +366,7 @@ int main(void) {
|
||||
keys[IK_L] = (key & KEY_L);
|
||||
keys[IK_R] = (key & KEY_R);
|
||||
|
||||
int32 frame = frameIndex;
|
||||
int32 frame = frameIndex / 2;
|
||||
update(frame - lastFrameIndex);
|
||||
lastFrameIndex = frame;
|
||||
|
||||
@ -396,7 +375,7 @@ int main(void) {
|
||||
fpsCounter++;
|
||||
if (frameIndex >= 60) {
|
||||
frameIndex -= 60;
|
||||
lastFrameIndex -= 60;
|
||||
lastFrameIndex -= 30;
|
||||
|
||||
fps = fpsCounter;
|
||||
|
||||
|
@ -1,36 +1,28 @@
|
||||
#include "common.h"
|
||||
|
||||
#define DIV_TABLE_SIZE 256
|
||||
|
||||
uint16 divTable[DIV_TABLE_SIZE]; // IWRAM 0.5 kb
|
||||
|
||||
#if defined(_WIN32)
|
||||
uint8 fb[WIDTH * HEIGHT * 2];
|
||||
uint16 fb[WIDTH * HEIGHT];
|
||||
#elif defined(__GBA__)
|
||||
uint32 fb = VRAM;
|
||||
#elif defined(__TNS__)
|
||||
uint8 fb[WIDTH * HEIGHT];
|
||||
uint16 fb[WIDTH * HEIGHT];
|
||||
#endif
|
||||
|
||||
#define FixedInvS(x) ((x < 0) ? -divTable[abs(x)] : divTable[x])
|
||||
#define FixedInvU(x) divTable[x]
|
||||
#define PAL_COLOR_TRANSP 0x0000
|
||||
#define PAL_COLOR_BLACK 0x0421
|
||||
|
||||
#if defined(USE_MODE_5) || defined(_WIN32)
|
||||
uint16 palette[256];
|
||||
#endif
|
||||
|
||||
uint8 lightmap[256 * 32]; // IWRAM 8 kb
|
||||
uint8* ft_lightmap;
|
||||
|
||||
const uint8* tiles;
|
||||
const uint8* tile;
|
||||
uint16 palette[256]; // IWRAM 0.5 kb
|
||||
uint8 lightmap[256 * 32]; // IWRAM 8 kb
|
||||
const uint8* ft_lightmap;
|
||||
|
||||
const Texture* textures;
|
||||
const uint8* tiles;
|
||||
const uint8* tile;
|
||||
|
||||
uint32 gVerticesCount = 0;
|
||||
int32 gFacesCount = 0;
|
||||
|
||||
EWRAM_DATA Vertex gVertices[MAX_VERTICES]; // EWRAM 8 kb
|
||||
EWRAM_DATA Vertex gVertices[MAX_VERTICES]; // EWRAM 16 kb
|
||||
EWRAM_DATA Face* gFacesSorted[MAX_FACES]; // EWRAM 2 kb
|
||||
EWRAM_DATA Face gFaces[MAX_FACES]; // EWRAM 5 kb
|
||||
|
||||
@ -38,9 +30,6 @@ EWRAM_DATA Face gFaces[MAX_FACES]; // EWRAM 5 kb
|
||||
|
||||
Rect clip;
|
||||
|
||||
Matrix matrixStack[MAX_MATRICES];
|
||||
int32 matrixStackIndex = 0;
|
||||
|
||||
template <class T>
|
||||
INLINE void swap(T &a, T &b) {
|
||||
T tmp = a;
|
||||
@ -52,12 +41,6 @@ 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);
|
||||
}
|
||||
|
||||
INLINE void sortVertices(VertexUV *&t, VertexUV *&m, VertexUV *&b) {
|
||||
if (t->v.y > m->v.y) swap(t, m);
|
||||
if (t->v.y > b->v.y) swap(t, b);
|
||||
if (m->v.y > b->v.y) swap(m, b);
|
||||
}
|
||||
|
||||
INLINE int32 classify(const Vertex* v) {
|
||||
return (v->x < clip.x0 ? 1 : 0) |
|
||||
(v->x > clip.x1 ? 2 : 0) |
|
||||
@ -65,14 +48,68 @@ INLINE int32 classify(const Vertex* v) {
|
||||
(v->y > clip.y1 ? 8 : 0);
|
||||
}
|
||||
|
||||
void transform(const vec3s &v, int32 vg) {
|
||||
#if defined(_WIN32)
|
||||
if (gVerticesCount >= MAX_VERTICES) {
|
||||
DebugBreak();
|
||||
return;
|
||||
bool boxIsVisible(const Box* box)
|
||||
{
|
||||
const Matrix &m = matrixGet();
|
||||
|
||||
if (m[2][3] >= VIEW_MAX_F) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
const Matrix &m = matrixStack[matrixStackIndex];
|
||||
|
||||
if (m[2][3] < VIEW_MIN_F) { // TODO large objects
|
||||
return false;
|
||||
}
|
||||
|
||||
const vec3i v[8] {
|
||||
{ box->minX, box->minY, box->minZ },
|
||||
{ box->maxX, box->minY, box->minZ },
|
||||
{ box->minX, box->maxY, box->minZ },
|
||||
{ box->maxX, box->maxY, box->minZ },
|
||||
{ box->minX, box->minY, box->maxZ },
|
||||
{ box->maxX, box->minY, box->maxZ },
|
||||
{ box->minX, box->maxY, box->maxZ },
|
||||
{ box->maxX, box->maxY, box->maxZ }
|
||||
};
|
||||
|
||||
Rect rect = { INT_MAX, INT_MAX, INT_MIN, INT_MIN };
|
||||
|
||||
for (int32 i = 0; i < 8; i++) {
|
||||
int32 z = DP43(m[2], v[i]);
|
||||
|
||||
if (z < VIEW_MIN_F || z >= VIEW_MAX_F) { // TODO znear clip
|
||||
continue;
|
||||
}
|
||||
|
||||
int32 x = DP43(m[0], v[i]);
|
||||
int32 y = DP43(m[1], v[i]);
|
||||
|
||||
z >>= FOV_SHIFT;
|
||||
|
||||
x = (x / z);
|
||||
y = (y / z);
|
||||
|
||||
if (x < rect.x0) rect.x0 = x;
|
||||
if (x > rect.x1) rect.x1 = x;
|
||||
if (y < rect.y0) rect.y0 = y;
|
||||
if (y > rect.y1) rect.y1 = y;
|
||||
}
|
||||
|
||||
rect.x0 += (FRAME_WIDTH / 2);
|
||||
rect.y0 += (FRAME_HEIGHT / 2);
|
||||
rect.x1 += (FRAME_WIDTH / 2);
|
||||
rect.y1 += (FRAME_HEIGHT / 2);
|
||||
|
||||
return !(rect.x0 > rect.x1 ||
|
||||
rect.x0 > clip.x1 ||
|
||||
rect.x1 < clip.x0 ||
|
||||
rect.y0 > clip.y1 ||
|
||||
rect.y1 < clip.y0);
|
||||
}
|
||||
|
||||
void transform(const vec3s &v, int32 vg) {
|
||||
ASSERT(gVerticesCount < MAX_VERTICES);
|
||||
|
||||
const Matrix &m = matrixGet();
|
||||
|
||||
Vertex &res = gVertices[gVerticesCount++];
|
||||
|
||||
@ -110,7 +147,7 @@ void transform(const vec3s &v, int32 vg) {
|
||||
res.clip = classify(&res);
|
||||
}
|
||||
|
||||
void transform_room(const Room::Vertex* vertex, int32 vCount)
|
||||
void transformRoom(const RoomInfo::Vertex* vertex, int32 vCount)
|
||||
{
|
||||
for (int32 i = 0; i < vCount; i++)
|
||||
{
|
||||
@ -119,10 +156,10 @@ void transform_room(const Room::Vertex* vertex, int32 vCount)
|
||||
}
|
||||
}
|
||||
|
||||
void transform_mesh(const vec3s* vertices, int32 vCount)
|
||||
void transformMesh(const vec3s* vertices, int32 vCount, uint16 intensity)
|
||||
{
|
||||
for (int32 i = 0; i < vCount; i++) {
|
||||
transform(*vertices++, 4096);
|
||||
transform(*vertices++, intensity);
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,40 +300,15 @@ VertexUV* clipPoly(VertexUV* poly, VertexUV* tmp, int32 &pCount) {
|
||||
#define FETCH_GT_PAL() 32
|
||||
#define FETCH_G_PAL(palIndex) 32
|
||||
#else
|
||||
#define FETCH_T() tile[(t & 0xFF00) | (t >> 24)]
|
||||
#define FETCH_GT() lightmap[(g & 0x1F00) | FETCH_T()]
|
||||
#define FETCH_FT() ft_lightmap[FETCH_T()]
|
||||
|
||||
INLINE uint32 FETCH_FT2(uint32 &t, uint32 dtdx) {
|
||||
uint32 p = FETCH_FT();
|
||||
t += dtdx;
|
||||
p |= FETCH_FT() << 8;
|
||||
t += dtdx;
|
||||
return p;
|
||||
}
|
||||
#define FETCH_T() tile[(t & 0xFF00) | (t >> 24)]
|
||||
#define FETCH_G() lightmap[(g & 0x1F00) | palIndex]
|
||||
#define FETCH_GT() lightmap[(g & 0x1F00) | FETCH_T()]
|
||||
#define FETCH_FT() ft_lightmap[FETCH_T()]
|
||||
|
||||
INLINE uint32 FETCH_GT2(uint32 &g, uint32 &t, uint32 dgdx, uint32 dtdx) {
|
||||
#if 0
|
||||
uint32 light = g & 0x1F00;
|
||||
uint32 p = lightmap[light | FETCH_T()];
|
||||
t += dtdx;
|
||||
p |= lightmap[light | FETCH_T()] << 8;
|
||||
t += dtdx;
|
||||
g += dgdx;
|
||||
return p;
|
||||
#else
|
||||
uint32 p = FETCH_GT();
|
||||
t += dtdx;
|
||||
p |= FETCH_GT() << 8;
|
||||
t += dtdx;
|
||||
g += dgdx;
|
||||
return p;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define FETCH_G(palIndex) lightmap[(g & 0x1F00) | palIndex]
|
||||
#define FETCH_GT_PAL() palette[FETCH_GT()]
|
||||
#define FETCH_G_PAL(palIndex) palette[FETCH_G(palIndex)]
|
||||
#define PUT_PIXEL_GT() { uint16 p = palette[FETCH_GT()]; if (p) *pixel = p; }
|
||||
#define PUT_PIXEL_FT() { uint16 p = palette[FETCH_FT()]; if (p) *pixel = p; }
|
||||
#define PUT_PIXEL_G() { *pixel = palette[FETCH_G()]; }
|
||||
#endif
|
||||
|
||||
struct Edge {
|
||||
@ -427,426 +439,70 @@ struct Edge {
|
||||
};
|
||||
|
||||
INLINE void scanlineG(uint16* buffer, int32 x1, int32 x2, uint8 palIndex, uint32 g, uint32 dgdx) {
|
||||
#if defined(USE_MODE_5)
|
||||
uint16* pixel = buffer + x1;
|
||||
uint16* pixel = buffer + x1;
|
||||
|
||||
if (x1 & 1) {
|
||||
*pixel++ = FETCH_G_PAL(palIndex);
|
||||
g += dgdx;
|
||||
x1++;
|
||||
int32 width = x2 - x1;
|
||||
|
||||
if (x1 >= x2) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
dgdx <<= 1;
|
||||
|
||||
int32 width2 = (x2 - x1) >> 1;
|
||||
|
||||
dgdx <<= 1;
|
||||
|
||||
while (width2--) {
|
||||
uint32 p = FETCH_G_PAL(palIndex);
|
||||
g += dgdx;
|
||||
|
||||
*(uint32*)pixel = p | (p << 16);
|
||||
pixel += 2;
|
||||
}
|
||||
|
||||
if (x2 & 1) {
|
||||
*pixel++ = FETCH_G_PAL(palIndex);
|
||||
}
|
||||
#elif defined(USE_MODE_4)
|
||||
if (x1 & 1)
|
||||
{
|
||||
uint16 &p = *(uint16*)((uint8*)buffer + x1 - 1);
|
||||
p = (p & 0x00FF) | (FETCH_G(palIndex) << 8);
|
||||
g += dgdx;
|
||||
x1++;
|
||||
}
|
||||
|
||||
int32 width = (x2 - x1) >> 1;
|
||||
uint16* pixel = (uint16*)((uint8*)buffer + x1);
|
||||
|
||||
dgdx <<= 1;
|
||||
|
||||
if (width && (x1 & 3))
|
||||
{
|
||||
uint16 p = FETCH_G(palIndex);
|
||||
*pixel++ = p | (FETCH_G(palIndex) << 8);
|
||||
|
||||
g += dgdx;
|
||||
while (width--) {
|
||||
PUT_PIXEL_G();
|
||||
pixel++;
|
||||
|
||||
if (width) {
|
||||
width--;
|
||||
PUT_PIXEL_G();
|
||||
pixel++;
|
||||
}
|
||||
|
||||
while (width-- > 0)
|
||||
{
|
||||
uint32 p = FETCH_G(palIndex);
|
||||
p |= (FETCH_G(palIndex) << 8);
|
||||
|
||||
g += dgdx;
|
||||
|
||||
if (width-- > 0)
|
||||
{
|
||||
p |= (FETCH_G(palIndex) << 16);
|
||||
p |= (FETCH_G(palIndex) << 24);
|
||||
|
||||
g += dgdx;
|
||||
|
||||
*(uint32*)pixel = p;
|
||||
pixel += 2;
|
||||
} else {
|
||||
*(uint16*)pixel = p;
|
||||
pixel += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (x2 & 1)
|
||||
{
|
||||
*pixel = (*pixel & 0xFF00) | FETCH_G(palIndex);
|
||||
}
|
||||
#else
|
||||
if (x1 & 1)
|
||||
{
|
||||
*((uint8*)buffer + x1) = FETCH_G(palIndex);
|
||||
g += dgdx;
|
||||
x1++;
|
||||
}
|
||||
|
||||
int32 width = (x2 - x1) >> 1;
|
||||
uint16* pixel = (uint16*)((uint8*)buffer + x1);
|
||||
|
||||
dgdx <<= 1;
|
||||
|
||||
if (width && (x1 & 3))
|
||||
{
|
||||
uint16 p = FETCH_G(palIndex);
|
||||
*pixel++ = p | (FETCH_G(palIndex) << 8);
|
||||
|
||||
g += dgdx;
|
||||
|
||||
width--;
|
||||
}
|
||||
|
||||
while (width-- > 0)
|
||||
{
|
||||
uint32 p = FETCH_G(palIndex);
|
||||
p |= (FETCH_G(palIndex) << 8);
|
||||
|
||||
g += dgdx;
|
||||
|
||||
if (width-- > 0)
|
||||
{
|
||||
p |= (FETCH_G(palIndex) << 16);
|
||||
p |= (FETCH_G(palIndex) << 24);
|
||||
|
||||
g += dgdx;
|
||||
|
||||
*(uint32*)pixel = p;
|
||||
pixel += 2;
|
||||
} else {
|
||||
*(uint16*)pixel = p;
|
||||
pixel += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (x2 & 1)
|
||||
{
|
||||
*((uint8*)pixel) = FETCH_G(palIndex);
|
||||
}
|
||||
#endif
|
||||
g += dgdx;
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void scanlineGT(uint16* buffer, int32 x1, int32 x2, uint32 g, uint32 t, uint32 dgdx, uint32 dtdx) {
|
||||
#if defined(USE_MODE_5)
|
||||
uint16* pixel = buffer + x1;
|
||||
uint16* pixel = buffer + x1;
|
||||
|
||||
if (x1 & 1) {
|
||||
*pixel++ = FETCH_GT_PAL();
|
||||
t += dtdx;
|
||||
g += dgdx;
|
||||
x1++;
|
||||
int32 width = x2 - x1;
|
||||
|
||||
if (x1 >= x2) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
dgdx <<= 1;
|
||||
|
||||
int32 width2 = (x2 - x1) >> 1;
|
||||
while (width--) {
|
||||
PUT_PIXEL_GT();
|
||||
pixel++;
|
||||
t += dtdx;
|
||||
|
||||
dgdx <<= 1;
|
||||
|
||||
while (width2--) {
|
||||
uint32 p = FETCH_GT_PAL();
|
||||
t += dtdx;
|
||||
p |= FETCH_GT_PAL() << 16;
|
||||
t += dtdx;
|
||||
g += dgdx;
|
||||
|
||||
*(uint32*)pixel = p;
|
||||
pixel += 2;
|
||||
}
|
||||
|
||||
if (x2 & 1) {
|
||||
*pixel++ = FETCH_GT_PAL();
|
||||
}
|
||||
|
||||
#elif defined(USE_MODE_4)
|
||||
uint8* pixel = (uint8*)buffer + x1;
|
||||
|
||||
// align to 2
|
||||
if (x1 & 1)
|
||||
{
|
||||
pixel--;
|
||||
*(uint16*)pixel = *pixel | (FETCH_GT() << 8);
|
||||
pixel += 2;
|
||||
t += dtdx;
|
||||
g += dgdx;
|
||||
x1++;
|
||||
}
|
||||
|
||||
int32 width = (x2 - x1) >> 1;
|
||||
|
||||
dgdx <<= 1;
|
||||
|
||||
// align to 4
|
||||
if (width && (x1 & 3))
|
||||
{
|
||||
*(uint16*)pixel = FETCH_GT2(g, t, dgdx, dtdx);
|
||||
pixel += 2;
|
||||
if (width) {
|
||||
width--;
|
||||
}
|
||||
|
||||
// fast line
|
||||
if (width > 0)
|
||||
{
|
||||
while (width)
|
||||
{
|
||||
uint32 p = FETCH_GT2(g, t, dgdx, dtdx);
|
||||
if (width > 1) {
|
||||
// write 4 px
|
||||
p |= (FETCH_GT2(g, t, dgdx, dtdx) << 16);
|
||||
*(uint32*)pixel = p;
|
||||
pixel += 4;
|
||||
width -= 2;
|
||||
continue;
|
||||
}
|
||||
// write 2 px, end of fast line
|
||||
*(uint16*)pixel = p;
|
||||
pixel += 2;
|
||||
width -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// write 1 px, end of scanline
|
||||
if (x2 & 1)
|
||||
{
|
||||
*(uint16*)pixel = (*(uint16*)pixel & 0xFF00) | FETCH_GT();
|
||||
}
|
||||
#else
|
||||
if (x1 & 1)
|
||||
{
|
||||
*((uint8*)buffer + x1) = FETCH_GT();
|
||||
PUT_PIXEL_GT();
|
||||
pixel++;
|
||||
t += dtdx;
|
||||
g += dgdx;
|
||||
x1++;
|
||||
}
|
||||
|
||||
int32 width = (x2 - x1) >> 1;
|
||||
uint16* pixel = (uint16*)((uint8*)buffer + x1);
|
||||
|
||||
dgdx <<= 1;
|
||||
|
||||
if (width && (x1 & 3))
|
||||
{
|
||||
uint16 p = FETCH_GT();
|
||||
t += dtdx;
|
||||
*pixel++ = p | (FETCH_GT() << 8);
|
||||
t += dtdx;
|
||||
|
||||
g += dgdx;
|
||||
|
||||
width--;
|
||||
}
|
||||
|
||||
while (width-- > 0)
|
||||
{
|
||||
uint32 p = FETCH_GT();
|
||||
t += dtdx;
|
||||
p |= (FETCH_GT() << 8);
|
||||
t += dtdx;
|
||||
|
||||
g += dgdx;
|
||||
|
||||
if (width-- > 0)
|
||||
{
|
||||
p |= (FETCH_GT() << 16);
|
||||
t += dtdx;
|
||||
p |= (FETCH_GT() << 24);
|
||||
t += dtdx;
|
||||
|
||||
g += dgdx;
|
||||
|
||||
*(uint32*)pixel = p;
|
||||
pixel += 2;
|
||||
} else {
|
||||
*(uint16*)pixel = p;
|
||||
pixel += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (x2 & 1)
|
||||
{
|
||||
*((uint8*)pixel) = FETCH_GT();
|
||||
}
|
||||
#endif
|
||||
g += dgdx;
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void scanlineFT(uint16* buffer, int32 x1, int32 x2, uint32 t, uint32 dtdx) {
|
||||
#if defined(USE_MODE_5)
|
||||
uint16* pixel = buffer + x1;
|
||||
uint16* pixel = buffer + x1;
|
||||
|
||||
if (x1 & 1) {
|
||||
*pixel++ = FETCH_GT_PAL();
|
||||
t += dtdx;
|
||||
g += dgdx;
|
||||
x1++;
|
||||
int32 width = x2 - x1;
|
||||
|
||||
if (x1 >= x2) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (width--) {
|
||||
PUT_PIXEL_FT();
|
||||
pixel++;
|
||||
t += dtdx;
|
||||
|
||||
int32 width2 = (x2 - x1) >> 1;
|
||||
|
||||
dgdx <<= 1;
|
||||
|
||||
while (width2--) {
|
||||
uint32 p = FETCH_GT_PAL();
|
||||
t += dtdx;
|
||||
p |= FETCH_GT_PAL() << 16;
|
||||
t += dtdx;
|
||||
g += dgdx;
|
||||
|
||||
*(uint32*)pixel = p;
|
||||
pixel += 2;
|
||||
}
|
||||
|
||||
if (x2 & 1) {
|
||||
*pixel++ = FETCH_GT_PAL();
|
||||
}
|
||||
|
||||
#elif defined(USE_MODE_4)
|
||||
uint8* pixel = (uint8*)buffer + x1;
|
||||
|
||||
// align to 2
|
||||
if (x1 & 1)
|
||||
{
|
||||
pixel--;
|
||||
*(uint16*)pixel = *pixel | (FETCH_FT() << 8);
|
||||
pixel += 2;
|
||||
t += dtdx;
|
||||
x1++;
|
||||
}
|
||||
|
||||
int32 width = (x2 - x1) >> 1;
|
||||
|
||||
// align to 4
|
||||
if (width && (x1 & 3))
|
||||
{
|
||||
*(uint16*)pixel = FETCH_FT2(t, dtdx);
|
||||
pixel += 2;
|
||||
if (width) {
|
||||
width--;
|
||||
}
|
||||
|
||||
// fast line
|
||||
if (width > 0)
|
||||
{
|
||||
while (width)
|
||||
{
|
||||
uint32 p = FETCH_FT2(t, dtdx);
|
||||
if (width > 1) {
|
||||
// write 4 px
|
||||
p |= (FETCH_FT2(t, dtdx) << 16);
|
||||
*(uint32*)pixel = p;
|
||||
pixel += 4;
|
||||
width -= 2;
|
||||
continue;
|
||||
}
|
||||
// write 2 px, end of fast line
|
||||
*(uint16*)pixel = p;
|
||||
pixel += 2;
|
||||
width -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// write 1 px, end of scanline
|
||||
if (x2 & 1)
|
||||
{
|
||||
*(uint16*)pixel = (*(uint16*)pixel & 0xFF00) | FETCH_FT();
|
||||
}
|
||||
|
||||
#else
|
||||
if (x1 & 1)
|
||||
{
|
||||
*((uint8*)buffer + x1) = FETCH_GT();
|
||||
PUT_PIXEL_FT();
|
||||
pixel++;
|
||||
t += dtdx;
|
||||
g += dgdx;
|
||||
x1++;
|
||||
}
|
||||
|
||||
int32 width = (x2 - x1) >> 1;
|
||||
uint16* pixel = (uint16*)((uint8*)buffer + x1);
|
||||
|
||||
dgdx <<= 1;
|
||||
|
||||
if (width && (x1 & 3))
|
||||
{
|
||||
uint16 p = FETCH_GT();
|
||||
t += dtdx;
|
||||
*pixel++ = p | (FETCH_GT() << 8);
|
||||
t += dtdx;
|
||||
|
||||
g += dgdx;
|
||||
|
||||
width--;
|
||||
}
|
||||
|
||||
while (width-- > 0)
|
||||
{
|
||||
uint32 p = FETCH_GT();
|
||||
t += dtdx;
|
||||
p |= (FETCH_GT() << 8);
|
||||
t += dtdx;
|
||||
|
||||
g += dgdx;
|
||||
|
||||
if (width-- > 0)
|
||||
{
|
||||
p |= (FETCH_GT() << 16);
|
||||
t += dtdx;
|
||||
p |= (FETCH_GT() << 24);
|
||||
t += dtdx;
|
||||
|
||||
g += dgdx;
|
||||
|
||||
*(uint32*)pixel = p;
|
||||
pixel += 2;
|
||||
} else {
|
||||
*(uint16*)pixel = p;
|
||||
pixel += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (x2 & 1)
|
||||
{
|
||||
*((uint8*)pixel) = FETCH_GT();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void rasterizeG(int16 y, int32 palIndex, Edge &L, Edge &R) {
|
||||
uint16 *buffer = (uint16*)fb + y * (WIDTH / PIXEL_SIZE);
|
||||
uint16 *buffer = (uint16*)fb + y * WIDTH;
|
||||
|
||||
while (1)
|
||||
{
|
||||
@ -884,7 +540,7 @@ void rasterizeG(int16 y, int32 palIndex, Edge &L, Edge &R) {
|
||||
scanlineG(buffer, x1, x2, palIndex, L.g >> 8, dgdx);
|
||||
}
|
||||
|
||||
buffer += WIDTH / PIXEL_SIZE;
|
||||
buffer += WIDTH;
|
||||
|
||||
L.stepG();
|
||||
R.stepG();
|
||||
@ -893,7 +549,7 @@ void rasterizeG(int16 y, int32 palIndex, Edge &L, Edge &R) {
|
||||
}
|
||||
|
||||
void rasterizeGT(int16 y, Edge &L, Edge &R) {
|
||||
uint16 *buffer = (uint16*)fb + y * (WIDTH / PIXEL_SIZE);
|
||||
uint16 *buffer = (uint16*)fb + y * WIDTH;
|
||||
|
||||
while (1)
|
||||
{
|
||||
@ -935,7 +591,7 @@ void rasterizeGT(int16 y, Edge &L, Edge &R) {
|
||||
scanlineGT(buffer, x1, x2, L.g >> 8, L.t.uv, dgdx, dtdx);
|
||||
};
|
||||
|
||||
buffer += WIDTH / PIXEL_SIZE;
|
||||
buffer += WIDTH;
|
||||
|
||||
L.stepGT();
|
||||
R.stepGT();
|
||||
@ -944,7 +600,7 @@ void rasterizeGT(int16 y, Edge &L, Edge &R) {
|
||||
}
|
||||
|
||||
void rasterizeFT(int16 y, Edge &L, Edge &R) {
|
||||
uint16 *buffer = (uint16*)fb + y * (WIDTH / PIXEL_SIZE);
|
||||
uint16 *buffer = (uint16*)fb + y * WIDTH;
|
||||
|
||||
ft_lightmap = &lightmap[(L.vert[0]->v.g << 8) & 0x1F00];
|
||||
|
||||
@ -986,7 +642,7 @@ void rasterizeFT(int16 y, Edge &L, Edge &R) {
|
||||
scanlineFT(buffer, x1, x2, L.t.uv, dtdx);
|
||||
};
|
||||
|
||||
buffer += WIDTH / PIXEL_SIZE;
|
||||
buffer += WIDTH;
|
||||
|
||||
L.stepFT();
|
||||
R.stepFT();
|
||||
@ -999,7 +655,9 @@ void drawTriangle(const Face* face, VertexUV *v) {
|
||||
*v2 = v + 1,
|
||||
*v3 = v + 2;
|
||||
|
||||
sortVertices(v1, v2, v3);
|
||||
if (v1->v.y > v2->v.y) swap(v1, v2);
|
||||
if (v1->v.y > v3->v.y) swap(v1, v3);
|
||||
if (v2->v.y > v3->v.y) swap(v2, v3);
|
||||
|
||||
int32 temp = (v2->v.y - v1->v.y) * FixedInvU(v3->v.y - v1->v.y);
|
||||
|
||||
@ -1020,9 +678,7 @@ void drawTriangle(const Face* face, VertexUV *v) {
|
||||
L.vert[0] = v3;
|
||||
L.vert[1] = v1;
|
||||
L.index = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
L.vert[0] = v3;
|
||||
L.vert[1] = v2;
|
||||
L.vert[2] = v1;
|
||||
@ -1049,23 +705,35 @@ void drawQuad(const Face* face, VertexUV *v) {
|
||||
*v3 = v + 2,
|
||||
*v4 = v + 3;
|
||||
|
||||
int32 minY = 0x7FFF;
|
||||
int32 maxY = -0x7FFF;
|
||||
int32 t = 0, b = 0;
|
||||
|
||||
VertexUV* poly[8] = { v1, v2, v3, v4, v1, v2, v3, v4 };
|
||||
|
||||
for (int32 i = 0; i < 4; i++) {
|
||||
VertexUV *v = poly[i];
|
||||
int32 t, b;
|
||||
|
||||
if (v->v.y < minY) {
|
||||
minY = v->v.y;
|
||||
t = i;
|
||||
if (v1->v.y < v2->v.y) {
|
||||
if (v1->v.y < v3->v.y) {
|
||||
t = (v1->v.y < v4->v.y) ? 0 : 3;
|
||||
} else {
|
||||
t = (v3->v.y < v4->v.y) ? 2 : 3;
|
||||
}
|
||||
} else {
|
||||
if (v2->v.y < v3->v.y) {
|
||||
t = (v2->v.y < v4->v.y) ? 1 : 3;
|
||||
} else {
|
||||
t = (v3->v.y < v4->v.y) ? 2 : 3;
|
||||
}
|
||||
}
|
||||
|
||||
if (v->v.y > maxY) {
|
||||
maxY = v->v.y;
|
||||
b = i;
|
||||
if (v1->v.y > v2->v.y) {
|
||||
if (v1->v.y > v3->v.y) {
|
||||
b = (v1->v.y > v4->v.y) ? 0 : 3;
|
||||
} else {
|
||||
b = (v3->v.y > v4->v.y) ? 2 : 3;
|
||||
}
|
||||
} else {
|
||||
if (v2->v.y > v3->v.y) {
|
||||
b = (v2->v.y > v4->v.y) ? 1 : 3;
|
||||
} else {
|
||||
b = (v3->v.y > v4->v.y) ? 2 : 3;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1163,53 +831,28 @@ void drawGlyph(const Sprite *sprite, int32 x, int32 y) {
|
||||
int32 ix = x + sprite->l;
|
||||
int32 iy = y + sprite->t;
|
||||
|
||||
uint16* ptr = (uint16*)fb + iy * (WIDTH / PIXEL_SIZE);
|
||||
uint16* ptr = (uint16*)fb + iy * WIDTH;
|
||||
|
||||
#ifdef USE_MODE_5
|
||||
ptr += ix;
|
||||
#else
|
||||
ptr += ix >> 1;
|
||||
#endif
|
||||
|
||||
const uint8* glyphData = tiles + (sprite->tile << 16) + 256 * sprite->v + sprite->u;
|
||||
|
||||
while (h--)
|
||||
{
|
||||
#ifdef USE_MODE_5
|
||||
for (int32 i = 0; i < w; i++) {
|
||||
if (glyphData[i] == 0) continue;
|
||||
|
||||
ptr[i] = palette[glyphData[i]];
|
||||
}
|
||||
#else
|
||||
const uint8* p = glyphData;
|
||||
|
||||
for (int32 i = 0; i < (w / 2); i++) {
|
||||
|
||||
if (p[0] || p[1]) {
|
||||
uint16 d = ptr[i];
|
||||
|
||||
if (p[0]) d = (d & 0xFF00) | p[0];
|
||||
if (p[1]) d = (d & 0x00FF) | (p[1] << 8);
|
||||
|
||||
ptr[i] = d;
|
||||
}
|
||||
|
||||
p += 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
ptr += WIDTH / PIXEL_SIZE;
|
||||
ptr += WIDTH;
|
||||
glyphData += 256;
|
||||
}
|
||||
}
|
||||
|
||||
void faceAddQuad(uint32 flags, const Index* indices, int32 startVertex) {
|
||||
#if defined(_WIN32)
|
||||
if (gFacesCount >= MAX_FACES) {
|
||||
DebugBreak();
|
||||
}
|
||||
#endif
|
||||
ASSERT(gFacesCount < MAX_FACES);
|
||||
|
||||
Vertex* v = gVertices + startVertex;
|
||||
Vertex* v1 = v + indices[0];
|
||||
Vertex* v2 = v + indices[1];
|
||||
@ -1247,11 +890,8 @@ void faceAddQuad(uint32 flags, const Index* indices, int32 startVertex) {
|
||||
}
|
||||
|
||||
void faceAddTriangle(uint32 flags, const Index* indices, int32 startVertex) {
|
||||
#if defined(_WIN32)
|
||||
if (gFacesCount >= MAX_FACES) {
|
||||
DebugBreak();
|
||||
}
|
||||
#endif
|
||||
ASSERT(gFacesCount < MAX_FACES);
|
||||
|
||||
Vertex* v = gVertices + startVertex;
|
||||
Vertex* v1 = v + indices[0];
|
||||
Vertex* v2 = v + indices[1];
|
||||
@ -1286,7 +926,7 @@ void faceAddTriangle(uint32 flags, const Index* indices, int32 startVertex) {
|
||||
f->indices[2] = indices[2] - indices[0];
|
||||
}
|
||||
|
||||
void faceAdd_room(const Quad* quads, int32 qCount, const Triangle* triangles, int32 tCount, int32 startVertex)
|
||||
void faceAddRoom(const Quad* quads, int32 qCount, const Triangle* triangles, int32 tCount, int32 startVertex)
|
||||
{
|
||||
for (uint16 i = 0; i < qCount; i++) {
|
||||
faceAddQuad(quads[i].flags, quads[i].indices, startVertex);
|
||||
@ -1297,7 +937,7 @@ void faceAdd_room(const Quad* quads, int32 qCount, const Triangle* triangles, in
|
||||
}
|
||||
}
|
||||
|
||||
void faceAdd_mesh(const Quad* rFaces, const Quad* crFaces, const Triangle* tFaces, const Triangle* ctFaces, int32 rCount, int32 crCount, int32 tCount, int32 ctCount, int32 startVertex)
|
||||
void faceAddMesh(const Quad* rFaces, const Quad* crFaces, const Triangle* tFaces, const Triangle* ctFaces, int32 rCount, int32 crCount, int32 tCount, int32 ctCount, int32 startVertex)
|
||||
{
|
||||
for (int i = 0; i < rCount; i++) {
|
||||
faceAddQuad(rFaces[i].flags, rFaces[i].indices, startVertex);
|
||||
@ -1359,6 +999,9 @@ void flush() {
|
||||
v[1].t.uv = tex.uv1;
|
||||
v[2].t.uv = tex.uv2;
|
||||
v[3].t.uv = tex.uv3;
|
||||
palette[0] = (tex.attribute == 1) ? PAL_COLOR_TRANSP : PAL_COLOR_BLACK;
|
||||
} else {
|
||||
palette[0] = PAL_COLOR_BLACK;
|
||||
}
|
||||
|
||||
Vertex *p = gVertices + face->start;
|
||||
@ -1397,14 +1040,6 @@ void flush() {
|
||||
gFacesCount = 0;
|
||||
}
|
||||
|
||||
void initRender() {
|
||||
divTable[0] = 0xFFFF;
|
||||
divTable[1] = 0xFFFF;
|
||||
for (uint32 i = 2; i < DIV_TABLE_SIZE; i++) {
|
||||
divTable[i] = (1 << 16) / i;
|
||||
}
|
||||
}
|
||||
|
||||
void dmaClear(uint32 *dst, uint32 count) {
|
||||
#ifdef __GBA__
|
||||
vu32 value = 0;
|
||||
@ -1417,5 +1052,5 @@ void dmaClear(uint32 *dst, uint32 count) {
|
||||
}
|
||||
|
||||
void clear() {
|
||||
dmaClear((uint32*)fb, (WIDTH * HEIGHT) >> PIXEL_SIZE);
|
||||
dmaClear((uint32*)fb, (WIDTH * HEIGHT) >> 1);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user