win32_gui: implement background glyph rendering
try to use system TrasnparentBlt (or not)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/* NetHack 3.6 mhmap.c $NHDT-Date: 1432512811 2015/05/25 00:13:31 $ $NHDT-Branch: master $:$NHDT-Revision: 1.48 $ */
|
||||
/* Copyright (C) 2001 by Alex Kompel */
|
||||
/* Copyright (C) 2001 by Alex Kompel */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#include "winMS.h"
|
||||
@@ -16,9 +16,13 @@
|
||||
|
||||
extern short glyph2tile[];
|
||||
|
||||
#define TILEBMP_X(ntile) ((ntile % GetNHApp()->mapTilesPerLine) * GetNHApp()->mapTile_X)
|
||||
#define TILEBMP_Y(ntile) ((ntile / GetNHApp()->mapTilesPerLine) * GetNHApp()->mapTile_Y)
|
||||
|
||||
/* map window data */
|
||||
typedef struct mswin_nethack_map_window {
|
||||
int map[COLNO][ROWNO]; /* glyph map */
|
||||
int bkmap[COLNO][ROWNO]; /* backround glyph map */
|
||||
|
||||
int mapMode; /* current map mode */
|
||||
boolean bAsciiMode; /* switch ASCII/tiled mode */
|
||||
@@ -29,7 +33,7 @@ typedef struct mswin_nethack_map_window {
|
||||
int xScrTile, yScrTile; /* size of display tile */
|
||||
POINT map_orig; /* map origin point */
|
||||
|
||||
HFONT hMapFont; /* font for ASCII mode */
|
||||
HFONT hMapFont; /* font for ASCII mode */
|
||||
} NHMapWindow, *PNHMapWindow;
|
||||
|
||||
static TCHAR szNHMapWindowClass[] = TEXT("MSNethackMapWndClass");
|
||||
@@ -449,6 +453,7 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
case MSNH_MSG_PRINT_GLYPH: {
|
||||
PMSNHMsgPrintGlyph msg_data = (PMSNHMsgPrintGlyph) lParam;
|
||||
data->map[msg_data->x][msg_data->y] = msg_data->glyph;
|
||||
data->bkmap[msg_data->x][msg_data->y] = msg_data->bkglyph;
|
||||
|
||||
/* invalidate the update area */
|
||||
nhcoord2display(data, msg_data->x, msg_data->y, &rt);
|
||||
@@ -589,6 +594,7 @@ onCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
for (i = 0; i < COLNO; i++)
|
||||
for (j = 0; j < ROWNO; j++) {
|
||||
data->map[i][j] = -1;
|
||||
data->bkmap[i][j] = -1;
|
||||
}
|
||||
|
||||
data->bAsciiMode = FALSE;
|
||||
@@ -693,34 +699,53 @@ onPaint(HWND hWnd)
|
||||
}
|
||||
SelectObject(hDC, oldFont);
|
||||
} else {
|
||||
short ntile;
|
||||
int t_x, t_y;
|
||||
int glyph, bkglyph;
|
||||
RECT glyph_rect;
|
||||
|
||||
/* prepare tiles DC for mapping */
|
||||
tileDC = CreateCompatibleDC(hDC);
|
||||
saveBmp = SelectObject(tileDC, GetNHApp()->bmpMapTiles);
|
||||
|
||||
/* draw the map */
|
||||
for (i = paint_rt.left; i < paint_rt.right; i++)
|
||||
for (j = paint_rt.top; j < paint_rt.bottom; j++)
|
||||
if (data->map[i][j] >= 0) {
|
||||
short ntile;
|
||||
int t_x, t_y;
|
||||
RECT glyph_rect;
|
||||
for (j = paint_rt.top; j < paint_rt.bottom; j++) {
|
||||
glyph = data->map[i][j];
|
||||
bkglyph = (glyph >= 0)? data->bkmap[i][j] : -1;
|
||||
|
||||
ntile = glyph2tile[data->map[i][j]];
|
||||
t_x = (ntile % GetNHApp()->mapTilesPerLine)
|
||||
* GetNHApp()->mapTile_X;
|
||||
t_y = (ntile / GetNHApp()->mapTilesPerLine)
|
||||
* GetNHApp()->mapTile_Y;
|
||||
if (glyph == bkglyph) {
|
||||
glyph = -1;
|
||||
}
|
||||
|
||||
if (bkglyph >= 0) {
|
||||
ntile = glyph2tile[bkglyph];
|
||||
t_x = TILEBMP_X(ntile);
|
||||
t_y = TILEBMP_Y(ntile);
|
||||
nhcoord2display(data, i, j, &glyph_rect);
|
||||
|
||||
StretchBlt(hDC, glyph_rect.left, glyph_rect.top,
|
||||
data->xScrTile, data->yScrTile, tileDC,
|
||||
t_x, t_y, GetNHApp()->mapTile_X,
|
||||
GetNHApp()->mapTile_Y, SRCCOPY);
|
||||
if (glyph_is_pet(data->map[i][j])
|
||||
}
|
||||
|
||||
if (glyph >= 0) {
|
||||
ntile = glyph2tile[glyph];
|
||||
t_x = TILEBMP_X(ntile);
|
||||
t_y = TILEBMP_Y(ntile);
|
||||
nhcoord2display(data, i, j, &glyph_rect);
|
||||
|
||||
(*GetNHApp()->lpfnTransparentBlt)(
|
||||
hDC, glyph_rect.left, glyph_rect.top,
|
||||
data->xScrTile, data->yScrTile, tileDC,
|
||||
t_x, t_y, GetNHApp()->mapTile_X,
|
||||
GetNHApp()->mapTile_Y, TILE_BK_COLOR);
|
||||
|
||||
if (glyph_is_pet(glyph)
|
||||
&& iflags.wc_hilite_pet) {
|
||||
/* apply pet mark transparently over
|
||||
pet image */
|
||||
pet image */
|
||||
HDC hdcPetMark;
|
||||
HBITMAP bmPetMarkOld;
|
||||
|
||||
@@ -729,7 +754,7 @@ onPaint(HWND hWnd)
|
||||
bmPetMarkOld = SelectObject(
|
||||
hdcPetMark, GetNHApp()->bmpPetMark);
|
||||
|
||||
nhapply_image_transparent(
|
||||
(*GetNHApp()->lpfnTransparentBlt)(
|
||||
hDC, glyph_rect.left, glyph_rect.top,
|
||||
data->xScrTile, data->yScrTile, hdcPetMark, 0,
|
||||
0, TILE_X, TILE_Y, TILE_BK_COLOR);
|
||||
@@ -737,6 +762,7 @@ onPaint(HWND hWnd)
|
||||
DeleteDC(hdcPetMark);
|
||||
}
|
||||
}
|
||||
}
|
||||
SelectObject(tileDC, saveBmp);
|
||||
DeleteDC(tileDC);
|
||||
}
|
||||
@@ -987,87 +1013,3 @@ nhcolor_to_RGB(int c)
|
||||
}
|
||||
}
|
||||
|
||||
/* apply bitmap pointed by sourceDc transparently over
|
||||
bitmap pointed by hDC */
|
||||
|
||||
typedef BOOL(WINAPI *LPTRANSPARENTBLT)(HDC, int, int, int, int, HDC, int, int,
|
||||
int, int, UINT);
|
||||
void
|
||||
nhapply_image_transparent(HDC hDC, int x, int y, int width, int height,
|
||||
HDC sourceDC, int s_x, int s_y, int s_width,
|
||||
int s_height, COLORREF cTransparent)
|
||||
{
|
||||
/* Don't use TransparentBlt; According to Microsoft, it contains a memory
|
||||
* leak in Window 95/98. */
|
||||
HDC hdcMem, hdcBack, hdcObject, hdcSave;
|
||||
COLORREF cColor;
|
||||
HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave;
|
||||
HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;
|
||||
|
||||
/* Create some DCs to hold temporary data. */
|
||||
hdcBack = CreateCompatibleDC(hDC);
|
||||
hdcObject = CreateCompatibleDC(hDC);
|
||||
hdcMem = CreateCompatibleDC(hDC);
|
||||
hdcSave = CreateCompatibleDC(hDC);
|
||||
|
||||
/* this is bitmap for our pet image */
|
||||
bmSave = CreateCompatibleBitmap(hDC, width, height);
|
||||
|
||||
/* Monochrome DC */
|
||||
bmAndBack = CreateBitmap(width, height, 1, 1, NULL);
|
||||
bmAndObject = CreateBitmap(width, height, 1, 1, NULL);
|
||||
|
||||
/* resulting bitmap */
|
||||
bmAndMem = CreateCompatibleBitmap(hDC, width, height);
|
||||
|
||||
/* Each DC must select a bitmap object to store pixel data. */
|
||||
bmBackOld = SelectObject(hdcBack, bmAndBack);
|
||||
bmObjectOld = SelectObject(hdcObject, bmAndObject);
|
||||
bmMemOld = SelectObject(hdcMem, bmAndMem);
|
||||
bmSaveOld = SelectObject(hdcSave, bmSave);
|
||||
|
||||
/* copy source image because it is going to be overwritten */
|
||||
StretchBlt(hdcSave, 0, 0, width, height, sourceDC, s_x, s_y, s_width,
|
||||
s_height, SRCCOPY);
|
||||
|
||||
/* Set the background color of the source DC to the color.
|
||||
contained in the parts of the bitmap that should be transparent */
|
||||
cColor = SetBkColor(hdcSave, cTransparent);
|
||||
|
||||
/* Create the object mask for the bitmap by performing a BitBlt
|
||||
from the source bitmap to a monochrome bitmap. */
|
||||
BitBlt(hdcObject, 0, 0, width, height, hdcSave, 0, 0, SRCCOPY);
|
||||
|
||||
/* Set the background color of the source DC back to the original
|
||||
color. */
|
||||
SetBkColor(hdcSave, cColor);
|
||||
|
||||
/* Create the inverse of the object mask. */
|
||||
BitBlt(hdcBack, 0, 0, width, height, hdcObject, 0, 0, NOTSRCCOPY);
|
||||
|
||||
/* Copy background to the resulting image */
|
||||
BitBlt(hdcMem, 0, 0, width, height, hDC, x, y, SRCCOPY);
|
||||
|
||||
/* Mask out the places where the source image will be placed. */
|
||||
BitBlt(hdcMem, 0, 0, width, height, hdcObject, 0, 0, SRCAND);
|
||||
|
||||
/* Mask out the transparent colored pixels on the source image. */
|
||||
BitBlt(hdcSave, 0, 0, width, height, hdcBack, 0, 0, SRCAND);
|
||||
|
||||
/* XOR the source image with the beckground. */
|
||||
BitBlt(hdcMem, 0, 0, width, height, hdcSave, 0, 0, SRCPAINT);
|
||||
|
||||
/* blt resulting image to the screen */
|
||||
BitBlt(hDC, x, y, width, height, hdcMem, 0, 0, SRCCOPY);
|
||||
|
||||
/* cleanup */
|
||||
DeleteObject(SelectObject(hdcBack, bmBackOld));
|
||||
DeleteObject(SelectObject(hdcObject, bmObjectOld));
|
||||
DeleteObject(SelectObject(hdcMem, bmMemOld));
|
||||
DeleteObject(SelectObject(hdcSave, bmSaveOld));
|
||||
|
||||
DeleteDC(hdcMem);
|
||||
DeleteDC(hdcBack);
|
||||
DeleteDC(hdcObject);
|
||||
DeleteDC(hdcSave);
|
||||
}
|
||||
|
||||
@@ -1056,7 +1056,7 @@ onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
if (GetNHApp()->bmpMapTiles == GetNHApp()->bmpTiles) {
|
||||
/* using original nethack tiles - apply image transparently */
|
||||
nhapply_image_transparent(lpdis->hDC, x, y, TILE_X, TILE_Y,
|
||||
(*GetNHApp()->lpfnTransparentBlt)(lpdis->hDC, x, y, TILE_X, TILE_Y,
|
||||
tileDC, t_x, t_y, TILE_X, TILE_Y,
|
||||
TILE_BK_COLOR);
|
||||
} else {
|
||||
|
||||
@@ -36,6 +36,7 @@ typedef struct mswin_nhmsg_print_glyph {
|
||||
XCHAR_P x;
|
||||
XCHAR_P y;
|
||||
int glyph;
|
||||
int bkglyph;
|
||||
} MSNHMsgPrintGlyph, *PMSNHMsgPrintGlyph;
|
||||
|
||||
typedef struct mswin_nhmsg_cliparound {
|
||||
|
||||
@@ -206,7 +206,7 @@ NHSplashWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
hdcBitmap = CreateCompatibleDC(hdc);
|
||||
SetBkMode(hdc, OPAQUE);
|
||||
OldBitmap = SelectObject(hdcBitmap, GetNHApp()->bmpSplash);
|
||||
nhapply_image_transparent(hdc, SPLASH_OFFSET_X, SPLASH_OFFSET_Y,
|
||||
(*GetNHApp()->lpfnTransparentBlt)(hdc, SPLASH_OFFSET_X, SPLASH_OFFSET_Y,
|
||||
SPLASH_WIDTH, SPLASH_HEIGHT, hdcBitmap, 0,
|
||||
0, SPLASH_WIDTH, SPLASH_HEIGHT,
|
||||
TILE_BK_COLOR);
|
||||
|
||||
@@ -1280,6 +1280,7 @@ mswin_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph)
|
||||
data.x = x;
|
||||
data.y = y;
|
||||
data.glyph = glyph;
|
||||
data.bkglyph = bkglyph;
|
||||
SendMessage(GetNHApp()->windowlist[wid].win, WM_MSNH_COMMAND,
|
||||
(WPARAM) MSNH_MSG_PRINT_GLYPH, (LPARAM) &data);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* NetHack 3.6 winMS.h $NHDT-Date: 1433806621 2015/06/08 23:37:01 $ $NHDT-Branch: master $:$NHDT-Revision: 1.37 $ */
|
||||
/* Copyright (C) 2001 by Alex Kompel */
|
||||
/* Copyright (C) 2001 by Alex Kompel */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#ifndef WINMS_H
|
||||
@@ -58,6 +58,9 @@ typedef struct mswin_nhwindow_data {
|
||||
int dead;
|
||||
} MSNHWinData, *PMSNHWinData;
|
||||
|
||||
typedef BOOL(WINAPI *LPTRANSPARENTBLT)(HDC, int, int, int, int, HDC, int, int,
|
||||
int, int, UINT);
|
||||
|
||||
typedef struct mswin_nhwindow_app {
|
||||
HINSTANCE hApp;
|
||||
HWND hMainWnd;
|
||||
@@ -107,6 +110,8 @@ typedef struct mswin_nhwindow_app {
|
||||
BOOL bWindowsLocked; /* TRUE if windows are "locked" - no captions */
|
||||
|
||||
BOOL bNoSounds; /* disable sounds */
|
||||
|
||||
LPTRANSPARENTBLT lpfnTransparentBlt; /* transparent blt function */
|
||||
} NHWinApp, *PNHWinApp;
|
||||
|
||||
#define E extern
|
||||
@@ -182,9 +187,6 @@ winid mswin_winid_from_type(int type);
|
||||
winid mswin_winid_from_handle(HWND hWnd);
|
||||
void mswin_window_mark_dead(winid wid);
|
||||
void bail(const char *mesg);
|
||||
void nhapply_image_transparent(HDC hDC, int x, int y, int width, int height,
|
||||
HDC sourceDC, int s_x, int s_y, int s_width,
|
||||
int s_height, COLORREF cTransparent);
|
||||
|
||||
void mswin_popup_display(HWND popup, int *done_indicator);
|
||||
void mswin_popup_destroy(HWND popup);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* NetHack 3.6 winhack.c $NHDT-Date: 1432512811 2015/05/25 00:13:31 $ $NHDT-Branch: master $:$NHDT-Revision: 1.40 $ */
|
||||
/* Copyright (C) 2001 by Alex Kompel */
|
||||
/* NetHack 3.6 winhack.c $NHDT-Date: 1432512811 2015/05/25 00:13:31 $ $NHDT-Branch: master $:$NHDT-Revision: 1.40 $ */
|
||||
/* Copyright (C) 2001 by Alex Kompel */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
// winhack.cpp : Defines the entry point for the application.
|
||||
@@ -50,6 +50,10 @@ Version _WIN_32IE Platform/IE
|
||||
extern void FDECL(nethack_exit, (int));
|
||||
static TCHAR *_get_cmd_arg(TCHAR *pCmdLine);
|
||||
static HRESULT GetComCtlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor);
|
||||
BOOL WINAPI
|
||||
_nhapply_image_transparent(HDC hDC, int x, int y, int width, int height,
|
||||
HDC sourceDC, int s_x, int s_y, int s_width,
|
||||
int s_height, UINT cTransparent);
|
||||
|
||||
// Global Variables:
|
||||
NHWinApp _nethack_app;
|
||||
@@ -78,6 +82,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
|
||||
char buf[BUFSZ];
|
||||
DWORD major, minor;
|
||||
boolean resuming;
|
||||
/* OSVERSIONINFO osvi; */
|
||||
|
||||
UNREFERENCED_PARAMETER(hPrevInstance);
|
||||
UNREFERENCED_PARAMETER(lpCmdLine);
|
||||
@@ -121,6 +126,17 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
|
||||
|
||||
_nethack_app.bNoSounds = FALSE;
|
||||
|
||||
#if 0 /* GdiTransparentBlt does not render spash bitmap for whatever reason */
|
||||
/* use system-provided TransparentBlt for Win2k+ */
|
||||
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
|
||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
GetVersionEx(&osvi);
|
||||
if (osvi.dwMajorVersion >= 5)
|
||||
_nethack_app.lpfnTransparentBlt = GdiTransparentBlt;
|
||||
else
|
||||
#endif
|
||||
_nethack_app.lpfnTransparentBlt = _nhapply_image_transparent;
|
||||
|
||||
// init controls
|
||||
if (FAILED(GetComCtlVersion(&major, &minor))) {
|
||||
char buf[TBUFSZ];
|
||||
@@ -287,3 +303,87 @@ GetComCtlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
|
||||
FreeLibrary(hComCtl);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/* apply bitmap pointed by sourceDc transparently over
|
||||
bitmap pointed by hDC */
|
||||
BOOL WINAPI
|
||||
_nhapply_image_transparent(HDC hDC, int x, int y, int width, int height,
|
||||
HDC sourceDC, int s_x, int s_y, int s_width,
|
||||
int s_height, UINT cTransparent)
|
||||
{
|
||||
/* Don't use TransparentBlt; According to Microsoft, it contains a memory
|
||||
* leak in Window 95/98. */
|
||||
HDC hdcMem, hdcBack, hdcObject, hdcSave;
|
||||
COLORREF cColor;
|
||||
HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave;
|
||||
HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;
|
||||
|
||||
/* Create some DCs to hold temporary data. */
|
||||
hdcBack = CreateCompatibleDC(hDC);
|
||||
hdcObject = CreateCompatibleDC(hDC);
|
||||
hdcMem = CreateCompatibleDC(hDC);
|
||||
hdcSave = CreateCompatibleDC(hDC);
|
||||
|
||||
/* this is bitmap for our pet image */
|
||||
bmSave = CreateCompatibleBitmap(hDC, width, height);
|
||||
|
||||
/* Monochrome DC */
|
||||
bmAndBack = CreateBitmap(width, height, 1, 1, NULL);
|
||||
bmAndObject = CreateBitmap(width, height, 1, 1, NULL);
|
||||
|
||||
/* resulting bitmap */
|
||||
bmAndMem = CreateCompatibleBitmap(hDC, width, height);
|
||||
|
||||
/* Each DC must select a bitmap object to store pixel data. */
|
||||
bmBackOld = SelectObject(hdcBack, bmAndBack);
|
||||
bmObjectOld = SelectObject(hdcObject, bmAndObject);
|
||||
bmMemOld = SelectObject(hdcMem, bmAndMem);
|
||||
bmSaveOld = SelectObject(hdcSave, bmSave);
|
||||
|
||||
/* copy source image because it is going to be overwritten */
|
||||
StretchBlt(hdcSave, 0, 0, width, height, sourceDC, s_x, s_y, s_width,
|
||||
s_height, SRCCOPY);
|
||||
|
||||
/* Set the background color of the source DC to the color.
|
||||
contained in the parts of the bitmap that should be transparent */
|
||||
cColor = SetBkColor(hdcSave, cTransparent);
|
||||
|
||||
/* Create the object mask for the bitmap by performing a BitBlt
|
||||
from the source bitmap to a monochrome bitmap. */
|
||||
BitBlt(hdcObject, 0, 0, width, height, hdcSave, 0, 0, SRCCOPY);
|
||||
|
||||
/* Set the background color of the source DC back to the original
|
||||
color. */
|
||||
SetBkColor(hdcSave, cColor);
|
||||
|
||||
/* Create the inverse of the object mask. */
|
||||
BitBlt(hdcBack, 0, 0, width, height, hdcObject, 0, 0, NOTSRCCOPY);
|
||||
|
||||
/* Copy background to the resulting image */
|
||||
BitBlt(hdcMem, 0, 0, width, height, hDC, x, y, SRCCOPY);
|
||||
|
||||
/* Mask out the places where the source image will be placed. */
|
||||
BitBlt(hdcMem, 0, 0, width, height, hdcObject, 0, 0, SRCAND);
|
||||
|
||||
/* Mask out the transparent colored pixels on the source image. */
|
||||
BitBlt(hdcSave, 0, 0, width, height, hdcBack, 0, 0, SRCAND);
|
||||
|
||||
/* XOR the source image with the beckground. */
|
||||
BitBlt(hdcMem, 0, 0, width, height, hdcSave, 0, 0, SRCPAINT);
|
||||
|
||||
/* blt resulting image to the screen */
|
||||
BitBlt(hDC, x, y, width, height, hdcMem, 0, 0, SRCCOPY);
|
||||
|
||||
/* cleanup */
|
||||
DeleteObject(SelectObject(hdcBack, bmBackOld));
|
||||
DeleteObject(SelectObject(hdcObject, bmObjectOld));
|
||||
DeleteObject(SelectObject(hdcMem, bmMemOld));
|
||||
DeleteObject(SelectObject(hdcSave, bmSaveOld));
|
||||
|
||||
DeleteDC(hdcMem);
|
||||
DeleteDC(hdcBack);
|
||||
DeleteDC(hdcObject);
|
||||
DeleteDC(hdcSave);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user