diff options
| author | Simon Tatham <anakin@pobox.com> | 2005-06-22 08:30:31 +0000 |
|---|---|---|
| committer | Simon Tatham <anakin@pobox.com> | 2005-06-22 08:30:31 +0000 |
| commit | b176767dfac722d85b3d3b4ab7969e5572189aa0 (patch) | |
| tree | 100e6510f20f829d35a5fe66131d58afdb3f51f8 /windows.c | |
| parent | 64fbdf60ee2eac039c469f867a3e9c0e1b9e119f (diff) | |
| download | puzzles-b176767dfac722d85b3d3b4ab7969e5572189aa0.zip puzzles-b176767dfac722d85b3d3b4ab7969e5572189aa0.tar.gz puzzles-b176767dfac722d85b3d3b4ab7969e5572189aa0.tar.bz2 puzzles-b176767dfac722d85b3d3b4ab7969e5572189aa0.tar.xz | |
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]
Diffstat (limited to 'windows.c')
| -rw-r--r-- | windows.c | 82 |
1 files changed, 82 insertions, 0 deletions
@@ -90,6 +90,12 @@ struct cfg_aux { int ctlid; }; +struct blitter { + HBITMAP bitmap; + frontend *fe; + int x, y, w, h; +}; + struct frontend { midend_data *me; 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) { DWORD c = GetSysColor(COLOR_MENU); /* ick */ |