Add WinHack source files to distribution
This commit is contained in:
466
win/win32/mhmap.c
Normal file
466
win/win32/mhmap.c
Normal file
@@ -0,0 +1,466 @@
|
||||
/* Copyright (C) 2001 by Alex Kompel <shurikk@pacbell.net> */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#include "winMS.h"
|
||||
#include "resource.h"
|
||||
#include "mhstatus.h"
|
||||
#include "mhmsg.h"
|
||||
#include "mhinput.h"
|
||||
|
||||
#define MAXWINDOWTEXT 255
|
||||
extern short glyph2tile[];
|
||||
|
||||
/* map window data */
|
||||
typedef struct mswin_nethack_map_window {
|
||||
int map[COLNO][ROWNO]; /* glyph map */
|
||||
|
||||
int xPos, yPos;
|
||||
int xPageSize, yPageSize;
|
||||
int xCur, yCur;
|
||||
} NHMapWindow, *PNHMapWindow;
|
||||
|
||||
static TCHAR szNHMapWindowClass[] = TEXT("MSNethackMapWndClass");
|
||||
LRESULT CALLBACK MapWndProc(HWND, UINT, WPARAM, LPARAM);
|
||||
static void register_map_window_class();
|
||||
static void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
||||
static void onMSNH_VScroll(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
||||
static void onMSNH_HScroll(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
||||
static void onPaint(HWND hWnd);
|
||||
static void onCreate(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
HWND mswin_init_map_window () {
|
||||
static int run_once = 0;
|
||||
HWND ret;
|
||||
|
||||
if( !run_once ) {
|
||||
register_map_window_class();
|
||||
run_once = 1;
|
||||
}
|
||||
|
||||
ret = CreateWindow(
|
||||
szNHMapWindowClass, /* registered class name */
|
||||
NULL, /* window name */
|
||||
WS_CHILD | WS_HSCROLL | WS_VSCROLL | WS_CLIPSIBLINGS, /* window style */
|
||||
0, /* horizontal position of window - set it later */
|
||||
0, /* vertical position of window - set it later */
|
||||
0, /* window width - set it later */
|
||||
0, /* window height - set it later*/
|
||||
GetNHApp()->hMainWnd, /* handle to parent or owner window */
|
||||
NULL, /* menu handle or child identifier */
|
||||
GetNHApp()->hApp, /* handle to application instance */
|
||||
NULL ); /* window-creation data */
|
||||
if( !ret ) {
|
||||
panic("Cannot create map window");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void register_map_window_class()
|
||||
{
|
||||
WNDCLASS wcex;
|
||||
ZeroMemory( &wcex, sizeof(wcex));
|
||||
|
||||
/* window class */
|
||||
wcex.style = CS_NOCLOSE;
|
||||
wcex.lpfnWndProc = (WNDPROC)MapWndProc;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = GetNHApp()->hApp;
|
||||
wcex.hIcon = NULL;
|
||||
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wcex.hbrBackground = CreateSolidBrush(RGB(0, 0, 0)); /* set backgroup here */
|
||||
wcex.lpszMenuName = NULL;
|
||||
wcex.lpszClassName = szNHMapWindowClass;
|
||||
|
||||
if( !RegisterClass(&wcex) ) {
|
||||
panic("cannot register Map window class");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LRESULT CALLBACK MapWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
PNHMapWindow data;
|
||||
|
||||
data = (PNHMapWindow)GetWindowLong(hWnd, GWL_USERDATA);
|
||||
switch (message)
|
||||
{
|
||||
case WM_CREATE:
|
||||
onCreate( hWnd, wParam, lParam );
|
||||
break;
|
||||
|
||||
case WM_MSNH_COMMAND:
|
||||
onMSNHCommand(hWnd, wParam, lParam);
|
||||
break;
|
||||
|
||||
case WM_PAINT:
|
||||
onPaint(hWnd);
|
||||
break;
|
||||
|
||||
case WM_SETFOCUS:
|
||||
/* transfer focus back to the main window */
|
||||
SetFocus(GetNHApp()->hMainWnd);
|
||||
break;
|
||||
|
||||
case WM_HSCROLL:
|
||||
onMSNH_HScroll(hWnd, wParam, lParam);
|
||||
break;
|
||||
|
||||
case WM_VSCROLL:
|
||||
onMSNH_VScroll(hWnd, wParam, lParam);
|
||||
break;
|
||||
|
||||
case WM_SIZE:
|
||||
{
|
||||
SCROLLINFO si;
|
||||
int xNewSize;
|
||||
int yNewSize;
|
||||
|
||||
xNewSize = LOWORD(lParam);
|
||||
yNewSize = HIWORD(lParam);
|
||||
|
||||
/* adjust horizontal scroll bar */
|
||||
if( xNewSize/TILE_X >= COLNO ) {
|
||||
data->xPos = 0;
|
||||
GetNHApp()->bNoHScroll = TRUE;
|
||||
} else {
|
||||
GetNHApp()->bNoHScroll = FALSE;
|
||||
data->xPos = max(0, min(COLNO, u.ux - xNewSize/TILE_X/2));
|
||||
}
|
||||
|
||||
si.cbSize = sizeof(si);
|
||||
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
|
||||
si.nMin = 0;
|
||||
si.nMax = COLNO;
|
||||
si.nPage = xNewSize/TILE_X;
|
||||
si.nPos = data->xPos;
|
||||
SetScrollInfo(hWnd, SB_HORZ, &si, TRUE);
|
||||
|
||||
/* adjust vertical scroll bar */
|
||||
if( yNewSize/TILE_Y >= ROWNO ) {
|
||||
data->yPos = 0;
|
||||
GetNHApp()->bNoVScroll = TRUE;
|
||||
} else {
|
||||
GetNHApp()->bNoVScroll = FALSE;
|
||||
data->yPos = max(0, min(ROWNO, u.uy - yNewSize/TILE_Y/2));
|
||||
}
|
||||
|
||||
si.cbSize = sizeof(si);
|
||||
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
|
||||
si.nMin = 0;
|
||||
si.nMax = ROWNO;
|
||||
si.nPage = yNewSize/TILE_Y;
|
||||
si.nPos = data->yPos;
|
||||
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
|
||||
|
||||
/* erase window */
|
||||
InvalidateRect(hWnd, NULL, TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
NHEVENT_MS(
|
||||
min(COLNO, data->xPos + LOWORD(lParam)/TILE_X),
|
||||
min(ROWNO, data->yPos + HIWORD(lParam)/TILE_Y)
|
||||
);
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
free(data);
|
||||
SetWindowLong(hWnd, GWL_USERDATA, (LONG)0);
|
||||
break;
|
||||
|
||||
default:
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
PNHMapWindow data;
|
||||
RECT rt;
|
||||
|
||||
data = (PNHMapWindow)GetWindowLong(hWnd, GWL_USERDATA);
|
||||
switch(wParam) {
|
||||
case MSNH_MSG_PRINT_GLYPH:
|
||||
{
|
||||
PMSNHMsgPrintGlyph msg_data = (PMSNHMsgPrintGlyph)lParam;
|
||||
data->map[msg_data->x][msg_data->y] = msg_data->glyph;
|
||||
|
||||
/* invalidate the update area */
|
||||
rt.left = msg_data->x*TILE_X - TILE_X*data->xPos;
|
||||
rt.top = msg_data->y*TILE_Y - TILE_Y*data->yPos;
|
||||
rt.right = rt.left + TILE_X;
|
||||
rt.bottom = rt.top + TILE_Y;
|
||||
|
||||
InvalidateRect(hWnd, &rt, TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSNH_MSG_CLIPAROUND:
|
||||
{
|
||||
PMSNHMsgClipAround msg_data = (PMSNHMsgClipAround)lParam;
|
||||
SCROLLINFO si;
|
||||
int xPage, yPage;
|
||||
int x, y;
|
||||
|
||||
/* get page size */
|
||||
if( !GetNHApp()->bNoHScroll ) {
|
||||
si.cbSize = sizeof(si);
|
||||
si.fMask = SIF_PAGE;
|
||||
GetScrollInfo(hWnd, SB_HORZ, &si);
|
||||
xPage = si.nPage;
|
||||
|
||||
x = max(0, min(COLNO, msg_data->x - xPage/2));
|
||||
|
||||
SendMessage( hWnd, WM_HSCROLL, (WPARAM)MAKELONG(SB_THUMBTRACK, x), (LPARAM)NULL );
|
||||
}
|
||||
|
||||
if( !GetNHApp()->bNoVScroll ) {
|
||||
si.cbSize = sizeof(si);
|
||||
si.fMask = SIF_PAGE;
|
||||
GetScrollInfo(hWnd, SB_VERT, &si);
|
||||
yPage = si.nPage;
|
||||
|
||||
y = max(0, min(ROWNO, msg_data->y - yPage/2));
|
||||
|
||||
SendMessage( hWnd, WM_VSCROLL, (WPARAM)MAKELONG(SB_THUMBTRACK, y), (LPARAM)NULL );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MSNH_MSG_CLEAR_WINDOW:
|
||||
{
|
||||
int i, j;
|
||||
for(i=0; i<COLNO; i++)
|
||||
for(j=0; j<ROWNO; j++) {
|
||||
data->map[i][j] = -1;
|
||||
}
|
||||
InvalidateRect(hWnd, NULL, TRUE);
|
||||
} break;
|
||||
|
||||
case MSNH_MSG_CURSOR:
|
||||
{
|
||||
PMSNHMsgCursor msg_data = (PMSNHMsgCursor)lParam;
|
||||
HDC hdc;
|
||||
RECT rt;
|
||||
|
||||
/* move focus rectangle at the cursor postion */
|
||||
hdc = GetDC(hWnd);
|
||||
rt.left = (data->xCur - data->xPos)*TILE_X;
|
||||
rt.top = (data->yCur - data->yPos)*TILE_Y;
|
||||
rt.right = rt.left + TILE_X;
|
||||
rt.bottom = rt.top + TILE_Y;
|
||||
DrawFocusRect(hdc, &rt);
|
||||
|
||||
data->xCur = msg_data->x;
|
||||
data->yCur = msg_data->y;
|
||||
rt.left = (data->xCur - data->xPos)*TILE_X;
|
||||
rt.top = (data->yCur - data->yPos)*TILE_Y;
|
||||
rt.right = rt.left + TILE_X;
|
||||
rt.bottom = rt.top + TILE_Y;
|
||||
DrawFocusRect(hdc, &rt);
|
||||
|
||||
ReleaseDC(hWnd, hdc);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void onCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
PNHMapWindow data;
|
||||
int i,j;
|
||||
|
||||
/* set window data */
|
||||
data = (PNHMapWindow)malloc(sizeof(NHMapWindow));
|
||||
if( !data ) panic("out of memory");
|
||||
|
||||
ZeroMemory(data, sizeof(NHMapWindow));
|
||||
for(i=0; i<COLNO; i++)
|
||||
for(j=0; j<ROWNO; j++) {
|
||||
data->map[i][j] = -1;
|
||||
}
|
||||
SetWindowLong(hWnd, GWL_USERDATA, (LONG)data);
|
||||
}
|
||||
|
||||
void onPaint(HWND hWnd)
|
||||
{
|
||||
PNHMapWindow data;
|
||||
PAINTSTRUCT ps;
|
||||
HDC hDC;
|
||||
HDC tileDC;
|
||||
HGDIOBJ saveBmp;
|
||||
RECT paint_rt;
|
||||
int i, j;
|
||||
|
||||
/* get window data */
|
||||
data = (PNHMapWindow)GetWindowLong(hWnd, GWL_USERDATA);
|
||||
|
||||
hDC = BeginPaint(hWnd, &ps);
|
||||
|
||||
/* calculate paint rectangle */
|
||||
if( !IsRectEmpty(&ps.rcPaint) ) {
|
||||
/* prepare tiles DC for mapping */
|
||||
tileDC = CreateCompatibleDC(hDC);
|
||||
saveBmp = SelectObject(tileDC, GetNHApp()->bmpTiles);
|
||||
|
||||
/* calculate paint rectangle */
|
||||
paint_rt.top = data->yPos + ps.rcPaint.top/TILE_X;
|
||||
paint_rt.left = data->xPos + ps.rcPaint.left/TILE_Y;
|
||||
paint_rt.bottom = min(data->yPos+ps.rcPaint.bottom/TILE_Y+1, ROWNO);
|
||||
paint_rt.right = min(data->xPos+ps.rcPaint.right/TILE_X+1, COLNO);
|
||||
|
||||
/* 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;
|
||||
|
||||
ntile = glyph2tile[ data->map[i][j] ];
|
||||
t_x = (ntile % TILES_PER_LINE)*TILE_X;
|
||||
t_y = (ntile / TILES_PER_LINE)*TILE_Y;
|
||||
|
||||
BitBlt(hDC, (i-data->xPos)*TILE_X, (j-data->yPos)*TILE_Y, TILE_X, TILE_Y, tileDC, t_x, t_y, SRCCOPY );
|
||||
}
|
||||
SelectObject(tileDC, saveBmp);
|
||||
DeleteDC(tileDC);
|
||||
|
||||
/* draw focus rect */
|
||||
paint_rt.left = (data->xCur - data->xPos)*TILE_X;
|
||||
paint_rt.top = (data->yCur - data->yPos)*TILE_Y;
|
||||
paint_rt.right = paint_rt.left + TILE_X;
|
||||
paint_rt.bottom = paint_rt.top + TILE_Y;
|
||||
DrawFocusRect(hDC, &paint_rt);
|
||||
}
|
||||
EndPaint(hWnd, &ps);
|
||||
}
|
||||
|
||||
void onMSNH_VScroll(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
PNHMapWindow data;
|
||||
SCROLLINFO si;
|
||||
int yNewPos;
|
||||
int yDelta;
|
||||
|
||||
/* get window data */
|
||||
data = (PNHMapWindow)GetWindowLong(hWnd, GWL_USERDATA);
|
||||
|
||||
/* get page size */
|
||||
si.cbSize = sizeof(si);
|
||||
si.fMask = SIF_PAGE;
|
||||
GetScrollInfo(hWnd, SB_VERT, &si);
|
||||
|
||||
switch(LOWORD (wParam))
|
||||
{
|
||||
/* User clicked shaft left of the scroll box. */
|
||||
case SB_PAGEUP:
|
||||
yNewPos = data->yPos-si.nPage;
|
||||
break;
|
||||
|
||||
/* User clicked shaft right of the scroll box. */
|
||||
case SB_PAGEDOWN:
|
||||
yNewPos = data->yPos+si.nPage;
|
||||
break;
|
||||
|
||||
/* User clicked the left arrow. */
|
||||
case SB_LINEUP:
|
||||
yNewPos = data->yPos-1;
|
||||
break;
|
||||
|
||||
/* User clicked the right arrow. */
|
||||
case SB_LINEDOWN:
|
||||
yNewPos = data->yPos+1;
|
||||
break;
|
||||
|
||||
/* User dragged the scroll box. */
|
||||
case SB_THUMBTRACK:
|
||||
yNewPos = HIWORD(wParam);
|
||||
break;
|
||||
|
||||
default:
|
||||
yNewPos = data->yPos;
|
||||
}
|
||||
|
||||
yNewPos = max(0, yNewPos);
|
||||
yNewPos = min(ROWNO, yNewPos);
|
||||
if( yNewPos == data->yPos ) return;
|
||||
|
||||
yDelta = yNewPos - data->yPos;
|
||||
data->yPos = yNewPos;
|
||||
|
||||
ScrollWindowEx (hWnd, 0, -TILE_Y * yDelta,
|
||||
(CONST RECT *) NULL, (CONST RECT *) NULL,
|
||||
(HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE | SW_ERASE);
|
||||
|
||||
si.cbSize = sizeof(si);
|
||||
si.fMask = SIF_POS;
|
||||
si.nPos = data->yPos;
|
||||
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
|
||||
}
|
||||
|
||||
void onMSNH_HScroll(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
PNHMapWindow data;
|
||||
SCROLLINFO si;
|
||||
int xNewPos;
|
||||
int xDelta;
|
||||
|
||||
/* get window data */
|
||||
data = (PNHMapWindow)GetWindowLong(hWnd, GWL_USERDATA);
|
||||
|
||||
/* get page size */
|
||||
si.cbSize = sizeof(si);
|
||||
si.fMask = SIF_PAGE;
|
||||
GetScrollInfo(hWnd, SB_HORZ, &si);
|
||||
|
||||
switch(LOWORD (wParam))
|
||||
{
|
||||
/* User clicked shaft left of the scroll box. */
|
||||
case SB_PAGEUP:
|
||||
xNewPos = data->xPos-si.nPage;
|
||||
break;
|
||||
|
||||
/* User clicked shaft right of the scroll box. */
|
||||
case SB_PAGEDOWN:
|
||||
xNewPos = data->xPos+si.nPage;
|
||||
break;
|
||||
|
||||
/* User clicked the left arrow. */
|
||||
case SB_LINEUP:
|
||||
xNewPos = data->xPos-1;
|
||||
break;
|
||||
|
||||
/* User clicked the right arrow. */
|
||||
case SB_LINEDOWN:
|
||||
xNewPos = data->xPos+1;
|
||||
break;
|
||||
|
||||
/* User dragged the scroll box. */
|
||||
case SB_THUMBTRACK:
|
||||
xNewPos = HIWORD(wParam);
|
||||
break;
|
||||
|
||||
default:
|
||||
xNewPos = data->xPos;
|
||||
}
|
||||
|
||||
xNewPos = max(0, xNewPos);
|
||||
xNewPos = min(COLNO, xNewPos);
|
||||
if( xNewPos == data->xPos ) return;
|
||||
|
||||
xDelta = xNewPos - data->xPos;
|
||||
data->xPos = xNewPos;
|
||||
|
||||
ScrollWindowEx (hWnd, -TILE_X * xDelta, 0,
|
||||
(CONST RECT *) NULL, (CONST RECT *) NULL,
|
||||
(HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE | SW_ERASE);
|
||||
|
||||
|
||||
si.cbSize = sizeof(si);
|
||||
si.fMask = SIF_POS;
|
||||
si.nPos = data->xPos;
|
||||
SetScrollInfo(hWnd, SB_HORZ, &si, TRUE);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user