Пример #1
0
void DrawingSurface_Clear(ScriptDrawingSurface *sds, int colour)
{
    Bitmap *ds = sds->StartDrawing();
    int allegroColor;
    if ((colour == -SCR_NO_VALUE) || (colour == SCR_COLOR_TRANSPARENT))
    {
        allegroColor = ds->GetMaskColor();
    }
    else
    {
        allegroColor = ds->GetCompatibleColor(colour);
    }
    ds->Fill(allegroColor);
    sds->FinishedDrawing();
}
Пример #2
0
void DrawingSurface_SetDrawingColor(ScriptDrawingSurface *sds, int newColour) 
{
    sds->currentColourScript = newColour;
    // StartDrawing to set up ds to set the colour at the appropriate
    // depth for the background
    Bitmap *ds = sds->StartDrawing();
    if (newColour == SCR_COLOR_TRANSPARENT)
    {
        sds->currentColour = ds->GetMaskColor();
    }
    else
    {
        sds->currentColour = ds->GetCompatibleColor(newColour);
    }
    sds->FinishedDrawingReadOnly();
}
Пример #3
0
void DynamicSprite_Rotate(ScriptDynamicSprite *sds, int angle, int width, int height) {
    if ((angle < 1) || (angle > 359))
        quit("!DynamicSprite.Rotate: invalid angle (must be 1-359)");
    if (sds->slot == 0)
        quit("!DynamicSprite.Rotate: sprite has been deleted");

    if ((width == SCR_NO_VALUE) || (height == SCR_NO_VALUE)) {
        // calculate the new image size automatically
        // 1 degree = 181 degrees in terms of x/y size, so % 180
        int useAngle = angle % 180;
        // and 0..90 is the same as 180..90
        if (useAngle > 90)
            useAngle = 180 - useAngle;
        // useAngle is now between 0 and 90 (otherwise the sin/cos stuff doesn't work)
        double angleInRadians = (double)useAngle * (M_PI / 180.0);
        double sinVal = sin(angleInRadians);
        double cosVal = cos(angleInRadians);

        width = (cosVal * (double)spritewidth[sds->slot] + sinVal * (double)spriteheight[sds->slot]);
        height = (sinVal * (double)spritewidth[sds->slot] + cosVal * (double)spriteheight[sds->slot]);
    }
    else {
        multiply_up_coordinates(&width, &height);
    }

    // convert to allegro angle
    angle = (angle * 256) / 360;

    // resize the sprite to the requested size
    Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[sds->slot]->GetColorDepth());
    newPic->Clear(newPic->GetMaskColor());

    // rotate the sprite about its centre
    // (+ width%2 fixes one pixel offset problem)
    newPic->RotateBlt(spriteset[sds->slot], width / 2 + width % 2, height / 2,
        spritewidth[sds->slot] / 2, spriteheight[sds->slot] / 2, itofix(angle));

    delete spriteset[sds->slot];

    // replace the bitmap in the sprite set
    add_dynamic_sprite(sds->slot, newPic, (game.spriteflags[sds->slot] & SPF_ALPHACHANNEL) != 0);
}
Пример #4
0
void update_walk_behind_images()
{
  int ee, rr;
  int bpp = (thisroom.ebscene[play.bg_frame]->GetColorDepth() + 7) / 8;
  Bitmap *wbbmp;
  for (ee = 1; ee < MAX_OBJ; ee++)
  {
    update_polled_stuff_if_runtime();
    
    if (walkBehindRight[ee] > 0)
    {
      wbbmp = BitmapHelper::CreateBitmap( 
                               (walkBehindRight[ee] - walkBehindLeft[ee]) + 1,
                               (walkBehindBottom[ee] - walkBehindTop[ee]) + 1,
							   thisroom.ebscene[play.bg_frame]->GetColorDepth());
      wbbmp->Clear(wbbmp->GetMaskColor());
      int yy, startX = walkBehindLeft[ee], startY = walkBehindTop[ee];
      for (rr = startX; rr <= walkBehindRight[ee]; rr++)
      {
        for (yy = startY; yy <= walkBehindBottom[ee]; yy++)
        {
          if (thisroom.object->GetScanLine(yy)[rr] == ee)
          {
            for (int ii = 0; ii < bpp; ii++)
              wbbmp->GetScanLineForWriting(yy - startY)[(rr - startX) * bpp + ii] = thisroom.ebscene[play.bg_frame]->GetScanLine(yy)[rr * bpp + ii];
          }
        }
      }

      update_polled_stuff_if_runtime();

      if (walkBehindBitmap[ee] != NULL)
      {
        gfxDriver->DestroyDDB(walkBehindBitmap[ee]);
      }
      walkBehindBitmap[ee] = gfxDriver->CreateDDBFromBitmap(wbbmp, false);
      delete wbbmp;
    }
  }

  walkBehindsCachedForBgNum = play.bg_frame;
}
Пример #5
0
void DynamicSprite_ChangeCanvasSize(ScriptDynamicSprite *sds, int width, int height, int x, int y) 
{
    if (sds->slot == 0)
        quit("!DynamicSprite.ChangeCanvasSize: sprite has been deleted");
    if ((width < 1) || (height < 1))
        quit("!DynamicSprite.ChangeCanvasSize: new size is too small");

    multiply_up_coordinates(&x, &y);
    multiply_up_coordinates(&width, &height);

    Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[sds->slot]->GetColorDepth());
    newPic->Clear(newPic->GetMaskColor());
    // blit it into the enlarged image
    newPic->Blit(spriteset[sds->slot], 0, 0, x, y, spritewidth[sds->slot], spriteheight[sds->slot]);

    delete spriteset[sds->slot];

    // replace the bitmap in the sprite set
    add_dynamic_sprite(sds->slot, newPic, (game.spriteflags[sds->slot] & SPF_ALPHACHANNEL) != 0);
}
Пример #6
0
ScriptDynamicSprite* DynamicSprite_Create(int width, int height, int alphaChannel) 
{
    multiply_up_coordinates(&width, &height);

    int gotSlot = spriteset.findFreeSlot();
    if (gotSlot <= 0)
        return NULL;

    Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, final_col_dep);
    if (newPic == NULL)
        return NULL;
    newPic->Clear(newPic->GetMaskColor());

    if ((alphaChannel) && (final_col_dep < 32))
        alphaChannel = false;

    add_dynamic_sprite(gotSlot, gfxDriver->ConvertBitmapToSupportedColourDepth(newPic), alphaChannel != 0);
    ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot);
    GlobalReturnValue.SetDynamicObject(new_spr, new_spr);
    return new_spr;
}
Пример #7
0
void DynamicSprite_Flip(ScriptDynamicSprite *sds, int direction) {
    if ((direction < 1) || (direction > 3))
        quit("!DynamicSprite.Flip: invalid direction");
    if (sds->slot == 0)
        quit("!DynamicSprite.Flip: sprite has been deleted");

    // resize the sprite to the requested size
    Bitmap *newPic = BitmapHelper::CreateBitmap(spritewidth[sds->slot], spriteheight[sds->slot], spriteset[sds->slot]->GetColorDepth());
    newPic->Clear(newPic->GetMaskColor());

    if (direction == 1)
        newPic->FlipBlt(spriteset[sds->slot], 0, 0, Common::kBitmap_HFlip);
    else if (direction == 2)
        newPic->FlipBlt(spriteset[sds->slot], 0, 0, Common::kBitmap_VFlip);
    else if (direction == 3)
        newPic->FlipBlt(spriteset[sds->slot], 0, 0, Common::kBitmap_HVFlip);

    delete spriteset[sds->slot];

    // replace the bitmap in the sprite set
    add_dynamic_sprite(sds->slot, newPic, (game.spriteflags[sds->slot] & SPF_ALPHACHANNEL) != 0);
}
Пример #8
0
int DrawingSurface_GetPixel(ScriptDrawingSurface *sds, int x, int y) {
    sds->MultiplyCoordinates(&x, &y);
    Bitmap *ds = sds->StartDrawing();
    unsigned int rawPixel = ds->GetPixel(x, y);
    unsigned int maskColor = ds->GetMaskColor();
    int colDepth = ds->GetColorDepth();

    if (rawPixel == maskColor)
    {
        rawPixel = SCR_COLOR_TRANSPARENT;
    }
    else if (colDepth > 8)
    {
        int r = getr_depth(colDepth, rawPixel);
        int ds = getg_depth(colDepth, rawPixel);
        int b = getb_depth(colDepth, rawPixel);

        rawPixel = Game_GetColorFromRGB(r, ds, b);
    }

    sds->FinishedDrawingReadOnly();

    return rawPixel;
}
Пример #9
0
void DrawSpriteWithTransparency(Bitmap *ds, Bitmap *sprite, int x, int y, int alpha)
{
    if (alpha <= 0)
    {
        // fully transparent, don't draw it at all
        return;
    }

    int surface_depth = ds->GetColorDepth();
    int sprite_depth  = sprite->GetColorDepth();

    if (sprite_depth < surface_depth
        // CHECKME: what is the purpose of this hack and is this still relevant?
#if defined(IOS_VERSION) || defined(ANDROID_VERSION)
        || (ds->GetBPP() < surface_depth && psp_gfx_renderer > 0) // Fix for corrupted speechbox outlines with the OGL driver
#endif
        )
    {
        // If sprite is lower color depth than destination surface, e.g.
        // 8-bit sprites drawn on 16/32-bit surfaces.
        if (sprite_depth == 8 && surface_depth >= 24)
        {
            // 256-col sprite -> truecolor background
            // this is automatically supported by allegro, no twiddling needed
            ds->Blit(sprite, x, y, kBitmap_Transparency);
            return;
        }

        // 256-col sprite -> hi-color background, or
        // 16-bit sprite -> 32-bit background
        Bitmap hctemp;
        hctemp.CreateCopy(sprite, surface_depth);
        if (sprite_depth == 8)
        {
            // only do this for 256-col -> hi-color, cos the Blit call converts
            // transparency for 16->32 bit
            color_t mask_color = hctemp.GetMaskColor();
            for (int scan_y = 0; scan_y < hctemp.GetHeight(); ++scan_y)
            {
                // we know this must be 1 bpp source and 2 bpp pixel destination
                const uint8_t *src_scanline = sprite->GetScanLine(scan_y);
                uint16_t      *dst_scanline = (uint16_t*)hctemp.GetScanLineForWriting(scan_y);
                for (int scan_x = 0; scan_x < hctemp.GetWidth(); ++scan_x)
                {
                    if (src_scanline[scan_x] == 0)
                    {
                        dst_scanline[scan_x] = mask_color;
                    }
                }
            }
        }

        if (alpha < 0xFF) 
        {
            set_trans_blender(0, 0, 0, alpha);
            ds->TransBlendBlt(&hctemp, x, y);
        }
        else
        {
            ds->Blit(&hctemp, x, y, kBitmap_Transparency);
        }
    }
    else
    {
        if (alpha < 0xFF && surface_depth > 8 && sprite_depth > 8) 
        {
            set_trans_blender(0, 0, 0, alpha);
            ds->TransBlendBlt(sprite, x, y);
        }
        else
        {
            ds->Blit(sprite, x, y, kBitmap_Transparency);
        }
    }
}
Пример #10
0
void DynamicSprite_CopyTransparencyMask(ScriptDynamicSprite *sds, int sourceSprite) {
    if (sds->slot == 0)
        quit("!DynamicSprite.CopyTransparencyMask: sprite has been deleted");

    if ((spritewidth[sds->slot] != spritewidth[sourceSprite]) ||
        (spriteheight[sds->slot] != spriteheight[sourceSprite]))
    {
        quit("!DynamicSprite.CopyTransparencyMask: sprites are not the same size");
    }

    Bitmap *target = spriteset[sds->slot];
    Bitmap *source = spriteset[sourceSprite];

    if (target->GetColorDepth() != source->GetColorDepth())
    {
        quit("!DynamicSprite.CopyTransparencyMask: sprites are not the same colour depth");
    }

    // set the target's alpha channel depending on the source
    bool sourceHasAlpha = (game.spriteflags[sourceSprite] & SPF_ALPHACHANNEL) != 0;
    game.spriteflags[sds->slot] &= ~SPF_ALPHACHANNEL;
    if (sourceHasAlpha)
    {
        game.spriteflags[sds->slot] |= SPF_ALPHACHANNEL;
    }

    unsigned int maskColor = source->GetMaskColor();
    int colDep = source->GetColorDepth();
    int bytesPerPixel = (colDep + 1) / 8;

    unsigned short *shortPtr;
    unsigned int *longPtr;
    for (int y = 0; y < target->GetHeight(); y++)
    {
        unsigned char * sourcePixel = source->GetScanLineForWriting(y);
        unsigned char * targetPixel = target->GetScanLineForWriting(y);
        for (int x = 0; x < target->GetWidth(); x++)
        {
            shortPtr = (unsigned short*)sourcePixel;
            longPtr = (unsigned int*)sourcePixel;

            if ((colDep == 8) && (sourcePixel[0] == maskColor))
            {
                targetPixel[0] = maskColor;
            }
            else if ((bytesPerPixel == 2) && (shortPtr[0] == maskColor))
            {
                ((unsigned short*)targetPixel)[0] = maskColor;
            }
            else if ((bytesPerPixel == 3) && (memcmp(sourcePixel, &maskColor, 3) == 0))
            {
                memcpy(targetPixel, sourcePixel, 3);
            }
            else if ((bytesPerPixel == 4) && (longPtr[0] == maskColor))
            {
                ((unsigned int*)targetPixel)[0] = maskColor;
            }
            else if ((bytesPerPixel == 4) && (sourceHasAlpha))
            {
                // the fourth byte is the alpha channel, copy it
                targetPixel[3] = sourcePixel[3];
            }
            else if (bytesPerPixel == 4)
            {
                // set the alpha channel byte to opaque
                targetPixel[3] = 0xff;
            }

            sourcePixel += bytesPerPixel;
            targetPixel += bytesPerPixel;
        }
    }
}