for (unsigned int j = 0; j < portals.node[i].portal_count; j++) {
for (unsigned int k = 0; k < portals.node[i].portal[j].point_count - 2; k++) {
- vec3_t v1, v2, normal, n;
+ vec3_t v1{}, v2{}, normal{}, n{};
VectorSubtract(portals.node[i].portal[j].point[k + 2].p, portals.node[i].portal[j].point[k + 1].p, v1);
VectorSubtract(portals.node[i].portal[j].point[k].p, portals.node[i].portal[j].point[k + 1].p, v2);
CrossProduct(v1, v2, n);
c += length;
switch ( len ) /* all the case statements fall through */
{
- case 11: c += ( ( ub4 ) UB1Traits::as_ub1( k[10] ) << 24 );
- case 10: c += ( ( ub4 ) UB1Traits::as_ub1( k[9] ) << 16 );
- case 9: c += ( ( ub4 ) UB1Traits::as_ub1( k[8] ) << 8 );
+ case 11: c += ( ( ub4 ) UB1Traits::as_ub1( k[10] ) << 24 ); __attribute((fallthrough));
+ case 10: c += ( ( ub4 ) UB1Traits::as_ub1( k[9] ) << 16 ); __attribute((fallthrough));
+ case 9: c += ( ( ub4 ) UB1Traits::as_ub1( k[8] ) << 8 ); __attribute((fallthrough));
/* the first byte of c is reserved for the length */
- case 8: b += ( ( ub4 ) UB1Traits::as_ub1( k[7] ) << 24 );
- case 7: b += ( ( ub4 ) UB1Traits::as_ub1( k[6] ) << 16 );
- case 6: b += ( ( ub4 ) UB1Traits::as_ub1( k[5] ) << 8 );
- case 5: b += UB1Traits::as_ub1( k[4] );
- case 4: a += ( ( ub4 ) UB1Traits::as_ub1( k[3] ) << 24 );
- case 3: a += ( ( ub4 ) UB1Traits::as_ub1( k[2] ) << 16 );
- case 2: a += ( ( ub4 ) UB1Traits::as_ub1( k[1] ) << 8 );
+ case 8: b += ( ( ub4 ) UB1Traits::as_ub1( k[7] ) << 24 ); __attribute((fallthrough));
+ case 7: b += ( ( ub4 ) UB1Traits::as_ub1( k[6] ) << 16 ); __attribute((fallthrough));
+ case 6: b += ( ( ub4 ) UB1Traits::as_ub1( k[5] ) << 8 ); __attribute((fallthrough));
+ case 5: b += UB1Traits::as_ub1( k[4] ); __attribute((fallthrough));
+ case 4: a += ( ( ub4 ) UB1Traits::as_ub1( k[3] ) << 24 ); __attribute((fallthrough));
+ case 3: a += ( ( ub4 ) UB1Traits::as_ub1( k[2] ) << 16 ); __attribute((fallthrough));
+ case 2: a += ( ( ub4 ) UB1Traits::as_ub1( k[1] ) << 8 ); __attribute((fallthrough));
case 1: a += UB1Traits::as_ub1( k[0] );
/* case 0: nothing left to add */
}
if (g_Layout_enableDetachableMenus.m_value) {
menu_tearoff(menu_in_menu);
}
- create_menu_item_with_mnemonic(menu_in_menu, "Make _Hollow", "CSGHollow");
+ create_menu_item_with_mnemonic(menu_in_menu, "Make _Hollow", "CSGMakeHollow");
+ create_menu_item_with_mnemonic(menu_in_menu, "Make _Room", "CSGMakeRoom");
create_menu_item_with_mnemonic(menu_in_menu, "CSG _Subtract", "CSGSubtract");
create_menu_item_with_mnemonic(menu_in_menu, "CSG _Merge", "CSGMerge");
}
}
}
+void Face_makeRoom(Face &face, const Brush &brush, brush_vector_t &out, float offset)
+{
+ if (face.contributes()) {
+ face.getPlane().offset(offset);
+ out.push_back(new Brush(brush));
+ face.getPlane().offset(-offset);
+ Face *newFace = out.back()->addFace(face);
+ if (newFace != 0) {
+ newFace->flipWinding();
+ newFace->planeChanged();
+ }
+ }
+}
+
void Brush_makeHollow(const Brush &brush, brush_vector_t &out, float offset)
{
Brush_forEachFace(brush, [&](Face &face) {
});
}
+void Brush_makeRoom(const Brush &brush, brush_vector_t &out, float offset)
+{
+ Brush_forEachFace(brush, [&](Face &face) {
+ Face_makeRoom(face, brush, out, offset);
+ });
+}
+
class BrushHollowSelectedWalker : public scene::Graph::Walker {
float m_offset;
+ bool m_makeRoom;
public:
- BrushHollowSelectedWalker(float offset)
- : m_offset(offset)
+ BrushHollowSelectedWalker(float offset, bool makeRoom)
+ : m_offset(offset), m_makeRoom(makeRoom)
{
}
&& Instance_getSelectable(instance)->isSelected()
&& path.size() > 1) {
brush_vector_t out;
- Brush_makeHollow(*brush, out, m_offset);
+
+ if (m_makeRoom) {
+ Brush_makeRoom(*brush, out, m_offset);
+ }
+ else {
+ Brush_makeHollow(*brush, out, m_offset);
+ }
+
for (brush_vector_t::const_iterator i = out.begin(); i != out.end(); ++i) {
(*i)->removeEmptyFaces();
NodeSmartReference node((new BrushNode())->node());
}
};
-void Scene_BrushMakeHollow_Selected(scene::Graph &graph)
+void Scene_BrushMakeHollow_Selected(scene::Graph &graph, bool makeRoom)
{
- GlobalSceneGraph().traverse(BrushHollowSelectedWalker(GetGridSize()));
+ GlobalSceneGraph().traverse(BrushHollowSelectedWalker(GetGridSize(), makeRoom));
GlobalSceneGraph().traverse(BrushDeleteSelected());
}
{
UndoableCommand undo("brushHollow");
- Scene_BrushMakeHollow_Selected(GlobalSceneGraph());
+ Scene_BrushMakeHollow_Selected(GlobalSceneGraph(), false);
+
+ SceneChangeNotify();
+}
+
+void CSG_MakeRoom(void)
+{
+ UndoableCommand undo("brushRoom");
+
+ Scene_BrushMakeHollow_Selected(GlobalSceneGraph(), true);
SceneChangeNotify();
}
void CSG_MakeHollow(void);
+void CSG_MakeRoom(void);
+
void CSG_Subtract(void);
void CSG_Merge(void);
{
toolbar_append_button(toolbar, "CSG Subtract (SHIFT + U)", "selection_csgsubtract.png", "CSGSubtract");
toolbar_append_button(toolbar, "CSG Merge (CTRL + U)", "selection_csgmerge.png", "CSGMerge");
- toolbar_append_button(toolbar, "Hollow", "selection_makehollow.png", "CSGHollow");
+ toolbar_append_button(toolbar, "Make Hollow", "selection_makehollow.png", "CSGMakeHollow");
+ toolbar_append_button(toolbar, "Make Room", "selection_makeroom.png", "CSGMakeRoom");
}
void ComponentModes_constructToolbar(ui::Toolbar toolbar)
GlobalCommands_insert("CSGSubtract", makeCallbackF(CSG_Subtract),
Accelerator('U', (GdkModifierType) GDK_SHIFT_MASK));
GlobalCommands_insert("CSGMerge", makeCallbackF(CSG_Merge), Accelerator('U', (GdkModifierType) GDK_CONTROL_MASK));
- GlobalCommands_insert("CSGHollow", makeCallbackF(CSG_MakeHollow));
+ GlobalCommands_insert("CSGMakeHollow", makeCallbackF(CSG_MakeHollow));
+ GlobalCommands_insert("CSGMakeRoom", makeCallbackF(CSG_MakeRoom));
Grid_registerCommands();
switch (alphafunc) {
case IShader::eAlways:
state.m_alphafunc = GL_ALWAYS;
+ break;
case IShader::eEqual:
state.m_alphafunc = GL_EQUAL;
+ break;
case IShader::eLess:
state.m_alphafunc = GL_LESS;
+ break;
case IShader::eGreater:
state.m_alphafunc = GL_GREATER;
+ break;
case IShader::eLEqual:
state.m_alphafunc = GL_LEQUAL;
+ break;
case IShader::eGEqual:
state.m_alphafunc = GL_GEQUAL;
+ break;
}
}
reinterpret_cast<Vector3 &>( state.m_colour ) = m_shader->getTexture()->color;
*/
#include "globaldefs.h"
+#include <stdint.h>
#if !GDEF_OS_WINDOWS
// The below define is necessary to use
// pthreads extensions like pthread_mutexattr_settype
{"-fs_game <gamename>", "Sets a different game directory name (default for Q3A: baseq3, can be used more than once)"},
{"-fs_homebase <dir>", "Specifies where the user home directory name is on Linux (default for Q3A: .q3a)"},
{"-fs_homepath <path>", "Sets the given path as home directory name"},
- {"-fs_nobasepath", "Do not load base paths in VFS"},
+ {"-fs_nobasepath", "Do not load base paths in VFS, imply -fs_nomagicpath"},
+ {"-fs_nomagicpath", "Do not try to guess base path magically"},
{"-fs_nohomepath", "Do not load home path in VFS"},
{"-fs_pakpath <path>", "Specify a package directory (can be used more than once to look in multiple paths)"},
{"-game <gamename>", "Load settings for the given game (default: quake3)"},
int noBasePath = 0;
int noHomePath = 0;
+ int noMagicPath = 0;
/* note it */
Sys_FPrintf( SYS_VRB, "--- InitPaths ---\n" );
/* -fs_nobasepath */
else if ( strcmp( argv[ i ], "-fs_nobasepath" ) == 0 ) {
noBasePath = 1;
+ // we don't want any basepath, neither guessed ones
+ noMagicPath = 1;
argv[ i ] = NULL;
}
+ /* -fs_nomagicpath */
+ else if ( strcmp( argv[ i ], "-fs_nomagicpath") == 0) {
+ noMagicPath = 1;
+ argv[ i ] = NULL;
+ }
+
/* -fs_basepath */
else if ( strcmp( argv[ i ], "-fs_basepath" ) == 0 ) {
if ( ++i >= *argc ) {
AddPakPath( argv[ i ] );
argv[ i ] = NULL;
}
-
}
/* remove processed arguments */
/* add standard game path */
AddGamePath( game->gamePath );
- /* if there is no base path set, figure it out */
- if ( numBasePaths == 0 && noBasePath == 0 ) {
+ /* if there is no base path set, figure it out unless fs_nomagicpath is set */
+ if ( numBasePaths == 0 && noBasePath == 0 && noMagicPath == 0 ) {
/* this is another crappy replacement for SetQdirFromPath() */
len2 = strlen( game->magic );
for ( i = 0; i < *argc && numBasePaths == 0; i++ )
}
+#define snprintf_ignore(s, n, format, ...) do { \
+ size_t __n = snprintf(s, n, format, __VA_ARGS__); \
+ if (n >= n) {} /* truncated, ignore */ \
+} while (0)
/*
GetIndexedShader() - ydnar
/* make a shader name */
if ( minShaderIndex == maxShaderIndex ) {
- sprintf( shader, "textures/%s_%d", im->shader, maxShaderIndex );
+ snprintf_ignore( shader, sizeof shader, "textures/%s_%d", im->shader, maxShaderIndex );
}
else{
- sprintf( shader, "textures/%s_%dto%d", im->shader, minShaderIndex, maxShaderIndex );
+ snprintf_ignore( shader, sizeof shader, "textures/%s_%dto%d", im->shader, minShaderIndex, maxShaderIndex );
}
/* get the shader */
/* ydnar: sky hack/fix for GL_CLAMP borders on ati cards */
if ( skyFixHack && si->skyParmsImageBase[ 0 ] != '\0' ) {
//% Sys_FPrintf( SYS_VRB, "Enabling sky hack for shader %s using env %s\n", si->shader, si->skyParmsImageBase );
- sprintf( tempShader, "%s_lf", si->skyParmsImageBase );
+ snprintf_ignore( tempShader, sizeof tempShader, "%s_lf", si->skyParmsImageBase );
DrawSurfaceForShader( tempShader );
- sprintf( tempShader, "%s_rt", si->skyParmsImageBase );
+ snprintf_ignore( tempShader, sizeof tempShader, "%s_rt", si->skyParmsImageBase );
DrawSurfaceForShader( tempShader );
- sprintf( tempShader, "%s_ft", si->skyParmsImageBase );
+ snprintf_ignore( tempShader, sizeof tempShader, "%s_ft", si->skyParmsImageBase );
DrawSurfaceForShader( tempShader );
- sprintf( tempShader, "%s_bk", si->skyParmsImageBase );
+ snprintf_ignore( tempShader, sizeof tempShader, "%s_bk", si->skyParmsImageBase );
DrawSurfaceForShader( tempShader );
- sprintf( tempShader, "%s_up", si->skyParmsImageBase );
+ snprintf_ignore( tempShader, sizeof tempShader, "%s_up", si->skyParmsImageBase );
DrawSurfaceForShader( tempShader );
- sprintf( tempShader, "%s_dn", si->skyParmsImageBase );
+ snprintf_ignore( tempShader, sizeof tempShader, "%s_dn", si->skyParmsImageBase );
DrawSurfaceForShader( tempShader );
}