BOOL EnterInsertForUndo(PPOSITION Pos, ULONG Length) { ULONG ByteCount = CountBytes(Pos); CheckForUndoneToRelease(TRUE); EnableUndo(); if (!LastUndo || (LastUndo->Pos != (ULONG)-1 && LastUndo->Pos != ByteCount - LastUndo->Inserted)) if (!NewUndo()) return (FALSE); if (LastUndo->Pos == (ULONG)-1) LastUndo->Pos = ByteCount; LastUndo->Inserted += Length; return (TRUE); }
//Because loading and saving the map takes a few seconds, we want to post a message //on the screen and then update it which requires passing the screen back to the main loop. //When we come back for the next frame, we then actually save or load the map. So this //process takes two full screen cycles. UINT32 ProcessFileIO() { INT16 usStartX, usStartY; CHAR8 ubNewFilename[50]; BOOLEAN fAltMap;//dnl ch31 150909 switch( gbCurrentFileIOStatus ) { case INITIATE_MAP_SAVE: //draw save message StartFrameBufferRender( ); SaveFontSettings(); SetFont( HUGEFONT ); SetFontForeground( FONT_LTKHAKI ); SetFontShadow( FONT_DKKHAKI ); SetFontBackground( 0 ); swprintf( zOrigName, L"Saving map: %s", gzFilename ); usStartX = iScreenWidthOffset + 320 - StringPixLength( zOrigName, LARGEFONT1 ) / 2; usStartY = iScreenHeightOffset + 180 - GetFontHeight( LARGEFONT1 ) / 2; mprintf( usStartX, usStartY, zOrigName ); InvalidateScreen( ); EndFrameBufferRender( ); gbCurrentFileIOStatus = SAVING_MAP; return LOADSAVE_SCREEN; case SAVING_MAP: //save map sprintf( ubNewFilename, "%S", gzFilename ); RaiseWorldLand(); if( gfShowPits ) RemoveAllPits(); OptimizeSchedules(); ShowHighGround(4);//dnl ch41 210909 //dnl ch33 091009 BOOLEAN fRet; if(gfVanillaMode && iNewMapWorldRows == OLD_WORLD_ROWS && iNewMapWorldCols == OLD_WORLD_COLS) fRet = SaveWorld(ubNewFilename, VANILLA_MAJOR_MAP_VERSION, VANILLA_MINOR_MAP_VERSION); else fRet = SaveWorld(ubNewFilename); if(!fRet) { //dnl ch37 150909 gfSaveError = TRUE; if(gfErrorCatch) { InitErrorCatchDialog(); return(EDIT_SCREEN); } gbCurrentFileIOStatus = IOSTATUS_NONE; CreateMessageBox((STR16)(_BS(L" Error saving ") << (const char*)ubNewFilename << L" file. Try another filename? " << _BS::wget).c_str() ); return(guiCurrentScreen); } if( gfShowPits ) AddAllPits(); GetSectorFromFileName(gzFilename, gWorldSectorX, gWorldSectorY, gbWorldSectorZ, fAltMap);//dnl ch31 140909 if( gfGlobalSummaryExists ) UpdateSectorSummary( gzFilename, gfUpdateSummaryInfo ); else//dnl ch30 150909 ReEvaluateWorld(ubNewFilename); iCurrentAction = ACTION_NULL; gbCurrentFileIOStatus = IOSTATUS_NONE; gfRenderWorld = TRUE; gfRenderTaskbar = TRUE; fEnteringLoadSaveScreen = TRUE; RestoreFontSettings(); if( gfErrorCatch ) { InitErrorCatchDialog(); return EDIT_SCREEN; } fNewMapSaved = TRUE; return EDIT_SCREEN; case INITIATE_MAP_LOAD: //draw load message SaveFontSettings(); gbCurrentFileIOStatus = LOADING_MAP; if( gfEditMode && iCurrentTaskbar == TASK_MERCS ) IndicateSelectedMerc( SELECT_NO_MERC ); SpecifyItemToEdit( NULL, -1 ); return LOADSAVE_SCREEN; case LOADING_MAP: //load map DisableUndo(); sprintf( ubNewFilename, "%S", gzFilename ); RemoveMercsInSector( ); // Want to override crash, so user can do something else. if(!ReEvaluateWorld(ubNewFilename) || !LoadWorld(ubNewFilename))//dnl ch36 140909 { EnableUndo(); gbCurrentFileIOStatus = IOSTATUS_NONE; gfGlobalError = FALSE; gfLoadError = TRUE; CreateMessageBox((STR16)(_BS(L" Error loading ") << (const char*)ubNewFilename << L" file. Try another filename? " << _BS::wget).c_str()); return(guiCurrentScreen); } //ADB these are NOT set yet! but they need to be, duh CompileWorldMovementCosts(); GetSectorFromFileName(gzFilename, gWorldSectorX, gWorldSectorY, gbWorldSectorZ, fAltMap);//dnl ch31 140909 RestoreFontSettings(); //Load successful, update necessary information. //ATE: Any current mercs are transfered here... //UpdateMercsInSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); AddSoldierInitListTeamToWorld( ENEMY_TEAM, 255 ); AddSoldierInitListTeamToWorld( CREATURE_TEAM, 255 ); AddSoldierInitListTeamToWorld( MILITIA_TEAM, 255 ); AddSoldierInitListTeamToWorld( CIV_TEAM, 255 ); iCurrentAction = ACTION_NULL; gbCurrentFileIOStatus = IOSTATUS_NONE; if( !gfCaves && !gfBasement ) { gusLightLevel = 12; if( ubAmbientLightLevel != 4 ) { ubAmbientLightLevel = 4; LightSetBaseLevel( ubAmbientLightLevel ); } } else gusLightLevel = (UINT16)(EDITOR_LIGHT_MAX - ubAmbientLightLevel ); gEditorLightColor = gpLightColors[ 0 ]; gfRenderWorld = TRUE; gfRenderTaskbar = TRUE; fEnteringLoadSaveScreen = TRUE; InitJA2SelectionWindow(); ShowEntryPoints(); EnableUndo(); RemoveAllFromUndoList(); SetEditorSmoothingMode( gMapInformation.ubEditorSmoothingType ); if( gMapInformation.ubEditorSmoothingType == SMOOTHING_CAVES ) AnalyseCaveMapForStructureInfo(); AddLockedDoorCursors(); gubCurrRoomNumber = gubMaxRoomNumber; UpdateRoofsView(); UpdateWallsView(); ShowLightPositionHandles(); SetMercTeamVisibility( ENEMY_TEAM, gfShowEnemies ); SetMercTeamVisibility( CREATURE_TEAM, gfShowCreatures ); SetMercTeamVisibility( MILITIA_TEAM, gfShowRebels ); SetMercTeamVisibility( CIV_TEAM, gfShowCivilians ); BuildItemPoolList(); gpItemPool = NULL;//dnl ch26 210909 fShowHighGround = FALSE;//dnl ch2 210909 fRaiseWorld = FALSE;//dnl ch3 210909 ShowHighGround(4);//dnl ch41 210909 SetRenderCenter(WORLD_COLS/2, WORLD_ROWS/2);//dnl ch43 280909 if( gfShowPits ) AddAllPits(); if( iCurrentTaskbar == TASK_MAPINFO ) { //We have to temporarily remove the current textinput mode, //update the disabled text field values, then restore the current //text input fields. SaveAndRemoveCurrentTextInputMode(); UpdateMapInfoFields(); RestoreSavedTextInputMode(); } return EDIT_SCREEN; } gbCurrentFileIOStatus = IOSTATUS_NONE; return LOADSAVE_SCREEN; }
//Because loading and saving the map takes a few seconds, we want to post a message //on the screen and then update it which requires passing the screen back to the main loop. //When we come back for the next frame, we then actually save or load the map. So this //process takes two full screen cycles. UINT32 ProcessFileIO() { INT16 usStartX, usStartY; UINT8 ubNewFilename[50]; switch( gbCurrentFileIOStatus ) { case INITIATE_MAP_SAVE: //draw save message StartFrameBufferRender( ); SaveFontSettings(); SetFont( HUGEFONT ); SetFontForeground( FONT_LTKHAKI ); SetFontShadow( FONT_DKKHAKI ); SetFontBackground( 0 ); swprintf( zOrigName, L"Saving map: %s", gzFilename ); usStartX = 320 - StringPixLength( zOrigName, LARGEFONT1 ) / 2; usStartY = 180 - GetFontHeight( LARGEFONT1 ) / 2; mprintf( usStartX, usStartY, zOrigName ); InvalidateScreen( ); EndFrameBufferRender( ); gbCurrentFileIOStatus = SAVING_MAP; return LOADSAVE_SCREEN; case SAVING_MAP: //save map sprintf( ubNewFilename, "%S", gzFilename ); RaiseWorldLand(); if( gfShowPits ) RemoveAllPits(); OptimizeSchedules(); if ( !SaveWorld( ubNewFilename ) ) { if( gfErrorCatch ) { InitErrorCatchDialog(); return EDIT_SCREEN; } return ERROR_SCREEN; } if( gfShowPits ) AddAllPits(); SetGlobalSectorValues( gzFilename ); if( gfGlobalSummaryExists ) UpdateSectorSummary( gzFilename, gfUpdateSummaryInfo ); iCurrentAction = ACTION_NULL; gbCurrentFileIOStatus = IOSTATUS_NONE; gfRenderWorld = TRUE; gfRenderTaskbar = TRUE; fEnteringLoadSaveScreen = TRUE; RestoreFontSettings(); if( gfErrorCatch ) { InitErrorCatchDialog(); return EDIT_SCREEN; } if( gMapInformation.ubMapVersion != gubMinorMapVersion ) ScreenMsg( FONT_MCOLOR_RED, MSG_ERROR, L"Map data has just been corrupted!!! What did you just do? KM : 0" ); return EDIT_SCREEN; case INITIATE_MAP_LOAD: //draw load message SaveFontSettings(); gbCurrentFileIOStatus = LOADING_MAP; if( gfEditMode && iCurrentTaskbar == TASK_MERCS ) IndicateSelectedMerc( SELECT_NO_MERC ); SpecifyItemToEdit( NULL, -1 ); return LOADSAVE_SCREEN; case LOADING_MAP: //load map DisableUndo(); sprintf( ubNewFilename, "%S", gzFilename ); RemoveMercsInSector( ); if( !LoadWorld( ubNewFilename ) ) { //Want to override crash, so user can do something else. EnableUndo(); SetPendingNewScreen( LOADSAVE_SCREEN ); gbCurrentFileIOStatus = IOSTATUS_NONE; gfGlobalError = FALSE; gfLoadError = TRUE; //RemoveButton( iTempButton ); CreateMessageBox( L" Error loading file. Try another filename?" ); return LOADSAVE_SCREEN; } SetGlobalSectorValues( gzFilename ); RestoreFontSettings(); //Load successful, update necessary information. //ATE: Any current mercs are transfered here... //UpdateMercsInSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); AddSoldierInitListTeamToWorld( ENEMY_TEAM, 255 ); AddSoldierInitListTeamToWorld( CREATURE_TEAM, 255 ); AddSoldierInitListTeamToWorld( MILITIA_TEAM, 255 ); AddSoldierInitListTeamToWorld( CIV_TEAM, 255 ); iCurrentAction = ACTION_NULL; gbCurrentFileIOStatus = IOSTATUS_NONE; if( !gfCaves && !gfBasement ) { gusLightLevel = 12; if( ubAmbientLightLevel != 4 ) { ubAmbientLightLevel = 4; LightSetBaseLevel( ubAmbientLightLevel ); } } else gusLightLevel = (UINT16)(EDITOR_LIGHT_MAX - ubAmbientLightLevel ); gEditorLightColor = gpLightColors[ 0 ]; gfRenderWorld = TRUE; gfRenderTaskbar = TRUE; fEnteringLoadSaveScreen = TRUE; InitJA2SelectionWindow(); ShowEntryPoints(); EnableUndo(); RemoveAllFromUndoList(); SetEditorSmoothingMode( gMapInformation.ubEditorSmoothingType ); if( gMapInformation.ubEditorSmoothingType == SMOOTHING_CAVES ) AnalyseCaveMapForStructureInfo(); AddLockedDoorCursors(); gubCurrRoomNumber = gubMaxRoomNumber; UpdateRoofsView(); UpdateWallsView(); ShowLightPositionHandles(); SetMercTeamVisibility( ENEMY_TEAM, gfShowEnemies ); SetMercTeamVisibility( CREATURE_TEAM, gfShowCreatures ); SetMercTeamVisibility( MILITIA_TEAM, gfShowRebels ); SetMercTeamVisibility( CIV_TEAM, gfShowCivilians ); BuildItemPoolList(); if( gfShowPits ) AddAllPits(); if( iCurrentTaskbar == TASK_MAPINFO ) { //We have to temporarily remove the current textinput mode, //update the disabled text field values, then restore the current //text input fields. SaveAndRemoveCurrentTextInputMode(); UpdateMapInfoFields(); RestoreSavedTextInputMode(); } return EDIT_SCREEN; } gbCurrentFileIOStatus = IOSTATUS_NONE; return LOADSAVE_SCREEN; }
BOOL EnterDeleteForUndo(PPOSITION Pos, ULONG Length, WORD Flags) /*Flags: 1=enter as selected, reselect after undo * 2=remove last undo information, cannot be undone later */ { LPBYTE NewBuf = NULL; HGLOBAL NewMem = 0; POSITION p; ULONG Inx; ULONG ByteCount = CountBytes(Pos); ULONG OldSize; LPUNDO Reallocated = NULL; if (Flags & 2) { if (!LastUndo->Inserted) return (FALSE); --LastUndo->Inserted; return (TRUE); } CheckForUndoneToRelease(TRUE); EnableUndo(); if (!LastUndo || (LastUndo->Pos != (ULONG)-1 && (LastUndo->Pos != ByteCount - LastUndo->Inserted || (int)(Flags & 1) != ((LastUndo->Flags & UD_SELECT) != 0) || !(LastUndo->Flags & UD_GLOBALMEM && LastUndo->DelFill+Length > 64000)))) if (!NewUndo()) return (FALSE); if (LastUndo->Pos == (ULONG)-1) LastUndo->Pos = ByteCount; if (!LastUndo->DelFill) { OldSize = 0; if (Length > 64000) { LastUndo->Flags |= UD_GLOBALMEM; NewMem = GlobalAlloc(GMEM_MOVEABLE, Length); if (NewMem) NewBuf = GlobalLock(NewMem); } else { assert(!(LastUndo->Flags & UD_GLOBALMEM)); LastUndo->Flags &= ~UD_GLOBALMEM; Reallocated = (LPUNDO)_frealloc(LastUndo, (size_t)(sizeof(UNDO)+Length)); if (Reallocated == NULL) return (FALSE); NewBuf = (LPBYTE)Reallocated + sizeof(UNDO); } } else { if (LastUndo->Flags & UD_GLOBALMEM) { OldSize = GlobalSize(LastUndo->DelMem); if (LastUndo->DelFill + Length > OldSize) { NewMem = GlobalReAlloc(LastUndo->DelMem, LastUndo->DelFill + Length, GMEM_MOVEABLE); } else NewMem = LastUndo->DelMem; if (NewMem) NewBuf = GlobalLock(NewMem); } else { Reallocated = (LPUNDO)_frealloc(LastUndo, (size_t)(sizeof(UNDO) + Length + LastUndo->DelFill)); if (Reallocated == NULL) return (FALSE); NewBuf = (LPBYTE)Reallocated + sizeof(UNDO); OldSize = 0; } } UndoMemUsed -= OldSize; if (NewBuf == NULL) { if (NewMem) GlobalFree(NewMem); return (FALSE); } if (Reallocated!=NULL && Reallocated!=LastUndo) { /*correct any references to this object...*/ if (NextSequenceUndo == LastUndo) NextSequenceUndo = Reallocated; if (Reallocated->Prev != NULL) Reallocated->Prev->Next = Reallocated; if (FirstUndo == LastUndo) FirstUndo = Reallocated; LastUndo = Reallocated; } Inx = LastUndo->DelFill; if (NewMem) { UndoMemUsed += GlobalSize(NewMem); LastUndo->DelMem = NewMem; } else UndoMemUsed += Length; LastUndo->DelFill += Length; if (Flags & 1) LastUndo->Flags |= UD_SELECT; p = *Pos; while (Length) { UINT n, c = CharAt(&p); if (c == C_EOF) { /*should not occur!...*/ assert(c != C_EOF); /*!?*/ LastUndo->DelFill -= Length; break; } if (Length > p.p->Fill - p.i) n = p.p->Fill - p.i; else n = (UINT)Length; assert(p.p->PageBuf); assert(n > 0); assert(n <= PAGESIZE); assert(p.i+n <= PAGESIZE); hmemcpy(NewBuf + Inx, p.p->PageBuf + p.i, n); Inx += n; p.i += n; Length -= n; } if (NewMem) GlobalUnlock(NewMem); return (TRUE); }