296 lines
5.7 KiB
C
296 lines
5.7 KiB
C
#ifndef LIGHTG_H
|
|
#define LIGHTG_H
|
|
|
|
//
|
|
// Do we want coloured lights?
|
|
//
|
|
|
|
#define LIGHT_COLOURED 1
|
|
|
|
|
|
//
|
|
// A structure that describes a light.
|
|
//
|
|
|
|
typedef struct
|
|
{
|
|
SLONG x;
|
|
SLONG y;
|
|
SLONG z;
|
|
UBYTE red;
|
|
UBYTE green;
|
|
UBYTE blue;
|
|
UBYTE range;
|
|
UBYTE type;
|
|
UBYTE param;
|
|
UWORD dummy;
|
|
|
|
} LIGHT_Save;
|
|
|
|
|
|
|
|
//
|
|
// A light colour.
|
|
//
|
|
|
|
#if LIGHT_COLOURED
|
|
|
|
typedef struct
|
|
{
|
|
UBYTE red;
|
|
UBYTE green;
|
|
UBYTE blue;
|
|
|
|
} LIGHT_Colour;
|
|
|
|
#else
|
|
|
|
typedef UBYTE LIGHT_Colour;
|
|
|
|
#endif
|
|
|
|
//
|
|
// UBYTE values of lights go from 0 to LIGHT_MAX_BRIGHT, all values above
|
|
// LIGHT_MAX_BRIGHT are at maximum brightness.
|
|
//
|
|
|
|
#define LIGHT_MAX_BRIGHT 64
|
|
|
|
//
|
|
// The maximum range of the light in world coords.
|
|
//
|
|
|
|
#define LIGHT_MAX_RANGE 0x600
|
|
|
|
|
|
//
|
|
// So the light module can work with any sort of height field.
|
|
// The LIGHT_Map you pass can be on the stack because the
|
|
// function takes a copy of it.
|
|
//
|
|
|
|
typedef struct
|
|
{
|
|
SLONG width;
|
|
SLONG height;
|
|
|
|
SLONG (*get_height)(SLONG x, SLONG z); // 0 <= x < width, 0 <= z < height
|
|
LIGHT_Colour (*get_light) (SLONG x, SLONG z);
|
|
void (*set_light) (SLONG x, SLONG z, LIGHT_Colour light);
|
|
|
|
} LIGHT_Map;
|
|
|
|
void LIGHT_set_hf(LIGHT_Map *map);
|
|
|
|
|
|
//
|
|
// Sets the ambient light used. The normal of the light should have
|
|
// a length of 255.
|
|
//
|
|
|
|
extern LIGHT_Colour LIGHT_amb_colour; // DONT SET THESE VALUES, USE THE FUNCTION BELOW!
|
|
extern SLONG LIGHT_amb_norm_x;
|
|
extern SLONG LIGHT_amb_norm_y;
|
|
extern SLONG LIGHT_amb_norm_z;
|
|
|
|
void LIGHT_set_ambient(
|
|
LIGHT_Colour amb_colour,
|
|
SLONG amb_norm_x,
|
|
SLONG amb_norm_y,
|
|
SLONG amb_norm_z);
|
|
|
|
//
|
|
// Removes all lights and removes all cached light info.
|
|
//
|
|
|
|
void LIGHT_init(void);
|
|
|
|
|
|
//
|
|
// Where building-point lighting goes.
|
|
//
|
|
|
|
extern LIGHT_Colour LIGHT_building_point[RMAX_PRIM_POINTS];
|
|
|
|
|
|
//
|
|
// Recalcs all lighting on the current height-field and puts values in the
|
|
// LIGHT_building_point[] array for the lights on the building prim points.
|
|
//
|
|
|
|
void LIGHT_recalc_hf(void);
|
|
|
|
|
|
|
|
|
|
//
|
|
// Lights...
|
|
//
|
|
|
|
typedef UWORD LIGHT_Index;
|
|
|
|
|
|
//
|
|
// Creates a new light. The meaning of 'param' depends on
|
|
// the type of light.
|
|
//
|
|
|
|
#define LIGHT_TYPE_NORMAL 1
|
|
#define LIGHT_TYPE_BROKEN 2 // param is how often the light flickers off.
|
|
#define LIGHT_TYPE_PULSE 3 // param is the speed of flashing.
|
|
#define LIGHT_TYPE_FADE 4 // param is how long the light lasts.
|
|
|
|
LIGHT_Index LIGHT_create(
|
|
GameCoord where,
|
|
LIGHT_Colour colour,
|
|
UBYTE range,
|
|
UBYTE type,
|
|
UBYTE param);
|
|
|
|
void LIGHT_destroy(LIGHT_Index l_index);
|
|
|
|
//
|
|
// Gets/sets a light's position.
|
|
//
|
|
|
|
GameCoord LIGHT_pos_get(LIGHT_Index l_index);
|
|
void LIGHT_pos_set(LIGHT_Index l_index, GameCoord pos);
|
|
|
|
|
|
//
|
|
// Processes all the lights.
|
|
//
|
|
|
|
void LIGHT_process(void);
|
|
|
|
|
|
|
|
//
|
|
// Returns a value that identifies the lighting context of the given thing.
|
|
// If the lighting context changes then that thing needs to be re-lit. The
|
|
// position and orientation of the actual thing is not taken into account
|
|
// in the context. You have to check for that yourself.
|
|
//
|
|
|
|
SLONG LIGHT_get_context(THING_INDEX t_index);
|
|
|
|
|
|
//
|
|
// Returns the colour of light at the given point. It only uses light found
|
|
// in the last call to LIGHT_get_context.
|
|
//
|
|
|
|
LIGHT_Colour LIGHT_get_point(SLONG x, SLONG y, SLONG z);
|
|
|
|
|
|
//
|
|
// Lights the given prim. It puts the light values in the LIGHT_point_colour array.
|
|
// Uses the prim_normal array... make sure you've called calc_prim_normals();
|
|
//
|
|
|
|
void LIGHT_prim (THING_INDEX t_index);
|
|
void LIGHT_prim_use_normals(THING_INDEX t_index);
|
|
|
|
//
|
|
// Lights a building. It puts the light values in the LIGHT_point_colour array.
|
|
//
|
|
|
|
void LIGHT_building_use_normals(THING_INDEX t_index);
|
|
|
|
//
|
|
// The array in which the colours of the points will be returned.
|
|
//
|
|
|
|
#define LIGHT_MAX_POINTS 2560
|
|
|
|
extern LIGHT_Colour LIGHT_point_colour[LIGHT_MAX_POINTS];
|
|
extern SLONG LIGHT_point_colour_upto;
|
|
|
|
|
|
|
|
//
|
|
// Returns a D3D colour from a LIGHT_Colour.
|
|
//
|
|
|
|
#if LIGHT_COLOURED
|
|
inline void LIGHT_get_d3d_colour(LIGHT_Colour col, ULONG *colour, ULONG *specular)
|
|
{
|
|
SLONG red = col.red;
|
|
SLONG green = col.green;
|
|
SLONG blue = col.blue;
|
|
|
|
SLONG wred = 0;
|
|
SLONG wgreen = 0;
|
|
SLONG wblue = 0;
|
|
|
|
red *= (256 / LIGHT_MAX_BRIGHT);
|
|
green *= (256 / LIGHT_MAX_BRIGHT);
|
|
blue *= (256 / LIGHT_MAX_BRIGHT);
|
|
|
|
if (red > 255) {wred = red - 255 >> 1; red = 255; if (wred > 255) {wred = 255;}}
|
|
if (green > 255) {wgreen = green - 255 >> 1; green = 255; if (wgreen > 255) {wgreen = 255;}}
|
|
if (blue > 255) {wblue = blue - 255 >> 1; blue = 255; if (wblue > 255) {wblue = 255;}}
|
|
|
|
*colour = (red << 16) | (green << 8) | (blue << 0);
|
|
*specular = (wred << 16) | (wgreen << 8) | (wblue << 0);
|
|
}
|
|
inline ULONG LIGHT_get_glide_colour(LIGHT_Colour col)
|
|
{
|
|
SLONG red = col.red;
|
|
SLONG green = col.green;
|
|
SLONG blue = col.blue;
|
|
SLONG alpha = 0;
|
|
|
|
red *= (256 / LIGHT_MAX_BRIGHT);
|
|
green *= (256 / LIGHT_MAX_BRIGHT);
|
|
blue *= (256 / LIGHT_MAX_BRIGHT);
|
|
|
|
if (red > 255) {alpha += red - 255; red = 255;}
|
|
if (green > 255) {alpha += green - 255; green = 255;}
|
|
if (blue > 255) {alpha += blue - 255; blue = 255;}
|
|
if (alpha > 255) {alpha = 255;}
|
|
|
|
return (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
|
|
}
|
|
|
|
#else
|
|
inline void LIGHT_get_d3d_colour(LIGHT_Colour col, ULONG *colour, ULONG *specular)
|
|
{
|
|
SLONG whiteout;
|
|
SLONG bright;
|
|
|
|
bright = col * (256 / LIGHT_MAX_BRIGHT);
|
|
|
|
//
|
|
// Once we go over fully-bright, we get into saturated colour.
|
|
//
|
|
|
|
if (bright > 255)
|
|
{
|
|
whiteout = bright - 255 >> 1;
|
|
bright = 255;
|
|
|
|
if (whiteout > 255) {whiteout = 255;}
|
|
}
|
|
else
|
|
{
|
|
whiteout = 0;
|
|
}
|
|
|
|
*colour = (bright << 0) | (bright << 8) | (bright << 16);
|
|
*specular = (whiteout << 0) | (whiteout << 8) | (whiteout << 16);
|
|
}
|
|
#endif
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|