- DrawMapPSX test optimization #2

This commit is contained in:
Ilya Shurumov 2022-04-10 23:57:31 +06:00
parent 23e38d0149
commit 6c7a9c5d6d
6 changed files with 293 additions and 183 deletions

View File

@ -4,9 +4,6 @@
#include "map.h" #include "map.h"
#include "spool.h" #include "spool.h"
int cell_object_index = 0;
CELL_OBJECT cell_object_buffer[1024];
u_char cell_object_computed_values[2048]; u_char cell_object_computed_values[2048];
extern u_char NumPlayers; extern u_char NumPlayers;
@ -155,21 +152,3 @@ PACKED_CELL_OBJECT* GetNextPackedCop(CELL_ITERATOR* pci)
return ppco; return ppco;
} }
// [D] [T]
CELL_OBJECT* UnpackCellObject(PACKED_CELL_OBJECT* ppco, XZPAIR* near)
{
int newIndex;
CELL_OBJECT* pco;
if (ppco == NULL)
return NULL;
pco = &cell_object_buffer[newIndex = cell_object_index];
cell_object_index = newIndex + 1 & 1023;
QuickUnpackCellObject(ppco, near, pco);
return pco;
}

View File

@ -7,7 +7,6 @@ extern void ClearCopUsage(); // 0x00023DC0
extern PACKED_CELL_OBJECT * GetFirstPackedCop(int cellx, int cellz, CELL_ITERATOR *pci, int use_computed, int level = -1); // 0x00023BAC extern PACKED_CELL_OBJECT * GetFirstPackedCop(int cellx, int cellz, CELL_ITERATOR *pci, int use_computed, int level = -1); // 0x00023BAC
extern PACKED_CELL_OBJECT* GetNextPackedCop(CELL_ITERATOR* pci); // 0x0003F5F0 extern PACKED_CELL_OBJECT* GetNextPackedCop(CELL_ITERATOR* pci); // 0x0003F5F0
extern CELL_OBJECT* UnpackCellObject(PACKED_CELL_OBJECT* ppco, XZPAIR* near); // 0x000418E8
inline void QuickUnpackCellObject(PACKED_CELL_OBJECT* ppco, XZPAIR* near, CELL_OBJECT* pco) inline void QuickUnpackCellObject(PACKED_CELL_OBJECT* ppco, XZPAIR* near, CELL_OBJECT* pco)
{ {

View File

@ -15,6 +15,7 @@
#include "debris.h" #include "debris.h"
#include "ASM/rndrasm.h" #include "ASM/rndrasm.h"
#include "event.h" #include "event.h"
#include "pres.h"
MATRIX aspect = MATRIX aspect =
@ -86,6 +87,11 @@ SVECTOR night_colours[4] =
{ 880, 880, 905, 0 } { 880, 880, 905, 0 }
}; };
int tiles_found = 0;
int sprites_found = 0;
int other_models_found = 0;
int anim_objs_found = 0;
void* model_object_ptrs[MAX_DRAWN_BUILDINGS]; void* model_object_ptrs[MAX_DRAWN_BUILDINGS];
void* model_tile_ptrs[MAX_DRAWN_TILES]; void* model_tile_ptrs[MAX_DRAWN_TILES];
void* anim_obj_buffer[MAX_DRAWN_ANIMATING]; void* anim_obj_buffer[MAX_DRAWN_ANIMATING];
@ -119,6 +125,27 @@ struct MVERTEX5x5
MVERTEX verts[5][5]; MVERTEX verts[5][5];
}; };
int draw_cell_object_index = 0;
CELL_OBJECT draw_cell_object_buffer[1024];
// [A]
CELL_OBJECT* UnpackDrawCellObject(PACKED_CELL_OBJECT* ppco, XZPAIR* near)
{
CELL_OBJECT* pco;
#ifndef PSX
if (ppco == NULL)
return NULL;
#endif
pco = &draw_cell_object_buffer[draw_cell_object_index];
draw_cell_object_index = draw_cell_object_index + 1 & 1023;
QuickUnpackCellObject(ppco, near, pco);
return pco;
}
// [D] [T] [A] // [D] [T] [A]
void addSubdivSpriteShadow(POLYFT4* src, SVECTOR* verts, int z) void addSubdivSpriteShadow(POLYFT4* src, SVECTOR* verts, int z)
{ {
@ -373,49 +400,83 @@ void SetupPlaneColours(u_int ambient)
int current_pvs_cell; int current_pvs_cell;
int current_draw_cell_x;
int current_draw_cell_z;
int current_draw_angle_y;
SVECTOR current_draw_cameraangle;
// [D] [T] // [D] [T]
void SetupDrawMapPSX(void) void SetupDrawMapPSX(void)
{ {
int cell_x, cell_z; int cell_x, cell_z;
int theta; int region_x, region_z;
int pvs_cell; int current_barrel_region_x, current_barrel_region_z;
int setup;
if (setupYet != 0) setup = setupYet;
{
return;
}
cell_x = (camera_position.vx + units_across_halved) / MAP_CELL_SIZE; cell_x = (camera_position.vx + units_across_halved) / MAP_CELL_SIZE;
cell_z = (camera_position.vz + units_down_halved) / MAP_CELL_SIZE; cell_z = (camera_position.vz + units_down_halved) / MAP_CELL_SIZE;
current_cell_x = cell_x; if (cell_x != current_draw_cell_x ||
current_cell_z = cell_z; cell_z != current_draw_cell_z)
pvs_cell = (cell_z % MAP_REGION_SIZE) * MAP_REGION_SIZE + (cell_x % MAP_REGION_SIZE);
if (pvs_cell != current_pvs_cell)
{ {
int region_x1, region_z1; // update all
int current_barrel_region_x1, current_barrel_region_z1; current_draw_angle_y = camera_angle.vy;
current_draw_cell_x = cell_x;
current_draw_cell_z = cell_z;
region_x1 = cell_x / MAP_REGION_SIZE; // PVS, frustum, matrices to be dropped
region_z1 = cell_z / MAP_REGION_SIZE; setup = 0;
}
current_barrel_region_x1 = (region_x1 & 1); else
current_barrel_region_z1 = (region_z1 & 1); {
if (ABS(DIFF_ANGLES(current_draw_cameraangle.vy, camera_angle.vy)) > 16)
current_pvs_cell = pvs_cell; {
GetPVSRegionCell2( setup &= ~SETUP_FRUSTUM;
current_barrel_region_x1 + current_barrel_region_z1 * 2,
region_x1 + region_z1 * regions_across,
pvs_cell, CurrentPVS);
} }
if (ABS(DIFF_ANGLES(current_draw_cameraangle.vx, camera_angle.vx)) > 0 ||
ABS(DIFF_ANGLES(current_draw_cameraangle.vy, camera_angle.vy)) > 0)
{
current_draw_cameraangle = camera_angle;
setup &= ~SETUP_MATRICES;
}
}
if ((setup & SETUP_MATRICES) == 0)
{
int theta;
for (theta = 0; theta < 64; theta++)
MulMatrix0(&inv_camera_matrix, (MATRIX*)&matrixtable[theta], (MATRIX*)&CompoundMatrix[theta]);
setup |= SETUP_MATRICES;
}
if ((setup & SETUP_PVS) == 0)
{
region_x = current_draw_cell_x / MAP_REGION_SIZE;
region_z = current_draw_cell_z / MAP_REGION_SIZE;
current_barrel_region_x = (region_x & 1);
current_barrel_region_z = (region_z & 1);
GetPVSRegionCell2(
current_barrel_region_x + current_barrel_region_z * 2,
region_x + region_z * regions_across,
(current_draw_cell_z % MAP_REGION_SIZE) * MAP_REGION_SIZE + (current_draw_cell_x % MAP_REGION_SIZE),
CurrentPVS);
setup |= SETUP_PVS | SETUP_DRAW_NEEDED;
}
if ((setup & SETUP_FRUSTUM) == 0)
{
InitFrustrumMatrix(); InitFrustrumMatrix();
SetFrustrumMatrix(); SetFrustrumMatrix();
setup |= SETUP_FRUSTUM | SETUP_DRAW_NEEDED;
}
setupYet = 1; setupYet = setup;
} }
MATRIX frustrum_matrix; MATRIX frustrum_matrix;
@ -1309,6 +1370,16 @@ void DrawMapPSX(int* comp_val)
// clean cell cache // clean cell cache
ClearCopUsage(); ClearCopUsage();
if (setupYet & SETUP_DRAW_NEEDED)
{
static int treecount = 0;
static int alleycount = 0;
setupYet &= ~SETUP_DRAW_NEEDED;
// clean cell cache
ClearCopUsage();
drawData.cellLevel = events.camera ? events.draw : -1; drawData.cellLevel = events.camera ? events.draw : -1;
drawData.backPlane = 6144; drawData.backPlane = 6144;
@ -1340,19 +1411,16 @@ void DrawMapPSX(int* comp_val)
drawData.tiles_found = 0; drawData.tiles_found = 0;
drawData.sprites_found = 0; drawData.sprites_found = 0;
drawData.current_object_computed_value = (*comp_val & 4095) | drawData.cellLevel << 16;
drawData.other_models_found = 0; drawData.other_models_found = 0;
drawData.anim_objs_found = 0; drawData.anim_objs_found = 0;
drawData.cellzpos = current_cell_z; drawData.current_object_computed_value = *comp_val;
drawData.cellxpos = current_cell_x;
drawData.cellxpos = current_draw_cell_x;
drawData.cellzpos = current_draw_cell_z;
PVS_ptr = CurrentPVS + 220; PVS_ptr = CurrentPVS + 220;
vloop = 0;
hloop = 0;
dir = 0;
goFaster ^= fasterToggle; goFaster ^= fasterToggle;
if (NumPlayers == 2) if (NumPlayers == 2)
@ -1361,15 +1429,22 @@ void DrawMapPSX(int* comp_val)
distScale = goFaster & 31; distScale = goFaster & 31;
i = (gDrawDistance >> distScale); // [A] i = (gDrawDistance >> distScale); // [A]
vloop = 0;
hloop = 0;
dir = 0;
// walk through all cells // walk through all cells
do do
{ {
if (ABS(hloop) + ABS(vloop) < 21) if (ABS(hloop) + ABS(vloop) < 21)
{ {
// clamped vis values // clamped vis values
#ifdef PSX
int vis_h = hloop;
int vis_v = vloop;
#else
int vis_h = MIN(MAX(hloop, -9), 10); int vis_h = MIN(MAX(hloop, -9), 10);
int vis_v = MIN(MAX(vloop, -9), 10); int vis_v = MIN(MAX(vloop, -9), 10);
#endif
cellx = drawData.cellxpos + hloop; cellx = drawData.cellxpos + hloop;
cellz = drawData.cellzpos + vloop; cellz = drawData.cellzpos + vloop;
@ -1382,25 +1457,32 @@ void DrawMapPSX(int* comp_val)
PVS_ptr[vis_v * pvs_square + vis_h]) // check PVS table PVS_ptr[vis_v * pvs_square + vis_h]) // check PVS table
{ {
// walk each cell object in cell // walk each cell object in cell
for (ppco = GetFirstPackedCop(cellx, cellz, &ci, 1, drawData.cellLevel); ppco; ppco = GetNextPackedCop(&ci)) for (ppco = GetFirstPackedCop(cellx, cellz, &ci, 1, drawData.cellLevel); ppco != NULL; ppco = GetNextPackedCop(&ci))
{ {
model = modelpointers[(ppco->value >> 6) | ((ppco->pos).vy & 1) << 10]; model = modelpointers[(ppco->value >> 6) | (ppco->pos.vy & 1) << 10];
if (FrustrumCheck16(ppco, model->bounding_sphere) != -1) if (FrustrumCheck16(ppco, model->bounding_sphere) == -1)
{ {
continue;
}
u_short shapeFlags = model->shape_flags;
u_short modelFlags = model->flags2;
// sprity type // sprity type
if (model->shape_flags & SHAPE_FLAG_SPRITE) if (shapeFlags & SHAPE_FLAG_SPRITE)
{ {
if (drawData.sprites_found < MAX_DRAWN_SPRITES) if (drawData.sprites_found < MAX_DRAWN_SPRITES)
spriteList[drawData.sprites_found++] = ppco; spriteList[drawData.sprites_found++] = ppco;
if ((model->flags2 & MODEL_FLAG_ANIMOBJ) && drawData.anim_objs_found < MAX_DRAWN_ANIMATING) if (drawData.anim_objs_found < MAX_DRAWN_ANIMATING &&
(modelFlags & MODEL_FLAG_ANIMOBJ))
{ {
cop = UnpackCellObject(ppco, &ci.nearCell); cop = UnpackDrawCellObject(ppco, &ci.nearCell);
anim_obj_buffer[drawData.anim_objs_found++] = cop; anim_obj_buffer[drawData.anim_objs_found++] = cop;
} }
if (model->flags2 & MODEL_FLAG_TREE) if (modelFlags & MODEL_FLAG_TREE)
{ {
if (treecount == 0) if (treecount == 0)
{ {
@ -1420,25 +1502,31 @@ void DrawMapPSX(int* comp_val)
} }
else else
{ {
int yang; int modelNumber;
MATRIX2* cmat; modelNumber = ppco->value & 0x3f;
yang = ppco->value & 63; if (modelNumber > 0)
cmat = &CompoundMatrix[yang]; {
MATRIX2* cmat;
cmat = &CompoundMatrix[modelNumber];
if (cmat->computed != drawData.current_object_computed_value) if (cmat->computed != drawData.current_object_computed_value)
{ {
cmat->computed = drawData.current_object_computed_value; cmat->computed = drawData.current_object_computed_value;
if (yang > 0)
MulMatrix0(&inv_camera_matrix, (MATRIX*)&matrixtable[yang], (MATRIX*)cmat); gte_ReadRotMatrix(&mRotStore);
else gte_sttr(mRotStore.t);
*(MATRIX*)cmat = inv_camera_matrix;
MulMatrix0(&inv_camera_matrix, (MATRIX*)&matrixtable[modelNumber], (MATRIX*)cmat);
gte_SetRotMatrix(&mRotStore);
}
} }
if ((model->shape_flags & (SHAPE_FLAG_WATER | SHAPE_FLAG_TILE)) || if ((shapeFlags & (SHAPE_FLAG_WATER | SHAPE_FLAG_TILE)) ||
(model->flags2 & (MODEL_FLAG_PATH | MODEL_FLAG_GRASS))) (modelFlags & (MODEL_FLAG_PATH | MODEL_FLAG_GRASS)))
{ {
if (model->flags2 & MODEL_FLAG_ALLEY) if (modelFlags & MODEL_FLAG_ALLEY)
{ {
alleycount++; alleycount++;
@ -1460,16 +1548,22 @@ void DrawMapPSX(int* comp_val)
} }
else else
{ {
cop = UnpackCellObject(ppco, &ci.nearCell); bool canAddBuilding = drawData.other_models_found < MAX_DRAWN_BUILDINGS;
bool canAddAnimating = drawData.anim_objs_found < MAX_DRAWN_ANIMATING && (modelFlags& MODEL_FLAG_ANIMOBJ);
if (drawData.other_models_found < MAX_DRAWN_BUILDINGS) if (canAddBuilding || canAddAnimating)
{
cop = UnpackDrawCellObject(ppco, &ci.nearCell);
if (canAddBuilding)
model_object_ptrs[drawData.other_models_found++] = cop; model_object_ptrs[drawData.other_models_found++] = cop;
if (drawData.anim_objs_found < MAX_DRAWN_ANIMATING && (model->flags2 & MODEL_FLAG_ANIMOBJ)) if (canAddAnimating)
anim_obj_buffer[drawData.anim_objs_found++] = cop; anim_obj_buffer[drawData.anim_objs_found++] = cop;
} }
} }
} }
} }
} }
} }
@ -1506,42 +1600,48 @@ void DrawMapPSX(int* comp_val)
} }
}while (i-- > 0); }while (i-- > 0);
#if 0 tiles_found = drawData.tiles_found;
sprites_found = drawData.sprites_found;
other_models_found = drawData.other_models_found;
anim_objs_found = drawData.anim_objs_found;
}
#if 1
char tempBuf[512]; char tempBuf[512];
SetTextColour(255, 255, 0); SetTextColour(255, 255, 0);
sprintf(tempBuf, "Buildings: %d", drawData.other_models_found); sprintf(tempBuf, "Buildings: %d", other_models_found);
PrintString(tempBuf, 10, 60); PrintString(tempBuf, 10, 60);
sprintf(tempBuf, "Sprites: %d", drawData.sprites_found); sprintf(tempBuf, "Sprites: %d", sprites_found);
PrintString(tempBuf, 10, 75); PrintString(tempBuf, 10, 75);
sprintf(tempBuf, "Tiles: %d", drawData.tiles_found); sprintf(tempBuf, "Tiles: %d", tiles_found);
PrintString(tempBuf, 10, 90); PrintString(tempBuf, 10, 90);
sprintf(tempBuf, "Anims: %d", drawData.anim_objs_found); sprintf(tempBuf, "Anims: %d", anim_objs_found);
PrintString(tempBuf, 10, 105); PrintString(tempBuf, 10, 105);
sprintf(tempBuf, "TOTAL: %d", drawData.other_models_found + drawData.sprites_found + drawData.tiles_found + drawData.anim_objs_found); sprintf(tempBuf, "TOTAL: %d", other_models_found + sprites_found + tiles_found + anim_objs_found);
PrintString(tempBuf, 10, 120); PrintString(tempBuf, 10, 120);
#endif #endif
SetupPlaneColours(combointensity); SetupPlaneColours(combointensity);
if (drawData.anim_objs_found) if (anim_objs_found)
DrawAllAnimatingObjects((CELL_OBJECT**)anim_obj_buffer, drawData.anim_objs_found); DrawAllAnimatingObjects((CELL_OBJECT**)anim_obj_buffer, anim_objs_found);
if (drawData.sprites_found) if (sprites_found)
DrawSprites((PACKED_CELL_OBJECT**)spriteList, drawData.sprites_found); DrawSprites((PACKED_CELL_OBJECT**)spriteList, sprites_found);
if (drawData.tiles_found) if (tiles_found)
DrawTILES((PACKED_CELL_OBJECT**)model_tile_ptrs, drawData.tiles_found); DrawTILES((PACKED_CELL_OBJECT**)model_tile_ptrs, tiles_found);
if (drawData.other_models_found) if (other_models_found)
DrawAllBuildings((CELL_OBJECT**)model_object_ptrs, drawData.other_models_found); DrawAllBuildings((CELL_OBJECT**)model_object_ptrs, other_models_found);
setupYet = 0; //setupYet = 0;
} }
#ifdef DYNAMIC_LIGHTING #ifdef DYNAMIC_LIGHTING

View File

@ -77,6 +77,14 @@ enum PlotFlags
PLOT_CUSTOM_PALETTE = (1 << 4), PLOT_CUSTOM_PALETTE = (1 << 4),
}; };
enum DrawSetupFlags
{
SETUP_PVS = (1 << 0),
SETUP_FRUSTUM = (1 << 1),
SETUP_MATRICES = (1 << 2),
SETUP_DRAW_NEEDED = (1 << 3),
};
extern void* model_tile_ptrs[MAX_DRAWN_TILES]; extern void* model_tile_ptrs[MAX_DRAWN_TILES];
extern int units_across_halved; extern int units_across_halved;

View File

@ -677,9 +677,8 @@ void State_GameInit(void* param)
if (NewLevel) if (NewLevel)
{ {
// alloc pointer list // alloc pointer list
// [A] use model_tile_ptrs for this since it is only used for drawing purposes coplist = (CELL_OBJECT**)D_MALLOC(sizeof(CELL_OBJECT*) * 160);
coplist = (CELL_OBJECT**)(model_tile_ptrs); pcoplist = (PACKED_CELL_OBJECT**)D_MALLOC(sizeof(PACKED_CELL_OBJECT*) * 160)
pcoplist = (PACKED_CELL_OBJECT**)(model_tile_ptrs + 160);
} }
if (NoPlayerControl == 0) if (NoPlayerControl == 0)
@ -1546,7 +1545,7 @@ void CheckForPause(void)
} }
} }
int gMultiStep = 0; int gMultiStep = 1;
// [D] [T] // [D] [T]
void State_GameLoop(void* param) void State_GameLoop(void* param)
@ -1568,7 +1567,10 @@ void State_GameLoop(void* param)
// moved from StepGame // moved from StepGame
if (FrameCnt == 5) if (FrameCnt == 5)
{
setupYet = 0;
SetDispMask(1); SetDispMask(1);
}
#ifdef PSX #ifdef PSX
static int lastTime32Hz = 0; static int lastTime32Hz = 0;
@ -2253,7 +2255,6 @@ void RenderGame2(int view)
SetCameraVector(); SetCameraVector();
SetupDrawMapPSX(); SetupDrawMapPSX();
setupYet = 0;
if (gLoadedMotionCapture != 0) if (gLoadedMotionCapture != 0)
DrawAllPedestrians(); DrawAllPedestrians();

View File

@ -14,6 +14,29 @@
#include "players.h" #include "players.h"
#include "main.h" #include "main.h"
int cell_object_index = 0;
CELL_OBJECT cell_object_buffer[1024];
// [D] [T]
CELL_OBJECT* UnpackCellObject(PACKED_CELL_OBJECT* ppco, XZPAIR* near)
{
int newIndex;
CELL_OBJECT* pco;
#ifndef PSX
if (ppco == NULL)
return NULL;
#endif
pco = &cell_object_buffer[newIndex = cell_object_index];
cell_object_index = newIndex + 1 & 1023;
QuickUnpackCellObject(ppco, near, pco);
return pco;
}
// [D] [T] // [D] [T]
char CellEmpty(VECTOR *pPosition, int radius) char CellEmpty(VECTOR *pPosition, int radius)
{ {