1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-12 08:04:09 +02:00

#370 3DO faceAddRoomQuads asm

This commit is contained in:
XProger
2021-12-04 04:29:08 +03:00
parent 13b0efcb01
commit 2f257faf82
12 changed files with 480 additions and 153 deletions

View File

@@ -431,7 +431,7 @@ extern int32 fps;
#define MAX_SAMPLES 180
#ifndef VIEW_DIST
#define VIEW_DIST (1024 * 16)
#define VIEW_DIST (1024 * 10)
#endif
#define FOV_SHIFT 3
@@ -607,8 +607,8 @@ struct Matrix
struct RoomQuad
{
#ifdef __3DO__
Index indices[4];
uint32 flags;
Index indices[4];
#else
Index indices[4];
uint16 flags;
@@ -618,8 +618,8 @@ struct RoomQuad
struct MeshQuad
{
#ifdef __3DO__
uint32 indices;
uint32 flags;
uint32 indices;
#else
Index indices[4];
uint16 flags;
@@ -629,9 +629,8 @@ struct MeshQuad
struct RoomTriangle
{
#ifdef __3DO__
Index indices[3];
uint16 _unused;
uint32 flags;
Index indices[4];
#else
Index indices[3];
uint16 flags;
@@ -641,8 +640,8 @@ struct RoomTriangle
struct MeshTriangle
{
#ifdef __3DO__
uint32 indices;
uint32 flags;
uint32 indices;
#else
Index indices[3];
uint16 flags;
@@ -1992,8 +1991,10 @@ struct IMA_STATE
};
#if defined(MODEHW)
#define PERSPECTIVE_DZ(z) (z >> 4)
#define PERSPECTIVE(x, y, z) {\
int32 dz = z >> 4;\
int32 dz = PERSPECTIVE_DZ(z);\
if (dz >= DIV_TABLE_SIZE) dz = DIV_TABLE_SIZE - 1;\
int32 d = FixedInvU(dz);\
x = (x * d) >> 12;\
@@ -2008,9 +2009,10 @@ struct IMA_STATE
y = d * (y >> 14) >> 12;\
}
#elif defined(MODE4)
#define PERSPECTIVE_DZ(z) ((z >> 4) + (z >> 6))
#define PERSPECTIVE(x, y, z) {\
int32 dz = z >> 4;\
dz += z >> 6;\
int32 dz = PERSPECTIVE_DZ(z);\
if (dz >= DIV_TABLE_SIZE) dz = DIV_TABLE_SIZE - 1;\
int32 d = FixedInvU(dz);\
x = (x * d) >> 12;\
@@ -2147,6 +2149,7 @@ X_INLINE Matrix& matrixGet()
X_INLINE void matrixPush()
{
ASSERT(matrixPtr - matrixStack < MAX_MATRICES);
memcpy(matrixPtr + 1, matrixPtr, sizeof(Matrix));
matrixPtr++;
}

View File

@@ -421,19 +421,19 @@ bool Room::checkPortal(const Portal* portal)
continue;
}
if (z >= VIEW_MAX_F)
if (z > VIEW_MAX_F)
{
z = VIEW_MAX_F;
zfar++;
}
int32 dz = (z >> (FIXED_SHIFT + FOV_SHIFT + 1)); // TODO PROJ_SHIFT?
x >>= FIXED_SHIFT;
y >>= FIXED_SHIFT;
z >>= FIXED_SHIFT;
int32 dz = PERSPECTIVE_DZ(z);
if (dz > 0) {
x >>= FIXED_SHIFT;
y >>= FIXED_SHIFT;
z >>= FIXED_SHIFT;
PERSPECTIVE(x, y, z);
x += FRAME_WIDTH >> 1;

View File

@@ -1,6 +1,8 @@
AREA |C$$code|, CODE, READONLY
|x$codeseg|
INCLUDE common_asm.inc
EXPORT ccbMap3_asm
ccbMap3_asm
@@ -32,9 +34,6 @@ shift RN hs
hddx RN ws
hddy RN hs
FRAME_WIDTH EQU 320
FRAME_HEIGHT EQU 240
stmfd sp!, {r4-r6, lr}
add face, face, #16 ; offset to ccb_XPos

View File

@@ -1,6 +1,8 @@
AREA |C$$code|, CODE, READONLY
|x$codeseg|
INCLUDE common_asm.inc
EXPORT ccbMap4_asm
ccbMap4_asm
@@ -37,9 +39,6 @@ ws RN r12
hs RN lr
shift RN hs
FRAME_WIDTH EQU 320
FRAME_HEIGHT EQU 240
stmfd sp!, {r4-r8, lr}
add face, face, #16 ; offset to ccb_XPos

View File

@@ -0,0 +1,59 @@
IMPORT matrixPtr
IMPORT viewportRel
IMPORT gVertices
IMPORT gFacesBase
IMPORT gOT
IMPORT gPaletteOffset
IMPORT shadeTable
IMPORT divTable
IMPORT level
CCB_NOBLK EQU 0x00000010
CCB_BGND EQU 0x00000020
CCB_ACE EQU 0x00004000
CCB_ACCW EQU 0x00020000
CCB_ACW EQU 0x00040000
CCB_ALSC EQU 0x00080000
CCB_ACSC EQU 0x00100000
CCB_YOXY EQU 0x00200000
CCB_LDPLUT EQU 0x00800000
CCB_LDPPMP EQU 0x01000000
CCB_LDPRS EQU 0x02000000
CCB_LDSIZE EQU 0x04000000
CCB_PPABS EQU 0x08000000
CCB_SPABS EQU 0x10000000
CCB_NPABS EQU 0x20000000
SIZE_OF_CCB EQU 68
FRAME_WIDTH EQU 320
FRAME_HEIGHT EQU 240
FIXED_SHIFT EQU 14
PROJ_SHIFT EQU 4
LVL_TEX_OFFSET EQU (23 * 4)
CLIP_SHIFT EQU 8
CLIP_MASK EQU ((1 << CLIP_SHIFT) - 1)
CLIP_LEFT EQU (1 << 0)
CLIP_RIGHT EQU (1 << 1)
CLIP_TOP EQU (1 << 2)
CLIP_BOTTOM EQU (1 << 3)
CLIP_FAR EQU (1 << 4)
CLIP_NEAR EQU (1 << 5)
FACE_MIP_SHIFT EQU 11
MIP_DIST EQU (1024 * 5)
VIEW_DIST EQU (1024 * 10) ; max = DIV_TABLE_END << PROJ_SHIFT
FOG_SHIFT EQU 1
FOG_MAX EQU VIEW_DIST
FOG_MIN EQU (FOG_MAX - (8192 >> FOG_SHIFT))
VIEW_MIN_F EQU (256 << FIXED_SHIFT)
VIEW_MAX_F EQU (VIEW_DIST << FIXED_SHIFT)
OT_SHIFT EQU 4
OT_SIZE EQU ((VIEW_MAX_F >> (FIXED_SHIFT + OT_SHIFT)) + 1)
DIV_TABLE_END EQU (1025 - 1)
VIEW_MIN EQU (256 << CLIP_SHIFT)
VIEW_MAX EQU (VIEW_DIST << CLIP_SHIFT)
MulManyVec3Mat33_F16 EQU (0x50000 + 2)

View File

@@ -0,0 +1,260 @@
AREA |C$$code|, CODE, READONLY
|x$codeseg|
INCLUDE common_asm.inc
EXPORT faceAddRoomQuads_asm
faceAddRoomQuads_asm
quadsArg RN r0
countArg RN r1
flags RN quadsArg
vx0 RN r2
vy0 RN r3
vx1 RN r4
vy1 RN r5
vx3 RN r6
vy3 RN r7
vx2 RN r8
vy2 RN r9
pixc RN r10
tex RN r11
mask RN r12
depth RN lr
spQuads RN vx0
spLast RN vx1
spVertices RN vy3
spOT RN vx2
spShadeLUT RN vy2
spTextures RN pixc
spFaceBase RN tex
spPalette RN mask
face RN mask
faceBase RN mask
hv0 RN mask
hv1 RN vy2
i0 RN vy0
i1 RN vy1
vz0 RN vy0
vz1 RN vy1
vz2 RN vy2
vz3 RN vy3
vp0 RN vx0
vp1 RN vx1
vp2 RN vx2
vp3 RN vx3
xpos RN vx0
ypos RN vy0
hdx0 RN vx1
hdy0 RN vy1
hdx1 RN vx2
hdy1 RN vy2
vdx0 RN vx3
vdy0 RN vy3
hddx RN hdx1
hddy RN hdy1
nextPtr RN vy2
dataPtr RN flags
plutPtr RN countArg
tmp RN countArg
ot RN countArg
otTail RN depth
shadeLUT RN pixc
fog RN pixc
intensity RN vy2
plutOffset RN vy2
texIndex RN vy2
ws RN tex
hs RN depth
shift RN depth
SP_QUADS EQU 0
SP_LAST EQU 4
SP_VERTICES EQU 8
SP_OT EQU 12
SP_SHADELUT EQU 16
SP_TEXTURES EQU 20
SP_FACEBASE EQU 24
SP_PALETTE EQU 28
SP_SIZE EQU 32
stmfd sp!, {r4-r11, lr}
sub sp, sp, #SP_SIZE
add countArg, countArg, countArg, lsl #1
add spLast, quadsArg, countArg, lsl #2
ldr spVertices, =gVertices
ldr spOT, =gOT
ldr spShadeLUT, =shadeTable
ldr spTextures, =level
ldr spTextures, [spTextures, #LVL_TEX_OFFSET]
ldr spFaceBase, =gFacesBase
ldr spPalette, =gPaletteOffset
ldr spPalette, [spPalette]
stmia sp, {quadsArg, spLast, spVertices, spOT, spShadeLUT, spTextures, spFaceBase, spPalette}
loop ldmia sp, {spQuads, spLast, spVertices}
cmp spQuads, spLast
bge done
ldmia spQuads!, {flags, i0, i1}
str spQuads, [sp, #SP_QUADS]
; get vertex pointers
add vp0, spVertices, i0, lsr #16
mov i0, i0, lsl #16
add vp1, spVertices, i0, lsr #16
add vp2, spVertices, i1, lsr #16
mov i1, i1, lsl #16
add vp3, spVertices, i1, lsr #16
; read z value with clip mask
ldr vz0, [vp0, #8]
ldr vz1, [vp1, #8]
ldr vz2, [vp2, #8]
ldr vz3, [vp3, #8]
; check clipping
and mask, vz1, vz0
and mask, vz2, mask
and mask, vz3, mask
tst mask, #CLIP_MASK
bne loop
; depth = max(vz0, vz1, vz2, vz3) (DEPTH_Q_MAX)
mov depth, vz0
cmp depth, vz1
movlt depth, vz1
cmp depth, vz2
movlt depth, vz2
cmp depth, vz3
movlt depth, vz3
; (vx1 - vx0) * (vy3 - vy0) <= (vy1 - vy0) * (vx3 - vx0)
ldmia vp0, {vx0, vy0}
ldmia vp1, {vx1, vy1}
ldmia vp3, {vx3, vy3}
sub hdx0, vx1, vx0
sub hdy0, vy1, vy0
sub vdx0, vx3, vx0
sub vdy0, vy3, vy0
mul hv0, hdx0, vdy0
mul hv1, hdy0, vdx0
cmp hv0, hv1
ble loop
; depth = max(0, depth) >> (CLIP_SHIFT + OT_SHIFT)
movs depth, depth, lsr #(CLIP_SHIFT + OT_SHIFT)
movmi depth, #0
; fog = max(0, (depth - (FOG_MIN >> OT_SHIFT)) >> 1)
sub fog, depth, #(FOG_MIN >> OT_SHIFT)
movs fog, fog, asr #1
movmi fog, #0
; intensity = min(255, fog + ((flags >> (FACE_MIP_SHIFT + FACE_MIP_SHIFT)) & 0xFF)) >> 3
mov intensity, flags, lsl #(32 - 8 - FACE_MIP_SHIFT - FACE_MIP_SHIFT)
add intensity, fog, intensity, lsr #(32 - 8)
cmp intensity, #255
movcs intensity, #255
mov intensity, intensity, lsr #3
add tmp, sp, #SP_OT
ldmia tmp, {ot, shadeLUT, tex, faceBase}
; pixc = shadeTable[intensity]
ldr pixc, [shadeLUT, intensity, lsl #2]
; get texture ptr (base or mip)
mov texIndex, flags
cmp depth, #(MIP_DIST >> OT_SHIFT)
movgt texIndex, flags, lsr #FACE_MIP_SHIFT
mov texIndex, texIndex, lsl #(32 - FACE_MIP_SHIFT)
mov texIndex, texIndex, lsr #(32 - FACE_MIP_SHIFT)
add texIndex, texIndex, texIndex, lsl #1
add tex, tex, texIndex, lsl #2
; faceAdd
cmp depth, #(OT_SIZE - 1)
movgt depth, #(OT_SIZE - 1)
add ot, ot, depth, lsl #3 ; mul by size of OT element
mov depth, faceBase ; use depth reg as faceBase due face reg collision
ldr face, [depth]
add nextPtr, face, #SIZE_OF_CCB
str nextPtr, [depth]
ldmia ot, {nextPtr, otTail}
cmp nextPtr, #0
moveq otTail, face
stmia ot, {face, otTail}
; ccb flags
ands flags, flags, #(1 << 30)
movne flags, #(CCB_BGND)
orr flags, flags, #(CCB_NOBLK)
orr flags, flags, #(CCB_ACE + CCB_ACCW + CCB_ACW + CCB_ALSC + CCB_ACSC + CCB_YOXY)
orr flags, flags, #(CCB_LDPLUT + CCB_LDPPMP + CCB_LDPRS + CCB_LDSIZE + CCB_PPABS + CCB_SPABS + CCB_NPABS)
; ccbMap4
stmia face!, {flags, nextPtr}
ldmia tex, {dataPtr, plutPtr, shift}
ldr plutOffset, [sp, #SP_PALETTE]
add plutPtr, plutPtr, plutOffset
ldmia vp2, {vx2, vy2}
sub vx2, vx2, vx0
sub vy2, vy2, vy0
sub hdx1, vx2, vx3
sub hdy1, vy2, vy3
and ws, shift, #0xFF
mov hs, shift, lsr #8
mov hdx0, hdx0, lsl ws
mov hdy0, hdy0, lsl ws
mov vdx0, vdx0, lsl hs
mov vdy0, vdy0, lsl hs
rsb hs, hs, #16
rsb hddx, hdx0, hdx1, lsl ws
rsb hddy, hdy0, hdy1, lsl ws
mov hddx, hddx, asr hs
mov hddy, hddy, asr hs
mov xpos, vx0, lsl #16
mov ypos, vy0, lsl #16
add xpos, xpos, #(FRAME_WIDTH << 15)
add ypos, ypos, #(FRAME_HEIGHT << 15)
stmia face, {dataPtr, plutPtr, xpos, ypos, hdx0, hdy0, vdx0, vdy0, hddx, hddy, pixc}
bl loop
done add sp, sp, #SP_SIZE
ldmfd sp!, {r4-r11, pc}
END

View File

@@ -1,8 +1,8 @@
AREA |C$$code|, CODE, READONLY
|x$codeseg|
IMPORT matrixPtr
IMPORT divTable
INCLUDE common_asm.inc
EXPORT matrixLerp_asm
n RN r0

View File

@@ -1,10 +1,8 @@
AREA |C$$code|, CODE, READONLY
|x$codeseg|
IMPORT matrixPtr
IMPORT viewportRel
IMPORT divTable
IMPORT gVertices
INCLUDE common_asm.inc
EXPORT projectVertices_asm
vCount RN r0
@@ -25,23 +23,6 @@ last RN r10
vertex RN r11
divLUT RN lr
FIXED_SHIFT EQU 14
PROJ_SHIFT EQU 4
CLIP_SHIFT EQU 8
CLIP_LEFT EQU (1 << 0)
CLIP_RIGHT EQU (1 << 1)
CLIP_TOP EQU (1 << 2)
CLIP_BOTTOM EQU (1 << 3)
CLIP_FAR EQU (1 << 4)
CLIP_NEAR EQU (1 << 5)
DIV_TABLE_END EQU (1025 - 1)
VIEW_DIST EQU (1024 * 10) ; max = DIV_TABLE_END << PROJ_SHIFT
VIEW_MIN EQU (256 << CLIP_SHIFT)
VIEW_MAX EQU (VIEW_DIST << CLIP_SHIFT)
MulManyVec3Mat33_F16 EQU (0x50000 + 2)
projectVertices_asm
stmfd sp!, {r4-r11, lr}

View File

@@ -22,11 +22,14 @@ int32 gFacesCount;
Vertex gVertices[MAX_VERTICES];
Face* gFaces; // MAX_FACES
Face* otFacesHead[OT_SIZE];
Face* otFacesTail[OT_SIZE];
Face* gFacesBase;
int32 otMin = OT_SIZE - 1;
int32 otMax = 0;
struct ListOT {
Face* head;
Face* tail;
};
ListOT gOT[OT_SIZE];
struct ViewportRel {
int16 x0, y0;
@@ -75,7 +78,7 @@ enum ShadeValue
SHADE_24 = DUP16( PPMPC_MF_8 | PPMPC_SF_16 | PPMPC_2S_PDC ) // 1 + 8/16
};
static const uint32 shadeTable[32] = {
extern "C" const uint32 shadeTable[32] = {
SHADE_24,
SHADE_24,
SHADE_23,
@@ -114,6 +117,7 @@ void renderInit()
{
gPalette = (uint16*)RAM_TEX;
gFaces = (Face*)RAM_CEL;
gFacesBase = gFaces;
Face* face = gFaces;
for (int32 i = 0; i < MAX_FACES; i++, face++)
@@ -164,10 +168,10 @@ int32 boxIsVisible(const AABBs* box)
return rectIsVisible(&rect);
}
X_INLINE bool checkBackface(const Vertex *a, const Vertex *b, const Vertex *c)
X_INLINE int32 cross(const Vertex *a, const Vertex *b, const Vertex *c)
{
return (b->x - a->x) * (c->y - a->y) -
(c->x - a->x) * (b->y - a->y) <= 0;
(c->x - a->x) * (b->y - a->y);
}
enum ClipFlags {
@@ -181,12 +185,18 @@ enum ClipFlags {
CLIP_NEAR = 1 << 5
};
#define DEPTH_T_AVG(z0,z1,z2) ((z0 + z1 + z2 + z2) >> (2 + CLIP_SHIFT + OT_SHIFT))
#define DEPTH_Q_AVG(z0,z1,z2,z3) ((z0 + z1 + z2 + z3) >> (2 + CLIP_SHIFT + OT_SHIFT))
#define DEPTH_T_MAX(z0,z1,z2) (X_MAX(z0, X_MAX(z1, z2)) >> (CLIP_SHIFT + OT_SHIFT))
#define DEPTH_Q_MAX(z0,z1,z2,z3) (X_MAX(z0, X_MAX(z1, X_MAX(z2, z3))) >> (CLIP_SHIFT + OT_SHIFT))
#ifdef USE_ASM
#define unpackRoom unpackRoom_asm
#define unpackMesh unpackMesh_asm
#define projectVertices projectVertices_asm
#define ccbMap4 ccbMap4_asm
#define ccbMap3 ccbMap3_asm
#define faceAddRoomQuads faceAddRoomQuads_asm
extern "C" {
void unpackRoom_asm(const RoomVertex* vertices, int32 vCount);
@@ -194,6 +204,7 @@ enum ClipFlags {
void projectVertices_asm(int32 vCount);
void ccbMap4_asm(Face* f, const Vertex* v0, const Vertex* v1, const Vertex* v2, const Vertex* v3, uint32 shift);
void ccbMap3_asm(Face* f, const Vertex* v0, const Vertex* v1, const Vertex* v2, uint32 shift);
void faceAddRoomQuads_asm(const RoomQuad* quads, int32 count);
}
#else
#define unpackRoom unpackRoom_c
@@ -201,6 +212,11 @@ enum ClipFlags {
#define projectVertices projectVertices_c
#define ccbMap4 ccbMap4_c
#define ccbMap3 ccbMap3_c
#define faceAddRoomQuads faceAddRoomQuads_c
Face* faceAdd(int32 depth);
void ccbSetTexture(uint32 flags, Face* face, const Texture* texture);
void ccbSetColor(uint32 flags, Face* face);
void unpackRoom_c(const RoomVertex* vertices, int32 vCount)
{
@@ -305,7 +321,7 @@ void projectVertices_c(int32 vCount)
} while (v < last);
}
void ccbMap4_c(Face* f, const Vertex* v0, const Vertex* v1, const Vertex* v2, const Vertex* v3, uint32 shift)
X_INLINE void ccbMap4_c(Face* f, const Vertex* v0, const Vertex* v1, const Vertex* v2, const Vertex* v3, uint32 shift)
{
int32 x1 = v1->x;
int32 y1 = v1->y;
@@ -345,7 +361,7 @@ void ccbMap4_c(Face* f, const Vertex* v0, const Vertex* v1, const Vertex* v2, co
#endif
}
void ccbMap3_c(Face* f, const Vertex* v0, const Vertex* v1, const Vertex* v2, uint32 shift)
X_INLINE void ccbMap3_c(Face* f, const Vertex* v0, const Vertex* v1, const Vertex* v2, uint32 shift)
{
int32 x0 = v0->x;
int32 y0 = v0->y;
@@ -377,6 +393,57 @@ void ccbMap3_c(Face* f, const Vertex* v0, const Vertex* v1, const Vertex* v2, ui
f->ccb_PIXC = SHADE_SHADOW;
#endif
}
void faceAddRoomQuads_c(const RoomQuad* quads, int32 count)
{
for (int32 i = 0; i < count; i++, quads++)
{
uint32 flags = quads->flags;
uint32* indices = (uint32*)quads->indices;
uint32 i01 = indices[0];
uint32 i23 = indices[1];
uint32 i0 = (i01 >> 16);
uint32 i1 = (i01 & 0xFFFF);
uint32 i2 = (i23 >> 16);
uint32 i3 = (i23 & 0xFFFF);
const Vertex* v0 = (Vertex*)((uint8*)gVertices + i0);
const Vertex* v1 = (Vertex*)((uint8*)gVertices + i1);
const Vertex* v2 = (Vertex*)((uint8*)gVertices + i2);
const Vertex* v3 = (Vertex*)((uint8*)gVertices + i3);
uint32 c0 = v0->z;
uint32 c1 = v1->z;
uint32 c2 = v2->z;
uint32 c3 = v3->z;
if ((c0 & c1 & c2 & c3) & CLIP_MASK)
continue;
int32 depth = DEPTH_Q_MAX(c0, c1, c2, c3);
if (cross(v0, v1, v3) <= 0)
continue;
Face* f = faceAdd(depth);
int32 fog = X_MAX(0, (depth - (FOG_MIN >> OT_SHIFT)) >> 1);
uint32 intensity = X_MIN(255, fog + ((flags >> (FACE_MIP_SHIFT + FACE_MIP_SHIFT)) & 0xFF));
f->ccb_PIXC = shadeTable[intensity >> 3];
uint32 texIndex = flags;
if (depth > (MIP_DIST >> OT_SHIFT)) {
texIndex >>= FACE_MIP_SHIFT;
}
const Texture* texture = level.textures + (texIndex & FACE_TEXTURE);
ccbSetTexture(flags, f, texture);
ccbMap4(f, v0, v1, v2, v3, texture->shift);
}
}
#endif
bool transformBoxRect(const AABBs* box, RectMinMax* rect)
@@ -454,29 +521,20 @@ void transformMesh(const MeshVertex* vertices, int32 vCount, const uint16* vInte
gVerticesCount += vCount;
}
#define DEPTH_T_AVG(z0,z1,z2) ((z0 + z1 + z2 + z2) >> (2 + CLIP_SHIFT + OT_SHIFT))
#define DEPTH_Q_AVG(z0,z1,z2,z3) ((z0 + z1 + z2 + z3) >> (2 + CLIP_SHIFT + OT_SHIFT))
#define DEPTH_T_MAX(z0,z1,z2) (X_MAX(z0, X_MAX(z1, z2)) >> (CLIP_SHIFT + OT_SHIFT))
#define DEPTH_Q_MAX(z0,z1,z2,z3) (X_MAX(z0, X_MAX(z1, X_MAX(z2, z3))) >> (CLIP_SHIFT + OT_SHIFT))
X_INLINE Face* faceAdd(int32 depth)
{
if (depth < 0) depth = 0;
if (depth > OT_SIZE - 1) depth = OT_SIZE - 1;
if (depth < otMin) otMin = depth;
if (depth > otMax) otMax = depth;
Face* face = gFacesBase++;
Face* face = gFaces + gFacesCount++;
if (otFacesHead[depth]) {
face->ccb_NextPtr = otFacesHead[depth];
if (gOT[depth].head) {
face->ccb_NextPtr = gOT[depth].head;
} else {
face->ccb_NextPtr = NULL;
otFacesTail[depth] = face;
gOT[depth].tail = face;
}
otFacesHead[depth] = face;
gOT[depth].head = face;
return face;
}
@@ -522,54 +580,6 @@ X_INLINE void ccbSetColor(uint32 flags, Face* face)
face->ccb_SourcePtr = (CelData*)&gPalette[flags & 0xFF];
}
X_INLINE void faceAddRoomQuad(uint32 flags, const Index* indices)
{
uint32 i01 = ((uint32*)indices)[0];
uint32 i23 = ((uint32*)indices)[1];
uint32 i0 = (i01 >> 16);
uint32 i1 = (i01 & 0xFFFF);
uint32 i2 = (i23 >> 16);
uint32 i3 = (i23 & 0xFFFF);
const Vertex* v0 = gVertices + i0;
const Vertex* v1 = gVertices + i1;
const Vertex* v2 = gVertices + i2;
const Vertex* v3 = gVertices + i3;
uint32 c0 = v0->z;
uint32 c1 = v1->z;
uint32 c2 = v2->z;
uint32 c3 = v3->z;
if ((c0 & c1 & c2 & c3) & CLIP_MASK)
return;
int32 depth = DEPTH_Q_MAX(c0, c1, c2, c3);
if (checkBackface(v0, v1, v3) == !(flags & FACE_CCW))
return;
Face* f = faceAdd(depth);
uint32 intensity = (flags >> (FACE_MIP_SHIFT + FACE_MIP_SHIFT)) & 0xFF;
if (depth > (FOG_MIN >> OT_SHIFT)) {
intensity += (depth - (FOG_MIN >> OT_SHIFT)) >> 1;
intensity = X_MIN(intensity, 255);
}
f->ccb_PIXC = shadeTable[intensity >> 3];
uint32 texIndex = flags;
if (depth > (MIP_DIST >> OT_SHIFT)) {
texIndex >>= FACE_MIP_SHIFT;
}
const Texture* texture = level.textures + (texIndex & FACE_TEXTURE);
ccbSetTexture(flags, f, texture);
ccbMap4(f, v0, v1, v2, v3, texture->shift);
}
X_INLINE void faceAddRoomTriangle(uint32 flags, const Index* indices)
{
uint32 i01 = ((uint32*)indices)[0];
@@ -579,9 +589,9 @@ X_INLINE void faceAddRoomTriangle(uint32 flags, const Index* indices)
uint32 i1 = (i01 & 0xFFFF);
uint32 i2 = (i23 >> 16);
const Vertex* v0 = gVertices + i0;
const Vertex* v1 = gVertices + i1;
const Vertex* v2 = gVertices + i2;
const Vertex* v0 = (Vertex*)((uint8*)gVertices + i0);
const Vertex* v1 = (Vertex*)((uint8*)gVertices + i1);
const Vertex* v2 = (Vertex*)((uint8*)gVertices + i2);
uint32 c0 = v0->z;
uint32 c1 = v1->z;
@@ -592,7 +602,7 @@ X_INLINE void faceAddRoomTriangle(uint32 flags, const Index* indices)
int32 depth = DEPTH_T_MAX(c0, c1, c2);
if (checkBackface(v0, v1, v2) == !(flags & FACE_CCW))
if (cross(v0, v1, v2) <= 0)
return;
Face* f = faceAdd(depth);
@@ -635,7 +645,7 @@ X_INLINE void faceAddMeshQuad(uint32 flags, uint32 indices, uint32 shade)
if ((c0 & c1 & c2 & c3) & CLIP_MASK)
return;
if (checkBackface(v0, v1, v3) == !(flags & FACE_CCW)) // TODO (hdx0 * vdy0 - vdx0 * hdy0) <= 0
if ((cross(v0, v1, v3) ^ flags) & FACE_CCW) // TODO (hdx0 * vdy0 - vdx0 * hdy0) <= 0
return;
int32 depth = DEPTH_Q_AVG(v0->z, v1->z, v2->z, v3->z);
@@ -666,7 +676,7 @@ X_INLINE void faceAddMeshTriangle(uint32 flags, uint32 indices, uint32 shade)
if ((c0 & c1 & c2) & CLIP_MASK)
return;
if (checkBackface(v0, v1, v2))
if (cross(v0, v1, v2) <= 0)
return;
int32 depth = DEPTH_T_AVG(v0->z, v1->z, v2->z);
@@ -700,7 +710,7 @@ X_INLINE void faceAddMeshQuadFlat(uint32 flags, uint32 indices, uint32 shade)
if ((c0 & c1 & c2 & c3) & CLIP_MASK)
return;
if (checkBackface(v0, v1, v3))
if (cross(v0, v1, v3) <= 0)
return;
int32 depth = DEPTH_Q_AVG(v0->z, v1->z, v2->z, v3->z);
@@ -730,7 +740,7 @@ X_INLINE void faceAddMeshTriangleFlat(uint32 flags, uint32 indices, uint32 shade
if ((c0 & c1 & c2) & CLIP_MASK)
return;
if (checkBackface(v0, v1, v2))
if (cross(v0, v1, v2) <= 0)
return;
int32 depth = DEPTH_T_AVG(v0->z, v1->z, v2->z);
@@ -745,6 +755,10 @@ X_INLINE void faceAddMeshTriangleFlat(uint32 flags, uint32 indices, uint32 shade
void faceAddShadow(int32 x, int32 z, int32 sx, int32 sz)
{
if (gFacesCount + 3 > MAX_FACES)
return;
gFacesCount += 3;
x <<= F16_SHIFT;
z <<= F16_SHIFT;
sx <<= F16_SHIFT;
@@ -775,6 +789,7 @@ void faceAddSprite(int32 vx, int32 vy, int32 vz, int32 vg, int32 index)
{
if (gFacesCount >= MAX_FACES)
return;
gFacesCount++;
const Matrix &m = matrixGet();
@@ -789,8 +804,6 @@ void faceAddSprite(int32 vx, int32 vy, int32 vz, int32 vg, int32 index)
return;
}
ASSERT(gFacesCount < MAX_FACES);
int32 x = DP33(m.e00, m.e01, m.e02, vx, vy, vz);
int32 y = DP33(m.e10, m.e11, m.e12, vx, vy, vz);
@@ -854,6 +867,10 @@ void faceAddSprite(int32 vx, int32 vy, int32 vz, int32 vg, int32 index)
void faceAddGlyph(int32 vx, int32 vy, int32 index)
{
if (gFacesCount >= MAX_FACES)
return;
gFacesCount++;
const Sprite* sprite = level.sprites + index;
Face* f = faceAdd(0);
@@ -880,16 +897,14 @@ void faceAddGlyph(int32 vx, int32 vy, int32 index)
void faceAddRoom(const Room* room)
{
const RoomQuad* quads = room->data.quads;
faceAddRoomQuads(room->data.quads, room->info->quadsCount);
const RoomTriangle* triangles = room->data.triangles;
for (int32 i = 0; i < room->info->quadsCount; i++, quads++) {
faceAddRoomQuad(quads->flags, quads->indices);
}
for (int32 i = 0; i < room->info->trianglesCount; i++, triangles++) {
faceAddRoomTriangle(triangles->flags, triangles->indices);
}
gFacesCount = gFacesBase - gFaces;
}
void faceAddMesh(const MeshQuad* rFaces, const MeshQuad* crFaces, const MeshTriangle* tFaces, const MeshTriangle* ctFaces, int32 rCount, int32 crCount, int32 tCount, int32 ctCount)
@@ -916,6 +931,8 @@ void faceAddMesh(const MeshQuad* rFaces, const MeshQuad* crFaces, const MeshTria
for (int32 i = 0; i < ctCount; i++) {
faceAddMeshTriangleFlat(ctFaces[i].flags, ctFaces[i].indices, shade);
}
gFacesCount = gFacesBase - gFaces;
}
void flush()
@@ -927,12 +944,12 @@ void flush()
{
PROFILE(CNT_FLUSH);
for (int32 i = otMax; i >= otMin; i--)
for (int32 i = OT_SIZE - 1; i >= 0; i--)
{
if (!otFacesHead[i]) continue;
if (!gOT[i].head) continue;
Face *face = otFacesHead[i];
otFacesHead[i] = NULL;
Face *face = gOT[i].head;
gOT[i].head = NULL;
if (face)
{
@@ -943,13 +960,10 @@ void flush()
facesHead = face;
}
facesTail = otFacesTail[i];
facesTail = gOT[i].tail;
}
}
otMin = OT_SIZE - 1;
otMax = 0;
if (facesHead)
{
LAST_CEL(facesTail);
@@ -967,6 +981,7 @@ void flush()
gVerticesCount = 0;
gFacesCount = 0;
gFacesBase = gFaces;
}
void clear()

View File

@@ -1,7 +1,8 @@
AREA |C$$code|, CODE, READONLY
|x$codeseg|
IMPORT gVertices
INCLUDE common_asm.inc
EXPORT unpackMesh_asm
unpackMesh_asm

View File

@@ -1,8 +1,8 @@
AREA |C$$code|, CODE, READONLY
|x$codeseg|
IMPORT cameraViewOffset
IMPORT gVertices
INCLUDE common_asm.inc
EXPORT unpackRoom_asm
unpackRoom_asm

View File

@@ -816,11 +816,11 @@ struct LevelPC
void write(FileStream &f) const
{
f.write(flags);
f.write(indices[0]);
f.write(indices[1]);
f.write(indices[2]);
f.write(indices[3]);
f.write(flags);
}
};
@@ -831,11 +831,11 @@ struct LevelPC
void write(FileStream &f) const
{
f.write(flags);
f.write(indices[3]);
f.write(indices[2]);
f.write(indices[1]);
f.write(indices[0]);
f.write(flags);
}
};
@@ -862,11 +862,11 @@ struct LevelPC
void write(FileStream &f) const
{
f.write(flags);
f.write(indices[0]);
f.write(indices[1]);
f.write(indices[2]);
f.write(_unused);
f.write(flags);
}
};
@@ -878,12 +878,12 @@ struct LevelPC
void write(FileStream &f) const
{
f.write(flags);
uint8 unused = 0;
f.write(unused);
f.write(indices[2]);
f.write(indices[1]);
f.write(indices[0]);
f.write(flags);
}
};
@@ -3738,14 +3738,20 @@ struct LevelPC
q.indices[2] = addRoomVertex(info.yTop, v2, true);
q.indices[3] = addRoomVertex(info.yTop, v3, true);
ASSERT((int32)q.indices[0] * 12 < 0xFFFF);
ASSERT((int32)q.indices[1] * 12 < 0xFFFF);
ASSERT((int32)q.indices[2] * 12 < 0xFFFF);
ASSERT((int32)q.indices[3] * 12 < 0xFFFF);
RoomQuad3DO comp;
comp.indices[0] = q.indices[0];
comp.indices[1] = q.indices[1];
comp.indices[2] = q.indices[2];
comp.indices[3] = q.indices[3];
comp.indices[0] = q.indices[0] * 12;
comp.indices[1] = q.indices[1] * 12;
comp.indices[2] = q.indices[2] * 12;
comp.indices[3] = q.indices[3] * 12;
comp.flags = q.flags;
// add ccw flag and swap indices
calcQuadFlip(comp);
ASSERT((comp.flags & FACE_CCW) == 0);
// add intensity
comp.flags |= (intensity << (FACE_MIP_SHIFT + FACE_MIP_SHIFT));
if (textures3DO[comp.flags & FACE_TEXTURE].pre0 & PRE0_BGND) {
@@ -3777,10 +3783,14 @@ struct LevelPC
t.indices[1] = addRoomVertex(info.yTop, v1, true);
t.indices[2] = addRoomVertex(info.yTop, v2, true);
ASSERT((int32)t.indices[0] * 12 < 0xFFFF);
ASSERT((int32)t.indices[1] * 12 < 0xFFFF);
ASSERT((int32)t.indices[2] * 12 < 0xFFFF);
RoomTriangle3DO comp;
comp.indices[0] = t.indices[0];
comp.indices[1] = t.indices[1];
comp.indices[2] = t.indices[2];
comp.indices[0] = t.indices[0] * 12;
comp.indices[1] = t.indices[1] * 12;
comp.indices[2] = t.indices[2] * 12;
comp._unused = 0;
comp.flags = t.flags;
// add intensity