Flat textures were loaded incorrectly in some cases.

UDMF map parser should work ~35% faster now.
Texture browser form: keyboard focus was not updated when switching between textures using Tab key.
"Graphics" folder is now checked when searching for texture patches.
Various cosmetic changes here and there.
This commit is contained in:
MaxED 2013-12-20 09:24:43 +00:00
parent ae56aad3b7
commit 0366f13c9a
20 changed files with 381 additions and 359 deletions

View file

@ -266,28 +266,13 @@ namespace CodeImp.DoomBuilder.Controls
if(list.SelectedItems.Count > 0)
{
ListViewItem selected = list.SelectedItems[0];
bool foundselected = false;
foreach(ListViewItem n in visibleitems)
{
if((n.Text == selected.Text) && foundselected)
{
// This is the next item
n.Selected = true;
n.EnsureVisible();
return;
}
if(n == selected)
foundselected = true;
}
// Start from the top
foreach(ListViewItem n in visibleitems)
{
if((n.Text == selected.Text) && foundselected)
{
// This is the next item
//mxd
foreach(ListViewItem n in visibleitems) {
if(n == selected) continue;
if(n.Text == selected.Text) {
n.Selected = true;
n.Focused = true;
n.EnsureVisible();
return;
}

View file

@ -113,7 +113,7 @@ namespace CodeImp.DoomBuilder.Data
// When implemented, this returns the patch lump
public virtual Stream GetPatchData(string pname) { return null; }
//mxd. When implemented, this returns a path to... path (like /patches/walls/WALL001.png)
//mxd. When implemented, this returns a path to patch (like /patches/walls/WALL001.png)
public virtual string GetPatchLocation(string pname) { return pname; }
// When implemented, this returns the texture lump

View file

@ -249,46 +249,55 @@ namespace CodeImp.DoomBuilder.Data
PixelColor* texturepixels = (PixelColor*)(texturebmpdata.Scan0.ToPointer());
PixelColor* tcp = texturepixels + numpixels - 1;
if(p.style == TexturePathRenderStyle.Add) {
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--) {
cp->r = (byte)Math.Min(255, (int)cp->r + (int)tcp->r);
cp->g = (byte)Math.Min(255, (int)cp->g + (int)tcp->g);
cp->b = (byte)Math.Min(255, (int)cp->b + (int)tcp->b);
cp->a = (byte)((((float)cp->a * PixelColor.BYTE_TO_FLOAT) * p.alpha) * 255.0f);
tcp--;
}
} else if(p.style == TexturePathRenderStyle.Subtract) {
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--) {
cp->r = (byte)Math.Max(0, (int)tcp->r - (int)cp->r);
cp->g = (byte)Math.Max(0, (int)tcp->g - (int)cp->g);
cp->b = (byte)Math.Max(0, (int)tcp->b - (int)cp->b);
cp->a = (byte)((((float)cp->a * PixelColor.BYTE_TO_FLOAT) * p.alpha) * 255.0f);
tcp--;
}
} else if(p.style == TexturePathRenderStyle.ReverseSubtract) {
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--) {
cp->r = (byte)Math.Max(0, (int)cp->r - (int)tcp->r);
cp->g = (byte)Math.Max(0, (int)cp->g - (int)tcp->g);
cp->b = (byte)Math.Max(0, (int)cp->b - (int)tcp->b);
cp->a = (byte)((((float)cp->a * PixelColor.BYTE_TO_FLOAT) * p.alpha) * 255.0f);
tcp--;
}
}else if(p.style == TexturePathRenderStyle.Modulate){
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--) {
float pr = (float)cp->r * PixelColor.BYTE_TO_FLOAT;
float pg = (float)cp->g * PixelColor.BYTE_TO_FLOAT;
float pb = (float)cp->b * PixelColor.BYTE_TO_FLOAT;
switch(p.style) {
case TexturePathRenderStyle.Add:
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--) {
cp->r = (byte)Math.Min(255, cp->r + tcp->r);
cp->g = (byte)Math.Min(255, cp->g + tcp->g);
cp->b = (byte)Math.Min(255, cp->b + tcp->b);
cp->a = (byte)(((cp->a * PixelColor.BYTE_TO_FLOAT) * p.alpha) * 255.0f);
tcp--;
}
break;
float tr = (float)tcp->r * PixelColor.BYTE_TO_FLOAT;
float tg = (float)tcp->g * PixelColor.BYTE_TO_FLOAT;
float tb = (float)tcp->b * PixelColor.BYTE_TO_FLOAT;
case TexturePathRenderStyle.Subtract:
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--) {
cp->r = (byte)Math.Max(0, tcp->r - cp->r);
cp->g = (byte)Math.Max(0, tcp->g - cp->g);
cp->b = (byte)Math.Max(0, tcp->b - cp->b);
cp->a = (byte)(((cp->a * PixelColor.BYTE_TO_FLOAT) * p.alpha) * 255.0f);
tcp--;
}
break;
cp->r = (byte)((pr * tr) * 255.0f);
cp->g = (byte)((pg * tg) * 255.0f);
cp->b = (byte)((pb * tb) * 255.0f);
case TexturePathRenderStyle.ReverseSubtract:
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--) {
cp->r = (byte)Math.Max(0, cp->r - tcp->r);
cp->g = (byte)Math.Max(0, cp->g - tcp->g);
cp->b = (byte)Math.Max(0, cp->b - tcp->b);
cp->a = (byte)(((cp->a * PixelColor.BYTE_TO_FLOAT) * p.alpha) * 255.0f);
tcp--;
}
break;
case TexturePathRenderStyle.Modulate:
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--) {
float pr = cp->r * PixelColor.BYTE_TO_FLOAT;
float pg = cp->g * PixelColor.BYTE_TO_FLOAT;
float pb = cp->b * PixelColor.BYTE_TO_FLOAT;
float tr = tcp->r * PixelColor.BYTE_TO_FLOAT;
float tg = tcp->g * PixelColor.BYTE_TO_FLOAT;
float tb = tcp->b * PixelColor.BYTE_TO_FLOAT;
cp->r = (byte)((pr * tr) * 255.0f);
cp->g = (byte)((pg * tg) * 255.0f);
cp->b = (byte)((pb * tb) * 255.0f);
tcp--;
}
break;
tcp--;
}
}
source.UnlockBits(texturebmpdata);

