/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * 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 . * */ #include "ags/lib/allegro/gfx.h" #include "ags/lib/allegro/color.h" #include "ags/lib/allegro/flood.h" #include "ags/lib/allegro/rotate.h" #include "ags/ags.h" #include "ags/globals.h" #include "common/textconsole.h" #include "common/util.h" #include "graphics/screen.h" namespace AGS3 { int color_conversion; /*-------------------------------------------------------------------*/ void set_color_conversion(int mode) { color_conversion = mode; } int get_color_conversion() { return color_conversion; } int set_gfx_mode(int card, int w, int h, int depth) { // Graphics shutdown can be ignored if (card != -1) { assert(card == SCUMMVM_ID); ::AGS::g_vm->setGraphicsMode(w, h, depth); } return 0; } void set_clip_rect(BITMAP *bitmap, int x1, int y1, int x2, int y2) { // The rect passed to the function in inclusive-inclusive, but // internally the clipping rect in BITMAP is inclusive-exclusive. bitmap->cl = CLIP(x1, 0, (int)bitmap->w - 1); bitmap->ct = CLIP(y1, 0, (int)bitmap->h - 1); bitmap->cr = CLIP(x2 + 1, 0, (int)bitmap->w); bitmap->cb = CLIP(y2 + 1, 0, (int)bitmap->h); } void get_clip_rect(BITMAP *bitmap, int *x1, int *y1, int *x2, int *y2) { if (x1) *x1 = bitmap->cl; if (y1) *y1 = bitmap->ct; if (x2) *x2 = bitmap->cr - 1; if (y2) *y2 = bitmap->cb - 1; } void acquire_bitmap(BITMAP *bitmap) { // No implementation needed } void release_bitmap(BITMAP *bitmap) { // No implementation needed } void clear_to_color(BITMAP *bitmap, int color) { Graphics::ManagedSurface &surf = **bitmap; surf.clear(color); } int bitmap_color_depth(BITMAP *bmp) { Graphics::ManagedSurface &surf = **bmp; return (surf.format.bytesPerPixel == 1) ? 8 : surf.format.bpp(); } int bitmap_mask_color(BITMAP *bmp) { // For paletted sprites this is 0. // For other color depths this is bright pink (RGB 255, 0, 255). // The alpha chanel should be 0. //if (bmp-format.bytesPerPixel == 1) // return 0; //return bmp->format.AGRBToColor(0, 255, 0, 255); return bmp->getTransparentColor(); } void blit(const BITMAP *src, BITMAP *dest, int src_x, int src_y, int dst_x, int dst_y, int width, int height) { dest->draw(src, Common::Rect(src_x, src_y, src_x + width, src_y + height), dst_x, dst_y, false, false, false, -1); } void stretch_blit(const BITMAP *src, BITMAP *dest, int source_x, int source_y, int source_width, int source_height, int dest_x, int dest_y, int dest_width, int dest_height) { dest->stretchDraw(src, Common::Rect(source_x, source_y, source_x + source_width, source_y + source_height), Common::Rect(dest_x, dest_y, dest_x + dest_width, dest_y + dest_height), false, -1); } void masked_blit(const BITMAP *src, BITMAP *dest, int src_x, int src_y, int dst_x, int dst_y, int width, int height) { assert(src->format == dest->format); dest->draw(src, Common::Rect(src_x, src_y, src_x + width, src_y + height), dst_x, dst_y, false, false, true, -1); } void masked_stretch_blit(const BITMAP *src, BITMAP *dest, int source_x, int source_y, int source_width, int source_height, int dest_x, int dest_y, int dest_width, int dest_height) { dest->stretchDraw(src, Common::Rect(source_x, source_y, source_x + source_width, source_y + source_height), Common::Rect(dest_x, dest_y, dest_x + dest_width, dest_y + dest_height), true, -1); } void draw_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y) { bmp->draw(sprite, Common::Rect(0, 0, sprite->w, sprite->h), x, y, false, false, true, -1); } void stretch_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int w, int h) { bmp->stretchDraw(sprite, Common::Rect(0, 0, sprite->w, sprite->h), Common::Rect(x, y, x + w, y + h), true, -1); } void draw_trans_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y) { bmp->draw(sprite, Common::Rect(0, 0, sprite->w, sprite->h), x, y, false, false, true, _G(trans_blend_alpha)); } void draw_lit_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int color) { bmp->draw(sprite, Common::Rect(0, 0, sprite->w, sprite->h), x, y, false, false, true, color, _G(trans_blend_red), _G(trans_blend_green), _G(trans_blend_blue)); } void draw_sprite_h_flip(BITMAP *bmp, const BITMAP *sprite, int x, int y) { bmp->draw(sprite, Common::Rect(0, 0, sprite->w, sprite->h), x, y, true, false, true, -1); } void draw_sprite_v_flip(BITMAP *bmp, const BITMAP *sprite, int x, int y) { bmp->draw(sprite, Common::Rect(0, 0, sprite->w, sprite->h), x, y, false, true, true, -1); } void draw_sprite_vh_flip(BITMAP *bmp, const BITMAP *sprite, int x, int y) { bmp->draw(sprite, Common::Rect(0, 0, sprite->w, sprite->h), x, y, true, true, true, -1); } void rotate_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, fixed angle) { pivot_scaled_sprite(bmp, sprite, (x<<16) + (sprite->w * 0x10000) / 2, (y<<16) + (sprite->h * 0x10000) / 2, sprite->w << 15, sprite->h << 15, angle, 0x10000); } void pivot_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int cx, int cy, fixed angle) { pivot_scaled_sprite(bmp, sprite, x<<16, y<<16, cx<<16, cy<<16, angle, 0x10000); } bool is_screen_bitmap(BITMAP *bmp) { return dynamic_cast(bmp) != nullptr; } bool is_video_bitmap(BITMAP *bmp) { return dynamic_cast(bmp) != nullptr; } bool is_planar_bitmap(BITMAP *bmp) { return false; } bool is_linear_bitmap(BITMAP *bmp) { return true; } bool is_same_bitmap(BITMAP *bmp1, BITMAP *bmp2) { if ((bmp1 == nullptr) || (bmp2 == nullptr)) return false; if (bmp1 == bmp2) return true; // TODO: allegro also returns true if one bmp is a sub of the other, // i.e. they share the same id // This (if needed?) would require a different implementation return false; } void bmp_select(BITMAP *bmp) { // No implementation needed } byte *bmp_write_line(BITMAP *bmp, int line) { return bmp->line[line]; } void bmp_write8(byte *addr, int color) { *addr = color; } void bmp_write15(byte *addr, int color) { *((uint16 *)addr) = color; } void bmp_write16(byte *addr, int color) { *((uint16 *)addr) = color; } void bmp_write24(byte *addr, int color) { *addr = (color & 0xff); *(addr + 1) = ((color >> 8) & 0xff); *(addr + 2) = ((color >> 16) & 0xff); } void bmp_write32(byte *addr, int color) { *((uint32 *)addr) = color; } void memory_putpixel(BITMAP *bmp, int x, int y, int color) { putpixel(bmp, x, y, color); } void putpixel(BITMAP *bmp, int x, int y, int color) { Graphics::ManagedSurface &surf = **bmp; if (x < 0 || x >= surf.w || y < 0 || y >= surf.h) return; void *p = surf.getBasePtr(x, y); switch (surf.format.bytesPerPixel) { case 1: *((uint8 *)p) = color; break; case 2: *((uint16 *)p) = color; break; case 4: *((uint32 *)p) = color; break; default: break; } } void _putpixel(BITMAP *bmp, int x, int y, int color) { Graphics::ManagedSurface &surf = **bmp; if (x < 0 || x >= surf.w || y < 0 || y >= surf.h) return; void *p = surf.getBasePtr(x, y); *((uint8 *)p) = color; } void _putpixel15(BITMAP *bmp, int x, int y, int color) { error("Unsupported bpp"); } void _putpixel16(BITMAP *bmp, int x, int y, int color) { Graphics::ManagedSurface &surf = **bmp; if (x < 0 || x >= surf.w || y < 0 || y >= surf.h) return; void *p = surf.getBasePtr(x, y); *((uint16 *)p) = color; } void _putpixel24(BITMAP *bmp, int x, int y, int color) { error("Unsupported bpp"); } void _putpixel32(BITMAP *bmp, int x, int y, int color) { Graphics::ManagedSurface &surf = **bmp; if (x < 0 || x >= surf.w || y < 0 || y >= surf.h) return; void *p = surf.getBasePtr(x, y); *((uint32 *)p) = color; } int getpixel(const BITMAP *bmp, int x, int y) { Graphics::ManagedSurface &surf = **bmp; // Allegro returns -1 if the pixel lies outside the bitmap if (x < 0 || y < 0 || x >= surf.w || y >= surf.h) return -1; void *p = surf.getBasePtr(x, y); switch (surf.format.bytesPerPixel) { case 1: return *((uint8 *)p); case 2: return *((uint16 *)p); case 4: return *((uint32 *)p); default: break; } error("Unsupported bpp"); } int _getpixel(const BITMAP *bmp, int x, int y) { Graphics::ManagedSurface &surf = **bmp; if (x < 0 || y < 0 || x >= surf.w || y >= surf.h) return -1; void *p = surf.getBasePtr(x, y); return *((uint8 *)p); } int _getpixel15(const BITMAP *bmp, int x, int y) { error("Unsupported bpp"); } int _getpixel16(const BITMAP *bmp, int x, int y) { Graphics::ManagedSurface &surf = **bmp; if (x < 0 || y < 0 || x >= surf.w || y >= surf.h) return -1; void *p = surf.getBasePtr(x, y); return *((uint16 *)p); } int _getpixel24(const BITMAP *bmp, int x, int y) { error("Unsupported bpp"); } int _getpixel32(const BITMAP *bmp, int x, int y) { Graphics::ManagedSurface &surf = **bmp; if (x < 0 || y < 0 || x >= surf.w || y >= surf.h) return -1; void *p = surf.getBasePtr(x, y); return *((uint32 *)p); } void line(BITMAP *bmp, int x1, int y1, int x2, int y2, int color) { Graphics::ManagedSurface &surf = **bmp; surf.drawLine(x1, y1, x2, y2, color); } void rect(BITMAP *bmp, int x1, int y1, int x2, int y2, int color) { Graphics::ManagedSurface &surf = **bmp; if (x1 > x2) SWAP(x1, x2); if (y1 > y2) SWAP(y1, y2); surf.frameRect(Common::Rect(x1, y1, x2 + 1, y2 + 1), color); } void rectfill(BITMAP *bmp, int x1, int y1, int x2, int y2, int color) { Graphics::ManagedSurface &surf = **bmp; if (x1 > x2) SWAP(x1, x2); if (y1 > y2) SWAP(y1, y2); surf.fillRect(Common::Rect(x1, y1, x2 + 1, y2 + 1), color); } void triangle(BITMAP *bmp, int x1, int y1, int x2, int y2, int x3, int y3, int color) { Graphics::ManagedSurface &surf = **bmp; surf.drawLine(x1, y1, x2, y2, color); surf.drawLine(x2, y2, x3, y3, color); surf.drawLine(x3, y3, x1, y1, color); } void circlefill(BITMAP *bmp, int x, int y, int radius, int color) { bmp->circlefill(x, y, radius, color); } void clear_bitmap(BITMAP *bmp) { bmp->clear(); } } // namespace AGS3