1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-03-13 23:59:41 +01:00

#368 ARM version for flush and rasterize functions (4% boost)

This commit is contained in:
XProger 2022-02-04 09:40:12 +03:00
parent 889d3af918
commit 48e57ece0e
25 changed files with 559 additions and 251 deletions

View File

@ -29,7 +29,7 @@ EWRAM_DATA const char* const* STR = STR_EN;
EWRAM_DATA ExtraInfoLara playersExtra[MAX_PLAYERS];
#ifdef __GBA__
#if defined(__GBA__)
#include "TRACKS_IMA.h"
#include "TITLE_SCR.h"
#include "TITLE_PKD.h"
@ -1230,7 +1230,7 @@ void matrixLerp_c(const Matrix &n, int32 pmul, int32 pdiv)
}
}
#define MATRIX_TRANSLATE(x,y,z)\
#define MATRIX_TRANS(x,y,z)\
Matrix &m = matrixGet();\
int32 tx = DP33(m.e00, m.e01, m.e02, x, y, z);\
int32 ty = DP33(m.e10, m.e11, m.e12, x, y, z);\
@ -1238,7 +1238,7 @@ void matrixLerp_c(const Matrix &n, int32 pmul, int32 pdiv)
void matrixTranslateRel_c(int32 x, int32 y, int32 z)
{
MATRIX_TRANSLATE(x, y, z);
MATRIX_TRANS(x, y, z);
m.e03 += tx;
m.e13 += ty;
m.e23 += tz;
@ -1249,7 +1249,7 @@ void matrixTranslateAbs_c(int32 x, int32 y, int32 z)
x -= gCameraViewPos.x;
y -= gCameraViewPos.y;
z -= gCameraViewPos.z;
MATRIX_TRANSLATE(x, y, z);
MATRIX_TRANS(x, y, z);
m.e03 = tx;
m.e13 = ty;
m.e23 = tz;
@ -1257,7 +1257,7 @@ void matrixTranslateAbs_c(int32 x, int32 y, int32 z)
void matrixTranslateSet_c(int32 x, int32 y, int32 z)
{
MATRIX_TRANSLATE(x, y, z);
MATRIX_TRANS(x, y, z);
m.e03 = tx;
m.e13 = ty;
m.e23 = tz;
@ -1587,6 +1587,7 @@ void dmaFill(void* dst, uint8 value, uint32 count)
#endif
}
#ifndef __NDS__
void dmaCopy(const void* src, void* dst, uint32 size)
{
ASSERT((size & 3) == 0);
@ -1596,3 +1597,4 @@ void dmaCopy(const void* src, void* dst, uint32 size)
memcpy(dst, src, size);
#endif
}
#endif

View File

@ -20,6 +20,7 @@
#define USE_DIV_TABLE
#define ROM_READ
#define USE_ASM
#define ALIGNED_LIGHTMAP
#include <tonc.h>
#elif defined(__NDS__)
@ -410,8 +411,10 @@ extern int32 fps;
#define SND_MAX 127
#endif
#ifdef __3DO__
#if defined(__3DO__)
#define MAX_VERTICES (1024 + 32) // for mesh (max = LEVEL10A room:58)
#elif defined(__GBA__)
#define MAX_VERTICES (5*1024) // for frame (max is 8191 - check the assumption in flush.s)
#else
#define MAX_VERTICES (5*1024) // for frame
#endif
@ -428,6 +431,7 @@ extern int32 fps;
#define MAX_CAMERAS 16
#define MAX_BOXES 1024
#define MAX_TEXTURES 1536
#define MAX_SPRITES 180
#define MAX_FACES 1920
#define MAX_ROOM_LIST 16
#define MAX_PORTALS 16
@ -710,8 +714,8 @@ struct Face
#else
struct Face
{
Face* next;
uint32 flags;
Face* next;
uint16 indices[4];
};
#endif
@ -1005,9 +1009,9 @@ struct Texture
uint8* data;
uint32 shift;
#else
uint16 attribute;
uint16 tile;
uint32 uv[4];
uint32 tile;
uint32 uv01;
uint32 uv23;
#endif
};
@ -1017,9 +1021,8 @@ struct Sprite
uint32 texture;
int32 l, t, r, b;
#else
uint16 tile;
uint8 u, v;
uint8 w, h;
uint32 tile;
uint32 uwvh;
int16 l, t, r, b;
#endif
};
@ -1998,11 +2001,11 @@ struct Level
uint16 soundSourcesCount;
uint16 boxesCount;
uint16 texturesCount;
uint16 spritesCount;
uint16 itemsCount;
uint16 camerasCount;
uint16 cameraFramesCount;
uint16 soundOffsetsCount;
uint16 _reserved;
const uint16* palette;
const uint8* lightmap;
@ -2020,7 +2023,7 @@ struct Level
const Model* models;
const StaticMesh* staticMeshes;
Texture* textures;
const Sprite* sprites;
Sprite* sprites;
const SpriteSeq* spriteSequences;
FixedCamera* cameras;
uint32 soundSources;
@ -2578,6 +2581,7 @@ vec3i boxPushOut(const AABBi &a, const AABBi &b);
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();
}
#define matrixPush matrixPush_asm
@ -2596,6 +2600,7 @@ vec3i boxPushOut(const AABBi &a, const AABBi &b);
#define boxRotateYQ boxRotateYQ_asm
#define boxIsVisible boxIsVisible_asm
#define sphereIsVisible sphereIsVisible_asm
#define flush flush_asm
#else
#define matrixPush matrixPush_c
#define matrixSetIdentity matrixSetIdentity_c
@ -2613,6 +2618,7 @@ vec3i boxPushOut(const AABBi &a, const AABBi &b);
#define boxRotateYQ boxRotateYQ_c
#define boxIsVisible boxIsVisible_c
#define sphereIsVisible sphereIsVisible_c
#define flush flush_c
void matrixPush_c();
void matrixSetIdentity_c();
@ -2631,6 +2637,7 @@ vec3i boxPushOut(const AABBi &a, const AABBi &b);
void boxRotateYQ_c(AABBi &box, int32 quadrant);
int32 boxIsVisible_c(const AABBs* box);
int32 sphereIsVisible_c(int32 x, int32 y, int32 z, int32 r);
void flush_c();
#endif
#define matrixPop() gMatrixPtr--
@ -2655,7 +2662,6 @@ void renderSprite(int32 vx, int32 vy, int32 vz, int32 vg, int32 index);
void renderGlyph(int32 vx, int32 vy, int32 index);
void renderBorder(int32 x, int32 y, int32 width, int32 height, int32 shade, int32 color1, int32 color2, int32 z);
void renderBar(int32 x, int32 y, int32 width, int32 value, BarType type);
void flush();
void renderBackground(const void* background);
void* copyBackground();

View File

