mirror of
https://github.com/OpenDriver2/REDRIVER2.git
synced 2024-11-24 11:22:39 +01:00
- add dynamic lights support for PC
This commit is contained in:
parent
4059658834
commit
8e454c2354
136
data/config.ini
136
data/config.ini
@ -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
|
@ -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(>3rgb);
|
||||
|
||||
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(>3rgb);
|
||||
|
||||
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(>3rgb);
|
||||
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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
@ -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];
|
||||
|
@ -2387,6 +2387,11 @@ void RenderGame2(int view)
|
||||
DrawAllTheCars(view);
|
||||
|
||||
#ifndef PSX
|
||||
|
||||
#ifdef DYNAMIC_LIGHTING
|
||||
gNumDlights = 0;
|
||||
#endif
|
||||
|
||||
extern void DrawDebugOverlays();
|
||||
|
||||
DrawDebugOverlays();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user