From 3b48ebaeeee6884c4e5115a3b9dc365eb03b3685 Mon Sep 17 00:00:00 2001 From: avolkov Date: Fri, 25 Dec 2009 11:52:50 +0000 Subject: [PATCH] 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 --- sc2/src/libs/gfxlib.h | 13 ++- sc2/src/libs/graphics/drawable.c | 58 +++++++++++ sc2/src/libs/graphics/sdl/canvas.c | 153 +++++++++++++++++++++++++++ sc2/src/libs/graphics/tfb_draw.h | 9 ++ sc2/src/uqm/planets/planets.c | 14 +-- sc2/src/uqm/planets/planets.h | 4 +- sc2/src/uqm/planets/plangen.c | 162 +++++++++++++++-------------- 7 files changed, 320 insertions(+), 93 deletions(-) diff --git a/sc2/src/libs/gfxlib.h b/sc2/src/libs/gfxlib.h index 6e4471dd3..70e024c7c 100644 --- a/sc2/src/libs/gfxlib.h +++ b/sc2/src/libs/gfxlib.h @@ -27,7 +27,7 @@ struct Color { BYTE r; BYTE g; BYTE b; - BYTE a; // Currently unused + BYTE a; }; #include "libs/reslib.h" @@ -353,7 +353,16 @@ extern FRAME IncFrameIndex (FRAME Frame); extern FRAME DecFrameIndex (FRAME Frame); extern DRAWABLE RotateFrame (FRAME Frame, int angle_deg); 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); // If the frame is an active SCREEN_DRAWABLE, this call must be diff --git a/sc2/src/libs/graphics/drawable.c b/sc2/src/libs/graphics/drawable.c index 3be43e82e..747b778f6 100644 --- a/sc2/src/libs/graphics/drawable.c +++ b/sc2/src/libs/graphics/drawable.c @@ -338,3 +338,61 @@ RescaleFrame (FRAME frame, int width, int height) 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); +} diff --git a/sc2/src/libs/graphics/sdl/canvas.c b/sc2/src/libs/graphics/sdl/canvas.c index c5428a9e8..6c3e2fe0d 100644 --- a/sc2/src/libs/graphics/sdl/canvas.c +++ b/sc2/src/libs/graphics/sdl/canvas.c @@ -15,6 +15,9 @@ */ #include "port.h" +#include + // for memcpy() + #include SDL_INCLUDE(SDL.h) #include "sdl_common.h" #include "libs/graphics/gfx_common.h" @@ -1865,3 +1868,153 @@ TFB_DrawCanvas_Intersect (TFB_Canvas canvas1, POINT c1org, 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); +} diff --git a/sc2/src/libs/graphics/tfb_draw.h b/sc2/src/libs/graphics/tfb_draw.h index 1b0114511..297a42de6 100644 --- a/sc2/src/libs/graphics/tfb_draw.h +++ b/sc2/src/libs/graphics/tfb_draw.h @@ -180,6 +180,15 @@ Color TFB_DrawCanvas_GetPixel (TFB_Canvas canvas, int x, int y); BOOLEAN TFB_DrawCanvas_Intersect (TFB_Canvas canvas1, POINT c1org, 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); TFB_Canvas TFB_GetScreenCanvas (SCREEN screen); diff --git a/sc2/src/uqm/planets/planets.c b/sc2/src/uqm/planets/planets.c index e94b6fa71..c71307f95 100644 --- a/sc2/src/uqm/planets/planets.c +++ b/sc2/src/uqm/planets/planets.c @@ -298,16 +298,10 @@ FreePlanet (void) DestroyDrawable (ReleaseDrawable (Orbit->WorkFrame)); Orbit->WorkFrame = 0; - if (Orbit->lpTopoMap != 0) - { - HFree (Orbit->lpTopoMap); - Orbit->lpTopoMap = 0; - } - if (Orbit->ScratchArray != 0) - { - HFree (Orbit->ScratchArray); - Orbit->ScratchArray = 0; - } + HFree (Orbit->TopoColors); + Orbit->TopoColors = NULL; + HFree (Orbit->ScratchArray); + Orbit->ScratchArray = NULL; DestroyStringTable (ReleaseStringTable ( pSolarSysState->SysInfo.PlanetInfo.DiscoveryString diff --git a/sc2/src/uqm/planets/planets.h b/sc2/src/uqm/planets/planets.h index 9564ddda0..0e14c0948 100644 --- a/sc2/src/uqm/planets/planets.h +++ b/sc2/src/uqm/planets/planets.h @@ -143,9 +143,9 @@ struct planet_orbit // tinted topo images for current scan type (dynamic) Color TintColor; // the color of the last used tint - DWORD *lpTopoMap; + Color *TopoColors; // RGBA version of topo image; for 3d planet - DWORD *ScratchArray; + Color *ScratchArray; // temp RGBA data for whatever transforms (nuked often) FRAME WorkFrame; // any extra frame workspace (for dynamic objects) diff --git a/sc2/src/uqm/planets/plangen.c b/sc2/src/uqm/planets/plangen.c index bb7f6d8ef..ba5b9cb10 100644 --- a/sc2/src/uqm/planets/plangen.c +++ b/sc2/src/uqm/planets/plangen.c @@ -41,13 +41,10 @@ // they should be sorted out and cleaned up at some point extern DWORD frame_mapRGBA (FRAME FramePtr, UBYTE r, UBYTE g, 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, int x, int y); extern void arith_frame_blit (FRAME srcFrame, const RECT *rsrc, 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 @@ -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); } -//get_avg_rgb creates either a red, green, or blue value by -//computing the weightd averages of the 4 points in p1 -static UBYTE -get_avg_rgb (DWORD p1[4], DWORD mult[4], COUNT offset) +static inline BYTE +get_color_channel (Color c, int channel) { - COUNT i, j; - UBYTE c; + switch (channel) + { + 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; - i = offset << 3; //sum(mult[])==65536 //c is the red/green/blue value of this pixel for (j = 0; j < 4; j++) { - c = p1[j] >> i; + BYTE c = get_color_channel (p[j], channel); ci += c * mult[j]; } ci >>= AA_WEIGHT_BITS; @@ -509,7 +520,8 @@ CreateSphereTiltMap (int angle) static FRAME CreateShieldMask (void) { - DWORD clear, *rgba, *p_rgba; + Color clear; + Color *pix; int x, y; FRAME ShieldFrame; PLANET_ORBIT *Orbit = &pSolarSysState->Orbit; @@ -518,14 +530,13 @@ CreateShieldMask (void) CreateDrawable (WANT_PIXMAP | WANT_ALPHA, SHIELD_DIAM, SHIELD_DIAM, 1)); - rgba = Orbit->ScratchArray; - p_rgba = rgba; + pix = Orbit->ScratchArray; // 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 (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; // This is a non-transparent red for the halo @@ -535,13 +546,13 @@ CreateShieldMask (void) if (rad_2 >= SHIELD_RADIUS_THRES) { // outside all bounds - *p_rgba = clear; + *pix = clear; continue; } // Inside the halo if (rad_2 <= RADIUS_2) { // planet's pixels, ours transparent - *p_rgba = clear; + *pix = clear; continue; } @@ -562,11 +573,12 @@ CreateShieldMask (void) 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, SHIELD_RADIUS + 1)); @@ -604,40 +616,34 @@ SetShieldThrobEffect (FRAME ShieldFrame, int offset, FRAME ThrobFrame) int i; int width, height; PLANET_ORBIT *Orbit = &pSolarSysState->Orbit; - DWORD *rgba; + Color *pix; int level; level = shield_level (offset); width = GetFrameWidth (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; - int r, g, b, a; + Color p = *pix; - r = (UBYTE)(p >> 24); - g = (UBYTE)(p >> 16); - b = (UBYTE)(p >> 8); - a = (UBYTE)(p); - - if (a == 255) + if (p.a == 255) { // adjust color data for full-alpha pixels - r = r * level / THROB_MAX_LEVEL; - g = g * level / THROB_MAX_LEVEL; - b = b * level / THROB_MAX_LEVEL; + p.r = p.r * level / THROB_MAX_LEVEL; + p.g = p.g * 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 - 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)); } @@ -682,8 +688,8 @@ calc_map_light (UBYTE val, DWORD dif, int lvf) return ((UBYTE)i); } -static inline DWORD -get_map_pixel (DWORD *pixels, int x, int y) +static inline Color +get_map_pixel (Color *pixels, int x, int y) { 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 RenderPlanetSphere (FRAME MaskFrame, int offset, BOOLEAN doThrob) { + PLANET_ORBIT *Orbit = &pSolarSysState->Orbit; POINT pt; - DWORD *rgba, *p_rgba; - DWORD clear; + Color *pix; + Color clear; int x, y; - DWORD *pixels; + Color *pixels; SBYTE *elevs; int shLevel; @@ -718,17 +725,16 @@ RenderPlanetSphere (FRAME MaskFrame, int offset, BOOLEAN doThrob) shLevel = shield_level (offset); - rgba = pSolarSysState->Orbit.ScratchArray; - p_rgba = rgba; - clear = frame_mapRGBA (MaskFrame, 0, 0, 0, 0); - pixels = pSolarSysState->Orbit.lpTopoMap + offset; - elevs = pSolarSysState->Orbit.lpTopoData; + pix = Orbit->ScratchArray; + clear = BUILD_COLOR_RGBA (0, 0, 0, 0); + pixels = Orbit->TopoColors + offset; + elevs = Orbit->lpTopoData; 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]; int i; MAP3D_POINT *ppt = &map_rotate[pt.y][pt.x]; @@ -736,30 +742,28 @@ RenderPlanetSphere (FRAME MaskFrame, int offset, BOOLEAN doThrob) if (diffus == 0) { // full diffusion - *p_rgba = clear; + *pix = clear; continue; } // get pixel from topo map and factor from light variance map if (ppt->m[0] == 0) { // 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); - + c = get_map_pixel (pixels, ppt->p[0].x, ppt->p[0].y); lvf = get_map_elev (elevs, ppt->p[0].x, ppt->p[0].y, offset); } else { // fractional pixel -- blend from 4 - DWORD p[4]; + Color p[4]; int lvsum; // compute 'ideal' pixel for (i = 0; i < 4; i++) 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 for (i = 0, lvsum = 0; i < 4; i++) @@ -775,12 +779,12 @@ RenderPlanetSphere (FRAME MaskFrame, int offset, BOOLEAN doThrob) int r; // add lite red filter (3/4) component - c[1] = (c[1] >> 1) + (c[1] >> 2); - c[0] = (c[0] >> 1) + (c[0] >> 2); + c.g = (c.g >> 1) + (c.g >> 2); + c.b = (c.b >> 1) + (c.b >> 2); - 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); + c.r = calc_map_light (c.r, diffus, lvf); + c.g = calc_map_light (c.g, diffus, lvf); + c.b = calc_map_light (c.b, diffus, lvf); // The shield is glow + reflect (+ filter for others) 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 += c[2]; + r += c.r; if (r > 255) r = 255; - c[2] = r; + c.r = r; } else { - 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); + c.r = calc_map_light (c.r, diffus, lvf); + c.g = calc_map_light (c.g, 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 - process_rgb_bmp (MaskFrame, rgba, DIAMETER, DIAMETER); + WriteFramePixelColors (MaskFrame, Orbit->ScratchArray, DIAMETER, DIAMETER); SetFrameHot (MaskFrame, MAKE_HOT_SPOT (RADIUS + 1, RADIUS + 1)); #if PROFILE_ROTATION @@ -1301,13 +1305,13 @@ planet_orbit_init (void) WANT_PIXMAP | WANT_ALPHA, MAP_WIDTH, MAP_HEIGHT, 2)); Orbit->ObjectFrame = 0; Orbit->WorkFrame = 0; - Orbit->lpTopoData = HMalloc (MAP_WIDTH * MAP_HEIGHT); + Orbit->lpTopoData = HCalloc (MAP_WIDTH * MAP_HEIGHT); Orbit->TopoZoomFrame = CaptureDrawable (CreateDrawable ( 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))); // 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)); } @@ -1773,7 +1777,7 @@ GeneratePlanetSurface (PLANET_DESC *pPlanetDesc, FRAME SurfDefFrame) } // grab the elevation data in 1 byte per pixel format - getpixelarray (Orbit->lpTopoData, 1, ElevFrame, + ReadFramePixelIndexes (ElevFrame, (BYTE *)Orbit->lpTopoData, MAP_WIDTH, MAP_HEIGHT); // the supplied data is in unsigned format, must convert 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. // It may be more efficient to build it from lpTopoData instead of the // FRAMPTR though. - getpixelarray (Orbit->lpTopoMap, 4, pSolarSysState->TopoFrame, + ReadFramePixelColors (pSolarSysState->TopoFrame, Orbit->TopoColors, MAP_WIDTH + SPHERE_SPAN_X, MAP_HEIGHT); // Extend the width from MAP_WIDTH to MAP_WIDTH+SPHERE_SPAN_X for (y = 0; y < MAP_HEIGHT * (MAP_WIDTH + SPHERE_SPAN_X); y += MAP_WIDTH + SPHERE_SPAN_X) - memcpy (Orbit->lpTopoMap + y + MAP_WIDTH, Orbit->lpTopoMap + y, - SPHERE_SPAN_X * sizeof (Orbit->lpTopoMap[0])); + memcpy (Orbit->TopoColors + y + MAP_WIDTH, Orbit->TopoColors + y, + SPHERE_SPAN_X * sizeof (Orbit->TopoColors[0])); if (PLANALGO (PlanDataPtr->Type) != GAS_GIANT_ALGO) { // convert topo data to a light map, based on relative