@ -730,6 +730,8 @@ void drawRoom(const Room* room)
void drawRooms(Camera* camera)
{
RectMinMax vp = viewport;
camera->view.room->clip = viewport;
Room** visRoom = camera->view.room->getVisibleRooms();
@ -765,12 +767,8 @@ void drawRooms(Camera* camera)
}
}
#ifndef MODEHW
flush();
#endif
setPaletteIndex(0);
setViewport(camera->view.room->clip);
setViewport(vp);
}
void drawHUD(Lara* lara)

View File

@ -937,6 +937,11 @@ int32 ItemObj::getSpheres(Sphere* spheres, bool flag) const
#include "enemy.h"
#include "object.h"
#ifdef __GBA__
// ItemObj ctor is called on existing and pre-filled memory
#pragma GCC diagnostic ignored "-Wuninitialized"
#endif
ItemObj::ItemObj(Room* room)
{
angle.x = 0;
@ -945,7 +950,7 @@ ItemObj::ItemObj(Room* room)
hSpeed = 0;
nextItem = NULL;
nextActive = NULL;
animIndex = level.models[type].animIndex; // ignore this warning, it's initialized
animIndex = level.models[type].animIndex;
frameIndex = level.anims[animIndex].frameBegin;
state = uint8(level.anims[animIndex].state);
nextState = state;
@ -955,8 +960,17 @@ ItemObj::ItemObj(Room* room)
hitMask = 0;
visibleMask = 0xFFFFFFFF;
flags &= (ITEM_FLAG_ONCE | ITEM_FLAG_MASK); // and this...
flags |= ITEM_FLAG_COLLISION;
flags &= (ITEM_FLAG_ONCE | ITEM_FLAG_MASK);
if ((type == ITEM_BRIDGE_FLAT) ||
(type == ITEM_BRIDGE_TILT_1) ||
(type == ITEM_BRIDGE_TILT_2) ||
(type == ITEM_TRAP_FLOOR))
{
// no collision
} else {
flags |= ITEM_FLAG_COLLISION;
}
if (flags & ITEM_FLAG_ONCE) // once -> invisible
{
@ -978,6 +992,10 @@ ItemObj::ItemObj(Room* room)
room->add(this);
}
#ifdef __GBA__
#pragma GCC diagnostic warning "-Wuninitialized"
#endif
void ItemObj::update()
{
//

View File

@ -7,13 +7,14 @@
Level level;
#ifndef MODEHW
IWRAM_DATA uint8 lightmap[256 * 32]; // IWRAM 8k
IWRAM_DATA uint8 gLightmap[256 * 32]; // IWRAM 8k
#endif
EWRAM_DATA ItemObj items[MAX_ITEMS];
#ifdef ROM_READ
EWRAM_DATA Texture textures[MAX_TEXTURES]; // animated textures require memory swap
EWRAM_DATA Sprite sprites[MAX_SPRITES];
EWRAM_DATA FixedCamera cameras[MAX_CAMERAS];
EWRAM_DATA Box boxes[MAX_BOXES];
#endif
@ -62,7 +63,7 @@ void readLevel_GBA(const uint8* data)
// initialize global pointers
gBrightness = -128;
palSet(level.palette, gSettings.video_gamma << 4, gBrightness);
memcpy(lightmap, level.lightmap, sizeof(lightmap));
memcpy(gLightmap, level.lightmap, sizeof(gLightmap));
#endif
// prepare models // TODO prerocess
@ -111,6 +112,10 @@ void readLevel_GBA(const uint8* data)
memcpy(textures, level.textures, level.texturesCount * sizeof(Texture));
level.textures = textures;
// prepare sprites (TODO preprocess tile address in packer)
memcpy(sprites, level.sprites, level.spritesCount * sizeof(Sprite));
level.sprites = sprites;
// prepare boxes
memcpy(boxes, level.boxes, level.boxesCount * sizeof(Box));
level.boxes = boxes;
@ -126,6 +131,17 @@ void readLevel_GBA(const uint8* data)
Texture* tex = level.textures + i;
tex->data += intptr_t(RAM_TEX);
}
#else
// TODO preprocess in packer
for (int32 i = 0; i < level.texturesCount; i++)
{
level.textures[i].tile += (uint32)level.tiles;
}
for (int32 i = 0; i < level.spritesCount; i++)
{
level.sprites[i].tile += (uint32)level.tiles;
}
#endif
}

View File

@ -3,6 +3,9 @@
#define TEX_2PX // lazy texturing, comment out for per-pixel
#define FRAME_WIDTH 240
#define FRAME_HEIGHT 160
.equ VERTEX_X, 0
.equ VERTEX_Y, 2
.equ VERTEX_Z, 4
@ -13,14 +16,21 @@
.equ VERTEX_NEXT, 16
.equ VERTEX_SIZEOF, 20
.equ LEVEL_TILES, 40
.equ LEVEL_TEXTURES, 92
.equ LEVEL_SPRITES, 96
.equ SPRITE_SIZE, 16
.equ TEXTURE_TILE, 2
.equ TEXTURE_UV01, 4
.equ TEXTURE_UV23, 8
.equ EWRAM_START, 0x2000000
.equ IWRAM_START, 0x3000000
.equ VRAM_START, 0x6000000
.equ VRAM_PAGE, 0x000A000
.equ FRAME_WIDTH, 240
.equ FRAME_HEIGHT, 160
.equ DIVLUT_ADDR, EWRAM_START
.equ LMAP_ADDR, IWRAM_START
@ -33,9 +43,30 @@
.equ CLIP_MASK_VP, (CLIP_LEFT + CLIP_RIGHT + CLIP_TOP + CLIP_BOTTOM)
.equ CLIP_MASK, (CLIP_MASK_VP + CLIP_FAR + CLIP_NEAR)
.equ FACE_TYPE_SHIFT, 11
.equ FACE_FLAT_ADD, (2 << FACE_TYPE_SHIFT)
.equ FACE_CLIPPED, (1 << 16)
.equ FACE_TEXTURE_BITS, 13
.equ FACE_TRIANGLE, (1 << FACE_TEXTURE_BITS)
.equ FACE_TEXTURE, ((1 << FACE_TEXTURE_BITS) - 1)
.equ FACE_FLAGS, 0
.equ FACE_NEXT, 4
.equ FACE_INDICES, 8
.equ FACE_TYPE_SHIFT, 14
.equ FACE_TYPE_MASK, (15 << FACE_TYPE_SHIFT)
.equ FACE_TYPE_SHADOW, (0 << FACE_TYPE_SHIFT)
.equ FACE_TYPE_F, (1 << FACE_TYPE_SHIFT)
.equ FACE_TYPE_FT, (2 << FACE_TYPE_SHIFT)
.equ FACE_TYPE_FTA, (3 << FACE_TYPE_SHIFT)
.equ FACE_TYPE_GT, (4 << FACE_TYPE_SHIFT)
.equ FACE_TYPE_GTA, (5 << FACE_TYPE_SHIFT)
.equ FACE_TYPE_SPRITE, (6 << FACE_TYPE_SHIFT)
.equ FACE_TYPE_FILL_S, (7 << FACE_TYPE_SHIFT)
.equ FACE_TYPE_LINE_H, (8 << FACE_TYPE_SHIFT)
.equ FACE_TYPE_LINE_V, (9 << FACE_TYPE_SHIFT)
.equ FACE_GOURAUD, (2 << FACE_TYPE_SHIFT)
.equ FACE_CLIPPED, (1 << 18)
.equ FIXED_SHIFT, 14
.equ PROJ_SHIFT, 4
@ -49,6 +80,8 @@
.equ VIEW_MAX, (VIEW_DIST)
.equ VIEW_OFF, 4096
.equ OT_SIZE, 641
.equ VIEW_MIN_F, (VIEW_MIN << FIXED_SHIFT)
.equ VIEW_MAX_F, (VIEW_MAX << FIXED_SHIFT)
.equ VIEW_OFF_F, (VIEW_OFF << FIXED_SHIFT)

