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:
+11
-2
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
|
||||||
Orbit->lpTopoMap = 0;
|
|
||||||
}
|
|
||||||
if (Orbit->ScratchArray != 0)
|
|
||||||
{
|
|
||||||
HFree (Orbit->ScratchArray);
|
HFree (Orbit->ScratchArray);
|
||||||
Orbit->ScratchArray = 0;
|
Orbit->ScratchArray = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
DestroyStringTable (ReleaseStringTable (
|
DestroyStringTable (ReleaseStringTable (
|
||||||
pSolarSysState->SysInfo.PlanetInfo.DiscoveryString
|
pSolarSysState->SysInfo.PlanetInfo.DiscoveryString
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user