/** ** Let the (remaining) areas taken by the cursors, as determined by ** DrawAnyCursor and InvalidateAreaAndCheckcursor, be invalidated. ** Note: building-cursor is already invalidated by redraw-map */ global void InvalidateCursorAreas(void) { //Invalidate cursor sprite if ( OldCursorInvalidate ) { InvalidateArea(OldCursorX,OldCursorY,OldCursorW,OldCursorH); OldCursorInvalidate=0; } //Invalidate hidden cursor sprite if ( HiddenCursorW ) { InvalidateArea(HiddenCursorX,HiddenCursorY,HiddenCursorW,HiddenCursorH); HiddenCursorW=0; } //Invalidate cursor rectangle if ( OldCursorRectangleInvalidate ) { InvalidateRectangle(OldCursorRectangleX,OldCursorRectangleY, OldCursorRectangleW,OldCursorRectangleH); OldCursorRectangleInvalidate=0; } //Invalidate hidden cursor rectangle if ( HiddenCursorRectangleW ) { InvalidateRectangle(HiddenCursorRectangleX,HiddenCursorRectangleY, HiddenCursorRectangleW,HiddenCursorRectangleH); HiddenCursorRectangleW=0; } }
/** ** Draw information about the map. ** ** @param x Screen X position. ** @param y Screen Y position. */ local void DrawMouseCoordsOnMap(int x,int y) { char buf[128]; #ifdef ACTION_MAP DrawImage(ImageMinimapTop,0,0,0,0); sprintf(buf,"%3d,%3d=%04X/%04X",Screen2MapX(x),Screen2MapY(y) ,TheMap.MovementMap[Screen2MapX(x)+Screen2MapY(y)*TheMap.Width] ,TheMap.ActionMap[Screen2MapX(x)+Screen2MapY(y)*TheMap.Width]); DrawText(3,3,SMALL_FONT,buf); InvalidateArea(0,0,176,24); #else #ifdef MOVE_MAP x=Screen2MapX(x); y=Screen2MapY(y); if( x<0 || y<0 || x>=TheMap.Width || y>=TheMap.Height ) { DebugLevel0(__FUNCTION__": coords outside map %d,%d\n",x,y); return; } DrawImage(ImageMinimapTop,0,0,0,0); sprintf(buf,"%3d,%3d=%02X|%04X|%04X",x,y ,TheMap.Fields[x+y*TheMap.Width].Value ,TheMap.MovementMap[x+y*TheMap.Width] ,TheMap.Fields[x+y*TheMap.Width].Flags); DrawText(3,3,SMALL_FONT,buf); InvalidateArea(0,0,176,24); #endif unsigned flags; x=Screen2MapX(x); y=Screen2MapY(y); if( x<0 || y<0 || x>=TheMap.Width || y>=TheMap.Height ) { DebugLevel0(__FUNCTION__": coords outside map %d,%d\n",x,y); return; } DrawImage(ImageMinimapTop,0,0,0,0); flags=TheMap.Fields[x+y*TheMap.Width].Flags; sprintf(buf,"%3d,%3d=%02X|%04X|%c%c%c%c%c%c%c%c%c",x,y ,TheMap.Fields[x+y*TheMap.Width].Value ,flags ,flags&MapFieldUnpassable ?'u':'-' ,flags&MapFieldNoBuilding ?'n':'-' ,flags&MapFieldForest ?'f':'-' ,flags&MapFieldWaterAllowed ?'w':'-' ,flags&MapFieldCoastAllowed ?'c':'-' ,flags&MapFieldLandAllowed ?'l':'-' ,flags&MapFieldHuman ?'h':'-' ,flags&MapFieldExplored ?'e':'-' ,flags&MapFieldVisible ?'v':'-' ); DrawText(3,3,SMALL_FONT,buf); InvalidateArea(0,0,176,24); #endif }
/** ** Invalidate only the sides of a given rectangle (not its contents) ** ** @param x left-top x-position of rectangle on screen ** @param y left-top y-position of rectangle on screen ** @param w width of rectangle on screen ** @param h height of rectangle on screen */ local void InvalidateRectangle(int x, int y, int w, int h) { InvalidateArea(x,y,w,1); // top side if ( --h > 0 ) { InvalidateArea(x,y+h,w,1); // bottom side if ( --h > 0 ) { InvalidateArea(x,++y,1,h); // left side if ( --w > 0 ) InvalidateArea(x+w,y,1,h); // right side } } }
/** ** Show load progress. ** ** @param fmt printf format string. */ void ShowLoadProgress(const char *fmt, ...) { static unsigned int lastProgressUpdate = SDL_GetTicks(); if (SDL_GetTicks() < lastProgressUpdate + 16) { // Only show progress updates every c. 1/60th of a second, otherwise we're waiting for the screen too much return; } lastProgressUpdate = SDL_GetTicks(); UpdateLoadProgress(); va_list va; char temp[4096]; va_start(va, fmt); vsnprintf(temp, sizeof(temp) - 1, fmt, va); temp[sizeof(temp) - 1] = '\0'; va_end(va); if (Video.Depth && IsGameFontReady() && GetGameFont().IsLoaded()) { // Remove non printable chars for (unsigned char *s = (unsigned char *)temp; *s; ++s) { if (*s < 32) { *s = ' '; } } //Wyrmgus start // Video.FillRectangle(ColorBlack, 5, Video.Height - 18, Video.Width - 10, 18); if (loadingBackground == nullptr) { Video.FillRectangle(ColorBlack, 0, Video.Height - 18, Video.Width, 18); } //Wyrmgus end CLabel(GetGameFont()).DrawCentered(Video.Width / 2, Video.Height - 16, temp); //Wyrmgus start // InvalidateArea(5, Video.Height - 18, Video.Width - 10, 18); if (loadingBackground == nullptr) { InvalidateArea(0, Video.Height - 18, Video.Width, 18); } else { InvalidateArea(0, 0, Video.Width, Video.Height); } //Wyrmgus end RealizeVideoMemory(); } else { DebugPrint("!!!!%s\n" _C_ temp); } PollEvents(); }
BOOL SearchAgain(WORD Flags) /*Flags: 1=Reverse (search in opposite direction) * 2=pop up dialog if not searched before */ { BOOL Return; ULONG OldLength; HideEditCaret(); if (Flags & 2 && !MatchValid) { SearchDialog(); return (TRUE); } OldLength = SelectCount; if (OldLength) { InvalidateArea(&SelectStart, SelectCount, 1); SelectCount = 0; UpdateWindow(hwndMain); } SelectStart = CurrPos; Return = SearchAndStatus(&SelectStart, (WORD)((Flags & 1) | 2)); if (Return) { if ((OldLength==0 && Mode!=InsertMode) || ComparePos(&SelectStart, &CurrPos) == 0) { if (CountBytes(&EndMatch) - CountBytes(&StartPos) == OldLength) { SelectStart = CurrPos; Return = SearchAndStatus(&SelectStart, (WORD)(Flags & 1)); } } if (Return) { NewPosition(&SelectStart); UpdateWindow(hwndMain); SelectStart = StartPos; SelectBytePos = CountBytes(&StartPos); SelectCount = CountBytes(&EndMatch) - SelectBytePos; InvalidateArea(&SelectStart, SelectCount, 0); UpdateWindow(hwndMain); } } CheckClipboard(); ShowEditCaret(); GetXPos(&CurrCol); return (Return); }
/** ** Let an area be invalidated, but remembering if cursor is automaticly ** invalidated with this area. ** Note: building-cursor is already invalidated by redraw-map ** ** @param x left-top x-position of area on screen ** @param y left-top y-position of area on screen ** @param w width of area on screen ** @param h height of area on screen */ global void InvalidateAreaAndCheckCursor( int x, int y, int w, int h ) { int dx,dy; //Invalidate area InvalidateArea(x,y,w,h); //Now check if cursor sprite is inside it, then no need for invalidate if ( OldCursorInvalidate ) { dx = OldCursorX-x; dy = OldCursorY-y; if ( dx >= 0 && dy >= 0 && (w-dx) >= OldCursorW && (h-dy) >= OldCursorH ) OldCursorInvalidate = 0; } //Now check if previously hidden cursor sprite is inside it.. if ( HiddenCursorW ) { dx = HiddenCursorX-x; dy = HiddenCursorY-y; if ( dx >= 0 && dy >= 0 && (w-dx) >= HiddenCursorW && (h-dy) >= HiddenCursorH ) HiddenCursorW = 0; } //Now check if cursor rectangle is inside it.. if ( OldCursorRectangleInvalidate ) { dx = OldCursorRectangleX-x; dy = OldCursorRectangleY-y; if ( dx >= 0 && dy >= 0 && (w-dx) >= OldCursorRectangleW && (h-dy) >= OldCursorRectangleH ) OldCursorRectangleInvalidate = 0; } //Now check if previously hidden cursor rectangle is inside it.. if ( HiddenCursorRectangleW ) { dx = HiddenCursorRectangleX-x; dy = HiddenCursorRectangleY-y; if ( dx >= 0 && dy >= 0 && (w-dx) >= HiddenCursorRectangleW && (h-dy) >= HiddenCursorRectangleH ) HiddenCursorRectangleW = 0; } }
void Undo(WORD Flags) /* Flags: 0 = called as vi-like undo: * undo of whole last operation, * a second undo reverts the undo operation, * entered as character 'u'; * 1 = called as Windows-like undo: * undo last change at one position, * repeated undos go further back in history, * entered as <Alt+Bksp>, menu, or tool button; * 2 = repeated vi-like undo ('.'): * can repeat both undo and redo; * 4 = vi-like undo of whole line: * not yet implemented, * entered as character 'U'; */ { LPUNDO lpUndo; BOOL fUndone = FALSE; ULONG StartSkip = (ULONG)-1; extern INT HexEditFirstNibble; if (Flags & 3) lpUndo = NextSequenceUndo; else { lpUndo = NextSequenceUndo = LastUndo; if (LastUndo != NULL) { LastUndo->Flags |= UD_START; if (LastUndo->Flags & UD_BYUNDO) { if (Redoing && LastUndo->UndoRef!=NULL) lpUndo = LastUndo->UndoRef; Redoing ^= TRUE^FALSE; } else Redoing = FALSE; } } if (lpUndo==NULL || (Redoing && !(lpUndo->Flags & UD_BYUNDO))) { Error(219); return; } if (IsViewOnly()) return; if (UtfEncoding == 16) { /*any undo ops must be double-byte, check before doing anything...*/ LPUNDO lp = lpUndo; ULONG Skip; while (lp != NULL) { if ((Skip = lpUndo->Pos) != (ULONG)-1) { if (lp->DelFill & 1 || lp->Inserted & 1) { ErrorBox(MB_ICONSTOP, 260); return; } if (StartSkip == (ULONG)-1) StartSkip = Skip; if (Flags & 1) break; } if (lp->Flags & UD_NEWOP && StartSkip != (ULONG)-1) break; lp = lp->Prev; } StartSkip = (ULONG)-1; } HideEditCaret(); wsprintf(QueryString, "%s %s, used mem %lu", Redoing ? "redoing" : "undoing", lpUndo->Flags & UD_BYUNDO ? "undo" : "non-undo", UndoMemUsed); QueryTime = GetTickCount(); GlobalUndoFlags |= UD_BYUNDO; StartWithRemove = lpUndo->Flags & UD_START; StartUndoSequence(); if (FirstUndo == NULL || (FirstUndo->Next == NULL && FirstUndo != lpUndo)) lpUndo = NULL; StartWithRemove = TRUE; HexEditFirstNibble = -1; while (lpUndo != NULL) { POSITION Pos; ULONG Skip; if ((Skip = lpUndo->Pos) != (ULONG)-1) { if (StartSkip == (ULONG)-1) StartSkip = Skip; Pos.p = FirstPage; while (Skip >= Pos.p->Fill) { if (!Pos.p->Next) { if (Skip != Pos.p->Fill) { /*must not occur*/ assert(Skip == Pos.p->Fill); /*!?*/ return; } break; } Skip -= Pos.p->Fill; Pos.p = Pos.p->Next; } if (SelectCount) { InvalidateArea(&SelectStart, SelectCount, 1); SelectCount = 0; UpdateWindow(hwndMain); } Pos.i = (UINT)Skip; Pos.f = 0; /*TODO: check flags to be filled here*/ if (lpUndo->Inserted) { SelectStart = Pos; SelectCount = lpUndo->Inserted; SelectBytePos = CountBytes(&SelectStart); DeleteSelected(3); fUndone = TRUE; Indenting = FALSE; } if (lpUndo->DelFill) { LPSTR Buf; LONG ByteCount = CountBytes(&Pos); if (lpUndo->Flags & UD_GLOBALMEM) Buf = GlobalLock(lpUndo->DelMem); else Buf = (LPBYTE)lpUndo + sizeof(UNDO); if (Buf != NULL) { NewPosition(&Pos); InsertBuffer(Buf, lpUndo->DelFill, 0); fUndone = TRUE; if (lpUndo->Flags & UD_GLOBALMEM) GlobalUnlock(lpUndo->DelMem); /*reposition to current position...*/ Pos.p = FirstPage; Pos.i = 0; Advance(&Pos, ByteCount); if (lpUndo->Flags & UD_SELECT && Flags & 1) { SelectStart = Pos; SelectCount = lpUndo->DelFill; SelectBytePos = CountBytes(&SelectStart); InvalidateArea(&SelectStart, SelectCount, 0); CheckClipboard(); } } else ErrorBox(MB_ICONSTOP, 313); } if (Flags & 1) break; } if (lpUndo->Flags & UD_NEWOP && StartSkip != (ULONG)-1) break; lpUndo = lpUndo->Prev; } GlobalUndoFlags = 0; if (lpUndo != NULL) { if (lpUndo->Flags & UD_SAFE) { EnableToolButton(IDB_SAVE, FALSE); SetSafe(FALSE); GlobalUndoFlags = UD_SAFE; } else if (fUndone) SetUnsafe(); LastUndo->UndoRef = NextSequenceUndo = lpUndo->Prev; #if 0 // if (NextSequenceUndo!=NULL && lpUndo->Flags & UD_BYUNDO // && !(NextSequenceUndo->Flags&UD_BYUNDO)) // NextSequenceUndo->Flags &= ~UD_START; #endif } else { if (fUndone) SetUnsafe(); NextSequenceUndo = NULL; } if (Redoing) CheckForUndoneToRelease(FALSE); /*...undo information about redo and previous undo is not needed anymore * because the original undo information will be used instead. */ if (StartSkip != (ULONG)-1) { CurrPos.p = FirstPage; CurrPos.i = 0; Advance(&CurrPos, StartSkip); FindValidPosition(&CurrPos, (WORD)(Mode==InsertMode || Mode==ReplaceMode)); GetXPos(&CurrCol); } if (lpUndo==NULL || NextSequenceUndo==NULL) EnableToolButton(IDB_UNDO, FALSE); ShowEditCaret(); }