From 310e8c9dc0e9ab821a117b6c4d6f27588b1adbb8 Mon Sep 17 00:00:00 2001 From: XProger Date: Mon, 22 Feb 2021 14:18:48 +0300 Subject: [PATCH] GBA objects and animations, remove MODE4 code --- src/platform/gba/camera.h | 11 +- src/platform/gba/common.cpp | 193 ++++++--- src/platform/gba/common.h | 223 ++++++---- src/platform/gba/level.h | 602 ++++++++++++++++++-------- src/platform/gba/main.cpp | 65 +-- src/platform/gba/render.iwram.cpp | 685 +++++++----------------------- 6 files changed, 913 insertions(+), 866 deletions(-) diff --git a/src/platform/gba/camera.h b/src/platform/gba/camera.h index 04da9bf..cfbbb32 100644 --- a/src/platform/gba/camera.h +++ b/src/platform/gba/camera.h @@ -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); } }; diff --git a/src/platform/gba/common.cpp b/src/platform/gba/common.cpp index f943473..197356a 100644 --- a/src/platform/gba/common.cpp +++ b/src/platform/gba/common.cpp @@ -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; } \ No newline at end of file diff --git a/src/platform/gba/common.h b/src/platform/gba/common.h index b0d8a40..ba242d0 100644 --- a/src/platform/gba/common.h +++ b/src/platform/gba/common.h @@ -22,47 +22,25 @@ #endif #include -#include #include #include -#include +#include //#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 diff --git a/src/platform/gba/level.h b/src/platform/gba/level.h index eee96e6..971bb93 100644 --- a/src/platform/gba/level.h +++ b/src/platform/gba/level.h @@ -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 diff --git a/src/platform/gba/main.cpp b/src/platform/gba/main.cpp index 9bc7066..87dcf8b 100644 --- a/src/platform/gba/main.cpp +++ b/src/platform/gba/main.cpp @@ -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; diff --git a/src/platform/gba/render.iwram.cpp b/src/platform/gba/render.iwram.cpp index dfc7cda..0e941e6 100644 --- a/src/platform/gba/render.iwram.cpp +++ b/src/platform/gba/render.iwram.cpp @@ -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 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); }