- add dynamic lights support for PC

This commit is contained in:
Ilya Shurumov 2022-04-04 11:32:11 +06:00
parent 4059658834
commit 8e454c2354
10 changed files with 575 additions and 191 deletions

View File

@ -2,25 +2,6 @@
# dataFolder=REDRIVER2
# dataFolder=.
# Game keyboard controls (Psy-X layer PSX mapping)
[kbcontrols_game]
cross=up
square=down
circle=right shift
triangle=space
up=NONE
down=NONE
left=left
right=right
start=escape
select=c
l1=right ctrl
r1=H
l2=A
r2=D
l3=S
r3=return
# Available controller binds (refer to SDL2 game controller)
#
# Axes:
@ -37,51 +18,46 @@ r3=return
# leftshoulder rightshoulder
# dpup dpdown dpleft dpright
# Game keyboard controls (Psy-X layer PSX mapping)
[kbcontrols_game]
cross=Up
square=Down
circle=Right Shift
triangle=Space
up=
down=
left=Left
right=Right
start=Escape
select=C
l1=Right Ctrl
r1=H
l2=A
r2=D
l3=S
r3=Return
[controls_game]
# cross=a
# square=x
# circle=b
# triangle=y
# up=dpup
# down=dpdown
# left=dpleft
# right=dpright
# start=start
# select=back
# l1=leftshoulder
# r1=rightshoulder
# l2=lefttrigger
# r2=righttrigger
# l3=leftstick
# r3=rightstick
# axis_left_x=leftx
# axis_left_y=lefty
# axis_right_x=rightx
# axis_right_y=righty
[controls_menu]
# cross=x
# square=x
# circle=b
# triangle=y
# up=dpup
# down=dpdown
# left=dpleft
# right=dpright
# start=start
# select=back
# l1=leftshoulder
# r1=rightshoulder
# l2=lefttrigger
# r2=righttrigger
# l3=leftstick
# r3=rightstick
# axis_left_x=leftx
# axis_left_y=lefty
# axis_right_x=rightx
# axis_right_y=righty
cross=a
square=x
circle=b
triangle=y
up=dpup
down=dpdown
left=dpleft
right=dpright
start=start
select=back
l1=leftshoulder
r1=rightshoulder
l2=lefttrigger
r2=righttrigger
l3=leftstick
r3=rightstick
axis_left_x=leftx
axis_left_y=lefty
axis_right_x=rightx
axis_right_y=righty
[kbcontrols_menu]
cross=return
@ -97,31 +73,31 @@ start=w
select=H
[cdfs]
#image=install/Driver2CD1.bin
mode=1,2,2352 # track, mode, sector size. DO NOT MODIFY
image=install/Driver2CD1.bin
mode=1,2,2352 # track, mode, sector size. DO NOT MODIFY
[pad]
pad1device=-1 # player 1 controller device; -1 for automatic assignment
pad2device=-1 # player 2 controller device; -1 for automatic assignment
pad1device=-1 # player 1 controller device; -1 for automatic assignment
pad2device=-1 # player 2 controller device; -1 for automatic assignment
[render]
windowWidth=1280
windowHeight=720
fullscreen=0 # enable full screen mode
screenWidth=1280 # screen resolution when fullscreen is on
screenHeight=720
vsync=1 # Prevents screen tearing in Full screen. Turn it off if you have framerate problems.
fullscreen=0 # enable full screen mode; it takes screen resolution
pgxpTextureMapping=1
bilinearFiltering=1 # "smooth" textures
pgxpZbuffer=1 # full Z-buffer on PSX polygons
bilinearFiltering=1 # "smooth" textures
pgxpZbuffer=1 # full Z-buffer on PSX polygons
vsync=1
[game]
languageId=0 # 0 = ENGLISH; 1 = ITALIAN; 2 = GERMAN; 3 = FRENCH; 4 = SPANISH;
drawDistance=1800 # 441..1800
fieldOfView=256 # 128..384, 256 is default
disableChicagoBridges=0 # Experimental: also activate AI roads
freeCamera=1 # Press F7 in game to enable
languageId=0 # 0 = ENGLISH; 1 = ITALIAN; 2 = GERMAN; 3 = FRENCH; 4 = SPANISH;
drawDistance=1800 # 441..1800
dynamicLights=1 # set 1 to enable dynamic street lights
fieldOfView=256 # 128..384, 256 is default
disableChicagoBridges=0 # Experimental: also activate AI roads
freeCamera=1 # Press F7 in game to enable
fastLoadingScreens=1
widescreenOverlays=1 # set 1 to see map, bars and stats aligned to screen corners
driver1music=0 # put Driver 1's MUSIC.BIN as D1MUSIC.BIN to DRIVER2\SOUNDS folder
overrideContent=0 # this enables texture and car model modding
widescreenOverlays=1 # set 1 to see map, bars and stats aligned to screen corners
driver1music=0 # put Driver 1's MUSIC.BIN as D1MUSIC.BIN to DRIVER2\SOUND folder
overrideContent=0 # this enables texture and car model modding
userChases=RacingFreak,Snoopi,Olanov,Vortex,Fireboyd78

