/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * MacOS X common quartz (quickdraw) gfx driver functions. * * By Angelo Mottola, based on similar QNX code by Eric Botcazou. * * See readme.txt for copyright information. */ #include "allegro.h" #include "allegro/internal/aintern.h" #include "allegro/platform/aintosx.h" #ifndef ALLEGRO_MACOSX #error something is wrong with the makefile #endif /* setup_direct_shifts * Setups direct color shifts. */ void setup_direct_shifts(void) { _rgb_r_shift_15 = 10; _rgb_g_shift_15 = 5; _rgb_b_shift_15 = 0; _rgb_r_shift_16 = 11; _rgb_g_shift_16 = 5; _rgb_b_shift_16 = 0; _rgb_r_shift_24 = 16; _rgb_g_shift_24 = 8; _rgb_b_shift_24 = 0; _rgb_a_shift_32 = 24; _rgb_r_shift_32 = 16; _rgb_g_shift_32 = 8; _rgb_b_shift_32 = 0; } /* osx_qz_write_line: * Line switcher for video bitmaps. */ unsigned long osx_qz_write_line(BITMAP *bmp, int line) { if (!(bmp->id & BMP_ID_LOCKED)) { bmp->id |= BMP_ID_LOCKED; if (bmp->extra) { while (!QDDone(BMP_EXTRA(bmp)->port)); LockPortBits(BMP_EXTRA(bmp)->port); } } return (unsigned long)(bmp->line[line]); } /* osx_qz_unwrite_line: * Line updater for video bitmaps. */ void osx_qz_unwrite_line(BITMAP *bmp) { if (bmp->id & BMP_ID_AUTOLOCK) { bmp->id &= ~(BMP_ID_LOCKED | BMP_ID_AUTOLOCK); if (bmp->extra) UnlockPortBits(BMP_EXTRA(bmp)->port); } } /* osx_qz_acquire: * Bitmap locking for video bitmaps. */ void osx_qz_acquire(BITMAP *bmp) { if (!(bmp->id & BMP_ID_LOCKED)) { bmp->id |= BMP_ID_LOCKED; if (bmp->extra) { while (!QDDone(BMP_EXTRA(bmp)->port)); while (LockPortBits(BMP_EXTRA(bmp)->port)); } } } /* osx_qz_release: * Bitmap unlocking for video bitmaps. */ void osx_qz_release(BITMAP *bmp) { bmp->id &= ~BMP_ID_LOCKED; if (bmp->extra) UnlockPortBits(BMP_EXTRA(bmp)->port); } /* osx_qz_created_sub_bitmap: * Makes a sub bitmap to inherit the GWorld of its parent. */ void osx_qz_created_sub_bitmap(BITMAP *bmp, BITMAP *parent) { bmp->extra = parent->extra; } /* _make_quickdraw_bitmap: * Creates a BITMAP using a QuickDraw GWorld as backing store. */ static BITMAP *_make_quickdraw_bitmap(int width, int height, int flags) { BITMAP *bmp; GWorldPtr gworld; Rect rect; char *addr; int pitch; int i, size; /* create new GWorld */ SetRect(&rect, 0, 0, width, height); if (NewGWorld(&gworld, screen->vtable->color_depth, &rect, NULL, NULL, flags)) return NULL; LockPortBits(gworld); addr = GetPixBaseAddr(GetPortPixMap(gworld)); pitch = GetPixRowBytes(GetPortPixMap(gworld)); UnlockPortBits(gworld); if (!addr) { DisposeGWorld(gworld); return NULL; } /* create Allegro bitmap */ size = sizeof(BITMAP) + sizeof(char *) * height; bmp = (BITMAP *) malloc(size); if (!bmp) { DisposeGWorld(gworld); return NULL; } bmp->w = bmp->cr = width; bmp->h = bmp->cb = height; bmp->clip = TRUE; bmp->cl = bmp->ct = 0; bmp->vtable = &_screen_vtable; bmp->write_bank = bmp->read_bank = osx_qz_write_line; bmp->dat = NULL; bmp->id = BMP_ID_VIDEO; bmp->extra = NULL; bmp->x_ofs = 0; bmp->y_ofs = 0; bmp->seg = _video_ds(); bmp->line[0] = (unsigned char *)addr; for (i = 1; i < height; i++) bmp->line[i] = bmp->line[i - 1] + pitch; /* setup surface info structure to store additional information */ bmp->extra = malloc(sizeof(struct BMP_EXTRA_INFO)); if (!bmp->extra) { free(bmp); DisposeGWorld(gworld); return NULL; } BMP_EXTRA(bmp)->port = gworld; return bmp; } /* osx_qz_create_video_bitmap: * Tries to allocate a BITMAP in video memory. */ BITMAP *osx_qz_create_video_bitmap(int width, int height) { if ((gfx_driver->w == width) && (gfx_driver->h == height) && (!osx_screen_used)) { osx_screen_used = TRUE; return screen; } return _make_quickdraw_bitmap(width, height, useDistantHdwrMem); } /* osx_qz_create_system_bitmap: * Tries to allocates a BITMAP in AGP memory. */ BITMAP *osx_qz_create_system_bitmap(int width, int height) { return _make_quickdraw_bitmap(width, height, useLocalHdwrMem); } /* osx_qz_destroy_video_bitmap: * Frees memory used by bitmap structure and releases associated GWorld. */ void osx_qz_destroy_video_bitmap(BITMAP *bmp) { if (bmp) { if (bmp == screen) { osx_screen_used = FALSE; return; } if (bmp->extra) { if (BMP_EXTRA(bmp)->port) DisposeGWorld(BMP_EXTRA(bmp)->port); free(bmp->extra); } free(bmp); } } /* osx_qz_blit_to_self: * Accelerated vram -> vram blitting routine. */ void osx_qz_blit_to_self(BITMAP *source, BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height) { Rect source_rect, dest_rect; SetRect(&source_rect, source_x + source->x_ofs, source_y + source->y_ofs, source_x + source->x_ofs + width, source_y + source->y_ofs + height); SetRect(&dest_rect, dest_x + dest->x_ofs, dest_y + dest->y_ofs, dest_x + dest->x_ofs + width, dest_y + dest->y_ofs + height); while (!QDDone(BMP_EXTRA(dest)->port)); if (!(dest->id & BMP_ID_LOCKED)) LockPortBits(BMP_EXTRA(dest)->port); CopyBits(GetPortBitMapForCopyBits(BMP_EXTRA(source)->port), GetPortBitMapForCopyBits(BMP_EXTRA(dest)->port), &source_rect, &dest_rect, srcCopy, NULL); if (!(dest->id & BMP_ID_LOCKED)) UnlockPortBits(BMP_EXTRA(dest)->port); }