/* ======================================================================================================================= QE_CheckAutoSave If five minutes have passed since making a change and the map hasn't been saved, save it out. ======================================================================================================================= */ void QE_CheckAutoSave(void) { static bool inAutoSave = false; static bool autoToggle = false; if (inAutoSave) { Sys_Status("Did not autosave due recursive entry into autosave routine\n"); return; } if ( !mapModified ) { return; } inAutoSave = true; if ( g_PrefsDlg.m_bAutoSave ) { CString strMsg = g_PrefsDlg.m_bSnapShots ? "Autosaving snapshot..." : "Autosaving..."; Sys_Status(strMsg.GetBuffer(0), 0); if (g_PrefsDlg.m_bSnapShots && stricmp(currentmap, "unnamed.map") != 0) { Map_Snapshot(); } else { Map_SaveFile(ValueForKey(g_qeglobals.d_project_entity, (autoToggle == 0) ? "autosave1" : "autosave2" ), false, true); autoToggle ^= 1; } Sys_Status("Autosaving...Saved.", 0); mapModified = 0; // DHM - _D3XP } else { common->Printf("Autosave skipped...\n"); Sys_Status("Autosave skipped...", 0); } inAutoSave = false; }
/* ======================================================================================================================= ======================================================================================================================= */ void SelectVertexByRay(idVec3 org, idVec3 dir) { int i, besti; float d, bestd; idVec3 temp; float scale = g_pParentWnd->ActiveXY()->Scale(); // find the point closest to the ray besti = -1; bestd = 8 / scale / 2; for (i = 0; i < g_qeglobals.d_numpoints; i++) { temp = g_qeglobals.d_points[i] - org; d = temp * dir; temp = org + d * dir; temp = g_qeglobals.d_points[i] - temp; d = temp.Length(); if ( d < bestd ) { bestd = d; besti = i; } } if (besti == -1 || bestd > 8 / scale / 2 ) { Sys_Status("Click didn't hit a vertex\n"); return; } Sys_Status("hit vertex\n"); g_qeglobals.d_move_points[g_qeglobals.d_num_move_points++] = &g_qeglobals.d_points[besti]; // SelectVertex (besti); }
/* ============= Undo_AddBrush ============= */ void Undo_AddBrush(brush_t *pBrush) { if (!g_lastundo) { Sys_Status("Undo_AddBrushList: no last undo.\n"); return; } if (g_lastundo->entitylist.next != &g_lastundo->entitylist) { Sys_Status("Undo_AddBrushList: WARNING adding brushes after entity.\n"); } //if the brush is already in the undo if (Undo_BrushInUndo(g_lastundo, pBrush)) return; //clone the brush brush_t* pClone = Brush_FullClone(pBrush); //save the ID of the owner entity pClone->ownerId = pBrush->owner->entityId; if (pBrush->owner && !(pBrush->owner->eclass->nShowFlags & ECLASS_WORLDSPAWN)) { Undo_AddEntity(pBrush->owner); } //save the old undo ID for previous undos pClone->undoId = pBrush->undoId; Brush_AddToList (pClone, &g_lastundo->brushlist); // g_undoMemorySize += Brush_MemorySize(pClone); }
void SelectBrush (int entitynum, int brushnum) { entity_t *e; brush_t *b; int i; if (entitynum == 0) e = world_entity; else { e = entities.next; while (--entitynum) { e=e->next; if (e == &entities) { Sys_Status ("No such entity.", 0); return; } } } b = e->brushes.onext; if (b == &e->brushes) { Sys_Status ("No such brush.", 0); return; } while (brushnum--) { b=b->onext; if (b == &e->brushes) { Sys_Status ("No such brush.", 0); return; } } Brush_RemoveFromList (b); Brush_AddToList (b, &selected_brushes); Sys_UpdateWindows (W_ALL); for (i=0 ; i<3 ; i++) { if (g_pParentWnd->GetXYWnd()) g_pParentWnd->GetXYWnd()->GetOrigin()[i] = (b->mins[i] + b->maxs[i])/2; if (g_pParentWnd->GetXZWnd()) g_pParentWnd->GetXZWnd()->GetOrigin()[i] = (b->mins[i] + b->maxs[i])/2; if (g_pParentWnd->GetYZWnd()) g_pParentWnd->GetYZWnd()->GetOrigin()[i] = (b->mins[i] + b->maxs[i])/2; } Sys_Status ("Selected.", 0); }
/* =============== ConnectEntities Sets target / targetname on the two entities selected from the first selected to the secon =============== */ void ConnectEntities( void ){ entity_t *e1, *e2; const char *target; char *newtarg = NULL; if ( g_qeglobals.d_select_count != 2 ) { Sys_Status( "Must have two brushes selected", 0 ); Sys_Beep(); return; } e1 = g_qeglobals.d_select_order[0]->owner; e2 = g_qeglobals.d_select_order[1]->owner; if ( e1 == world_entity || e2 == world_entity ) { Sys_Status( "Can't connect to the world", 0 ); Sys_Beep(); return; } if ( e1 == e2 ) { Sys_Status( "Brushes are from same entity", 0 ); Sys_Beep(); return; } target = ValueForKey( e1, "target" ); if ( target && target[0] ) { newtarg = g_strdup( target ); } else { target = ValueForKey( e2, "targetname" ); if ( target && target[0] ) { newtarg = g_strdup( target ); } else{ Entity_Connect( e1, e2 ); } } if ( newtarg != NULL ) { SetKeyValue( e1, "target", newtarg ); SetKeyValue( e2, "targetname", newtarg ); g_free( newtarg ); } Sys_UpdateWindows( W_XY | W_CAMERA ); Select_Deselect(); Select_Brush( g_qeglobals.d_select_order[1] ); }
/* ======================================================================================================================= ======================================================================================================================= */ void SelectEdgeByRay(idVec3 org, idVec3 dir) { int i, j, besti; float d, bestd; idVec3 mid, temp; pedge_t *e; // find the edge closest to the ray besti = -1; bestd = 8; for (i = 0; i < g_qeglobals.d_numedges; i++) { for (j = 0; j < 3; j++) { mid[j] = 0.5 * (g_qeglobals.d_points[g_qeglobals.d_edges[i].p1][j] + g_qeglobals.d_points[g_qeglobals.d_edges[i].p2][j]); } temp = mid - org; d = temp * dir; temp = org + d * dir; temp = mid - temp; d = temp.Length(); if ( d < bestd ) { bestd = d; besti = i; } } if (besti == -1) { Sys_Status("Click didn't hit an edge\n"); return; } Sys_Status("hit edge\n"); // // make the two faces that border the edge use the two edge points as primary drag // points // g_qeglobals.d_num_move_points = 0; e = &g_qeglobals.d_edges[besti]; #ifdef NEWEDGESEL for (brush_t * b = selected_brushes.next; b != &selected_brushes; b = b->next) { SelectFaceEdge(b, e->f1, e->p1, e->p2); SelectFaceEdge(b, e->f2, e->p2, e->p1); } #else SelectFaceEdge(e->f1, e->p1, e->p2); SelectFaceEdge(e->f2, e->p2, e->p1); #endif }
/* ================ 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_RegionSelectedBrushes ======================================================================================================================= */ void Map_RegionSelectedBrushes(void) { Map_RegionOff(); if (selected_brushes.next == &selected_brushes) { // nothing selected Sys_Status("Tried to region with no selection...\n"); return; } region_active = true; Select_GetBounds(region_mins, region_maxs); // move the entire active_brushes list to filtered_brushes filtered_brushes.next = active_brushes.next; filtered_brushes.prev = active_brushes.prev; filtered_brushes.next->prev = &filtered_brushes; filtered_brushes.prev->next = &filtered_brushes; Patch_Deselect(); // move the entire selected_brushes list to active_brushes active_brushes.next = selected_brushes.next; active_brushes.prev = selected_brushes.prev; active_brushes.next->prev = &active_brushes; active_brushes.prev->next = &active_brushes; // clear selected_brushes selected_brushes.next = selected_brushes.prev = &selected_brushes; Sys_UpdateWindows(W_ALL); }
/* Turn the currently selected entity back into normal brushes */ void Select_Ungroup (void) { entity_t *e; brush_t *b; e = selected_brushes.next->owner; if (!e || e == world_entity || e->eclass->fixedsize) { Sys_Status ("Not a grouped entity.", 0); return; } for (b=e->brushes.onext ; b != &e->brushes ; b=e->brushes.onext) { Brush_RemoveFromList (b); Brush_AddToList (b, &active_brushes); Entity_UnlinkBrush (b); Entity_LinkBrush (world_entity, b); Brush_Build( b ); b->owner = world_entity; } Entity_Free (e); Sys_UpdateWindows (W_ALL); }
/* ============= Undo_AddEntity ============= */ void Undo_AddEntity(entity_t *entity) { entity_t* pClone; if (!g_lastundo) { Sys_Status("Undo_AddEntity: no last undo.\n"); return; } //if the entity is already in the undo if (Undo_EntityInUndo(g_lastundo, entity)) return; //clone the entity pClone = Entity_Clone(entity); //NOTE: Entity_Clone adds the entity to the entity list // so we remove it from that list here Entity_RemoveFromList(pClone); //save the old undo ID for previous undos pClone->undoId = entity->undoId; //save the entity ID (we need a full clone) pClone->entityId = entity->entityId; // Entity_AddToList(pClone, &g_lastundo->entitylist); // g_undoMemorySize += Entity_MemorySize(pClone); }
/* ======================================================================================================================= ======================================================================================================================= */ void SelectSplinePointByRay(const idVec3 &org, const idVec3 &dir, int buttons) { int i, besti; float d, bestd; idVec3 temp; // find the point closest to the ray besti = -1; bestd = 8; for (i = 0; i < g_qeglobals.d_numpoints; i++) { temp = g_qeglobals.d_points[i] - org; d = temp * dir; temp = org + d * dir; temp = g_qeglobals.d_points[i] - temp; d = temp.Length(); if ( d <= bestd ) { bestd = d; besti = i; } } if (besti == -1) { return; } Sys_Status("hit curve point\n"); g_qeglobals.d_num_move_points = 0; g_qeglobals.d_move_points[g_qeglobals.d_num_move_points++] = &g_qeglobals.d_points[besti]; // g_splineList->setSelectedPoint(&g_qeglobals.d_points[besti]); }
/*! connects two entities creating a unique target/targetname value */ void Entity_Connect(entity_t *e1, entity_t *e2) { const char *maptarget; char newtarget[16]; int maxtarget=0; // highest t# value in the map entity_t *e; // map entities if (e1 == e2) { #ifdef _DEBUG Sys_Status ("Entity_Connect: Brushes are from same entity.", 0); #endif return; } for (e=entities.next ; e != &entities ; e=e->next) { maptarget = ValueForKey (e, "target"); if (maptarget && maptarget[0]) { int targetnum = atoi(maptarget+1); if (targetnum > maxtarget) maxtarget = targetnum; } } sprintf (newtarget, "t%i", maxtarget+1); #ifdef _DEBUG Sys_Printf("Connecting entities with new target/targetname: %s\n", newtarget); #endif SetKeyValue (e1, "target", newtarget); SetKeyValue (e2, "targetname", newtarget); }
void Sys_UpdateStatusBar( void ) { extern int g_numbrushes, g_numentities; char numbrushbuffer[100] = ""; sprintf( numbrushbuffer, "Brushes: %d Entities: %d", g_numbrushes, g_numentities ); Sys_Status( numbrushbuffer, 2 ); }
void QE_CheckAutoSave( void ) { static clock_t s_start; clock_t now; now = clock(); if ( modified != 1 || !s_start) { s_start = now; return; } if ( now - s_start > ( CLOCKS_PER_SEC * 60 * g_PrefsDlg.m_nAutoSave)) { if (g_PrefsDlg.m_bAutoSave) { CString strMsg = g_PrefsDlg.m_bSnapShots ? "Autosaving snapshot..." : "Autosaving..."; Sys_Printf(strMsg.GetBuffer(0)); Sys_Printf("\n"); Sys_Status (strMsg.GetBuffer(0),0); // only snapshot if not working on a default map if (g_PrefsDlg.m_bSnapShots && stricmp(currentmap, "unnamed.map") != 0) { Map_Snapshot(); } else { Map_SaveFile (ValueForKey(g_qeglobals.d_project_entity, "autosave"), false); } Sys_Status ("Autosaving...Saved.", 0 ); modified = 2; } else { Sys_Printf ("Autosave skipped...\n"); Sys_Status ("Autosave skipped...", 0 ); } s_start = now; } }
/* ======================================================================================================================= ======================================================================================================================= */ bool QE_SingleBrush(bool bQuiet, bool entityOK) { if ((selected_brushes.next == &selected_brushes) || (selected_brushes.next->next != &selected_brushes)) { if (!bQuiet) { Sys_Status("Error: you must have a single brush selected\n"); } return false; } if (!entityOK && selected_brushes.next->owner->eclass->fixedsize) { if (!bQuiet) { Sys_Status("Error: you cannot manipulate fixed size entities\n"); } return false; } return true; }
/* ======================================================================================================================= ======================================================================================================================= */ void Face_ScaleTexture_BrushPrimit(face_t *face, float sS, float sT) { if (!g_qeglobals.m_bBrushPrimitMode) { Sys_Status("BP mode required\n"); return; } brushprimit_texdef_t *pBP = &face->brushprimit_texdef; BPMatScale(pBP->coords, sS, sT); // now emit the coordinates on the winding EmitBrushPrimitTextureCoordinates(face, face->face_winding); }
/* =========== Map_SaveFile \todo FIXME remove the use_region, this is broken .. work with a global flag to set region mode or not =========== */ void Map_SaveFile( const char *filename, qboolean use_region ){ clock_t start, finish; double elapsed_time; start = clock(); Sys_Printf( "Saving map to %s\n",filename ); Pointfile_Clear(); if ( !use_region ) { char backup[1024]; // rename current to .bak strcpy( backup, filename ); StripExtension( backup ); strcat( backup, ".bak" ); unlink( backup ); rename( filename, backup ); } Sys_Printf( "Map_SaveFile: %s\n", filename ); // build the out data stream FileStream file; if ( !file.Open( filename,"w" ) ) { Sys_FPrintf( SYS_ERR, "ERROR: couldn't open %s for write\n", filename ); return; } // extract filetype Map_Export( &file, filename_get_extension( filename ), use_region ); file.Close(); finish = clock(); elapsed_time = (double)( finish - start ) / CLOCKS_PER_SEC; Sys_Printf( "Saved in %-.2f second(s).\n",elapsed_time ); modified = false; if ( !strstr( filename, "autosave" ) ) { Sys_SetTitle( filename ); } if ( !use_region ) { time_t timer; time( &timer ); Sys_Beep(); Sys_Status( "Saved.", 0 ); } }
/* ============= Undo_AddBrushList ============= */ void Undo_AddBrushList(brush_t *brushlist) { brush_t *pBrush; if (!g_lastundo) { Sys_Status("Undo_AddBrushList: no last undo.\n"); return; } if (g_lastundo->entitylist.next != &g_lastundo->entitylist) { Sys_Status("Undo_AddBrushList: WARNING adding brushes after entity.\n"); } //copy the brushes to the undo for (pBrush = brushlist->next ; pBrush != NULL && pBrush != brushlist; pBrush=pBrush->next) { //if the brush is already in the undo if (Undo_BrushInUndo(g_lastundo, pBrush)) continue; //clone the brush brush_t* pClone = Brush_FullClone(pBrush); //save the ID of the owner entity pClone->ownerId = pBrush->owner->entityId; //save the old undo ID from previous undos pClone->undoId = pBrush->undoId; if ( pBrush->owner && pBrush->owner != world_entity ) { Undo_AddEntity(pBrush->owner); } Brush_AddToList (pClone, &g_lastundo->brushlist); // g_undoMemorySize += Brush_MemorySize(pClone); } }
// advance camera to previous point void Pointfile_Prev( void ) { idVec3 dir; if( s_check_point == 0 ) { Sys_Status( "Start of pointfile", 0 ); return; } s_check_point--; VectorCopy( s_pointvecs[s_check_point], g_pParentWnd->GetCamera()->Camera().origin ); VectorCopy( s_pointvecs[s_check_point], g_pParentWnd->GetXYWnd()->GetOrigin() ); VectorSubtract( s_pointvecs[s_check_point + 1], g_pParentWnd->GetCamera()->Camera().origin, dir ); dir.Normalize(); g_pParentWnd->GetCamera()->Camera().angles[1] = atan2( dir[1], dir[0] ) * 180 / 3.14159; g_pParentWnd->GetCamera()->Camera().angles[0] = asin( dir[2] ) * 180 / 3.14159; Sys_UpdateWindows( W_ALL ); }
void ScaleMode (void) { if (g_pParentWnd->getCurrentToolMode() == ScaleMode && g_pParentWnd->getDefaultToolMode() != ScaleMode) { g_pParentWnd->getDefaultToolMode()(); } else { g_pParentWnd->setCurrentToolMode(ScaleMode); g_currentToolModeSupportsComponentEditing = true; GlobalClipper().onClipMode(false); Sys_Status(c_ScaleMode_status); GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eScale); ToolChanged(); ModeChangeNotify(); } }
// advance camera to next point void Pointfile_Next( void ) { vec3_t dir; if ( s_check_point >= s_num_points - 2 ) { Sys_Status( "End of pointfile", 0 ); return; } s_check_point++; VectorCopy( s_pointvecs[s_check_point], g_pParentWnd->GetCamWnd()->Camera()->origin ); VectorCopy( s_pointvecs[s_check_point], g_pParentWnd->GetXYWnd()->GetOrigin() ); VectorSubtract( s_pointvecs[s_check_point + 1], g_pParentWnd->GetCamWnd()->Camera()->origin, dir ); VectorNormalize( dir, dir ); g_pParentWnd->GetCamWnd()->Camera()->angles[1] = atan2( dir[1], dir[0] ) * 180 / 3.14159; g_pParentWnd->GetCamWnd()->Camera()->angles[0] = asin( dir[2] ) * 180 / 3.14159; Sys_UpdateWindows( W_ALL ); }
/* ======================================================================================================================= ======================================================================================================================= */ void CNewTexWnd::OnLButtonDown(UINT nFlags, CPoint point) { cursor = point; SetFocus(); bool fitScale = Sys_KeyDown(VK_CONTROL); bool edit = Sys_KeyDown(VK_SHIFT) && !fitScale; const idMaterial *mat = getMaterialAtPoint(point); if (mat) { Select_SetDefaultTexture(mat, fitScale, true); } else { Sys_Status("Did not select a texture\n", 0); } // UpdateSurfaceDialog(); UpdatePatchInspector(); }
void Texture_SetTexture(texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef, bool bFitScale, bool bSetSelection) { if (texdef->name[0] == '(') { Sys_Status("Can't select an entity texture\n", 0); return; } g_qeglobals.d_texturewin.texdef = *texdef; // // store the texture coordinates for new brush primitive mode be sure that all the // callers are using the default 2x2 texture // if (g_qeglobals.m_bBrushPrimitMode) { g_qeglobals.d_texturewin.brushprimit_texdef = *brushprimit_texdef; } g_dlgFind.updateTextures(texdef->name); if (!g_dlgFind.isOpen() && bSetSelection) { Select_SetTexture(texdef, brushprimit_texdef, bFitScale); } g_Inspectors->texWnd.EnsureTextureIsVisible(texdef->name); if ( g_Inspectors->mediaDlg.IsWindowVisible() ) { g_Inspectors->mediaDlg.SelectCurrentItem(true, g_qeglobals.d_texturewin.texdef.name, CDialogTextures::MATERIALS); } g_qeglobals.d_texturewin.texdef = *texdef; // store the texture coordinates for new brush primitive mode be sure that all the // callers are using the default 2x2 texture // if (g_qeglobals.m_bBrushPrimitMode) { g_qeglobals.d_texturewin.brushprimit_texdef = *brushprimit_texdef; } Sys_UpdateWindows(W_TEXTURE); }
/* =========== 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, ""); }
void SelectFaceEdge (face_t * f, int p1, int p2) #endif { idWinding *w; int i, j, k; int pnum[128]; #ifdef NEWEDGESEL w = Brush_MakeFaceWinding(b, f); #else w = Brush_MakeFaceWinding(selected_brushes.next, f); #endif if (!w) { return; } for (i = 0; i < w->GetNumPoints(); i++) { pnum[i] = FindPoint( (*w)[i].ToVec3() ); } for (i = 0; i < w->GetNumPoints(); i++) { if (pnum[i] == p1 && pnum[(i + 1) % w->GetNumPoints()] == p2) { VectorCopy(g_qeglobals.d_points[pnum[i]], f->planepts[0]); VectorCopy(g_qeglobals.d_points[pnum[(i + 1) % w->GetNumPoints()]], f->planepts[1]); VectorCopy(g_qeglobals.d_points[pnum[(i + 2) % w->GetNumPoints()]], f->planepts[2]); for (j = 0; j < 3; j++) { for (k = 0; k < 3; k++) { f->planepts[j][k] = floor(f->planepts[j][k] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize; } } AddPlanept(&f->planepts[0]); AddPlanept(&f->planepts[1]); break; } } if ( i == w->GetNumPoints() ) { Sys_Status("SelectFaceEdge: failed\n"); } delete w; }
void Sys_Printf (char *text, ...) { va_list argptr; char buf[32768]; char *out; va_start (argptr,text); vsprintf (buf, text,argptr); va_end (argptr); out = TranslateString (buf); #ifdef LATER Sys_Status(out); #else SendMessage (g_qeglobals.d_hwndEdit, EM_REPLACESEL, 0, (LPARAM)out); #endif }
void Sys_Printf( char* text, ... ) { va_list argptr; char buf[32768]; char* out; LRESULT result; // PGM DWORD oldPosS, oldPosE; // PGM va_start( argptr, text ); vsprintf( buf, text, argptr ); va_end( argptr ); out = TranslateString( buf ); #ifdef LATER Sys_Status( out ); #else //PGM result = SendMessage( g_qeglobals.d_hwndEdit, EM_GETLINECOUNT, 0, 0 ); if ( result > SCROLLBACK_MAX_LINES ) { char replaceText[5]; replaceText[0] = '\0'; SendMessage( g_qeglobals.d_hwndEdit, WM_SETREDRAW, ( WPARAM )0, ( LPARAM )0 ); SendMessage( g_qeglobals.d_hwndEdit, EM_GETSEL, ( WPARAM )&oldPosS, ( LPARAM )&oldPosE ); SendMessage( g_qeglobals.d_hwndEdit, EM_SETSEL, 0, SCROLLBACK_DEL_CHARS ); SendMessage( g_qeglobals.d_hwndEdit, EM_REPLACESEL, ( WPARAM )0, ( LPARAM )replaceText ); SendMessage( g_qeglobals.d_hwndEdit, EM_SETSEL, oldPosS, oldPosE ); SendMessage( g_qeglobals.d_hwndEdit, WM_SETREDRAW, ( WPARAM )1, ( LPARAM )0 ); } //PGM SendMessage( g_qeglobals.d_hwndEdit, EM_REPLACESEL, 0, ( LPARAM )out ); #endif }
/* Makes the current brushhave the given number of 2d sides */ void Brush_MakeSided(int sides) { int i; vec3_t mins, maxs; brush_t *b; texdef_t *texdef; face_t *f; vec3_t mid; float width,sv,cv; if(sides < 3) { Sys_Status ("Bad sides number", 0); return; } else if(!QE_SingleBrush()) { Sys_Status ("Must have a single brush selected", 0 ); return; } b = selected_brushes.next; Math_VectorCopy(b->mins,mins); Math_VectorCopy(b->maxs,maxs); texdef = &g_qeglobals.d_texturewin.texdef; Brush_Free (b); // find center of brush width = 8; for (i=0 ; i<2 ; i++) { mid[i] = (maxs[i] + mins[i])*0.5; if (maxs[i] - mins[i] > width) width = maxs[i] - mins[i]; } width /= 2; b = qmalloc (sizeof(brush_t)); // create top face f = Face_Alloc(); f->texdef = *texdef; f->next = b->brush_faces; b->brush_faces = f; f->planepts[2][0] = mins[0];f->planepts[2][1] = mins[1];f->planepts[2][2] = maxs[2]; f->planepts[1][0] = maxs[0];f->planepts[1][1] = mins[1];f->planepts[1][2] = maxs[2]; f->planepts[0][0] = maxs[0];f->planepts[0][1] = maxs[1];f->planepts[0][2] = maxs[2]; // create bottom face f = Face_Alloc(); f->texdef = *texdef; f->next = b->brush_faces; b->brush_faces = f; f->planepts[0][0] = mins[0];f->planepts[0][1] = mins[1];f->planepts[0][2] = mins[2]; f->planepts[1][0] = maxs[0];f->planepts[1][1] = mins[1];f->planepts[1][2] = mins[2]; f->planepts[2][0] = maxs[0];f->planepts[2][1] = maxs[1];f->planepts[2][2] = mins[2]; for (i=0 ; i<sides ; i++) { f = Face_Alloc(); f->texdef = *texdef; f->next = b->brush_faces; b->brush_faces = f; sv = sin (i*3.14159265*2/sides); cv = cos (i*3.14159265*2/sides); f->planepts[0][0] = floor(mid[0]+width*cv+0.5); f->planepts[0][1] = floor(mid[1]+width*sv+0.5); f->planepts[0][2] = mins[2]; f->planepts[1][0] = f->planepts[0][0]; f->planepts[1][1] = f->planepts[0][1]; f->planepts[1][2] = maxs[2]; f->planepts[2][0] = floor(f->planepts[0][0] - width*sv + 0.5); f->planepts[2][1] = floor(f->planepts[0][1] + width*cv + 0.5); f->planepts[2][2] = maxs[2]; } Brush_AddToList (b, &selected_brushes); Entity_LinkBrush (world_entity, b); Brush_Build( b ); Sys_UpdateWindows (W_ALL); }
/* ============= 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); }
/* ============= Undo_Undo ============= */ void Undo_Undo(void) { undo_t *undo, *redo; brush_t *pBrush, *pNextBrush; entity_t *pEntity, *pNextEntity, *pUndoEntity; if (!g_lastundo) { Sys_Status("Nothing left to undo.\n"); return; } if (!g_lastundo->done) { Sys_Status("Undo_Undo: WARNING: last undo not yet finished!\n"); } // get the last undo undo = g_lastundo; if (g_lastundo->prev) g_lastundo->prev->next = NULL; else g_undolist = NULL; g_lastundo = g_lastundo->prev; //allocate a new redo redo = (undo_t *) Mem_ClearedAlloc(sizeof(undo_t), TAG_TOOLS); if (!redo) return; memset(redo, 0, sizeof(undo_t)); redo->brushlist.next = &redo->brushlist; redo->brushlist.prev = &redo->brushlist; redo->entitylist.next = &redo->entitylist; redo->entitylist.prev = &redo->entitylist; if (g_lastredo) g_lastredo->next = redo; else g_redolist = redo; redo->prev = g_lastredo; redo->next = NULL; g_lastredo = redo; redo->time = Sys_DoubleTime(); redo->id = g_redoId++; redo->done = true; redo->operation = undo->operation; //reset the redo IDs of all brushes using the new ID for (pBrush = active_brushes.next; pBrush != NULL && pBrush != &active_brushes; pBrush = pBrush->next) { if (pBrush->redoId == redo->id) { pBrush->redoId = 0; } } for (pBrush = selected_brushes.next; pBrush != NULL && pBrush != &selected_brushes; pBrush = pBrush->next) { if (pBrush->redoId == redo->id) { pBrush->redoId = 0; } } //reset the redo IDs of all entities using thew new ID for (pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pEntity->next) { if (pEntity->redoId == redo->id) { pEntity->redoId = 0; } } // remove current selection Select_Deselect(); // move "created" brushes to the redo for (pBrush = active_brushes.next; pBrush != NULL && pBrush != &active_brushes; pBrush=pNextBrush) { pNextBrush = pBrush->next; if (pBrush->undoId == undo->id) { //Brush_Free(pBrush); //move the brush to the redo Brush_RemoveFromList(pBrush); Brush_AddToList(pBrush, &redo->brushlist); //make sure the ID of the owner is stored pBrush->ownerId = pBrush->owner->entityId; //unlink the brush from the owner entity Entity_UnlinkBrush(pBrush); } } // move "created" entities to the redo for (pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pNextEntity) { pNextEntity = pEntity->next; if (pEntity->undoId == undo->id) { // check if this entity is in the undo for (pUndoEntity = undo->entitylist.next; pUndoEntity != NULL && pUndoEntity != &undo->entitylist; pUndoEntity = pUndoEntity->next) { // move brushes to the undo entity if (pUndoEntity->entityId == pEntity->entityId) { pUndoEntity->brushes.next = pEntity->brushes.next; pUndoEntity->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, &redo->entitylist); } } // add the undo entities back into the entity list for (pEntity = undo->entitylist.next; pEntity != NULL && pEntity != &undo->entitylist; pEntity = undo->entitylist.next) { g_undoMemorySize -= Entity_MemorySize(pEntity); //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); pEntity->redoId = redo->id; } } // add the undo brushes back into the selected brushes for (pBrush = undo->brushlist.next; pBrush != NULL && pBrush != &undo->brushlist; pBrush = undo->brushlist.next) { g_undoMemorySize -= Brush_MemorySize(pBrush); 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); pBrush->redoId = redo->id; } // common->Printf("%s undone.\n", undo->operation); // free the undo g_undoMemorySize -= sizeof(undo_t); Mem_Free(undo); g_undoSize--; g_undoId--; if (g_undoId <= 0) g_undoId = 2 * g_undoMaxSize; // Sys_BeginWait(); brush_t *b, *next; for (b = active_brushes.next ; b != NULL && b != &active_brushes ; b=next) { next = b->next; Brush_Build( b, true, false, false ); } for (b = selected_brushes.next ; b != NULL && b != &selected_brushes ; b=next) { next = b->next; Brush_Build( b, true, false, false ); } Sys_EndWait(); g_bScreenUpdates = true; Sys_UpdateWindows(W_ALL); }