mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 08:01:30 -07:00
New front end functions to save and restore a region of the puzzle
bitmap. Can be used to implement sprite-like animations: for example, useful for games that wish to implement a user interface which involves dragging an object around the playing area. [originally from svn r5987]
This commit is contained in:
51
gtk.c
51
gtk.c
@ -334,6 +334,57 @@ void draw_polygon(frontend *fe, int *coords, int npoints,
|
|||||||
sfree(points);
|
sfree(points);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct blitter {
|
||||||
|
GdkPixmap *pixmap;
|
||||||
|
int w, h, x, y;
|
||||||
|
};
|
||||||
|
|
||||||
|
blitter *blitter_new(int w, int h)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We can't create the pixmap right now, because fe->window
|
||||||
|
* might not yet exist. So we just cache w and h and create it
|
||||||
|
* during the firs call to blitter_save.
|
||||||
|
*/
|
||||||
|
blitter *bl = snew(blitter);
|
||||||
|
bl->pixmap = NULL;
|
||||||
|
bl->w = w;
|
||||||
|
bl->h = h;
|
||||||
|
return bl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void blitter_free(blitter *bl)
|
||||||
|
{
|
||||||
|
if (bl->pixmap)
|
||||||
|
gdk_pixmap_unref(bl->pixmap);
|
||||||
|
sfree(bl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void blitter_save(frontend *fe, blitter *bl, int x, int y)
|
||||||
|
{
|
||||||
|
if (!bl->pixmap)
|
||||||
|
bl->pixmap = gdk_pixmap_new(fe->area->window, bl->w, bl->h, -1);
|
||||||
|
bl->x = x;
|
||||||
|
bl->y = y;
|
||||||
|
gdk_draw_pixmap(bl->pixmap,
|
||||||
|
fe->area->style->fg_gc[GTK_WIDGET_STATE(fe->area)],
|
||||||
|
fe->pixmap,
|
||||||
|
x, y, 0, 0, bl->w, bl->h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void blitter_load(frontend *fe, blitter *bl, int x, int y)
|
||||||
|
{
|
||||||
|
assert(bl->pixmap);
|
||||||
|
if (x == BLITTER_FROMSAVED && y == BLITTER_FROMSAVED) {
|
||||||
|
x = bl->x;
|
||||||
|
y = bl->y;
|
||||||
|
}
|
||||||
|
gdk_draw_pixmap(fe->pixmap,
|
||||||
|
fe->area->style->fg_gc[GTK_WIDGET_STATE(fe->area)],
|
||||||
|
bl->pixmap,
|
||||||
|
0, 0, x, y, bl->w, bl->h);
|
||||||
|
}
|
||||||
|
|
||||||
void draw_update(frontend *fe, int x, int y, int w, int h)
|
void draw_update(frontend *fe, int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
if (fe->bbox_l > x ) fe->bbox_l = x ;
|
if (fe->bbox_l > x ) fe->bbox_l = x ;
|
||||||
|
42
osx.m
42
osx.m
@ -1232,6 +1232,48 @@ void draw_text(frontend *fe, int x, int y, int fonttype, int fontsize,
|
|||||||
|
|
||||||
[string drawAtPoint:point withAttributes:attr];
|
[string drawAtPoint:point withAttributes:attr];
|
||||||
}
|
}
|
||||||
|
struct blitter {
|
||||||
|
int w, h;
|
||||||
|
int x, y;
|
||||||
|
NSImage *img;
|
||||||
|
};
|
||||||
|
blitter *blitter_new(int w, int h)
|
||||||
|
{
|
||||||
|
blitter *bl = snew(blitter);
|
||||||
|
bl->x = bl->y = -1;
|
||||||
|
bl->w = w;
|
||||||
|
bl->h = h;
|
||||||
|
bl->img = [[NSImage alloc] initWithSize:NSMakeSize(w, h)];
|
||||||
|
[bl->img setFlipped:YES];
|
||||||
|
return bl;
|
||||||
|
}
|
||||||
|
void blitter_free(blitter *bl)
|
||||||
|
{
|
||||||
|
[bl->img release];
|
||||||
|
sfree(bl);
|
||||||
|
}
|
||||||
|
void blitter_save(frontend *fe, blitter *bl, int x, int y)
|
||||||
|
{
|
||||||
|
[fe->image unlockFocus];
|
||||||
|
[bl->img lockFocus];
|
||||||
|
[fe->image drawInRect:NSMakeRect(0, 0, bl->w, bl->h)
|
||||||
|
fromRect:NSMakeRect(x, y, bl->w, bl->h)
|
||||||
|
operation:NSCompositeCopy fraction:1.0];
|
||||||
|
[bl->img unlockFocus];
|
||||||
|
[fe->image lockFocus];
|
||||||
|
bl->x = x;
|
||||||
|
bl->y = y;
|
||||||
|
}
|
||||||
|
void blitter_load(frontend *fe, blitter *bl, int x, int y)
|
||||||
|
{
|
||||||
|
if (x == BLITTER_FROMSAVED && y == BLITTER_FROMSAVED) {
|
||||||
|
x = bl->x;
|
||||||
|
y = bl->y;
|
||||||
|
}
|
||||||
|
[bl->img drawInRect:NSMakeRect(x, y, bl->w, bl->h)
|
||||||
|
fromRect:NSMakeRect(0, 0, bl->w, bl->h)
|
||||||
|
operation:NSCompositeCopy fraction:1.0];
|
||||||
|
}
|
||||||
void draw_update(frontend *fe, int x, int y, int w, int h)
|
void draw_update(frontend *fe, int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
[fe->view setNeedsDisplayInRect:NSMakeRect(x,y,w,h)];
|
[fe->view setNeedsDisplayInRect:NSMakeRect(x,y,w,h)];
|
||||||
|
11
puzzles.h
11
puzzles.h
@ -74,6 +74,7 @@ typedef struct game_aux_info game_aux_info;
|
|||||||
typedef struct game_ui game_ui;
|
typedef struct game_ui game_ui;
|
||||||
typedef struct game_drawstate game_drawstate;
|
typedef struct game_drawstate game_drawstate;
|
||||||
typedef struct game game;
|
typedef struct game game;
|
||||||
|
typedef struct blitter blitter;
|
||||||
|
|
||||||
#define ALIGN_VNORMAL 0x000
|
#define ALIGN_VNORMAL 0x000
|
||||||
#define ALIGN_VCENTRE 0x100
|
#define ALIGN_VCENTRE 0x100
|
||||||
@ -146,6 +147,16 @@ void activate_timer(frontend *fe);
|
|||||||
void status_bar(frontend *fe, char *text);
|
void status_bar(frontend *fe, char *text);
|
||||||
void get_random_seed(void **randseed, int *randseedsize);
|
void get_random_seed(void **randseed, int *randseedsize);
|
||||||
|
|
||||||
|
blitter *blitter_new(int w, int h);
|
||||||
|
void blitter_free(blitter *bl);
|
||||||
|
/* save puts the portion of the current display with top-left corner
|
||||||
|
* (x,y) to the blitter. load puts it back again to the specified
|
||||||
|
* coords, or else wherever it was saved from
|
||||||
|
* (if x = y = BLITTER_FROMSAVED). */
|
||||||
|
void blitter_save(frontend *fe, blitter *bl, int x, int y);
|
||||||
|
#define BLITTER_FROMSAVED (-1)
|
||||||
|
void blitter_load(frontend *fe, blitter *bl, int x, int y);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* midend.c
|
* midend.c
|
||||||
*/
|
*/
|
||||||
|
82
windows.c
82
windows.c
@ -90,6 +90,12 @@ struct cfg_aux {
|
|||||||
int ctlid;
|
int ctlid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct blitter {
|
||||||
|
HBITMAP bitmap;
|
||||||
|
frontend *fe;
|
||||||
|
int x, y, w, h;
|
||||||
|
};
|
||||||
|
|
||||||
struct frontend {
|
struct frontend {
|
||||||
midend_data *me;
|
midend_data *me;
|
||||||
HWND hwnd, statusbar, cfgbox;
|
HWND hwnd, statusbar, cfgbox;
|
||||||
@ -149,6 +155,82 @@ void status_bar(frontend *fe, char *text)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blitter *blitter_new(int w, int h)
|
||||||
|
{
|
||||||
|
blitter *bl = snew(blitter);
|
||||||
|
|
||||||
|
memset(bl, 0, sizeof(blitter));
|
||||||
|
bl->w = w;
|
||||||
|
bl->h = h;
|
||||||
|
bl->bitmap = 0;
|
||||||
|
|
||||||
|
return bl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void blitter_free(blitter *bl)
|
||||||
|
{
|
||||||
|
if (bl->bitmap) DeleteObject(bl->bitmap);
|
||||||
|
sfree(bl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void blitter_mkbitmap(frontend *fe, blitter *bl)
|
||||||
|
{
|
||||||
|
HDC hdc = GetDC(fe->hwnd);
|
||||||
|
bl->bitmap = CreateCompatibleBitmap(hdc, bl->w, bl->h);
|
||||||
|
ReleaseDC(fe->hwnd, hdc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BitBlt(dstDC, dstX, dstY, dstW, dstH, srcDC, srcX, srcY, dType) */
|
||||||
|
|
||||||
|
void blitter_save(frontend *fe, blitter *bl, int x, int y)
|
||||||
|
{
|
||||||
|
HDC hdc_win, hdc_blit;
|
||||||
|
HBITMAP prev_blit;
|
||||||
|
|
||||||
|
if (!bl->bitmap) blitter_mkbitmap(fe, bl);
|
||||||
|
|
||||||
|
bl->x = x; bl->y = y;
|
||||||
|
|
||||||
|
hdc_win = GetDC(fe->hwnd);
|
||||||
|
hdc_blit = CreateCompatibleDC(hdc_win);
|
||||||
|
if (!hdc_blit) fatal("hdc_blit failed: 0x%x", GetLastError());
|
||||||
|
|
||||||
|
prev_blit = SelectObject(hdc_blit, bl->bitmap);
|
||||||
|
if (prev_blit == NULL || prev_blit == HGDI_ERROR)
|
||||||
|
fatal("SelectObject for hdc_main failed: 0x%x", GetLastError());
|
||||||
|
|
||||||
|
if (!BitBlt(hdc_blit, 0, 0, bl->w, bl->h,
|
||||||
|
fe->hdc_bm, x, y, SRCCOPY))
|
||||||
|
fatal("BitBlt failed: 0x%x", GetLastError());
|
||||||
|
|
||||||
|
SelectObject(hdc_blit, prev_blit);
|
||||||
|
DeleteDC(hdc_blit);
|
||||||
|
ReleaseDC(fe->hwnd, hdc_win);
|
||||||
|
}
|
||||||
|
|
||||||
|
void blitter_load(frontend *fe, blitter *bl, int x, int y)
|
||||||
|
{
|
||||||
|
HDC hdc_win, hdc_blit;
|
||||||
|
HBITMAP prev_blit;
|
||||||
|
|
||||||
|
assert(bl->bitmap); /* we should always have saved before loading */
|
||||||
|
|
||||||
|
if (x == BLITTER_FROMSAVED) x = bl->x;
|
||||||
|
if (y == BLITTER_FROMSAVED) y = bl->y;
|
||||||
|
|
||||||
|
hdc_win = GetDC(fe->hwnd);
|
||||||
|
hdc_blit = CreateCompatibleDC(hdc_win);
|
||||||
|
|
||||||
|
prev_blit = SelectObject(hdc_blit, bl->bitmap);
|
||||||
|
|
||||||
|
BitBlt(fe->hdc_bm, x, y, bl->w, bl->h,
|
||||||
|
hdc_blit, 0, 0, SRCCOPY);
|
||||||
|
|
||||||
|
SelectObject(hdc_blit, prev_blit);
|
||||||
|
DeleteDC(hdc_blit);
|
||||||
|
ReleaseDC(fe->hwnd, hdc_win);
|
||||||
|
}
|
||||||
|
|
||||||
void frontend_default_colour(frontend *fe, float *output)
|
void frontend_default_colour(frontend *fe, float *output)
|
||||||
{
|
{
|
||||||
DWORD c = GetSysColor(COLOR_MENU); /* ick */
|
DWORD c = GetSysColor(COLOR_MENU); /* ick */
|
||||||
|
Reference in New Issue
Block a user