1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-03-14 16:19:41 +01:00

#407 32X use asm code for matrix math and misc functions, watch dog timers for profiling (hw only), change gamepad layout, fix sprite rasterization,

This commit is contained in:
XProger 2022-03-08 18:56:20 +03:00
parent 13255f9d5e
commit c49a46de6b
14 changed files with 933 additions and 199 deletions

View File

@ -1,10 +1,10 @@
#ifndef H_COMMON
#define H_COMMON
//#define STATIC_ITEMS
//#define PROFILING
#define PROFILING
#ifdef PROFILING
#define STATIC_ITEMS
// #define PROFILE_FRAMETIME
#define PROFILE_FRAMETIME
// #define PROFILE_SOUNDTIME
#endif
@ -322,7 +322,7 @@ extern void* osLoadLevel(const char* name);
extern uint32 gCounters[CNT_MAX];
#if defined(__3DO__) // should be first, armcpp bug (#elif)
#if defined(__3DO__) || defined(__32X__) // should be first, armcpp bug (#elif)
extern int32 g_timer;
#define PROFILE_START() {\
@ -2692,9 +2692,61 @@ vec3i boxPushOut(const AABBi &a, const AABBi &b);
#ifdef __32X__ // TODO
#undef matrixPush
#define matrixPush matrixPush_asm
#undef matrixSetIdentity
#undef matrixSetBasis
#undef matrixLerp
#undef matrixTranslateRel
#undef matrixTranslateAbs
#undef matrixTranslateSet
#undef matrixRotateX
#undef matrixRotateY
#undef matrixRotateZ
#undef matrixRotateYXZ
#undef matrixRotateYQ
//#undef boxTranslate
//#undef boxRotateYQ
//#undef boxIsVisible
//#undef sphereIsVisible
//#undef flush
extern "C" void matrixPush_asm();
#define matrixPush matrixPush_asm
#define matrixSetIdentity matrixSetIdentity_asm
#define matrixSetBasis matrixSetBasis_asm
#define matrixLerp matrixLerp_asm
#define matrixTranslateRel matrixTranslateRel_asm
#define matrixTranslateAbs matrixTranslateAbs_asm
#define matrixTranslateSet matrixTranslateSet_asm
#define matrixRotateX matrixRotateX_asm
#define matrixRotateY matrixRotateY_asm
#define matrixRotateZ matrixRotateZ_asm
#define matrixRotateYXZ matrixRotateYXZ_asm
#define matrixRotateYQ matrixRotateYQ_asm
//#define boxTranslate boxTranslate_asm
//#define boxRotateYQ boxRotateYQ_asm
//#define boxIsVisible boxIsVisible_asm
//#define sphereIsVisible sphereIsVisible_asm
//#define flush flush_asm
extern "C"
{
void matrixPush_asm();
void matrixSetIdentity_asm();
void matrixSetBasis_asm(Matrix &dst, const Matrix &src);
void matrixLerp_asm(const Matrix &n, int32 pmul, int32 pdiv);
void matrixTranslateRel_asm(int32 x, int32 y, int32 z);
void matrixTranslateAbs_asm(int32 x, int32 y, int32 z);
void matrixTranslateSet_asm(int32 x, int32 y, int32 z);
void matrixRotateX_asm(int32 angle);
void matrixRotateY_asm(int32 angle);
void matrixRotateZ_asm(int32 angle);
void matrixRotateYQ_asm(int32 quadrant);
void matrixRotateYXZ_asm(int32 angleX, int32 angleY, int32 angleZ);
void boxTranslate_asm(AABBi &box, int32 x, int32 y, int32 z);
void boxRotateYQ_asm(AABBi &box, int32 quadrant);
int32 boxIsVisible_asm(const AABBs* box);
int32 sphereIsVisible_asm(int32 x, int32 y, int32 z, int32 r);
void flush_asm();
}
#endif
#define matrixPop() gMatrixPtr--

View File

@ -2739,12 +2739,12 @@ struct Lara : ItemObj
}
#elif defined(__32X__)
// 6 buttons
if (keys & IK_A) input |= IN_JUMP;
if (keys & IK_A) input |= IN_WEAPON;
if (keys & IK_B) input |= IN_ACTION;
if (keys & IK_C) input |= IN_WEAPON;
if (keys & IK_X) input |= IN_WALK;
if (keys & IK_C) input |= IN_JUMP;
if (keys & IK_X) input |= IN_LOOK;
if (keys & IK_Y) input |= IN_UP | IN_DOWN;
if (keys & IK_Z) input |= IN_LOOK;
if (keys & IK_Z) input |= IN_WALK;
#elif defined(__GBA__) || defined(_WIN32)
int32 ikA, ikB;

View File