View file

@ -43,29 +43,6 @@ namespace CodeImp.DoomBuilder.Data
// This check image data and returns the appropriate image reader
public static IImageReader GetImageReader(Stream data, int guessformat, Playpal palette)
{
//mxd. Try to read it as "classic" image format first...
// Could it be a doom picture?
if(guessformat == DOOMPICTURE) {
// Check if data is valid for a doom picture
data.Seek(0, SeekOrigin.Begin);
DoomPictureReader picreader = new DoomPictureReader(palette);
if(picreader.Validate(data)) return picreader;
}
// Could it be a doom flat?
else if(guessformat == DOOMFLAT) {
// Check if data is valid for a doom flat
data.Seek(0, SeekOrigin.Begin);
DoomFlatReader flatreader = new DoomFlatReader(palette);
if(flatreader.Validate(data)) return flatreader;
}
// Could it be a doom colormap?
else if(guessformat == DOOMCOLORMAP) {
// Check if data is valid for a doom colormap
data.Seek(0, SeekOrigin.Begin);
DoomColormapReader colormapreader = new DoomColormapReader(palette);
if(colormapreader.Validate(data)) return colormapreader;
}
// Data long enough to check for signatures?
if(data.Length > 10) {
// Check for PNG signature
@ -103,6 +80,30 @@ namespace CodeImp.DoomBuilder.Data
if(CheckSignature(data, BMP_SIGNATURE))
return new UnknownImageReader(); //mxd. Not supported in (G)ZDoom
}
// Could it be a doom picture?
switch(guessformat) {
case DOOMPICTURE:
// Check if data is valid for a doom picture
data.Seek(0, SeekOrigin.Begin);
DoomPictureReader picreader = new DoomPictureReader(palette);
if(picreader.Validate(data)) return picreader;
break;
case DOOMFLAT:
// Check if data is valid for a doom flat
data.Seek(0, SeekOrigin.Begin);
DoomFlatReader flatreader = new DoomFlatReader(palette);
if(flatreader.Validate(data)) return flatreader;
break;
case DOOMCOLORMAP:
// Check if data is valid for a doom colormap
data.Seek(0, SeekOrigin.Begin);
DoomColormapReader colormapreader = new DoomColormapReader(palette);
if(colormapreader.Validate(data)) return colormapreader;
break;
}
// Format not supported
return new UnknownImageReader();

View file

@ -36,6 +36,7 @@ namespace CodeImp.DoomBuilder.Data
protected const string HIRES_DIR = "hires";
protected const string SPRITES_DIR = "sprites";
protected const string COLORMAPS_DIR = "colormaps";
protected const string GRAPHICS_DIR = "graphics"; //mxd
#endregion
@ -52,7 +53,7 @@ namespace CodeImp.DoomBuilder.Data
#region ================== Properties
protected string[] PatchLocations = { PATCHES_DIR, TEXTURES_DIR, FLATS_DIR }; //mxd. Because ZDoom looks for patches in these folders
protected string[] PatchLocations = { PATCHES_DIR, TEXTURES_DIR, FLATS_DIR, GRAPHICS_DIR }; //mxd. Because ZDoom looks for patches in these folders ///TODO: check the order of these
#endregion

View file

@ -768,16 +768,24 @@ namespace CodeImp.DoomBuilder.Editing
protected virtual void RenderMultiSelection()
{
//mxd
PixelColor marqueColor = PixelColor.Transparent;
PixelColor marqueColor;
if(marqueSelectionMode == MarqueSelectionMode.SELECT) {
marqueColor = General.Colors.Selection.WithAlpha(SELECTION_ALPHA);
} else if(marqueSelectionMode == MarqueSelectionMode.ADD) {
marqueColor = General.Colors.Highlight.WithAlpha(SELECTION_ALPHA);
} else if(marqueSelectionMode == MarqueSelectionMode.SUBTRACT) {
marqueColor = General.Colors.Selection.WithAlpha(SELECTION_ALPHA).InverseKeepAlpha();
} else { //should be Intersect
marqueColor = General.Colors.Highlight.WithAlpha(SELECTION_ALPHA).InverseKeepAlpha();
switch(marqueSelectionMode) {
case MarqueSelectionMode.SELECT:
marqueColor = General.Colors.Selection.WithAlpha(SELECTION_ALPHA);
break;
case MarqueSelectionMode.ADD:
marqueColor = General.Colors.Highlight.WithAlpha(SELECTION_ALPHA);
break;
case MarqueSelectionMode.SUBTRACT:
marqueColor = General.Colors.Selection.WithAlpha(SELECTION_ALPHA).InverseKeepAlpha();
break;
default: //should be Intersect
marqueColor = General.Colors.Highlight.WithAlpha(SELECTION_ALPHA).InverseKeepAlpha();
break;
}
renderer.RenderRectangle(selectionrect, SELECTION_BORDER_SIZE, marqueColor, true);

View file

@ -290,21 +290,21 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
if (!gotErrors) {
//general checks
if (light.Color.Red == 0.0f && light.Color.Green == 0.0f && light.Color.Blue == 0.0f) {
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": light Color is " + light.Color.Red + "," + light.Color.Green + "," + light.Color.Blue + ". It won't be shown in GZDoom!");
General.ErrorLogger.Add(ErrorType.Warning, "'" + sourcefilename + "', line " + GetCurrentLineNumber() + ": light Color is " + light.Color.Red + "," + light.Color.Green + "," + light.Color.Blue + ". It won't be shown in GZDoom!");
gotErrors = true;
}
//light-type specific checks
if (light.Type == DynamicLightType.NORMAL) {
if (light.PrimaryRadius == 0) {
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": light Size is 0. It won't be shown in GZDoom!");
General.ErrorLogger.Add(ErrorType.Warning, "'" + sourcefilename + "', line " + GetCurrentLineNumber() + ": light Size is 0. It won't be shown in GZDoom!");
gotErrors = true;
}
}
if (light.Type == DynamicLightType.FLICKER || light.Type == DynamicLightType.PULSE || light.Type == DynamicLightType.RANDOM) {
if (light.PrimaryRadius == 0 && light.SecondaryRadius == 0) {
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": 'Size' and 'SecondarySize' are 0. This light won't be shown in GZDoom!");
General.ErrorLogger.Add(ErrorType.Warning, "'" + sourcefilename + "', line " + GetCurrentLineNumber() + ": 'Size' and 'SecondarySize' are 0. This light won't be shown in GZDoom!");
gotErrors = true;
}
}
@ -417,9 +417,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
}
}
if (objects.Count > 0)
return true;
return false;
return objects.Count > 0;
}
}
}

