/** * premultiply_rgba: * * Takes an input in ABGR non-premultiplied image data and premultiplies it. * The returned data must be freed with free(). **/ static unsigned char* premultiply_rgba (unsigned char* data, int width, int height, int stride) { unsigned char* retdata = reinterpret_cast<unsigned char*>(_cairo_malloc_ab(height, stride)); if (!retdata) return NULL; unsigned char* end = data + stride * height; for (unsigned char* in = data, *out = retdata; in < end; in += stride, out += stride) { for (int i = 0; i < width; ++i) { // XXX for a big-endian platform this'd have to change int idx = 4 * i; unsigned char alpha = in[idx + 3]; out[idx + 0] = premultiply(in[idx + 0], alpha); // B out[idx + 1] = premultiply(in[idx + 1], alpha); // G out[idx + 2] = premultiply(in[idx + 2], alpha); // R out[idx + 3] = in[idx + 3]; // Alpha } } return retdata; }
static cairo_int_status_t _cairo_beos_surface_fill_rectangles (void *abstract_surface, cairo_operator_t op, const cairo_color_t *color, cairo_rectangle_int16_t *rects, int num_rects) { fprintf(stderr, "Drawing %i rectangles\n", num_rects); cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>( abstract_surface); if (num_rects <= 0) return CAIRO_INT_STATUS_SUCCESS; AutoLockView locker(surface->view); if (!locker) return CAIRO_INT_STATUS_SUCCESS; drawing_mode mode; if (!_cairo_op_to_be_op(op, &mode)) return CAIRO_INT_STATUS_UNSUPPORTED; rgb_color be_color = _cairo_color_to_be_color(color); if (mode == B_OP_ALPHA && be_color.alpha == 0xFF) mode = B_OP_COPY; // For CAIRO_OPERATOR_SOURCE, cairo expects us to use the premultiplied // color info. This is only relevant when drawing into an rgb24 buffer // (as for others, we can convert when asked for the image) if (mode == B_OP_COPY && be_color.alpha != 0xFF && (!surface->bitmap || surface->bitmap->ColorSpace() != B_RGBA32)) { be_color.red = premultiply(be_color.red, be_color.alpha); be_color.green = premultiply(be_color.green, be_color.alpha); be_color.blue = premultiply(be_color.blue, be_color.alpha); } surface->view->PushState(); surface->view->SetDrawingMode(mode); surface->view->SetHighColor(be_color); if (surface->bitmap && surface->bitmap->ColorSpace() == B_RGBA32) surface->view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE); else surface->view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY); for (int i = 0; i < num_rects; ++i) { _cairo_beos_surface_fill_rectangle(surface, &rects[i]); } surface->view->PopState(); return CAIRO_INT_STATUS_SUCCESS; }
static uint32_t color_stop_to_pixel(const cairo_gradient_stop_t *stop) { uint8_t a, r, g, b; a = stop->color.alpha_short >> 8; r = premultiply(stop->color.red, stop->color.alpha); g = premultiply(stop->color.green, stop->color.alpha); b = premultiply(stop->color.blue, stop->color.alpha); if (_cairo_is_little_endian ()) return a << 24 | r << 16 | g << 8 | b << 0; else return a << 0 | r << 8 | g << 16 | b << 24; }
std::shared_ptr<FIBITMAP> load_image(const std::wstring& filename) { if(!boost::filesystem::exists(filename)) BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(narrow(filename))); FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileTypeU(filename.c_str(), 0); if(fif == FIF_UNKNOWN) fif = FreeImage_GetFIFFromFilenameU(filename.c_str()); if(fif == FIF_UNKNOWN || !FreeImage_FIFSupportsReading(fif)) BOOST_THROW_EXCEPTION(invalid_argument() << msg_info("Unsupported image format.")); auto bitmap = std::shared_ptr<FIBITMAP>(FreeImage_LoadU(fif, filename.c_str(), 0), FreeImage_Unload); if(FreeImage_GetBPP(bitmap.get()) != 32) { bitmap = std::shared_ptr<FIBITMAP>(FreeImage_ConvertTo32Bits(bitmap.get()), FreeImage_Unload); if(!bitmap) BOOST_THROW_EXCEPTION(invalid_argument() << msg_info("Unsupported image format.")); } //PNG-images need to be premultiplied with their alpha if(fif == FIF_PNG) { image_view<bgra_pixel> original_view(FreeImage_GetBits(bitmap.get()), FreeImage_GetWidth(bitmap.get()), FreeImage_GetHeight(bitmap.get())); premultiply(original_view); } return bitmap; }
/* * Draw a character to a context. */ static void draw_char(FT_Bitmap * bitmap, int x, int y, uint32_t fg, gfx_context_t * ctx) { int i, j, p, q; int x_max = x + bitmap->width; int y_max = y + bitmap->rows; for (j = y, q = 0; j < y_max; j++, q++) { for ( i = x, p = 0; i < x_max; i++, p++) { uint32_t a = _ALP(fg); a = (a * bitmap->buffer[q * bitmap->width + p]) / 255; uint32_t tmp = premultiply(rgba(_RED(fg),_GRE(fg),_BLU(fg),a)); SGFX(ctx->backbuffer,i,j,ctx->width) = alpha_blend_rgba(SGFX(ctx->backbuffer,i,j,ctx->width),tmp); } } }
void Tile::AssembleSpriteFromSheet( int spriteNum, ALLEGRO_BITMAP* spriteSheet, ALLEGRO_COLOR color, float x, float y, Tile * b, float in_scale) { int sheetx = spriteNum % SHEET_OBJECTSWIDE; int sheety = spriteNum / SHEET_OBJECTSWIDE; AssembleSprite( spriteSheet, premultiply(b ? shadeAdventureMode(color, b->fog_of_war, b->designation.bits.outside) : color), sheetx * SPRITEWIDTH * in_scale, sheety * SPRITEHEIGHT * in_scale, SPRITEWIDTH * in_scale, SPRITEHEIGHT * in_scale, x, y - (WALLHEIGHT)*ssConfig.scale, SPRITEWIDTH*ssConfig.scale, SPRITEHEIGHT*ssConfig.scale, 0); }
result_type operator()(argument_type srcP) const { result_type dstP; premultiply () (srcP,dstP); return dstP; }
void blend(TToonzImageP ti, TRasterPT<PIXEL> rasOut, const std::vector<BlendParam> ¶ms) { assert(ti->getRaster()->getSize() == rasOut->getSize()); // Extract the interesting raster. It should be the savebox of passed cmap, // plus - if // some param has the 0 index as blending color - the intensity of that blend // param. unsigned int i, j; TRect saveBox(ti->getSavebox()); int enlargement = 0; for (i = 0; i < params.size(); ++i) for (j = 0; j < params[i].colorsIndexes.size(); ++j) if (params[i].colorsIndexes[j] == 0) enlargement = std::max(enlargement, tceil(params[i].intensity)); saveBox = saveBox.enlarge(enlargement); TRasterCM32P cmIn(ti->getRaster()->extract(saveBox)); TRasterPT<PIXEL> rasOutExtract = rasOut->extract(saveBox); // Ensure that cmIn and rasOut have the same size unsigned int lx = cmIn->getLx(), ly = cmIn->getLy(); // Build the pure colors infos SelectionRaster selectionRaster(cmIn); // Now, build a little group of BlurPatterns - and for each, one for passed // param. // A small number of patterns per param is needed to make the pattern look not // ever the same. const int blurPatternsPerParam = 10; std::vector<BlurPatternContainer> blurGroup(params.size()); for (i = 0; i < params.size(); ++i) { BlurPatternContainer &blurContainer = blurGroup[i]; blurContainer.reserve(blurPatternsPerParam); for (j = 0; j < blurPatternsPerParam; ++j) blurContainer.push_back(BlurPattern( params[i].intensity, params[i].smoothness, params[i].stopAtCountour)); } // Build the palette TPalette *palette = ti->getPalette(); std::vector<TPixel32> paletteColors; paletteColors.resize(palette->getStyleCount()); for (i = 0; i < paletteColors.size(); ++i) paletteColors[i] = premultiply(palette->getStyle(i)->getAverageColor()); // Build the 4 auxiliary rasters for the blending procedure: they are ink / // paint versus input / output in the blend. // The output raster is reused to spare some memory - it should be, say, the // inkLayer's second at the end of the overall // blending procedure. It could be the first, without the necessity of // clearing it before blending the layers, but things // get more complicated when PIXEL is TPixel64... RGBMRasterPair inkLayer, paintLayer; TRaster32P rasOut32P_1(lx, ly, lx, (TPixel32 *)rasOut->getRawData(), false); inkLayer.first = (params.size() % 2) ? rasOut32P_1 : TRaster32P(lx, ly); inkLayer.second = (params.size() % 2) ? TRaster32P(lx, ly) : rasOut32P_1; if (PIXEL::maxChannelValue >= TPixel64::maxChannelValue) { TRaster32P rasOut32P_2(lx, ly, lx, ((TPixel32 *)rasOut->getRawData()) + lx * ly, false); paintLayer.first = (params.size() % 2) ? rasOut32P_2 : TRaster32P(lx, ly); paintLayer.second = (params.size() % 2) ? TRaster32P(lx, ly) : rasOut32P_2; } else { paintLayer.first = TRaster32P(lx, ly); paintLayer.second = TRaster32P(lx, ly); } inkLayer.first->clear(); inkLayer.second->clear(); paintLayer.first->clear(); paintLayer.second->clear(); // Now, we have to perform the blur of each of the cm's pixels. cmIn->lock(); rasOut->lock(); inkLayer.first->lock(); inkLayer.second->lock(); paintLayer.first->lock(); paintLayer.second->lock(); // Convert the initial cmIn to fullcolor ink - paint layers buildLayers(cmIn, paletteColors, inkLayer.first, paintLayer.first); // Perform the blend on separated ink - paint layers for (i = 0; i < params.size(); ++i) { if (params[i].colorsIndexes.size() == 0) continue; selectionRaster.updateSelection(cmIn, params[i]); doBlend(cmIn, inkLayer, paintLayer, selectionRaster, blurGroup[i]); tswap(inkLayer.first, inkLayer.second); tswap(paintLayer.first, paintLayer.second); } // Release the unnecessary rasters inkLayer.second->unlock(); paintLayer.second->unlock(); inkLayer.second = TRaster32P(); paintLayer.second = TRaster32P(); // Clear rasOut - since it was reused to spare space... rasOut->clear(); // Add the ink & paint layers on the output raster double PIXELmaxChannelValue = PIXEL::maxChannelValue; double toPIXELFactor = PIXELmaxChannelValue / (double)TPixel32::maxChannelValue; double inkFactor, paintFactor; TPoint pos; PIXEL *outPix, *outBegin = (PIXEL *)rasOutExtract->getRawData(); TPixelCM32 *cmPix, *cmBegin = (TPixelCM32 *)cmIn->getRawData(); int wrap = rasOutExtract->getWrap(); TPixel32 *inkPix = (TPixel32 *)inkLayer.first->getRawData(); TPixel32 *paintPix = (TPixel32 *)paintLayer.first->getRawData(); for (i = 0; i < ly; ++i) { outPix = outBegin + wrap * i; cmPix = cmBegin + wrap * i; for (j = 0; j < lx; ++j, ++outPix, ++cmPix, ++inkPix, ++paintPix) { getFactors(cmPix->getTone(), inkFactor, paintFactor); outPix->r = tcrop( toPIXELFactor * (inkFactor * inkPix->r + paintFactor * paintPix->r), 0.0, PIXELmaxChannelValue); outPix->g = tcrop( toPIXELFactor * (inkFactor * inkPix->g + paintFactor * paintPix->g), 0.0, PIXELmaxChannelValue); outPix->b = tcrop( toPIXELFactor * (inkFactor * inkPix->b + paintFactor * paintPix->b), 0.0, PIXELmaxChannelValue); outPix->m = tcrop( toPIXELFactor * (inkFactor * inkPix->m + paintFactor * paintPix->m), 0.0, PIXELmaxChannelValue); } } inkLayer.first->unlock(); paintLayer.first->unlock(); cmIn->unlock(); rasOut->unlock(); // Destroy the auxiliary bitmaps selectionRaster.destroy(); }
void c_sprite::draw_world_offset(int x, int y, int z, Block * b, int tileoffset, bool chop) { if(defaultsheet == 0) defaultsheet = IMGObjectSheet; //sprites can be offset by a random amount, both animationwise, and just variationwise. //the base offset is set here. int rando = randomCube[(b->x)%RANDOM_CUBE][(b->y)%RANDOM_CUBE][(b->z)%RANDOM_CUBE]; //and the random offset of the animation frame is set here, provided the sprite iis set to use random animation frames. int offsetAnimFrame = ((randomanimation?rando:0) + currentAnimationFrame) % MAX_ANIMFRAME; //the following stuff is only bothered with if the animation frames say it should be drawn. this can be over-ridden // by setting animate to 0 if(sheetindex == 48) { int spam = 0; spam++; } if ((animframes & (1 << offsetAnimFrame)) || !animate) { //if set by the xml file, a random offset between 0 and 'variations' is added to the sprite. int randoffset = 0; if(variations) randoffset = rando%variations; if(!b) return; //if the xml says that this is a blood sprite, and offset is set here for proper pooling. this over-rides the random offset. if(bloodsprite) randoffset = getBloodOffset(b); if((water_direction < 0) || (water_direction == get_relative_water_direction(b))) { if(( //these are all border conditions. this first section is a list of positive conditions. if at least one of the border conditions is met, the tile can be shown. (openborders & b->openborders) || (upstairborders & b->upstairborders) || (downstairborders & b->downstairborders) || (rampborders & b->rampborders) || (wallborders & b->wallborders) || (floorborders & b->floorborders) || (lightborders & b->lightborders) ) && !( //This second block consists of negative conditions. if /any/ of these border conditions are met, the tile will not be drawn (notopenborders & b->openborders) || (notupstairborders & b->upstairborders) || (notdownstairborders & b->downstairborders) || (notrampborders & b->rampborders) || (notwallborders & b->wallborders) || (notfloorborders & b->floorborders) || (darkborders & b->lightborders) )) { int foo = 0; if( ( snowmin <= b->snowlevel && (snowmax == -1 || snowmax >= b->snowlevel) ) && ( bloodmin <= b->bloodlevel && (bloodmax == -1 || bloodmax >= b->bloodlevel) ) && ( mudmin <= b->mudlevel && (mudmax == -1 || mudmax >= b->mudlevel) ) && ( grassmin <= b->grasslevel && (grassmax == -1 || grassmax >= b->grasslevel) ) && //only bother with this tile if it's in the light, or not. ( (light==LIGHTANY) || ( (light==LIGHTYES) && b->designation.bits.outside ) || ( (light==LIGHTNO) && !(b->designation.bits.outside) ) ) && ( (grasstype == -1) || (grasstype == b->grassmat) ) && ( (grass_growth == GRASS_GROWTH_ANY) || ( (grass_growth == GRASS_GROWTH_NORMAL) && ( (b->tileMaterial == tiletype_material::GRASS_DARK) || (b->tileMaterial == tiletype_material::GRASS_LIGHT) ) ) || ( (grass_growth == GRASS_GROWTH_DRY) && (b->tileMaterial == tiletype_material::GRASS_DRY) ) || ( (grass_growth == GRASS_GROWTH_DEAD) && (b->tileMaterial == tiletype_material::GRASS_DEAD) ) ) ) { int32_t drawx = x; int32_t drawy = y; int32_t drawz = z; //- ownerSegment->sizez + 1; correctBlockForSegmetOffset( drawx, drawy, drawz); correctBlockForRotation( drawx, drawy, drawz, b->ownerSegment->rotation); int32_t viewx = drawx; int32_t viewy = drawy; int32_t viewz = drawz; pointToScreen((int*)&drawx, (int*)&drawy, drawz); drawx -= (TILEWIDTH>>1)*config.scale; if(((drawx + spritewidth*config.scale) < 0) || (drawx > al_get_bitmap_width(al_get_target_bitmap())) || ((drawy + spriteheight*config.scale) < 0) || (drawy > al_get_bitmap_height(al_get_target_bitmap()))) return; int sheetx, sheety; if(tilelayout == BLOCKTILE) { sheetx = ((sheetindex+tileoffset+randoffset) % SHEET_OBJECTSWIDE) * spritewidth; sheety = ((sheetindex+tileoffset+randoffset) / SHEET_OBJECTSWIDE) * spriteheight; } else if(tilelayout == RAMPBOTTOMTILE) { sheetx = SPRITEWIDTH * b->ramp.index; sheety = ((TILEHEIGHT + FLOORHEIGHT + SPRITEHEIGHT) * (sheetindex+tileoffset+randoffset))+(TILEHEIGHT + FLOORHEIGHT); } else if(tilelayout == RAMPTOPTILE) { sheetx = SPRITEWIDTH * b->ramp.index; sheety = (TILEHEIGHT + FLOORHEIGHT + SPRITEHEIGHT) * (sheetindex+tileoffset+randoffset); } else { sheetx = ((sheetindex+tileoffset+randoffset) % SHEET_OBJECTSWIDE) * spritewidth; sheety = ((sheetindex+tileoffset+randoffset) / SHEET_OBJECTSWIDE) * spriteheight; } ALLEGRO_COLOR shade_color = get_color(b); if(!b->designation.bits.pile && config.fog_of_war && (contentLoader->gameMode.g_mode == GAMEMODE_ADVENTURE)) { shade_color.r *= 0.25f; shade_color.g *= 0.25f; shade_color.b *= 0.25f; } if(chop && ( halftile == HALFTILECHOP)) { if(fileindex < 0) { if(config.block_count) config.drawcount ++; if(shade_color.a > 0.001f) al_draw_tinted_scaled_bitmap( defaultsheet, premultiply(shade_color), sheetx * spritescale, (sheety+WALL_CUTOFF_HEIGHT) * spritescale, spritewidth * spritescale, (spriteheight-WALL_CUTOFF_HEIGHT) * spritescale, drawx + (offset_x + offset_user_x)*config.scale, drawy + (offset_user_y + (offset_y - WALLHEIGHT)+WALL_CUTOFF_HEIGHT)*config.scale, spritewidth*config.scale, (spriteheight-WALL_CUTOFF_HEIGHT)*config.scale, 0); } else { if(config.block_count) config.drawcount ++; if(shade_color.a > 0.001f) al_draw_tinted_scaled_bitmap( getImgFile(fileindex), premultiply(shade_color), sheetx * spritescale, (sheety+WALL_CUTOFF_HEIGHT) * spritescale, spritewidth * spritescale, (spriteheight-WALL_CUTOFF_HEIGHT) * spritescale, drawx + (offset_x + offset_user_x)*config.scale, drawy + (offset_user_y + (offset_y - WALLHEIGHT)+WALL_CUTOFF_HEIGHT)*config.scale, spritewidth*config.scale, (spriteheight-WALL_CUTOFF_HEIGHT)*config.scale, 0); } //draw cut-off floor thing if(config.block_count) config.drawcount ++; if(shade_color.a > 0.001f) al_draw_scaled_bitmap(IMGObjectSheet, TILEWIDTH * SPRITEFLOOR_CUTOFF, 0, SPRITEWIDTH, SPRITEWIDTH, drawx+offset_x, drawy+offset_y-((SPRITEHEIGHT-WALL_CUTOFF_HEIGHT)/2), SPRITEWIDTH*config.scale, SPRITEWIDTH*config.scale, 0); } else if ((chop && (halftile == HALFTILEYES)) || (!chop && (halftile == HALFTILENO)) || (!chop && (halftile == HALFTILECHOP)) || (halftile == HALFTILEBOTH)) { if((isoutline == OUTLINENONE) || ((isoutline == OUTLINERIGHT) && (b->depthBorderNorth)) || ((isoutline == OUTLINELEFT) && (b->depthBorderWest)) || ((isoutline == OUTLINEBOTTOM) && (b->depthBorderDown))) { if(fileindex < 0) { if(config.block_count) config.drawcount ++; if(shade_color.a > 0.001f) al_draw_tinted_scaled_bitmap( defaultsheet, premultiply(shade_color), sheetx * spritescale, sheety * spritescale, spritewidth * spritescale, spriteheight * spritescale, drawx + (offset_x + offset_user_x)*config.scale, drawy + (offset_user_y + (offset_y - WALLHEIGHT))*config.scale, spritewidth*config.scale, spriteheight*config.scale, 0); } else { if(config.block_count) config.drawcount ++; if(shade_color.a > 0.001f) al_draw_tinted_scaled_bitmap( getImgFile(fileindex), premultiply(shade_color), sheetx * spritescale, sheety * spritescale, spritewidth * spritescale, spriteheight * spritescale, drawx + (offset_x + offset_user_x)*config.scale, drawy + (offset_user_y + (offset_y - WALLHEIGHT))*config.scale, spritewidth*config.scale, spriteheight*config.scale, 0); } } if(needoutline) { //drawy -= (WALLHEIGHT); //Northern border if(b->depthBorderNorth) DrawSpriteFromSheet(281, IMGObjectSheet, al_map_rgb(255,255,255), drawx + (offset_x)*config.scale, drawy + (offset_y)*config.scale, b ); //Western border if(b->depthBorderWest) DrawSpriteFromSheet(280, IMGObjectSheet, al_map_rgb(255,255,255), drawx + (offset_x)*config.scale, drawy + (offset_y)*config.scale, b ); //drawy += (WALLHEIGHT); } } //draw_textf_border(font, al_map_rgb(255,255,255), drawx, drawy, 0, "%d,%d", fileindex, sheetindex); } }
void drawFloorBlood ( Block *b, int32_t drawx, int32_t drawy ) { t_occupancy occ = b->occ; t_SpriteWithOffset sprite; int x = b->x, y = b->y, z = b->z; if( b->water.index < 1 && (b->bloodlevel)) { sprite.fileIndex = INVALID_INDEX; // Spatter (should be blood, not blood2) swapped for testing if( b->bloodlevel <= config.poolcutoff ) sprite.sheetIndex = 7; // Smear (should be blood2, not blood) swapped for testing else { // if there's no block in the respective direction it's false. if there's no blood in that direction it's false too. should also check to see if there's a ramp below, but since blood doesn't flow, that'd look wrong anyway. bool _N = ( b->ownerSegment->getBlockRelativeTo( x, y, z, eUp ) != NULL ? (b->ownerSegment->getBlockRelativeTo( x, y, z, eUp )->bloodlevel > config.poolcutoff) : false ), _S = ( b->ownerSegment->getBlockRelativeTo( x, y, z, eDown ) != NULL ? (b->ownerSegment->getBlockRelativeTo( x, y, z, eDown )->bloodlevel > config.poolcutoff) : false ), _E = ( b->ownerSegment->getBlockRelativeTo( x, y, z, eRight ) != NULL ? (b->ownerSegment->getBlockRelativeTo( x, y, z, eRight )->bloodlevel > config.poolcutoff) : false ), _W = ( b->ownerSegment->getBlockRelativeTo( x, y, z, eLeft ) != NULL ? (b->ownerSegment->getBlockRelativeTo( x, y, z, eLeft )->bloodlevel > config.poolcutoff) : false ); // do rules-based puddling if( _N || _S || _E || _W ) { if( _E ) { if( _N && _S ) sprite.sheetIndex = 5; else if( _S ) sprite.sheetIndex = 3; else if( _W ) sprite.sheetIndex = 1; else sprite.sheetIndex = 6; } else if( _W ) { if( _S && _N) sprite.sheetIndex = 5; else if( _S ) sprite.sheetIndex = 2; else sprite.sheetIndex = 0; } else if ( _N ) sprite.sheetIndex = 4; else sprite.sheetIndex = 2; } else sprite.sheetIndex = 8; } int sheetOffsetX = TILEWIDTH * (sprite.sheetIndex % SHEET_OBJECTSWIDE), sheetOffsetY = 0; al_draw_tinted_scaled_bitmap( IMGBloodSheet, premultiply(b->bloodcolor), sheetOffsetX, sheetOffsetY, TILEWIDTH, TILEHEIGHT+FLOORHEIGHT, drawx, drawy, TILEWIDTH*config.scale, (TILEHEIGHT+FLOORHEIGHT)*config.scale, 0); al_draw_scaled_bitmap( IMGBloodSheet, sheetOffsetX, sheetOffsetY+TILEHEIGHT+FLOORHEIGHT, TILEWIDTH, TILEHEIGHT+FLOORHEIGHT, drawx, drawy, TILEWIDTH*config.scale, (TILEHEIGHT+FLOORHEIGHT)*config.scale, 0); } }
void Tile::AssembleFloorBlood ( int32_t drawx, int32_t drawy ) { t_SpriteWithOffset sprite; if( designation.bits.flow_size < 1 && (bloodlevel)) { sprite.fileIndex = INVALID_INDEX; // Spatter (should be blood, not blood2) swapped for testing if( bloodlevel <= ssConfig.poolcutoff ) { sprite.sheetIndex = 7; } // Smear (should be blood2, not blood) swapped for testing else { // if there's no tile in the respective direction it's false. if there's no blood in that direction it's false too. should also check to see if there's a ramp below, but since blood doesn't flow, that'd look wrong anyway. bool _N = ( ownerSegment->getTileRelativeTo( x, y, z, eUp ) != NULL ? (ownerSegment->getTileRelativeTo( x, y, z, eUp )->bloodlevel > ssConfig.poolcutoff) : false ), _S = ( ownerSegment->getTileRelativeTo( x, y, z, eDown ) != NULL ? (ownerSegment->getTileRelativeTo( x, y, z, eDown )->bloodlevel > ssConfig.poolcutoff) : false ), _E = ( ownerSegment->getTileRelativeTo( x, y, z, eRight ) != NULL ? (ownerSegment->getTileRelativeTo( x, y, z, eRight )->bloodlevel > ssConfig.poolcutoff) : false ), _W = ( ownerSegment->getTileRelativeTo( x, y, z, eLeft ) != NULL ? (ownerSegment->getTileRelativeTo( x, y, z, eLeft )->bloodlevel > ssConfig.poolcutoff) : false ); // do rules-based puddling if( _N || _S || _E || _W ) { if( _E ) { if( _N && _S ) { sprite.sheetIndex = 5; } else if( _S ) { sprite.sheetIndex = 3; } else if( _W ) { sprite.sheetIndex = 1; } else { sprite.sheetIndex = 6; } } else if( _W ) { if( _S && _N) { sprite.sheetIndex = 5; } else if( _S ) { sprite.sheetIndex = 2; } else { sprite.sheetIndex = 0; } } else if ( _N ) { sprite.sheetIndex = 4; } else { sprite.sheetIndex = 2; } } else { sprite.sheetIndex = 8; } } int sheetOffsetX = TILEWIDTH * (sprite.sheetIndex % SHEET_OBJECTSWIDE), sheetOffsetY = 0; AssembleSprite( IMGBloodSheet, premultiply(bloodcolor), sheetOffsetX, sheetOffsetY, TILEWIDTH, TILETOPHEIGHT+FLOORHEIGHT, drawx, drawy, TILEWIDTH*ssConfig.scale, (TILETOPHEIGHT+FLOORHEIGHT)*ssConfig.scale, 0); AssembleSprite( IMGBloodSheet, al_map_rgb(255,255,255), sheetOffsetX, sheetOffsetY+TILETOPHEIGHT+FLOORHEIGHT, TILEWIDTH, TILETOPHEIGHT+FLOORHEIGHT, drawx, drawy, TILEWIDTH*ssConfig.scale, (TILETOPHEIGHT+FLOORHEIGHT)*ssConfig.scale, 0); } }
void WorldSegment::drawAllBlocks(){ if(!loaded) return; // x,y,z print pricess ALLEGRO_BITMAP * temp = al_get_target_bitmap(); int32_t vsxmax = sizex-1; int32_t vsymax = sizey-1; int32_t vszmax = sizez-1; // grabbing one tile +z more than we should for tile rules //al_hold_bitmap_drawing(true); for(int32_t vsz=0; vsz < vszmax; vsz++) { if(config.showRenderStatus) SetTitle("Stonesense - Drawing Terrain, Level %d/%d", (vsz+1), vszmax); if(config.fogenable && config.foga) { if(!fog) { fog = al_create_bitmap(al_get_bitmap_width(temp), al_get_bitmap_height(temp)); al_set_target_bitmap(fog); al_clear_to_color(premultiply(al_map_rgba_f(config.fogr, config.fogg, config.fogb, config.foga))); al_set_target_bitmap(temp); } if(!((al_get_bitmap_width(fog) == al_get_bitmap_width(temp)) && (al_get_bitmap_height(fog) == al_get_bitmap_height(temp)))) { al_destroy_bitmap(fog); fog = al_create_bitmap(al_get_bitmap_width(temp), al_get_bitmap_height(temp)); al_set_target_bitmap(fog); al_clear_to_color(al_map_rgba_f(config.fogr*config.foga, config.fogg*config.foga, config.fogb*config.foga, config.foga)); al_set_target_bitmap(temp); } al_draw_bitmap(fog, 0, 0, 0); } if(vsz == vszmax-1) { if (config.show_osd) DrawCurrentLevelOutline(true); } if(config.dayNightCycle) al_hold_bitmap_drawing(true); for(int32_t vsx=1; vsx < vsxmax; vsx++) { for(int32_t vsy=1; vsy < vsymax; vsy++) { Block *b = getBlockLocal(vsx,vsy,vsz); if (b==NULL || (b->tileShapeBasic!=tiletype_shape_basic::Floor && b->tileShapeBasic!=tiletype_shape_basic::Ramp && b->tileShapeBasic==tiletype_shape_basic::Wall)) { Block* bLow = getBlockLocal(vsx,vsy,vsz-1); if (bLow != NULL) { bLow->DrawRamptops(); } } if (b) { b->Draw(); //while(!key[KEY_SPACE]) ; //rest(100); } } } al_hold_bitmap_drawing(false); al_hold_bitmap_drawing(true); for(int32_t vsx=1; vsx < vsxmax; vsx++) { for(int32_t vsy=1; vsy < vsymax; vsy++) { Block *b = getBlockLocal(vsx,vsy,vsz); if (b) { b->Drawcreaturetext(); //while(!key[KEY_SPACE]) ; //rest(100); } } } al_hold_bitmap_drawing(false); } if(config.showRenderStatus) SetTitle("Stonesense"); }
int load_sprite_png(sprite_t * sprite, char * file) { png_structp png_ptr; png_infop info_ptr; int number_of_passes; png_bytep * row_pointers; int x, y; png_uint_32 width, height; int color_type; int bit_depth; char header[8]; FILE *fp = fopen(file, "rb"); if (!fp) { return 1; } fread(header, 1, 8, fp); if (png_sig_cmp(header, 0, 8)) { fclose(fp); return 1; } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { fclose(fp); return 1; } info_ptr = png_create_info_struct(png_ptr); png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height); for (y = 0; y < height; ++y) { row_pointers[y] = (png_byte *) malloc(png_get_rowbytes(png_ptr, info_ptr)); } png_read_image(png_ptr, row_pointers); fclose(fp); sprite->width = width; sprite->height = height; sprite->bitmap = malloc(sizeof(uint32_t) * width * height); sprite->alpha = 0; sprite->blank = 0; if (color_type == 2) { sprite->alpha = ALPHA_OPAQUE; for (y = 0; y < height; ++y) { png_byte* row = row_pointers[y]; for (x = 0; x < width; ++x) { png_byte * ptr = &(row[x*3]); sprite->bitmap[(y) * width + x] = rgb(ptr[0], ptr[1], ptr[2]); } } } else if (color_type == 6) { sprite->alpha = ALPHA_EMBEDDED; for (y = 0; y < height; ++y) { png_byte* row = row_pointers[y]; for (x = 0; x < width; ++x) { png_byte * ptr = &(row[x*4]); sprite->bitmap[(y) * width + x] = premultiply(rgba(ptr[0], ptr[1], ptr[2], ptr[3])); } } } else { printf("XXX: UNKNOWN COLOR TYPE: %d!\n", color_type); } for (y = 0; y < height; ++y) { free(row_pointers[y]); } free(row_pointers); png_destroy_read_struct(&png_ptr,&info_ptr,NULL); return 0; }
void WorldSegment::DrawAllTiles() { if(!loaded) { return; } if(ssConfig.fogenable) { ALLEGRO_BITMAP* temp = al_get_target_bitmap(); if(!fog) { fog = al_create_bitmap(ssState.ScreenW, ssState.ScreenH); al_set_target_bitmap(fog); al_clear_to_color(premultiply(ssConfig.fogcol)); al_set_target_bitmap(temp); } if(!((al_get_bitmap_width(fog) == ssState.ScreenW) && (al_get_bitmap_height(fog) == ssState.ScreenH))) { al_destroy_bitmap(fog); fog = al_create_bitmap(ssState.ScreenW, ssState.ScreenH); al_set_target_bitmap(fog); al_clear_to_color(premultiply(ssConfig.fogcol)); al_set_target_bitmap(temp); } } if (ssConfig.show_osd) { DrawCurrentLevelOutline(true); } if(todraw.size()>0) { al_hold_bitmap_drawing(true); for(int i=0; i<todraw.size(); i++) { if(i%ssConfig.bitmapHolds==0) { al_hold_bitmap_drawing(false); al_hold_bitmap_drawing(true); } switch(todraw[i].type) { case TintedScaledBitmap: al_draw_tinted_scaled_bitmap( (ALLEGRO_BITMAP*) todraw[i].drawobject, todraw[i].tint, todraw[i].sx, todraw[i].sy, todraw[i].sw, todraw[i].sh, todraw[i].dx, todraw[i].dy, todraw[i].dw, todraw[i].dh, todraw[i].flags ); break; case CreatureText: DrawCreatureText( todraw[i].dx, todraw[i].dy, (SS_Unit*) todraw[i].drawobject ); break; } } } if (ssConfig.show_osd) { DrawCurrentLevelOutline(false); } al_hold_bitmap_drawing(false); al_hold_bitmap_drawing(true); }
/* call this once at the beginning */ void initialise_decoder(void) { premultiply(); imdct_init(); calculate_t43(); }