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:
@@ -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++;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
59
src/platform/3do/common_asm.inc
Normal file
59
src/platform/3do/common_asm.inc
Normal 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)
|
260
src/platform/3do/faceAddRoomQuads.s
Normal file
260
src/platform/3do/faceAddRoomQuads.s
Normal 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
|
@@ -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
|
||||
|
@@ -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}
|
||||
|
||||
|
@@ -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()
|
||||
|
@@ -1,7 +1,8 @@
|
||||
AREA |C$$code|, CODE, READONLY
|
||||
|x$codeseg|
|
||||
|
||||
IMPORT gVertices
|
||||
INCLUDE common_asm.inc
|
||||
|
||||
EXPORT unpackMesh_asm
|
||||
|
||||
unpackMesh_asm
|
||||
|
@@ -1,8 +1,8 @@
|
||||
AREA |C$$code|, CODE, READONLY
|
||||
|x$codeseg|
|
||||
|
||||
IMPORT cameraViewOffset
|
||||
IMPORT gVertices
|
||||
INCLUDE common_asm.inc
|
||||
|
||||
EXPORT unpackRoom_asm
|
||||
|
||||
unpackRoom_asm
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user