View file

@ -667,7 +667,6 @@ namespace CodeImp.DoomBuilder.IO
// Check if string ends
case '\"':
return val;
break;
// Check for new line
case '\n':
@ -723,14 +722,11 @@ namespace CodeImp.DoomBuilder.IO
}
else
{
int ival = 0;
long lval = 0;
// Convert to int
try
{
// Convert to value
ival = System.Convert.ToInt32(val.Trim(), CultureInfo.InvariantCulture);
int ival = System.Convert.ToInt32(val.Trim(), CultureInfo.InvariantCulture);
return ival;
}
catch(System.OverflowException)
@ -739,7 +735,7 @@ namespace CodeImp.DoomBuilder.IO
try
{
// Convert to value
lval = System.Convert.ToInt64(val.Trim(), CultureInfo.InvariantCulture);
long lval = System.Convert.ToInt64(val.Trim(), CultureInfo.InvariantCulture);
return lval;
}
catch(System.OverflowException)
@ -884,7 +880,7 @@ namespace CodeImp.DoomBuilder.IO
}
else
{
RaiseError(file, line, "Include missing structure '" + args[1].ToString() + "' in file '" + includefile + "'");
RaiseError(file, line, "Include missing structure '" + args[1] + "' in file '" + includefile + "'");
return;
}
}

View file

@ -57,24 +57,15 @@ namespace CodeImp.DoomBuilder.IO
// This validates the data as doom flat
public bool Validate(Stream stream)
{
float sqrlength;
// Check if the flat is square
sqrlength = (float)Math.Sqrt(stream.Length);
float sqrlength = (float)Math.Sqrt(stream.Length);
if(sqrlength == (float)Math.Truncate(sqrlength))
{
// Success when not 0
return ((int)sqrlength > 0);
}
// Check if the data is more than 4096
else if(stream.Length > 4096)
{
// Success
return true;
}
// Format invalid
return false;
// Valid if the data is more than 4096
return stream.Length > 4096;
}
// This creates a Bitmap from the given data

View file

