- // This is needed to make the 2nd status pane visible
- GetClientRect(hWnd, &rc1);
- pt.x = rc1.right - zoomWndWidth, pt.y = -1;
- SendMessage(hStatusBar, SB_SETPARTS, 2, (LPARAM)&pt);
- break;
-
- case WM_RBUTTONDOWN:
-
- GetCursorPos(&pt);
- SetWindowPos(hToolPalWnd, 0, pt.x, pt.y, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
- SetFocus(hToolPalWnd);
- SetCapture(hToolPalWnd); // Ensure tool palette gets RButtonUp
- SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW))); // Tool pallete has "regular" cursor
- break;
-
- case WM_LBUTTONDOWN:
-
- mouseDown = true;
-
- if (currentTool == TOOLScroll || currentTool == TOOLZoom)
- SetCapture(hWnd); // Make sure we capture the mouse when in scroll/zoom mode
- else if (currentTool == TOOLAddPt) // "Add Point" tool
- {
- if (pts.GetNumPoints() > 0)
- {
-//Do we really need to put a cap on this???
-//Maybe...
-// if (pts.GetNumPoints() < 16)
-// {
- pt.x = lParam & 0xFFFF, pt.y = lParam >> 16;
- hdc = GetDC(hWnd);
- DPtoLP(hdc, &pt, 1);
- pts.InsertPoint(pts.GetNext(ptHighlight), pt.x, pt.y, (wParam & (MK_SHIFT | MK_CONTROL) ? false : true));
- ptHighlight = ptNextHighlight;
- ReleaseDC(hWnd, hdc);
- InvalidateRect(hWnd, NULL, TRUE);
-// }
- }
- }
- else if (currentTool == TOOLAddPoly) // "Add Poly" tool
- {
-#ifdef DEBUGFOO
-wsprintf(strBuf, "Adding point... # polys: %u, # points: %u", pts.GetNumPolys(), pts.GetNumPoints());
-WriteLogMsg(strBuf);
-#endif
- if (polyFirstPoint)
- {
- polyFirstPoint = false;
- pts.AddNewPolyAtEnd();
- }
-
-//Do we really need to put a cap on this???
-//Maybe...
-// if (pts.GetNumPoints() < 16)
-// {
- pt.x = lParam & 0xFFFF, pt.y = lParam >> 16;
- hdc = GetDC(hWnd);
- DPtoLP(hdc, &pt, 1);
- ReleaseDC(hWnd, hdc);
- // Append a point to the end of the structure
- pts += IPoint(pt.x, pt.y, (wParam & (MK_SHIFT | MK_CONTROL) ? false : true));
-ptHighlight = pts.GetNumPoints() - 1;
- InvalidateRect(hWnd, NULL, TRUE);
-// }
-#ifdef DEBUGFOO
-wsprintf(strBuf, " --> [# polys: %u, # points: %u]\xD\xA", pts.GetNumPolys(), pts.GetNumPoints());
-WriteLogMsg(strBuf);
-#endif
- }
- else if (currentTool == TOOLSelect || currentTool == TOOLPolySelect)
- {
- if (pts.GetNumPoints() > 0)
- {
- pt.x = pts.GetX(ptHighlight), pt.y = pts.GetY(ptHighlight);
- hdc = GetDC(hWnd);
- LPtoDP(hdc, &pt, 1);
- ClientToScreen(hWnd, &pt);
- SetCursorPos(pt.x, pt.y);
- ReleaseDC(hWnd, hdc);
-
- if (wParam & (MK_SHIFT | MK_CONTROL))
- pts.SetOnCurve(ptHighlight, !pts.GetOnCurve(ptHighlight));
- }
- }
- else if (currentTool == TOOLDelPt)
- {
- if (pts.GetNumPoints() > 0)
-//Or could use:
-// if (ptHighlight != -1)
- {
-//This assumes that WM_MOUSEMOVE happens before this!
-//The above commented out line should take care of this contingency... !!! FIX !!!
- pts.DeletePoint(ptHighlight);
- InvalidateRect(hWnd, NULL, TRUE);
- }
- }
-
- break;
-
- case WM_LBUTTONUP:
-
- mouseDown = false;
-
- if (currentTool == TOOLScroll || currentTool == TOOLZoom)
- ReleaseCapture();
-
- break;
-
- case WM_MOUSEMOVE:
-
- SetCursor(hCur[currentTool]);
-
- // Extract current point from lParam/calc offset from previous point
-
- pt.x = lParam & 0xFFFF, pt.y = lParam >> 16;
- ptOffset.x = pt.x - ptPrevious.x,
- ptOffset.y = pt.y - ptPrevious.y;
-
- if (mouseDown)
- {
- if (currentTool == TOOLScroll)
- {
- // NOTE: OffsetViewportOrg operates in DEVICE UNITS...
-
- hdc = GetDC(hWnd);
- OffsetViewportOrgEx(hdc, ptOffset.x, ptOffset.y, NULL);
- ReleaseDC(hWnd, hdc);
-
-// this shows that it works, so the logic above must be faulty...
-// And it is. It should convert the coords first, then do the subtraction to figure the offset...
-// Above: DONE
-// Then multiply it by the scaling factor. Whee!
-
- InvalidateRect(hWnd, NULL, TRUE);
-// SendMessage(hWnd, WM_PAINT, NULL, NULL);
- }
- else if (currentTool == TOOLAddPt || currentTool == TOOLAddPoly || currentTool == TOOLSelect)
- {
- if (currentTool != TOOLAddPt || pts.GetNumPoints() > 0)//yecch.
- {
- POINT pt2;
- pt2.x = pt.x, pt2.y = pt.y;
- // Should also set onCurve here as well, depending on keystate
-//Or should we?
- hdc = GetDC(hWnd);
- DPtoLP(hdc, &pt2, 1);
- pts.SetXY(ptHighlight, pt2.x, pt2.y);
- ReleaseDC(hWnd, hdc);
- InvalidateRect(hWnd, NULL, TRUE);
- }
- }
- else if (currentTool == TOOLPolySelect)
- {
- if (pts.GetNumPoints() > 0)
- {
- POINT pt2;
- pt2.x = pt.x, pt2.y = pt.y;
- // Should also set onCurve here as well, depending on keystate
-//Or should we?
- hdc = GetDC(hWnd);
- DPtoLP(hdc, &pt2, 1);
- pts.OffsetPoly(pts.GetPoly(ptHighlight), pt2.x - pts.GetX(ptHighlight), pt2.y - pts.GetY(ptHighlight));
- ReleaseDC(hWnd, hdc);
- InvalidateRect(hWnd, NULL, TRUE);
- }
- }
- }
- else
- {
- if (currentTool == TOOLSelect || currentTool == TOOLDelPt || currentTool == TOOLAddPt
- || currentTool == TOOLPolySelect)// || currentTool == TOOLAddPoly)
- {
- POINT pt2;
- pt2.x = pt.x, pt2.y = pt.y;
- hdc = GetDC(hWnd);
- DPtoLP(hdc, &pt2, 1);
- ReleaseDC(hWnd, hdc);
-
- double closest = 1.0e+99;
-
- for(int i=0; i<pts.GetNumPoints(); i++)
- {
- double dist = ((pt2.x - pts.GetX(i)) * (pt2.x - pts.GetX(i)))
- + ((pt2.y - pts.GetY(i)) * (pt2.y - pts.GetY(i)));
-
- if (dist < closest)
- closest = dist, ptHighlight = i;
- }
-
- if (ptHighlight != oldPtHighlight)
- {
- oldPtHighlight = ptHighlight;
- InvalidateRect(hWnd, NULL, TRUE);
- }
-
- // What follows here looks like voodoo, but is really simple. What we do is
- // check to see if the mouse point has a perpendicular intersection with any of
- // the line segments. If it does, calculate the length of the perpendicular
- // and choose the smallest length. If there is no perpendicular, then choose the
- // length of line connecting the closer of either the first endpoint or the
- // second and choose the smallest of those.
-
- // There is one bit of math that looks like voodoo to me ATM--will explain once
- // I understand it better (the calculation of the length of the perpendicular).
-
- if (pts.GetNumPoints() > 1 && currentTool == TOOLAddPt)
- {
- double smallest = 1.0e+99;
-
- for(int i=0; i<pts.GetNumPoints(); i++)
- {
- int32 p1x = pts.GetX(i), p1y = pts.GetY(i),
- p2x = pts.GetX(pts.GetNext(i)), p2y = pts.GetY(pts.GetNext(i));
-
- vector ls(p2x, p2y, 0, p1x, p1y, 0), v1(pt2.x, pt2.y, 0, p1x, p1y, 0),
- v2(pt2.x, pt2.y, 0, p2x, p2y, 0);
- double pp = ls.dot(v1) / ls.length(), dist;
-// Geometric interpretation:
-// pp is the paremeterized point on the vector ls where the perpendicular intersects ls.
-// If pp < 0, then the perpendicular lies beyond the 1st endpoint. If pp > length of ls,
-// then the perpendicular lies beyond the 2nd endpoint.
-
- if (pp < 0.0)
- dist = v1.length();
- else if (pp > ls.length())
- dist = v2.length();
- else // distance = ?Det?(ls, v1) / |ls|
- dist = abs((ls.x * v1.y - v1.x * ls.y) / ls.length());
-
-//The answer to the above looks like it might be found here:
-//
-//If the segment endpoints are s and e, and the point is p, then the test for the perpendicular
-//intercepting the segment is equivalent to insisting that the two dot products {s-e}.{s-p} and
-//{e-s}.{e-p} are both non-negative. Perpendicular distance from the point to the segment is
-//computed by first computing the area of the triangle the three points form, then dividing by the
-//length of the segment. Distances are done just by the Pythagorean theorem. Twice the area of the
-//triangle formed by three points is the determinant of the following matrix:
-//
-//sx sy 1
-//ex ey 1
-//px py 1
-//
-//(???) By translating the start point to the origin, this can be rewritten as:
-//By subtracting row 1 from all rows, you get the following:
-//
-//0 0 0
-//(ex - sx) (ey - sy) 0
-//(px - sx) (py - sy) 0
-//
-//which greatly simplifies the calculation of the determinant.
-
- if (dist < smallest)
- smallest = dist, ptNextHighlight = pts.GetNext(i), ptHighlight = i;
- }
-
- if (ptNextHighlight != oldPtNextHighlight)
- {
- oldPtNextHighlight = ptNextHighlight;
- InvalidateRect(hWnd, NULL, TRUE);
- }
- }
- }
- }
-
- ptPrevious.x = pt.x, ptPrevious.y = pt.y;
-
- break;
-
- case WM_NOTIFY:
-
- if (((NMHDR *)lParam)->code == TTN_NEEDTEXT)
- {
- LoadString(hInst, ((TOOLTIPTEXT *)lParam)->hdr.idFrom + 0x80, toolTipTxt, 16);
- ((TOOLTIPTEXT *)lParam)->lpszText = toolTipTxt;
- }
-
- break;
-
- case WM_MENUSELECT:
- {
- statusBarTxt[0] = 0; // Clear status bar text
- uint16 flags = wParam >> 16; // Extract flags
-
- if (!(flags & MFT_SEPARATOR))
- {
- uint16 id = wParam & 0xFFFF;
-
- if (flags & MF_POPUP)
- {
- if (flags & MF_SYSMENU)
- id = IDS_SYSMENU;
- else
- id = IDM_FILEMENU + wParam;
- }
-
- LoadString(hInst, id, statusBarTxt, 64);
- }
-
- SendMessage(hStatusBar, SB_SETTEXT, 0 + SBT_NOBORDERS, (LPARAM)statusBarTxt);
- break;
- }
- case WM_COMMAND:
- {
- uint16 cmd = wParam & 0xFFFF;
-
- if (cmd == IDM_NEW)
- {
-// call CmdIDM_NEW
- }
- else if (cmd == IDM_OPEN)
- {
-// call SaveChanges
-// .IF (eax)
-// movmov ofn.hwndOwner, eax, hMainWnd
-// mov ofn.Flags, OFN_PATHMUSTEXIST + OFN_FILEMUSTEXIST
-// invoke GetOpenFileName, ADDR ofn
-// .IF (eax)
-////////
-//jmp @F
-//szDMsg1a BYTE "Could not open the file (GetOpenFileName)...", 0
-//szDMsg1b BYTE "Open error!", 0
-//szDMsg1c BYTE "About to attempt to open file...", 0
-//@@:
-////invoke MessageBox, hWnd, ADDR szDMsg1a, ADDR szDMsg1b, MB_ICONERROR or MB_OK
-//invoke MessageBox, hMainWnd, ADDR szDMsg1c, ADDR szFile, MB_ICONERROR or MB_OK
-// invoke LoadTTF, ADDR szFile
-//
-//////
-// // <<< FILE OPEN CODE HERE >>>
-// or fFileStatus, NAMEDbit
-// and fFileStatus, NOT CHANGEDbit
-// call NewWindowName
-// mov eax, TRUE // return TRUE
-// jmp Return
-// //��������������������������������������
-//OpenError: invoke GetLastError
-// // <<< FILE OPEN ERROR CODE HERE >>>
-// .ENDIF
-// zero eax // return FALSE
-// .ENDIF
- }
- else if (cmd == IDM_SAVEAS)
- {
-// and fFileStatus, NOT NAMEDbit
-// call CmdIDM_SAVE
- }
- else if (cmd == IDM_SAVE)
- {
-// call CmdIDM_SAVE
- }
- else if (cmd == IDM_ABOUT)
- DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ABOUT), hMainWnd, AboutProc, NULL);
- else if (cmd == IDM_EXIT)
- SendMessage(hWnd, WM_CLOSE, 0, 0);
- else if (cmd == ID_TBCHARWIN)
- {
- ShowWindow(hCharWnd, (IsWindowVisible(hCharWnd) ? SW_HIDE : SW_SHOWNOACTIVATE));
-
-#ifdef DEBUGFOO
-wpC.length = sizeof(WINDOWPLACEMENT);
-GetWindowPlacement(hCharWnd, &wpC);
-wsprintf(strBuf, "Char window showCmd = %08X...\n", wpC.showCmd);
-WriteLogMsg(strBuf);
-#endif
- }
- else
- return DefWindowProc(hWnd, msgID, wParam, lParam);
-
- break;
- }
- default:
- return DefWindowProc(hWnd, msgID, wParam, lParam);
- }
-
- return 0;
-}
-
-//
-// Initialize TTF data
-//
-void CreateNewDoc(void)
-{
-}
-
-//
-// Save changes to document before quitting
-//
-bool SaveChanges(void)
-{
- return true;
-}
-
-
-
-//
-// ABOUT Dialog WndProc
-//
-BOOL CALLBACK AboutProc(HWND hDlg, UINT msgID, WPARAM wParam, LPARAM lParam)
-{
- switch (msgID)
- {
- case WM_INITDIALOG:
-
- MiscCenterWnd(hDlg, hMainWnd);
- break;
-
- case WM_COMMAND:
-
- if (wParam == IDOK || wParam == IDCANCEL)
- EndDialog(hDlg, TRUE);
-
- break;
-
- default:
- return FALSE;
- }
-
- return TRUE;
-}
-
-//
-// Character Window WndProc
-//
-WndProcCW PROC STDCALL, hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
-
- mov eax, uMsg // pickup our message
- .IF (eax == WM_PAINT)
- mov eax, 0 // Non-sense... (placeholder!)
-// Scan conversion etc. goes here...
- .ELSEIF (eax == WM_LBUTTONDOWN)
- invoke SetCapture, hCharWnd
- .ELSEIF (eax == WM_LBUTTONUP)
- invoke ReleaseCapture
- invoke SetFocus, hMainWnd // Make sure the main wnd keeps focus!
- .ELSEIF (eax == WM_NCLBUTTONDOWN)
- invoke DefWindowProc, hWnd, uMsg, wParam, lParam // Let it do its thing
- invoke SetFocus, hMainWnd // Make sure the main wnd keeps focus!
- .ELSE
-DefProc: invoke DefWindowProc, hWnd, uMsg, wParam, lParam
- .ENDIF
- ret
-
-WndProcCW ENDP
-
-//
-// Character Window WndProc
-//
-LRESULT CALLBACK WndProcCW(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
-{
- switch (msgID)
- {
- default:
- return DefWindowProc(hWnd, msgID, wParam, lParam);
- }
-
- return 0;
-}
-
-
-// Function prototypes
-
-int32 FindSelectedTool(void);
-
-//
-// Tool Palette WndProc
-//
-LRESULT CALLBACK WndProcTP(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
-{
- PAINTSTRUCT ps;
- HDC hdc;
- POINT pt;
- static uint32 prevTool = -1;
-
- switch (msgID)
- {
- case WM_PAINT:
- {
- hdc = BeginPaint(hWnd, &ps);
- HDC newDC = CreateCompatibleDC(NULL);
- SelectObject(newDC, hBMToolPal1);
- BitBlt(hdc, 0, 0, sizeTPBM.x, sizeTPBM.y, newDC, 0, 0, SRCCOPY);
- DeleteDC(newDC);
-
-// This is crappy. Find some way to tighten this up!
- int32 tool = FindSelectedTool();
-
- if (tool != -1)
- {
- newDC = CreateCompatibleDC(NULL);
- SelectObject(newDC, hBMToolPal1);
- //need ul corner of bitmap, ul corner of dest, width/height
- pt.x = sizeStamp.x * (tool & 0x03), pt.y = sizeStamp.y * (tool >> 2);
- BitBlt(hdc, pt.x, pt.y, sizeStamp.x, sizeStamp.y, newDC, pt.x, pt.y, NOTSRCCOPY);
- DeleteDC(newDC);
- }
-
- EndPaint(hWnd, &ps);
- break;
- }
- case WM_MOUSEMOVE:
- {
- int32 tool = FindSelectedTool();
-
- if (tool != prevTool)
- {
- prevTool = tool;
- InvalidateRect(hWnd, NULL, FALSE);
- }
-
- break;
- }
- case WM_RBUTTONUP:
- {
- int32 tool = FindSelectedTool(), oldTool = currentTool;
-
- if (tool != -1)
- currentTool = tool;
-
- if (currentTool != TOOLSelect && currentTool != TOOLDelPt && currentTool != TOOLAddPt
- && currentTool != TOOLPolySelect)
- ptHighlight = -1;
-
- if (currentTool != oldTool)
- InvalidateRect(hMainWnd, NULL, TRUE);
-
- if (currentTool == TOOLAddPoly)
-#ifdef DEBUGFOO
-{
-#endif
- polyFirstPoint = true;
-#ifdef DEBUGFOO
-wsprintf(strBuf, "--> Selected poly tool, polyFirstPoint is %s\n", polyFirstPoint ? "true" : "false");
-WriteLogMsg(strBuf);
-}
-#endif
-
- ReleaseCapture();
- ShowWindow(hToolPalWnd, SW_HIDE);
- SetFocus(hMainWnd); // Make sure the main wnd keeps focus!
-
- break;
- }
- default:
- return DefWindowProc(hWnd, msgID, wParam, lParam);
- }
-
- return 0;
-}
-
-//
-// Find which tool we're pointing at
-// Use: xcoord = mouse.x / (bmsize.x/4), ycoord = mouse.y / (bmsize.y/2)
-//
-int32 FindSelectedTool(void)
-{
- POINT pt;
-
- GetCursorPos(&pt);
- ScreenToClient(hToolPalWnd, &pt);
-
- uint32 x = (uint32)pt.x / sizeStamp.x, y = (uint32)pt.y / sizeStamp.y, tool = -1;
-
- if (x < 4 && y < 2)
-// {
- tool = (y * 4) + x;
-
-// if (tool == 7)
-// tool = -1; // 7 has no tool...
-// }
-
- return tool;