Gfxlib cleanup: fold getpixelarray() and process_rgb_bmp() into TFB_Canvas + Color paradigm

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3471 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
avolkov
2009-12-25 11:52:50 +00:00
parent 23c2ca27e7
commit 3b48ebaeee
7 changed files with 320 additions and 93 deletions
+11 -2
View File
@@ -27,7 +27,7 @@ struct Color {
BYTE r; BYTE r;
BYTE g; BYTE g;
BYTE b; BYTE b;
BYTE a; // Currently unused BYTE a;
}; };
#include "libs/reslib.h" #include "libs/reslib.h"
@@ -353,7 +353,16 @@ extern FRAME IncFrameIndex (FRAME Frame);
extern FRAME DecFrameIndex (FRAME Frame); extern FRAME DecFrameIndex (FRAME Frame);
extern DRAWABLE RotateFrame (FRAME Frame, int angle_deg); extern DRAWABLE RotateFrame (FRAME Frame, int angle_deg);
extern DRAWABLE RescaleFrame (FRAME, int width, int height); extern DRAWABLE RescaleFrame (FRAME, int width, int height);
// This pair works for both paletted and trucolor frames
extern BOOLEAN ReadFramePixelColors (FRAME frame, Color *pixels,
int width, int height);
extern BOOLEAN WriteFramePixelColors (FRAME frame, const Color *pixels,
int width, int height);
// This pair only works for paletted frames
extern BOOLEAN ReadFramePixelIndexes (FRAME frame, BYTE *pixels,
int width, int height);
extern BOOLEAN WriteFramePixelIndexes (FRAME frame, const BYTE *pixels,
int width, int height);
extern void SetFrameTransparentColor (FRAME, Color); extern void SetFrameTransparentColor (FRAME, Color);
// If the frame is an active SCREEN_DRAWABLE, this call must be // If the frame is an active SCREEN_DRAWABLE, this call must be
+58
View File
@@ -338,3 +338,61 @@ RescaleFrame (FRAME frame, int width, int height)
return drawable; return drawable;
} }
BOOLEAN
ReadFramePixelColors (FRAME frame, Color *pixels, int width, int height)
{
TFB_Image *img;
if (!frame)
return FALSE;
// TODO: Do we need to lock the img->mutex here?
img = frame->image;
return TFB_DrawCanvas_GetPixelColors (img->NormalImg, pixels,
width, height);
}
// Warning: this functions bypasses DCQ, which is why it is not a DrawXXX
BOOLEAN
WriteFramePixelColors (FRAME frame, const Color *pixels, int width, int height)
{
TFB_Image *img;
if (!frame)
return FALSE;
// TODO: Do we need to lock the img->mutex here?
img = frame->image;
return TFB_DrawCanvas_SetPixelColors (img->NormalImg, pixels,
width, height);
}
BOOLEAN
ReadFramePixelIndexes (FRAME frame, BYTE *pixels, int width, int height)
{
TFB_Image *img;
if (!frame)
return FALSE;
// TODO: Do we need to lock the img->mutex here?
img = frame->image;
return TFB_DrawCanvas_GetPixelIndexes (img->NormalImg, pixels,
width, height);
}
// Warning: this functions bypasses DCQ, which is why it is not a DrawXXX
BOOLEAN
WriteFramePixelIndexes (FRAME frame, const BYTE *pixels, int width, int height)
{
TFB_Image *img;
if (!frame)
return FALSE;
// TODO: Do we need to lock the img->mutex here?
img = frame->image;
return TFB_DrawCanvas_SetPixelIndexes (img->NormalImg, pixels,
width, height);
}
+153
View File
@@ -15,6 +15,9 @@
*/ */
#include "port.h" #include "port.h"
#include <string.h>
// for memcpy()
#include SDL_INCLUDE(SDL.h) #include SDL_INCLUDE(SDL.h)
#include "sdl_common.h" #include "sdl_common.h"
#include "libs/graphics/gfx_common.h" #include "libs/graphics/gfx_common.h"
@@ -1865,3 +1868,153 @@ TFB_DrawCanvas_Intersect (TFB_Canvas canvas1, POINT c1org,
return ret; return ret;
} }
// Read/write the canvas pixels in a Color format understood by the core.
// The pixels array is assumed to be at least width * height large.
// The pixels array can be wider/narrower or taller/shorter than the canvas,
// and in that case, only the relevant pixels will be transfered.
static BOOLEAN
TFB_DrawCanvas_TransferColors (TFB_Canvas canvas, BOOLEAN write,
Color *pixels, int width, int height)
{
SDL_Surface *surf = canvas;
SDL_PixelFormat *fmt;
GetPixelFn getpix;
PutPixelFn putpix;
int x, y, w, h;
if (canvas == 0)
{
log_add (log_Warning, "ERROR: TFB_DrawCanvas_TransferColors "
"passed null canvas");
return FALSE;
}
fmt = surf->format;
getpix = getpixel_for (surf);
putpix = putpixel_for (surf);
w = width < surf->w ? width : surf->w;
h = height < surf->h ? height : surf->h;
SDL_LockSurface (surf);
// This could be done faster if we assumed 32bpp surfaces
for (y = 0; y < h; ++y)
{
// pixels array pitch is width so as not to violate the interface
Color *c = pixels + y * width;
for (x = 0; x < w; ++x, ++c)
{
if (write)
{ // writing from data to surface
Uint32 p = SDL_MapRGBA (fmt, c->r, c->g, c->b, c->a);
putpix (surf, x, y, p);
}
else
{ // reading from surface to data
Uint32 p = getpix (surf, x, y);
SDL_GetRGBA (p, fmt, &c->r, &c->g, &c->b, &c->a);
}
}
}
SDL_UnlockSurface (surf);
return TRUE;
}
// Read the canvas pixels in a Color format understood by the core.
// See TFB_DrawCanvas_TransferColors() for pixels array info
BOOLEAN
TFB_DrawCanvas_GetPixelColors (TFB_Canvas canvas, Color *pixels,
int width, int height)
{
return TFB_DrawCanvas_TransferColors (canvas, FALSE, pixels,
width, height);
}
// Write the canvas pixels from a Color format understood by the core.
// See TFB_DrawCanvas_TransferColors() for pixels array info
BOOLEAN
TFB_DrawCanvas_SetPixelColors (TFB_Canvas canvas, const Color *pixels,
int width, int height)
{
// unconst pixels, but it is safe -- it will not be written to
return TFB_DrawCanvas_TransferColors (canvas, TRUE, (Color *)pixels,
width, height);
}
// Read/write the indexed canvas pixels as palette indexes.
// The data array is assumed to be at least width * height large.
// The data array can be wider/narrower or taller/shorter than the canvas,
// and in that case, only the relevant pixels will be transfered.
static BOOLEAN
TFB_DrawCanvas_TransferIndexes (TFB_Canvas canvas, BOOLEAN write,
BYTE *data, int width, int height)
{
SDL_Surface *surf = canvas;
const SDL_PixelFormat *fmt;
int y, w, h;
if (canvas == 0)
{
log_add (log_Warning, "ERROR: TFB_DrawCanvas_TransferIndexes "
"passed null canvas");
return FALSE;
}
fmt = surf->format;
if (!TFB_DrawCanvas_IsPaletted (canvas) || fmt->BitsPerPixel != 8)
{
log_add (log_Warning, "ERROR: TFB_DrawCanvas_TransferIndexes "
"unimplemeted function: not an 8bpp indexed canvas");
return FALSE;
}
w = width < surf->w ? width : surf->w;
h = height < surf->h ? height : surf->h;
SDL_LockSurface (surf);
for (y = 0; y < h; ++y)
{
Uint8 *surf_p = (Uint8 *)surf->pixels + y * surf->pitch;
// pixels array pitch is width so as not to violate the interface
BYTE *data_p = data + y * width;
if (write)
{ // writing from data to surface
memcpy (surf_p, data_p, w * sizeof (BYTE));
}
else
{ // reading from surface to data
memcpy (data_p, surf_p, w * sizeof (BYTE));
}
}
SDL_UnlockSurface (surf);
return TRUE;
}
// Read the indexed canvas pixels as palette indexes.
// See TFB_DrawCanvas_TransferIndexes() for data array info.
BOOLEAN
TFB_DrawCanvas_GetPixelIndexes (TFB_Canvas canvas, BYTE *data,
int width, int height)
{
return TFB_DrawCanvas_TransferIndexes (canvas, FALSE, data,
width, height);
}
// Write the indexed canvas pixels as palette indexes.
// See TFB_DrawCanvas_TransferIndexes() for data array info.
BOOLEAN
TFB_DrawCanvas_SetPixelIndexes (TFB_Canvas canvas, const BYTE *data,
int width, int height)
{
// unconst data, but it is safe -- it will not be written to
return TFB_DrawCanvas_TransferIndexes (canvas, TRUE, (BYTE *)data,
width, height);
}
+9
View File
@@ -180,6 +180,15 @@ Color TFB_DrawCanvas_GetPixel (TFB_Canvas canvas, int x, int y);
BOOLEAN TFB_DrawCanvas_Intersect (TFB_Canvas canvas1, POINT c1org, BOOLEAN TFB_DrawCanvas_Intersect (TFB_Canvas canvas1, POINT c1org,
TFB_Canvas canvas2, POINT c2org, const RECT *interRect); TFB_Canvas canvas2, POINT c2org, const RECT *interRect);
BOOLEAN TFB_DrawCanvas_GetPixelColors (TFB_Canvas, Color *pixels,
int width, int height);
BOOLEAN TFB_DrawCanvas_SetPixelColors (TFB_Canvas, const Color *pixels,
int width, int height);
BOOLEAN TFB_DrawCanvas_GetPixelIndexes (TFB_Canvas, BYTE *data,
int width, int height);
BOOLEAN TFB_DrawCanvas_SetPixelIndexes (TFB_Canvas, const BYTE *data,
int width, int height);
const char *TFB_DrawCanvas_GetError (void); const char *TFB_DrawCanvas_GetError (void);
TFB_Canvas TFB_GetScreenCanvas (SCREEN screen); TFB_Canvas TFB_GetScreenCanvas (SCREEN screen);
+4 -10
View File
@@ -298,16 +298,10 @@ FreePlanet (void)
DestroyDrawable (ReleaseDrawable (Orbit->WorkFrame)); DestroyDrawable (ReleaseDrawable (Orbit->WorkFrame));
Orbit->WorkFrame = 0; Orbit->WorkFrame = 0;
if (Orbit->lpTopoMap != 0) HFree (Orbit->TopoColors);
{ Orbit->TopoColors = NULL;
HFree (Orbit->lpTopoMap); HFree (Orbit->ScratchArray);
Orbit->lpTopoMap = 0; Orbit->ScratchArray = NULL;
}
if (Orbit->ScratchArray != 0)
{
HFree (Orbit->ScratchArray);
Orbit->ScratchArray = 0;
}
DestroyStringTable (ReleaseStringTable ( DestroyStringTable (ReleaseStringTable (
pSolarSysState->SysInfo.PlanetInfo.DiscoveryString pSolarSysState->SysInfo.PlanetInfo.DiscoveryString
+2 -2
View File
@@ -143,9 +143,9 @@ struct planet_orbit
// tinted topo images for current scan type (dynamic) // tinted topo images for current scan type (dynamic)
Color TintColor; Color TintColor;
// the color of the last used tint // the color of the last used tint
DWORD *lpTopoMap; Color *TopoColors;
// RGBA version of topo image; for 3d planet // RGBA version of topo image; for 3d planet
DWORD *ScratchArray; Color *ScratchArray;
// temp RGBA data for whatever transforms (nuked often) // temp RGBA data for whatever transforms (nuked often)
FRAME WorkFrame; FRAME WorkFrame;
// any extra frame workspace (for dynamic objects) // any extra frame workspace (for dynamic objects)
+83 -79
View File
@@ -41,13 +41,10 @@
// they should be sorted out and cleaned up at some point // they should be sorted out and cleaned up at some point
extern DWORD frame_mapRGBA (FRAME FramePtr, UBYTE r, UBYTE g, extern DWORD frame_mapRGBA (FRAME FramePtr, UBYTE r, UBYTE g,
UBYTE b, UBYTE a); UBYTE b, UBYTE a);
extern void process_rgb_bmp (FRAME FramePtr, DWORD *rgba, int maxx, int maxy);
extern void fill_frame_rgb (FRAME FramePtr, DWORD color, int x0, int y0, extern void fill_frame_rgb (FRAME FramePtr, DWORD color, int x0, int y0,
int x, int y); int x, int y);
extern void arith_frame_blit (FRAME srcFrame, const RECT *rsrc, extern void arith_frame_blit (FRAME srcFrame, const RECT *rsrc,
FRAME dstFrame, const RECT *rdst, int num, int denom); FRAME dstFrame, const RECT *rdst, int num, int denom);
extern void getpixelarray (void *map, int Bpp, FRAME FramePtr,
int width, int height);
#define SHIELD_GLOW_COMP 120 #define SHIELD_GLOW_COMP 120
@@ -406,21 +403,35 @@ create_aa_points (MAP3D_POINT *ppt, double x, double y)
ppt->m[i] = (DWORD)(m[i] * (1 << AA_WEIGHT_BITS) + 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 static inline BYTE
//computing the weightd averages of the 4 points in p1 get_color_channel (Color c, int channel)
static UBYTE
get_avg_rgb (DWORD p1[4], DWORD mult[4], COUNT offset)
{ {
COUNT i, j; switch (channel)
UBYTE c; {
case 0:
return c.r;
case 1:
return c.g;
case 2:
return c.b;
default:
return 0;
}
}
// Creates either a red, green, or blue value by
// computing the weighted averages of the 4 points in p
static BYTE
get_avg_channel (Color p[4], DWORD mult[4], int channel)
{
COUNT j;
DWORD ci = 0; DWORD ci = 0;
i = offset << 3;
//sum(mult[])==65536 //sum(mult[])==65536
//c is the red/green/blue value of this pixel //c is the red/green/blue value of this pixel
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
{ {
c = p1[j] >> i; BYTE c = get_color_channel (p[j], channel);
ci += c * mult[j]; ci += c * mult[j];
} }
ci >>= AA_WEIGHT_BITS; ci >>= AA_WEIGHT_BITS;
@@ -509,7 +520,8 @@ CreateSphereTiltMap (int angle)
static FRAME static FRAME
CreateShieldMask (void) CreateShieldMask (void)
{ {
DWORD clear, *rgba, *p_rgba; Color clear;
Color *pix;
int x, y; int x, y;
FRAME ShieldFrame; FRAME ShieldFrame;
PLANET_ORBIT *Orbit = &pSolarSysState->Orbit; PLANET_ORBIT *Orbit = &pSolarSysState->Orbit;
@@ -518,14 +530,13 @@ CreateShieldMask (void)
CreateDrawable (WANT_PIXMAP | WANT_ALPHA, CreateDrawable (WANT_PIXMAP | WANT_ALPHA,
SHIELD_DIAM, SHIELD_DIAM, 1)); SHIELD_DIAM, SHIELD_DIAM, 1));
rgba = Orbit->ScratchArray; pix = Orbit->ScratchArray;
p_rgba = rgba;
// This is 100% transparent. // This is 100% transparent.
clear = frame_mapRGBA (ShieldFrame, 0, 0, 0, 0); clear = BUILD_COLOR_RGBA (0, 0, 0, 0);
for (y = -SHIELD_RADIUS; y <= SHIELD_RADIUS; y++) for (y = -SHIELD_RADIUS; y <= SHIELD_RADIUS; y++)
{ {
for (x = -SHIELD_RADIUS; x <= SHIELD_RADIUS; x++, p_rgba++) for (x = -SHIELD_RADIUS; x <= SHIELD_RADIUS; ++x, ++pix)
{ {
int rad_2 = x * x + y * y; int rad_2 = x * x + y * y;
// This is a non-transparent red for the halo // This is a non-transparent red for the halo
@@ -535,13 +546,13 @@ CreateShieldMask (void)
if (rad_2 >= SHIELD_RADIUS_THRES) if (rad_2 >= SHIELD_RADIUS_THRES)
{ // outside all bounds { // outside all bounds
*p_rgba = clear; *pix = clear;
continue; continue;
} }
// Inside the halo // Inside the halo
if (rad_2 <= RADIUS_2) if (rad_2 <= RADIUS_2)
{ // planet's pixels, ours transparent { // planet's pixels, ours transparent
*p_rgba = clear; *pix = clear;
continue; continue;
} }
@@ -562,11 +573,12 @@ CreateShieldMask (void)
red = 0; red = 0;
} }
*p_rgba = frame_mapRGBA (ShieldFrame, red, 0, 0, alpha); *pix = BUILD_COLOR_RGBA (red, 0, 0, alpha);
} }
} }
process_rgb_bmp (ShieldFrame, rgba, SHIELD_DIAM, SHIELD_DIAM); WriteFramePixelColors (ShieldFrame, Orbit->ScratchArray,
SHIELD_DIAM, SHIELD_DIAM);
SetFrameHot (ShieldFrame, MAKE_HOT_SPOT (SHIELD_RADIUS + 1, SetFrameHot (ShieldFrame, MAKE_HOT_SPOT (SHIELD_RADIUS + 1,
SHIELD_RADIUS + 1)); SHIELD_RADIUS + 1));
@@ -604,40 +616,34 @@ SetShieldThrobEffect (FRAME ShieldFrame, int offset, FRAME ThrobFrame)
int i; int i;
int width, height; int width, height;
PLANET_ORBIT *Orbit = &pSolarSysState->Orbit; PLANET_ORBIT *Orbit = &pSolarSysState->Orbit;
DWORD *rgba; Color *pix;
int level; int level;
level = shield_level (offset); level = shield_level (offset);
width = GetFrameWidth (ShieldFrame); width = GetFrameWidth (ShieldFrame);
height = GetFrameHeight (ShieldFrame); height = GetFrameHeight (ShieldFrame);
getpixelarray (Orbit->ScratchArray, 4, ShieldFrame, width, height); ReadFramePixelColors (ShieldFrame, Orbit->ScratchArray, width, height);
for (i = 0, rgba = Orbit->ScratchArray; i < width * height; ++i, ++rgba) for (i = 0, pix = Orbit->ScratchArray; i < width * height; ++i, ++pix)
{ {
DWORD p = *rgba; Color p = *pix;
int r, g, b, a;
r = (UBYTE)(p >> 24); if (p.a == 255)
g = (UBYTE)(p >> 16);
b = (UBYTE)(p >> 8);
a = (UBYTE)(p);
if (a == 255)
{ // adjust color data for full-alpha pixels { // adjust color data for full-alpha pixels
r = r * level / THROB_MAX_LEVEL; p.r = p.r * level / THROB_MAX_LEVEL;
g = g * level / THROB_MAX_LEVEL; p.g = p.g * level / THROB_MAX_LEVEL;
b = b * level / THROB_MAX_LEVEL; p.b = p.b * level / THROB_MAX_LEVEL;
} }
else if (a > 0) else if (p.a > 0)
{ // adjust alpha for translucent pixels { // adjust alpha for translucent pixels
a = a * level / THROB_MAX_LEVEL; p.a = p.a * level / THROB_MAX_LEVEL;
} }
*rgba = frame_mapRGBA (ThrobFrame, r, g, b, a); *pix = p;
} }
process_rgb_bmp (ThrobFrame, Orbit->ScratchArray, width, height); WriteFramePixelColors (ThrobFrame, Orbit->ScratchArray, width, height);
SetFrameHot (ThrobFrame, GetFrameHot (ShieldFrame)); SetFrameHot (ThrobFrame, GetFrameHot (ShieldFrame));
} }
@@ -682,8 +688,8 @@ calc_map_light (UBYTE val, DWORD dif, int lvf)
return ((UBYTE)i); return ((UBYTE)i);
} }
static inline DWORD static inline Color
get_map_pixel (DWORD *pixels, int x, int y) get_map_pixel (Color *pixels, int x, int y)
{ {
return pixels[y * (MAP_WIDTH + SPHERE_SPAN_X) + x]; return pixels[y * (MAP_WIDTH + SPHERE_SPAN_X) + x];
} }
@@ -700,11 +706,12 @@ get_map_elev (SBYTE *elevs, int x, int y, int offset)
void void
RenderPlanetSphere (FRAME MaskFrame, int offset, BOOLEAN doThrob) RenderPlanetSphere (FRAME MaskFrame, int offset, BOOLEAN doThrob)
{ {
PLANET_ORBIT *Orbit = &pSolarSysState->Orbit;
POINT pt; POINT pt;
DWORD *rgba, *p_rgba; Color *pix;
DWORD clear; Color clear;
int x, y; int x, y;
DWORD *pixels; Color *pixels;
SBYTE *elevs; SBYTE *elevs;
int shLevel; int shLevel;
@@ -718,17 +725,16 @@ RenderPlanetSphere (FRAME MaskFrame, int offset, BOOLEAN doThrob)
shLevel = shield_level (offset); shLevel = shield_level (offset);
rgba = pSolarSysState->Orbit.ScratchArray; pix = Orbit->ScratchArray;
p_rgba = rgba; clear = BUILD_COLOR_RGBA (0, 0, 0, 0);
clear = frame_mapRGBA (MaskFrame, 0, 0, 0, 0); pixels = Orbit->TopoColors + offset;
pixels = pSolarSysState->Orbit.lpTopoMap + offset; elevs = Orbit->lpTopoData;
elevs = pSolarSysState->Orbit.lpTopoData;
for (pt.y = 0, y = -RADIUS; pt.y <= TWORADIUS; ++pt.y, ++y) for (pt.y = 0, y = -RADIUS; pt.y <= TWORADIUS; ++pt.y, ++y)
{ {
for (pt.x = 0, x = -RADIUS; pt.x <= TWORADIUS; ++pt.x, ++x, ++p_rgba) for (pt.x = 0, x = -RADIUS; pt.x <= TWORADIUS; ++pt.x, ++x, ++pix)
{ {
UBYTE c[3]; Color c;
DWORD diffus = light_diff[pt.y][pt.x]; DWORD diffus = light_diff[pt.y][pt.x];
int i; int i;
MAP3D_POINT *ppt = &map_rotate[pt.y][pt.x]; MAP3D_POINT *ppt = &map_rotate[pt.y][pt.x];
@@ -736,30 +742,28 @@ RenderPlanetSphere (FRAME MaskFrame, int offset, BOOLEAN doThrob)
if (diffus == 0) if (diffus == 0)
{ // full diffusion { // full diffusion
*p_rgba = clear; *pix = clear;
continue; continue;
} }
// get pixel from topo map and factor from light variance map // get pixel from topo map and factor from light variance map
if (ppt->m[0] == 0) if (ppt->m[0] == 0)
{ // exact pixel from the topo map { // exact pixel from the topo map
DWORD p = get_map_pixel (pixels, ppt->p[0].x, ppt->p[0].y); c = 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); lvf = get_map_elev (elevs, ppt->p[0].x, ppt->p[0].y, offset);
} }
else else
{ // fractional pixel -- blend from 4 { // fractional pixel -- blend from 4
DWORD p[4]; Color p[4];
int lvsum; int lvsum;
// compute 'ideal' pixel // compute 'ideal' pixel
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
p[i] = get_map_pixel (pixels, ppt->p[i].x, ppt->p[i].y); 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 (p, ppt->m, i); c.r = get_avg_channel (p, ppt->m, 0);
c.g = get_avg_channel (p, ppt->m, 1);
c.b = get_avg_channel (p, ppt->m, 2);
// compute 'ideal' light variance // compute 'ideal' light variance
for (i = 0, lvsum = 0; i < 4; i++) for (i = 0, lvsum = 0; i < 4; i++)
@@ -775,12 +779,12 @@ RenderPlanetSphere (FRAME MaskFrame, int offset, BOOLEAN doThrob)
int r; int r;
// add lite red filter (3/4) component // add lite red filter (3/4) component
c[1] = (c[1] >> 1) + (c[1] >> 2); c.g = (c.g >> 1) + (c.g >> 2);
c[0] = (c[0] >> 1) + (c[0] >> 2); c.b = (c.b >> 1) + (c.b >> 2);
c[2] = calc_map_light (c[2], diffus, lvf); c.r = calc_map_light (c.r, diffus, lvf);
c[1] = calc_map_light (c[1], diffus, lvf); c.g = calc_map_light (c.g, diffus, lvf);
c[0] = calc_map_light (c[0], diffus, lvf); c.b = calc_map_light (c.b, diffus, lvf);
// The shield is glow + reflect (+ filter for others) // The shield is glow + reflect (+ filter for others)
r = calc_map_light (SHIELD_REFLECT_COMP, diffus, 0); r = calc_map_light (SHIELD_REFLECT_COMP, diffus, 0);
@@ -791,24 +795,24 @@ RenderPlanetSphere (FRAME MaskFrame, int offset, BOOLEAN doThrob)
r = r * shLevel / THROB_MAX_LEVEL; r = r * shLevel / THROB_MAX_LEVEL;
} }
r += c[2]; r += c.r;
if (r > 255) if (r > 255)
r = 255; r = 255;
c[2] = r; c.r = r;
} }
else else
{ {
c[2] = calc_map_light (c[2], diffus, lvf); c.r = calc_map_light (c.r, diffus, lvf);
c[1] = calc_map_light (c[1], diffus, lvf); c.g = calc_map_light (c.g, diffus, lvf);
c[0] = calc_map_light (c[0], diffus, lvf); c.b = calc_map_light (c.b, diffus, lvf);
} }
*p_rgba = frame_mapRGBA (MaskFrame, c[2], c[1], c[0], 255); c.a = 0xff;
*pix = c;
} }
} }
// Map the rgb bitmap onto the SDL_Surface WriteFramePixelColors (MaskFrame, Orbit->ScratchArray, DIAMETER, DIAMETER);
process_rgb_bmp (MaskFrame, rgba, DIAMETER, DIAMETER);
SetFrameHot (MaskFrame, MAKE_HOT_SPOT (RADIUS + 1, RADIUS + 1)); SetFrameHot (MaskFrame, MAKE_HOT_SPOT (RADIUS + 1, RADIUS + 1));
#if PROFILE_ROTATION #if PROFILE_ROTATION
@@ -1301,13 +1305,13 @@ planet_orbit_init (void)
WANT_PIXMAP | WANT_ALPHA, MAP_WIDTH, MAP_HEIGHT, 2)); WANT_PIXMAP | WANT_ALPHA, MAP_WIDTH, MAP_HEIGHT, 2));
Orbit->ObjectFrame = 0; Orbit->ObjectFrame = 0;
Orbit->WorkFrame = 0; Orbit->WorkFrame = 0;
Orbit->lpTopoData = HMalloc (MAP_WIDTH * MAP_HEIGHT); Orbit->lpTopoData = HCalloc (MAP_WIDTH * MAP_HEIGHT);
Orbit->TopoZoomFrame = CaptureDrawable (CreateDrawable ( Orbit->TopoZoomFrame = CaptureDrawable (CreateDrawable (
WANT_PIXMAP, MAP_WIDTH << 2, MAP_HEIGHT << 2, 1)); WANT_PIXMAP, MAP_WIDTH << 2, MAP_HEIGHT << 2, 1));
Orbit->lpTopoMap = HMalloc (sizeof (DWORD) Orbit->TopoColors = HMalloc (sizeof (Orbit->TopoColors[0])
* (MAP_HEIGHT * (MAP_WIDTH + SPHERE_SPAN_X))); * (MAP_HEIGHT * (MAP_WIDTH + SPHERE_SPAN_X)));
// always allocate the scratch array to largest needed size // always allocate the scratch array to largest needed size
Orbit->ScratchArray = HMalloc (sizeof (DWORD) Orbit->ScratchArray = HMalloc (sizeof (Orbit->ScratchArray[0])
* (SHIELD_DIAM) * (SHIELD_DIAM)); * (SHIELD_DIAM) * (SHIELD_DIAM));
} }
@@ -1773,7 +1777,7 @@ GeneratePlanetSurface (PLANET_DESC *pPlanetDesc, FRAME SurfDefFrame)
} }
// grab the elevation data in 1 byte per pixel format // grab the elevation data in 1 byte per pixel format
getpixelarray (Orbit->lpTopoData, 1, ElevFrame, ReadFramePixelIndexes (ElevFrame, (BYTE *)Orbit->lpTopoData,
MAP_WIDTH, MAP_HEIGHT); MAP_WIDTH, MAP_HEIGHT);
// the supplied data is in unsigned format, must convert // the supplied data is in unsigned format, must convert
for (i = 0, elev = Orbit->lpTopoData; for (i = 0, elev = Orbit->lpTopoData;
@@ -1907,13 +1911,13 @@ GeneratePlanetSurface (PLANET_DESC *pPlanetDesc, FRAME SurfDefFrame)
// WAP_WIDTH+SPHERE_SPAN_X wide and we need this method for Earth anyway. // WAP_WIDTH+SPHERE_SPAN_X wide and we need this method for Earth anyway.
// It may be more efficient to build it from lpTopoData instead of the // It may be more efficient to build it from lpTopoData instead of the
// FRAMPTR though. // FRAMPTR though.
getpixelarray (Orbit->lpTopoMap, 4, pSolarSysState->TopoFrame, ReadFramePixelColors (pSolarSysState->TopoFrame, Orbit->TopoColors,
MAP_WIDTH + SPHERE_SPAN_X, MAP_HEIGHT); MAP_WIDTH + SPHERE_SPAN_X, MAP_HEIGHT);
// Extend the width from MAP_WIDTH to MAP_WIDTH+SPHERE_SPAN_X // Extend the width from MAP_WIDTH to MAP_WIDTH+SPHERE_SPAN_X
for (y = 0; y < MAP_HEIGHT * (MAP_WIDTH + SPHERE_SPAN_X); for (y = 0; y < MAP_HEIGHT * (MAP_WIDTH + SPHERE_SPAN_X);
y += MAP_WIDTH + SPHERE_SPAN_X) y += MAP_WIDTH + SPHERE_SPAN_X)
memcpy (Orbit->lpTopoMap + y + MAP_WIDTH, Orbit->lpTopoMap + y, memcpy (Orbit->TopoColors + y + MAP_WIDTH, Orbit->TopoColors + y,
SPHERE_SPAN_X * sizeof (Orbit->lpTopoMap[0])); SPHERE_SPAN_X * sizeof (Orbit->TopoColors[0]));
if (PLANALGO (PlanDataPtr->Type) != GAS_GIANT_ALGO) if (PLANALGO (PlanDataPtr->Type) != GAS_GIANT_ALGO)
{ // convert topo data to a light map, based on relative { // convert topo data to a light map, based on relative