MuckyFoot-UrbanChaos/fallen/Source/tracks.cpp
2017-05-20 11:14:17 +10:00

379 lines
8.1 KiB
C++

//
// tracks.cpp
// tyre tracks, footprints...
// 22 sept 98
//
#include "game.h"
#include "tracks.h"
#include "structs.h"
#ifndef PSX
#include "C:\fallen\DDEngine\Headers\poly.h"
#else
#include "c:\fallen\psxeng\headers\poly.h"
#endif
#include "person.h"
#include "puddle.h"
#include "pap.h"
#include "interact.h"
#include "animate.h"
#include "sound.h"
#include "memory.h"
//...debug...
#include "dirt.h"
#define TRACK_WATER_COLOUR 0x203D60
#define TRACK_MUDDY_COLOUR 0x482000
#define TRACK_ONSNOW_COLOUR 0x000000
Track *tracks;//[TRACK_BUFFER_LENGTH];
UWORD track_head,track_tail,track_eob; //stopped them being pointers by MikeD
void TRACKS_InitOnce(SWORD size)
{
track_eob=size; //&tracks[TRACK_BUFFER_LENGTH]; // yes, intentionally one past the end of the buffer
track_head=track_tail=0;//tracks;
memset((UBYTE*)tracks,0,sizeof(Track)*size);
}
void TRACKS_Reset(SWORD size)
{
while (track_tail!=track_head)
{
remove_thing_from_map(TO_THING(TO_TRACK(track_tail)->thing));
free_thing(TO_THING(TO_TRACK(track_tail)->thing));
track_tail++;
if (track_tail==track_eob) track_tail=0;//tracks;
}
TRACKS_InitOnce(size);
}
inline void RShift8(SLONG &x, SLONG &y, SLONG &z) {
x>>=8; y>>=8; z>>=8;
}
/*
void TRACKS_Draw() {
Track *walk;
walk=track_tail;
while (walk!=track_head) {
TRACKS_DrawTrack(TO_THING(walk->thing));
walk++;
if (walk==track_eob) walk=tracks;
}
}
*/
// Figure out the offsets given the width
void TRACKS_CalcDiffs(Track &track, UBYTE width) {
/* SLONG x,z,sf;
ULONG ux,uz,f;
// x=(track.dz)*256; z=-(track.dx)*256;
x=(track.dz); z=-(track.dx);
//TRACE("track calc x: %d y: %d\n",x,z);
ux=abs(x); uz=abs(z);
ux*=ux; uz*=uz;
f=ux+uz;
f=Root(f); if (!f) f=1;
sf=f;
TRACE("track -- x: %d z: %d f: %d ux: %d uz: %d\n",x,z,f,ux,uz);
x*=width; z*=width;
x/=sf; z/=sf;
TRACE("result: x: %d z: %d\n",x,z);
track.sx=x; track.sz=z;*/
SLONG x,z,f;
x=(track.dz); z=-(track.dx);
f=Root((x*x)+(z*z));
if (!f) f=1;
x*=width; z*=width; x/=f; z/=f;
track.sx=x; track.sz=z;
// TRACE("result: x: %d z: %d\n",x,z);
}
// Add a track unit supplying exact parameters one by one
void TRACKS_AddQuad(SLONG x, SLONG y, SLONG z, SLONG dx, SLONG dy, SLONG dz, SLONG page, SLONG colour, UBYTE width, UBYTE flip, UBYTE flags) {
Track track;
// THING_INDEX t_index;
Thing *thing;
thing = alloc_thing(CLASS_TRACK);
if (thing) {
// thing=TO_THING(t_index);
track.thing=THING_NUMBER(thing);
thing->Class = CLASS_TRACK;
thing->WorldPos.X=x;
thing->WorldPos.Y=y;
thing->WorldPos.Z=z;
thing->DrawType=DT_TRACK;
thing->Flags=0;
add_thing_to_map(thing);
track.dx=dx; track.dy=dy; track.dz=dz;
track.page=page; track.colour=colour; track.flip=flip; //track.width=width;
track.flags=flags; track.splut=0; track.splutmax=1+(width>>1);
TRACKS_CalcDiffs(track,width);
TRACKS_AddTrack(track);
}
}
// Add a track unit supplying a completed track entry
void TRACKS_AddTrack(Track &track)
{
*(TO_TRACK(track_head))=track;
// debug -- back up x/y/z
// track_head->x=track_head->thing->WorldPos.X;
// track_head->y=track_head->thing->WorldPos.Y;
// track_head->z=track_head->thing->WorldPos.Z;
// hee hee //ho ho
TO_THING(TO_TRACK(track_head)->thing)->Genus.Track=TO_TRACK(track_head);
track_head++;
if (track_head==track_eob) track_head=0; //tracks;
if (track_head==track_tail)
{
// TRACE("stomp\n");
// stomping one, so free it's thing first (woof)
remove_thing_from_map(TO_THING(TO_TRACK(track_tail)->thing));
free_thing(TO_THING(TO_TRACK(track_tail)->thing));
track_tail++;
if (track_tail==track_eob) track_tail=0; //tracks;
}
}
// Add a track unit "intelligently" supplying coordinates and a type of track
UWORD TRACKS_Add(SLONG x, SLONG y, SLONG z, SLONG dx, SLONG dy, SLONG dz, UBYTE type, UWORD last) {
UBYTE age=last>>8;
UBYTE lastkind=last&0xff;
SLONG code,kind,page,colour;
CBYTE msg[20];
switch (type) {
case TRACK_TYPE_TYRE_SKID:
// TRACKS_AddQuad(x, y, z, dx, dy, dz, POLY_PAGE_TYRESKID, 0x00ffffff, 10, 0, TRACK_FLAGS_INVALPHA);
TRACKS_AddQuad(x, y, z, dx, dy, dz, POLY_PAGE_TYRESKID, 0x00ffffff, 10, 0, 0);
break;
case TRACK_TYPE_TYRE: // muddy tyres (not skidmarks)
if ((!dx)&&(!dy)&&(!dz)) return last;
if (SDIST2(dx,dz)>25) {
code=TRACKS_GroundAtXZ(x,z);
switch(code) {
case PERSON_ON_WATER:
kind=TRACK_SURFACE_WATER;
break;
case PERSON_ON_GRAVEL:
case PERSON_ON_GRASS:
kind=TRACK_SURFACE_MUDDY;
break;
default:
kind=TRACK_SURFACE_NONE;
}
if (lastkind!=TRACK_SURFACE_NONE) {
page=POLY_PAGE_TYRETRACK;
switch (lastkind) {
case TRACK_SURFACE_MUDDY:
colour=TRACK_MUDDY_COLOUR;
break;
case TRACK_SURFACE_WATER:
colour=TRACK_WATER_COLOUR;
break;
}
colour+=((255-age)<<24);
TRACKS_AddQuad(x, y, z, dx, dy, dz, page, colour, 10, 0, 0);
}
}
// fade or renew tracks
//
if (kind==TRACK_SURFACE_NONE) {
if (age>8) {
age-=8;
} else {
lastkind=TRACK_SURFACE_NONE;
age=0;
}
} else {
age=255;
lastkind=kind;
}
break;
case TRACK_TYPE_LEFT_PRINT:
case TRACK_TYPE_RIGHT_PRINT:
if (world_type==WORLD_TYPE_SNOW)
kind=TRACK_SURFACE_ONSNOW;
else
{
code=TRACKS_GroundAtXZ(x,z);
switch(code) {
case PERSON_ON_WATER:
kind=TRACK_SURFACE_WATER;
break;
case PERSON_ON_GRAVEL:
case PERSON_ON_GRASS:
kind=TRACK_SURFACE_MUDDY;
break;
default:
kind=TRACK_SURFACE_NONE;
}
}
//
// do combination of kind/lastkind;
//
if (lastkind!=TRACK_SURFACE_NONE) {
// page=POLY_PAGE_FLAMES;
page=POLY_PAGE_FOOTPRINT;
switch (lastkind) {
case TRACK_SURFACE_MUDDY:
colour=TRACK_MUDDY_COLOUR;
break;
case TRACK_SURFACE_WATER:
colour=TRACK_WATER_COLOUR;
break;
case TRACK_SURFACE_ONSNOW:
colour=TRACK_ONSNOW_COLOUR;
}
colour+=((255-age)<<24);
TRACKS_AddQuad(x, y, z, dx, dy, dz, page, colour, 10, (type==TRACK_TYPE_RIGHT_PRINT), TRACK_FLAGS_FLIPABLE);
}
// fade or renew tracks
//
if (kind==TRACK_SURFACE_NONE) {
if (age>8) {
age-=8;
} else {
lastkind=TRACK_SURFACE_NONE;
age=0;
}
} else {
age=255;
lastkind=kind;
}
break;
}
last=(age<<8)+lastkind;
return last;
}
SLONG TRACKS_GroundAtXZ(SLONG X, SLONG Z) {
//
// Standing in a puddle?
//
#ifndef PSX
#ifndef TARGET_DC
if (PUDDLE_in(X >> 8,Z >> 8)) return PERSON_ON_WATER;
#endif
#endif
//
// Check for special floor textures...
//
SLONG mx = X >> 16;
SLONG mz = Z >> 16;
if (WITHIN(mx, 0, MAP_WIDTH - 1) &&
WITHIN(mz, 0, MAP_HEIGHT - 1))
{
SLONG page = PAP_2HI(mx,mz).Texture & 0x3ff;
if (page == 65 ||
page == 66 ||
page == 143)
{
return PERSON_ON_WOOD;
}
if (page >= 69 && page <= 74)
{
return PERSON_ON_GRASS;
}
if (page == 68 || (page >= 106 && page <= 111))
{
return PERSON_ON_GRAVEL;
}
}
return PERSON_ON_DUNNO;
}
void TRACKS_Bleed(Thing *bleeder) {
//#ifdef VERSION_GERMAN
if(!VIOLENCE)
return;
//#endif
UBYTE sz=1+(rand()&0x1f);
UBYTE u=(Random()&1)?SUB_OBJECT_LEFT_FOOT:SUB_OBJECT_RIGHT_FOOT;
SLONG dx, dr, dz,x,y,z;
dr=rand()&2047;
dx=((SIN(dr)>>8)*sz)>>8;
dz=((COS(dr)>>8)*sz)>>8;
if ((dx==0)&&(dz==0)) dz=1;
calc_sub_objects_position(
bleeder,
bleeder->Draw.Tweened->AnimTween,
u,
&x,
&y,
&z);
x<<=8; z<<=8;
x+=bleeder->WorldPos.X;
z+=bleeder->WorldPos.Z;
x+=(rand()&0247)-1024; z+=(rand()&2047)-1024;
y=(PAP_calc_map_height_at(x>>8,z>>8)<<8)+257;
TRACKS_AddQuad(x, y, z, dx, 0, dz, POLY_PAGE_BLOODSPLAT, 0x00ffffff, sz, 0, TRACK_FLAGS_SPLUTTING);
}
void TRACKS_Bloodpool(Thing *bleeder) {
//#ifdef VERSION_GERMAN
if(!VIOLENCE)
return;
//#endif
UBYTE sz=80+(rand()&0x1f);
SLONG dx, dr, dz,x,y,z;
dr=rand()&2047;
dx=((SIN(dr)>>8)*sz)>>8;
dz=((COS(dr)>>8)*sz)>>8;
if ((dx==0)&&(dz==0)) dz=1;
calc_sub_objects_position(
bleeder,
bleeder->Draw.Tweened->AnimTween,
SUB_OBJECT_PELVIS,
&x,
&y,
&z);
x<<=8; z<<=8;
x+=bleeder->WorldPos.X;
z+=bleeder->WorldPos.Z;
x-=(dx/2); z-=(dz/2);
y=(PAP_calc_height_at_thing(bleeder,x>>8,z>>8)<<8)+257;
TRACKS_AddQuad(x, y, z, dx, 0, dz, POLY_PAGE_BLOODSPLAT, 0x00ffffff, sz, 0, TRACK_FLAGS_SPLUTTING);
}