diff --git a/win/win32/mhmap.c b/win/win32/mhmap.c index 3d3403446..ec5f5c5f7 100644 --- a/win/win32/mhmap.c +++ b/win/win32/mhmap.c @@ -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); -} diff --git a/win/win32/mhmenu.c b/win/win32/mhmenu.c index 45b3efcf4..258eed46d 100644 --- a/win/win32/mhmenu.c +++ b/win/win32/mhmenu.c @@ -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 { diff --git a/win/win32/mhmsg.h b/win/win32/mhmsg.h index 7a5b06747..926f7d0eb 100644 --- a/win/win32/mhmsg.h +++ b/win/win32/mhmsg.h @@ -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 { diff --git a/win/win32/mhsplash.c b/win/win32/mhsplash.c index ccd410e54..4d2277249 100644 --- a/win/win32/mhsplash.c +++ b/win/win32/mhsplash.c @@ -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); diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index f3fc54e2b..3bfa23b1d 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -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); } diff --git a/win/win32/winMS.h b/win/win32/winMS.h index e344572f5..3aa3b4a65 100644 --- a/win/win32/winMS.h +++ b/win/win32/winMS.h @@ -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); diff --git a/win/win32/winhack.c b/win/win32/winhack.c index 86f2b6bb3..54a483a4c 100644 --- a/win/win32/winhack.c +++ b/win/win32/winhack.c @@ -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; +}