@ -91,7 +91,15 @@
#define SH2_DMA_DMAOR (*(volatile unsigned long *)0xFFFFFFB0)
#define SH2_INT_ICR (*(volatile unsigned short *)0xFFFFFEE0)
#define SH2_INT_IPRA (*(volatile unsigned short *)0xFFFFFEE2)
#define SH2_INT_IPRB (*(volatile unsigned short *)0xFFFFFE60)
#define SH2_INT_VCRA (*(volatile unsigned short *)0xFFFFFE62)
#define SH2_INT_VCRB (*(volatile unsigned short *)0xFFFFFE64)
#define SH2_INT_VCRC (*(volatile unsigned short *)0xFFFFFE66)
#define SH2_INT_VCRD (*(volatile unsigned short *)0xFFFFFE68)
#define SH2_INT_VCRWDT (*(volatile unsigned short *)0xFFFFFEE4)
#define SH2_INT_VCRDIV (*(volatile unsigned long *)0xFFFFFF0C)
#define SEGA_CTRL_UP 0x0001
#define SEGA_CTRL_DOWN 0x0002
@ -116,6 +124,20 @@
#define MASTER_LOCK 4
#define SLAVE_LOCK 8
#define SH2_WDT_WTCNT 0x5A00
#define SH2_WDT_WTCSR (0xA500 | (1 << 3) | (1 << 4))
#define SH2_WDT_WTCSR_CKS_2 0
#define SH2_WDT_WTCSR_CKS_64 1
#define SH2_WDT_WTCSR_CKS_128 2
#define SH2_WDT_WTCSR_CKS_256 3
#define SH2_WDT_WTCSR_CKS_512 4
#define SH2_WDT_WTCSR_CKS_1024 5
#define SH2_WDT_WTCSR_CKS_4096 6
#define SH2_WDT_WTCSR_CKS_8192 7
#define SH2_WDT_WTCSR_TME (1 << 5)
#define SH2_WDT_WTCSR_WTIT (1 << 6)
#define SH2_WDT_WTCSR_OVF (1 << 7)
/* global functions in sh2_crt0.s */
extern "C"
{

View File

@ -0,0 +1,25 @@
#define M00 0
#define M01 4
#define M02 8
#define M03 12
#define M10 16
#define M11 20
#define M12 24
#define M13 28
#define M20 32
#define M21 36
#define M22 40
#define M23 44
#define FIXED_SHIFT 14
#define FACE_TYPE_F 1
#define VERTEX_X 0
#define VERTEX_Y 2
#define VERTEX_Z 4
#define VERTEX_G 6
#define VERTEX_CLIP 7
#define VERTEX_T 8
#define VERTEX_PREV 12
#define VERTEX_NEXT 13

View File

@ -0,0 +1,171 @@
#include "common.i"
.text
#define n r4 // arg
#define pmul r5 // arg
#define pdiv r6 // arg
#define m0 r0
#define m1 r1
#define m2 r2
#define n0 r3
#define n1 pdiv
#define n2 r7
#define m r14
#define tmp m0
#define divLUT m1
.macro load
mov.l @(0, m), m0
mov.l @(4, m), m1
mov.l @(8, m), m2
mov.l @(0, n), n0
mov.l @(4, n), n1
mov.l @(8, n), n2
.endm
.macro store
mov.l m0, @(0, m)
mov.l m1, @(4, m)
mov.l m2, @(8, m)
.endm
.macro next
add #16, m
add #16, n
.endm
.macro _1_2 // a = (a + b) / 2
load
add n0, m0
add n1, m1
add n2, m2
shar m0
shar m1
shar m2
store
.endm
.macro _1_4 // a = a + (b - a) / 4
load
sub m0, n0
sub m1, n1
sub m2, n2
shar n0
shar n1
shar n2
shar n0
shar n1
shar n2
add n0, m0
add n1, m1
add n2, m2
store
.endm
.macro _3_4 // a = b - (b - a) / 4 = b + (a - b) / 4
load
sub n0, m0
sub n1, m1
sub n2, m2
shar m0
shar m1
shar m2
shar m0
shar m1
shar m2
add n0, m0
add n1, m1
add n2, m2
store
.endm
.macro masr_8 x
mul.l \x, pmul
sts MACL, \x
shar \x
shar \x
shar \x
shar \x
shar \x
shar \x
shar \x
shar \x
.endm
.macro _X_Y // a = a + (b - a) * mul / div
load
sub m0, n0
sub m1, n1
sub m2, n2
masr_8 n0
masr_8 n1
masr_8 n2
add n0, m0
add n1, m1
add n2, m2
store
.endm
.macro lerp func
\func // e00, e01, e02
next
\func // e10, e11, e12
next
\func // e20, e21, e22
.endm
.align 4
.global _matrixLerp_asm
_matrixLerp_asm:
mov.l r14, @-sp
mov.l var_gMatrixPtr, m
mov.l @m, m
mov pdiv, tmp
.check_2:
cmp/eq #2, tmp
bf .check_XY
.m1_d2:
lerp _1_2
rts
mov.l @sp+, r14
.check_XY:
cmp/eq #4, tmp
bt .check_4
bra .mX_dY
nop
.check_4:
mov pmul, tmp
cmp/eq #2, tmp
bt .m1_d2 // 2/4 = 1/2
cmp/eq #1, tmp
bt .m1_d4
.m3_d4:
lerp _3_4
rts
mov.l @sp+, r14
.m1_d4:
lerp _1_4
rts
mov.l @sp+, r14
.mX_dY:
mov.l var_divTable, divLUT
mov.l @divLUT, divLUT
mov.w @(tmp, divLUT), tmp // tmp = pdiv
mul.l tmp, pmul
sts MACL, pmul
shlr8 pmul
lerp _X_Y
rts
mov.l @sp+, r14
nop
var_gMatrixPtr:
.long _gMatrixPtr
var_divTable:
.long _divTable

View File

@ -1,27 +1,36 @@
.macro COPY_ROW
mov.l @r0+, r1
mov.l @r0+, r2
mov.l @r0+, r3
mov.l @r0+, r4
mov.l r1, @(32, r0)
mov.l r2, @(36, r0)
mov.l r3, @(40, r0)
mov.l r4, @(44, r0)
.endm
#include "common.i"
.text
.align 4
#define ptr r0
#define x r1
#define y r2
#define z r3
#define w r4
#define m r5
.global _matrixPush_asm
.macro COPY_ROW
mov.l @m+, x
mov.l @m+, y
mov.l @m+, z
mov.l @m+, w
mov.l x, @(32, m)
mov.l y, @(36, m)
mov.l z, @(40, m)
mov.l w, @(44, m)
.endm
.align 4
.global _matrixPush_asm
_matrixPush_asm:
mov.l .var_matrixPtr, r5
mov.l @r5, r0
mov.l var_gMatrixPtr, ptr
mov.l @ptr, m
COPY_ROW /* row[0] */
COPY_ROW /* row[1] */
COPY_ROW /* row[2] */
COPY_ROW // row[0]
COPY_ROW // row[1]
COPY_ROW // row[2]
rts
mov.l r0, @r5
mov.l m, @ptr
.var_matrixPtr:
var_gMatrixPtr:
.long _gMatrixPtr

View File

@ -0,0 +1,244 @@
#include "common.i"
.text
.macro sincos idx, sin, cos
shll2 \idx
mov.l var_gSinCosTable, \sin
mov.l @(\idx, \sin), \sin
exts.w \sin, \cos
swap.w \sin, \sin
exts.w \sin, \sin
.endm
.macro rotxy x, y, sin, cos, tx, ty
mul.l \x, \sin
sts MACL, \tx
mul.l \y, \sin
sts MACL, \ty
mul.l \x, \cos
sts MACL, \x
mul.l \y, \cos
sts MACL, \y
sub \ty, \x
add \tx, \y
// int(x) >> (FIXED_SHIFT = 14)
shll2 \x
swap.w \x, \x
exts.w \x, \x
// int(y) >> (FIXED_SHIFT = 14)
shll2 \y
swap.w \y, \y
exts.w \y, \y
.endm
#define angleX r4 // arg
#define angleY r5 // arg
#define angleZ r6 // arg
#define tmpX r7 // unused in subroutines
#define tmpZ r8
#define arg angleX
.align 4
.global _matrixRotateYXZ_asm
_matrixRotateYXZ_asm:
mov.l r8, @-sp
sts.l pr, @-sp
mov angleX, tmpX
mov angleZ, tmpZ
.rotY:
tst angleY, angleY
bt .rotX
bsr _matrixRotateY_asm
mov angleY, arg
.rotX:
tst tmpX, tmpX
bt .rotZ
bsr _matrixRotateX_asm
mov tmpX, arg
.rotZ:
tst tmpZ, tmpZ
bt .done
bsr _matrixRotateZ_asm
mov tmpZ, arg
.done:
lds.l @sp+, pr
rts
mov.l @sp+, r8
nop
#define e0 r0
#define e1 r1
#define sin r2
#define cos r3
#define angle r4 // arg
#define tx r5
#define ty r6
#define idx e0
#define m angle
.align 4
.global _matrixRotateX_asm
_matrixRotateX_asm:
extu.w angle, idx
shlr2 idx
shlr2 idx
sincos idx, sin, cos
mov.l var_gMatrixPtr, m
mov.l @m, m
mov.l @(M01, m), e0
mov.l @(M02, m), e1
rotxy e1, e0, sin, cos, tx, ty
mov.l e0, @(M01, m)
mov.l e1, @(M02, m)
mov.l @(M11, m), e0
mov.l @(M12, m), e1
rotxy e1, e0, sin, cos, tx, ty
mov.l e0, @(M11, m)
mov.l e1, @(M12, m)
mov.l @(M21, m), e0
mov.l @(M22, m), e1
rotxy e1, e0, sin, cos, tx, ty
mov.l e0, @(M21, m)
rts
mov.l e1, @(M22, m)
.align 4
.global _matrixRotateY_asm
_matrixRotateY_asm:
extu.w angle, idx
shlr2 idx
shlr2 idx
sincos idx, sin, cos
mov.l var_gMatrixPtr, m
mov.l @m, m
mov.l @(M00, m), e0
mov.l @(M02, m), e1
rotxy e0, e1, sin, cos, tx, ty
mov.l e0, @(M00, m)
mov.l e1, @(M02, m)
mov.l @(M10, m), e0
mov.l @(M12, m), e1
rotxy e0, e1, sin, cos, tx, ty
mov.l e0, @(M10, m)
mov.l e1, @(M12, m)
mov.l @(M20, m), e0
mov.l @(M22, m), e1
rotxy e0, e1, sin, cos, tx, ty
mov.l e0, @(M20, m)
rts
mov.l e1, @(M22, m)
.align 4
.global _matrixRotateZ_asm
_matrixRotateZ_asm:
extu.w angle, idx
shlr2 idx
shlr2 idx
sincos idx, sin, cos
mov.l var_gMatrixPtr, m
mov.l @m, m
mov.l @(M00, m), e0
mov.l @(M01, m), e1
rotxy e1, e0, sin, cos, tx, ty
mov.l e0, @(M00, m)
mov.l e1, @(M01, m)
mov.l @(M10, m), e0
mov.l @(M11, m), e1
rotxy e1, e0, sin, cos, tx, ty
mov.l e0, @(M10, m)
mov.l e1, @(M11, m)
mov.l @(M20, m), e0
mov.l @(M21, m), e1
rotxy e1, e0, sin, cos, tx, ty
mov.l e0, @(M20, m)
rts
mov.l e1, @(M21, m)
#define q r0
#define n r1
#define e00 r2
#define e02 r3
#define qarg r4 // arg
#define e10 r5
#define e12 r6
#define e20 r7
#define e22 qarg
.align 4
.global _matrixRotateYQ_asm
_matrixRotateYQ_asm:
mov qarg, q
cmp/eq #2, q
bt/s .q_2
cmp/eq #1, q
mov.l var_gMatrixPtr, n
mov.l @n, n
mov.l @(M00, n), e00
mov.l @(M02, n), e02
mov.l @(M10, n), e10
mov.l @(M12, n), e12
mov.l @(M20, n), e20
bt/s .q_1
mov.l @(M22, n), e22
tst q, q
bt/s .q_0
neg e22, e22 // for q_0 and q_3
.q_3:
neg e02, e02
neg e12, e12
mov.l e02, @(M00, n)
mov.l e00, @(M02, n)
mov.l e12, @(M10, n)
mov.l e10, @(M12, n)
mov.l e22, @(M20, n)
mov.l e20, @(M22, n)
.q_2:
rts
nop
.q_0:
neg e00, e00
neg e02, e02
neg e10, e10
neg e12, e12
neg e20, e20
mov.l e00, @(M00, n)
mov.l e02, @(M02, n)
mov.l e10, @(M10, n)
mov.l e12, @(M12, n)
mov.l e20, @(M20, n)
rts
mov.l e22, @(M22, n)
.q_1:
neg e00, e00
neg e10, e10
neg e20, e20
mov.l e02, @(M00, n)
mov.l e00, @(M02, n)
mov.l e12, @(M10, n)
mov.l e10, @(M12, n)
mov.l e22, @(M20, n)
rts
mov.l e20, @(M22, n)
var_gMatrixPtr:
.long _gMatrixPtr
var_gSinCosTable:
.long _gSinCosTable

View File

@ -0,0 +1,44 @@
#include "common.i"
.text
#define dst r4
#define src r5
#define e00 r0
#define e01 r1
#define e02 r2
#define e10 r6
#define e11 e00
#define e12 e01
#define e20 e02
#define e21 e10
#define e22 e00
.align 4
.global _matrixSetBasis_asm
_matrixSetBasis_asm:
mov.l @(M00, src), e00
mov.l @(M01, src), e01
mov.l @(M02, src), e02
mov.l @(M10, src), e10
mov.l e00, @(M00, dst)
mov.l e01, @(M01, dst)
mov.l e02, @(M02, dst)
mov.l e10, @(M10, dst)
mov.l @(M11, src), e11
mov.l @(M12, src), e12
mov.l @(M20, src), e20
mov.l @(M21, src), e21
mov.l e11, @(M11, dst)
mov.l e12, @(M12, dst)
mov.l e20, @(M20, dst)
mov.l e21, @(M21, dst)
mov.l @(M22, src), e22
rts
mov.l e22, @(M22, dst)

View File

@ -0,0 +1,38 @@
#include "common.i"
.text
#define m r0
#define e0 r1
#define e1 r2
.align 4
.global _matrixSetIdentity_asm
_matrixSetIdentity_asm:
mov.l var_gMatrixPtr, m
mov.l @m, m
mov #0, e0
mov #64, e1
shll8 r1
// row[0]
mov.l e1, @(M00, m)
mov.l e0, @(M01, m)
mov.l e0, @(M02, m)
mov.l e0, @(M03, m)
// row[1]
mov.l e0, @(M10, m)
mov.l e1, @(M11, m)
mov.l e0, @(M12, m)
mov.l e0, @(M13, m)
// row[2]
mov.l e0, @(M20, m)
mov.l e0, @(M21, m)
mov.l e1, @(M22, m)
rts
mov.l e0, @(M23, m)
var_gMatrixPtr:
.long _gMatrixPtr

View File

@ -0,0 +1,149 @@
#include "common.i"
.text
#define m r0
#define e0 r1
#define e1 r2
#define e2 r3
#define x r4 // arg
#define y r5 // arg
#define z r6 // arg
#define v r7
.align 4
.global _matrixTranslateRel_asm
_matrixTranslateRel_asm:
mov.l var_gMatrixPtr, m
mov.l @m, m
mov #1, v
mov.l v, @-sp
mov.l z, @-sp
mov.l y, @-sp
mov.l x, @-sp
// x
clrmac
mov sp, v
mac.l @v+, @m+
mac.l @v+, @m+
mac.l @v+, @m+
mac.l @v+, @m+
sts.l MACL, @-m
add #4, m
// y
clrmac
mov sp, v
mac.l @v+, @m+
mac.l @v+, @m+
mac.l @v+, @m+
mac.l @v+, @m+
sts.l MACL, @-m
add #4, m
// z
clrmac
mov sp, v
mac.l @v+, @m+
mac.l @v+, @m+
mac.l @v+, @m+
mac.l @v+, @m+
sts.l MACL, @-m
rts
add #16, sp
.align 4
.global _matrixTranslateAbs_asm
_matrixTranslateAbs_asm:
mov.l var_gCameraViewPos, v
mov.l @v+, e0
mov.l @v+, e1
mov.l @v+, e2
sub e0, x
sub e1, y
sub e2, z
mov.l z, @-sp
mov.l y, @-sp
mov.l x, @-sp
mov.l var_gMatrixPtr, m
mov.l @m, m
// x
clrmac
mov sp, v
mac.l @v+, @m+
mac.l @v+, @m+
mac.l @v+, @m+
add #4, m
sts.l MACL, @-m
add #4, m
// y
clrmac
mov sp, v
mac.l @v+, @m+
mac.l @v+, @m+
mac.l @v+, @m+
add #4, m
sts.l MACL, @-m
add #4, m
// z
clrmac
mov sp, v
mac.l @v+, @m+
mac.l @v+, @m+
mac.l @v+, @m+
add #4, m
sts.l MACL, @-m
rts
add #12, sp
.align 4
.global _matrixTranslateSet_asm
_matrixTranslateSet_asm:
mov.l z, @-sp
mov.l y, @-sp
mov.l x, @-sp
mov.l var_gMatrixPtr, m
mov.l @m, m
// x
clrmac
mov sp, v
mac.l @v+, @m+
mac.l @v+, @m+
mac.l @v+, @m+
add #4, m
sts.l MACL, @-m
add #4, m
// y
clrmac
mov sp, v
mac.l @v+, @m+
mac.l @v+, @m+
mac.l @v+, @m+
add #4, m
sts.l MACL, @-m
add #4, m
// z
clrmac
mov sp, v
mac.l @v+, @m+
mac.l @v+, @m+
mac.l @v+, @m+
add #4, m
sts.l MACL, @-m
rts
add #12, sp
var_gMatrixPtr:
.long _gMatrixPtr
var_gCameraViewPos:
.long _gCameraViewPos

View File

@ -0,0 +1,8 @@
#include "common.i"
.text
.align 4
.global _rasterize_dummy_asm
_rasterize_dummy_asm:
rts
nop

View File

@ -5,6 +5,23 @@ extern void* LEVEL1_PKD;
#include "game.h"
volatile unsigned mars_frt_ovf_count = 0;
extern "C" {
volatile uint32 mars_pwdt_ovf_count = 0;
volatile uint32 mars_swdt_ovf_count = 0;
}
int32 gFrameIndex = 0;
#define SH2_WDT_RTCSR (*(volatile unsigned char *)0xFFFFFE80)
#define SH2_WDT_RTCNT (*(volatile unsigned char *)0xFFFFFE81)
#define SH2_WDT_RRSTCSR (*(volatile unsigned char *)0xFFFFFE83)
#define SH2_WDT_WTCSR_TCNT (*(volatile unsigned short *)0xFFFFFE80)
#define SH2_WDT_WRWOVF_RST (*(volatile unsigned short *)0xFFFFFE82)
#define SH2_WDT_VCR (*(volatile unsigned short *)0xFFFFFEE4)
int32 g_timer;
int32 fps;
void osSetPalette(const uint16* palette)
@ -15,7 +32,7 @@ void osSetPalette(const uint16* palette)
int32 osGetSystemTimeMS()
{
return 0;
return int32((mars_pwdt_ovf_count << 8) | SH2_WDT_RTCNT);
}
bool osSaveSettings()
@ -85,9 +102,44 @@ void pageFlip()
MARS_VDP_FBCTL = pageIndex;
}
extern "C" void slave(void)
extern "C" void pri_vbi_handler()
{
gFrameIndex++;
}
extern "C" void secondary()
{
// init DMA
SH2_DMA_SAR0 = 0;
SH2_DMA_DAR0 = 0;
SH2_DMA_TCR0 = 0;
SH2_DMA_CHCR0 = 0;
SH2_DMA_DRCR0 = 0;
SH2_DMA_SAR1 = 0;
SH2_DMA_DAR1 = 0;
SH2_DMA_TCR1 = 0;
SH2_DMA_CHCR1 = 0;
SH2_DMA_DRCR1 = 0;
SH2_DMA_DMAOR = 1; // enable DMA
SH2_DMA_VCR1 = 66; // set exception vector for DMA channel 1
SH2_INT_IPRA = (SH2_INT_IPRA & 0xF0FF) | 0x0400; // set DMA INT to priority 4
while (1)
{
int cmd;
while ((cmd = MARS_SYS_COMM4) == 0);
// TODO
MARS_SYS_COMM4 = 0;
}
}
extern "C" void sec_dma1_handler()
{
SH2_DMA_CHCR1; // read TE
SH2_DMA_CHCR1 = 0; // clear TE
}
int main()
@ -102,25 +154,37 @@ int main()
volatile uint16* lineTable = &MARS_FRAMEBUFFER;
uint16 wordOffset = 0x100;
for (int32 i = 0; i < 224; i++, wordOffset += FRAME_WIDTH / 2)
for (int32 i = 0; i < 256; i++)
{
lineTable[i] = wordOffset;
if (i < FRAME_HEIGHT - 1) {
wordOffset += FRAME_WIDTH / 2;
}
}
uint8* fb = (uint8*)(lineTable + 0x100);
memset(fb, 0, 0x10000 - 0x200);
clear();
}
SH2_WDT_VCR = (65<<8) | (SH2_WDT_VCR & 0x00FF); // set exception vector for WDT
SH2_INT_IPRA = (SH2_INT_IPRA & 0xFF0F) | 0x0020; // set WDT INT to priority 2
SH2_WDT_WTCSR_TCNT = 0x5A00;
SH2_WDT_WTCSR_TCNT = 0xA53E;
MARS_SYS_COMM4 = 0;
gameInit(gLevelInfo[gLevelID].name);
int32 lastFrame = (MARS_SYS_COMM12 >> 1) - 1;
int32 lastFrame = (gFrameIndex >> 1) - 1;
int32 fpsCounter = 0;
int32 fpsFrame = MARS_SYS_COMM12;
int32 fpsFrame = gFrameIndex;
int32 vsyncRate = (MARS_VDP_DISPMODE & MARS_NTSC_FORMAT) ? 60 : 50;
while (1)
{
int32 frame = MARS_SYS_COMM12;
int32 frame = gFrameIndex;
if (frame - fpsFrame >= vsyncRate)
{

View File

@ -6,9 +6,24 @@
extern uint8 gLightmap[256 * 32];
extern const uint8* gTile;
extern "C" {
void rasterize_dummy_asm(uint16* pixel, const VertexLink* L, const VertexLink* R);
void rasterizeS_asm(uint16* pixel, const VertexLink* L, const VertexLink* R);
void rasterizeF_asm(uint16* pixel, const VertexLink* L, const VertexLink* R);
void rasterizeFT_asm(uint16* pixel, const VertexLink* L, const VertexLink* R);
void rasterizeGT_asm(uint16* pixel, const VertexLink* L, const VertexLink* R);
void rasterizeFTA_asm(uint16* pixel, const VertexLink* L, const VertexLink* R);
void rasterizeGTA_asm(uint16* pixel, const VertexLink* L, const VertexLink* R);
void rasterizeLineH_asm(uint16* pixel, const VertexLink* L, const VertexLink* R);
void rasterizeLineV_asm(uint16* pixel, const VertexLink* L, const VertexLink* R);
void rasterizeFillS_asm(uint16* pixel, const VertexLink* L, const VertexLink* R);
}
#define rasterize_dummy rasterize_dummy_asm
// #define rasterizeF rasterizeF_asm
#define rasterizeS rasterizeS_c
#define rasterizeF rasterizeF_c
#define rasterizeG rasterizeG_c
#define rasterizeFT rasterizeFT_c
#define rasterizeGT rasterizeGT_c
#define rasterizeFTA rasterizeFTA_c
@ -18,7 +33,7 @@ extern const uint8* gTile;
#define rasterizeLineV rasterizeLineV_c
#define rasterizeFillS rasterizeFillS_c
void rasterizeS_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
extern "C" void rasterizeS_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
{
const uint8* ft_lightmap = &gLightmap[0x1A00];
@ -117,7 +132,7 @@ void rasterizeS_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
}
}
void rasterizeF_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
extern "C" void rasterizeF_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
{
uint32 color = (uint32)R;
color = gLightmap[(L->v.g << 8) | color];
@ -225,129 +240,7 @@ void rasterizeF_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
}
}
void rasterizeG_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
{
int32 Lh = 0, Rh = 0;
int32 Lx, Rx, Ldx = 0, Rdx = 0;
int32 Lg, Rg, Ldg = 0, Rdg = 0;
const uint8* ft_lightmap = gLightmap + L->t.t;
while (1)
{
while (!Lh)
{
const VertexLink* N = L + L->prev;
if (N->v.y < L->v.y) return;
Lh = N->v.y - L->v.y;
Lx = L->v.x;
Lg = L->v.g;
if (Lh > 1)
{
int32 tmp = FixedInvU(Lh);
Ldx = tmp * (N->v.x - Lx);
Ldg = tmp * (N->v.g - Lg);
}
Lx <<= 16;
Lg <<= 16;
L = N;
}
while (!Rh)
{
const VertexLink* N = R + R->next;
if (N->v.y < R->v.y) return;
Rh = N->v.y - R->v.y;
Rx = R->v.x;
Rg = R->v.g;
if (Rh > 1)
{
int32 tmp = FixedInvU(Rh);
Rdx = tmp * (N->v.x - Rx);
Rdg = tmp * (N->v.g - Rg);
}
Rx <<= 16;
Rg <<= 16;
R = N;
}
int32 h = X_MIN(Lh, Rh);
Lh -= h;
Rh -= h;
while (h--)
{
int32 x1 = Lx >> 16;
int32 x2 = Rx >> 16;
int32 width = x2 - x1;
if (width > 0)
{
int32 tmp = FixedInvU(width);
int32 dgdx = tmp * ((Rg - Lg) >> 5) >> 10;
int32 g = Lg;
volatile uint8* ptr = (uint8*)pixel + x1;
if (intptr_t(ptr) & 1)
{
*ptr++ = ft_lightmap[g >> 16 << 8];
g += dgdx >> 1;
width--;
}
if (width & 1)
{
ptr[width - 1] = ft_lightmap[Rg >> 16 << 8];
}
if (width & 2)
{
uint8 p = ft_lightmap[g >> 16 << 8];
g += dgdx;
*(uint16*)ptr = p | (p << 8);
ptr += 2;
}
width >>= 2;
while (width--)
{
uint8 p;
p = ft_lightmap[g >> 16 << 8];
*(uint16*)ptr = p | (p << 8);
g += dgdx;
ptr += 2;
p = ft_lightmap[g >> 16 << 8];
*(uint16*)ptr = p | (p << 8);
g += dgdx;
ptr += 2;
}
}
pixel += VRAM_WIDTH;
Lx += Ldx;
Rx += Rdx;
Lg += Ldg;
Rg += Rdg;
}
}
}
void rasterizeFT_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
extern "C" void rasterizeFT_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
{
const uint8* ft_lightmap = &gLightmap[L->v.g << 8];
@ -474,7 +367,7 @@ void rasterizeFT_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
}
}
void rasterizeGT_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
extern "C" void rasterizeGT_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
{
#ifdef ALIGNED_LIGHTMAP
ASSERT((intptr_t(gLightmap) & 0xFFFF) == 0); // lightmap should be 64k aligned
@ -635,7 +528,7 @@ void rasterizeGT_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
}
}
void rasterizeFTA_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
extern "C" void rasterizeFTA_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
{
const uint8* ft_lightmap = &gLightmap[L->v.g << 8];
@ -781,12 +674,12 @@ void rasterizeFTA_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
}
}
void rasterizeGTA_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
extern "C" void rasterizeGTA_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
{
rasterizeFTA(pixel, L, R);
}
void rasterizeSprite_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
extern "C" void rasterizeSprite_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
{
R++;
const uint8* ft_lightmap = &gLightmap[L->v.g << 8];
@ -838,6 +731,16 @@ void rasterizeSprite_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
if (w <= 0) return;
bool alignL = intptr_t(ptr) & 1;
if (alignL)
{
w--;
}
bool alignR = w & 1;
w >>= 1;
for (int32 y = 0; y < h; y++)
{
const uint8* xtile = gTile + (v & 0xFF00);
@ -846,9 +749,7 @@ void rasterizeSprite_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
int32 xu = u;
int32 width = w;
if (intptr_t(xptr) & 1)
if (alignL)
{
uint8 indexB = xtile[xu >> 8];
if (indexB) {
@ -856,20 +757,10 @@ void rasterizeSprite_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
}
xptr++;
xu += du;
}
if (width & 1)
{
width--;
uint8 indexA = xtile[xu >> 8];
if (indexA) {
xptr[width] = ft_lightmap[indexA];
}
}
for (int32 x = 0; x < width / 2; x++)
for (int32 x = 0; x < w; x++)
{
uint8 indexA = xtile[xu >> 8];
xu += du;
@ -890,13 +781,21 @@ void rasterizeSprite_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
xptr += 2;
}
if (alignR)
{
uint8 indexA = xtile[xu >> 8];
if (indexA) {
*xptr = ft_lightmap[indexA];
}
}
v += dv;
ptr += FRAME_WIDTH;
}
}
void rasterizeLineH_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
extern "C" void rasterizeLineH_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
{
R++;
int32 x = L->v.x;
@ -926,7 +825,7 @@ void rasterizeLineH_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
}
}
void rasterizeLineV_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
extern "C" void rasterizeLineV_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
{
R++;
int32 x = L->v.x;
@ -942,7 +841,7 @@ void rasterizeLineV_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
}
}
void rasterizeFillS_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
extern "C" void rasterizeFillS_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
{
R++;
int32 x = L->v.x;

View File

@ -123,6 +123,17 @@ extern "C" {
X_NOINLINE void drawQuad(uint32 flags, VertexLink* v);
}
extern "C" {
void transformRoom_asm(const RoomVertex* vertices, int32 count);
void transformRoomUW_asm(const RoomVertex* vertices, int32 count);
void transformMesh_asm(const MeshVertex* vertices, int32 count, int32 intensity);
void faceAddRoomQuads_asm(const RoomQuad* polys, int32 count);
void faceAddRoomTriangles_asm(const RoomTriangle* polys, int32 count);
void faceAddMeshQuads_asm(const MeshQuad* polys, int32 count);
void faceAddMeshTriangles_asm(const MeshTriangle* polys, int32 count);
void rasterize_asm(uint32 flags, VertexLink* top);
}
#ifdef USE_ASM
#define transformRoom transformRoom_asm
#define transformRoomUW transformRoomUW_asm
@ -133,16 +144,7 @@ extern "C" {
#define faceAddMeshTriangles faceAddMeshTriangles_asm
#define rasterize rasterize_asm
extern "C" {
void transformRoom_asm(const RoomVertex* vertices, int32 count);
void transformRoomUW_asm(const RoomVertex* vertices, int32 count);
void transformMesh_asm(const MeshVertex* vertices, int32 count, int32 intensity);
void faceAddRoomQuads_asm(const RoomQuad* polys, int32 count);
void faceAddRoomTriangles_asm(const RoomTriangle* polys, int32 count);
void faceAddMeshQuads_asm(const MeshQuad* polys, int32 count);
void faceAddMeshTriangles_asm(const MeshTriangle* polys, int32 count);
void rasterize_asm(uint32 flags, VertexLink* top);
}
#else
#define transformRoom transformRoom_c
#define transformRoomUW transformRoomUW_c
@ -151,7 +153,8 @@ extern "C" {
#define faceAddRoomTriangles faceAddRoomTriangles_c
#define faceAddMeshQuads faceAddMeshQuads_c
#define faceAddMeshTriangles faceAddMeshTriangles_c
#define rasterize rasterize_c
//#define rasterize rasterize_c
#define rasterize rasterize_asm
X_INLINE bool checkBackface(const Vertex *a, const Vertex *b, const Vertex *c)
{
@ -619,7 +622,7 @@ int32 sphereIsVisible_c(int32 sx, int32 sy, int32 sz, int32 r)
typedef void (*RasterProc)(uint16* pixel, const VertexLink* L, const VertexLink* R);
RasterProc gRasterProc[FACE_TYPE_MAX] = { // IWRAM
extern "C" const RasterProc gRasterProc[FACE_TYPE_MAX] = { // IWRAM
rasterizeS,
rasterizeF,
rasterizeFT,
@ -960,12 +963,18 @@ void faceAddMesh(const MeshQuad* quads, const MeshTriangle* triangles, int32 qCo
void clear()
{
#if 1
MARS_VDP_FILLEN = 0xFF;
for(int32 i = 0x100; i < 0x100 + (FRAME_WIDTH * FRAME_HEIGHT >> 1); i += 0xFF)
MARS_VDP_FILADR = 0x100; // skip line table
for(int32 i = 0; i < (FRAME_WIDTH * FRAME_HEIGHT) >> 9; i++)
{
MARS_VDP_FILADR = i;
MARS_VDP_FILDAT = 0x0000;
while (MARS_VDP_FBCTL & MARS_VDP_FEN);
MARS_VDP_FILADR += 0x100;
}
#else
dmaFill((void*)fb, 0, FRAME_WIDTH * FRAME_HEIGHT);
#endif
}
void renderRoom(const Room* room)