citylimits/core/map.cpp

1026 lines
28 KiB
C++
Raw Normal View History

2024-05-03 22:50:34 -04:00
/* map.cpp
*
* Micropolis, Unix Version. This game was released for the Unix platform
* in or about 1990 and has been modified for inclusion in the One Laptop
* Per Child program. Copyright (C) 1989 - 2007 Electronic Arts Inc. If
* you need assistance with this program, you may contact:
* http://wiki.laptop.org/go/Micropolis or email micropolis@laptop.org.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. You should have received a
* copy of the GNU General Public License along with this program. If
* not, see <http://www.gnu.org/licenses/>.
*
* ADDITIONAL TERMS per GNU GPL Section 7
*
* No trademark or publicity rights are granted. This license does NOT
* give you any right, title or interest in the trademark SimCity or any
* other Electronic Arts trademark. You may not distribute any
* modification of this program using the trademark SimCity or claim any
* affliation or association with Electronic Arts Inc. or its employees.
*
* Any propagation or conveyance of this program must include this
* copyright notice and these terms.
*
* If you convey this program (or any modifications of it) and assume
* contractual liability for the program to recipients of it, you agree
* to indemnify Electronic Arts for any liability that those contractual
* assumptions impose on Electronic Arts.
*
* You may not misrepresent the origins of this program; modified
* versions of the program must be marked as such and not identified as
* the original program.
*
* This disclaimer supplements the one included in the General Public
* License. TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, THIS
* PROGRAM IS PROVIDED TO YOU "AS IS," WITH ALL FAULTS, WITHOUT WARRANTY
* OF ANY KIND, AND YOUR USE IS AT YOUR SOLE RISK. THE ENTIRE RISK OF
* SATISFACTORY QUALITY AND PERFORMANCE RESIDES WITH YOU. ELECTRONIC ARTS
* DISCLAIMS ANY AND ALL EXPRESS, IMPLIED OR STATUTORY WARRANTIES,
* INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY, SATISFACTORY QUALITY,
* FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT OF THIRD PARTY
* RIGHTS, AND WARRANTIES (IF ANY) ARISING FROM A COURSE OF DEALING,
* USAGE, OR TRADE PRACTICE. ELECTRONIC ARTS DOES NOT WARRANT AGAINST
* INTERFERENCE WITH YOUR ENJOYMENT OF THE PROGRAM; THAT THE PROGRAM WILL
* MEET YOUR REQUIREMENTS; THAT OPERATION OF THE PROGRAM WILL BE
* UNINTERRUPTED OR ERROR-FREE, OR THAT THE PROGRAM WILL BE COMPATIBLE
* WITH THIRD PARTY SOFTWARE OR THAT ANY ERRORS IN THE PROGRAM WILL BE
* CORRECTED. NO ORAL OR WRITTEN ADVICE PROVIDED BY ELECTRONIC ARTS OR
* ANY AUTHORIZED REPRESENTATIVE SHALL CREATE A WARRANTY. SOME
* JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF OR LIMITATIONS ON IMPLIED
* WARRANTIES OR THE LIMITATIONS ON THE APPLICABLE STATUTORY RIGHTS OF A
* CONSUMER, SO SOME OR ALL OF THE ABOVE EXCLUSIONS AND LIMITATIONS MAY
* NOT APPLY TO YOU.
*/
/**
* @file map.cpp
* @brief Handles drawing and managing various map overlays in
* Micropolis.
*
* This file includes functions for drawing different types of map
* overlays, such as residential, commercial, industrial areas, power
* grid, and various types of density maps. It also contains functions
* for applying dynamic filters to maps and managing map state.
*/
////////////////////////////////////////////////////////////////////////
#include "micropolis.h"
// NOTE: This is disabled, and should be re-implementd in the front-end.
#if 0
////////////////////////////////////////////////////////////////////////
// Disabled this small map drawing, filtering and overlaying code.
// Going to re-implement it in the tile engine and Python.
#define VAL_NONE 0
#define VAL_LOW 1
#define VAL_MEDIUM 2
#define VAL_HIGH 3
#define VAL_VERYHIGH 4
#define VAL_PLUS 5
#define VAL_VERYPLUS 6
#define VAL_MINUS 7
#define VAL_VERYMINUS 8
/* These are names of the 16 colors */
#define COLOR_WHITE 0
#define COLOR_YELLOW 1
#define COLOR_ORANGE 2
#define COLOR_RED 3
#define COLOR_DARKRED 4
#define COLOR_DARKBLUE 5
#define COLOR_LIGHTBLUE 6
#define COLOR_BROWN 7
#define COLOR_LIGHTGREEN 8
#define COLOR_DARKGREEN 9
#define COLOR_OLIVE 10
#define COLOR_LIGHTBROWN 11
#define COLOR_LIGHTGRAY 12
#define COLOR_MEDIUMGRAY 13
#define COLOR_DARKGRAY 14
#define COLOR_BLACK 15
/*
static short valMap[] = {
-1, // VAL_NONE
COLOR_LIGHTGRAY, // VAL_LOW
COLOR_YELLOW, // VAL_MEDIUM
COLOR_ORANGE, // VAL_HIGH
COLOR_RED, // VAL_VERYHIGH
COLOR_DARKGREEN, // VAL_PLUS
COLOR_LIGHTGREEN, // VAL_VERYPLUS
COLOR_ORANGE, // VAL_MINUS
COLOR_YELLOW, // VAL_VERYMINUS
};
static short valGrayMap[] = {
-1, 31, 127, 191, 255,
223, 255, 31, 0
};
*/
/* color pixel values */
#define UNPOWERED COLOR_LIGHTBLUE
#define POWERED COLOR_RED
#define CONDUCTIVE COLOR_LIGHTGRAY
#define DRAW_BEGIN \
int col, row; \
unsigned short tile; \
short *mp; \
unsigned char *imageBase; \
unsigned char *image; \
UQuad *mem; \
UQuad m; \
int lineBytes = view->line_bytes8; \
int pixelBytes = view->pixel_bytes; \
mp = &map[0][0]; \
imageBase = view->x->color ? view->data : view->data8; \
for (col = 0; col < WORLD_W; col++) { \
image = imageBase + (3 * pixelBytes * col); \
for (row = 0; row < WORLD_H; row++) { \
tile = *(mp++) & LOMASK; \
if (tile >= TILE_COUNT) { \
tile -= TILE_COUNT; \
}
#ifdef IS_INTEL
#define ROW1_8(n) \
m = mem[n]; \
image[0] = (unsigned char)(m); \
image[1] = (unsigned char)(m >>8); \
image[2] = (unsigned char)(m >>16); \
image += lineBytes;
#define ROW1_16(n) \
memcpy((char *)image, ((char *)mem) + (n * 4 * 2), (3 * 2)); \
image += lineBytes;
#define ROW1_24(n) \
memcpy((char *)image, ((char *)mem) + (n * 4 * 3), (3 * 3)); \
image += lineBytes;
#define ROW1_32(n) \
memcpy((char *)image, ((char *)mem) + (n * 4 * 4), (3 * 4)); \
image += lineBytes;
#else
#define ROW1_8(n) \
m = (UQuad)(mem[n]); \
image[0] = (unsigned char)(m >>24); \
image[1] = (unsigned char)(m >>16); \
image[2] = (unsigned char)(m >>8); \
image += lineBytes;
#define ROW1_16(n) \
m = (UQuad)mem[n]; /* XXX: WRONG. handle depth */ \
image[0] = (unsigned char)(m >>24); \
image[1] = (unsigned char)(m >>16); \
image[2] = (unsigned char)(m >>8); \
image += lineBytes;
#define ROW1_24(n) \
m = (UQuad)mem[n]; /* XXX: WRONG. handle depth */ \
image[0] = (unsigned char)(m >>24); \
image[1] = (unsigned char)(m >>16); \
image[2] = (unsigned char)(m >>8); \
image += lineBytes;
#define ROW1_32(n) \
m = (UQuad)mem[n]; /* XXX: WRONG. handle depth */ \
image[0] = (unsigned char)(m >>24); \
image[1] = (unsigned char)(m >>16); \
image[2] = (unsigned char)(m >>8); \
image += lineBytes;
#endif
#define ROW3_8 ROW1_8(0) ROW1_8(1) ROW1_8(2)
#define ROW3_16 ROW1_16(0) ROW1_16(1) ROW1_16(2)
#define ROW3_24 ROW1_24(0) ROW1_24(1) ROW1_24(2)
#define ROW3_32 ROW1_32(0) ROW1_32(1) ROW1_32(2)
#define ROW3 \
switch (view->x->depth) { \
case 1: \
case 8: \
ROW3_8 \
break; \
case 15: \
case 16: \
ROW3_16 \
break; \
case 24: \
ROW3_24 \
break; \
case 32: \
ROW3_32 \
break; \
default: \
assert(0); /* Undefined depth */ \
break; \
}
#define DRAW_END \
mem = (UQuad *)&view->smalltiles[tile * 4 * 4 * pixelBytes]; \
ROW3 \
} \
}
void Micropolis::drawAll()
{
DRAW_BEGIN
DRAW_END
}
void Micropolis::drawRes()
{
DRAW_BEGIN
if (tile >= COMBASE) {
tile = DIRT;
}
DRAW_END
}
void Micropolis::drawCom()
{
DRAW_BEGIN
if ((tile > COMLAST) ||
((tile >= LVRAIL6) &&
(tile < COMBASE))) {
tile = DIRT;
}
DRAW_END
}
void Micropolis::drawInd()
{
DRAW_BEGIN
if (((tile >= RESBASE) && (tile < INDBASE)) ||
((tile >= PORTBASE) && (tile < SMOKEBASE)) ||
((tile >= TINYEXP) && (tile <= TINYEXPLAST)) ||
(tile >= FOOTBALLGAME1)) {
tile = DIRT;
}
DRAW_END
}
void Micropolis::drawLilTransMap()
{
DRAW_BEGIN
if ((tile >= RESBASE) ||
((tile >= BRWXXX7) && (tile <= LVPOWER10)) ||
(tile == UNUSED_TRASH6)) {
tile = DIRT;
}
DRAW_END
}
void Micropolis::drawPowerGrid()
{
short col, row;
unsigned short tile;
short *mp;
unsigned char *image, *imageBase;
UQuad *mem;
UQuad m;
int lineBytes = view->line_bytes8;
int pixelBytes = view->pixel_bytes;
int pix;
int powered, unpowered, conductive;
if (view->x->color) {
powered = view->pixels[POWERED];
unpowered = view->pixels[UNPOWERED];
conductive = view->pixels[CONDUCTIVE];
} else {
powered = 255;
unpowered = 0;
conductive = 127;
}
mp =
&map[0][0];
imageBase =
view->x->color ? view->data : view->data8;
for (col = 0; col < WORLD_W; col++) {
image =
imageBase + (3 * pixelBytes * col);
for (row = 0; row < WORLD_H; row++) {
tile = *(mp++);
if ((tile & LOMASK) >= TILE_COUNT) {
tile -= TILE_COUNT;
}
if ((tile & LOMASK) <= LASTFIRE) {
tile &= LOMASK;
pix = -1;
} else if (tile & ZONEBIT) {
pix = (tile & PWRBIT) ? powered : unpowered;
} else {
if (tile & CONDBIT) {
pix = conductive;
} else {
tile = DIRT;
pix = -1;
}
}
if (pix < 0) {
mem = (UQuad *)&view->smalltiles[tile * 4 * 4 * pixelBytes];
ROW3
} else {
switch (view->x->depth) {
case 1:
case 8:
image[0] = image[1] = image[2] = pix;
image += lineBytes;
image[0] = image[1] = image[2] = pix;
image += lineBytes;
image[0] = image[1] = image[2] = pix;
image += lineBytes;
break;
case 15:
case 16: {
unsigned short *p;
p = (unsigned short *)image;
p[0] = p[1] = p[2] = pix;
image += lineBytes;
p = (unsigned short *)image;
p[0] = p[1] = p[2] = pix;
image += lineBytes;
p = (unsigned short *)image;
p[0] = p[1] = p[2] = pix;
image += lineBytes;
break;
}
case 24:
case 32: {
int x, y;
for (y = 0; y < 3; y++) {
unsigned char *img = image;
for (x = 0; x < 4; x++) {
*(img++) = (pix >> 0) & 0xff;
*(img++) = (pix >> 8) & 0xff;
*(img++) = (pix >> 16) & 0xff;
if (pixelBytes == 4) {
img++;
} // if
} // for x
image += lineBytes;
} // for y
break;
}
default:
assert(0); /* Undefined depth */
break;
}
}
}
}
}
bool Micropolis::dynamicFilter(
int col,
int row)
{
int populationDensity = populationDensityMap.worldGet(col, row);
int rateOfGrowth = rateOfGrowthMap.worldGet(col, row);
int traffic = trafficDensityMap.worldGet(col, row);
int pollution = pollutionDensityMap.worldGet(col, row);
int crime = crimeRateMap.worldGet(col, row);
int landValue = landValueMap.worldGet(col, row);
int police = policeStationEffectMap.worldGet(col, row);
int fire = fireStationEffectMap.worldGet(col, row);
return (
((dynamicData[0] > dynamicData[1]) ||
(populationDensity >= dynamicData[0]) &&
(populationDensity <= dynamicData[1])) &&
((dynamicData[2] > dynamicData[3]) ||
(rateOfGrowth >= ((2 * dynamicData[2]) - 256)) &&
(rateOfGrowth <= ((2 * dynamicData[3]) - 256))) &&
((dynamicData[4] > dynamicData[5]) ||
(traffic >= dynamicData[4]) &&
(traffic <= dynamicData[5])) &&
((dynamicData[6] > dynamicData[7]) ||
(pollution >= dynamicData[6]) &&
(pollution <= dynamicData[7])) &&
((dynamicData[8] > dynamicData[9]) ||
(crime >= dynamicData[8]) &&
(crime <= dynamicData[9])) &&
((dynamicData[10] > dynamicData[11]) ||
(landValue >= dynamicData[10]) &&
(landValue <= dynamicData[11])) &&
((dynamicData[12] > dynamicData[13]) ||
(police >= dynamicData[12]) &&
(police <= dynamicData[13])) &&
((dynamicData[14] > dynamicData[15]) ||
(fire >= dynamicData[14]) &&
(fire <= dynamicData[15])));
}
void Micropolis::drawDynamic()
{
DRAW_BEGIN
if (tile > LASTFIRE) {
if (!dynamicFilter(col, row)) {
tile = DIRT;
} // if
} // if
DRAW_END
}
short Micropolis::getCI(short x)
{
if (x < 50) {
return VAL_NONE;
}
if (x < 100) {
return VAL_LOW;
}
if (x < 150) {
return VAL_MEDIUM;
}
if (x < 200) {
return VAL_HIGH;
}
return VAL_VERYHIGH;
}
/** Draw population density overlay at small map */
void Micropolis::drawPopulationDensity()
{
short x, y;
drawAll();
for (x = 0; x < WORLD_W; x += populationDensityMap.MAP_BLOCKSIZE) {
for (y = 0; y < WORLD_H; y += populationDensityMap.MAP_BLOCKSIZE) {
maybeDrawRect(
getCI(populationDensityMap.worldGet(x, y)),
x * 3,
y * 3,
3 * populationDensityMap.MAP_BLOCKSIZE,
3 * populationDensityMap.MAP_BLOCKSIZE);
}
}
}
void Micropolis::drawRateOfGrowth()
{
short x, y;
drawAll();
for (x = 0; x < rateOfGrowthMap.MAP_W; x++) {
for (y = 0; y < rateOfGrowthMap.MAP_H; y++) {
short val;
short z = rateOfGrowthMap.get(x, y);
if (z > 100) {
val = VAL_VERYPLUS;
} else {
if (z > 20) {
val = VAL_PLUS;
} else {
if (z < -100) {
val = VAL_VERYMINUS;
} else {
if (z < -20) {
val = VAL_MINUS;
} else {
val = VAL_NONE;
}
}
}
}
maybeDrawRect(
val,
x * 24,
y * 24,
24,
24);
}
}
}
/** Draw traffic density overlay at the small map */
void Micropolis::drawTrafficDensityMap()
{
short x;
short y;
drawLilTransMap();
for (x = 0; x < WORLD_W; x += trafficDensityMap.MAP_BLOCKSIZE) {
for (y = 0; y < WORLD_H; y += trafficDensityMap.MAP_BLOCKSIZE) {
maybeDrawRect(
getCI(trafficDensityMap.worldGet(x, y)),
x * 3,
y * 3,
3 * trafficDensityMap.MAP_BLOCKSIZE,
3 * trafficDensityMap.MAP_BLOCKSIZE);
}
}
}
/** Draw pollution overlay at the small map */
void Micropolis::drawPollutionMap()
{
short x, y;
drawAll(view);
for (x = 0; x < WORLD_W; x += pollutionDensityMap.MAP_BLOCKSIZE) {
for (y = 0; y < WORLD_H; y += pollutionDensityMap.MAP_BLOCKSIZE) {
maybeDrawRect(
getCI(10 + pollutionDensityMap.worldGet(x, y)),
x * 3,
y * 3,
3 * pollutionDensityMap.MAP_BLOCKSIZE,
3 * pollutionDensityMap.MAP_BLOCKSIZE);
}
}
}
/** Draw crime overlay at the small map */
void Micropolis::drawCrimeRateMap()
{
short x, y;
drawAll();
for (x = 0; x < WORLD_W; x += crimeRateMap.MAP_BLOCKSIZE) {
for (y = 0; y < WORLD_H; y += crimeRateMap.MAP_BLOCKSIZE) {
maybeDrawRect(
getCI(crimeRateMap.worldGet(x, y)),
x * 3,
y * 3,
3 * crimeRateMap.MAP_BLOCKSIZE,
3 * crimeRateMap.MAP_BLOCKSIZE);
}
}
}
void Micropolis::drawLandValueMap()
{
short x, y;
drawAll();
for (x = 0; x < landValueMap.MAP_W; x++) {
for (y = 0; y < landValueMap.MAP_H; y++) {
maybeDrawRect(
view,
getCI(landValueMap.get(x, y)),
x * 6,
y * 6,
6,
6);
}
}
}
void Micropolis::drawFireRadius()
{
short x, y;
drawAll();
for (x = 0; x < fireStationEffectMap.MAP_W; x++) {
for (y = 0; y < fireStationEffectMap.MAP_H; y++) {
maybeDrawRect(
getCI(fireStationEffectMap.get(x, y)),
x * 24,
y * 24,
24,
24);
}
}
}
void Micropolis::drawPoliceRadius()
{
short x, y;
drawAll();
for (x = 0; x < policeStationEffectMap.MAP_W; x++) {
for (y = 0; y < policeStationEffectMap.MAP_H; y++) {
maybeDrawRect(
getCI(policeStationEffectMap.get(x, y)),
x * 24,
y * 24,
24,
24);
}
}
}
void Micropolis::memDrawMap()
{
switch (view->map_state) {
case MAP_TYPE_ALL:
drawAll(view);
break;
case MAP_TYPE_RES:
drawRes(view);
break;
case MAP_TYPE_COM:
drawCom(view);
break;
case MAP_TYPE_IND:
drawInd(view);
break;
case MAP_TYPE_POWER:
drawPowerGrid(view);
break;
case MAP_TYPE_ROAD:
drawLilTransMap(view);
break;
case MAP_TYPE_POPULATION_DENSITY:
drawPopulationDensity(view);
break;
case MAP_TYPE_RATE_OF_GROWTH:
drawRateOfGrowth(view);
break;
case MAP_TYPE_TRAFFIC:
drawTrafficDensityMap(view);
break;
case MAP_TYPE_POLLUTION:
drawPollutionDensityMap(view);
break;
case MAP_TYPE_CRIME:
drawCrimeRateMap(view);
break;
case MAP_TYPE_LAND_VALUE:
drawLandValueMap(view);
break;
case MAP_TYPE_FIRE_RADIUS:
drawFireRadius(view);
break;
case MAP_TYPE_POLICE_RADIUS:
drawPoliceRadius(view);
break;
case MAP_TYPE_DYNAMIC:
drawDynamic(view);
break;
default:
assert(0); /* Undefined map */
break;
}
/*
if (!view->x->color) {
ditherMap(view);
XSetForeground(view->x->dpy, view->x->gc, view->pixels[COLOR_BLACK]);
XSetBackground(view->x->dpy, view->x->gc, view->pixels[COLOR_WHITE]);
XPutImage(view->x->dpy, view->pixmap, view->x->gc, view->image,
0, 0, 0, 0, view->m_width, view->m_height);
}
*/
}
void Micropolis::ditherMap()
{
/*
int i, x, y, width, height;
int err, pixel1, pixel8;
int line_bytes1 = view->line_bytes;
int line_bytes8 = view->line_bytes8;
unsigned char *image1 = view->data;
unsigned char *image8 = view->data8;
int *errors;
width = view->m_width;
height = view->m_height;
errors = (int *)newPtr(sizeof(int) * width);
for (i = 0; i < width; i++) {
errors[i] = (getRandom16() & 15) - 7;
}
err = (getRandom16() & 15) - 7;
for (y = 0; y < height; y += 2) {
unsigned char *i1 = image1;
unsigned char *i8 = image8;
image1 += line_bytes1;
image8 += line_bytes8;
for (x = 0; x < width; x += 8) {
pixel1 = 0;
for (i = 0; i < 8; i++) {
pixel1 <<= 1;
pixel8 = *(i8++) + err + errors[x + i];
if (pixel8 > 127) {
err = pixel8 - 255;
} else {
pixel1 |= 1;
err = pixel8;
}
errors[x + i] = err/2;
err = err/2;
}
*(i1++) = pixel1;
}
i1 = image1 + (width / 8) - 1;
i8 = image8 + width - 1;
image1 += line_bytes1;
image8 += line_bytes8;
for (x = width - 8; x >= 0; x -= 8) {
pixel1 = 0;
for (i = 7; i >= 0; i--) {
pixel1 >>= 1;
pixel8 = *(i8--) + err + errors[x + i];
if (pixel8 > 127) {
err = pixel8 - 255;
} else {
pixel1 |= 128;
err = pixel8;
}
errors[x + i] = err/2;
err = err/2;
}
*(i1--) = pixel1;
}
}
freePtr(errors);
*/
}
void Micropolis::maybeDrawRect(
int val,
int x,
int y,
int w,
int h)
{
if (val == VAL_NONE) {
return;
}
/*
if (view->x->color) {
drawRect(view, view->pixels[valMap[val]], 0, x, y, w, h);
} else {
drawRect(view, valGrayMap[val], 1, x, y, w, h);
}
*/
}
void Micropolis::drawRect(
int pixel,
int solid,
int x,
int y,
int w,
int h)
{
/*
int W = view->m_width, H = view->m_height;
if (x < 0) {
if ((w += x) < 0) {
w = 0;
}
x = 0;
} else if (x > W) {
x = 0;
w = 0;
}
if (x + w > W) {
w = W - x;
}
if (y < 0) {
if ((h += y) < 0) {
h = 0;
}
y = 0;
} else if (y > H) {
y = 0;
h = 0;
}
if (y + h > H) {
h = H - y;
}
if (w && h) {
int i, j, stipple = (x ^ y) & 1;
unsigned char *data =
view->x->color ? view->data : view->data8;
// In the case of black and white, we use an 8 bit buffer and dither it.
int pixelBytes =
view->x->color ? view->pixel_bytes : 1;
Quad line =
view->x->color ? view->line_bytes : view->line_bytes8;
unsigned char *image =
&(data[(line * y) + (x * pixelBytes)]);
switch (pixelBytes) {
case 1: {
unsigned char *data =
view->data8;
unsigned char *image =
&data[(line * y) + (x * pixelBytes)];
if (solid) {
for (i = h; i > 0; i--) {
for (j = w; j > 0; j--) {
*image = pixel;
image++;
}
image += line - w;
}
} else {
for (i = h; i > 0; i--) {
for (j = w; j > 0; j--) {
if (stipple++ & 1) {
*image = pixel;
}
image++;
}
if (!(w & 1))
stipple++;
image += line - w;
}
}
break;
}
case 2: {
unsigned short *data =
(unsigned short *)view->data;
unsigned short *image;
line >>= 1; // Convert from byte offset to short offset
image =
&data[(line * y) + x];
if (solid) {
for (i = h; i > 0; i--) {
for (j = w; j > 0; j--) {
*image = pixel;
image++;
}
image += line - w;
}
} else {
for (i = h; i > 0; i--) {
for (j = w; j > 0; j--) {
if (stipple++ & 1) {
*image = pixel;
}
image++;
}
if (!(w & 1)) {
stipple++;
}
image += line - w;
}
}
break;
}
case 3:
case 4: {
unsigned char *data =
(unsigned char *)view->data;
unsigned char *image;
int bitmapPad = view->x->small_tile_image->bitmap_pad;
int rowBytes = view->x->small_tile_image->bytes_per_line;
line = rowBytes >> 1; // Convert from byte offset to short offset
image = &data[(line * y) + x];
if (solid) {
for (i = h; i > 0; i--) {
for (j = w; j > 0; j--) {
*(image++) = (pixel >> 0) & 0xff;
*(image++) = (pixel >> 8) & 0xff;
*(image++) = (pixel >> 16) & 0xff;
if (bitmapPad == 32) {
image++;
}
}
image += line - w;
}
} else {
for (i = h; i > 0; i--) {
for (j = w; j > 0; j--) {
if (stipple++ & 1) {
*(image++) = (pixel >> 0) & 0xff;
*(image++) = (pixel >> 8) & 0xff;
*(image++) = (pixel >> 16) & 0xff;
if (bitmapPad == 32) {
image++;
}
}
}
if (!(w & 1)) {
stipple++;
}
image += line - w;
}
}
break;
}
default:
assert(0); // Undefined depth
break;
}
}
*/
}
#endif
////////////////////////////////////////////////////////////////////////