/* ============ Select_SetTexture Timo : bFitScale to compute scale on the plane and counteract plane / axial plane snapping Timo : brush primitive texturing the brushprimit_texdef given must be understood as a qtexture_t width=2 height=2 ( HiRes ) Timo : texture plugin, added an IPluginTexdef* parameter must be casted to an IPluginTexdef! if not NULL, get ->Copy() of it into each face or brush ( and remember to hook ) if NULL, means we have no information, ask for a default ============ */ void WINAPI Select_SetTexture( texdef_t* texdef, brushprimit_texdef_s* brushprimit_texdef, bool bFitScale, void* pPlugTexdef ) { brush_s* b; int nCount = g_ptrSelectedFaces.GetSize(); if ( nCount > 0 ) { Undo_Start( "set face textures" ); ASSERT( g_ptrSelectedFaces.GetSize() == g_ptrSelectedFaceBrushes.GetSize() ); for ( int i = 0; i < nCount; i++ ) { face_s* selFace = reinterpret_cast<face_s*>( g_ptrSelectedFaces.GetAt( i ) ); brush_s* selBrush = reinterpret_cast<brush_s*>( g_ptrSelectedFaceBrushes.GetAt( i ) ); Undo_AddBrush( selBrush ); SetFaceTexdef( selBrush, selFace, texdef, brushprimit_texdef, bFitScale, static_cast<IPluginTexdef*>( pPlugTexdef ) ); Brush_Build( selBrush, bFitScale ); Undo_EndBrush( selBrush ); } Undo_End(); } else if ( selected_brushes.next != &selected_brushes ) { Undo_Start( "set brush textures" ); for ( b = selected_brushes.next ; b != &selected_brushes ; b = b->next ) if ( !b->owner->eclass->fixedsize ) { Undo_AddBrush( b ); Brush_SetTexture( b, texdef, brushprimit_texdef, bFitScale, static_cast<IPluginTexdef*>( pPlugTexdef ) ); Undo_EndBrush( b ); } Undo_End(); } Sys_UpdateWindows( W_ALL ); }
/* ================ Drag_MouseUp ================ */ void Drag_MouseUp(int nButtons) { Sys_Status("drag completed.", 0); if (g_qeglobals.d_select_mode == sel_area) { Patch_SelectAreaPoints(); g_qeglobals.d_select_mode = sel_curvepoint; Sys_UpdateWindows(W_ALL); } if (g_qeglobals.d_select_translate[0] || g_qeglobals.d_select_translate[1] || g_qeglobals.d_select_translate[2]) { Select_Move(g_qeglobals.d_select_translate); VectorCopy(vec3_origin, g_qeglobals.d_select_translate); Sys_UpdateWindows(W_CAMERA); } g_pParentWnd->SetStatusText(3, ""); /* if (g_pParentWnd->GetCamera()->UpdateRenderEntities()) { Sys_UpdateWindows(W_CAMERA); } */ Undo_EndBrushList(&selected_brushes); Undo_End(); }
/* =========== Map_RegionTallBrush =========== */ void Map_RegionTallBrush( void ){ brush_t *b; if ( !QE_SingleBrush() ) { return; } b = selected_brushes.next; Map_RegionOff(); VectorCopy( b->mins, region_mins ); VectorCopy( b->maxs, region_maxs ); region_mins[2] = g_MinWorldCoord + 64; region_maxs[2] = g_MaxWorldCoord - 64; Undo_Start( "delete" ); Undo_AddBrushList( &selected_brushes ); Undo_AddEntity( b->owner ); Select_Delete(); Undo_EndBrushList( &selected_brushes ); Undo_End(); Map_ApplyRegion(); }
void Map_ImportBuffer( char *buf ){ Select_Deselect(); Undo_Start( "import buffer" ); MemStream stream; stream.Write( buf, strlen( buf ) ); Map_Import( &stream, "xmap" ); stream.Close(); Sys_UpdateWindows( W_ALL ); Sys_MarkMapModified(); Undo_End(); }
/* ============= Undo_Redo ============= */ void Undo_Redo(void) { undo_t *redo; brush_t *pBrush, *pNextBrush; entity_t *pEntity, *pNextEntity, *pRedoEntity; if (!g_lastredo) { Sys_Status("Nothing left to redo.\n"); return; } if (g_lastundo) { if (!g_lastundo->done) { Sys_Status("WARNING: last undo not finished.\n"); } } // get the last redo redo = g_lastredo; if (g_lastredo->prev) g_lastredo->prev->next = NULL; else g_redolist = NULL; g_lastredo = g_lastredo->prev; // Undo_GeneralStart(redo->operation); // remove current selection Select_Deselect(); // move "created" brushes back to the last undo for (pBrush = active_brushes.next; pBrush != NULL && pBrush != &active_brushes; pBrush = pNextBrush) { pNextBrush = pBrush->next; if (pBrush->redoId == redo->id) { //move the brush to the undo Brush_RemoveFromList(pBrush); Brush_AddToList(pBrush, &g_lastundo->brushlist); g_undoMemorySize += Brush_MemorySize(pBrush); pBrush->ownerId = pBrush->owner->entityId; Entity_UnlinkBrush(pBrush); } } // move "created" entities back to the last undo for (pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pNextEntity) { pNextEntity = pEntity->next; if (pEntity->redoId == redo->id) { // check if this entity is in the redo for (pRedoEntity = redo->entitylist.next; pRedoEntity != NULL && pRedoEntity != &redo->entitylist; pRedoEntity = pRedoEntity->next) { // move brushes to the redo entity if (pRedoEntity->entityId == pEntity->entityId) { pRedoEntity->brushes.next = pEntity->brushes.next; pRedoEntity->brushes.prev = pEntity->brushes.prev; pEntity->brushes.next = &pEntity->brushes; pEntity->brushes.prev = &pEntity->brushes; } } // //Entity_Free(pEntity); //move the entity to the redo Entity_RemoveFromList(pEntity); Entity_AddToList(pEntity, &g_lastundo->entitylist); g_undoMemorySize += Entity_MemorySize(pEntity); } } // add the undo entities back into the entity list for (pEntity = redo->entitylist.next; pEntity != NULL && pEntity != &redo->entitylist; pEntity = redo->entitylist.next) { //if this is the world entity if (pEntity->entityId == world_entity->entityId) { //free the epairs of the world entity Entity_FreeEpairs(world_entity); //set back the original epairs world_entity->epairs = pEntity->epairs; //free the world_entity clone that stored the epairs Entity_Free(pEntity); } else { Entity_RemoveFromList(pEntity); Entity_AddToList(pEntity, &entities); } } // add the redo brushes back into the selected brushes for (pBrush = redo->brushlist.next; pBrush != NULL && pBrush != &redo->brushlist; pBrush = redo->brushlist.next) { Brush_RemoveFromList(pBrush); Brush_AddToList(pBrush, &active_brushes); for (pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pEntity->next) { if (pEntity->entityId == pBrush->ownerId) { Entity_LinkBrush(pEntity, pBrush); break; } } //if the brush is not linked then it should be linked into the world entity if (pEntity == NULL || pEntity == &entities) { Entity_LinkBrush(world_entity, pBrush); } //build the brush //Brush_Build(pBrush); Select_Brush(pBrush); } // Undo_End(); // common->Printf("%s redone.\n", redo->operation); // g_redoId--; // free the undo Mem_Free(redo); // g_bScreenUpdates = true; Sys_UpdateWindows(W_ALL); }
void SI_SetTexdef_FaceList(texdef_to_face_t* texdef_face_list, bool b_SetUndoPoint, bool bFit_to_Scale) { texdef_to_face_t* texdef_to_face; bool b_isQuake2; if (g_pGameDescription->quake2) b_isQuake2 = true; else b_isQuake2 = false; if (!texdef_face_list) return; if (b_SetUndoPoint) { if(g_ptrSelectedFaces.GetSize() > 1) Sys_FPrintf(SYS_WRN, "WARNING: Undo NOT supported for multiple face selections\n"); else if( (selected_brushes.next != &selected_brushes) || (g_ptrSelectedFaces.GetSize() == 1)) { // Give something to undo to for(texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next) if (b_isQuake2) SetFaceTexdef_Q2(texdef_to_face->face, &texdef_to_face->orig_texdef, bFit_to_Scale); else SetFaceTexdef(texdef_to_face->face, &texdef_to_face->orig_texdef, &texdef_to_face->orig_bp_texdef, bFit_to_Scale); Undo_Start("set facelist texdefs"); if( selected_brushes.next != &selected_brushes ) Undo_AddBrushList(&selected_brushes); else Undo_AddBrush(texdef_face_list->brush); } } for(texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next) { if (b_isQuake2) SetFaceTexdef_Q2(texdef_to_face->face, &texdef_to_face->texdef, bFit_to_Scale); else { brushprimit_texdef_t brushprimit_texdef; FakeTexCoordsToTexMat(texdef_to_face->texdef.shift, texdef_to_face->texdef.rotate, texdef_to_face->texdef.scale, brushprimit_texdef.coords); SetFaceTexdef(texdef_to_face->face, &texdef_to_face->texdef, &brushprimit_texdef , bFit_to_Scale); } Brush_Build(texdef_to_face->brush); if(bFit_to_Scale) texdef_to_face->texdef = texdef_to_face->face->texdef; } if ( b_SetUndoPoint ) { if( (selected_brushes.next != &selected_brushes) || (g_ptrSelectedFaces.GetSize() == 1) ) { if(selected_brushes.next != &selected_brushes) Undo_EndBrushList(&selected_brushes); else Undo_EndBrush(texdef_face_list->brush); Undo_End(); // Over-write the orig_texdef list, cementing the change. for(texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next) { texdef_to_face->orig_texdef = texdef_to_face->texdef; texdef_to_face->orig_bp_texdef = texdef_to_face->face->brushprimit_texdef; } } } Sys_UpdateWindows (W_ALL); }
// // ======================================================================================================================= // Map_ImportFile Timo 09/01/99:: called by CXYWnd::Paste & Map_ImportFile if Map_ImportFile ( prefab ), the buffer // may contain brushes in old format ( conversion needed ) // ======================================================================================================================= // void Map_ImportBuffer(char *buf, bool renameEntities) { entity_t *ent; brush_t *b = NULL; CPtrArray ptrs; Select_Deselect(); Undo_Start("import buffer"); g_qeglobals.d_parsed_brushes = 0; if (buf) { CMapStringToString mapStr; StartTokenParsing(buf); g_qeglobals.d_num_entities = 0; // // Timo will be used in Entity_Parse to detect if a conversion between brush // formats is needed // g_qeglobals.bNeedConvert = false; g_qeglobals.bOldBrushes = false; g_qeglobals.bPrimitBrushes = false; g_qeglobals.mapVersion = 1.0; if (GetToken(true)) { if (stricmp(token, "Version") == 0) { GetToken(false); g_qeglobals.mapVersion = atof(token); common->Printf("Map version: %1.2f\n", g_qeglobals.mapVersion); } else { UngetToken(); } } idDict RemappedNames; // since I can't use "map <string, string>"... sigh. So much for STL... while (1) { // // use the selected brushes list as it's handy ent = Entity_Parse (false, // &selected_brushes); // ent = Entity_Parse(false, &active_brushes); if (!ent) { break; } // end entity for undo Undo_EndEntity(ent); // end brushes for undo for (b = ent->brushes.onext; b && b != &ent->brushes; b = b->onext) { Undo_EndBrush(b); } if (!strcmp(ValueForKey(ent, "classname"), "worldspawn")) { // world brushes need to be added to the current world entity b = ent->brushes.onext; while (b && b != &ent->brushes) { brush_t *bNext = b->onext; Entity_UnlinkBrush(b); Entity_LinkBrush(world_entity, b); ptrs.Add(b); b = bNext; } } else { // the following bit remaps conflicting target/targetname key/value pairs CString str = ValueForKey(ent, "target"); CString strKey; CString strTarget(""); if (str.GetLength() > 0) { if (FindEntity("target", str.GetBuffer(0))) { if (!mapStr.Lookup(str, strKey)) { idStr key; UniqueTargetName(key); strKey = key; mapStr.SetAt(str, strKey); } strTarget = strKey; SetKeyValue(ent, "target", strTarget.GetBuffer(0)); } } /* * str = ValueForKey(ent, "name"); if (str.GetLength() > 0) { if * (FindEntity("name", str.GetBuffer(0))) { if (!mapStr.Lookup(str, strKey)) { * UniqueTargetName(strKey); mapStr.SetAt(str, strKey); } Entity_SetName(ent, * strKey.GetBuffer(0)); } } */ CString cstrNameOld = ValueForKey(ent, "name"); Entity_Name(ent, renameEntities); CString cstrNameNew = ValueForKey(ent, "name"); if (cstrNameOld != cstrNameNew) { RemappedNames.Set(cstrNameOld, cstrNameNew); } // // if (strTarget.GetLength() > 0) SetKeyValue(ent, "target", // strTarget.GetBuffer(0)); // add the entity to the end of the entity list // ent->next = &entities; ent->prev = entities.prev; entities.prev->next = ent; entities.prev = ent; g_qeglobals.d_num_entities++; for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext) { ptrs.Add(b); } } } // now iterate through the remapped names, and see if there are any target-connections that need remaking... // // (I could probably write this in half the size with STL, but WTF, work with what we have...) // int iNumKeyVals = RemappedNames.GetNumKeyVals(); for (int iKeyVal=0; iKeyVal < iNumKeyVals; iKeyVal++) { const idKeyValue *pKeyVal = RemappedNames.GetKeyVal( iKeyVal ); LPCSTR psOldName = pKeyVal->GetKey().c_str(); LPCSTR psNewName = pKeyVal->GetValue().c_str(); entity_t *pEntOld = FindEntity("name", psOldName); // original ent we cloned from entity_t *pEntNew = FindEntity("name", psNewName); // cloned ent if (pEntOld && pEntNew) { CString cstrTargetNameOld = ValueForKey(pEntOld, "target"); if (!cstrTargetNameOld.IsEmpty()) { // ok, this ent was targeted at another ent, so it's clone needs updating to point to // the clone of that target, so... // entity_t *pEntOldTarget = FindEntity("name", cstrTargetNameOld); if ( pEntOldTarget ) { LPCSTR psNewTargetName = RemappedNames.GetString( cstrTargetNameOld ); if (psNewTargetName && psNewTargetName[0]) { SetKeyValue(pEntNew, "target", psNewTargetName); } } } } } } // // ::ShowWindow(g_qeglobals.d_hwndEntity, FALSE); // ::LockWindowUpdate(g_qeglobals.d_hwndEntity); // g_bScreenUpdates = false; for (int i = 0; i < ptrs.GetSize(); i++) { Brush_Build(reinterpret_cast < brush_t * > (ptrs[i]), true, false); Select_Brush(reinterpret_cast < brush_t * > (ptrs[i]), true, false); } // ::LockWindowUpdate(NULL); g_bScreenUpdates = true; ptrs.RemoveAll(); // // reset the "need conversion" flag conversion to the good format done in // Map_BuildBrushData // g_qeglobals.bNeedConvert = false; Sys_UpdateWindows(W_ALL); // Sys_MarkMapModified(); mapModified = 1; Undo_End(); }
/* ============= Undo_Redo ============= */ void Undo_Redo( void ){ // spog - disable undo if undo levels = 0 if ( g_PrefsDlg.m_nUndoLevels == 0 ) { Sys_Printf( "Undo_Redo: undo is disabled.\n" ); return; } undo_t *redo; brush_t *pBrush, *pNextBrush; entity_t *pEntity, *pNextEntity, *pRedoEntity; if ( !g_lastredo ) { Sys_Printf( "Nothing left to redo.\n" ); return; } if ( g_lastundo ) { if ( !g_lastundo->done ) { Sys_Printf( "WARNING: last undo not finished.\n" ); } } // get the last redo redo = g_lastredo; if ( g_lastredo->prev ) { g_lastredo->prev->next = NULL; } else{g_redolist = NULL; } g_lastredo = g_lastredo->prev; // Undo_GeneralStart( redo->operation ); // remove current selection Select_Deselect(); // move "created" brushes back to the last undo for ( pBrush = active_brushes.next; pBrush != NULL && pBrush != &active_brushes; pBrush = pNextBrush ) { pNextBrush = pBrush->next; if ( pBrush->redoId == redo->id ) { //move the brush to the undo Brush_RemoveFromList( pBrush ); Brush_AddToList( pBrush, &g_lastundo->brushlist ); g_undoMemorySize += Brush_MemorySize( pBrush ); pBrush->ownerId = pBrush->owner->entityId; Entity_UnlinkBrush( pBrush ); } } // move "created" entities back to the last undo for ( pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pNextEntity ) { pNextEntity = pEntity->next; if ( pEntity->redoId == redo->id ) { // check if this entity is in the redo for ( pRedoEntity = redo->entitylist.next; pRedoEntity != NULL && pRedoEntity != &redo->entitylist; pRedoEntity = pRedoEntity->next ) { // move brushes to the redo entity if ( pRedoEntity->entityId == pEntity->entityId ) { pRedoEntity->brushes.next = pEntity->brushes.next; pRedoEntity->brushes.prev = pEntity->brushes.prev; pEntity->brushes.next = &pEntity->brushes; pEntity->brushes.prev = &pEntity->brushes; } } // //Entity_Free(pEntity); //move the entity to the redo Entity_RemoveFromList( pEntity ); Entity_AddToList( pEntity, &g_lastundo->entitylist ); g_undoMemorySize += Entity_MemorySize( pEntity ); } } // add the undo entities back into the entity list for ( pEntity = redo->entitylist.next; pEntity != NULL && pEntity != &redo->entitylist; pEntity = redo->entitylist.next ) { //if this is the world entity if ( pEntity->entityId == world_entity->entityId ) { epair_t* tmp = world_entity->epairs; world_entity->epairs = pEntity->epairs; pEntity->epairs = tmp; Entity_Free( pEntity ); } else { Entity_RemoveFromList( pEntity ); Entity_AddToList( pEntity, &entities ); } } // add the redo brushes back into the selected brushes for ( pBrush = redo->brushlist.next; pBrush != NULL && pBrush != &redo->brushlist; pBrush = redo->brushlist.next ) { Brush_RemoveFromList( pBrush ); Brush_AddToList( pBrush, &active_brushes ); for ( pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pEntity->next ) // fixes broken undo on entities { if ( pEntity->entityId == pBrush->ownerId ) { Entity_LinkBrush( pEntity, pBrush ); break; } } //if the brush is not linked then it should be linked into the world entity if ( pEntity == NULL || pEntity == &entities ) { Entity_LinkBrush( world_entity, pBrush ); } //build the brush //Brush_Build(pBrush); Select_Brush( pBrush ); } // Undo_End(); // Sys_Printf( "%s redone.\n", redo->operation ); // g_redoId--; // free the undo free( redo ); // g_bScreenUpdates = true; UpdateSurfaceDialog(); Sys_UpdateWindows( W_ALL ); }
// //================ //Map_ImportFile // Timo 09/01/99 : called by CXYWnd::Paste & Map_ImportFile // if Map_ImportFile ( prefab ), the buffer may contain brushes in old format ( conversion needed ) //================ // void Map_ImportBuffer (char* buf) { entity_t* ent; brush_t* b = NULL; CPtrArray ptrs; Select_Deselect(); Undo_Start("import buffer"); g_qeglobals.d_parsed_brushes = 0; if (buf) { CMapStringToString mapStr; StartTokenParsing (buf); g_qeglobals.d_num_entities = 0; // Timo // will be used in Entity_Parse to detect if a conversion between brush formats is needed g_qeglobals.bNeedConvert = false; g_qeglobals.bOldBrushes = false; g_qeglobals.bPrimitBrushes = false; while (1) { // use the selected brushes list as it's handy //ent = Entity_Parse (false, &selected_brushes); ent = Entity_Parse (false, &active_brushes); if (!ent) break; //end entity for undo Undo_EndEntity(ent); //end brushes for undo for(b = ent->brushes.onext; b && b != &ent->brushes; b = b->onext) { Undo_EndBrush(b); } if (!strcmp(ValueForKey (ent, "classname"), "worldspawn")) { // world brushes need to be added to the current world entity b=ent->brushes.onext; while (b && b != &ent->brushes) { brush_t* bNext = b->onext; Entity_UnlinkBrush(b); Entity_LinkBrush(world_entity, b); ptrs.Add(b); b = bNext; } } else { // the following bit remaps conflicting target/targetname key/value pairs CString str = ValueForKey(ent, "target"); CString strKey; CString strTarget(""); if (str.GetLength() > 0) { if (FindEntity("target", str.GetBuffer(0))) { if (!mapStr.Lookup(str, strKey)) { UniqueTargetName(strKey); mapStr.SetAt(str, strKey); } strTarget = strKey; SetKeyValue(ent, "target", strTarget.GetBuffer(0)); } } str = ValueForKey(ent, "targetname"); if (str.GetLength() > 0) { if (FindEntity("targetname", str.GetBuffer(0))) { if (!mapStr.Lookup(str, strKey)) { UniqueTargetName(strKey); mapStr.SetAt(str, strKey); } SetKeyValue(ent, "targetname", strKey.GetBuffer(0)); } } //if (strTarget.GetLength() > 0) // SetKeyValue(ent, "target", strTarget.GetBuffer(0)); // add the entity to the end of the entity list ent->next = &entities; ent->prev = entities.prev; entities.prev->next = ent; entities.prev = ent; g_qeglobals.d_num_entities++; for (b=ent->brushes.onext ; b != &ent->brushes ; b=b->onext) { ptrs.Add(b); } } } } //::ShowWindow(g_qeglobals.d_hwndEntity, FALSE); //::LockWindowUpdate(g_qeglobals.d_hwndEntity); g_bScreenUpdates = false; for (int i = 0; i < ptrs.GetSize(); i++) { Brush_Build(reinterpret_cast<brush_t*>(ptrs[i]), true, false); Select_Brush(reinterpret_cast<brush_t*>(ptrs[i]), true, false); } //::LockWindowUpdate(NULL); g_bScreenUpdates = true; ptrs.RemoveAll(); // reset the "need conversion" flag // conversion to the good format done in Map_BuildBrushData g_qeglobals.bNeedConvert=false; Sys_UpdateWindows (W_ALL); //Sys_MarkMapModified(); modified = true; Undo_End(); }