View File

@ -41,10 +41,24 @@ struct plotCarGlobals
#endif
MATRIX light_matrix =
{ { { 4096, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, { 0, 0, 0 } };
{
{
{ 4096, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 }
},
{ 0, 0, 0 }
};
MATRIX colour_matrix =
{ { { 4032, 0, 0 }, { 3936, 0, 0 }, { 3520, 0, 0 } }, { 0, 0, 0 } };
{
{
{ 4032, 0, 0 },
{ 3936, 0, 0 },
{ 3520, 0, 0 }
},
{ 0, 0, 0 }
};
// PHYSICS
CAR_DATA car_data[MAX_CARS + 2]; // all cars + Tanner cbox + Camera cbox
@ -269,6 +283,95 @@ void plotCarPolyGT3(int numTris, CAR_POLY *src, SVECTOR *vlist, SVECTOR *nlist,
pg->primptr = (unsigned char*)prim;
}
#ifdef DYNAMIC_LIGHTING
void plotCarPolyGT3Lit(int numTris, CAR_POLY* src, SVECTOR* vlist, SVECTOR* nlist, plotCarGlobals* pg, int palette)
{
int Z;
int otz;
SVECTOR* v2;
SVECTOR* v1;
SVECTOR* v0;
u_int indices;
POLY_GT3* prim;
u_int r0, r1, r2;
int ofse;
prim = (POLY_GT3*)pg->primptr;
int GT3rgb = pg->intensity | 0x34000000;
gte_ldrgb(&GT3rgb);
while (numTris > 0)
{
indices = src->vindices;
v0 = vlist + (indices & 0xff);
v1 = vlist + (indices >> 8 & 0xff);
v2 = vlist + (indices >> 16 & 0xff);
gte_ldv3(v0, v1, v2);
gte_rtpt();
gte_nclip();
gte_stopz(&Z);
gte_avsz3();
gte_stotz(&otz);
if (Z > -1 && otz > 0)
{
indices = src->nindices;
r0 = (u_int)(ushort)nlist[indices & 0xff].pad;
r1 = (u_int)(ushort)nlist[indices >> 8 & 0xff].pad;
r2 = (u_int)(ushort)nlist[indices >> 16 & 0xff].pad;
*(u_int*)&prim->r0 = (r0 & 0xff) << 0x10 | r0;
*(u_int*)&prim->r1 = (r1 & 0xff) << 0x10 | r1;
*(u_int*)&prim->r2 = (r2 & 0xff) << 0x10 | r2;
ofse = pg->damageLevel[src->originalindex];
*(u_int*)&prim->u0 = (src->clut_uv0 & 0xffffU | pg->pciv_clut[palette + (src->clut_uv0 >> 0x10)] << 0x10) + ofse;
*(u_int*)&prim->u1 = src->tpage_uv1 + ofse;
*(u_int*)&prim->u2 = src->uv3_uv2 + ofse;
gte_stsxy3(&prim->x0, &prim->x1, &prim->x2);
SVECTOR tmpPos;
gte_ldv0(v0);
gte_rtps();
gte_stsv(&tmpPos);
GetDLightLevel(&tmpPos, (u_int*)&prim->r0);
gte_ldv0(v1);
gte_rtps();
gte_stsv(&tmpPos);
GetDLightLevel(&tmpPos, (u_int*)&prim->r1);
gte_ldv0(v2);
gte_rtps();
gte_stsv(&tmpPos);
GetDLightLevel(&tmpPos, (u_int*)&prim->r2);
setPolyGT3(prim);
addPrim(pg->ot + (otz >> 1), prim);
prim++;
}
src++;
numTris--;
}
pg->primptr = (unsigned char*)prim;
}
#endif // DYNAMIC_LIGHTING
// [D] [T]
void plotCarPolyGT3nolight(int numTris, CAR_POLY *src, SVECTOR *vlist, plotCarGlobals *pg, int palette)
{
@ -298,11 +401,9 @@ void plotCarPolyGT3nolight(int numTris, CAR_POLY *src, SVECTOR *vlist, plotCarGl
gte_rtpt();
gte_nclip();
gte_stopz(&Z);
gte_avsz3();
gte_stotz(&otz);
if (Z > -1 && otz > 0)
@ -344,7 +445,7 @@ void setupLightingMatrices(void)
if (gTimeOfDay == 3)
{
gte_SetBackColor(64, 64, 64);
gte_SetBackColor(48, 48, 48);
}
else
{
@ -365,32 +466,24 @@ void ComputeCarLightingLevels(CAR_DATA* cp, char detail)
MATRIX& scratchPadMat = *(MATRIX*)((u_char*)getScratchAddr(0) + 0x344);
int doLight;
int orW;
int orY;
int orW, orY;
MODEL* model;
int num_norms;
int count;
int num_norms, count;
SVECTOR* ppads;
SVECTOR* norms;
SVECTOR lightsourcevector;
SVECTOR colour;
CVECTOR c0;
CVECTOR c1;
CVECTOR c2;
SVECTOR colour, lightsourcevector;
CVECTOR c0, c1, c2;
u_int GT3rgb;
if (gTimeOfDay > -1)
if (gTimeOfDay == 3)
{
if (gTimeOfDay < 3)
{
lightsourcevector = day_vectors[GameLevel];
colour = day_colours[GameLevel];
}
else if (gTimeOfDay == 3)
{
lightsourcevector = night_vectors[GameLevel];
colour = night_colours[GameLevel];
}
lightsourcevector = night_vectors[GameLevel];
colour = night_colours[GameLevel];
}
else
{
lightsourcevector = day_vectors[GameLevel];
colour = day_colours[GameLevel];
}
InvertMatrix(&cp->hd.where, &scratchPadMat);
@ -398,71 +491,58 @@ void ComputeCarLightingLevels(CAR_DATA* cp, char detail)
gte_ldv0(&lightsourcevector);
gte_rtv0();
gte_stsv(light_matrix.m[0]);
doLight = 0;
colour_matrix.m[0][0] = colour.vx;
colour_matrix.m[1][0] = colour.vy;
colour_matrix.m[2][0] = colour.vz;
if (gTimeOfDay != 3)
orY = ABS(cp->st.n.orientation[1] - cp->ap.qy);
orW = ABS(cp->st.n.orientation[3] - cp->ap.qw);
doLight = 0;
if ((orY + orW > 200) || (cp->lowDetail != (detail | lightning)))
doLight = 1;
if ((gTimeOfDay == 0 || gTimeOfDay == 2) && (cp->id & 15) == (CameraCnt & 15))
doLight = 1;
if (doLight)
{
orY = cp->st.n.orientation[1] - cp->ap.qy;
if (orY < 1)
orY = cp->ap.qy - cp->st.n.orientation[1];
orW = cp->st.n.orientation[3] - cp->ap.qw;
if (orW < 1)
orW = cp->ap.qw - cp->st.n.orientation[3];
if ((orY + orW > 200) || (cp->lowDetail != (detail | lightning)))
doLight = 1;
if ((gTimeOfDay == 0 || gTimeOfDay == 2) && (cp->id & 0xf) == (CameraCnt & 0xfU))
doLight = 1;
setupLightingMatrices();
if (doLight)
GT3rgb = combointensity & 0xffffffU | 0x34000000;
gte_ldrgb(&GT3rgb);
cp->ap.qy = cp->st.n.orientation[1];
cp->ap.qw = cp->st.n.orientation[3];
cp->lowDetail = detail | lightning;
if (detail == 0)
model = gCarLowModelPtr[cp->ap.model];
else
model = gCarCleanModelPtr[cp->ap.model];
num_norms = model->num_point_normals / 3;
norms = (SVECTOR*)model->point_normals;
ppads = gTempCarVertDump[cp->id];
count = num_norms;// +1;
while (count >= 0)
{
GT3rgb = combointensity & 0xffffffU | 0x34000000;
gte_ldrgb(&GT3rgb);
gte_ldv3(&norms[0], &norms[1], &norms[2]);
gte_ncct();
gte_strgb3(&c0, &c1, &c2);
cp->ap.qy = cp->st.n.orientation[1];
cp->ap.qw = cp->st.n.orientation[3];
cp->lowDetail = detail | lightning;
ppads[0].pad = *(short*)&c0;
ppads[1].pad = *(short*)&c1;
ppads[2].pad = *(short*)&c2;
if (detail == 0)
model = gCarLowModelPtr[cp->ap.model];
else
model = gCarCleanModelPtr[cp->ap.model];
num_norms = model->num_point_normals / 3;
norms = (SVECTOR*)model->point_normals;
ppads = gTempCarVertDump[cp->id];
count = num_norms;// +1;
while (count >= 0)
{
gte_ldv3(&norms[0], &norms[1], &norms[2]);
gte_ncct();
gte_strgb3(&c0, &c1, &c2);
ppads[0].pad = *(short*)&c0;
ppads[1].pad = *(short*)&c1;
ppads[2].pad = *(short*)&c2;
count--;
norms += 3;
ppads += 3;
}
count--;
norms += 3;
ppads += 3;
}
restoreLightingMatrices();
@ -855,12 +935,20 @@ void plotNewCarModel(CAR_MODEL* car, int palette)
if (gTimeOfDay == 3)
{
_pg.intensity = (combointensity & 0xfcfcf0U) >> 2;
#ifdef DYNAMIC_LIGHTING
(gEnableDlights ? plotCarPolyGT3Lit : plotCarPolyGT3)(car->numGT3, car->pGT3, car->vlist, car->nlist, &_pg, palette);
#else
plotCarPolyGT3nolight(car->numGT3, car->pGT3, car->vlist, &_pg, palette);
#endif // DYNAMIC_LIGHTING
}
else
{
_pg.intensity = combointensity & 0xffffff;
#ifdef DYNAMIC_LIGHTING
(gEnableDlights ? plotCarPolyGT3Lit : plotCarPolyGT3)(car->numGT3, car->pGT3, car->vlist, car->nlist, &_pg, palette);
#else
plotCarPolyGT3(car->numGT3, car->pGT3, car->vlist, car->nlist, &_pg, palette);
#endif
}
current->primptr = (char*)_pg.primptr;

View File

@ -1257,21 +1257,18 @@ int find_lamp_streak(int LampId)
return -1;
}
// [D] [T]
void AddSmallStreetLight(CELL_OBJECT *cop, int x, int y, int z, int type)
{
int count;
DAMAGED_LAMP* dam;
int halo_size;
short size;
short angle;
VECTOR v1;
VECTOR v2;
VECTOR v3;
SVECTOR pos;
CVECTOR col;
CVECTOR col1;
SVECTOR dpos;
short size, angle;
VECTOR v1, v2, v3;
SVECTOR pos, dpos;
CVECTOR col, col1;
dam = damaged_lamp;
col = {140, 140, 140};
@ -1296,7 +1293,8 @@ void AddSmallStreetLight(CELL_OBJECT *cop, int x, int y, int z, int type)
}
count = 0;
do {
for(count = 0; count < 4; count++)
{
if (dam->index == cop->pos.vx + cop->pos.vz)
{
if (dam->damage > 2)
@ -1308,10 +1306,8 @@ void AddSmallStreetLight(CELL_OBJECT *cop, int x, int y, int z, int type)
break;
}
count++;
dam++;
} while (count < 4);
}
dpos.vx = cop->pos.vx - camera_position.vx;
dpos.vy = cop->pos.vy - camera_position.vy;
@ -1381,6 +1377,10 @@ void AddSmallStreetLight(CELL_OBJECT *cop, int x, int y, int z, int type)
DisplayLightReflections(&v2, &col1, halo_size * 2, &lightref_texture);
#ifdef DYNAMIC_LIGHTING
AddDlight(&v3, &col, size * 280 >> 4);
#endif // DYNAMIC_LIGHTING
LightSortCorrect = -10;
}
@ -1390,8 +1390,7 @@ void AddLightEffect(CELL_OBJECT *cop, int x, int y, int z, int type, int colour)
short yang;
int angle;
int size;
VECTOR v1;
VECTOR v2;
VECTOR v1, v2;
VECTOR dpos;
SVECTOR pos;
CVECTOR col;
@ -1503,6 +1502,11 @@ void AddLightEffect(CELL_OBJECT *cop, int x, int y, int z, int type, int colour)
gte_SetTransVector(&v1);
ShowLight1(&v1, &col, size, &light_texture);
#ifdef DYNAMIC_LIGHTING
AddDlight(&v1, &col, size * 180 >> 4);
#endif // DYNAMIC_LIGHTING
DisplayLightReflections(&v2, &col, (size << 0xd) >> 0x10, &lightref_texture);
}

View File

@ -525,30 +525,23 @@ void DrawAllTheCars(int view)
{
gForceLowDetailCars = 0;
// sort cars by distance
i = 1;
while (i < num_cars_to_draw)
// insertion sort of cars by distance
for (i = 1; i < num_cars_to_draw; i++)
{
cp = cars_to_draw[i];
dist = car_distance[i];
j = i - 1;
while (dist < car_distance[j])
while (j >= 0 && dist < car_distance[j])
{
car_distance[i] = car_distance[j];
cars_to_draw[i] = cars_to_draw[j];
if (j == 0)
break;
j--;
}
cars_to_draw[i] = cp;
car_distance[i] = dist;
i++;
cars_to_draw[j+1] = cp;
car_distance[j+1] = dist;
}
i = 0;
@ -1550,6 +1543,9 @@ void DrawMapPSX(int* comp_val)
SetupPlaneColours(combointensity);
if (drawData.anim_objs_found)
DrawAllAnimatingObjects((CELL_OBJECT**)anim_obj_buffer, drawData.anim_objs_found);
if (drawData.sprites_found)
DrawSprites((PACKED_CELL_OBJECT**)spriteList, drawData.sprites_found);
@ -1559,8 +1555,74 @@ void DrawMapPSX(int* comp_val)
if (drawData.other_models_found)
DrawAllBuildings((CELL_OBJECT**)model_object_ptrs, drawData.other_models_found);
if (drawData.anim_objs_found)
DrawAllAnimatingObjects((CELL_OBJECT**)anim_obj_buffer, drawData.anim_objs_found);
setupYet = 0;
}
#ifdef DYNAMIC_LIGHTING
struct DLIGHT
{
SVECTOR position;
CVECTOR color;
};
int gEnableDlights = 0;
int gNumDlights = 0;
DLIGHT gLights[MAX_DLIGHTS];
void AddDlight(VECTOR* position, CVECTOR* color, int radius)
{
DLIGHT* pLight;
VECTOR lightPos;
if (gNumDlights + 1 >= MAX_DLIGHTS)
{
return;
}
pLight = &gLights[gNumDlights++];
lightPos = *position;
VecCopy(&pLight->position, &lightPos);
pLight->position.pad = ABS(radius);
pLight->color = *color;
}
void GetDLightLevel(SVECTOR* position, u_int* inOutColor)
{
DLIGHT* pLight;
int dx, dy, dz, dist, light;
u_int lightR, lightG, lightB;
lightR = (*inOutColor & 255);
lightG = (*inOutColor >> 8 & 255);
lightB = (*inOutColor >> 16 & 255);
for (int i = 0; i < gNumDlights; i++)
{
int radius;
pLight = &gLights[i];
dx = (int)position->vx - (int)pLight->position.vx;
dy = (int)position->vy - (int)pLight->position.vy;
dz = (int)position->vz - (int)pLight->position.vz;
dist = SquareRoot0(dx * dx + dy * dy + dz * dz);
radius = pLight->position.pad;
if (dist > radius) {
continue;
}
light = radius - dist;
lightR += pLight->color.r * light >> 13;
lightG += pLight->color.g * light >> 13;
lightB += pLight->color.b * light >> 13;
}
*inOutColor = MIN(lightB, 255) << 16 | MIN(lightG, 255) << 8 | MIN(lightR, 255) | (*inOutColor & 0xFF000000);
}
#endif // DYNAMIC_LIGHTING

View File

@ -21,6 +21,14 @@ struct _pct
int model;
};
#ifdef DYNAMIC_LIGHTING
extern int gEnableDlights;
extern int gNumDlights;
extern void AddDlight(VECTOR* position, CVECTOR* color, int radius);
extern void GetDLightLevel(SVECTOR* position, u_int* inOutColor);
#endif
extern SVECTOR day_vectors[4];
extern SVECTOR night_vectors[4];
extern SVECTOR day_colours[4];

View File

@ -2387,6 +2387,11 @@ void RenderGame2(int view)
DrawAllTheCars(view);
#ifndef PSX
#ifdef DYNAMIC_LIGHTING
gNumDlights = 0;
#endif
extern void DrawDebugOverlays();
DrawDebugOverlays();

View File

@ -14,6 +14,7 @@
#include "spool.h"
#include "system.h"
#include "pause.h"
#include "draw.h"
struct ANIMATED_OBJECT
{
@ -337,6 +338,13 @@ void InitAnimatingObjects(void)
modelPtr = modelpointers[model_idx];
modelPtr->flags2 |= MODEL_FLAG_ANIMOBJ;
#ifdef DYNAMIC_LIGHTING
if (gEnableDlights)
{
modelPtr->bounding_sphere <<= 3;
}
#endif // DYNAMIC_LIGHTING
if (aop->LitPoly)
modelPtr->flags2 |= MODEL_FLAG_LAMP;
@ -350,6 +358,13 @@ void InitAnimatingObjects(void)
modelPtr = modelpointers[modelPtr->instance_number];
modelPtr->flags2 |= MODEL_FLAG_ANIMOBJ;
#ifdef DYNAMIC_LIGHTING
if (gEnableDlights)
{
modelPtr->bounding_sphere <<= 3;
}
#endif // DYNAMIC_LIGHTING
if (aop->LitPoly)
modelPtr->flags2 |= MODEL_FLAG_LAMP;
@ -388,6 +403,13 @@ void InitSpooledAnimObj(int model_number)
if (aop->LitPoly)
modelPtr->flags2 |= MODEL_FLAG_LAMP;
#ifdef DYNAMIC_LIGHTING
if (gEnableDlights)
{
modelPtr->bounding_sphere <<= 3;
}
#endif // DYNAMIC_LIGHTING
// [A] store animated object number in normals pointer
// after all it was always unused
modelPtr->tri_verts = i;

View File

@ -8,6 +8,113 @@
#include "ASM/rndrasm.h"
#ifdef DYNAMIC_LIGHTING
void Tile1x1Lit(MODEL* model)
{
int opz, Z;
int ofse;
PL_POLYFT4* polys;
int i;
u_char ptype;
POLY_GT4* prims;
SVECTOR* srcVerts;
srcVerts = (SVECTOR*)model->vertices;
polys = (PL_POLYFT4*)model->poly_block;
// grass should be under pavements and other things
if ((model->shape_flags & SHAPE_FLAG_WATER) || (model->flags2 & MODEL_FLAG_GRASS))
ofse = 229;
else
ofse = 133;
#ifdef USE_PGXP
PGXP_SetZOffsetScale(0.0f, ofse > 200 ? 1.005f : 0.995f);
#endif
i = model->num_polys;
while (i-- > 0)
{
// iterate through polygons
// with skipping
ptype = polys->id & 0x1f;
// perform transform
gte_ldv3(&srcVerts[polys->v0], &srcVerts[polys->v1], &srcVerts[polys->v3]);
gte_rtpt();
// get culling value
gte_nclip();
gte_stopz(&opz);
if (opz > 0)
{
prims = (POLY_GT4*)plotContext.primptr;
*(ulong*)&prims->r0 = plotContext.colour;
*(ulong*)&prims->r1 = plotContext.colour;
*(ulong*)&prims->r2 = plotContext.colour;
*(ulong*)&prims->r3 = plotContext.colour;
setPolyGT4(prims);
// retrieve first three verts
gte_stsxy3(&prims->x0, &prims->x1, &prims->x2);
// translate 4th vert and get OT Z value
gte_ldv0(&srcVerts[polys->v2]);
gte_rtps();
gte_avsz4();
gte_stotz(&Z);
gte_stsxy(&prims->x3);
prims->tpage = (*plotContext.ptexture_pages)[polys->texture_set];
prims->clut = (*plotContext.ptexture_cluts)[polys->texture_set][polys->texture_id];
*(ushort*)&prims->u0 = *(ushort*)&polys->uv0;
*(ushort*)&prims->u1 = *(ushort*)&polys->uv1;
*(ushort*)&prims->u2 = *(ushort*)&polys->uv3;
*(ushort*)&prims->u3 = *(ushort*)&polys->uv2;
SVECTOR tmpPos;
gte_ldv0(&srcVerts[polys->v0]);
gte_rtps();
gte_stsv(&tmpPos);
GetDLightLevel(&tmpPos, (u_int*)&prims->r0);
gte_ldv0(&srcVerts[polys->v1]);
gte_rtps();
gte_stsv(&tmpPos);
GetDLightLevel(&tmpPos, (u_int*)&prims->r1);
gte_ldv0(&srcVerts[polys->v3]);
gte_rtps();
gte_stsv(&tmpPos);
GetDLightLevel(&tmpPos, (u_int*)&prims->r2);
gte_ldv0(&srcVerts[polys->v2]);
gte_rtps();
gte_stsv(&tmpPos);
GetDLightLevel(&tmpPos, (u_int*)&prims->r3);
addPrim(plotContext.ot + (Z >> 1) + ofse, prims);
plotContext.primptr += sizeof(POLY_GT4);
}
polys = (PL_POLYFT4*)((char*)polys + plotContext.polySizes[ptype]);
}
#ifdef USE_PGXP
PGXP_SetZOffsetScale(0.0f, 1.0f);
#endif
// done
plotContext.current->primptr = plotContext.primptr;
}
#endif
// [D] [T] [A]
void Tile1x1(MODEL *model)
{
@ -51,9 +158,9 @@ void Tile1x1(MODEL *model)
{
prims = (POLY_FT4*)plotContext.primptr;
setPolyFT4(prims);
*(ulong*)&prims->r0 = plotContext.colour;
setPolyFT4(prims);
// retrieve first three verts
gte_stsxy3(&prims->x0, &prims->x1, &prims->x2);
@ -160,14 +267,18 @@ void DrawTILES(PACKED_CELL_OBJECT** tiles, int tile_amount)
if (Z < 2000)
TileNxN(pModel, 4, 75);
else
else
TileNxN(pModel, 2, 35);
}
else
{
pModel = Z > DRAW_LOD_DIST_LOW ? pLodModels[model_number] : modelpointers[model_number];
#ifdef DYNAMIC_LIGHTING
(gEnableDlights ? Tile1x1Lit : Tile1x1)(pModel);
#else
Tile1x1(pModel);
#endif // DYNAMIC_LIGHTING
}
}
current->primptr = plotContext.primptr;
@ -356,6 +467,102 @@ void drawMesh(MVERTEX(*VSP)[5][5], int m, int n, _pct *pc)
pc->primptr = (char*)prim;
}
#ifdef DYNAMIC_LIGHTING
void drawMeshLit(MVERTEX(*VSP)[5][5], int m, int n, _pct* pc)
{
POLY_GT4* prim;
int z, opz;
prim = (POLY_GT4*)pc->primptr;
int numPolys = 4;
if (n < 2)
numPolys = 1;
#if 0
// no need to subdivide!
if (g_pgxpZBuffer)
numPolys = 1;
#endif
for (int index = 0; index < numPolys; index++)
{
setPolyGT4(prim);
// test
gte_ldv3(&(*VSP)[index][0], &(*VSP)[index][1], &(*VSP)[index][2]);
gte_rtpt();
gte_nclip();
gte_stopz(&opz);
gte_avsz3();
gte_stotz(&z);
if (pc->flags & (PLOT_NO_CULL | PLOT_INV_CULL))
{
if (pc->flags & PLOT_NO_CULL)
opz = 1; // no culling
else // PLOT_FRONT_CULL
opz = -opz; // front face
}
if (opz > 0 && z > 5)
{
gte_stsxy3(&prim->x0, &prim->x1, &prim->x2);
gte_ldv0(&(*VSP)[index][3]);
gte_rtps();
gte_stsxy(&prim->x3);
* (ulong*)&prim->r0 = plotContext.colour;
*(ulong*)&prim->r1 = plotContext.colour;
*(ulong*)&prim->r2 = plotContext.colour;
*(ulong*)&prim->r3 = plotContext.colour;
SVECTOR tmpPos;
gte_ldv0(&(*VSP)[index][0]);
gte_rtps();
gte_stsv(&tmpPos);
GetDLightLevel(&tmpPos, (u_int*)&prim->r0);
gte_ldv0(&(*VSP)[index][1]);
gte_rtps();
gte_stsv(&tmpPos);
GetDLightLevel(&tmpPos, (u_int*)&prim->r1);
gte_ldv0(&(*VSP)[index][2]);
gte_rtps();
gte_stsv(&tmpPos);
GetDLightLevel(&tmpPos, (u_int*)&prim->r2);
gte_ldv0(&(*VSP)[index][3]);
gte_rtps();
gte_stsv(&tmpPos);
GetDLightLevel(&tmpPos, (u_int*)&prim->r3);
setPolyGT4(prim);
* (ushort*)&prim->u0 = (*VSP)[index][0].uv.val;
*(ushort*)&prim->u1 = (*VSP)[index][1].uv.val;
*(ushort*)&prim->u2 = (*VSP)[index][2].uv.val;
*(ushort*)&prim->u3 = (*VSP)[index][3].uv.val;
prim->clut = pc->clut >> 0x10;
prim->tpage = pc->tpage >> 0x10;
addPrim(pc->ot + (z >> 1), prim);
prim++;
}
}
pc->primptr = (char*)prim;
}
#endif // DYNAMIC_LIGHTING
// [A] custom implemented function
void SubdivNxM(char *polys, int n, int m, int ofse)
{
@ -383,7 +590,11 @@ void SubdivNxM(char *polys, int n, int m, int ofse)
plotContext.ot += ofse;
makeMesh((MVERTEX(*)[5][5])subdivVerts, m, n);
#ifdef DYNAMIC_LIGHTING
(gEnableDlights ? drawMeshLit : drawMesh)((MVERTEX(*)[5][5])subdivVerts, m, n, &plotContext);
#else
drawMesh((MVERTEX(*)[5][5])subdivVerts, m, n, &plotContext);
#endif
plotContext.ot -= ofse;
}

View File

@ -4,6 +4,12 @@
// DRIVER 2 game engine limits
// please populate this file only with engine limits during refactoring
#ifndef PSX
#define DYNAMIC_LIGHTING
#define MAX_DLIGHTS 32
#endif
#ifndef PSX
#define MAX_PLAYERS 16 // used for replay streams mostly
#else

View File

@ -19,6 +19,7 @@
#include "C/overlay.h"
#include "C/players.h"
#include "C/time.h"
#include "C/draw.h"
#include "utils/ini.h"
@ -584,6 +585,7 @@ int main(int argc, char** argv)
// configure host game
ini_sget(config, "game", "drawDistance", "%d", &gDrawDistance);
ini_sget(config, "game", "dynamicLights", "%d", &gEnableDlights);
ini_sget(config, "game", "disableChicagoBridges", "%d", &gDisableChicagoBridges);
ini_sget(config, "game", "fieldOfView", "%d", &newScrZ);
ini_sget(config, "game", "freeCamera", "%d", &enableFreecamera);