Added lighting variance to give rotating planets a 3D look

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@2076 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
avolkov
2005-12-16 01:22:17 +00:00
parent 44970248cb
commit af70d11024
3 changed files with 385 additions and 91 deletions
+40 -15
View File
@@ -255,7 +255,8 @@ void fill_frame_rgb (FRAMEPTR FramePtr, Uint32 color, int x0, int y0,
UnlockMutex (tfbImg->mutex);
}
void arith_frame_blit (FRAMEPTR srcFrame, RECT *rsrc, FRAMEPTR dstFrame, RECT *rdst, int num,int denom)
void arith_frame_blit (FRAMEPTR srcFrame, RECT *rsrc, FRAMEPTR dstFrame,
RECT *rdst, int num, int denom)
{
TFB_Image *srcImg, *dstImg;
SDL_Surface *src, *dst;
@@ -305,36 +306,60 @@ void arith_frame_blit (FRAMEPTR srcFrame, RECT *rsrc, FRAMEPTR dstFrame, RECT *r
}
// Generate an array of all pixels in FramePtr
// The pixel format is :
// bits 25-32 : red
// bits 17-24 : green
// bits 9-16 : blue
// bits 1-8 : alpha
void getpixelarray(Uint32 *map, FRAMEPTR FramePtr, int width, int height)
// The 32bpp pixel format is :
// bits 24-31 : red
// bits 16-23 : green
// bits 8-15 : blue
// bits 0-7 : alpha
// The 8bpp pixel format is 1 index per pixel
void getpixelarray (void *map, int Bpp, FRAMEPTR FramePtr,
int width, int height)
{
Uint8 r,g,b,a;
Uint32 p, pos, row;
TFB_Image *tfbImg;
SDL_Surface *img;
GetPixelFn getpix;
int x,y;
int x, y, w, h;
tfbImg = FramePtr->image;
LockMutex (tfbImg->mutex);
img = (SDL_Surface *)tfbImg->NormalImg;
SDL_LockSurface (img);
getpix = getpixel_for (img);
for (y = 0, row = 0; y < height; y++, row += width)
w = width < img->w ? width : img->w;
h = height < img->h ? height : img->h;
SDL_LockSurface (img);
if (Bpp == 4)
{
if(y >= img->h)
continue;
for(x = 0, pos = row; x < img->w; x++, pos++)
Uint32 *dp = (Uint32 *)map;
for (y = 0, row = 0; y < h; y++, row += width)
{
for (x = 0, pos = row; x < w; x++, pos++)
{
p = getpix (img, x, y);
SDL_GetRGBA (p,img->format, &r, &g, &b, &a);
map[pos] = r << 24 | g << 16 | b << 8 | a;
SDL_GetRGBA (p, img->format, &r, &g, &b, &a);
dp[pos] = r << 24 | g << 16 | b << 8 | a;
}
}
}
else if (Bpp == 1)
{
Uint8 *dp = (Uint8 *)map;
for (y = 0, row = 0; y < h; y++, row += width)
{
for (x = 0, pos = row; x < w; x++, pos++)
{
p = getpix (img, x, y);
dp[pos] = p;
}
}
}
SDL_UnlockSurface (img);
UnlockMutex (tfbImg->mutex);
}
+2 -2
View File
@@ -120,8 +120,8 @@ DrawOrbitalDisplay (DRAW_ORBITAL_MODE Mode)
// (when orbit is entered; either from IP, or from loading a saved game)
// and when "starmap" is selected from orbit and then cancelled;
// also after in-orbit comm and after defeating planet guards in combat.
// IsDefined is true only when the planet comes with its own bitmap,
// namely for Earth.
// SurfDefFrame contains surface definition images when a planet comes
// with its own bitmap (currently only for Earth)
void
LoadPlanet (FRAME SurfDefFrame)
{
+340 -71
View File
@@ -49,7 +49,7 @@ extern void fill_frame_rgb (FRAME FramePtr, DWORD color, int x0, int y0,
int x, int y);
extern void arith_frame_blit (FRAME srcFrame, RECT *rsrc, FRAME dstFrame,
RECT *rdst, int num, int denom);
extern void getpixelarray (DWORD *array, FRAME FramePtr,
extern void getpixelarray (void *map, int Bpp, FRAMEPTR FramePtr,
int width, int height);
@@ -66,19 +66,8 @@ extern void getpixelarray (DWORD *array, FRAME FramePtr,
// distance beyond which all pixels are transparent (for aa)
#define RADIUS_THRES ((RADIUS + 1) * (RADIUS + 1))
#define DIAMETER (TWORADIUS + 1)
#define DIFFUSE_BITS 24
static inline UBYTE
GET_LIGHT (UBYTE val, DWORD dif, UBYTE sp)
{
DWORD i = (DWORD)val << DIFFUSE_BITS;
i -= val * dif;
i >>= DIFFUSE_BITS;
i += sp;
if (i > 255)
i = 255;
return ((UBYTE)i);
}
#define DIFFUSE_BITS 16
#define AA_WEIGHT_BITS 16
#ifndef M_TWOPI
#ifndef M_PI
@@ -91,7 +80,6 @@ GET_LIGHT (UBYTE val, DWORD dif, UBYTE sp)
#endif
DWORD light_diff[DIAMETER][DIAMETER];
UBYTE light_spec[DIAMETER][DIAMETER];
typedef struct
{
@@ -229,23 +217,30 @@ RenderTopography (BOOLEAN Reconstruct)
(void)Reconstruct; // swallow compiler whining
}
void P3mult (POINT3 *res, POINT3 *vec, double cnst)
static inline void
P3mult (POINT3 *res, POINT3 *vec, double cnst)
{
res->x = vec->x * cnst;
res->y = vec->y * cnst;
res->z = vec->z * cnst;
}
void P3sub (POINT3 *res, POINT3 *v1, POINT3 *v2)
static inline void
P3sub (POINT3 *res, POINT3 *v1, POINT3 *v2)
{
res->x = v1->x - v2->x;
res->y = v1->y - v2->y;
res->z = v1->z - v2->z;
}
double P3dot (POINT3 *v1, POINT3 *v2)
static inline double
P3dot (POINT3 *v1, POINT3 *v2)
{
return (v1->x * v2->x + v1->y * v2->y + v1->z * v2->z);
}
void P3norm (POINT3 *res, POINT3 *vec)
static inline void
P3norm (POINT3 *res, POINT3 *vec)
{
double mag = sqrt (P3dot (vec, vec));
P3mult (res, vec, 1/mag);
@@ -257,14 +252,12 @@ static void
RenderPhongMask (POINT loc)
{
POINT pt;
POINT3 light, view;
POINT3 light;
double lrad;
const DWORD step = 1 << DIFFUSE_BITS;
int y, x;
#define LIGHT_INTENS 0.3
#define AMBIENT_LIGHT 0.2
#define MSHI 2
#define AMBIENT_LIGHT 0.1
#define LIGHT_Z 1.2
// lrad is the distance from the sun to the planet
lrad = sqrt (loc.x * loc.x + loc.y * loc.y);
@@ -274,13 +267,6 @@ RenderPhongMask (POINT loc)
light.y = -((double)loc.y);
light.z = LIGHT_Z * lrad;
P3norm (&light, &light);
// always view along the z-axis
// ideally use a view point, and have the view change per pixel
// but that is too much effort for now.
// the view MUST be normalized!
view.x = 0;
view.y = 0;
view.z = 1.0;
for (pt.y = 0, y = -RADIUS; pt.y <= TWORADIUS; ++pt.y, y++)
{
@@ -290,9 +276,9 @@ RenderPhongMask (POINT loc)
{
DWORD x_2 = x * x;
DWORD rad_2 = x_2 + y_2;
DWORD diff_int;
POINT3 norm, rvec;
double diff, spec = 0.0, fb;
DWORD diff_int = 0;
POINT3 norm;
double diff;
if (rad_2 < RADIUS_THRES)
{
@@ -307,6 +293,26 @@ RenderPhongMask (POINT loc)
// negative diffuse is bad
if (diff < 0)
diff = 0.0;
#if 0
// Specular is not used in practice and is left here
// if someone decides to use it later for some reason.
// Specular highlight is only good for perfectly smooth
// surfaces, like balls (of which planets are not)
// This wouldn't be RenderPhongMask without the Phong eq.
#define LIGHT_INTENS 0.3
#define MSHI 2
double fb, spec;
POINT3 rvec;
POINT3 view;
// always view along the z-axis
// ideally use a view point, and have the view change
// per pixel, but that is too much effort for now.
// the view MUST be normalized!
view.x = 0;
view.y = 0;
view.z = 1.0;
// specular highlight is the phong equation:
// (rvec dot view)^MSHI
// where rvec = (2*diff)*norm - light (reflection of light
@@ -318,6 +324,7 @@ RenderPhongMask (POINT loc)
spec = LIGHT_INTENS * pow (fb, MSHI);
else
spec = 0;
#endif
// adjust for the ambient light
if (diff < AMBIENT_LIGHT)
diff = AMBIENT_LIGHT;
@@ -330,18 +337,10 @@ RenderPhongMask (POINT loc)
}
// diff_int allows us multiply by a ratio without using
// floating-point.
// instead of color*diff, we use ((color << 24) -
// stepint*color) >> 24
diff_int = step - (DWORD)(diff * step + 0.5);
}
else
{ // outside sphere bounds
diff_int = 1 << 31;
diff_int = (DWORD)(diff * step);
}
light_diff[pt.y][pt.x] = diff_int;
light_spec[pt.y][pt.x] = (UBYTE)(spec * 255);
}
}
}
@@ -417,7 +416,7 @@ create_aa_points (MAP3D_POINT *ppt, double x, double y)
m[3] = m[0] * d1 / d4;
for (i = 0; i < 4; i++)
ppt->m[i] = (DWORD)((1 << 16) * m[i] + 0.5);
ppt->m[i] = (DWORD)(m[i] * (1 << AA_WEIGHT_BITS) + 0.5);
}
//get_avg_rgb creates either a red, green, or blue value by
@@ -437,7 +436,7 @@ get_avg_rgb (DWORD p1[4], DWORD mult[4], COUNT offset)
c = (UBYTE)(p1[j] >> i);
ci += c * mult[j];
}
ci >>= 16;
ci >>= AA_WEIGHT_BITS;
//check for overflow
if (ci > 255)
ci = 255;
@@ -629,10 +628,39 @@ CreateShieldMask (void)
}
static inline UBYTE
calc_map_light (UBYTE val, DWORD dif, int lvf)
{
int i;
// apply diffusion
i = (dif * val) >> DIFFUSE_BITS;
// apply light variance for 3d lighting effect
i += (lvf * val) >> 7;
if (i < 0)
i = 0;
else if (i > 255)
i = 255;
return ((UBYTE)i);
}
static inline DWORD
get_map_pixel (DWORD *pixels, int x, int y)
{
return pixels[y * (MAP_WIDTH + MAP_HEIGHT) + x];
}
static inline int
get_map_elev (SBYTE *elevs, int x, int y, int offset)
{
return elevs[y * MAP_WIDTH + (offset + x) % MAP_WIDTH];
}
// RenderLevelMasks builds a frame for the rotating planet view
// offset is effectively the angle of rotation around the planet's axis
// We use the SDL routines to directly write to the SDL_Surface to improve performance
#define PT_TO_ADDR(y, x) ((y) * (MAP_WIDTH + MAP_HEIGHT) + (x))
void
RenderLevelMasks (int offset)
{
@@ -640,7 +668,8 @@ RenderLevelMasks (int offset)
DWORD *rgba, *p_rgba;
DWORD clear;
int x, y;
DWORD p, *pixels;
DWORD *pixels;
SBYTE *elevs;
FRAME MaskFrame;
#if PROFILE
@@ -656,7 +685,8 @@ RenderLevelMasks (int offset)
MaskFrame = SetAbsFrameIndex (pSolarSysState->Orbit.PlanetFrameArray,
(COUNT)(offset + 1));
clear = frame_mapRGBA (MaskFrame, 0, 0, 0, 0);
pixels = pSolarSysState->Orbit.lpTopoMap;
pixels = pSolarSysState->Orbit.lpTopoMap + offset;
elevs = pSolarSysState->Orbit.lpTopoData;
for (pt.y = 0, y = -RADIUS; pt.y <= TWORADIUS; ++pt.y, ++y)
{
@@ -664,32 +694,42 @@ RenderLevelMasks (int offset)
{
UBYTE c[3];
DWORD diffus = light_diff[pt.y][pt.x];
UBYTE spec = light_spec[pt.y][pt.x];
int i;
DWORD p1[4];
MAP3D_POINT *ppt = &map_rotate[pt.y][pt.x];
int lvf; // light variance factor
if (diffus >= (1 << DIFFUSE_BITS))
if (diffus == 0)
{ // full diffusion
*p_rgba = clear;
continue;
}
// get pixel from topo map and factor from light variance map
if (ppt->m[0] == 0)
{
p = pixels[PT_TO_ADDR (ppt->p[0].y, ppt->p[0].x) +
offset];
{ // exact pixel from the topo map
DWORD p = get_map_pixel (pixels, ppt->p[0].x, ppt->p[0].y);
c[0] = (UBYTE)(p >> 8);
c[1] = (UBYTE)(p >> 16);
c[2] = (UBYTE)(p >> 24);
lvf = get_map_elev (elevs, ppt->p[0].x, ppt->p[0].y, offset);
}
else
{
{ // fractional pixel -- blend from 4
DWORD p[4];
int lvsum;
// compute 'ideal' pixel
for (i = 0; i < 4; i++)
p1[i] = pixels[PT_TO_ADDR (ppt->p[i].y, ppt->p[i].x)
+ offset];
p[i] = get_map_pixel (pixels, ppt->p[i].x, ppt->p[i].y);
for (i = 1; i < 4; i++)
c[i - 1] = get_avg_rgb (p1, ppt->m, i);
c[i - 1] = get_avg_rgb (p, ppt->m, i);
// compute 'ideal' light variance
for (i = 0, lvsum = 0; i < 4; i++)
lvsum += get_map_elev (elevs, ppt->p[0].x, ppt->p[0].y,
offset) * ppt->m[i];
lvf = lvsum >> AA_WEIGHT_BITS;
}
// Apply the lighting model. This also bounds the sphere
@@ -702,12 +742,12 @@ RenderLevelMasks (int offset)
c[1] = (c[1] >> 1) + (c[1] >> 2);
c[0] = (c[0] >> 1) + (c[0] >> 2);
c[2] = GET_LIGHT (c[2], diffus, spec);
c[1] = GET_LIGHT (c[1], diffus, spec);
c[0] = GET_LIGHT (c[0], diffus, spec);
c[2] = calc_map_light (c[2], diffus, lvf);
c[1] = calc_map_light (c[1], diffus, lvf);
c[0] = calc_map_light (c[0], diffus, lvf);
// The shield is glow + reflect (+ filter for others)
r = GET_LIGHT (SHIELD_REFLECT_COMP, diffus, spec);
r = calc_map_light (SHIELD_REFLECT_COMP, diffus, 0);
r = r + SHIELD_GLOW_COMP + c[2];
if (r > 255)
r = 255;
@@ -715,9 +755,9 @@ RenderLevelMasks (int offset)
}
else
{
c[2] = GET_LIGHT (c[2], diffus, spec);
c[1] = GET_LIGHT (c[1], diffus, spec);
c[0] = GET_LIGHT (c[0], diffus, spec);
c[2] = calc_map_light (c[2], diffus, lvf);
c[1] = calc_map_light (c[1], diffus, lvf);
c[0] = calc_map_light (c[0], diffus, lvf);
}
*p_rgba = frame_mapRGBA (MaskFrame, c[2], c[1], c[0], 255);
@@ -1461,6 +1501,190 @@ TopoScale4x (PBYTE pDstTopo, PBYTE pSrcTopo, int num_faults, int fault_var)
}
}
// GenerateLightMap produces a surface light variance map for the
// rotating planet by, first, transforming absolute elevation data
// into normalized relative and then applying a weighted
// average-median of surrounding points
// Lots of pure Voodoo here ;)
// the goal is a 3D illusion, not mathematically correct lighting
#define LMAP_AVG_BLOCK ((MAP_HEIGHT + 4) / 5)
#define LMAP_MAX_DIST ((LMAP_AVG_BLOCK + 1) >> 1)
#define LMAP_WEIGHT_THRES (LMAP_MAX_DIST * 2 / 3)
typedef struct
{
int min;
int max;
int avg;
} elev_block_t;
static inline void
get_vblock_avg (elev_block_t *pblk, PSBYTE pTopo, int x, int y)
{
SBYTE *elev = pTopo;
int y0, y1, i;
int min = 127, max = -127;
int avg = 0, total_weight = 0;
// surface wraps around along x
x = (x + MAP_WIDTH) % MAP_WIDTH;
y0 = y - LMAP_MAX_DIST;
y1 = y + LMAP_MAX_DIST;
if (y0 < 0)
y0 = 0;
if (y1 > MAP_HEIGHT)
y1 = MAP_HEIGHT;
elev = pTopo + y0 * MAP_HEIGHT + x;
for (i = y0; i < y1; ++i, elev += MAP_HEIGHT)
{
int delta = abs (i - y);
int weight = 255; // full weight
int v = *elev;
if (delta >= LMAP_WEIGHT_THRES)
{ // too far -- progressively reduced weight
weight = weight * (LMAP_MAX_DIST - delta + 1)
/ (LMAP_MAX_DIST - LMAP_WEIGHT_THRES + 2);
}
if (v > max)
max = v;
if (v < min)
min = v;
avg += pblk->avg * weight;
total_weight += weight;
}
avg /= total_weight;
pblk->min = min;
pblk->max = max;
pblk->avg = avg / (y1 - y0);
}
// See description above
static void
GenerateLightMap (PSBYTE pTopo, int w, int h)
{
#define LMAP_BLOCKS (2 * LMAP_MAX_DIST + 1)
int x, y;
elev_block_t vblocks[LMAP_BLOCKS];
// we use a running block average to reduce the amount of work
// where a block is a vertical line of map points
SBYTE *elev;
int min, max, med;
int sfact, spread;
// normalize the topo data
min = 127;
max = -128;
for (x = 0, elev = pTopo; x < w * h; ++x, ++elev)
{
int v = *elev;
if (v > max)
max = v;
if (v < min)
min = v;
}
med = (min + max) / 2;
spread = max - med;
if (spread == 0)
{ // perfectly smooth surface -- nothing to do but
// level it out completely
if (max != 0)
memset (pTopo, 0, w * h);
return;
}
// these are whatever looks right
if (spread < 10)
sfact = 30; // minimal spread
else if (spread < 30)
sfact = 60;
else
sfact = 100; // full spread
// apply spread
for (x = 0, elev = pTopo; x < w * h; ++x, ++elev)
{
int v = *elev;
v = (v - med) * sfact / spread;
*elev = v;
}
// compute and apply weighted averages of surrounding points
for (y = 0, elev = pTopo; y < h; ++y)
{
elev_block_t *pblk;
int i;
// prime the running block average
// get the minimum, maximum and avg elevation for each block
for (i = -LMAP_MAX_DIST; i < LMAP_MAX_DIST; ++i)
{
// blocks wrap around on both sides
pblk = vblocks + ((i + LMAP_BLOCKS) % LMAP_BLOCKS);
get_vblock_avg (pblk, pTopo, i, y);
}
for (x = 0; x < w; ++x, ++elev)
{
int avg = 0, total_weight = 0;
min = 127;
max = -127;
// prepare next block as we move along x
pblk = vblocks + ((x + LMAP_MAX_DIST) % LMAP_BLOCKS);
get_vblock_avg (pblk, pTopo, x + LMAP_MAX_DIST, y);
// compute the min, max and weighted avg of blocks
for (i = x - LMAP_MAX_DIST; i <= x + LMAP_MAX_DIST; ++i)
{
int delta = abs (i - x);
int weight = 255; // full weight
pblk = vblocks + ((i + LMAP_BLOCKS) % LMAP_BLOCKS);
if (delta >= LMAP_WEIGHT_THRES)
{ // too far -- progressively reduced weight
weight = weight * (LMAP_MAX_DIST - delta + 1)
/ (LMAP_MAX_DIST - LMAP_WEIGHT_THRES + 2);
}
if (pblk->max > max)
max = pblk->max;
if (pblk->min < min)
min = pblk->min;
avg += pblk->avg * weight;
total_weight += weight;
}
avg /= total_weight;
// This is mostly Voodoo
// figure out what kind of relative lighting factor
// to assign to this point
#if 0
// relative to median
med = (min + max) / 2; // median
*elev = (int)*elev - med;
#else
// relative to median of (average, median)
med = (min + max) / 2; // median
med = (med + avg) / 2;
*elev = (int)*elev - med;
#endif
}
}
}
void
GeneratePlanetMask (PPLANET_DESC pPlanetDesc, FRAME SurfDefFrame)
{
@@ -1478,23 +1702,52 @@ GeneratePlanetMask (PPLANET_DESC pPlanetDesc, FRAME SurfDefFrame)
OldContext = SetContext (TaskContext);
planet_orbit_init ();
PlanDataPtr = &PlanData[pPlanetDesc->data_index & ~PLANET_SHIELDED];
if (SurfDefFrame)
{ // This is a defined planet; pixmap for the topography and
// elevation data is supplied in Surface Definition frame
BOOLEAN DeleteDef = FALSE;
FRAME ElevFrame;
// surface pixmap
SurfDefFrame = SetAbsFrameIndex (SurfDefFrame, 0);
if (GetFrameWidth (SurfDefFrame) != MAP_WIDTH
|| GetFrameHeight (SurfDefFrame) != MAP_HEIGHT)
{
pSolarSysState->TopoFrame = stretch_frame (SurfDefFrame,
MAP_WIDTH, MAP_HEIGHT, 1);
MAP_WIDTH, MAP_HEIGHT, 0);
// will not need the passed FRAME anymore
DeleteDef = TRUE;
}
else
pSolarSysState->TopoFrame = SurfDefFrame;
if (GetFrameCount (SurfDefFrame) > 1)
{ // 2nd frame is elevation data
ElevFrame = SetAbsFrameIndex (SurfDefFrame, 1);
if (GetFrameWidth (ElevFrame) != MAP_WIDTH
|| GetFrameHeight (ElevFrame) != MAP_HEIGHT)
{
ElevFrame = stretch_frame (ElevFrame, MAP_WIDTH,
MAP_HEIGHT, 0);
}
// grab the elevation data in 1 byte per pixel format
getpixelarray (Orbit->lpTopoData, 1, ElevFrame,
MAP_WIDTH, MAP_HEIGHT);
}
else
{ // no elevation data -- planet flat as a pancake
memset (Orbit->lpTopoData, 0, MAP_WIDTH * MAP_HEIGHT);
}
if (DeleteDef)
DestroyDrawable (ReleaseDrawable (SurfDefFrame));
}
else
{ // Generate planet surface elevation data and look
PlanDataPtr = &PlanData[pPlanetDesc->data_index & ~PLANET_SHIELDED];
r.corner.x = r.corner.y = 0;
r.extent.width = MAP_WIDTH;
r.extent.height = MAP_HEIGHT;
@@ -1585,7 +1838,13 @@ GeneratePlanetMask (PPLANET_DESC pPlanetDesc, FRAME SurfDefFrame)
}
pSolarSysState->XlatPtr = GetStringAddress (pSolarSysState->XlatRef);
RenderTopography (FALSE);
}
if (!(pPlanetDesc->data_index & PLANET_SHIELDED)
&& pSolarSysState->SysInfo.PlanetInfo.AtmoDensity
!= GAS_GIANT_ATMOSPHERE)
{ // produce 4x scaled topo image for IP
// for the planets that we can land on
pScaledTopo = HMalloc (MAP_WIDTH * 4 * MAP_HEIGHT * 4);
if (pScaledTopo)
{
@@ -1606,12 +1865,22 @@ GeneratePlanetMask (PPLANET_DESC pPlanetDesc, FRAME SurfDefFrame)
// FRAMPTR though.
x = MAP_WIDTH + MAP_HEIGHT;
y = MAP_HEIGHT;
getpixelarray (Orbit->lpTopoMap, pSolarSysState->TopoFrame, x, y);
getpixelarray (Orbit->lpTopoMap, 4, pSolarSysState->TopoFrame, x, y);
// Extend the width from MAP_WIDTH to MAP_WIDTH+MAP_HEIGHT
for (y = 0; y < MAP_HEIGHT * (MAP_WIDTH + MAP_HEIGHT);
y += MAP_WIDTH + MAP_HEIGHT)
for (x = 0; x < MAP_HEIGHT; x++)
Orbit->lpTopoMap[y + x + MAP_WIDTH] = Orbit->lpTopoMap[y + x];
memcpy (Orbit->lpTopoMap + y + MAP_WIDTH, Orbit->lpTopoMap + y,
MAP_HEIGHT * sizeof (Orbit->lpTopoMap[0]));
if (PLANALGO (PlanDataPtr->Type) != GAS_GIANT_ALGO)
{ // convert topo data to a light map, based on relative
// map point elevations
GenerateLightMap (Orbit->lpTopoData, MAP_WIDTH, MAP_HEIGHT);
}
else
{ // gas giants are pretty much flat
memset (Orbit->lpTopoData, 0, MAP_WIDTH * MAP_HEIGHT);
}
if (pSolarSysState->pOrbitalDesc->pPrevDesc ==
&pSolarSysState->SunDesc[0])
@@ -1656,7 +1925,6 @@ rotate_planet_task (void *data)
!Task_ReadState (task, TASK_EXIT))
TaskSwitch ();
// SetPlanetTilt ((pSS->SysInfo.PlanetInfo.AxialTilt << 8) / 360);
SetPlanetTilt (pSS->SysInfo.PlanetInfo.AxialTilt);
i = 1 - ((pSS->SysInfo.PlanetInfo.AxialTilt & 1) << 1);
@@ -1736,11 +2004,12 @@ rotate_planet_task (void *data)
SleepThreadUntil (TimeIn + (ONE_SECOND * ROTATION_TIME) /
(MAP_WIDTH));
// SleepThreadUntil (TimeIn + (ONE_SECOND * 5 / (MAP_WIDTH-32)));
TimeIn = GetTimeCounter ();
} while (--view_index && !Task_ReadState (task, TASK_EXIT));
}
FinishTask (task);
return 0;
}