View File

@ -30,7 +30,7 @@ depth .req vg0
ot .req vg1
vertices .req vg2
next .req vg3
next .req vp0
SP_OT = 0
SP_VERTICES = 4
@ -109,7 +109,7 @@ faceAddMeshQuads_asm:
ldr next, [ot, depth, lsl #2]
str face, [ot, depth, lsl #2]
stmia face!, {next, flags, vp1, vp3}
stmia face!, {flags, next, vp1, vp3}
.skip:
subs count, count, #1
bne .loop

View File

@ -28,7 +28,7 @@ vz2 .req vg2
depth .req vg0
ot .req vg1
next .req vg2
next .req vp0
.global faceAddMeshTriangles_asm
faceAddMeshTriangles_asm:
@ -92,7 +92,7 @@ faceAddMeshTriangles_asm:
ldr ot, =gOT
ldr next, [ot, depth, lsl #2]
str face, [ot, depth, lsl #2]
stmia face!, {next, flags, vp1, vp2}
stmia face!, {flags, next, vp1, vp2}
.skip:
subs count, count, #1
bne .loop

View File

@ -30,7 +30,7 @@ depth .req vg0
ot .req vg1
vertices .req vg2
next .req vg3
next .req vp0
SP_OT = 0
SP_VERTICES = 4
@ -87,7 +87,7 @@ faceAddRoomQuads_asm:
cmp vg0, vg1, lsl #24
cmpeq vg0, vg2, lsl #24
cmpeq vg0, vg3, lsl #24
addeq flags, flags, #FACE_FLAT_ADD
addne flags, flags, #FACE_GOURAUD
CCW .skip
@ -119,7 +119,7 @@ faceAddRoomQuads_asm:
ldr next, [ot, depth, lsl #2]
str face, [ot, depth, lsl #2]
stmia face!, {next, flags, vp1, vp3}
stmia face!, {flags, next, vp1, vp3}
.skip:
subs count, count, #1
bne .loop

View File

@ -28,7 +28,7 @@ vz2 .req vg2
depth .req vg0
ot .req vg1
next .req vg2
next .req vp0
.global faceAddRoomTriangles_asm
faceAddRoomTriangles_asm:
@ -73,7 +73,7 @@ faceAddRoomTriangles_asm:
mov vg0, vg0, lsl #24
cmp vg0, vg1, lsl #24
cmpeq vg0, vg2, lsl #24
addeq flags, flags, #FACE_FLAT_ADD
addne flags, flags, #FACE_GOURAUD
CCW .skip
@ -99,7 +99,7 @@ faceAddRoomTriangles_asm:
ldr ot, =gOT
ldr next, [ot, depth, lsl #2]
str face, [ot, depth, lsl #2]
stmia face!, {next, flags, vp1, vp2}
stmia face!, {flags, next, vp1, vp2}
.skip:
subs count, count, #1
bne .loop

View File

@ -0,0 +1,187 @@
#include "common_asm.inc"
flags .req r0 // flags is always in r0 for rasterize & draw* calls
vXY .req r1
vZG .req r2
tmp .req r3
OT .req r4
list .req r5
face .req r6
VERTICES .req r7
TEXTURES .req r8
SPRITES .req r9
TILE .req r10
MASK .req r11
index01 .req r12
index23 .req lr
faces .req vXY
uv01 .req index01
uv23 .req index23
uwvh .req index01
verticesBase .req vZG
facesBase .req vZG
vertex .req vZG
texture .req tmp
texIndex .req tmp
texTile .req tmp
sprite .req tmp
sprIndex .req tmp
sprTile .req tmp
type .req tmp
zero .req tmp
uv .req tmp
vXY0 .req vXY
vZG0 .req vZG
vXY1 .req index01
vZG1 .req index23
SP_SIZE = (16 * VERTEX_SIZEOF)
.extern rasterize_c, drawTriangle, drawQuad, drawPoly
.global flush_asm
flush_asm:
stmfd sp!, {r4-r11, lr}
ldr verticesBase, =gVerticesBase
ldr VERTICES, =gVertices
str VERTICES, [verticesBase]
ldr tmp, =gFacesBase
ldr faces, =gFaces
ldr facesBase, [tmp]
cmp facesBase, faces
ldmeqfd sp!, {r4-r11, lr}
bxeq lr
str faces, [tmp]
ldr tmp, =level
ldr TILE, =gTile
ldr TEXTURES, [tmp, #LEVEL_TEXTURES]
ldr SPRITES, [tmp, #LEVEL_SPRITES]
ldr OT, =gOT
add list, OT, #((OT_SIZE - 1) << 2)
mov MASK, #0xFF00
orr MASK, MASK, MASK, lsl #16
sub sp, #SP_SIZE
.loop_ot:
ldr face, [list], #-4 // read the first face from the list and decrement
cmp face, #0
beq .next_ot // list is empty, go next
mov zero, #0
str zero, [list, #4] // reset the list pointer in OT
.loop_list:
ldmia face, {flags, face, index01, index23} // read face params and next face
and type, flags, #FACE_TYPE_MASK
.draw_primitive: // shadows, triangles, quads and clipped polys
cmp type, #FACE_TYPE_GTA
bgt .draw_sprite
.set_vertices:
// 1st vertex
mov vertex, index01, lsl #16
add vertex, VERTICES, vertex, lsr #(16 - 3)
ldmia vertex, {vXY, vZG}
stmia sp, {vXY, vZG}
// 2nd vertex
add vertex, VERTICES, index01, lsr #(16 - 3) // assumption: vertex index will never exceed 8191
ldmia vertex, {vXY, vZG}
str vXY, [sp, #(VERTEX_X + VERTEX_SIZEOF * 1)]
str vZG, [sp, #(VERTEX_Z + VERTEX_SIZEOF * 1)]
// 3rd vertex
mov vertex, index23, lsl #16
add vertex, VERTICES, vertex, lsr #(16 - 3)
ldmia vertex, {vXY, vZG}
str vXY, [sp, #(VERTEX_X + VERTEX_SIZEOF * 2)]
str vZG, [sp, #(VERTEX_Z + VERTEX_SIZEOF * 2)]
// 4th vertex (quads only)
tst flags, #FACE_TRIANGLE
addeq vertex, VERTICES, index23, lsr #(16 - 3)
ldmeqia vertex, {vXY, vZG}
streq vXY, [sp, #(VERTEX_X + VERTEX_SIZEOF * 3)]
streq vZG, [sp, #(VERTEX_Z + VERTEX_SIZEOF * 3)]
// skip texturing for FACE_TYPE_SHADOW and FACE_TYPE_F
cmp type, #FACE_TYPE_F
ble .draw
.set_texture:
mov texIndex, flags, lsl #(32 - FACE_TEXTURE_BITS)
add texIndex, texIndex, texIndex, lsl #1
add texture, TEXTURES, texIndex, lsr #(32 - FACE_TEXTURE_BITS - 2)
ldmia texture, {texTile, uv01, uv23}
str texTile, [TILE]
and uv, MASK, uv01
str uv, [sp, #(VERTEX_T + VERTEX_SIZEOF * 0)]
and uv, MASK, uv01, lsl #8
str uv, [sp, #(VERTEX_T + VERTEX_SIZEOF * 1)]
and uv, MASK, uv23
str uv, [sp, #(VERTEX_T + VERTEX_SIZEOF * 2)]
and uv, MASK, uv23, lsl #8
str uv, [sp, #(VERTEX_T + VERTEX_SIZEOF * 3)]
.draw:
// r0 = flags
mov r1, sp
adr lr, .next_face
tst flags, #FACE_CLIPPED
bne drawPoly
tst flags, #FACE_TRIANGLE
bne drawTriangle
beq drawQuad
.draw_sprite: // sprites and gui elements
mov vertex, index01, lsl #16
add vertex, VERTICES, vertex, lsr #(16 - 3)
ldmia vertex, {vXY0, vZG0, vXY1, vZG1}
stmia sp, {vXY0, vZG0}
str vXY1, [sp, #(VERTEX_X + VERTEX_SIZEOF * 1)]
str vZG1, [sp, #(VERTEX_Z + VERTEX_SIZEOF * 1)]
// r0 = flags
mov r1, sp
adr lr, .next_face
// gui
cmp type, #FACE_TYPE_SPRITE
bne rasterize_asm
// sprite
and sprIndex, flags, #0xFF
add sprite, SPRITES, sprIndex, lsl #4
ldmia sprite, {sprTile, uwvh}
str sprTile, [TILE]
and uv, uwvh, MASK
str uv, [sp, #(VERTEX_T + VERTEX_SIZEOF * 0)]
bic uv, uwvh, MASK
str uv, [sp, #(VERTEX_T + VERTEX_SIZEOF * 1)]
b rasterize_asm
.next_face:
cmp face, #0
bne .loop_list
.next_ot:
cmp list, OT
bge .loop_ot
add sp, #SP_SIZE
ldmfd sp!, {r4-r11, lr}
bx lr

View File

@ -0,0 +1,52 @@
#include "common_asm.inc"
flags .req r0
top .req r1
y .req r2
width .req r3
pixel .req flags
type .req r12
.extern rasterizeS_asm
.extern rasterizeF_asm
.extern rasterizeFT_asm
.extern rasterizeFTA_asm
.extern rasterizeGT_asm
.extern rasterizeGTA_asm
.extern rasterizeSprite_c
.extern rasterizeFillS_asm
.extern rasterizeLineH_asm
.extern rasterizeLineV_asm
.extern rasterize_dummy
.global rasterize_asm
rasterize_asm:
and type, flags, #FACE_TYPE_MASK
cmp type, #FACE_TYPE_F
streqb flags, [top, #VERTEX_CLIP]
ldr pixel, =fb
ldr pixel, [pixel]
ldrsh y, [top, #VERTEX_Y]
#if (FRAME_WIDTH == 240) // pixel += (y * 16 - y) * 16
rsb y, y, y, lsl #4
add pixel, pixel, y, lsl #4
#else
mov width, #FRAME_WIDTH
mla pixel, y, width, pixel
#endif
mov r2, top
add pc, type, lsr #(FACE_TYPE_SHIFT - 2)
nop
b rasterizeS_asm
b rasterizeF_asm
b rasterizeFT_asm
b rasterizeFTA_asm
b rasterizeGT_asm
b rasterizeGTA_asm
b rasterizeSprite_c
b rasterizeFillS_asm
b rasterizeLineH_asm
b rasterizeLineV_asm

View File

@ -30,8 +30,9 @@ rasterizeF_asm:
mov LMAP, #LMAP_ADDR
// TODO use ldrh, swap g and clip
ldrb tmp, [L, #VERTEX_G]
ldrb index, [L, #VERTEX_T]
ldrb index, [L, #VERTEX_CLIP]
orr tmp, index, tmp, lsl #8 // tmp = index | (L->v.g << 8)
ldrb index, [LMAP, tmp] // tmp = lightmap[tmp]

View File

@ -89,7 +89,7 @@ rasterizeFT_asm:
ldrb tmp, [L, #VERTEX_G]
add LMAP, tmp, lsl #8 // tmp = (L->v.g << 8)
ldr TILE, =tile
ldr TILE, =gTile
ldr TILE, [TILE]
mov Lh, #0 // Lh = 0

View File

@ -95,7 +95,7 @@ rasterizeFTA_asm:
ldrb tmp, [L, #VERTEX_G]
add LMAP, tmp, lsl #8 // tmp = (L->v.g << 8)
ldr TILE, =tile
ldr TILE, =gTile
ldr TILE, [TILE]
mov Lh, #0 // Lh = 0

View File

@ -216,7 +216,7 @@ rasterizeGT_asm:
sub Lh, h // Lh -= h
sub Rh, h // Rh -= h
ldr TILE, =tile
ldr TILE, =gTile
ldr TILE, [TILE]
stmfd sp!, {L,R,Lh,Rh} // sp-16

View File

@ -221,7 +221,7 @@ rasterizeGTA_asm:
sub Lh, h // Lh -= h
sub Rh, h // Rh -= h
ldr TILE, =tile
ldr TILE, =gTile
ldr TILE, [TILE]
stmfd sp!, {L,R,Lh,Rh} // sp-16

View File

@ -23,14 +23,12 @@ pair .req DIVLUT
indexA .req Lh
indexB .req DIVLUT
.shadow_lightmap:
.word lightmap + 0x1A00
.global rasterizeS_asm
rasterizeS_asm:
stmfd sp!, {r4-r11, lr}
ldr LMAP, .shadow_lightmap
mov LMAP, #LMAP_ADDR
add LMAP, #0x1A00
mov Lh, #0 // Lh = 0
mov Rh, #0 // Rh = 0

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -561,7 +561,7 @@ void* osLoadLevel(const char* name)
int main(void)
{
if (intptr_t(divTable) != MEM_EWRAM) return 0;
if (intptr_t(lightmap) != MEM_IWRAM) return 0;
if (intptr_t(gLightmap) != MEM_IWRAM) return 0;
irq_init(NULL);
irq_add(II_VBLANK, vblank);

View File

@ -3,12 +3,12 @@
#include "common.h"
extern uint8 lightmap[256 * 32];
extern const uint8* tile;
extern uint8 gLightmap[256 * 32];
extern const uint8* gTile;
#ifdef USE_ASM
extern "C" {
//void rasterize_dummy(uint16* pixel, const VertexLink* L, const VertexLink* R);
void rasterize_dummy(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 rasterizeG_asm(uint16* pixel, const VertexLink* L, const VertexLink* R);
@ -47,7 +47,7 @@ extern const uint8* tile;
void rasterizeS_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
{
const uint8* ft_lightmap = &lightmap[0x1A00];
const uint8* ft_lightmap = &gLightmap[0x1A00];
int32 Lh = 0;
int32 Rh = 0;
@ -153,7 +153,7 @@ void rasterizeS_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
void rasterizeF_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
{
uint16 color = lightmap[(L->v.g << 8) | L->t.t];
uint16 color = gLightmap[(L->v.g << 8) | L->v.clip];
color |= (color << 8);
int32 Lh = 0;
@ -264,7 +264,7 @@ void rasterizeG_c(uint16* pixel, const VertexLink* L, const VertexLink* R, int32
int32 Lx, Rx, Ldx = 0, Rdx = 0;
int32 Lg, Rg, Ldg = 0, Rdg = 0;
const uint8* ft_lightmap = lightmap + index;
const uint8* ft_lightmap = gLightmap + index;
while (1)
{
@ -384,7 +384,7 @@ void rasterizeG_c(uint16* pixel, const VertexLink* L, const VertexLink* R, int32
void rasterizeFT_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
{
const uint8* ft_lightmap = &lightmap[L->v.g << 8];
const uint8* ft_lightmap = &gLightmap[L->v.g << 8];
int32 Lh = 0, Rh = 0;
int32 Lx, Rx, Ldx = 0, Rdx = 0;
@ -471,7 +471,7 @@ void rasterizeFT_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
if (intptr_t(ptr) & 1)
{
ptr--;
*(uint16*)ptr = *ptr | (ft_lightmap[tile[(t & 0xFF00) | (t >> 24)]] << 8);
*(uint16*)ptr = *ptr | (ft_lightmap[gTile[(t & 0xFF00) | (t >> 24)]] << 8);
ptr += 2;
t += dtdx;
width--;
@ -480,7 +480,7 @@ void rasterizeFT_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
if (width & 1)
{
uint32 tmp = Rt - dtdx;
*(uint16*)(ptr + width - 1) = (ptr[width] << 8) | ft_lightmap[tile[(tmp & 0xFF00) | (tmp >> 24)]];
*(uint16*)(ptr + width - 1) = (ptr[width] << 8) | ft_lightmap[gTile[(tmp & 0xFF00) | (tmp >> 24)]];
}
width >>= 1;
@ -488,9 +488,9 @@ void rasterizeFT_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
{
uint16 p;
p = ft_lightmap[tile[(t & 0xFF00) | (t >> 24)]];
p = ft_lightmap[gTile[(t & 0xFF00) | (t >> 24)]];
t += dtdx;
p |= ft_lightmap[tile[(t & 0xFF00) | (t >> 24)]] << 8;
p |= ft_lightmap[gTile[(t & 0xFF00) | (t >> 24)]] << 8;
t += dtdx;
*(uint16*)ptr = p;
@ -612,7 +612,7 @@ void rasterizeGT_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
if (intptr_t(ptr) & 1)
{
ptr--;
*(uint16*)ptr = *ptr | (lightmap[(g >> 8 << 8) | tile[(t & 0xFF00) | (t >> 24)]] << 8);
*(uint16*)ptr = *ptr | (gLightmap[(g >> 8 << 8) | gTile[(t & 0xFF00) | (t >> 24)]] << 8);
ptr += 2;
t += dtdx;
g += dgdx >> 1;
@ -622,7 +622,7 @@ void rasterizeGT_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
if (width & 1)
{
uint32 tmp = Rt - dtdx;
*(uint16*)(ptr + width - 1) = (ptr[width] << 8) | lightmap[(Rg >> 8 << 8) | tile[(tmp & 0xFF00) | (tmp >> 24)]];
*(uint16*)(ptr + width - 1) = (ptr[width] << 8) | gLightmap[(Rg >> 8 << 8) | gTile[(tmp & 0xFF00) | (tmp >> 24)]];
}
#ifdef ALIGNED_LIGHTMAP
@ -636,15 +636,15 @@ void rasterizeGT_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
#ifdef ALIGNED_LIGHTMAP
const uint8* LMAP = (uint8*)(g >> 8 << 8);
uint16 p = LMAP[tile[(t & 0xFF00) | (t >> 24)]];
uint16 p = LMAP[gTile[(t & 0xFF00) | (t >> 24)]];
t += dtdx;
p |= LMAP[tile[(t & 0xFF00) | (t >> 24)]] << 8;
p |= LMAP[gTile[(t & 0xFF00) | (t >> 24)]] << 8;
t += dtdx;
g += dgdx;
#else
uint16 p = lightmap[(g >> 8 << 8) | tile[(t & 0xFF00) | (t >> 24)]];
uint16 p = gLightmap[(g >> 8 << 8) | gTile[(t & 0xFF00) | (t >> 24)]];
t += dtdx;
p |= lightmap[(g >> 8 << 8) | tile[(t & 0xFF00) | (t >> 24)]] << 8;
p |= gLightmap[(g >> 8 << 8) | gTile[(t & 0xFF00) | (t >> 24)]] << 8;
t += dtdx;
g += dgdx;
#endif
@ -668,7 +668,7 @@ void rasterizeGT_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
void rasterizeFTA_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
{
const uint8* ft_lightmap = &lightmap[L->v.g << 8];
const uint8* ft_lightmap = &gLightmap[L->v.g << 8];
int32 Lh = 0, Rh = 0;
int32 Lx, Rx, Ldx = 0, Rdx = 0;
@ -754,7 +754,7 @@ void rasterizeFTA_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
if (intptr_t(ptr) & 1)
{
uint8 p = tile[(t & 0xFF00) | (t >> 24)];
uint8 p = gTile[(t & 0xFF00) | (t >> 24)];
ptr--;
if (p) {
*(uint16*)ptr = *ptr | (ft_lightmap[p] << 8);
@ -767,7 +767,7 @@ void rasterizeFTA_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
if (width & 1)
{
uint32 tmp = Rt - dtdx;
uint8 p = tile[(tmp & 0xFF00) | (tmp >> 24)];
uint8 p = gTile[(tmp & 0xFF00) | (tmp >> 24)];
if (p) {
*(uint16*)(ptr + width - 1) = (ptr[width] << 8) | ft_lightmap[p];
}
@ -776,9 +776,9 @@ void rasterizeFTA_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
width >>= 1;
while (width--)
{
uint8 indexA = tile[(t & 0xFF00) | (t >> 24)];
uint8 indexA = gTile[(t & 0xFF00) | (t >> 24)];
t += dtdx;
uint8 indexB = tile[(t & 0xFF00) | (t >> 24)];
uint8 indexB = gTile[(t & 0xFF00) | (t >> 24)];
t += dtdx;
if (indexA && indexB) {
@ -908,10 +908,10 @@ void rasterizeGTA_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
{
ptr--;
uint8 indexB = tile[(t & 0xFF00) | (t >> 24)];
uint8 indexB = gTile[(t & 0xFF00) | (t >> 24)];
if (indexB) {
*(uint16*)ptr = *ptr | (lightmap[(g >> 8 << 8) | indexB] << 8);
*(uint16*)ptr = *ptr | (gLightmap[(g >> 8 << 8) | indexB] << 8);
}
ptr += 2;
@ -924,10 +924,10 @@ void rasterizeGTA_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
{
uint32 tmp = Rt - dtdx;
uint8 indexA = tile[(tmp & 0xFF00) | (tmp >> 24)];
uint8 indexA = gTile[(tmp & 0xFF00) | (tmp >> 24)];
if (indexA) {
*(uint16*)(ptr + width - 1) = (ptr[width] << 8) | lightmap[(Rg >> 8 << 8) | indexA];
*(uint16*)(ptr + width - 1) = (ptr[width] << 8) | gLightmap[(Rg >> 8 << 8) | indexA];
}
}
@ -940,9 +940,9 @@ void rasterizeGTA_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
while (width--)
{
#ifdef ALIGNED_LIGHTMAP
uint8 indexA = tile[(t & 0xFF00) | (t >> 24)];
uint8 indexA = gTile[(t & 0xFF00) | (t >> 24)];
t += dtdx;
uint8 indexB = tile[(t & 0xFF00) | (t >> 24)];
uint8 indexB = gTile[(t & 0xFF00) | (t >> 24)];
t += dtdx;
g += dgdx;
@ -952,14 +952,14 @@ void rasterizeGTA_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
*(uint16*)ptr = LMAP[indexA] | (LMAP[indexB] << 8);
}
#else
uint8 indexA = tile[(t & 0xFF00) | (t >> 24)];
uint8 indexA = gTile[(t & 0xFF00) | (t >> 24)];
t += dtdx;
uint8 indexB = tile[(t & 0xFF00) | (t >> 24)];
uint8 indexB = gTile[(t & 0xFF00) | (t >> 24)];
t += dtdx;
g += dgdx;
if (indexA && indexB) {
*(uint16*)ptr = lightmap[(g >> 8 << 8) | indexA] | (lightmap[(g >> 8 << 8) | indexB] << 8);
*(uint16*)ptr = gLightmap[(g >> 8 << 8) | indexA] | (gLightmap[(g >> 8 << 8) | indexB] << 8);
}
#endif
@ -1036,7 +1036,7 @@ X_NOINLINE void rasterizeFillS_c(uint16* pixel, const VertexLink* L, const Verte
int32 width = R->v.x;
int32 height = R->v.y;
const uint8* lm = &lightmap[shade << 8];
const uint8* lm = &gLightmap[shade << 8];
for (int32 i = 0; i < height; i++)
{
@ -1069,10 +1069,10 @@ X_NOINLINE void rasterizeFillS_c(uint16* pixel, const VertexLink* L, const Verte
#endif
// TODO ARM version
X_NOINLINE void rasterizeSprite_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
extern "C" X_NOINLINE void rasterizeSprite_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
{
R++;
const uint8* ft_lightmap = &lightmap[L->v.g << 8];
const uint8* ft_lightmap = &gLightmap[L->v.g << 8];
int32 w = R->v.x - L->v.x;
if (w <= 0 || w >= DIV_TABLE_SIZE) return;
@ -1080,8 +1080,8 @@ X_NOINLINE void rasterizeSprite_c(uint16* pixel, const VertexLink* L, const Vert
int32 h = R->v.y - L->v.y;
if (h <= 0 || h >= DIV_TABLE_SIZE) return;
int32 u = L->t.uv.u << 8;
int32 v = L->t.uv.v << 8;
int32 u = L->t.uv.u;
int32 v = L->t.uv.v;
int32 iw = FixedInvU(w);
int32 ih = FixedInvU(h);
@ -1134,7 +1134,7 @@ X_NOINLINE void rasterizeSprite_c(uint16* pixel, const VertexLink* L, const Vert
for (int32 y = 0; y < h; y++)
{
const uint8* xtile = tile + (v & 0xFF00);
const uint8* xtile = gTile + (v & 0xFF00);
volatile uint8* xptr = ptr;

View File

@ -35,13 +35,12 @@ ViewportRel viewportRel;
#endif
enum FaceType {
FACE_TYPE_GT,
FACE_TYPE_GTA,
FACE_TYPE_SHADOW,
FACE_TYPE_F,
FACE_TYPE_FT,
FACE_TYPE_FTA,
FACE_TYPE_G,
FACE_TYPE_F,
FACE_TYPE_SHADOW,
FACE_TYPE_GT,
FACE_TYPE_GTA,
FACE_TYPE_SPRITE,
FACE_TYPE_FILL_S,
FACE_TYPE_LINE_H,
@ -49,23 +48,18 @@ enum FaceType {
FACE_TYPE_MAX
};
#define FACE_TRIANGLE (1 << 15)
#define FACE_CLIPPED (1 << 16)
#define FACE_TYPE_SHIFT 11
#define FACE_TRIANGLE (1 << 13)
#define FACE_CLIPPED (1 << 18)
#define FACE_TYPE_SHIFT 14
#define FACE_TYPE_MASK 15
#define FACE_FLAT_ADD (2 << FACE_TYPE_SHIFT)
#define FACE_TEXTURE 0x07FF
#if defined(__GBA__)
#define ALIGNED_LIGHTMAP
#endif
#define FACE_GOURAUD (2 << FACE_TYPE_SHIFT)
#define FACE_TEXTURE 0x1FFF
#include "rasterizer.h"
extern uint8 lightmap[256 * 32];
extern Level level;
const uint8* tile;
const uint8* gTile;
Vertex* gVerticesBase;
Face* gFacesBase;
@ -76,16 +70,16 @@ EWRAM_DATA Face gFaces[MAX_FACES]; // EWRAM 5k
Face* gOT[OT_SIZE]; // IWRAM 2.5k
enum ClipFlags {
CLIP_LEFT = 1 << 0,
CLIP_RIGHT = 1 << 1,
CLIP_TOP = 1 << 2,
CLIP_BOTTOM = 1 << 3,
CLIP_FAR = 1 << 4,
CLIP_NEAR = 1 << 5,
CLIP_LEFT = 1 << 0,
CLIP_RIGHT = 1 << 1,
CLIP_TOP = 1 << 2,
CLIP_BOTTOM = 1 << 3,
CLIP_FAR = 1 << 4,
CLIP_NEAR = 1 << 5,
CLIP_MASK_VP = (CLIP_LEFT | CLIP_RIGHT | CLIP_TOP | CLIP_BOTTOM),
};
extern "C" const MeshQuad gShadowQuads[] = {
const MeshQuad gShadowQuads[] = {
{ (FACE_TYPE_SHADOW << FACE_TYPE_SHIFT), {0, 1, 2, 7} },
{ (FACE_TYPE_SHADOW << FACE_TYPE_SHIFT), {7, 2, 3, 6} },
{ (FACE_TYPE_SHADOW << FACE_TYPE_SHIFT), {6, 3, 4, 5} }
@ -120,6 +114,12 @@ X_INLINE Face* faceAdd(int32 depth)
return face;
}
extern "C" {
X_NOINLINE void drawPoly(uint32 flags, VertexLink* v);
X_NOINLINE void drawTriangle(uint32 flags, VertexLink* v);
X_NOINLINE void drawQuad(uint32 flags, VertexLink* v);
}
#ifdef USE_ASM
#define transformRoom transformRoom_asm
#define transformRoomUW transformRoomUW_asm
@ -128,6 +128,7 @@ X_INLINE Face* faceAdd(int32 depth)
#define faceAddRoomTriangles faceAddRoomTriangles_asm
#define faceAddMeshQuads faceAddMeshQuads_asm
#define faceAddMeshTriangles faceAddMeshTriangles_asm
#define rasterize rasterize_asm
extern "C" {
void transformRoom_asm(const RoomVertex* vertices, int32 count);
@ -137,6 +138,7 @@ X_INLINE Face* faceAdd(int32 depth)
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
@ -146,6 +148,7 @@ X_INLINE Face* faceAdd(int32 depth)
#define faceAddRoomTriangles faceAddRoomTriangles_c
#define faceAddMeshQuads faceAddMeshQuads_c
#define faceAddMeshTriangles faceAddMeshTriangles_c
#define rasterize rasterize_c
X_INLINE bool checkBackface(const Vertex *a, const Vertex *b, const Vertex *c)
{
@ -360,8 +363,8 @@ void faceAddRoomQuads_c(const RoomQuad* polys, int32 count)
uint32 g2 = v2->g;
uint32 g3 = v3->g;
if (g0 == g1 && g0 == g2 && g0 == g3) {
flags += FACE_FLAT_ADD;
if (g0 != g1 || g0 != g2 || g0 != g3) {
flags += FACE_GOURAUD;
}
if (checkBackface(v0, v1, v2))
@ -404,8 +407,8 @@ void faceAddRoomTriangles_c(const RoomTriangle* polys, int32 count)
uint32 g1 = v1->g;
uint32 g2 = v2->g;
if (g0 == g1 && g0 == g2) {
flags += FACE_FLAT_ADD;
if (g0 != g1 || g0 != g2) {
flags += FACE_GOURAUD;
}
if (checkBackface(v0, v1, v2))
@ -608,6 +611,129 @@ int32 sphereIsVisible_c(int32 sx, int32 sy, int32 sz, int32 r)
return 1;
}
typedef void (*RasterProc)(uint16* pixel, const VertexLink* L, const VertexLink* R);
RasterProc gRasterProc[FACE_TYPE_MAX] = { // IWRAM
rasterizeS,
rasterizeF,
rasterizeFT,
rasterizeFTA,
rasterizeGT,
rasterizeGTA,
rasterizeSprite,
rasterizeFillS,
rasterizeLineH,
rasterizeLineV
};
X_NOINLINE void rasterize_c(uint32 flags, VertexLink* top)
{
uint8* pixel = (uint8*)fb + top->v.y * FRAME_WIDTH;
uint32 type = (flags >> FACE_TYPE_SHIFT) & FACE_TYPE_MASK;
if (type == FACE_TYPE_F) {
top->v.clip = flags; // use tex coord as color index for untextured polys
}
#if defined(_WIN32)
if (type <= FACE_TYPE_GTA) {
VertexLink* t = top;
do {
ASSERT(t->v.x >= 0 && t->v.x <= FRAME_WIDTH && t->v.y >= 0 && t->v.y <= FRAME_HEIGHT);
t = t->next;
} while (t != top);
}
#endif
gRasterProc[type]((uint16*)pixel, top, top);
}
void flush_c()
{
#ifdef PROFILING
#if !defined(PROFILE_FRAMETIME) && !defined(PROFILE_SOUNDTIME)
gCounters[CNT_VERT] += gVerticesBase - gVertices;
gCounters[CNT_POLY] += gFacesBase - gFaces;
#endif
#endif
gVerticesBase = gVertices;
if (gFacesBase == gFaces)
return;
gFacesBase = gFaces;
PROFILE(CNT_FLUSH);
for (int32 i = OT_SIZE - 1; i >= 0; i--)
{
if (!gOT[i]) continue;
Face *face = gOT[i];
gOT[i] = NULL;
do {
uint32 flags = face->flags;
VertexLink v[16];
uint32 type = (flags >> FACE_TYPE_SHIFT) & FACE_TYPE_MASK;
if (type <= FACE_TYPE_GTA)
{
if (type > FACE_TYPE_F)
{
const Texture &tex = level.textures[flags & FACE_TEXTURE];
gTile = (uint8*)tex.tile;
v[0].t.t = 0xFF00FF00 & (tex.uv01);
v[1].t.t = 0xFF00FF00 & (tex.uv01 << 8);
v[2].t.t = 0xFF00FF00 & (tex.uv23);
v[3].t.t = 0xFF00FF00 & (tex.uv23 << 8);
}
v[0].v = gVertices[face->indices[0]];
v[1].v = gVertices[face->indices[1]];
v[2].v = gVertices[face->indices[2]];
if (!(flags & FACE_TRIANGLE)) {
v[3].v = gVertices[face->indices[3]];
}
if (flags & FACE_CLIPPED) {
drawPoly(flags, v);
} else {
if (flags & FACE_TRIANGLE) {
drawTriangle(flags, v);
} else {
drawQuad(flags, v);
}
}
}
else
{
const Vertex *vert = gVertices + face->indices[0];
v[0].v = vert[0];
v[1].v = vert[1];
if (type == FACE_TYPE_SPRITE)
{
const Sprite &sprite = level.sprites[flags & FACE_TEXTURE];
gTile = (uint8*)sprite.tile;
v[0].t.t = (sprite.uwvh) & (0xFF00FF00);
v[1].t.t = (sprite.uwvh) & (0xFF00FF00 >> 8);
}
rasterize(flags, v);
}
face = face->next;
} while (face);
}
}
#endif
VertexLink* clipPoly(VertexLink* poly, VertexLink* tmp, int32 &pCount)
@ -677,38 +803,7 @@ void renderInit()
gFacesBase = gFaces;
}
typedef void (*RasterProc)(uint16* pixel, const VertexLink* L, const VertexLink* R);
RasterProc rasterProc[FACE_TYPE_MAX] = { // IWRAM
rasterizeGT,
rasterizeGTA,
rasterizeFT,
rasterizeFTA,
NULL,
rasterizeF,
rasterizeS,
rasterizeSprite,
rasterizeFillS,
rasterizeLineH,
rasterizeLineV
};
void rasterize(uint32 flags, VertexLink* top)
{
uint16* pixel = (uint16*)fb + top->v.y * VRAM_WIDTH;
uint32 type = (flags >> FACE_TYPE_SHIFT) & FACE_TYPE_MASK;
ASSERT(type != FACE_TYPE_G); // not used
if (type == FACE_TYPE_F) {
top->t.t = (flags & FACE_TEXTURE); // use tex coord as color index for untextured polys
}
rasterProc[type](pixel, top, top);
}
X_NOINLINE void drawTriangle(uint32 flags, VertexLink* v)
extern "C" X_NOINLINE void drawTriangle(uint32 flags, VertexLink* v)
{
VertexLink* v1 = v + 0;
VertexLink* v2 = v + 1;
@ -740,7 +835,7 @@ X_NOINLINE void drawTriangle(uint32 flags, VertexLink* v)
rasterize(flags, top);
}
X_NOINLINE void drawQuad(uint32 flags, VertexLink* v)
extern "C" X_NOINLINE void drawQuad(uint32 flags, VertexLink* v)
{
VertexLink* v1 = v + 0;
VertexLink* v2 = v + 1;
@ -775,7 +870,7 @@ X_NOINLINE void drawQuad(uint32 flags, VertexLink* v)
rasterize(flags, top);
}
X_NOINLINE void drawPoly(uint32 flags, VertexLink* v)
extern "C" X_NOINLINE void drawPoly(uint32 flags, VertexLink* v)
{
VertexLink tmp[16];
@ -857,100 +952,6 @@ void faceAddMesh(const MeshQuad* quads, const MeshTriangle* triangles, int32 qCo
}
}
void flush()
{
if (gFacesBase > gFaces)
{
PROFILE(CNT_FLUSH);
for (int32 i = OT_SIZE - 1; i >= 0; i--)
{
if (!gOT[i]) continue;
Face *face = gOT[i];
gOT[i] = NULL;
do {
uint32 flags = face->flags;
VertexLink v[16];
uint32 type = (flags >> FACE_TYPE_SHIFT) & FACE_TYPE_MASK;
if (type <= FACE_TYPE_SHADOW)
{
if (type <= FACE_TYPE_FTA)
{
const Texture &tex = level.textures[flags & FACE_TEXTURE];
tile = level.tiles + (tex.tile << 16);
v[0].t.t = tex.uv0;
v[1].t.t = tex.uv1;
v[2].t.t = tex.uv2;
v[3].t.t = tex.uv3;
}
v[0].v = gVertices[face->indices[0]];
v[1].v = gVertices[face->indices[1]];
v[2].v = gVertices[face->indices[2]];
if (!(flags & FACE_TRIANGLE)) {
v[3].v = gVertices[face->indices[3]];
}
if (flags & FACE_CLIPPED) {
drawPoly(flags, v);
} else {
if (flags & FACE_TRIANGLE) {
drawTriangle(flags, v);
} else {
drawQuad(flags, v);
}
}
}
else
{
if (type == FACE_TYPE_SPRITE)
{
const Sprite &sprite = level.sprites[face->indices[1]];
v[0].v = gVertices[face->indices[0] + 0];
v[0].t.uv.u = sprite.u;
v[0].t.uv.v = sprite.v;
v[1].v = gVertices[face->indices[0] + 1];
v[1].t.uv.u = sprite.w + 1;
v[1].t.uv.v = sprite.h + 1;
ASSERT(v[0].v.x <= v[1].v.x);
ASSERT(v[0].v.y <= v[1].v.y);
tile = level.tiles + (level.sprites[face->indices[1]].tile << 16);
rasterize(face->flags, v);
} else { // > FACE_TYPE_FILL_S
v[0].v = gVertices[face->indices[0]];
v[1].v = gVertices[face->indices[1]];
rasterize(flags, v);
}
}
face = face->next;
} while (face);
}
}
#ifdef PROFILING
#if !defined(PROFILE_FRAMETIME) && !defined(PROFILE_SOUNDTIME)
gCounters[CNT_VERT] += gVerticesBase - gVertices;
gCounters[CNT_POLY] += gFacesBase - gFaces;
#endif
#endif
gVerticesBase = gVertices;
gFacesBase = gFaces;
}
void clear()
{
dmaFill((void*)fb, 0, VRAM_WIDTH * FRAME_HEIGHT * 2);
@ -997,7 +998,7 @@ void renderMesh(const Mesh* mesh)
return;
}
int32 fCount = mesh->rCount + mesh->crCount + mesh->tCount + mesh->ctCount;
int32 fCount = mesh->rCount + mesh->tCount;
if ((gFacesBase - gFaces) + fCount > MAX_FACES)
{
ASSERT(false);
@ -1087,7 +1088,6 @@ X_NOINLINE void renderFill(int32 x, int32 y, int32 width, int32 height, int32 sh
Face* f = faceAdd(z);
f->flags = (FACE_TYPE_FILL_S << FACE_TYPE_SHIFT);
f->indices[0] = gVerticesBase - gVertices;
f->indices[1] = f->indices[0] + 1;
gVerticesBase += 2;
}
@ -1120,7 +1120,6 @@ X_NOINLINE void renderLine(int32 x, int32 y, int32 width, int32 height, int32 in
Face* f = faceAdd(z);
f->flags = (height == 1) ? (FACE_TYPE_LINE_H << FACE_TYPE_SHIFT) : (FACE_TYPE_LINE_V << FACE_TYPE_SHIFT);
f->indices[0] = idx;
f->indices[1] = idx + 1;
gVerticesBase += 2;
}
@ -1208,9 +1207,8 @@ void renderSprite(int32 vx, int32 vy, int32 vz, int32 vg, int32 index)
int32 depth = X_MAX(0, z - 128); // depth hack
Face* f = faceAdd(depth >> OT_SHIFT);
f->flags = (FACE_TYPE_SPRITE << FACE_TYPE_SHIFT);
f->flags = (FACE_TYPE_SPRITE << FACE_TYPE_SHIFT) | index;
f->indices[0] = v1 - gVertices;
f->indices[1] = index;
gVerticesBase += 2;
}
@ -1254,9 +1252,8 @@ void renderGlyph(int32 vx, int32 vy, int32 index)
//v2->g = vg;
Face* f = faceAdd(0);
f->flags = (FACE_TYPE_SPRITE << FACE_TYPE_SHIFT);
f->flags = (FACE_TYPE_SPRITE << FACE_TYPE_SHIFT) | index;
f->indices[0] = v1 - gVertices;
f->indices[1] = index;
gVerticesBase += 2;
}