mirror of
https://github.com/XProger/OpenLara.git
synced 2025-03-14 08:09:40 +01:00
#368 ARM version for flush and rasterize functions (4% boost)
This commit is contained in:
parent
889d3af918
commit
48e57ece0e
@ -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
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
{
|
||||
//
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
187
src/platform/gba/asm/flush.s
Normal file
187
src/platform/gba/asm/flush.s
Normal 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
|
52
src/platform/gba/asm/rasterize.s
Normal file
52
src/platform/gba/asm/rasterize.s
Normal 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
|
@ -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]
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user