mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-13 16:44:50 +02:00
GBA objects and animations, remove MODE4 code
This commit is contained in:
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#define CAM_SPEED (1 << 2)
|
#define CAM_SPEED (1 << 3)
|
||||||
#define CAM_ROT_SPEED (1 << 8)
|
#define CAM_ROT_SPEED (1 << 9)
|
||||||
#define CAM_ROT_X_MAX int16(85 * 0x8000 / 180)
|
#define CAM_ROT_X_MAX int16(85 * 0x8000 / 180)
|
||||||
|
|
||||||
struct Camera {
|
struct Camera {
|
||||||
@@ -19,6 +19,9 @@ struct Camera {
|
|||||||
|
|
||||||
rotX = 0;
|
rotX = 0;
|
||||||
rotY = 16 << 8;
|
rotY = 16 << 8;
|
||||||
|
|
||||||
|
//rotX = -0x1000;
|
||||||
|
//rotY = int16(0x8000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update() {
|
void update() {
|
||||||
@@ -29,7 +32,7 @@ struct Camera {
|
|||||||
|
|
||||||
rotX = clamp(rotX, -CAM_ROT_X_MAX, CAM_ROT_X_MAX);
|
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();
|
Matrix &m = matrixGet();
|
||||||
|
|
||||||
@@ -57,7 +60,7 @@ struct Camera {
|
|||||||
pos.z -= m[2].z * CAM_SPEED >> 10;
|
pos.z -= m[2].z * CAM_SPEED >> 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
room = getRoomIndex(room, pos);
|
room = getRoomIndex(room, &pos);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
vec3i viewPos;
|
uint16 divTable[DIV_TABLE_SIZE]; // IWRAM 0.5 kb
|
||||||
|
vec3i viewPos;
|
||||||
extern Matrix matrixStack[MAX_MATRICES];
|
Matrix matrixStack[MAX_MATRICES];
|
||||||
extern int32 matrixStackIndex;
|
int32 matrixStackIndex = 0;
|
||||||
|
|
||||||
const int16 sin_table[1025] = { // IWRAM 2 kb
|
const int16 sin_table[1025] = { // IWRAM 2 kb
|
||||||
0x0000, 0x0019, 0x0032, 0x004B, 0x0065, 0x007E, 0x0097, 0x00B0,
|
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);
|
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];
|
return matrixStack[matrixStackIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
void matrixPush() {
|
void matrixPush()
|
||||||
#if defined(_WIN32)
|
{
|
||||||
if (matrixStackIndex >= MAX_MATRICES - 1) {
|
ASSERT(matrixStackIndex < MAX_MATRICES - 1);
|
||||||
DebugBreak();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
Matrix &a = matrixStack[matrixStackIndex++];
|
Matrix &a = matrixStack[matrixStackIndex++];
|
||||||
Matrix &b = matrixStack[matrixStackIndex];
|
Matrix &b = matrixStack[matrixStackIndex];
|
||||||
memcpy(b, a, sizeof(Matrix));
|
memcpy(b, a, sizeof(Matrix));
|
||||||
}
|
}
|
||||||
|
|
||||||
void matrixPop() {
|
void matrixPop()
|
||||||
#if defined(_WIN32)
|
{
|
||||||
if (matrixStackIndex <= 0) {
|
ASSERT(matrixStackIndex > 0);
|
||||||
DebugBreak();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
matrixStackIndex--;
|
matrixStackIndex--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void matrixTranslate(const vec3i &offset) {
|
void matrixTranslate(int32 x, int32 y, int32 z)
|
||||||
|
{
|
||||||
Matrix &m = matrixGet();
|
Matrix &m = matrixGet();
|
||||||
|
|
||||||
m[0].w += DP33(m[0], offset);
|
vec3i offset(x, y, z);
|
||||||
m[1].w += DP33(m[1], offset);
|
m[0][3] += DP33(m[0], offset);
|
||||||
m[2].w += DP33(m[2], 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;
|
vec3i d;
|
||||||
d.x = offset.x - viewPos.x;
|
d.x = x - viewPos.x;
|
||||||
d.y = offset.y - viewPos.y;
|
d.y = y - viewPos.y;
|
||||||
d.z = offset.z - viewPos.z;
|
d.z = z - viewPos.z;
|
||||||
|
|
||||||
Matrix &m = matrixGet();
|
Matrix &m = matrixGet();
|
||||||
m[0].w = DP33(m[0], d);
|
m[0][3] = DP33(m[0], d);
|
||||||
m[1].w = DP33(m[1], d);
|
m[1][3] = DP33(m[1], d);
|
||||||
m[2].w = DP33(m[2], 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) {
|
Matrix &m = matrixGet();
|
||||||
int32 sx = phd_sin(rotX);
|
int32 a, b;
|
||||||
int32 cx = phd_cos(rotX);
|
|
||||||
int32 sy = phd_sin(rotY);
|
a = c * m[0][1] + s * m[0][2];
|
||||||
int32 cy = phd_cos(rotY);
|
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();
|
Matrix &m = matrixGet();
|
||||||
|
|
||||||
m[0].x = cy;
|
m[0][0] = cy;
|
||||||
m[0].y = 0;
|
m[0][1] = 0;
|
||||||
m[0].z = -sy;
|
m[0][2] = -sy;
|
||||||
m[0].w = pos.x;
|
m[0][3] = x;
|
||||||
|
|
||||||
m[1].x = (sx * sy) >> FIXED_SHIFT;
|
m[1][0] = (sx * sy) >> FIXED_SHIFT;
|
||||||
m[1].y = cx;
|
m[1][1] = cx;
|
||||||
m[1].z = (sx * cy) >> FIXED_SHIFT;
|
m[1][2] = (sx * cy) >> FIXED_SHIFT;
|
||||||
m[1].w = pos.y;
|
m[1][3] = y;
|
||||||
|
|
||||||
m[2].x = (cx * sy) >> FIXED_SHIFT;
|
m[2][0] = (cx * sy) >> FIXED_SHIFT;
|
||||||
m[2].y = -sx;
|
m[2][1] = -sx;
|
||||||
m[2].z = (cx * cy) >> FIXED_SHIFT;
|
m[2][2] = (cx * cy) >> FIXED_SHIFT;
|
||||||
m[2].w = pos.z;
|
m[2][3] = z;
|
||||||
|
|
||||||
viewPos = pos;
|
viewPos.x = x;
|
||||||
|
viewPos.y = y;
|
||||||
|
viewPos.z = z;
|
||||||
}
|
}
|
@@ -22,47 +22,25 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <assert.h>
|
#include <limits.h>
|
||||||
|
|
||||||
//#define DEBUG_OVERDRAW
|
//#define DEBUG_OVERDRAW
|
||||||
//#define DEBUG_FACES
|
//#define DEBUG_FACES
|
||||||
|
|
||||||
//#define USE_MODE_5 1
|
|
||||||
#define USE_MODE_4 1
|
|
||||||
|
|
||||||
#define SCALE 1
|
|
||||||
|
|
||||||
#if defined(__TNS__)
|
#if defined(__TNS__)
|
||||||
#define WIDTH SCREEN_WIDTH
|
#define WIDTH SCREEN_WIDTH
|
||||||
#define HEIGHT SCREEN_HEIGHT
|
#define HEIGHT SCREEN_HEIGHT
|
||||||
#define FRAME_WIDTH (WIDTH/SCALE)
|
#define FRAME_WIDTH WIDTH
|
||||||
#define FRAME_HEIGHT (HEIGHT/SCALE)
|
#define FRAME_HEIGHT HEIGHT
|
||||||
#define FOV_SHIFT 8
|
#define FOV_SHIFT 8
|
||||||
#else
|
#else
|
||||||
#ifdef USE_MODE_5
|
#define WIDTH 160
|
||||||
#define WIDTH 160
|
#define HEIGHT 128
|
||||||
#define HEIGHT 128
|
#define FRAME_WIDTH 160
|
||||||
#define FRAME_WIDTH 160
|
#define FRAME_HEIGHT 128
|
||||||
#define FRAME_HEIGHT 128
|
#define FOV_SHIFT 7
|
||||||
#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
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
@@ -116,6 +94,12 @@ typedef int16 Index;
|
|||||||
#define ALIGN4 __attribute__((aligned(4)))
|
#define ALIGN4 __attribute__((aligned(4)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#define ASSERT(x) { if (!(x)) { DebugBreak(); } }
|
||||||
|
#else
|
||||||
|
#define ASSERT(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef PROFILE
|
#ifdef PROFILE
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
|
||||||
@@ -189,6 +173,11 @@ struct vec3s {
|
|||||||
|
|
||||||
struct vec4i {
|
struct vec4i {
|
||||||
int32 x, y, z, w;
|
int32 x, y, z, w;
|
||||||
|
|
||||||
|
INLINE int32& operator [] (int32 index) const {
|
||||||
|
ASSERT(index >= 0 && index <= 3);
|
||||||
|
return ((int32*)this)[index];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef vec4i Matrix[3];
|
typedef vec4i Matrix[3];
|
||||||
@@ -203,12 +192,16 @@ struct Triangle {
|
|||||||
uint16 flags;
|
uint16 flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Room {
|
struct Box {
|
||||||
struct Info {
|
int16 minX;
|
||||||
int32 x, z;
|
int16 maxX;
|
||||||
int32 yBottom, yTop;
|
int16 minY;
|
||||||
};
|
int16 maxY;
|
||||||
|
int16 minZ;
|
||||||
|
int16 maxZ;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RoomInfo {
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
vec3s pos;
|
vec3s pos;
|
||||||
uint16 lighting;
|
uint16 lighting;
|
||||||
@@ -242,14 +235,17 @@ struct Room {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Mesh {
|
struct Mesh {
|
||||||
// int32 x, y, z;
|
int16 pos[6]; // TODO align struct (int32 x, y, z)
|
||||||
// uint16 rotation;
|
int16 rotation;
|
||||||
// uint16 intensity;
|
uint16 intensity;
|
||||||
// uint16 meshID;
|
uint16 staticMeshId;
|
||||||
uint8 dummy[18];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Info info;
|
int32 x;
|
||||||
|
int32 z;
|
||||||
|
int32 yBottom;
|
||||||
|
int32 yTop;
|
||||||
|
|
||||||
uint32 dataSize;
|
uint32 dataSize;
|
||||||
/*
|
/*
|
||||||
uint16 vCount;
|
uint16 vCount;
|
||||||
@@ -275,39 +271,89 @@ struct Model {
|
|||||||
uint32 type;
|
uint32 type;
|
||||||
uint16 mCount;
|
uint16 mCount;
|
||||||
uint16 mStart;
|
uint16 mStart;
|
||||||
uint32 node;
|
uint32 nodeIndex;
|
||||||
uint32 frame;
|
uint32 frameIndex;
|
||||||
uint16 animation;
|
uint16 animIndex;
|
||||||
uint16 paddding;
|
uint16 _padding;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FILE_MODEL_SIZE (sizeof(Model) - 2) // -padding
|
#define FILE_MODEL_SIZE (sizeof(Model) - 2) // -padding
|
||||||
|
|
||||||
struct Entity {
|
struct StaticMesh {
|
||||||
uint16 type;
|
int32 id;
|
||||||
uint16 room;
|
uint16 meshIndex;
|
||||||
vec3i pos;
|
Box vbox;
|
||||||
int16 rotation;
|
Box cbox;
|
||||||
uint16 flags;
|
uint16 flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EntityDesc { // 32 bytes
|
struct ItemInfo { // 24
|
||||||
uint16 type;
|
uint16 type;
|
||||||
uint16 flags;
|
int16 room;
|
||||||
|
|
||||||
vec3i pos;
|
vec3i pos;
|
||||||
|
int16 angleY;
|
||||||
|
uint16 intensity;
|
||||||
|
|
||||||
vec3s rot;
|
union {
|
||||||
uint8 state;
|
struct {
|
||||||
uint8 targetState;
|
uint16 gravity:1; // TODO
|
||||||
|
};
|
||||||
|
uint16 value;
|
||||||
|
} flags;
|
||||||
|
|
||||||
uint8 vSpeed;
|
uint16 _padding;
|
||||||
uint8 hSpeed;
|
};
|
||||||
uint8 room;
|
|
||||||
uint8 modelIndex;
|
#define FILE_ITEM_SIZE (sizeof(ItemInfo) - 2)
|
||||||
|
|
||||||
|
struct Item : ItemInfo { // 24 + 20 = 44
|
||||||
|
int16 angleX;
|
||||||
|
int16 angleZ;
|
||||||
|
|
||||||
|
uint16 vSpeed;
|
||||||
|
uint16 hSpeed;
|
||||||
|
|
||||||
uint16 animIndex;
|
uint16 animIndex;
|
||||||
uint16 frameIndex;
|
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 {
|
struct Texture {
|
||||||
@@ -352,7 +398,7 @@ union UV {
|
|||||||
|
|
||||||
struct VertexUV {
|
struct VertexUV {
|
||||||
Vertex v;
|
Vertex v;
|
||||||
UV t;
|
UV t;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Face {
|
struct Face {
|
||||||
@@ -371,12 +417,19 @@ struct Face {
|
|||||||
extern uint32 dbg_poly_count;
|
extern uint32 dbg_poly_count;
|
||||||
#endif
|
#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 FIXED_SHIFT 14
|
||||||
|
|
||||||
#define MAX_MATRICES 8
|
#define MAX_MATRICES 8
|
||||||
#define MAX_MODELS 64
|
#define MAX_MODELS 64
|
||||||
#define MAX_ENTITY 190
|
#define MAX_ITEMS 256
|
||||||
#define MAX_VERTICES 1024
|
#define MAX_MESHES 50
|
||||||
|
#define MAX_VERTICES 2048
|
||||||
#define MAX_FACES 512
|
#define MAX_FACES 512
|
||||||
#define FOG_SHIFT 1
|
#define FOG_SHIFT 1
|
||||||
#define FOG_MAX (10 * 1024)
|
#define FOG_MAX (10 * 1024)
|
||||||
@@ -390,6 +443,10 @@ struct Face {
|
|||||||
#define FACE_FLAT 0x1000
|
#define FACE_FLAT 0x1000
|
||||||
#define FACE_TEXTURE 0x0FFF
|
#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 MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||||
#define SQR(x) ((x) * (x))
|
#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 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 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 clamp(int32 x, int32 a, int32 b);
|
||||||
int32 phd_sin(int32 x);
|
int32 phd_sin(int32 x);
|
||||||
int32 phd_cos(int32 x);
|
int32 phd_cos(int32 x);
|
||||||
|
|
||||||
|
void initLUT();
|
||||||
|
|
||||||
Matrix& matrixGet();
|
Matrix& matrixGet();
|
||||||
void matrixPush();
|
void matrixPush();
|
||||||
void matrixPop();
|
void matrixPop();
|
||||||
void matrixTranslate(const vec3i &offset);
|
void matrixTranslate(int32 x, int32 y, int32 z);
|
||||||
void matrixTranslateAbs(const vec3i &offset);
|
void matrixTranslateAbs(int32 x, int32 y, int32 z);
|
||||||
void matrixRotate(int16 rotX, int16 rotY, int16 rotZ);
|
void matrixRotateX(int32 angle);
|
||||||
void matrixSetView(const vec3i &pos, int16 rotX, int16 rotY);
|
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 drawGlyph(const Sprite *sprite, int32 x, int32 y);
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
void transform_room(const Room::Vertex* vertices, int32 vCount);
|
bool boxIsVisible(const Box* box);
|
||||||
void transform_mesh(const vec3s* vertices, int32 vCount);
|
void transformRoom(const RoomInfo::Vertex* vertices, int32 vCount);
|
||||||
void faceAdd_room(const Quad* quads, int32 qCount, const Triangle* triangles, int32 tCount, int32 startVertex);
|
void transformMesh(const vec3s* vertices, int32 vCount, uint16 intensity);
|
||||||
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 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 flush();
|
||||||
void initRender();
|
|
||||||
|
|
||||||
void readLevel(const uint8 *data);
|
void readLevel(const uint8 *data);
|
||||||
const Room::Sector* getSector(int32 roomIndex, int32 x, int32 z);
|
const RoomInfo::Sector* getSector(int32 roomIndex, int32 x, int32 z);
|
||||||
int32 getRoomIndex(int32 roomIndex, const vec3i &pos);
|
int32 getRoomIndex(int32 roomIndex, const vec3i* pos);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -4,72 +4,82 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
|
|
||||||
|
#define GRAVITY 6
|
||||||
|
|
||||||
// level file data -------------------
|
// level file data -------------------
|
||||||
uint32 tilesCount;
|
int32 tilesCount;
|
||||||
extern const uint8* tiles;
|
extern const uint8* tiles;
|
||||||
|
|
||||||
#if defined(USE_MODE_5) || defined(_WIN32)
|
extern uint16 palette[256];
|
||||||
extern uint16 palette[256];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint8 lightmap[256 * 32];
|
extern uint8 lightmap[256 * 32];
|
||||||
|
|
||||||
uint16 roomsCount;
|
|
||||||
|
|
||||||
const uint16* floors;
|
const uint16* floors;
|
||||||
|
|
||||||
uint32 texturesCount;
|
int32 texturesCount;
|
||||||
extern const Texture* textures;
|
extern const Texture* textures;
|
||||||
|
|
||||||
const Sprite* sprites;
|
const Sprite* sprites;
|
||||||
|
|
||||||
uint32 spritesSeqCount;
|
int32 spritesSeqCount;
|
||||||
const SpriteSeq* spritesSeq;
|
const SpriteSeq* spritesSeq;
|
||||||
|
|
||||||
const uint8* meshData;
|
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 Model models[MAX_MODELS];
|
||||||
EWRAM_DATA int16 modelsMap[MAX_ENTITY];
|
EWRAM_DATA uint8 modelsMap[MAX_ITEMS];
|
||||||
|
EWRAM_DATA uint8 staticMeshesMap[MAX_MESHES];
|
||||||
|
|
||||||
uint32 entitiesCount;
|
int32 staticMeshesCount;
|
||||||
const Entity* entities;
|
const StaticMesh* staticMeshes;
|
||||||
|
|
||||||
|
int32 itemsCount;
|
||||||
|
EWRAM_DATA Item items[MAX_ITEMS];
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
|
|
||||||
struct RoomDesc {
|
struct Room {
|
||||||
Rect clip;
|
Rect clip;
|
||||||
|
uint8 firstItem;
|
||||||
bool visible;
|
bool visible;
|
||||||
|
|
||||||
|
// TODO leave in ROM
|
||||||
int32 x, z;
|
int32 x, z;
|
||||||
uint16 vCount;
|
uint16 vCount;
|
||||||
uint16 qCount;
|
uint16 qCount;
|
||||||
uint16 tCount;
|
uint16 tCount;
|
||||||
uint16 pCount;
|
uint16 pCount;
|
||||||
|
uint16 lCount;
|
||||||
|
uint16 mCount;
|
||||||
uint16 zSectors;
|
uint16 zSectors;
|
||||||
uint16 xSectors;
|
uint16 xSectors;
|
||||||
const Room::Vertex* vertices;
|
uint16 ambient;
|
||||||
const Quad* quads;
|
|
||||||
const Triangle* triangles;
|
|
||||||
const Room::Portal* portals;
|
|
||||||
const Room::Sector* sectors;
|
|
||||||
|
|
||||||
INLINE void reset() {
|
const RoomInfo::Vertex* vertices;
|
||||||
visible = false;
|
const Quad* quads;
|
||||||
clip = { FRAME_WIDTH, FRAME_HEIGHT, 0, 0 };
|
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 visRoomsCount;
|
||||||
int32 visRooms[16];
|
int32 visRooms[16];
|
||||||
|
|
||||||
#define ROOM_VISIBLE (1 << 15)
|
#define ROOM_VISIBLE (1 << 15)
|
||||||
|
|
||||||
#define ENTITY_LARA 0
|
|
||||||
|
|
||||||
#define SEQ_GLYPH 190
|
#define SEQ_GLYPH 190
|
||||||
|
|
||||||
enum FloorType {
|
enum FloorType {
|
||||||
@@ -80,51 +90,145 @@ enum FloorType {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int32 seqGlyphs;
|
int32 seqGlyphs;
|
||||||
int32 entityLara;
|
|
||||||
|
|
||||||
extern uint32 gVerticesCount;
|
extern uint32 gVerticesCount;
|
||||||
extern Rect clip;
|
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
|
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;
|
tiles = data + 8;
|
||||||
|
|
||||||
#define MDL_OFF 2
|
#define MDL_OFF 2
|
||||||
#define ENT_OFF 2
|
#define ITM_OFF 2
|
||||||
|
|
||||||
roomsCount = *((uint16*)(data + 720908));
|
roomsCount = *((int16*)(data + 720908));
|
||||||
const Room* roomsPtr = (Room*)(data + 720908 + 2);
|
const RoomInfo* roomsPtr = (RoomInfo*)(data + 720908 + 2);
|
||||||
|
|
||||||
floors = (uint16*)(data + 899492 + 4);
|
floors = (uint16*)(data + 899492 + 4);
|
||||||
|
|
||||||
meshData = data + 908172 + 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);
|
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);
|
textures = (Texture*)(data + 1271686 + 4 + MDL_OFF);
|
||||||
|
|
||||||
sprites = (Sprite*)(data + 1289634 + 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);
|
spritesSeq = (SpriteSeq*)(data + 1292130 + 4 + MDL_OFF);
|
||||||
|
|
||||||
entitiesCount = *((uint32*)(data + 1319252 + MDL_OFF + ENT_OFF));
|
itemsCount = *((int32*)(data + 1319252 + MDL_OFF + ITM_OFF));
|
||||||
entities = (Entity*)(data + 1319252 + 4 + MDL_OFF + ENT_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
|
// 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));
|
memcpy(lightmap, f_lightmap, sizeof(lightmap));
|
||||||
|
|
||||||
// prepare palette
|
// prepare palette
|
||||||
#if !(defined(USE_MODE_5) || defined(_WIN32))
|
const uint8* f_palette = data + 1328768 + MDL_OFF + ITM_OFF;
|
||||||
uint16 palette[256];
|
|
||||||
#endif
|
|
||||||
const uint8* f_palette = data + 1328768 + MDL_OFF + ENT_OFF;
|
|
||||||
|
|
||||||
const uint8* p = f_palette;
|
const uint8* p = f_palette;
|
||||||
|
|
||||||
@@ -137,59 +241,33 @@ void readLevel(const uint8 *data) { // TODO non-hardcode level loader, added *_O
|
|||||||
#endif
|
#endif
|
||||||
p += 3;
|
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
|
// prepare rooms
|
||||||
uint8 *ptr = (uint8*)roomsPtr;
|
uint8 *ptr = (uint8*)roomsPtr;
|
||||||
|
|
||||||
for (uint16 roomIndex = 0; roomIndex < roomsCount; roomIndex++) {
|
for (int32 roomIndex = 0; roomIndex < roomsCount; roomIndex++)
|
||||||
const Room *room = (Room*)ptr;
|
{
|
||||||
ptr += sizeof(Room);
|
const RoomInfo *room = (RoomInfo*)ptr;
|
||||||
|
ptr += sizeof(RoomInfo);
|
||||||
|
|
||||||
uint32 dataSize;
|
uint32 dataSize;
|
||||||
memcpy(&dataSize, &room->dataSize, sizeof(dataSize));
|
memcpy(&dataSize, &room->dataSize, sizeof(dataSize));
|
||||||
uint8* skipPtr = ptr + dataSize * 2;
|
uint8* skipPtr = ptr + dataSize * 2;
|
||||||
|
|
||||||
RoomDesc &desc = rooms[roomIndex];
|
Room &desc = rooms[roomIndex];
|
||||||
desc.reset();
|
roomReset(roomIndex);
|
||||||
|
|
||||||
|
desc.firstItem = NO_ITEM;
|
||||||
|
|
||||||
// offset
|
// offset
|
||||||
memcpy(&desc.x, &room->info.x, sizeof(room->info.x));
|
memcpy(&desc.x, &room->x, sizeof(room->x));
|
||||||
memcpy(&desc.z, &room->info.z, sizeof(room->info.z));
|
memcpy(&desc.z, &room->z, sizeof(room->z));
|
||||||
|
|
||||||
// vertices
|
// vertices
|
||||||
desc.vCount = *((uint16*)ptr);
|
desc.vCount = *((uint16*)ptr);
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
desc.vertices = (Room::Vertex*)ptr;
|
desc.vertices = (RoomInfo::Vertex*)ptr;
|
||||||
ptr += sizeof(Room::Vertex) * desc.vCount;
|
ptr += sizeof(RoomInfo::Vertex) * desc.vCount;
|
||||||
|
|
||||||
// quads
|
// quads
|
||||||
desc.qCount = *((uint16*)ptr);
|
desc.qCount = *((uint16*)ptr);
|
||||||
@@ -208,38 +286,99 @@ void readLevel(const uint8 *data) { // TODO non-hardcode level loader, added *_O
|
|||||||
// portals
|
// portals
|
||||||
desc.pCount = *((uint16*)ptr);
|
desc.pCount = *((uint16*)ptr);
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
desc.portals = (Room::Portal*)ptr;
|
desc.portals = (RoomInfo::Portal*)ptr;
|
||||||
ptr += sizeof(Room::Portal) * desc.pCount;
|
ptr += sizeof(RoomInfo::Portal) * desc.pCount;
|
||||||
|
|
||||||
desc.zSectors = *((uint16*)ptr);
|
desc.zSectors = *((uint16*)ptr);
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
desc.xSectors = *((uint16*)ptr);
|
desc.xSectors = *((uint16*)ptr);
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
desc.sectors = (Room::Sector*)ptr;
|
desc.sectors = (RoomInfo::Sector*)ptr;
|
||||||
ptr += sizeof(Room::Sector) * desc.zSectors * desc.xSectors;
|
ptr += sizeof(RoomInfo::Sector) * desc.zSectors * desc.xSectors;
|
||||||
|
|
||||||
//ambient = *((uint16*)ptr);
|
desc.ambient = *((uint16*)ptr);
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
|
|
||||||
uint16 lightsCount = *((uint16*)ptr);
|
desc.lCount = *((uint16*)ptr);
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
//lights = (Room::Light*)ptr;
|
desc.lights = (RoomInfo::Light*)ptr;
|
||||||
ptr += sizeof(Room::Light) * lightsCount;
|
ptr += sizeof(RoomInfo::Light) * desc.lCount;
|
||||||
|
|
||||||
uint16 meshesCount = *((uint16*)ptr);
|
desc.mCount = *((uint16*)ptr);
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
//meshes = (Room::Mesh*)ptr;
|
desc.meshes = (RoomInfo::Mesh*)ptr;
|
||||||
ptr += sizeof(Room::Mesh) * meshesCount;
|
ptr += sizeof(RoomInfo::Mesh) * desc.mCount;
|
||||||
|
|
||||||
ptr += 2 + 2; // skip alternateRoom and flags
|
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.init();
|
||||||
camera.room = entities[entityLara].room;
|
camera.room = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawMesh(int16 meshIndex) {
|
void drawMesh(int16 meshIndex, uint16 intensity) {
|
||||||
uint32 offset = meshOffsets[meshIndex];
|
int32 offset = meshOffsets[meshIndex];
|
||||||
const uint8* ptr = meshData + offset;
|
const uint8* ptr = meshData + offset;
|
||||||
|
|
||||||
ptr += 2 * 5; // skip [cx, cy, cz, radius, flags]
|
ptr += 2 * 5; // skip [cx, cy, cz, radius, flags]
|
||||||
@@ -271,52 +410,67 @@ void drawMesh(int16 meshIndex) {
|
|||||||
int32 startVertex = gVerticesCount;
|
int32 startVertex = gVerticesCount;
|
||||||
|
|
||||||
PROFILE_START();
|
PROFILE_START();
|
||||||
transform_mesh(vertices, vCount);
|
transformMesh(vertices, vCount, intensity);
|
||||||
PROFILE_STOP(dbg_transform);
|
PROFILE_STOP(dbg_transform);
|
||||||
|
|
||||||
PROFILE_START();
|
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);
|
PROFILE_STOP(dbg_poly);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawModel(int32 modelIndex) {
|
Frame* getFrame(const Item* item, const Model* model)
|
||||||
const Model* model = models + modelIndex;
|
{
|
||||||
|
const Anim* anim = anims + item->animIndex;
|
||||||
|
|
||||||
// non-aligned access
|
int32 frameSize = sizeof(Frame) / 2 + model->mCount * 2;
|
||||||
uint32 node, frame;
|
int32 frameIndex = (item->frameIndex - anim->frameBegin) / anim->frameRate;//* FixedInvU(anim->frameRate) >> 16;
|
||||||
memcpy(&node, &model->node, sizeof(node));
|
|
||||||
memcpy(&frame, &model->frame, sizeof(frame));
|
|
||||||
|
|
||||||
Node bones[32];
|
return (Frame*)(frames + anim->frameOffset / 2 + frameIndex * frameSize);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawEntity(int32 entityIndex) {
|
void drawItem(const Item* item) {
|
||||||
const Entity &e = entities[entityIndex];
|
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();
|
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();
|
matrixPop();
|
||||||
}
|
}
|
||||||
@@ -333,39 +487,62 @@ void drawNumber(int32 number, int32 x, int32 y) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern vec3i viewPos;
|
void drawRoom(int32 roomIndex) {
|
||||||
extern Vertex gVertices[MAX_VERTICES];
|
const Room* room = rooms + roomIndex;
|
||||||
|
|
||||||
void drawRoom(int16 roomIndex) {
|
clip = room->clip;
|
||||||
RoomDesc &room = rooms[roomIndex];
|
|
||||||
|
|
||||||
clip = room.clip;
|
|
||||||
|
|
||||||
int32 startVertex = gVerticesCount;
|
int32 startVertex = gVerticesCount;
|
||||||
|
|
||||||
matrixPush();
|
matrixPush();
|
||||||
matrixTranslateAbs(vec3i(room.x, 0, room.z));
|
matrixTranslateAbs(room->x, 0, room->z);
|
||||||
|
|
||||||
PROFILE_START();
|
PROFILE_START();
|
||||||
transform_room(room.vertices, room.vCount);
|
transformRoom(room->vertices, room->vCount);
|
||||||
PROFILE_STOP(dbg_transform);
|
PROFILE_STOP(dbg_transform);
|
||||||
|
|
||||||
matrixPop();
|
matrixPop();
|
||||||
|
|
||||||
PROFILE_START();
|
PROFILE_START();
|
||||||
faceAdd_room(room.quads, room.qCount, room.triangles, room.tCount, startVertex);
|
faceAddRoom(room->quads, room->qCount, room->triangles, room->tCount, startVertex);
|
||||||
if (roomIndex == entityLara) { // TODO draw all entities in the room
|
|
||||||
drawEntity(entityLara);
|
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);
|
PROFILE_STOP(dbg_poly);
|
||||||
|
|
||||||
room.reset();
|
roomReset(roomIndex);
|
||||||
|
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Room::Sector* getSector(int32 roomIndex, int32 x, int32 z) {
|
const RoomInfo::Sector* getSector(int32 roomIndex, int32 x, int32 z) {
|
||||||
RoomDesc &room = rooms[roomIndex];
|
Room &room = rooms[roomIndex];
|
||||||
|
|
||||||
int32 sx = clamp((x - room.x) >> 10, 0, room.xSectors - 1);
|
int32 sx = clamp((x - room.x) >> 10, 0, room.xSectors - 1);
|
||||||
int32 sz = clamp((z - room.z) >> 10, 0, room.zSectors - 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;
|
return room.sectors + sx * room.zSectors + sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 getRoomIndex(int32 roomIndex, const vec3i &pos) {
|
int32 getRoomIndex(int32 roomIndex, const vec3i* pos) {
|
||||||
const Room::Sector *sector = getSector(roomIndex, pos.x, pos.z);
|
const RoomInfo::Sector *sector = getSector(roomIndex, pos->x, pos->z);
|
||||||
|
|
||||||
if (sector->floorIndex) {
|
if (sector->floorIndex) {
|
||||||
const uint16 *data = floors + 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;
|
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;
|
roomIndex = sector->roomBelow;
|
||||||
sector = getSector(roomIndex, pos.x, pos.z);
|
sector = getSector(roomIndex, pos->x, pos->z);
|
||||||
}
|
}
|
||||||
|
|
||||||
return roomIndex;
|
return roomIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkPortal(int32 roomIndex, const Room::Portal &portal) {
|
bool checkPortal(int32 roomIndex, const RoomInfo::Portal* portal) {
|
||||||
RoomDesc &room = rooms[roomIndex];
|
Room &room = rooms[roomIndex];
|
||||||
|
|
||||||
vec3i d;
|
vec3i d;
|
||||||
d.x = portal.v[0].x - camera.pos.x + room.x;
|
d.x = portal->v[0].x - camera.pos.x + room.x;
|
||||||
d.y = portal.v[0].y - camera.pos.y;
|
d.y = portal->v[0].y - camera.pos.y;
|
||||||
d.z = portal.v[0].z - camera.pos.z + room.z;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,7 +609,7 @@ bool checkPortal(int32 roomIndex, const Room::Portal &portal) {
|
|||||||
vec3i pv[4];
|
vec3i pv[4];
|
||||||
|
|
||||||
for (int32 i = 0; i < 4; i++) {
|
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 x = DP43(m[0], v);
|
||||||
int32 y = DP43(m[1], 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;
|
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 (x0 < nextRoom.clip.x0) nextRoom.clip.x0 = x0;
|
||||||
if (x1 > nextRoom.clip.x1) nextRoom.clip.x1 = x1;
|
if (x1 > nextRoom.clip.x1) nextRoom.clip.x1 = x1;
|
||||||
@@ -512,38 +689,123 @@ bool checkPortal(int32 roomIndex, const Room::Portal &portal) {
|
|||||||
|
|
||||||
if (!nextRoom.visible) {
|
if (!nextRoom.visible) {
|
||||||
nextRoom.visible = true;
|
nextRoom.visible = true;
|
||||||
visRooms[visRoomsCount++] = portal.roomIndex;
|
visRooms[visRoomsCount++] = portal->roomIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getVisibleRooms(int32 roomIndex) {
|
void getVisibleRooms(int32 roomIndex)
|
||||||
RoomDesc &room = rooms[roomIndex];
|
{
|
||||||
|
const Room* room = rooms + roomIndex;
|
||||||
|
|
||||||
matrixPush();
|
matrixPush();
|
||||||
matrixTranslateAbs(vec3i(room.x, 0, room.z));
|
matrixTranslateAbs(room->x, 0, room->z);
|
||||||
|
|
||||||
for (int32 i = 0; i < room.pCount; i++) {
|
for (int32 i = 0; i < room->pCount; i++)
|
||||||
const Room::Portal &portal = room.portals[i];
|
{
|
||||||
if (checkPortal(roomIndex, portal)) {
|
const RoomInfo::Portal* portal = room->portals + i;
|
||||||
getVisibleRooms(portal.roomIndex);
|
|
||||||
|
if (checkPortal(roomIndex, portal))
|
||||||
|
{
|
||||||
|
getVisibleRooms(portal->roomIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
matrixPop();
|
matrixPop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawRooms() {
|
void drawRooms()
|
||||||
|
{
|
||||||
rooms[camera.room].clip = { 0, 0, FRAME_WIDTH, FRAME_HEIGHT };
|
rooms[camera.room].clip = { 0, 0, FRAME_WIDTH, FRAME_HEIGHT };
|
||||||
visRoomsCount = 0;
|
visRoomsCount = 0;
|
||||||
visRooms[visRoomsCount++] = camera.room;
|
visRooms[visRoomsCount++] = camera.room;
|
||||||
|
|
||||||
getVisibleRooms(camera.room);
|
getVisibleRooms(camera.room);
|
||||||
|
|
||||||
while (visRoomsCount--) {
|
while (visRoomsCount--)
|
||||||
|
{
|
||||||
drawRoom(visRooms[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
|
#endif
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
uint32 SCREEN[WIDTH * HEIGHT];
|
uint32 SCREEN[WIDTH * HEIGHT];
|
||||||
|
|
||||||
extern uint8 fb[WIDTH * HEIGHT * 2];
|
extern uint16 fb[WIDTH * HEIGHT];
|
||||||
|
|
||||||
LARGE_INTEGER g_timer;
|
LARGE_INTEGER g_timer;
|
||||||
LARGE_INTEGER g_current;
|
LARGE_INTEGER g_current;
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
#elif defined(__TNS__)
|
#elif defined(__TNS__)
|
||||||
uint8* LEVEL1_PHD;
|
uint8* LEVEL1_PHD;
|
||||||
|
|
||||||
extern uint8 fb[WIDTH * HEIGHT];
|
extern uint16 fb[WIDTH * HEIGHT];
|
||||||
|
|
||||||
unsigned int osTime;
|
unsigned int osTime;
|
||||||
volatile unsigned int *timerBUS;
|
volatile unsigned int *timerBUS;
|
||||||
@@ -95,6 +95,7 @@ int32 fpsCounter = 0;
|
|||||||
|
|
||||||
void update(int32 frames) {
|
void update(int32 frames) {
|
||||||
for (int32 i = 0; i < frames; i++) {
|
for (int32 i = 0; i < frames; i++) {
|
||||||
|
updateItems();
|
||||||
camera.update();
|
camera.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -212,9 +213,8 @@ void render() {
|
|||||||
drawNumber(dbg_poly, FRAME_WIDTH, 48);
|
drawNumber(dbg_poly, FRAME_WIDTH, 48);
|
||||||
drawNumber(dbg_sort, FRAME_WIDTH, 64);
|
drawNumber(dbg_sort, FRAME_WIDTH, 64);
|
||||||
drawNumber(dbg_flush, FRAME_WIDTH, 80);
|
drawNumber(dbg_flush, FRAME_WIDTH, 80);
|
||||||
drawNumber(dbg_transform + dbg_poly + dbg_sort + dbg_flush, FRAME_WIDTH, 96);
|
drawNumber(dbg_vert_count, FRAME_WIDTH, 96);
|
||||||
drawNumber(dbg_vert_count, FRAME_WIDTH, 120);
|
drawNumber(dbg_poly_count, FRAME_WIDTH, 112);
|
||||||
drawNumber(dbg_poly_count, FRAME_WIDTH, 136);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -226,22 +226,10 @@ void render() {
|
|||||||
HDC hDC;
|
HDC hDC;
|
||||||
|
|
||||||
void blit() {
|
void blit() {
|
||||||
#ifdef USE_MODE_5
|
for (int i = 0; i < WIDTH * HEIGHT; i++) {
|
||||||
for (int i = 0; i < WIDTH * HEIGHT; i++) {
|
uint16 c = ((uint16*)fb)[i];
|
||||||
uint16 c = ((uint16*)fb)[i];
|
SCREEN[i] = (((c << 3) & 0xFF) << 16) | ((((c >> 5) << 3) & 0xFF) << 8) | ((c >> 10 << 3) & 0xFF) | 0xFF000000;
|
||||||
SCREEN[i] = (((c << 3) & 0xFF) << 16) | ((((c >> 5) << 3) & 0xFF) << 8) | ((c >> 10 << 3) & 0xFF) | 0xFF000000;
|
}
|
||||||
}
|
|
||||||
#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
|
|
||||||
|
|
||||||
const BITMAPINFO bmi = { sizeof(BITMAPINFOHEADER), WIDTH, -HEIGHT, 1, 32, BI_RGB, 0, 0, 0, 0, 0 };
|
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);
|
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__)
|
#elif defined(__GBA__)
|
||||||
// set low latency mode via WAITCNT register (thanks to GValiente)
|
// 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)
|
||||||
#define REG_WAITCNT_NV *(u16*)(REG_BASE + 0x0204)
|
REG_WAITCNT_NV |= (0x0008 | 0x0010 | 0x4000);
|
||||||
|
|
||||||
BIT_SET(REG_WAITCNT_NV, 0x0008 | 0x0010 | 0x4000);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
initRender();
|
initLUT();
|
||||||
|
|
||||||
readLevel(LEVEL1_PHD);
|
readLevel(LEVEL1_PHD);
|
||||||
|
|
||||||
@@ -330,8 +316,8 @@ int main(void) {
|
|||||||
|
|
||||||
MSG msg;
|
MSG msg;
|
||||||
|
|
||||||
int startTime = GetTickCount();
|
int startTime = GetTickCount() - 33;
|
||||||
int lastTime = -16;
|
int lastFrame = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
|
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
|
||||||
@@ -339,9 +325,9 @@ int main(void) {
|
|||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
int time = GetTickCount() - startTime;
|
int frame = (GetTickCount() - startTime) / 33;
|
||||||
update((time - lastTime) / 16);
|
update(frame - lastFrame);
|
||||||
lastTime = time;
|
lastFrame = frame;
|
||||||
|
|
||||||
render();
|
render();
|
||||||
|
|
||||||
@@ -356,17 +342,10 @@ int main(void) {
|
|||||||
|
|
||||||
uint16 mode = BG2_ON | BACKBUFFER;
|
uint16 mode = BG2_ON | BACKBUFFER;
|
||||||
|
|
||||||
#ifdef USE_MODE_5
|
mode |= MODE_5;
|
||||||
mode |= MODE_5;
|
|
||||||
|
|
||||||
REG_BG2PA = 256 - 64 - 16 - 4 - 1;
|
REG_BG2PA = 256 - 64 - 16 - 4 - 1;
|
||||||
REG_BG2PD = 256 - 48 - 2;
|
REG_BG2PD = 256 - 48 - 2;
|
||||||
#else
|
|
||||||
mode |= MODE_4;
|
|
||||||
|
|
||||||
REG_BG2PA = 256 / SCALE;
|
|
||||||
REG_BG2PD = 256 / SCALE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int32 lastFrameIndex = -1;
|
int32 lastFrameIndex = -1;
|
||||||
|
|
||||||
@@ -387,7 +366,7 @@ int main(void) {
|
|||||||
keys[IK_L] = (key & KEY_L);
|
keys[IK_L] = (key & KEY_L);
|
||||||
keys[IK_R] = (key & KEY_R);
|
keys[IK_R] = (key & KEY_R);
|
||||||
|
|
||||||
int32 frame = frameIndex;
|
int32 frame = frameIndex / 2;
|
||||||
update(frame - lastFrameIndex);
|
update(frame - lastFrameIndex);
|
||||||
lastFrameIndex = frame;
|
lastFrameIndex = frame;
|
||||||
|
|
||||||
@@ -396,7 +375,7 @@ int main(void) {
|
|||||||
fpsCounter++;
|
fpsCounter++;
|
||||||
if (frameIndex >= 60) {
|
if (frameIndex >= 60) {
|
||||||
frameIndex -= 60;
|
frameIndex -= 60;
|
||||||
lastFrameIndex -= 60;
|
lastFrameIndex -= 30;
|
||||||
|
|
||||||
fps = fpsCounter;
|
fps = fpsCounter;
|
||||||
|
|
||||||
|
@@ -1,36 +1,28 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#define DIV_TABLE_SIZE 256
|
|
||||||
|
|
||||||
uint16 divTable[DIV_TABLE_SIZE]; // IWRAM 0.5 kb
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
uint8 fb[WIDTH * HEIGHT * 2];
|
uint16 fb[WIDTH * HEIGHT];
|
||||||
#elif defined(__GBA__)
|
#elif defined(__GBA__)
|
||||||
uint32 fb = VRAM;
|
uint32 fb = VRAM;
|
||||||
#elif defined(__TNS__)
|
#elif defined(__TNS__)
|
||||||
uint8 fb[WIDTH * HEIGHT];
|
uint16 fb[WIDTH * HEIGHT];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FixedInvS(x) ((x < 0) ? -divTable[abs(x)] : divTable[x])
|
#define PAL_COLOR_TRANSP 0x0000
|
||||||
#define FixedInvU(x) divTable[x]
|
#define PAL_COLOR_BLACK 0x0421
|
||||||
|
|
||||||
#if defined(USE_MODE_5) || defined(_WIN32)
|
uint16 palette[256]; // IWRAM 0.5 kb
|
||||||
uint16 palette[256];
|
uint8 lightmap[256 * 32]; // IWRAM 8 kb
|
||||||
#endif
|
const uint8* ft_lightmap;
|
||||||
|
|
||||||
uint8 lightmap[256 * 32]; // IWRAM 8 kb
|
|
||||||
uint8* ft_lightmap;
|
|
||||||
|
|
||||||
const uint8* tiles;
|
|
||||||
const uint8* tile;
|
|
||||||
|
|
||||||
const Texture* textures;
|
const Texture* textures;
|
||||||
|
const uint8* tiles;
|
||||||
|
const uint8* tile;
|
||||||
|
|
||||||
uint32 gVerticesCount = 0;
|
uint32 gVerticesCount = 0;
|
||||||
int32 gFacesCount = 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* gFacesSorted[MAX_FACES]; // EWRAM 2 kb
|
||||||
EWRAM_DATA Face gFaces[MAX_FACES]; // EWRAM 5 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;
|
Rect clip;
|
||||||
|
|
||||||
Matrix matrixStack[MAX_MATRICES];
|
|
||||||
int32 matrixStackIndex = 0;
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
INLINE void swap(T &a, T &b) {
|
INLINE void swap(T &a, T &b) {
|
||||||
T tmp = a;
|
T tmp = a;
|
||||||
@@ -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);
|
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) {
|
INLINE int32 classify(const Vertex* v) {
|
||||||
return (v->x < clip.x0 ? 1 : 0) |
|
return (v->x < clip.x0 ? 1 : 0) |
|
||||||
(v->x > clip.x1 ? 2 : 0) |
|
(v->x > clip.x1 ? 2 : 0) |
|
||||||
@@ -65,14 +48,68 @@ INLINE int32 classify(const Vertex* v) {
|
|||||||
(v->y > clip.y1 ? 8 : 0);
|
(v->y > clip.y1 ? 8 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void transform(const vec3s &v, int32 vg) {
|
bool boxIsVisible(const Box* box)
|
||||||
#if defined(_WIN32)
|
{
|
||||||
if (gVerticesCount >= MAX_VERTICES) {
|
const Matrix &m = matrixGet();
|
||||||
DebugBreak();
|
|
||||||
return;
|
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++];
|
Vertex &res = gVertices[gVerticesCount++];
|
||||||
|
|
||||||
@@ -110,7 +147,7 @@ void transform(const vec3s &v, int32 vg) {
|
|||||||
res.clip = classify(&res);
|
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++)
|
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++) {
|
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_GT_PAL() 32
|
||||||
#define FETCH_G_PAL(palIndex) 32
|
#define FETCH_G_PAL(palIndex) 32
|
||||||
#else
|
#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) {
|
#define FETCH_T() tile[(t & 0xFF00) | (t >> 24)]
|
||||||
uint32 p = FETCH_FT();
|
#define FETCH_G() lightmap[(g & 0x1F00) | palIndex]
|
||||||
t += dtdx;
|
#define FETCH_GT() lightmap[(g & 0x1F00) | FETCH_T()]
|
||||||
p |= FETCH_FT() << 8;
|
#define FETCH_FT() ft_lightmap[FETCH_T()]
|
||||||
t += dtdx;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
INLINE uint32 FETCH_GT2(uint32 &g, uint32 &t, uint32 dgdx, uint32 dtdx) {
|
#define PUT_PIXEL_GT() { uint16 p = palette[FETCH_GT()]; if (p) *pixel = p; }
|
||||||
#if 0
|
#define PUT_PIXEL_FT() { uint16 p = palette[FETCH_FT()]; if (p) *pixel = p; }
|
||||||
uint32 light = g & 0x1F00;
|
#define PUT_PIXEL_G() { *pixel = palette[FETCH_G()]; }
|
||||||
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)]
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct Edge {
|
struct Edge {
|
||||||
@@ -427,426 +439,70 @@ struct Edge {
|
|||||||
};
|
};
|
||||||
|
|
||||||
INLINE void scanlineG(uint16* buffer, int32 x1, int32 x2, uint8 palIndex, uint32 g, uint32 dgdx) {
|
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) {
|
int32 width = x2 - x1;
|
||||||
*pixel++ = FETCH_G_PAL(palIndex);
|
|
||||||
g += dgdx;
|
|
||||||
x1++;
|
|
||||||
|
|
||||||
if (x1 >= x2) {
|
dgdx <<= 1;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 width2 = (x2 - x1) >> 1;
|
while (width--) {
|
||||||
|
PUT_PIXEL_G();
|
||||||
dgdx <<= 1;
|
pixel++;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
|
if (width) {
|
||||||
width--;
|
width--;
|
||||||
|
PUT_PIXEL_G();
|
||||||
|
pixel++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (width-- > 0)
|
g += dgdx;
|
||||||
{
|
}
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE void scanlineGT(uint16* buffer, int32 x1, int32 x2, uint32 g, uint32 t, uint32 dgdx, uint32 dtdx) {
|
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) {
|
int32 width = x2 - x1;
|
||||||
*pixel++ = FETCH_GT_PAL();
|
|
||||||
t += dtdx;
|
|
||||||
g += dgdx;
|
|
||||||
x1++;
|
|
||||||
|
|
||||||
if (x1 >= x2) {
|
dgdx <<= 1;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 width2 = (x2 - x1) >> 1;
|
while (width--) {
|
||||||
|
PUT_PIXEL_GT();
|
||||||
|
pixel++;
|
||||||
|
t += dtdx;
|
||||||
|
|
||||||
dgdx <<= 1;
|
if (width) {
|
||||||
|
|
||||||
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;
|
|
||||||
width--;
|
width--;
|
||||||
}
|
PUT_PIXEL_GT();
|
||||||
|
pixel++;
|
||||||
// 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();
|
|
||||||
t += dtdx;
|
t += dtdx;
|
||||||
g += dgdx;
|
|
||||||
x1++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 width = (x2 - x1) >> 1;
|
g += dgdx;
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE void scanlineFT(uint16* buffer, int32 x1, int32 x2, uint32 t, uint32 dtdx) {
|
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) {
|
int32 width = x2 - x1;
|
||||||
*pixel++ = FETCH_GT_PAL();
|
|
||||||
t += dtdx;
|
|
||||||
g += dgdx;
|
|
||||||
x1++;
|
|
||||||
|
|
||||||
if (x1 >= x2) {
|
while (width--) {
|
||||||
return;
|
PUT_PIXEL_FT();
|
||||||
}
|
pixel++;
|
||||||
}
|
t += dtdx;
|
||||||
|
|
||||||
int32 width2 = (x2 - x1) >> 1;
|
if (width) {
|
||||||
|
|
||||||
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;
|
|
||||||
width--;
|
width--;
|
||||||
}
|
PUT_PIXEL_FT();
|
||||||
|
pixel++;
|
||||||
// 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();
|
|
||||||
t += dtdx;
|
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) {
|
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)
|
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);
|
scanlineG(buffer, x1, x2, palIndex, L.g >> 8, dgdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer += WIDTH / PIXEL_SIZE;
|
buffer += WIDTH;
|
||||||
|
|
||||||
L.stepG();
|
L.stepG();
|
||||||
R.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) {
|
void rasterizeGT(int16 y, Edge &L, Edge &R) {
|
||||||
uint16 *buffer = (uint16*)fb + y * (WIDTH / PIXEL_SIZE);
|
uint16 *buffer = (uint16*)fb + y * WIDTH;
|
||||||
|
|
||||||
while (1)
|
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);
|
scanlineGT(buffer, x1, x2, L.g >> 8, L.t.uv, dgdx, dtdx);
|
||||||
};
|
};
|
||||||
|
|
||||||
buffer += WIDTH / PIXEL_SIZE;
|
buffer += WIDTH;
|
||||||
|
|
||||||
L.stepGT();
|
L.stepGT();
|
||||||
R.stepGT();
|
R.stepGT();
|
||||||
@@ -944,7 +600,7 @@ void rasterizeGT(int16 y, Edge &L, Edge &R) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void rasterizeFT(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];
|
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);
|
scanlineFT(buffer, x1, x2, L.t.uv, dtdx);
|
||||||
};
|
};
|
||||||
|
|
||||||
buffer += WIDTH / PIXEL_SIZE;
|
buffer += WIDTH;
|
||||||
|
|
||||||
L.stepFT();
|
L.stepFT();
|
||||||
R.stepFT();
|
R.stepFT();
|
||||||
@@ -999,7 +655,9 @@ void drawTriangle(const Face* face, VertexUV *v) {
|
|||||||
*v2 = v + 1,
|
*v2 = v + 1,
|
||||||
*v3 = v + 2;
|
*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);
|
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[0] = v3;
|
||||||
L.vert[1] = v1;
|
L.vert[1] = v1;
|
||||||
L.index = 1;
|
L.index = 1;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
L.vert[0] = v3;
|
L.vert[0] = v3;
|
||||||
L.vert[1] = v2;
|
L.vert[1] = v2;
|
||||||
L.vert[2] = v1;
|
L.vert[2] = v1;
|
||||||
@@ -1049,23 +705,35 @@ void drawQuad(const Face* face, VertexUV *v) {
|
|||||||
*v3 = v + 2,
|
*v3 = v + 2,
|
||||||
*v4 = v + 3;
|
*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 };
|
VertexUV* poly[8] = { v1, v2, v3, v4, v1, v2, v3, v4 };
|
||||||
|
|
||||||
for (int32 i = 0; i < 4; i++) {
|
int32 t, b;
|
||||||
VertexUV *v = poly[i];
|
|
||||||
|
|
||||||
if (v->v.y < minY) {
|
if (v1->v.y < v2->v.y) {
|
||||||
minY = v->v.y;
|
if (v1->v.y < v3->v.y) {
|
||||||
t = i;
|
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) {
|
if (v1->v.y > v2->v.y) {
|
||||||
maxY = v->v.y;
|
if (v1->v.y > v3->v.y) {
|
||||||
b = i;
|
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 ix = x + sprite->l;
|
||||||
int32 iy = y + sprite->t;
|
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;
|
ptr += ix;
|
||||||
#else
|
|
||||||
ptr += ix >> 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const uint8* glyphData = tiles + (sprite->tile << 16) + 256 * sprite->v + sprite->u;
|
const uint8* glyphData = tiles + (sprite->tile << 16) + 256 * sprite->v + sprite->u;
|
||||||
|
|
||||||
while (h--)
|
while (h--)
|
||||||
{
|
{
|
||||||
#ifdef USE_MODE_5
|
|
||||||
for (int32 i = 0; i < w; i++) {
|
for (int32 i = 0; i < w; i++) {
|
||||||
if (glyphData[i] == 0) continue;
|
if (glyphData[i] == 0) continue;
|
||||||
|
|
||||||
ptr[i] = palette[glyphData[i]];
|
ptr[i] = palette[glyphData[i]];
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
const uint8* p = glyphData;
|
|
||||||
|
|
||||||
for (int32 i = 0; i < (w / 2); i++) {
|
ptr += WIDTH;
|
||||||
|
|
||||||
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;
|
|
||||||
glyphData += 256;
|
glyphData += 256;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void faceAddQuad(uint32 flags, const Index* indices, int32 startVertex) {
|
void faceAddQuad(uint32 flags, const Index* indices, int32 startVertex) {
|
||||||
#if defined(_WIN32)
|
ASSERT(gFacesCount < MAX_FACES);
|
||||||
if (gFacesCount >= MAX_FACES) {
|
|
||||||
DebugBreak();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
Vertex* v = gVertices + startVertex;
|
Vertex* v = gVertices + startVertex;
|
||||||
Vertex* v1 = v + indices[0];
|
Vertex* v1 = v + indices[0];
|
||||||
Vertex* v2 = v + indices[1];
|
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) {
|
void faceAddTriangle(uint32 flags, const Index* indices, int32 startVertex) {
|
||||||
#if defined(_WIN32)
|
ASSERT(gFacesCount < MAX_FACES);
|
||||||
if (gFacesCount >= MAX_FACES) {
|
|
||||||
DebugBreak();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
Vertex* v = gVertices + startVertex;
|
Vertex* v = gVertices + startVertex;
|
||||||
Vertex* v1 = v + indices[0];
|
Vertex* v1 = v + indices[0];
|
||||||
Vertex* v2 = v + indices[1];
|
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];
|
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++) {
|
for (uint16 i = 0; i < qCount; i++) {
|
||||||
faceAddQuad(quads[i].flags, quads[i].indices, startVertex);
|
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++) {
|
for (int i = 0; i < rCount; i++) {
|
||||||
faceAddQuad(rFaces[i].flags, rFaces[i].indices, startVertex);
|
faceAddQuad(rFaces[i].flags, rFaces[i].indices, startVertex);
|
||||||
@@ -1359,6 +999,9 @@ void flush() {
|
|||||||
v[1].t.uv = tex.uv1;
|
v[1].t.uv = tex.uv1;
|
||||||
v[2].t.uv = tex.uv2;
|
v[2].t.uv = tex.uv2;
|
||||||
v[3].t.uv = tex.uv3;
|
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;
|
Vertex *p = gVertices + face->start;
|
||||||
@@ -1397,14 +1040,6 @@ void flush() {
|
|||||||
gFacesCount = 0;
|
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) {
|
void dmaClear(uint32 *dst, uint32 count) {
|
||||||
#ifdef __GBA__
|
#ifdef __GBA__
|
||||||
vu32 value = 0;
|
vu32 value = 0;
|
||||||
@@ -1417,5 +1052,5 @@ void dmaClear(uint32 *dst, uint32 count) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
dmaClear((uint32*)fb, (WIDTH * HEIGHT) >> PIXEL_SIZE);
|
dmaClear((uint32*)fb, (WIDTH * HEIGHT) >> 1);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user