@ -155,10 +155,8 @@ namespace CodeImp.DoomBuilder.IO
// This copies lump data to another lump
internal void CopyTo(Lump lump)
{
BinaryReader reader;
// Create a reader
reader = new BinaryReader(stream);
BinaryReader reader = new BinaryReader(stream);
// Copy bytes over
stream.Seek(0, SeekOrigin.Begin);

View file

@ -20,7 +20,6 @@ using System;
using System.IO;
using System.Text;
using System.Globalization;
using System.Collections;
using System.Collections.Generic;
#endregion
@ -61,11 +60,18 @@ namespace CodeImp.DoomBuilder.IO
private int cpErrorResult = 0;
private string cpErrorDescription = "";
private int cpErrorLine = 0;
private char[] newline = new[]{'\n'}; //mxd
// Configuration root
private UniversalCollection root = null;
private const string numbers = "0123456789";
private const string numbers2 = "0123456789-.&";
private const string newline = "\n";
private char[] newlineChar = new[] {'\n'};
private StringBuilder key; //mxd
private StringBuilder val; //mxd
private Dictionary<string, UniversalEntry> matches; //mxd
// Settings
private bool strictchecking = true;
@ -113,7 +119,7 @@ namespace CodeImp.DoomBuilder.IO
{
// Replace the \ with \\ first!
str = str.Replace("\\", "\\\\");
str = str.Replace("\n", "\\n");
str = str.Replace(newline, "\\n");
str = str.Replace("\r", "\\r");
str = str.Replace("\t", "\\t");
str = str.Replace("\"", "\\\"");
@ -146,21 +152,17 @@ namespace CodeImp.DoomBuilder.IO
if(errorline > -1) RaiseError(errorline, ERROR_KEYMISSING);
validateresult = false;
}
else
else if(strictchecking) //Only when strict checking
{
// Only when strict checking
if(strictchecking)
// Check if all characters are valid
foreach(char c in key)
{
// Check if all characters are valid
foreach(char c in key)
if(KEY_CHARACTERS.IndexOf(c) == -1)
{
if(KEY_CHARACTERS.IndexOf(c) == -1)
{
// ERROR: Invalid characters in key name
if(errorline > -1) RaiseError(errorline, ERROR_KEYCHARACTERS);
validateresult = false;
break;
}
// ERROR: Invalid characters in key name
if(errorline > -1) RaiseError(errorline, ERROR_KEYCHARACTERS);
validateresult = false;
break;
}
}
}
@ -172,11 +174,13 @@ namespace CodeImp.DoomBuilder.IO
// This parses a structure in the given data starting
// from the given pos and line and updates pos and line.
private UniversalCollection InputStructure(ref string data, ref int pos, ref int line)
private UniversalCollection InputStructure(ref string[] data, ref int pos, ref int line, bool topLevel)
{
char c = '\0'; // current data character
int pm = PM_NOTHING; // current parse mode
string key = "", val = ""; // current key and value beign built
key.Remove(0, key.Length);
val.Remove(0, val.Length);
string s;
bool escape = false; // escape sequence?
bool endofstruct = false; // true as soon as this level struct ends
UniversalCollection cs = new UniversalCollection();
@ -184,10 +188,16 @@ namespace CodeImp.DoomBuilder.IO
// Go through all of the data until
// the end or until the struct closes
// or when an arror occurred
while ((pos < data.Length) && (cpErrorResult == 0) && (endofstruct == false))
while ((cpErrorResult == 0) && (endofstruct == false))
{
// Get current character
c = data[pos];
if(line == data.Length - 1) break;
if(pos > data[line].Length - 1) {
pos = 0;
line++;
}
c = data[line][pos];
// ================ What parse mode are we at?
if(pm == PM_NOTHING)
@ -196,28 +206,27 @@ namespace CodeImp.DoomBuilder.IO
switch(c)
{
case '{': // Begin of new struct
// Validate key
if(ValidateKey(key.Trim(), line))
s = key.ToString().Trim();
if(ValidateKey(s, line))
{
// Next character
pos++;
// Parse this struct and add it
cs.Add(new UniversalEntry(key.Trim(), InputStructure(ref data, ref pos, ref line)));
cs.Add(new UniversalEntry(s.ToLowerInvariant(), InputStructure(ref data, ref pos, ref line, false)));
// Check the last character
pos--;
// Reset the key
key = "";
key.Remove(0, key.Length);
}
// Leave switch
break;
case '}': // End of this struct
// Stop parsing in this struct
endofstruct = true;
@ -225,9 +234,8 @@ namespace CodeImp.DoomBuilder.IO
break;
case '=': // Assignment
// Validate key
if(ValidateKey(key.Trim(), line))
if(ValidateKey(key.ToString().Trim(), line))
{
// Now parsing assignment
pm = PM_ASSIGNMENT;
@ -239,7 +247,7 @@ namespace CodeImp.DoomBuilder.IO
case ';': // Terminator
// Validate key
if(ValidateKey(key.Trim(), line))
if(ValidateKey(key.ToString().Trim(), line))
{
// Error: No value
RaiseError(line, ERROR_KEYWITHOUTVALUE);
@ -249,35 +257,31 @@ namespace CodeImp.DoomBuilder.IO
break;
case '\n': // New line
// Count the line
line++;
pos = -1;
// Add this to the key as a space.
// Spaces are not allowed, but it will be trimmed
// when its the first or last character.
key += " ";
key.Append(" ");
// Leave switch
break;
case '\\': // Possible comment
case '/':
// Check for the line comment //
if(data.Substring(pos, 2) == "//")
if(data[line].Substring(pos, 2) == "//")
{
// Find the next line
int np = data.IndexOf("\n", pos);
// Next line found?
if(np > -1)
// Have next line?
if(line < data.Length)
{
// Count the line
line++;
// Skip everything on this line
pos = np;
pos = -1;
}
else
{
@ -287,17 +291,17 @@ namespace CodeImp.DoomBuilder.IO
}
}
// Check for the block comment /* */
else if(data.Substring(pos, 2) == "/*")
else if(data[line].Substring(pos, 2) == "/*")
{
// Find the next closing block comment
int np = data.IndexOf("*/", pos);
int np = data[line].IndexOf("*/", pos);
// Closing block comment found?
if(np > -1)
{
// Count the lines in the block comment
string blockdata = data.Substring(pos, np - pos + 2);
line += (blockdata.Split(newline).Length - 1);
string blockdata = data[line].Substring(pos, np - pos + 2);
line += (blockdata.Split(newlineChar).Length - 1);
// Skip everything in this block
pos = np + 1;
@ -314,10 +318,17 @@ namespace CodeImp.DoomBuilder.IO
break;
default: // Everything else
if (!topLevel && pos == 0) {
while(matches.ContainsKey(data[line])) {
cs.Add(matches[data[line]].Key, matches[data[line]].Value);
line++;
pos = -1;
}
}
// Add character to key
key += c.ToString(CultureInfo.InvariantCulture).ToLowerInvariant();
if(pos != -1) key.Append(c);
// Leave switch
break;
}
@ -329,10 +340,10 @@ namespace CodeImp.DoomBuilder.IO
if(c == '\"')
{
// Now parsing string
pm = PM_STRING;
pm = PM_STRING; //numbers
}
// Check for numeric character
else if(Configuration.NUMBERS2.IndexOf(c.ToString(CultureInfo.InvariantCulture)) > -1)
// Check for numeric character numbers
else if(numbers2.IndexOf(c) > -1)
{
// Now parsing number
pm = PM_NUMBER;
@ -354,8 +365,8 @@ namespace CodeImp.DoomBuilder.IO
pm = PM_NOTHING;
// Remove this if it causes problems
key = "";
val = "";
key.Remove(0, key.Length);
val.Remove(0, val.Length);
}
// Otherwise (if not whitespace) it will be a keyword
else if((c != ' ') && (c != '\t'))
@ -375,19 +386,19 @@ namespace CodeImp.DoomBuilder.IO
if(c == ';')
{
// Hexadecimal?
if((val.Length > 2) && val.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase))
s = val.ToString();
if((s.Length > 2) && s.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase))
{
int ival = 0;
long lval = 0;
// Convert to int
try
{
// Convert to value
ival = System.Convert.ToInt32(val.Substring(2).Trim(), 16);
int ival = System.Convert.ToInt32(s.Substring(2).Trim(), 16);
// Add it to struct
cs.Add(new UniversalEntry(key.Trim(), ival));
UniversalEntry entry = new UniversalEntry(key.ToString().Trim().ToLowerInvariant(), ival);
cs.Add(entry);
matches.Add(data[line], entry);
}
catch(System.OverflowException)
{
@ -395,10 +406,12 @@ namespace CodeImp.DoomBuilder.IO
try
{
// Convert to value
lval = System.Convert.ToInt64(val.Substring(2).Trim(), 16);
long lval = System.Convert.ToInt64(s.Substring(2).Trim(), 16);
// Add it to struct
cs.Add(new UniversalEntry(key.Trim(), lval));
UniversalEntry entry = new UniversalEntry(key.ToString().Trim().ToLowerInvariant(), lval);
cs.Add(entry);
matches.Add(data[line], entry);
}
catch(System.OverflowException)
{
@ -418,12 +431,12 @@ namespace CodeImp.DoomBuilder.IO
}
}
// Floating point?
else if(val.IndexOf(".") > -1)
else if(s.IndexOf('.') > -1)
{
float fval = 0;
// Convert to float (remove the f first)
try { fval = System.Convert.ToSingle(val.Trim(), CultureInfo.InvariantCulture); }
try { fval = System.Convert.ToSingle(s.Trim(), CultureInfo.InvariantCulture); }
catch(System.FormatException)
{
// ERROR: Invalid value in assignment
@ -431,21 +444,22 @@ namespace CodeImp.DoomBuilder.IO
}
// Add it to struct
cs.Add(new UniversalEntry(key.Trim(), fval));
UniversalEntry entry = new UniversalEntry(key.ToString().Trim().ToLowerInvariant(), fval);
cs.Add(entry);
matches.Add(data[line], entry);
}
else
{
int ival = 0;
long lval = 0;
// Convert to int
try
{
// Convert to value
ival = System.Convert.ToInt32(val.Trim(), CultureInfo.InvariantCulture);
int ival = System.Convert.ToInt32(s.Trim(), CultureInfo.InvariantCulture);
// Add it to struct
cs.Add(new UniversalEntry(key.Trim(), ival));
UniversalEntry entry = new UniversalEntry(key.ToString().Trim().ToLowerInvariant(), ival);
cs.Add(entry);
matches.Add(data[line], entry);
}
catch(System.OverflowException)
{
@ -453,10 +467,12 @@ namespace CodeImp.DoomBuilder.IO
try
{
// Convert to value
lval = System.Convert.ToInt64(val.Trim(), CultureInfo.InvariantCulture);
long lval = System.Convert.ToInt64(s.Trim(), CultureInfo.InvariantCulture);
// Add it to struct
cs.Add(new UniversalEntry(key.Trim(), lval));
UniversalEntry entry = new UniversalEntry(key.ToString().Trim().ToLowerInvariant(), lval);
cs.Add(entry);
matches.Add(data[line], entry);
}
catch(System.OverflowException)
{
@ -477,8 +493,8 @@ namespace CodeImp.DoomBuilder.IO
}
// Reset key and value
key = "";
val = "";
key.Remove(0, key.Length);
val.Remove(0, val.Length);
// End of assignment
pm = PM_NOTHING;
@ -488,11 +504,12 @@ namespace CodeImp.DoomBuilder.IO
{
// Count the new line
line++;
pos = -1;
}
// Everything else is part of the value
else
{
val += c.ToString(CultureInfo.InvariantCulture);
val.Append(c);
}
}
// ================ Parsing a string
@ -504,21 +521,20 @@ namespace CodeImp.DoomBuilder.IO
// What character?
switch(c)
{
case '\\': val += "\\"; break;
case 'n': val += "\n"; break;
case '\"': val += "\""; break;
case 'r': val += "\r"; break;
case 't': val += "\t"; break;
case '\\': val.Append('\\'); break;
case 'n': val.Append(newline); break;
case '\"': val.Append('\"'); break;
case 'r': val.Append('\r'); break;
case 't': val.Append('\t'); break;
default:
// Is it a number?
if(Configuration.NUMBERS.IndexOf(c.ToString(CultureInfo.InvariantCulture)) > -1)
if(numbers.IndexOf(c) > -1)
{
int vv = 0;
char vc = '0';
// Convert the next 3 characters to a number
string v = data.Substring(pos, 3);
string v = data[line].Substring(pos, 3);
try { vv = System.Convert.ToInt32(v.Trim(), CultureInfo.InvariantCulture); }
catch(System.FormatException)
{
@ -535,12 +551,12 @@ namespace CodeImp.DoomBuilder.IO
}
// Add the char
val += vc.ToString(CultureInfo.InvariantCulture);
val.Append(vc);
}
else
{
// Add the character as it is
val += c.ToString(CultureInfo.InvariantCulture);
val.Append(c);
}
// Leave switch
@ -562,26 +578,29 @@ namespace CodeImp.DoomBuilder.IO
else if(c == '\"')
{
// Add string to struct
cs.Add(new UniversalEntry(key.Trim(), val));
UniversalEntry entry = new UniversalEntry(key.ToString().Trim().ToLowerInvariant(), val.ToString());
cs.Add(entry);
matches.Add(data[line], entry);
// End of assignment
pm = PM_ASSIGNMENT;
// Reset key and value
key = "";
val = "";
key.Remove(0, key.Length);
val.Remove(0, val.Length);
}
// Check for new line
else if(c == '\n')
{
// Count the new line
line++;
pos = -1;
}
// Everything else is just part of string
else
{
// Add to value
val += c.ToString(CultureInfo.InvariantCulture);
val.Append(c);
}
}
}
@ -592,24 +611,25 @@ namespace CodeImp.DoomBuilder.IO
if(c == ';')
{
// Add to the struct depending on the keyword
switch(val.Trim().ToLowerInvariant())
switch(val.ToString().Trim().ToLowerInvariant())
{
case "true":
// Add boolean true
cs.Add(new UniversalEntry(key.Trim(), true));
UniversalEntry t = new UniversalEntry(key.ToString().Trim().ToLowerInvariant(), true);
cs.Add(t);
matches.Add(data[line], t);
break;
case "false":
// Add boolean false
cs.Add(new UniversalEntry(key.Trim(), false));
UniversalEntry f = new UniversalEntry(key.ToString().Trim().ToLowerInvariant(), false);
cs.Add(f);
matches.Add(data[line], f);
break;
default:
// Unknown keyword
RaiseError(line, ERROR_KEYWORDUNKNOWN + "\nUnrecognized token: '" + val.Trim().ToLowerInvariant() + "'");
RaiseError(line, ERROR_KEYWORDUNKNOWN + "\nUnrecognized token: '" + val.ToString().Trim().ToLowerInvariant() + "'");
break;
}
@ -617,20 +637,21 @@ namespace CodeImp.DoomBuilder.IO
pm = PM_NOTHING;
// Reset key and value
key = "";
val = "";
key.Remove(0, key.Length);
val.Remove(0, val.Length);
}
// Check for new line
else if(c == '\n')
{
// Count the new line
line++;
pos = -1;
}
// Everything else is just part of keyword
else
{
// Add to value
val += c.ToString(CultureInfo.InvariantCulture);
val.Append(c);
}
}
@ -691,8 +712,8 @@ namespace CodeImp.DoomBuilder.IO
// Check if the value is of boolean type
else if(de.Current.Value is bool)
{
db.Append(leveltabs).Append(de.Current.Key).Append(spacing).Append("=").Append(spacing);
db.Append((bool)de.Current.Value ? "true;" : "false;").Append(newline);
db.Append(leveltabs); db.Append(de.Current.Key); db.Append(spacing); db.Append("="); db.Append(spacing);
db.Append((bool)de.Current.Value ? "true;" : "false;"); db.Append(newline);
}
// Check if value is of float type
else if(de.Current.Value is float)
@ -750,7 +771,7 @@ namespace CodeImp.DoomBuilder.IO
public bool SaveConfiguration(string filename, string newline, bool whitespace)
{
// Kill the file if it exists
if(File.Exists(filename) == true) File.Delete(filename);
if(File.Exists(filename)) File.Delete(filename);
// Open file stream for writing
FileStream fstream = File.OpenWrite(filename);
@ -781,42 +802,49 @@ namespace CodeImp.DoomBuilder.IO
public bool LoadConfiguration(string filename)
{
// Check if the file is missing
if(File.Exists(filename) == false)
if(!File.Exists(filename))
{
throw(new FileNotFoundException("File not found \"" + filename + "\"", filename));
}
else
{
// Load the file contents
FileStream fstream = File.OpenRead(filename);
byte[] fbuffer = new byte[fstream.Length];
fstream.Read(fbuffer, 0, fbuffer.Length);
fstream.Close();
// Convert byte array to string
string data = Encoding.ASCII.GetString(fbuffer);
List<string> data = new List<string>(100);
using(FileStream stream = File.OpenRead(filename)) {
StreamReader reader = new StreamReader(stream, Encoding.ASCII);
while(!reader.EndOfStream) {
string line = reader.ReadLine();
if(string.IsNullOrEmpty(line)) continue;
// Remove returns and tabs because the
// parser only uses newline for new lines.
line = line.Replace("\r", "");
line = line.Replace("\t", "");
data.Add(line);
}
}
// Load the configuration from this data
return InputConfiguration(data);
return InputConfiguration(data.ToArray());
}
}
// This will load a configuration from string
public bool InputConfiguration(string data)
public bool InputConfiguration(string[] data)
{
// Remove returns and tabs because the
// parser only uses newline for new lines.
data = data.Replace("\r", "");
data = data.Replace("\t", "");
// Clear errors
ClearError();
// Parse the data to the root structure
int pos = 0;
int line = 1;
root = InputStructure(ref data, ref pos, ref line);
matches = new Dictionary<string, UniversalEntry>(); //mxd
key = new StringBuilder(16); //mxd
val = new StringBuilder(16); //mxd
root = InputStructure(ref data, ref pos, ref line, true);
// Return true when done, false when errors occurred
if(cpErrorResult == 0) return true; else return false;

View file

@ -141,7 +141,20 @@ namespace CodeImp.DoomBuilder.IO
try
{
// Read UDMF from stream
textmap.InputConfiguration(reader.ReadToEnd());
List<string> data = new List<string>(100);
while(!reader.EndOfStream) {
string line = reader.ReadLine();
if(string.IsNullOrEmpty(line)) continue;
// Remove returns and tabs because the
// parser only uses newline for new lines.
line = line.Replace("\r", "");
line = line.Replace("\t", "");
data.Add(line);
}
textmap.InputConfiguration(data.ToArray());
// Check for errors
if(textmap.ErrorResult != 0)

View file

@ -88,15 +88,14 @@ namespace CodeImp.DoomBuilder.Rendering
// This loads an effect
protected Effect LoadEffect(string fxfile)
{
Effect fx;
string errors;
Stream fxdata;
// Return null when not using shaders
if(!manager.Enabled) return null;
Effect fx;
string errors;
// Load the resource
fxdata = General.ThisAssembly.GetManifestResourceStream("CodeImp.DoomBuilder.Resources." + fxfile);
Stream fxdata = General.ThisAssembly.GetManifestResourceStream("CodeImp.DoomBuilder.Resources." + fxfile);
fxdata.Seek(0, SeekOrigin.Begin);
try

View file

@ -111,10 +111,8 @@ namespace CodeImp.DoomBuilder.Rendering
// Load resources
public void ReloadResource()
{
Capabilities caps;
// Check if we can use shaders
caps = General.Map.Graphics.Device.Capabilities;
Capabilities caps = General.Map.Graphics.Device.Capabilities;
useshaders = (caps.PixelShaderVersion.Major >= 2);
shadertechnique = "SM20";

View file

@ -55,23 +55,19 @@ namespace CodeImp.DoomBuilder.Types
// Find the thing with this class name
foreach(ThingTypeInfo t in General.Map.Data.ThingTypes)
{
if((t.Actor != null) && (string.Compare(t.Actor.ClassName, value, true) == 0))
if((string.Compare(t.ClassName, value, true) == 0)) //mxd
{
tid = t.Index;
break;
}
}
//tid = ThingBrowserForm.BrowseThing(parent, tid);
ThingBrowserForm f = new ThingBrowserForm(tid);
if(f.ShowDialog(Form.ActiveForm) == DialogResult.OK)
if(f.ShowDialog(Form.ActiveForm) == DialogResult.OK)
{
// Find the class name for this thing
ThingTypeInfo t = General.Map.Data.GetThingInfo(f.SelectedType);
if(t.Actor != null)
this.value = t.Actor.ClassName;
else
this.value = "";
this.value = !string.IsNullOrEmpty(t.ClassName) ? t.ClassName : ""; //mxd
}
f.Dispose();

View file

@ -17,7 +17,6 @@
#region ================== Namespaces
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;
using CodeImp.DoomBuilder.Windows;
@ -47,7 +46,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
#region ================== Enums
private enum ModifyMode : int
private enum ModifyMode
{
None,
Dragging,
@ -55,7 +54,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
Rotating
}
private enum Grip : int
private enum Grip
{
None,
Main,
@ -84,8 +83,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Variables
// Modes
private bool modealreadyswitching = false;
private bool pasting = false;
private bool modealreadyswitching;
private bool pasting;
private PasteOptions pasteoptions;
// Docker
@ -240,7 +239,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
// This returns the position of the highlighted item
private Vector2D GetHighlightedPosition()
/*private Vector2D GetHighlightedPosition()
{
if(highlighted is Vertex)
return (highlighted as Vertex).Position;
@ -248,7 +247,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
return (highlighted as Thing).Position;
else
throw new Exception("Highlighted element type is not supported.");
}
}*/
// This highlights a new vertex
protected void Highlight(MapElement h)
@ -538,7 +537,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
for(int i = 0; i < 8; i++)
{
// Make the vectors
float angle = (float)i * Angle2D.PI * 0.25f;
float angle = i * Angle2D.PI * 0.25f;
Vector2D gridvec = Vector2D.FromAngle(angle);
Vector3D rotvec = Vector2D.FromAngle(rotation);
@ -646,7 +645,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// This checks if a point is in a rect
private bool PointInRectF(RectangleF rect, Vector2D point)
{
return (point.x >= rect.Left) && (point.x <= rect.Right) && (point.y >= rect.Top) && (point.y <= rect.Bottom);
return !(point.x < rect.Left || point.x > rect.Right || point.y < rect.Top || point.y > rect.Bottom); //mxd
}
// This updates the values in the panel
@ -658,7 +657,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
// This moves all things and vertices to match the current transformation
private unsafe void UpdateGeometry()
private void UpdateGeometry()
{
float[] newthingangle = thingangle.ToArray();
int index;
@ -1107,7 +1106,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// If we're in the process of switching to another mode, reset to selection
// to its old position
if (modealreadyswitching == true)
if (modealreadyswitching)
{
// Reset geometry in original position
int index = 0;
@ -1173,10 +1172,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Go for all sidedes in the new geometry
List<Sidedef> newsides = General.Map.Map.GetMarkedSidedefs(true);
for(int i = 0; i < newsides.Count; i++)
{
Sidedef s = newsides[i];
foreach (Sidedef s in newsides) {
// Connected to a virtual sector?
if(s.Marked && s.Sector.Fields.ContainsKey(MapSet.VirtualSectorField))
{

View file

@ -17,7 +17,6 @@
#region ================== Namespaces
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;
using CodeImp.DoomBuilder.Windows;
@ -667,7 +666,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// This is called wheh selection ends
protected override void OnEndMultiSelection()
{
bool selectionvolume = ((Math.Abs(base.selectionrect.Width) > 0.1f) && (Math.Abs(base.selectionrect.Height) > 0.1f));
bool selectionvolume = ((Math.Abs(selectionrect.Width) > 0.1f) && (Math.Abs(selectionrect.Height) > 0.1f));
if(selectionvolume)
{
@ -679,22 +678,26 @@ namespace CodeImp.DoomBuilder.BuilderModes
};
//mxd
if(marqueSelectionMode == MarqueSelectionMode.SELECT) {
// Go for all lines
foreach(Linedef l in General.Map.Map.Linedefs)
l.Selected = isInSelectionRect(l, selectionOutline);
} else if(marqueSelectionMode == MarqueSelectionMode.ADD) {
// Go for all lines
foreach(Linedef l in General.Map.Map.Linedefs)
l.Selected |= isInSelectionRect(l, selectionOutline);
} else if(marqueSelectionMode == MarqueSelectionMode.SUBTRACT) {
// Go for all lines
foreach (Linedef l in General.Map.Map.Linedefs)
if(isInSelectionRect(l, selectionOutline)) l.Selected = false;
} else { //should be Intersect
// Go for the eyes, Boo! Go for the eyes!
foreach(Linedef l in General.Map.Map.Linedefs)
if(!isInSelectionRect(l, selectionOutline)) l.Selected = false;
switch(marqueSelectionMode) {
case MarqueSelectionMode.SELECT:
foreach(Linedef l in General.Map.Map.Linedefs)
l.Selected = isInSelectionRect(l, selectionOutline);
break;
case MarqueSelectionMode.ADD:
foreach(Linedef l in General.Map.Map.Linedefs)
l.Selected |= isInSelectionRect(l, selectionOutline);
break;
case MarqueSelectionMode.SUBTRACT:
foreach(Linedef l in General.Map.Map.Linedefs)
if(isInSelectionRect(l, selectionOutline)) l.Selected = false;
break;
default:
foreach(Linedef l in General.Map.Map.Linedefs)
if(!isInSelectionRect(l, selectionOutline)) l.Selected = false;
break;
}
//mxd
@ -758,10 +761,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(General.Map.Map.SelectedLinedefsCount > 0)
sel = General.Map.Map.GetSelectedLinedefs(true);
else if(highlighted != null)
{
sel = new List<Linedef>();
sel.Add(highlighted);
}
sel = new List<Linedef> {highlighted};
if(sel != null)
{

View file

@ -1049,31 +1049,39 @@ namespace CodeImp.DoomBuilder.BuilderModes
};
//mxd. collect changed sectors
if(marqueSelectionMode == MarqueSelectionMode.SELECT){
bool select;
foreach (Sector s in General.Map.Map.Sectors) {
select = isInSelectionRect(s, selectionOutline);
switch(marqueSelectionMode) {
case MarqueSelectionMode.SELECT:
bool select;
foreach(Sector s in General.Map.Map.Sectors) {
select = isInSelectionRect(s, selectionOutline);
if(select && !s.Selected) SelectSector(s, true, false);
else if(!select && s.Selected) SelectSector(s, false, false);
}
}else if(marqueSelectionMode == MarqueSelectionMode.ADD) { //additive selection
foreach(Sector s in General.Map.Map.Sectors) {
if(!s.Selected && isInSelectionRect(s, selectionOutline))
SelectSector(s, true, false);
}
} else if(marqueSelectionMode == MarqueSelectionMode.SUBTRACT) {
foreach(Sector s in General.Map.Map.Sectors) {
if(!s.Selected) continue;
if(isInSelectionRect(s, selectionOutline))
SelectSector(s, false, false);
}
} else { //should be Intersect
foreach(Sector s in General.Map.Map.Sectors) {
if(!s.Selected) continue;
if(!isInSelectionRect(s, selectionOutline))
SelectSector(s, false, false);
}
if(select && !s.Selected) SelectSector(s, true, false);
else if(!select && s.Selected) SelectSector(s, false, false);
}
break;
case MarqueSelectionMode.ADD:
foreach(Sector s in General.Map.Map.Sectors) {
if(!s.Selected && isInSelectionRect(s, selectionOutline))
SelectSector(s, true, false);
}
break;
case MarqueSelectionMode.SUBTRACT:
foreach(Sector s in General.Map.Map.Sectors) {
if(!s.Selected) continue;
if(isInSelectionRect(s, selectionOutline))
SelectSector(s, false, false);
}
break;
default: //should be Intersect
foreach(Sector s in General.Map.Map.Sectors) {
if(!s.Selected) continue;
if(!isInSelectionRect(s, selectionOutline))
SelectSector(s, false, false);
}
break;
}
// Make sure all linedefs reflect selected sectors
@ -1186,10 +1194,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(General.Map.Map.SelectedSectorsCount > 0)
sel = General.Map.Map.GetSelectedSectors(true);
else if(highlighted != null)
{
sel = new List<Sector>();
sel.Add(highlighted);
}
sel = new List<Sector> {highlighted};
if(sel != null)
{

View file

@ -17,7 +17,6 @@
#region ================== Namespaces
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;
using CodeImp.DoomBuilder.Windows;
@ -562,27 +561,31 @@ namespace CodeImp.DoomBuilder.BuilderModes
// This is called wheh selection ends
protected override void OnEndMultiSelection()
{
bool selectionvolume = ((Math.Abs(base.selectionrect.Width) > 0.1f) && (Math.Abs(base.selectionrect.Height) > 0.1f));
bool selectionvolume = ((Math.Abs(selectionrect.Width) > 0.1f) && (Math.Abs(selectionrect.Height) > 0.1f));
if(selectionvolume)
{
//mxd
if(marqueSelectionMode == MarqueSelectionMode.SELECT) {
// Go for all vertices
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
t.Selected = selectionrect.Contains(t.Position.x, t.Position.y);
} else if(marqueSelectionMode == MarqueSelectionMode.ADD) {
// Go for all vertices
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
t.Selected |= selectionrect.Contains(t.Position.x, t.Position.y);
} else if(marqueSelectionMode == MarqueSelectionMode.SUBTRACT) {
// Go for all vertices
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
if(selectionrect.Contains(t.Position.x, t.Position.y)) t.Selected = false;
} else { //should be Intersect
// Go for all vertices
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
if(!selectionrect.Contains(t.Position.x, t.Position.y)) t.Selected = false;
switch(marqueSelectionMode) {
case MarqueSelectionMode.SELECT:
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
t.Selected = selectionrect.Contains(t.Position.x, t.Position.y);
break;
case MarqueSelectionMode.ADD:
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
t.Selected |= selectionrect.Contains(t.Position.x, t.Position.y);
break;
case MarqueSelectionMode.SUBTRACT:
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
if(selectionrect.Contains(t.Position.x, t.Position.y)) t.Selected = false;
break;
default: //should be Intersect
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
if(!selectionrect.Contains(t.Position.x, t.Position.y)) t.Selected = false;
break;
}
updateSelectionInfo(); //mxd
@ -674,10 +677,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(General.Map.Map.SelectedThingsCount > 0)
sel = General.Map.Map.GetSelectedThings(true);
else if(highlighted != null)
{
sel = new List<Thing>();
sel.Add(highlighted);
}
sel = new List<Thing> {highlighted};
if(sel != null)
{
@ -892,7 +892,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
foreach(Thing t in toAlign) {
List<Linedef> excludedLines = new List<Linedef>();
bool aligned = false;
bool aligned;
do{
Linedef l = General.Map.Map.NearestLinedef(t.Position, excludedLines);

View file

@ -17,7 +17,6 @@
#region ================== Namespaces
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;
using CodeImp.DoomBuilder.Windows;
@ -572,27 +571,31 @@ namespace CodeImp.DoomBuilder.BuilderModes
// This is called wheh selection ends
protected override void OnEndMultiSelection()
{
bool selectionvolume = ((Math.Abs(base.selectionrect.Width) > 0.1f) && (Math.Abs(base.selectionrect.Height) > 0.1f));
bool selectionvolume = ((Math.Abs(selectionrect.Width) > 0.1f) && (Math.Abs(selectionrect.Height) > 0.1f));
if(selectionvolume)
{
//mxd
if(marqueSelectionMode == MarqueSelectionMode.SELECT) {
// Go for all vertices
foreach(Vertex v in General.Map.Map.Vertices)
v.Selected = selectionrect.Contains(v.Position.x, v.Position.y);
} else if(marqueSelectionMode == MarqueSelectionMode.ADD) {
// Go for all vertices
foreach(Vertex v in General.Map.Map.Vertices)
v.Selected |= selectionrect.Contains(v.Position.x, v.Position.y);
} else if(marqueSelectionMode == MarqueSelectionMode.SUBTRACT) {
// Go for all vertices
foreach(Vertex v in General.Map.Map.Vertices)
if(selectionrect.Contains(v.Position.x, v.Position.y)) v.Selected = false;
} else { //should be Intersect
// Go for all vertices
foreach(Vertex v in General.Map.Map.Vertices)
if(!selectionrect.Contains(v.Position.x, v.Position.y)) v.Selected = false;
switch(marqueSelectionMode) {
case MarqueSelectionMode.SELECT:
foreach(Vertex v in General.Map.Map.Vertices)
v.Selected = selectionrect.Contains(v.Position.x, v.Position.y);
break;
case MarqueSelectionMode.ADD:
foreach(Vertex v in General.Map.Map.Vertices)
v.Selected |= selectionrect.Contains(v.Position.x, v.Position.y);
break;
case MarqueSelectionMode.SUBTRACT:
foreach(Vertex v in General.Map.Map.Vertices)
if(selectionrect.Contains(v.Position.x, v.Position.y)) v.Selected = false;
break;
default: //should be Intersect
foreach(Vertex v in General.Map.Map.Vertices)
if(!selectionrect.Contains(v.Position.x, v.Position.y)) v.Selected = false;
break;
}
//mxd
@ -685,10 +688,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(General.Map.Map.SelectedVerticessCount > 0)
sel = General.Map.Map.GetSelectedVertices(true);
else if(highlighted != null)
{
sel = new List<Vertex>();
sel.Add(highlighted);
}
sel = new List<Vertex> {highlighted};
if(sel != null)
{