├── .gitattributes
├── .gitignore
├── App.config
├── Bloom.cs
├── Client.cs
├── ClientEffect.cs
├── ClientEntity.cs
├── ClientMain.cs
├── ClientParse.cs
├── ClientView.cs
├── Common.cs
├── Config.cs
├── Content
├── Q2BSPContent.contentproj
├── SpriteFont1.spritefont
├── bloom.fx
├── blur.fx
├── effects20.fx
├── effects30.fx
├── generic.fx
├── skins.fx
└── textures.fx
├── Files.cs
├── Game.ico
├── GameThumbnail.png
├── Gamma.cs
├── Image.cs
├── Input.cs
├── Library
├── Command.cs
├── Script.cs
└── TargaImage.cs
├── Light.cs
├── Local.cs
├── Main.cs
├── Model.cs
├── PointLight.cs
├── Program.cs
├── Properties
└── AssemblyInfo.cs
├── Q2BSP.cs
├── Q2BSP.csproj
├── Q2BSP.sln
├── Q2Game.cs
├── Q2MD2.cs
├── Server.cs
├── Shared.cs
├── Sky.cs
└── Surface.cs
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Eclipse
3 | #################
4 |
5 | *.pydevproject
6 | .project
7 | .metadata
8 | bin/
9 | tmp/
10 | *.tmp
11 | *.bak
12 | *.swp
13 | *~.nib
14 | local.properties
15 | .classpath
16 | .settings/
17 | .loadpath
18 |
19 | # External tool builders
20 | .externalToolBuilders/
21 |
22 | # Locally stored "Eclipse launch configurations"
23 | *.launch
24 |
25 | # CDT-specific
26 | .cproject
27 |
28 | # PDT-specific
29 | .buildpath
30 |
31 |
32 | #################
33 | ## Visual Studio
34 | #################
35 |
36 | ## Ignore Visual Studio temporary files, build results, and
37 | ## files generated by popular Visual Studio add-ons.
38 |
39 | # User-specific files
40 | *.suo
41 | *.user
42 | *.sln.docstates
43 |
44 | # Build results
45 |
46 | [Dd]ebug/
47 | [Rr]elease/
48 | x64/
49 | build/
50 | [Bb]in/
51 | [Oo]bj/
52 |
53 | # MSTest test Results
54 | [Tt]est[Rr]esult*/
55 | [Bb]uild[Ll]og.*
56 |
57 | *_i.c
58 | *_p.c
59 | *.ilk
60 | *.meta
61 | *.obj
62 | *.pch
63 | *.pdb
64 | *.pgc
65 | *.pgd
66 | *.rsp
67 | *.sbr
68 | *.tlb
69 | *.tli
70 | *.tlh
71 | *.tmp
72 | *.tmp_proj
73 | *.log
74 | *.vspscc
75 | *.vssscc
76 | .builds
77 | *.pidb
78 | *.log
79 | *.scc
80 |
81 | # Visual C++ cache files
82 | ipch/
83 | *.aps
84 | *.ncb
85 | *.opensdf
86 | *.sdf
87 | *.cachefile
88 |
89 | # Visual Studio profiler
90 | *.psess
91 | *.vsp
92 | *.vspx
93 |
94 | # Guidance Automation Toolkit
95 | *.gpState
96 |
97 | # ReSharper is a .NET coding add-in
98 | _ReSharper*/
99 | *.[Rr]e[Ss]harper
100 |
101 | # TeamCity is a build add-in
102 | _TeamCity*
103 |
104 | # DotCover is a Code Coverage Tool
105 | *.dotCover
106 |
107 | # NCrunch
108 | *.ncrunch*
109 | .*crunch*.local.xml
110 |
111 | # Installshield output folder
112 | [Ee]xpress/
113 |
114 | # DocProject is a documentation generator add-in
115 | DocProject/buildhelp/
116 | DocProject/Help/*.HxT
117 | DocProject/Help/*.HxC
118 | DocProject/Help/*.hhc
119 | DocProject/Help/*.hhk
120 | DocProject/Help/*.hhp
121 | DocProject/Help/Html2
122 | DocProject/Help/html
123 |
124 | # Click-Once directory
125 | publish/
126 |
127 | # Publish Web Output
128 | *.Publish.xml
129 | *.pubxml
130 |
131 | # NuGet Packages Directory
132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
133 | #packages/
134 |
135 | # Windows Azure Build Output
136 | csx
137 | *.build.csdef
138 |
139 | # Windows Store app package directory
140 | AppPackages/
141 |
142 | # Others
143 | sql/
144 | *.Cache
145 | ClientBin/
146 | [Ss]tyle[Cc]op.*
147 | ~$*
148 | *~
149 | *.dbmdl
150 | *.[Pp]ublish.xml
151 | *.pfx
152 | *.publishsettings
153 |
154 | # RIA/Silverlight projects
155 | Generated_Code/
156 |
157 | # Backup & report files from converting an old project file to a newer
158 | # Visual Studio version. Backup files are not needed, because we have git ;-)
159 | _UpgradeReport_Files/
160 | Backup*/
161 | UpgradeLog*.XML
162 | UpgradeLog*.htm
163 |
164 | # SQL Server files
165 | App_Data/*.mdf
166 | App_Data/*.ldf
167 |
168 | #############
169 | ## Windows detritus
170 | #############
171 |
172 | # Windows image file caches
173 | Thumbs.db
174 | ehthumbs.db
175 |
176 | # Folder config file
177 | Desktop.ini
178 |
179 | # Recycle Bin used on file shares
180 | $RECYCLE.BIN/
181 |
182 | # Mac crap
183 | .DS_Store
184 |
185 |
186 | #############
187 | ## Python
188 | #############
189 |
190 | *.py[co]
191 |
192 | # Packages
193 | *.egg
194 | *.egg-info
195 | dist/
196 | build/
197 | eggs/
198 | parts/
199 | var/
200 | sdist/
201 | develop-eggs/
202 | .installed.cfg
203 |
204 | # Installer logs
205 | pip-log.txt
206 |
207 | # Unit test / coverage reports
208 | .coverage
209 | .tox
210 |
211 | #Translations
212 | *.mo
213 |
214 | #Mr Developer
215 | .mr.developer.cfg
216 |
--------------------------------------------------------------------------------
/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
105 |
--------------------------------------------------------------------------------
/Bloom.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using Microsoft.Xna.Framework;
30 | using Microsoft.Xna.Framework.Graphics;
31 | using System.Text;
32 |
33 | namespace Q2BSP
34 | {
35 | public class CBloom
36 | {
37 | public int BlurAmount;
38 | private SpriteBatch spriteBatch;
39 |
40 | private RenderTarget2D RenderTargetScene;
41 | private RenderTarget2D RenderTarget1;
42 | private RenderTarget2D RenderTarget2;
43 |
44 | ///
45 | /// Setup
46 | /// -----
47 | /// Create the render targets used by the bloom postprocess
48 | ///
49 | public void Setup()
50 | {
51 | int Width;
52 | int Height;
53 | SurfaceFormat Format;
54 |
55 | // get the resolution and format of our main backbuffer
56 | PresentationParameters pp = CProgram.gQ2Game.gGraphicsDevice.PresentationParameters;
57 |
58 | Width = pp.BackBufferWidth;
59 | Height = pp.BackBufferHeight;
60 | Format = pp.BackBufferFormat;
61 |
62 | // create a texture for rendering the main scene, prior to applying bloom.
63 | RenderTargetScene = new RenderTarget2D(CProgram.gQ2Game.gGraphicsDevice, Width, Height, false, Format, pp.DepthStencilFormat, pp.MultiSampleCount, RenderTargetUsage.DiscardContents);
64 |
65 | // create two render targets for bloom processing half the size of the backbuffer
66 | Width /= 2;
67 | Height /= 2;
68 | RenderTarget1 = new RenderTarget2D(CProgram.gQ2Game.gGraphicsDevice, Width, Height);
69 | RenderTarget2 = new RenderTarget2D(CProgram.gQ2Game.gGraphicsDevice, Width, Height);
70 |
71 | BlurAmount = 4;
72 | spriteBatch = new SpriteBatch(CProgram.gQ2Game.gGraphicsDevice);
73 | }
74 |
75 | ///
76 | /// DrawBloom
77 | /// ---------
78 | /// This should be called at the very start of the scene rendering. The bloom component uses it to redirect drawing into its custom rendertarget,
79 | /// so it can capture the scene image in preparation for applying the bloom filter.
80 | ///
81 | public void DrawBloom()
82 | {
83 | if (CProgram.gQ2Game.gCMain.r_bloom == false)
84 | return;
85 |
86 | if (CProgram.gQ2Game.gCMain.r_wireframe == true)
87 | return;
88 |
89 | CProgram.gQ2Game.gGraphicsDevice.SetRenderTarget(RenderTargetScene);
90 | }
91 |
92 | ///
93 | /// Draw
94 | /// ----
95 | /// Process and draw the bloom postprocess
96 | ///
97 | public void Draw()
98 | {
99 | if (CProgram.gQ2Game.gCMain.r_bloom == false)
100 | return;
101 |
102 | if (CProgram.gQ2Game.gCMain.r_wireframe == true)
103 | return;
104 |
105 | CProgram.gQ2Game.gGraphicsDevice.SamplerStates[1] = SamplerState.LinearClamp;
106 |
107 |
108 | // pass 1
109 | // draw the scene into render target 1, using a shader that extracts only the brightest pixels
110 | DrawQuad(RenderTargetScene, RenderTarget1, "BloomExtract", IntermediateBuffer.PreBloom);
111 |
112 |
113 | // pass 2
114 | // draw from render target 1 into render target 2, applying a horizontal gaussian blur filter
115 | SetBlurEffectParameters(1.0f / (float)RenderTarget1.Width, 0.0f);
116 | DrawQuad(RenderTarget1, RenderTarget2, "GaussianBlur", IntermediateBuffer.BlurredHorizontally);
117 |
118 |
119 | // pass 3
120 | // draw from render target 2 back into render target 1, applying a vertical gaussian blur filter
121 | SetBlurEffectParameters(0.0f, 1.0f / (float)RenderTarget1.Height);
122 | DrawQuad(RenderTarget2, RenderTarget1, "GaussianBlur", IntermediateBuffer.BlurredBothWays);
123 |
124 |
125 | // pass 4
126 | // draw both render target 1 and the original scene texture back into the backbuffer
127 | // using a shader that combines them to produce the final bloomed result
128 | CProgram.gQ2Game.gGraphicsDevice.SetRenderTarget(null);
129 | CProgram.gQ2Game.gGraphicsDevice.Textures[1] = RenderTargetScene;
130 |
131 |
132 | CProgram.gQ2Game.gGraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1.0f, 0);
133 | DrawQuad(RenderTarget1, CProgram.gQ2Game.gGraphicsDevice.Viewport.Width, CProgram.gQ2Game.gGraphicsDevice.Viewport.Height, "BloomCombine", IntermediateBuffer.FinalResult);
134 | }
135 |
136 | private void DrawQuad(Texture2D texture, RenderTarget2D RenderTarget, string Technique, IntermediateBuffer currentBuffer)
137 | {
138 | CProgram.gQ2Game.gGraphicsDevice.SetRenderTarget(RenderTarget);
139 | DrawQuad(texture, RenderTarget.Width, RenderTarget.Height, Technique, currentBuffer);
140 | CProgram.gQ2Game.gGraphicsDevice.SetRenderTarget(null);
141 | }
142 |
143 | private void DrawQuad(Texture2D texture, int Width, int Height, string Technique, IntermediateBuffer currentBuffer)
144 | {
145 | // if the user has selected one of the show intermediate buffer options, we still draw the quad to make sure the image will end up on the screen,
146 | // but might need to skip applying the custom pixel shader.
147 | if (IntermediateBuffer.FinalResult < currentBuffer)
148 | CProgram.gQ2Game.gEffect = null;
149 | else
150 | CProgram.gQ2Game.gEffect.CurrentTechnique = CProgram.gQ2Game.gEffect.Techniques[Technique];
151 |
152 | spriteBatch.Begin(0, BlendState.Opaque, null, null, null, CProgram.gQ2Game.gEffect);
153 | spriteBatch.Draw(texture, new Rectangle(0, 0, Width, Height), Color.White);
154 | spriteBatch.End();
155 | }
156 |
157 | ///
158 | /// SetBlurEffectParameters
159 | /// -----------------------
160 | /// Computes sample weightings and texture coordinate offsets
161 | /// for one pass of a separable gaussian blur filter
162 | ///
163 | private void SetBlurEffectParameters(float dx, float dy)
164 | {
165 | EffectParameter weightsParameter;
166 | EffectParameter offsetsParameter;
167 | int sampleCount;
168 | float[] sampleWeights;
169 | Vector2[] sampleOffsets;
170 | float totalWeights;
171 |
172 | // get the sample weight and offset effect parameters
173 | weightsParameter = CProgram.gQ2Game.gEffect.Parameters["SampleWeights"];
174 | offsetsParameter = CProgram.gQ2Game.gEffect.Parameters["SampleOffsets"];
175 |
176 | // get the amount of samples our gaussian blur effect supports
177 | sampleCount = weightsParameter.Elements.Count;
178 |
179 | // create temporary arrays for computing our filter settings
180 | sampleWeights = new float[sampleCount];
181 | sampleOffsets = new Vector2[sampleCount];
182 |
183 | // the first sample always has a zero offset
184 | sampleWeights[0] = ComputeGaussian(0, BlurAmount);
185 | sampleOffsets[0] = new Vector2(0);
186 |
187 | // maintain a sum of all the weighting values
188 | totalWeights = sampleWeights[0];
189 |
190 | // add pairs of additional sample taps, positioned along a line in both directions from the center
191 | for (int i = 0; i < sampleCount / 2; i++)
192 | {
193 | float weight;
194 | float sampleOffset;
195 | Vector2 delta;
196 |
197 | // store weights for the positive and negative taps
198 | weight = ComputeGaussian(i + 1, BlurAmount);
199 | sampleWeights[i * 2 + 1] = weight;
200 | sampleWeights[i * 2 + 2] = weight;
201 | totalWeights += weight * 2;
202 |
203 | // To get the maximum amount of blurring from a limited number of pixel shader samples,
204 | // we take advantage of the bilinear filtering hardware inside the texture fetch unit.
205 | // If we position our texture coordinates exactly halfway between two texels, the filtering
206 | // unit will average them for us, giving two samples for the price of one.
207 | // This allows us to step in units of two texels per sample, rather than just one at a time.
208 | // The 1.5 offset kicks things off by positioning us nicely in between two texels.
209 | sampleOffset = i * 2 + 1.5f;
210 |
211 | delta = new Vector2(dx, dy) * sampleOffset;
212 |
213 | // store texture coordinate offsets for the positive and negative taps
214 | sampleOffsets[i * 2 + 1] = delta;
215 | sampleOffsets[i * 2 + 2] = -delta;
216 | }
217 |
218 | // normalize the list of sample weightings, so they will always sum to one
219 | for (int i = 0; i < sampleWeights.Length; i++)
220 | {
221 | sampleWeights[i] /= totalWeights;
222 | }
223 |
224 | // tell the effect about our new filter settings
225 | weightsParameter.SetValue(sampleWeights);
226 | offsetsParameter.SetValue(sampleOffsets);
227 | }
228 |
229 | ///
230 | /// Evaluates a single point on the gaussian falloff curve.
231 | /// Used for setting up the blur filter weightings.
232 | ///
233 | private float ComputeGaussian(float n, float theta)
234 | {
235 | return (float)((1.0d / Math.Sqrt(2 * Math.PI * theta)) * Math.Exp(-(n * n) / (2 * theta * theta)));
236 | }
237 |
238 | ///
239 | /// Release
240 | /// -------
241 | /// De-allocate the render targets used by the bloom postprocess
242 | ///
243 | public void Release()
244 | {
245 | if (RenderTargetScene != null)
246 | RenderTargetScene.Dispose();
247 |
248 | if (RenderTarget1 != null)
249 | RenderTarget1.Dispose();
250 |
251 | if (RenderTarget2 != null)
252 | RenderTarget2.Dispose();
253 | }
254 |
255 |
256 | public enum IntermediateBuffer
257 | {
258 | PreBloom,
259 | BlurredHorizontally,
260 | BlurredBothWays,
261 | FinalResult,
262 | }
263 |
264 | }
265 | }
266 |
--------------------------------------------------------------------------------
/Client.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using Microsoft.Xna.Framework;
30 | using System.Text;
31 |
32 | namespace Q2BSP
33 | {
34 | public class CClient
35 | {
36 | public const int CMD_BACKUP = 64; // allow a lot of command backups for very fast systems
37 |
38 | public static SClientState cl;
39 |
40 |
41 | // the SClientState structure is wiped completely at every server map change
42 | public struct SClientState
43 | {
44 | public int timeoutcount;
45 |
46 | public int timedemo_frames;
47 | public int timedemo_start;
48 |
49 | public bool refresh_prepped; // false if on new level or new ref dll
50 | public bool sound_prepped; // ambient sounds can start
51 | public bool force_refdef; // vid has changed, so we can't use a paused refdef
52 |
53 | public int parse_entities; // index (not anded off) into cl_parse_entities[]
54 |
55 | //usercmd_t cmd;
56 | //usercmd_t cmds[CMD_BACKUP]; // each mesage will send several old cmds
57 | public int[] cmd_time; // size: CMD_BACKUP (time sent, for calculating pings)
58 | public short[,] predicted_origins; // size: [CMD_BACKUP, 3] (for debug comparing against server)
59 |
60 | public float predicted_step; // for stair up smoothing
61 | public uint predicted_step_time;
62 |
63 | public Vector3 predicted_origin; // generated by CL_PredictMovement
64 | public Vector3 predicted_angles;
65 | public Vector3 prediction_error;
66 |
67 | //frame_t frame; // received from server
68 | public int surpressCount; // number of messages rate supressed
69 | //frame_t frames[UPDATE_BACKUP];
70 |
71 | // the client maintains its own idea of view angles, which are sent to the server each frame.
72 | // It is cleared to 0 upon entering each level. The server sends a delta each frame which is added to the
73 | // locally tracked view angles to account for standing on rotating objects, and teleport direction changes
74 | public Vector3 viewangles;
75 |
76 | public int time; // this is the time value that the client is rendering at. Always <= cls.realtime
77 | public int lerpfrac; // between oldframe and frame
78 |
79 | public CLocal.SRefDef RefDef;
80 |
81 | // set when refdef.angles is set
82 | public Vector3 v_forward;
83 | public Vector3 v_right;
84 | public Vector3 v_up;
85 |
86 | //
87 | // transient data from server
88 | //
89 | public string layout; // size: 1024 (general 2D overlay)
90 | public int[] inventory; // size: MAX_ITEMS
91 |
92 | //
93 | // non-gameserver information
94 | // FIXME: move this cinematic stuff into the cin_t structure
95 | //FILE *cinematic_file;
96 | public int cinematictime; // cls.realtime for first cinematic frame
97 | public int cinematicframe;
98 | public byte[] cinematicpalette; // size: 768
99 | public bool cinematicpalette_active;
100 |
101 |
102 | //
103 | // server state information
104 | //
105 | public bool attractloop; // running the attract loop, any key will menu
106 | public int servercount; // server identification for prespawns
107 | public string gamedir; // size: MAX_QPATH
108 | public int playernum;
109 | public string[] configstrings; // size: [MAX_CONFIGSTRINGS,MAX_QPATH]
110 |
111 |
112 | //
113 | // locally derived information from server state
114 | //
115 | //struct model_s *model_draw[MAX_MODELS];
116 | //struct cmodel_s *model_clip[MAX_MODELS];
117 |
118 | //struct sfx_s *sound_precache[MAX_SOUNDS];
119 | //struct image_s *image_precache[MAX_IMAGES];
120 |
121 | //clientinfo_t clientinfo[MAX_CLIENTS];
122 | //clientinfo_t baseclientinfo;
123 | }
124 |
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/ClientEffect.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using System.Text;
30 |
31 | namespace Q2BSP
32 | {
33 | public class CClientEffect
34 | {
35 | // ==============================================================
36 | //
37 | // LIGHT STYLE MANAGEMENT
38 | //
39 | // ==============================================================
40 | public SCLightStyle[] cl_lightstyle;
41 | public int lastofs;
42 |
43 | public CClientEffect()
44 | {
45 | cl_lightstyle = new SCLightStyle[CLocal.MAX_LIGHTSTYLES];
46 |
47 | for (int i = 0; i < CLocal.MAX_LIGHTSTYLES; i++)
48 | {
49 | cl_lightstyle[i].length = 0;
50 | cl_lightstyle[i].value = new float[3];
51 | cl_lightstyle[i].map = new float[CShared.MAX_QPATH];
52 | }
53 | }
54 |
55 | public void CL_ClearLightStyles()
56 | {
57 | for (int i = 0; i < cl_lightstyle.Length; i++)
58 | {
59 | cl_lightstyle[i].length = 0;
60 |
61 | for (int j = 0; j < cl_lightstyle[i].value.Length; j++)
62 | {
63 | cl_lightstyle[i].value[j] = 0.0f;
64 | }
65 |
66 | for (int j = 0; j < cl_lightstyle[i].map.Length; j++)
67 | {
68 | cl_lightstyle[i].map[j] = 0.0f;
69 | }
70 | }
71 |
72 | lastofs = -1;
73 | }
74 |
75 | public void CL_RunLightStyles()
76 | {
77 | int ofs;
78 |
79 | ofs = (int)(CProgram.gQ2Game.gCMain.gTimeGame.TotalGameTime.TotalMilliseconds / 1000.0f);
80 | if (ofs == lastofs)
81 | return;
82 |
83 | lastofs = ofs;
84 |
85 | for (int i = 0; i < CLocal.MAX_LIGHTSTYLES; i++)
86 | {
87 | if (cl_lightstyle[i].length == 0)
88 | {
89 | cl_lightstyle[i].value[0] = cl_lightstyle[i].value[1] = cl_lightstyle[i].value[2] = 1.0f;
90 | continue;
91 | }
92 |
93 | if (cl_lightstyle[i].length == 1)
94 | cl_lightstyle[i].value[0] = cl_lightstyle[i].value[1] = cl_lightstyle[i].value[2] = cl_lightstyle[i].map[0];
95 | else
96 | cl_lightstyle[i].value[0] = cl_lightstyle[i].value[1] = cl_lightstyle[i].value[2] = cl_lightstyle[i].map[ofs % cl_lightstyle[i].length];
97 | }
98 | }
99 |
100 | public void CL_SetLightstyle(int i)
101 | {
102 | int len;
103 | string s;
104 |
105 | s = CClient.cl.configstrings[CShared.CS_LIGHTS + i];
106 | len = s.Length;
107 |
108 | if (len >= CShared.MAX_QPATH)
109 | CMain.Error(CMain.EErrorParm.ERR_WARNING, "svc_lightstyle length=" + len.ToString());
110 |
111 | cl_lightstyle[i].length = len;
112 |
113 | for (int j = 0; j < len; j++)
114 | {
115 | cl_lightstyle[i].map[j] = (float)(s[j] - 'a') / (float)('m' - 'a');
116 | }
117 | }
118 |
119 | public void CL_AddLightStyles()
120 | {
121 | for (int i = 0; i < CLocal.MAX_LIGHTSTYLES; i++)
122 | {
123 | CProgram.gQ2Game.gCCommon.gCClientMain.gCClientView.V_AddLightStyle(i, cl_lightstyle[i].value[0], cl_lightstyle[i].value[1], cl_lightstyle[i].value[2]);
124 | }
125 | }
126 |
127 | public void CL_ClearEffects()
128 | {
129 | CL_ClearLightStyles();
130 | }
131 |
132 | public struct SCLightStyle
133 | {
134 | public int length;
135 | public float[] value; // size: 3
136 | public float[] map; // size: MAX_QPATH
137 | }
138 |
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/ClientEntity.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using System.Text;
30 |
31 | namespace Q2BSP
32 | {
33 | public class CClientEntity
34 | {
35 | public void CL_AddEntities()
36 | {
37 | CProgram.gQ2Game.gCCommon.gCClientMain.gCClientEffect.CL_AddLightStyles();
38 | }
39 |
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/ClientMain.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using System.Text;
30 |
31 | namespace Q2BSP
32 | {
33 | public class CClientMain
34 | {
35 | public CClientParse gCClientParse;
36 | public CClientEffect gCClientEffect;
37 | public CClientView gCClientView;
38 | public CClientEntity gCClientEntity;
39 |
40 | public CClientMain()
41 | {
42 | gCClientParse = new CClientParse();
43 | gCClientEffect = new CClientEffect();
44 | gCClientView = new CClientView();
45 | gCClientEntity = new CClientEntity();
46 |
47 |
48 |
49 | // TEMPORARY! (SHOULD BE IN SP_WORLDSPAWN)
50 | if (CClient.cl.configstrings == null)
51 | CClient.cl.configstrings = new string[CShared.MAX_CONFIGSTRINGS];
52 |
53 | // setup light animation tables. 'a' is total darkness, 'z' is doublebright.
54 |
55 | // 0 normal
56 | CClient.cl.configstrings[CShared.CS_LIGHTS + 0] = "m";
57 |
58 | // 1 FLICKER (first variety)
59 | CClient.cl.configstrings[CShared.CS_LIGHTS + 1] = "mmnmmommommnonmmonqnmmo";
60 |
61 | // 2 SLOW STRONG PULSE
62 | CClient.cl.configstrings[CShared.CS_LIGHTS + 2] = "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba";
63 |
64 | // 3 CANDLE (first variety)
65 | CClient.cl.configstrings[CShared.CS_LIGHTS + 3] = "mmmmmaaaaammmmmaaaaaabcdefgabcdefg";
66 |
67 | // 4 FAST STROBE
68 | CClient.cl.configstrings[CShared.CS_LIGHTS + 4] = "mamamamamama";
69 |
70 | // 5 GENTLE PULSE 1
71 | CClient.cl.configstrings[CShared.CS_LIGHTS + 5] = "jklmnopqrstuvwxyzyxwvutsrqponmlkj";
72 |
73 | // 6 FLICKER (second variety)
74 | CClient.cl.configstrings[CShared.CS_LIGHTS + 6] = "nmonqnmomnmomomno";
75 |
76 | // 7 CANDLE (second variety)
77 | CClient.cl.configstrings[CShared.CS_LIGHTS + 7] = "mmmaaaabcdefgmmmmaaaammmaamm";
78 |
79 | // 8 CANDLE (third variety)
80 | CClient.cl.configstrings[CShared.CS_LIGHTS + 8] = "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa";
81 |
82 | // 9 SLOW STROBE (fourth variety)
83 | CClient.cl.configstrings[CShared.CS_LIGHTS + 9] = "aaaaaaaazzzzzzzz";
84 |
85 | // 10 FLUORESCENT FLICKER
86 | CClient.cl.configstrings[CShared.CS_LIGHTS + 10] = "mmamammmmammamamaaamammma";
87 |
88 | // 11 SLOW PULSE NOT FADE TO BLACK
89 | CClient.cl.configstrings[CShared.CS_LIGHTS + 11] = "abcdefghijklmnopqrrqponmlkjihgfedcba";
90 |
91 | // styles 32-62 are assigned by the light program for switchable lights
92 |
93 | // 63 testing
94 | CClient.cl.configstrings[CShared.CS_LIGHTS + 63] = "a";
95 | }
96 |
97 | private void CL_ReadPackets()
98 | {
99 | gCClientParse.CL_ParseServerMessage();
100 | }
101 |
102 | public void CL_Frame(int msec)
103 | {
104 | CL_ReadPackets();
105 |
106 | gCClientEffect.CL_RunLightStyles();
107 | }
108 |
109 | public void CL_ClearState()
110 | {
111 | gCClientEffect.CL_ClearEffects();
112 | }
113 |
114 | public void CL_Disconnect()
115 | {
116 | CL_ClearState();
117 | }
118 |
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/ClientParse.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using System.Text;
30 |
31 | namespace Q2BSP
32 | {
33 | public class CClientParse
34 | {
35 | public string[] svc_strings =
36 | {
37 | "svc_bad",
38 |
39 | "svc_muzzleflash",
40 | "svc_muzzlflash2",
41 | "svc_temp_entity",
42 | "svc_layout",
43 | "svc_inventory",
44 |
45 | "svc_nop",
46 | "svc_disconnect",
47 | "svc_reconnect",
48 | "svc_sound",
49 | "svc_print",
50 | "svc_stufftext",
51 | "svc_serverdata",
52 | "svc_configstring",
53 | "svc_spawnbaseline",
54 | "svc_centerprint",
55 | "svc_download",
56 | "svc_playerinfo",
57 | "svc_packetentities",
58 | "svc_deltapacketentities",
59 | "svc_frame"
60 | };
61 |
62 |
63 | public void CL_ParseServerData()
64 | {
65 | CProgram.gQ2Game.gCCommon.gCClientMain.CL_ClearState();
66 | }
67 |
68 | private void CL_ParseConfigString()
69 | {
70 | int i;
71 | string s;
72 |
73 | //i = MSG_ReadShort(&net_message);
74 | //if (i < 0 || i >= MAX_CONFIGSTRINGS)
75 | // Com_Error(ERR_DROP, "configstring > MAX_CONFIGSTRINGS");
76 | //s = MSG_ReadString(&net_message);
77 |
78 | //strncpy(olds, cl.configstrings[i], sizeof(olds));
79 | //olds[sizeof(olds) - 1] = 0;
80 |
81 |
82 | // jkrige - just temporary setting a fake network message
83 | i = CShared.CS_LIGHTS;
84 | s = "gjrbdwed";
85 | //if (CClient.cl.configstrings == null)
86 | // CClient.cl.configstrings = new string[CShared.MAX_CONFIGSTRINGS];
87 | // jkrige - just temporary setting a fake network message
88 |
89 | CClient.cl.configstrings[i] = s;
90 |
91 | // do something apropriate
92 |
93 | if (i >= CShared.CS_LIGHTS && i < CShared.CS_LIGHTS + CShared.MAX_LIGHTSTYLES)
94 | CProgram.gQ2Game.gCCommon.gCClientMain.gCClientEffect.CL_SetLightstyle(i - CShared.CS_LIGHTS);
95 | }
96 |
97 | public void CL_ParseServerMessage()
98 | {
99 | CL_ParseServerData();
100 |
101 | CL_ParseConfigString();
102 | }
103 |
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/ClientView.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using System.Text;
30 |
31 | namespace Q2BSP
32 | {
33 | public class CClientView
34 | {
35 | private CLocal.SLightStyle[] r_lightstyles;
36 |
37 | public CClientView()
38 | {
39 | r_lightstyles = new CLocal.SLightStyle[CLocal.MAX_LIGHTSTYLES];
40 |
41 | for (int i = 0; i < CLocal.MAX_LIGHTSTYLES; i++)
42 | {
43 | r_lightstyles[i].white = 0;
44 | r_lightstyles[i].rgb = new float[3];
45 | }
46 | }
47 |
48 | public void V_AddLightStyle(int style, float r, float g, float b)
49 | {
50 | if (style < 0 || style > CShared.MAX_LIGHTSTYLES)
51 | CMain.Error(CMain.EErrorParm.ERR_WARNING, "Bad light style " + style.ToString());
52 |
53 | r_lightstyles[style].white = r + g + b;
54 | r_lightstyles[style].rgb[0] = r;
55 | r_lightstyles[style].rgb[1] = g;
56 | r_lightstyles[style].rgb[2] = b;
57 | }
58 |
59 | public void V_RenderView()
60 | {
61 | CProgram.gQ2Game.gCCommon.gCClientMain.gCClientEntity.CL_AddEntities();
62 |
63 | CClient.cl.RefDef.lightstyles = r_lightstyles;
64 | }
65 |
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Common.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using System.Text;
30 |
31 | namespace Q2BSP
32 | {
33 | public class CCommon
34 | {
35 | public CClientMain gCClientMain;
36 |
37 | // IMPORTANT NOTE: #1
38 | // main.cs will probably be desolved eventually as common.cs will likely be the main entry point
39 | // either that or main.cs will be used via xna draws while common.cs will be used via xna updates
40 | // ...something like that
41 |
42 | // IMPORTANT NOTE: #2
43 | // all the client source code from the common.cs class downwards is not referenced at this time.
44 | // its a guideline for continued development.
45 |
46 | public CCommon()
47 | {
48 | gCClientMain = new CClientMain();
49 | }
50 |
51 | public void Qcommon_Frame(int msec)
52 | {
53 | //if (host_speeds->value)
54 | // time_before = Sys_Milliseconds();
55 |
56 | //SV_Frame(msec);
57 |
58 | //if (host_speeds->value)
59 | // time_between = Sys_Milliseconds();
60 |
61 | gCClientMain.CL_Frame(msec);
62 |
63 | gCClientMain.gCClientView.V_RenderView();
64 | }
65 |
66 |
67 | public struct SSizeBuf
68 | {
69 | public bool allowoverflow; // if false, do a Com_Error
70 | public bool overflowed; // set to true if the buffer size failed
71 | public byte[] data;
72 | public int maxsize;
73 | public int cursize;
74 | public int readcount;
75 | }
76 |
77 |
78 | // ==============================================================
79 | //
80 | // PROTOCOL
81 | //
82 | // ==============================================================
83 | public const int PROTOCOL_VERSION = 34;
84 |
85 | public const int PORT_MASTER = 27900;
86 | public const int PORT_CLIENT = 27901;
87 | public const int PORT_SERVER = 27910;
88 |
89 | public const int UPDATE_BACKUP = 16; // copies of entity_state_t to keep buffered, must be power of two
90 | public const int UPDATE_MASK = UPDATE_BACKUP - 1;
91 |
92 | // the svc_strings[] array in ClientParse.cs should mirror this.
93 |
94 | // server to client
95 | public enum ESVC_Ops
96 | {
97 | svc_bad,
98 |
99 | // these ops are known to the game dll
100 | svc_muzzleflash,
101 | svc_muzzleflash2,
102 | svc_temp_entity,
103 | svc_layout,
104 | svc_inventory,
105 |
106 | // the rest are private to the client and server
107 | svc_nop,
108 | svc_disconnect,
109 | svc_reconnect,
110 | svc_sound, //
111 | svc_print, // [byte] id [string] null terminated string
112 | svc_stufftext, // [string] stuffed into client's console buffer, should be \n terminated
113 | svc_serverdata, // [long] protocol ...
114 | svc_configstring, // [short] [string]
115 | svc_spawnbaseline,
116 | svc_centerprint, // [string] to put in center of the screen
117 | svc_download, // [short] size [size bytes]
118 | svc_playerinfo, // variable
119 | svc_packetentities, // [...]
120 | svc_deltapacketentities, // [...]
121 | svc_frame
122 | }
123 |
124 | // client to server
125 | public enum ECLC_Ops
126 | {
127 | clc_bad,
128 | clc_nop,
129 | clc_move, // [[usercmd_t]
130 | clc_userinfo, // [[userinfo string]
131 | clc_stringcmd // [string] message
132 | };
133 |
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/Config.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using System.Configuration;
30 | using System.Text;
31 |
32 | namespace Q2BSP
33 | {
34 | public class CConfig
35 | {
36 | ///
37 | /// Gets the value of a configuration setting key and attempts to return its value as a boolean
38 | ///
39 | /// The configuration setting key
40 | /// Returns configuration setting key value as a boolean
41 | public static bool GetConfigBOOL(string KeyName)
42 | {
43 | bool KeyValue;
44 |
45 | try
46 | {
47 | KeyValue = Convert.ToBoolean(ConfigurationManager.AppSettings[KeyName].ToString());
48 | }
49 | catch
50 | {
51 | KeyValue = false;
52 | }
53 |
54 | return KeyValue;
55 | }
56 |
57 | ///
58 | /// Gets the value of a configuration setting key and attempts to return its value as a string
59 | ///
60 | /// The configuration setting key
61 | /// Returns configuration setting key value as a string
62 | public static string GetConfigSTRING(string KeyName)
63 | {
64 | string KeyValue;
65 |
66 | try
67 | {
68 | KeyValue = ConfigurationManager.AppSettings[KeyName].ToString();
69 | }
70 | catch
71 | {
72 | KeyValue = null;
73 | }
74 |
75 | return KeyValue;
76 | }
77 |
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/Content/Q2BSPContent.contentproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {29204DFD-5723-48DB-AC99-A8208752E4F1}
5 | {96E2B04D-8817-42c6-938A-82C39BA4D311};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
6 | Debug
7 | x86
8 | Library
9 | Properties
10 | v4.0
11 | v4.0
12 | x86
13 | bin\$(Platform)\$(Configuration)
14 | Content
15 | http://localhost/Q2BSPContent/
16 | true
17 | Web
18 | true
19 | Foreground
20 | 7
21 | Days
22 | false
23 | false
24 | true
25 | 0
26 | 1.0.0.%2a
27 | true
28 | false
29 | true
30 |
31 |
32 | Windows
33 | AllRules.ruleset
34 |
35 |
36 | Windows
37 | AllRules.ruleset
38 |
39 |
40 |
41 | False
42 |
43 |
44 | False
45 |
46 |
47 | False
48 |
49 |
50 | False
51 |
52 |
53 | False
54 |
55 |
56 | False
57 |
58 |
59 |
60 |
61 | SpriteFont1
62 | FontDescriptionImporter
63 | FontDescriptionProcessor
64 |
65 |
66 |
67 |
68 | effects20
69 | EffectImporter
70 | EffectProcessor
71 |
72 |
73 | effects30
74 | EffectImporter
75 | EffectProcessor
76 |
77 |
78 | bloom
79 | EffectImporter
80 | EffectProcessor
81 |
82 |
83 | blur
84 | EffectImporter
85 | EffectProcessor
86 |
87 |
88 | generic
89 | EffectImporter
90 | EffectProcessor
91 |
92 |
93 | skins
94 | EffectImporter
95 | EffectProcessor
96 |
97 |
98 | textures
99 | EffectImporter
100 | EffectProcessor
101 |
102 |
103 |
104 |
105 | False
106 | Microsoft .NET Framework 4 %28x86 and x64%29
107 | true
108 |
109 |
110 | False
111 | .NET Framework 3.5 SP1 Client Profile
112 | false
113 |
114 |
115 | False
116 | .NET Framework 3.5 SP1
117 | false
118 |
119 |
120 | False
121 | Windows Installer 3.1
122 | true
123 |
124 |
125 |
126 |
133 |
--------------------------------------------------------------------------------
/Content/SpriteFont1.spritefont:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
14 | Verdana
15 |
16 |
20 | 10
21 |
22 |
26 | 1
27 |
28 |
32 | true
33 |
34 |
38 |
39 |
40 |
44 |
45 |
46 |
53 |
54 |
55 |
56 | ~
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Content/bloom.fx:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 |
28 | // The initial phase of implementing bloom postprocess is to extract the brighter areas of a given image
29 | float4 BloomExtractPS(float2 texCoord : TEXCOORD0) : COLOR0
30 | {
31 | // get the original texture pixel color
32 | float4 Color = tex2D(TextureSampler, texCoord);
33 |
34 | // only retain the values that are brighter than the specified threshold
35 | return saturate((Color - xBloomThreshold) / (1 - xBloomThreshold));
36 | }
37 |
38 |
39 | // The final phase of implementing bloom postprocess is to combine the bloom image with the original scene
40 | sampler BaseSampler : register(s1);
41 | sampler BloomSampler : register(s0);
42 |
43 | float4 AdjustSaturation(float4 Color, float Saturation)
44 | {
45 | // the constants 0.3, 0.59 and 0.11 are chosen because the human eye
46 | // is more sensitive to green light and less to blue light.
47 | float Gray = dot(Color, float3(0.3, 0.59, 0.11));
48 |
49 | return lerp(Gray, Color, Saturation);
50 | }
51 |
52 | float4 BloomCombinePS(float2 texCoord : TEXCOORD0) : COLOR0
53 | {
54 | // get the original base texture pixel color as well as the bloom pixel color
55 | float4 base = tex2D(BaseSampler, texCoord);
56 | float4 bloom = tex2D(BloomSampler, texCoord);
57 |
58 | // adjust pixel color saturation and intensity
59 | base = AdjustSaturation(base, xBaseSaturation) * xBaseIntensity;
60 | bloom = AdjustSaturation(bloom, xBloomSaturation) * xBloomIntensity;
61 |
62 | // darken the base image in areas where there is a lot of bloom
63 | // to prevent things looking excessively burned-out.
64 | base *= (1 - saturate(bloom));
65 |
66 | return base + bloom;
67 | }
68 |
--------------------------------------------------------------------------------
/Content/blur.fx:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 |
28 | // Applies a one dimensional gaussian blur filter
29 | #define SAMPLE_COUNT 15
30 |
31 | float2 SampleOffsets[SAMPLE_COUNT];
32 | float SampleWeights[SAMPLE_COUNT];
33 |
34 | float4 GaussianBlurPS(float2 texCoord : TEXCOORD0) : COLOR0
35 | {
36 | float4 Color = float4(0.0, 0.0, 0.0, 0.0);
37 |
38 | // combine a number of weighted image filter taps
39 | for (int i = 0; i < SAMPLE_COUNT; i++)
40 | {
41 | Color += tex2D(TextureSampler, texCoord + SampleOffsets[i]) * SampleWeights[i];
42 | }
43 |
44 | return Color;
45 | }
46 |
--------------------------------------------------------------------------------
/Content/effects20.fx:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | #define LIGHT_COUNT 2
28 |
29 | #include "generic.fx"
30 | #include "skins.fx"
31 | #include "textures.fx"
32 | #include "bloom.fx"
33 | #include "blur.fx"
34 |
35 |
36 | // SKINS.FX
37 | technique TexturedSkin
38 | {
39 | pass Pass0
40 | {
41 | VertexShader = compile vs_2_0 TexturedSkinVS();
42 | PixelShader = compile ps_2_0 TexturedSkinPS();
43 | }
44 | }
45 |
46 |
47 | // TEXTURES.FX
48 | technique Textured
49 | {
50 | pass Pass0
51 | {
52 | VertexShader = compile vs_2_0 TexturedVS();
53 | PixelShader = compile ps_2_0 TexturedPS();
54 | }
55 | }
56 |
57 | technique TexturedLightmap
58 | {
59 | pass Pass0
60 | {
61 | VertexShader = compile vs_2_0 TexturedVS();
62 | PixelShader = compile ps_2_0 TexturedLightmapPS();
63 | }
64 | }
65 |
66 | technique TexturedWarped
67 | {
68 | pass Pass0
69 | {
70 | VertexShader = compile vs_2_0 TexturedWarpedVS();
71 | PixelShader = compile ps_2_0 TexturedPS();
72 | }
73 | }
74 |
75 | technique TexturedTranslucent
76 | {
77 | pass Pass0
78 | {
79 | AlphaBlendEnable = true;
80 | SrcBlend = SrcAlpha;
81 | DestBlend = InvSrcAlpha;
82 | VertexShader = compile vs_2_0 TexturedVS();
83 | PixelShader = compile ps_2_0 TexturedTranslucentPS();
84 | }
85 | }
86 |
87 | technique TexturedWarpedTranslucent
88 | {
89 | pass Pass0
90 | {
91 | AlphaBlendEnable = true;
92 | SrcBlend = SrcAlpha;
93 | DestBlend = InvSrcAlpha;
94 | VertexShader = compile vs_2_0 TexturedWarpedVS();
95 | PixelShader = compile ps_2_0 TexturedTranslucentPS();
96 | }
97 | }
98 |
99 | technique TexturedSkybox
100 | {
101 | pass Pass0
102 | {
103 | VertexShader = compile vs_2_0 TexturedSkyboxVS();
104 | PixelShader = compile ps_2_0 TexturedSkyboxPS();
105 | }
106 | }
107 |
108 | technique TexturedLight
109 | {
110 | pass Pass0
111 | {
112 | VertexShader = compile vs_2_0 TexturedLightVS();
113 | PixelShader = compile ps_2_0 TexturedLightPS();
114 | }
115 | }
116 |
117 |
118 | // BLOOM.FX
119 | technique BloomExtract
120 | {
121 | pass Pass0
122 | {
123 | PixelShader = compile ps_2_0 BloomExtractPS();
124 | }
125 | }
126 |
127 | technique BloomCombine
128 | {
129 | pass Pass0
130 | {
131 | PixelShader = compile ps_2_0 BloomCombinePS();
132 | }
133 | }
134 |
135 |
136 | // BLUR.FX (this is used twice by the bloom postprocess, blurring horizontally, then vertically)
137 | technique GaussianBlur
138 | {
139 | pass Pass0
140 | {
141 | PixelShader = compile ps_2_0 GaussianBlurPS();
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/Content/effects30.fx:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | #define LIGHT_COUNT 8
28 |
29 | #include "generic.fx"
30 | #include "skins.fx"
31 | #include "textures.fx"
32 | #include "bloom.fx"
33 | #include "blur.fx"
34 |
35 |
36 | // SKINS.FX
37 | technique TexturedSkin
38 | {
39 | pass Pass0
40 | {
41 | VertexShader = compile vs_3_0 TexturedSkinVS();
42 | PixelShader = compile ps_3_0 TexturedSkinPS();
43 | }
44 | }
45 |
46 |
47 | // TEXTURES.FX
48 | technique Textured
49 | {
50 | pass Pass0
51 | {
52 | VertexShader = compile vs_3_0 TexturedVS();
53 | PixelShader = compile ps_3_0 TexturedPS();
54 | }
55 | }
56 |
57 | technique TexturedLightmap
58 | {
59 | pass Pass0
60 | {
61 | VertexShader = compile vs_3_0 TexturedVS();
62 | PixelShader = compile ps_3_0 TexturedLightmapPS();
63 | }
64 | }
65 |
66 | technique TexturedWarped
67 | {
68 | pass Pass0
69 | {
70 | VertexShader = compile vs_3_0 TexturedWarpedVS();
71 | PixelShader = compile ps_3_0 TexturedPS();
72 | }
73 | }
74 |
75 | technique TexturedTranslucent
76 | {
77 | pass Pass0
78 | {
79 | AlphaBlendEnable = true;
80 | SrcBlend = SrcAlpha;
81 | DestBlend = InvSrcAlpha;
82 | VertexShader = compile vs_3_0 TexturedVS();
83 | PixelShader = compile ps_3_0 TexturedTranslucentPS();
84 | }
85 | }
86 |
87 | technique TexturedWarpedTranslucent
88 | {
89 | pass Pass0
90 | {
91 | AlphaBlendEnable = true;
92 | SrcBlend = SrcAlpha;
93 | DestBlend = InvSrcAlpha;
94 | VertexShader = compile vs_3_0 TexturedWarpedVS();
95 | PixelShader = compile ps_3_0 TexturedTranslucentPS();
96 | }
97 | }
98 |
99 | technique TexturedSkybox
100 | {
101 | pass Pass0
102 | {
103 | VertexShader = compile vs_3_0 TexturedSkyboxVS();
104 | PixelShader = compile ps_3_0 TexturedSkyboxPS();
105 | }
106 | }
107 |
108 | technique TexturedLight
109 | {
110 | pass Pass0
111 | {
112 | VertexShader = compile vs_3_0 TexturedLightVS();
113 | PixelShader = compile ps_3_0 TexturedLightPS();
114 | }
115 | }
116 |
117 |
118 | // BLOOM.FX
119 | technique BloomExtract
120 | {
121 | pass Pass0
122 | {
123 | PixelShader = compile ps_3_0 BloomExtractPS();
124 | }
125 | }
126 |
127 | technique BloomCombine
128 | {
129 | pass Pass0
130 | {
131 | PixelShader = compile ps_3_0 BloomCombinePS();
132 | }
133 | }
134 |
135 |
136 | // BLUR.FX (this is used twice by the bloom postprocess, blurring horizontally, then vertically)
137 | technique GaussianBlur
138 | {
139 | pass Pass0
140 | {
141 | PixelShader = compile ps_3_0 GaussianBlurPS();
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/Content/generic.fx:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | struct Light
28 | {
29 | float4 color;
30 | float4 position;
31 | float falloff;
32 | float range;
33 | };
34 |
35 | struct VertexShaderOutput
36 | {
37 | float4 Position : POSITION;
38 | float2 TextureCoords : TEXCOORD0;
39 | float2 LightmapCoords : TEXCOORD1;
40 | float3 WorldNormal : TEXCOORD2;
41 | float3 WorldPosition : TEXCOORD3;
42 | float4 ambientLightColor : COLOR0;
43 | };
44 |
45 | struct PixelShaderInput
46 | {
47 | float2 TextureCoords : TEXCOORD0;
48 | float2 LightmapCoords : TEXCOORD1;
49 | float3 WorldNormal : TEXCOORD2;
50 | float3 WorldPosition : TEXCOORD3;
51 | float4 ambientLightColor : COLOR0;
52 | };
53 |
54 |
55 | struct VertexShaderSkinOutput
56 | {
57 | float4 Position : POSITION;
58 | float2 TextureCoords : TEXCOORD0;
59 | float3 WorldNormal : TEXCOORD2;
60 | float3 WorldPosition : TEXCOORD3;
61 | float4 ambientLightColor : COLOR0;
62 | };
63 |
64 | struct PixelShaderSkinInput
65 | {
66 | float2 TextureCoords : TEXCOORD0;
67 | float3 WorldNormal : TEXCOORD2;
68 | float3 WorldPosition : TEXCOORD3;
69 | float4 ambientLightColor : COLOR0;
70 | };
71 |
72 |
73 | struct VertexShaderOutput_Skybox
74 | {
75 | float4 Position : POSITION;
76 | float2 TextureCoords : TEXCOORD0;
77 | float3 WorldPosition : TEXCOORD1;
78 | };
79 |
80 | struct PixelShaderInput_Skybox
81 | {
82 | float2 TextureCoords : TEXCOORD0;
83 | float3 WorldPosition : TEXCOORD1;
84 | };
85 |
86 |
87 | // -------- XNA to HLSL variables --------
88 | float4x4 xView;
89 | float4x4 xProjection;
90 | float4x4 xWorld;
91 | float4 xLightModel;
92 | float4 xLightAmbient;
93 | float xLightPower;
94 | float xTextureAlpha;
95 | float xGamma;
96 | float xRealTime;
97 | float xBloomThreshold;
98 | float xBaseIntensity;
99 | float xBloomIntensity;
100 | float xBaseSaturation;
101 | float xBloomSaturation;
102 | bool xPointLights;
103 | bool xFlow;
104 |
105 |
106 | // 7: GaussianQuad - A 4-sample Gaussian filter used as a texture magnification or minification filter.
107 | // 6: PyramidalQuad - A 4-sample tent filter used as a texture magnification or minification filter.
108 | // 3: Anisotropic - Anisotropic texture filtering used as a texture magnification or minification filter. This type of filtering compensates for distortion caused by the difference in angle between the texture polygon and the plane of the screen.
109 | // 2: Linear - Bilinear interpolation filtering used as a texture magnification or minification filter. A weighted average of a 2x2 area of texels surrounding the desired pixel is used. The texture filter used between mipmap levels is trilinear mipmap interpolation, in which the rasterizer performs linear interpolation on pixel color, using the texels of the two nearest mipmap textures.
110 | // 1: Point - Point filtering used as a texture magnification or minification filter. The texel with coordinates nearest to the desired pixel value is used. The texture filter used between mipmap levels is based on the nearest point; that is, the rasterizer uses the color from the texel of the nearest mipmap texture.
111 | // 0: None - Mipmapping disabled. The rasterizer uses the magnification filter instead.
112 |
113 |
114 | // -------- Texture Samplers --------
115 | Texture xTextureDiffuse;
116 | sampler TextureSamplerDiffuse = sampler_state {
117 | texture = ;
118 | MagFilter = Anisotropic;
119 | MinFilter = Anisotropic;
120 | MipFilter = Linear;
121 | MaxAnisotropy = 8;
122 | AddressU = Wrap;
123 | AddressV = Wrap;
124 | };
125 |
126 | Texture xTextureLightmap;
127 | sampler TextureSamplerLightmap = sampler_state {
128 | texture = ;
129 | MagFilter = Anisotropic;
130 | MinFilter = Anisotropic;
131 | MipFilter = LINEAR;
132 | MaxAnisotropy = 8;
133 | AddressU = Wrap;
134 | AddressV = Wrap;
135 | };
136 |
137 | Texture xTextureSkin;
138 | sampler TextureSamplerSkin = sampler_state {
139 | texture = ;
140 | MagFilter = Anisotropic;
141 | MinFilter = Anisotropic;
142 | MipFilter = Linear;
143 | MaxAnisotropy = 8;
144 | AddressU = Clamp;
145 | AddressV = Clamp;
146 | };
147 |
148 | sampler TextureSampler : register(s0);
149 |
150 |
151 | float4 CalculateSingleLightmap(Light light, float3 worldPosition, float3 worldNormal, float4 LightmapColor)
152 | {
153 | float3 lightVector = light.position - worldPosition;
154 | float lightDist = length(lightVector);
155 | float3 directionToLight = normalize(lightVector);
156 |
157 | // calculate the intensity of the light with exponential falloff
158 | float baseIntensity = pow(saturate((light.range - lightDist) / light.range), light.falloff);
159 | float diffuseIntensity = saturate(dot(directionToLight, worldNormal));
160 | diffuseIntensity *= xLightPower;
161 |
162 | // modify the lightmap pixels
163 | float4 diffuse = diffuseIntensity * light.color;
164 | float blendfactor = min(1, lightDist / light.range);
165 | float4 lightmapPixel = (1 - blendfactor) * diffuse + blendfactor * LightmapColor;
166 |
167 |
168 | return lightmapPixel * baseIntensity;
169 | }
170 |
171 | float4 CalculateSingleLight(Light light, float3 worldPosition, float3 worldNormal, float2 TextureCoords, float4 diffuseColor, float4 specularColor)
172 | {
173 | float3 lightVector = light.position - worldPosition;
174 | float lightDist = length(lightVector);
175 | float3 directionToLight = normalize(lightVector);
176 |
177 | //calculate the intensity of the light with exponential falloff
178 | float baseIntensity = pow(saturate((light.range - lightDist) / light.range), light.falloff);
179 | float diffuseIntensity = saturate(dot(directionToLight, worldNormal));
180 | diffuseIntensity *= xLightPower;
181 |
182 | float4 diffuse = diffuseIntensity * light.color * diffuseColor;
183 |
184 | //calculate phong components per-pixel
185 | //float3 reflectionVector = normalize(reflect(directionToLight, worldNormal));
186 | //float3 directionToCamera = normalize(cameraPosition - worldPosition);
187 |
188 | //calculate specular component
189 | //float4 specular = saturate(light.color * specularColor * specularIntensity * pow(saturate(dot(reflectionVector, directionToCamera)), specularPower));
190 | //return (diffuse + specular) * baseIntensity;
191 |
192 | return diffuse * baseIntensity;
193 | }
194 |
195 | float4 CalculateGamma(float4 color)
196 | {
197 | return log(1 + color) * xGamma;
198 | }
199 |
200 | float2 CalculateWarp(float2 TexCoords)
201 | {
202 | float2 TC;
203 | float TurbScale = (256.0f / (2 * 3.141592));
204 | float Flowing = 0.0f;
205 |
206 | if (xFlow == true)
207 | Flowing = -64.0f * ((xRealTime * 0.5f) - (int)(xRealTime * 0.5f));
208 |
209 | // muliplying the result by 3.0 to make the warping more dramatic
210 | TC.x = TexCoords.x + sin(radians((TexCoords.y * 0.125f + xRealTime) * TurbScale)) * 3.0f;
211 | TC.x += Flowing;
212 | TC.x *= (1.0f / 64.0f);
213 | TC.y = TexCoords.y + sin(radians((TexCoords.x * 0.125f + xRealTime) * TurbScale)) * 3.0f;
214 | TC.y *= (1.0f / 64.0f);
215 |
216 | return TC;
217 | }
218 |
--------------------------------------------------------------------------------
/Content/skins.fx:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | //-------- Technique: TexturedSkin --------
28 | VertexShaderSkinOutput TexturedSkinVS(float4 inPos : POSITION, float3 inNormal: NORMAL, float2 inTexCoords: TEXCOORD0)
29 | {
30 | VertexShaderSkinOutput Output = (VertexShaderSkinOutput)0;
31 |
32 | // generate the viewprojection and worldviewprojection
33 | float4x4 preViewProjection = mul(xView, xProjection);
34 | float4x4 preWorldViewProjection = mul(xWorld, preViewProjection);
35 |
36 | // transform the input position to the output
37 | Output.Position = mul(inPos, preWorldViewProjection);
38 |
39 | Output.WorldNormal = normalize(mul(inNormal, (float3x3)xWorld));
40 | Output.WorldPosition = mul(inPos, xWorld);
41 |
42 | // copy the tex coords to the interpolator
43 | Output.TextureCoords = inTexCoords;
44 |
45 | // copy the ambient lighting
46 | Output.ambientLightColor = float4(1.0, 1.0, 1.0, 1.0);
47 |
48 | return Output;
49 | }
50 |
51 | float4 TexturedSkinPS(PixelShaderSkinInput Input) : COLOR
52 | {
53 | float4 diffuseColor = tex2D(TextureSamplerSkin, Input.TextureCoords);
54 |
55 | // gamma correction
56 | diffuseColor = CalculateGamma(diffuseColor * xLightModel);
57 | diffuseColor.a = 1.0;
58 |
59 | return diffuseColor;
60 | }
61 |
--------------------------------------------------------------------------------
/Content/textures.fx:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | float numLights = LIGHT_COUNT;
28 | shared Light lights[LIGHT_COUNT];
29 |
30 |
31 | //-------- Technique: Textured --------
32 | VertexShaderOutput TexturedVS(float4 inPos : POSITION, float3 inNormal: NORMAL, float2 inTexCoords: TEXCOORD0, float2 inLightCoords: TEXCOORD1)
33 | {
34 | VertexShaderOutput Output = (VertexShaderOutput)0;
35 |
36 | // generate the viewprojection and worldviewprojection
37 | float4x4 preViewProjection = mul(xView, xProjection);
38 | float4x4 preWorldViewProjection = mul(xWorld, preViewProjection);
39 |
40 | // transform the input position to the output
41 | Output.Position = mul(inPos, preWorldViewProjection);
42 |
43 | Output.WorldNormal = normalize(mul(inNormal, (float3x3)xWorld));
44 | Output.WorldPosition = mul(inPos, xWorld);
45 |
46 | // copy the tex coords to the interpolator
47 | Output.TextureCoords = inTexCoords;
48 |
49 | // copy the lightmap coords to the interpolator
50 | Output.LightmapCoords = inLightCoords;
51 |
52 | // copy the ambient lighting
53 | Output.ambientLightColor = float4(1.0, 1.0, 1.0, 1.0);
54 |
55 | return Output;
56 | }
57 |
58 | float4 TexturedPS(PixelShaderInput Input) : COLOR
59 | {
60 | float4 diffuseColor = tex2D(TextureSamplerDiffuse, Input.TextureCoords);
61 |
62 | // gamma correction
63 | diffuseColor = CalculateGamma(diffuseColor);
64 | diffuseColor.a = 1.0;
65 |
66 | return diffuseColor;
67 | }
68 |
69 |
70 | //-------- Technique: TexturedWarped --------
71 | VertexShaderOutput TexturedWarpedVS(float4 inPos : POSITION, float3 inNormal: NORMAL, float2 inTexCoords: TEXCOORD0, float2 inLightCoords: TEXCOORD1)
72 | {
73 | VertexShaderOutput Output = (VertexShaderOutput)0;
74 |
75 | // generate the viewprojection and worldviewprojection
76 | float4x4 preViewProjection = mul(xView, xProjection);
77 | float4x4 preWorldViewProjection = mul(xWorld, preViewProjection);
78 |
79 | // transform the input position to the output
80 | Output.Position = mul(inPos, preWorldViewProjection);
81 |
82 | Output.WorldNormal = normalize(mul(inNormal, (float3x3)xWorld));
83 | Output.WorldPosition = mul(inPos, xWorld);
84 |
85 | // copy the tex coords to the interpolator
86 | Output.TextureCoords = CalculateWarp(inTexCoords);
87 |
88 | // copy the lightmap coords to the interpolator
89 | Output.LightmapCoords = inLightCoords;
90 |
91 | // copy the ambient lighting
92 | Output.ambientLightColor = float4(1.0, 1.0, 1.0, 1.0);
93 |
94 | return Output;
95 | }
96 |
97 |
98 | //-------- Technique: TexturedLightmap --------
99 | float4 TexturedLightmapPS(PixelShaderInput Input) : COLOR
100 | {
101 | float4 Color;
102 | float4 TextureColor = tex2D(TextureSamplerDiffuse, Input.TextureCoords);
103 | float4 LightmapColor = tex2D(TextureSamplerLightmap, Input.LightmapCoords);
104 |
105 | //all color components are summed in the pixel shader
106 | if(xPointLights == true)
107 | {
108 | for(int i = 0; i < LIGHT_COUNT; i++)
109 | {
110 | LightmapColor += CalculateSingleLightmap(lights[i], Input.WorldPosition, Input.WorldNormal, LightmapColor); // * (i < numLights);
111 | }
112 | }
113 |
114 | // gamma correction
115 | Color = CalculateGamma(TextureColor * LightmapColor);
116 | Color.a = 1.0;
117 |
118 | return Color;
119 | }
120 |
121 |
122 | //-------- Technique: TexturedTranslucent --------
123 | float4 TexturedTranslucentPS(PixelShaderInput Input) : COLOR
124 | {
125 | float4 diffuseColor = tex2D(TextureSamplerDiffuse, Input.TextureCoords);
126 |
127 | // gamma correction
128 | diffuseColor = CalculateGamma(diffuseColor);
129 | diffuseColor.a = xTextureAlpha;
130 |
131 | return diffuseColor;
132 | }
133 |
134 |
135 | //-------- Technique: TexturedSkybox --------
136 | VertexShaderOutput_Skybox TexturedSkyboxVS(float4 inPos : POSITION, float2 inTexCoords: TEXCOORD0)
137 | {
138 | VertexShaderOutput_Skybox Output = (VertexShaderOutput_Skybox)0;
139 |
140 | // generate the viewprojection and worldviewprojection
141 | float4x4 preViewProjection = mul(xView, xProjection);
142 | float4x4 preWorldViewProjection = mul(xWorld, preViewProjection);
143 |
144 | // transform the input position to the output
145 | Output.Position = mul(inPos, preWorldViewProjection);
146 | Output.WorldPosition = mul(inPos, xWorld);
147 |
148 | // copy the tex coords to the interpolator
149 | Output.TextureCoords = inTexCoords;
150 |
151 | return Output;
152 | }
153 |
154 | float4 TexturedSkyboxPS(PixelShaderInput_Skybox Input) : COLOR
155 | {
156 | float4 diffuseColor = tex2D(TextureSamplerDiffuse, Input.TextureCoords);
157 |
158 | // gamma correction
159 | diffuseColor = CalculateGamma(diffuseColor);
160 | diffuseColor.a = 1.0;
161 |
162 | return diffuseColor;
163 | }
164 |
165 |
166 | //-------- Technique: TexturedLight --------
167 | VertexShaderOutput TexturedLightVS(float4 inPos : POSITION, float3 inNormal: NORMAL, float2 inTexCoords: TEXCOORD0)
168 | {
169 | VertexShaderOutput Output = (VertexShaderOutput)0;
170 |
171 | // generate the viewprojection and worldviewprojection
172 | float4x4 preViewProjection = mul(xView, xProjection);
173 | float4x4 preWorldViewProjection = mul(xWorld, preViewProjection);
174 |
175 | // transform the input position to the output
176 | Output.Position = mul(inPos, preWorldViewProjection);
177 |
178 | Output.WorldNormal = normalize(mul(inNormal, (float3x3)xWorld));
179 | Output.WorldPosition = mul(inPos, xWorld);
180 |
181 | // copy the tex coords to the interpolator
182 | Output.TextureCoords = inTexCoords;
183 |
184 | // copy the ambient lighting
185 | Output.ambientLightColor = xLightAmbient;
186 |
187 | return Output;
188 | }
189 |
190 | float4 TexturedLightPS(PixelShaderInput Input) : COLOR
191 | {
192 | float4 diffuseColor = tex2D(TextureSamplerDiffuse, Input.TextureCoords);
193 | float4 specularColor = float4(0.15, 0.15, 0.15, 0.15);
194 | float4 Color = Input.ambientLightColor * diffuseColor;
195 |
196 | //all color components are summed in the pixel shader
197 | if(xPointLights == true)
198 | {
199 | for(int i = 0; i < LIGHT_COUNT; i++)
200 | {
201 | Color += CalculateSingleLight(lights[i], Input.WorldPosition, Input.WorldNormal, Input.TextureCoords, diffuseColor, specularColor); // * (i < numLights);
202 | }
203 | }
204 |
205 | // gamma correction
206 | Color = CalculateGamma(Color);
207 | Color.a = 1.0;
208 |
209 | return Color;
210 | }
211 |
--------------------------------------------------------------------------------
/Files.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using System.IO;
30 | using System.Text;
31 |
32 | namespace Q2BSP
33 | {
34 | public class CFiles
35 | {
36 | // ========================================================================
37 | // PAK FILE LOADING
38 | //
39 | // The .pak files are just a linear collapse of a directory tree
40 | // ========================================================================
41 | public const int IDPAKHEADER = (('K' << 24) + ('C' << 16) + ('A' << 8) + 'P');
42 | public const int PACK_MAX_FILES = 8192; // bumped from 4096 to support loading Heretic2
43 | public const int PACK_MAX_FILENAME_LENGTH = 56;
44 |
45 | // total number of files inside pak
46 | private int fs_packFiles;
47 |
48 | // the loaded pack information
49 | private SPack? qPack;
50 |
51 | public void FS_LoadPak(string PakFile, string BaseName)
52 | {
53 | if (CProgram.gQ2Game.gCMain.r_usepak == false)
54 | return;
55 |
56 | qPack = FS_LoadPakFile(PakFile, BaseName);
57 | }
58 |
59 | public void FS_ClosePak()
60 | {
61 | if (CProgram.gQ2Game.gCMain.r_usepak == false)
62 | return;
63 |
64 | if (qPack.HasValue == false)
65 | return;
66 |
67 | qPack.Value.handle.Close();
68 | qPack = null;
69 | }
70 |
71 | ///
72 | /// FS_ReadFile
73 | /// -----------
74 | /// filename are relative to the quake search path
75 | ///
76 | public void FS_ReadFile(string qpath, out byte[] qdata)
77 | {
78 | qdata = FS_ReadFile2(qpath);
79 | }
80 |
81 | public void FS_ReadFile(string qpath, out MemoryStream qdata)
82 | {
83 | byte[] data = FS_ReadFile2(qpath);
84 |
85 | if (data != null)
86 | qdata = new MemoryStream(data);
87 | else
88 | qdata = null;
89 | }
90 |
91 | private byte[] FS_ReadFile2(string qpath)
92 | {
93 | int i;
94 | bool found = false;
95 |
96 | if (qPack.HasValue == false)
97 | return null;
98 |
99 | for (i = 0; i < qPack.Value.buildBuffer.Count; i++)
100 | {
101 | if (qpath == qPack.Value.buildBuffer[i].Name)
102 | {
103 | found = true;
104 | break;
105 | }
106 |
107 | }
108 |
109 | if (found == true)
110 | {
111 | BinaryReader r = new BinaryReader(qPack.Value.handle);
112 |
113 | r.BaseStream.Seek(qPack.Value.buildBuffer[i].Position, System.IO.SeekOrigin.Begin);
114 | return r.ReadBytes(qPack.Value.buildBuffer[i].Size);
115 | }
116 |
117 | return null;
118 | }
119 |
120 | private SPack? FS_LoadPakFile(string PakFile, string BaseName)
121 | {
122 | SPack Pack;
123 | BinaryReader r;
124 |
125 | PakFile = CProgram.gQ2Game.Content.RootDirectory + "\\" + PakFile;
126 |
127 | if (File.Exists(PakFile) == false)
128 | {
129 | CMain.Error(CMain.EErrorParm.ERR_FATAL, "PAK file not found.");
130 | return null;
131 | }
132 |
133 | Pack.handle = File.OpenRead(PakFile);
134 |
135 | if (Pack.handle == null)
136 | return null;
137 |
138 | r = new BinaryReader(Pack.handle);
139 | PakFile = PakFile.ToLower();
140 | BaseName = BaseName.ToLower();
141 |
142 | if (r.ReadInt32() != IDPAKHEADER)
143 | {
144 | Pack.handle.Close();
145 | Pack.handle = null;
146 |
147 | CMain.Error(CMain.EErrorParm.ERR_FATAL, PakFile + " is not a packfile");
148 | return null;
149 | }
150 |
151 | Pack.packDirOffset = r.ReadInt32();
152 | Pack.packDirLength = r.ReadInt32();
153 |
154 | // if the directory offset is beyond the EOF then we assume its htic2-0.pak
155 | // Raven Software probably did this so unaware PAK readers fails to read the Heretic2 content
156 | if (CProgram.gQ2Game.gCMain.r_htic2 == true)
157 | {
158 | if (Pack.packDirOffset > r.BaseStream.Length)
159 | {
160 | Pack.packDirOffset = 215695973; // 0x0cdb4265 (215 695 973 bytes)
161 | Pack.packDirLength = 264256; // EOF - Pack.packDirOffset (EOF: 0x0cdf4aa5 | 215 960 229 bytes)
162 | }
163 | }
164 |
165 | // PACK_MAX_FILENAME_LENGTH + FilePosition + FileLength
166 | Pack.numfiles = Pack.packDirLength / (PACK_MAX_FILENAME_LENGTH + sizeof(int) + sizeof(int));
167 |
168 | if (Pack.numfiles > PACK_MAX_FILES)
169 | CMain.Error(CMain.EErrorParm.ERR_FATAL, PakFile + " has " + Pack.numfiles + " files");
170 |
171 | Pack.buildBuffer = new List();
172 |
173 | fs_packFiles += Pack.numfiles;
174 | Pack.pakFilename = PakFile;
175 | Pack.pakBasename = BaseName.Replace(".pak", "");
176 |
177 | r.BaseStream.Seek(Pack.packDirOffset, SeekOrigin.Begin);
178 |
179 | for (int i = 0; i < Pack.numfiles; i++)
180 | {
181 | SFileInPack _FileInPack;
182 |
183 | _FileInPack.Name = CShared.Com_ToString(r.ReadChars(PACK_MAX_FILENAME_LENGTH)).ToLower();
184 | _FileInPack.Position = r.ReadInt32();
185 | _FileInPack.Size = r.ReadInt32();
186 |
187 | Pack.buildBuffer.Add(_FileInPack);
188 | }
189 |
190 | //for (int i = 0; i < Pack.buildBuffer.Count; i++)
191 | //{
192 | // r.BaseStream.Seek(Pack.buildBuffer[i].Position, System.IO.SeekOrigin.Begin);
193 | // fs_headerLongs[fs_numHeaderLongs++] = CCrc32.GetMemoryCRC32(r.ReadBytes(Pack.buildBuffer[i].Size));
194 | //}
195 |
196 | //Pack.checksum = CProgram.vCCommon.Com_BlockChecksum(fs_headerLongs);
197 | //Pack.pure_checksum = CProgram.vCCommon.Com_BlockChecksumKey(fs_headerLongs, fs_checksumFeed);
198 |
199 | // As of yet unassigned
200 | //Pack.hashSize = 0;
201 | Pack.pakGamename = null;
202 |
203 | return Pack;
204 | }
205 |
206 |
207 | public struct SPack
208 | {
209 | public string pakFilename; // c:\quake2\baseq2\pak0.pak
210 | public string pakBasename; // pak0
211 | public string pakGamename; // baseq2
212 | public FileStream handle; // handle to pack file
213 | //public long checksum; // regular checksum
214 | //public long pure_checksum; // checksum for pure
215 | public int numfiles; // number of files in pak
216 | public List buildBuffer; // file entry
217 |
218 | public int packDirOffset;
219 | public int packDirLength;
220 | }
221 |
222 | public struct SFileInPack
223 | {
224 | public string Name; // name of the file
225 | public long Position; // file info position in pak
226 | public int Size; // file info size in pak
227 | }
228 |
229 |
230 | // ========================================================================
231 | // PCX FILE LOADING
232 | //
233 | // Used for as many images as possible
234 | // ========================================================================
235 | public struct SPCX
236 | {
237 | public byte manufacturer;
238 | public byte version;
239 | public byte encoding;
240 | public byte bits_per_pixel;
241 | public ushort xmin;
242 | public ushort ymin;
243 | public ushort xmax;
244 | public ushort ymax;
245 | public ushort hres;
246 | public ushort vres;
247 | public byte[] palette; // size: 48 (unsigned char ??)
248 | public byte reserved;
249 | public byte color_planes;
250 | public ushort bytes_per_line;
251 | public ushort palette_type;
252 | public byte[] filler; // size: 58
253 | public byte data; // unsigned char ??
254 | }
255 |
256 | /*typedef struct
257 | {
258 | char manufacturer;
259 | char version;
260 | char encoding;
261 | char bits_per_pixel;
262 | unsigned short xmin,ymin,xmax,ymax;
263 | unsigned short hres,vres;
264 | unsigned char palette[48];
265 | char reserved;
266 | char color_planes;
267 | unsigned short bytes_per_line;
268 | unsigned short palette_type;
269 | char filler[58];
270 | unsigned char data; // unbounded
271 | } pcx_t;*/
272 |
273 | }
274 | }
275 |
--------------------------------------------------------------------------------
/Game.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacqueskrige/quake2-csharp-xna/8d92b97d5cac4a4ed94fb90776157cc6c582c707/Game.ico
--------------------------------------------------------------------------------
/GameThumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacqueskrige/quake2-csharp-xna/8d92b97d5cac4a4ed94fb90776157cc6c582c707/GameThumbnail.png
--------------------------------------------------------------------------------
/Gamma.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using Microsoft.Xna.Framework.Graphics;
30 | using System.Text;
31 |
32 | namespace Q2BSP
33 | {
34 | public class CGamma
35 | {
36 | private float GammaValue;
37 |
38 | public CGamma()
39 | {
40 | GammaValue = 2.1f;
41 |
42 | CProgram.gQ2Game.gCMain.gSGlobal.HLSL.xGamma = GammaValue;
43 | }
44 |
45 | public void GammaLighten()
46 | {
47 | if (GammaValue > 5.0f)
48 | GammaValue = 5.0f;
49 |
50 | if (GammaValue == 5.0f)
51 | return;
52 |
53 | GammaValue += 0.02f;
54 | GammaValue = (float)Math.Round(GammaValue, 2);
55 |
56 | CProgram.gQ2Game.gCMain.gSGlobal.HLSL.xGamma = GammaValue;
57 |
58 | //SetGamma(GammaValue, GammaValue, GammaValue);
59 | }
60 |
61 | public void GammaDarken()
62 | {
63 | if (GammaValue < 1.0f)
64 | GammaValue = 1.0f;
65 |
66 | if (GammaValue <= 1.0f)
67 | return;
68 |
69 | GammaValue -= 0.02f;
70 | GammaValue = (float)Math.Round(GammaValue, 2);
71 |
72 | CProgram.gQ2Game.gCMain.gSGlobal.HLSL.xGamma = GammaValue;
73 |
74 | //SetGamma(GammaValue, GammaValue, GammaValue);
75 | }
76 |
77 | /*private void SetGamma(float Red, float Green, float Blue)
78 | {
79 | // map the float values (0.0 min, 1.0 max) to byte values (0 min, 255 max)
80 | //byte redOffset = (byte)(Red * 255);
81 | //byte greenOffset = (byte)(Green * 255);
82 | //byte blueOffset = (byte)(Blue * 255);
83 | short redOffset = (short)(Red * 255);
84 | short greenOffset = (short)(Green * 255);
85 | short blueOffset = (short)(Blue * 255);
86 |
87 | // get the gamma ramp
88 | GammaRamp ramp = CProgram.gQ2Game.gGraphicsDevice.GetGammaRamp();
89 | short[] r = ramp.GetRed();
90 | short[] g = ramp.GetGreen();
91 | short[] b = ramp.GetBlue();
92 |
93 | // set the gamma values
94 | // they are stored as shorts, but are treated as ushorts by the hardware
95 | // if the value is over short.MaxValue, subtract ushort.MaxValue from it
96 | for (short i = 0; i < 256; i++)
97 | {
98 | r[i] *= redOffset;
99 | if (r[i] > short.MaxValue)
100 | {
101 | r[i] -= (short)(r[i] - ushort.MaxValue * 2);
102 | System.Diagnostics.Debug.WriteLine("over red");
103 | }
104 | //if (r[i] > 2550)
105 | // r[i] = 2550;
106 |
107 | g[i] *= greenOffset;
108 | if (g[i] > short.MaxValue)
109 | {
110 | g[i] -= (short)(g[i] - ushort.MaxValue * 2);
111 | System.Diagnostics.Debug.WriteLine("over green");
112 | }
113 | //if (g[i] > 2550)
114 | // g[i] = 2550;
115 |
116 | b[i] *= blueOffset;
117 | if (b[i] > short.MaxValue)
118 | {
119 | b[i] -= (short)(b[i] - ushort.MaxValue * 2);
120 | System.Diagnostics.Debug.WriteLine("over blue");
121 | }
122 | //if (b[i] > 2550)
123 | // b[i] = 2550;
124 | }
125 |
126 | // set the gamma values
127 | ramp.SetRed(r);
128 | ramp.SetGreen(g);
129 | ramp.SetBlue(b);
130 | CProgram.gQ2Game.gGraphicsDevice.SetGammaRamp(true, ramp);
131 | }*/
132 |
133 | public float Gamma
134 | {
135 | get
136 | {
137 | return GammaValue;
138 | }
139 | }
140 |
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/Input.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using Microsoft.Xna.Framework;
30 | using Microsoft.Xna.Framework.Input;
31 |
32 | namespace Q2BSP
33 | {
34 | public class CInput
35 | {
36 | KeyboardState KeyboardStateLast;
37 | KeyboardState KeyboardStateCurrent;
38 |
39 | MouseState MouseStateOriginal;
40 | MouseState MouseStateCurrent;
41 |
42 | public CInput()
43 | {
44 | Mouse.SetPosition(CProgram.gQ2Game.gGraphicsDevice.Viewport.Width / 2, CProgram.gQ2Game.gGraphicsDevice.Viewport.Height / 2);
45 | MouseStateOriginal = Mouse.GetState();
46 | }
47 |
48 | public void ProcessMouse()
49 | {
50 | float RotationPitch = 0.0f;
51 | float RotationYaw = 0.0f;
52 | Quaternion RotationAdd;
53 |
54 | MouseStateCurrent = Mouse.GetState();
55 |
56 | if (MouseStateCurrent != MouseStateOriginal)
57 | {
58 | float xDifference = MouseStateCurrent.X - MouseStateOriginal.X;
59 | float yDifference = MouseStateCurrent.Y - MouseStateOriginal.Y;
60 |
61 | // the magic number 16 is used because its the number of milliseconds that passes when vsync is turned on
62 | // this ensures the mouse response remains constant whether vsync is turned on/off
63 | xDifference *= (16 / CProgram.gQ2Game.TargetElapsedTime.Milliseconds);
64 | yDifference *= (16 / CProgram.gQ2Game.TargetElapsedTime.Milliseconds);
65 |
66 | RotationYaw += CProgram.gQ2Game.gCMain.SpeedMouse * xDifference;
67 | RotationPitch -= CProgram.gQ2Game.gCMain.SpeedMouse * yDifference;
68 |
69 | Mouse.SetPosition(CProgram.gQ2Game.gGraphicsDevice.Viewport.Width / 2, CProgram.gQ2Game.gGraphicsDevice.Viewport.Height / 2);
70 | }
71 |
72 |
73 | // update camera pitch & yaw
74 | CClient.cl.RefDef.ViewAngles.X += Microsoft.Xna.Framework.MathHelper.ToDegrees(RotationPitch);
75 | CClient.cl.RefDef.ViewAngles.Z += Microsoft.Xna.Framework.MathHelper.ToDegrees(RotationYaw);
76 |
77 | if (CClient.cl.RefDef.ViewAngles.X < 0.0f)
78 | CClient.cl.RefDef.ViewAngles.X += 360.0f;
79 | else if (CClient.cl.RefDef.ViewAngles.X > 360.0f)
80 | CClient.cl.RefDef.ViewAngles.X -= 360.0f;
81 |
82 | if (CClient.cl.RefDef.ViewAngles.Z < 0.0f)
83 | CClient.cl.RefDef.ViewAngles.Z += 360.0f;
84 | else if (CClient.cl.RefDef.ViewAngles.Z > 360.0f)
85 | CClient.cl.RefDef.ViewAngles.Z -= 360.0f;
86 |
87 | // rotation
88 | RotationAdd = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), -RotationPitch) * Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), -RotationYaw);
89 | CClient.cl.RefDef.TargetAngles *= RotationAdd;
90 | }
91 |
92 | public void ProcessKeyboard()
93 | {
94 | float RotationRoll = 0.0f;
95 | Quaternion RotationAdd;
96 | Vector3 OriginAdd;
97 |
98 | KeyboardStateLast = KeyboardStateCurrent;
99 | KeyboardStateCurrent = Keyboard.GetState();
100 |
101 |
102 | // update camera roll
103 | if (KeyboardStateCurrent.IsKeyDown(Keys.Left) == true || KeyboardStateCurrent.IsKeyDown(Keys.Right) == true)
104 | {
105 | if (KeyboardStateCurrent.IsKeyDown(Keys.Left) == true)
106 | RotationRoll -= CProgram.gQ2Game.gCMain.SpeedRotation;
107 |
108 | if (KeyboardStateCurrent.IsKeyDown(Keys.Right) == true)
109 | RotationRoll += CProgram.gQ2Game.gCMain.SpeedRotation;
110 | }
111 |
112 | CClient.cl.RefDef.ViewAngles.Y += Microsoft.Xna.Framework.MathHelper.ToDegrees(RotationRoll);
113 |
114 | if (CClient.cl.RefDef.ViewAngles.Y < 0.0f)
115 | CClient.cl.RefDef.ViewAngles.Y += 360.0f;
116 | else if (CClient.cl.RefDef.ViewAngles.Y > 360.0f)
117 | CClient.cl.RefDef.ViewAngles.Y -= 360.0f;
118 |
119 |
120 | // movement for camera forward/backward
121 | if (KeyboardStateCurrent.IsKeyDown(Keys.Up) == true || KeyboardStateCurrent.IsKeyDown(Keys.Down) == true)
122 | {
123 | if (KeyboardStateCurrent.IsKeyDown(Keys.Up) == true)
124 | CProgram.gQ2Game.gCMain.MoveForward = -1;
125 |
126 | if (KeyboardStateCurrent.IsKeyDown(Keys.Down) == true)
127 | CProgram.gQ2Game.gCMain.MoveForward = 1;
128 | }
129 | else
130 | {
131 | CProgram.gQ2Game.gCMain.MoveForward = 0;
132 | }
133 |
134 | // movement for camera left/right (strafe)
135 | if (KeyboardStateCurrent.IsKeyDown(Keys.Z) == true || KeyboardStateCurrent.IsKeyDown(Keys.X) == true)
136 | {
137 | if (KeyboardStateCurrent.IsKeyDown(Keys.Z) == true)
138 | CProgram.gQ2Game.gCMain.MoveSide = 1;
139 |
140 | if (KeyboardStateCurrent.IsKeyDown(Keys.X) == true)
141 | CProgram.gQ2Game.gCMain.MoveSide = -1;
142 | }
143 | else
144 | {
145 | CProgram.gQ2Game.gCMain.MoveSide = 0;
146 | }
147 |
148 | // movement for camera up/down
149 | if (KeyboardStateCurrent.IsKeyDown(Keys.Q) == true || KeyboardStateCurrent.IsKeyDown(Keys.A) == true)
150 | {
151 | if (KeyboardStateCurrent.IsKeyDown(Keys.Q) == true)
152 | CProgram.gQ2Game.gCMain.MoveUp = 1;
153 |
154 | if (KeyboardStateCurrent.IsKeyDown(Keys.A) == true)
155 | CProgram.gQ2Game.gCMain.MoveUp = -1;
156 | }
157 | else
158 | {
159 | CProgram.gQ2Game.gCMain.MoveUp = 0;
160 | }
161 |
162 | // quit
163 | if (KeyboardStateCurrent.IsKeyDown(Keys.Escape) == true)
164 | {
165 | CProgram.gQ2Game.Exit();
166 | }
167 |
168 | // switch between wireframe and solid rendering modes
169 | if (KeyboardStateCurrent.IsKeyDown(Keys.O) == true && KeyboardStateLast.IsKeyUp(Keys.O) == true)
170 | {
171 | CProgram.gQ2Game.gCMain.r_wireframe = !CProgram.gQ2Game.gCMain.r_wireframe;
172 | }
173 |
174 | // switch entity on and off
175 | if (KeyboardStateCurrent.IsKeyDown(Keys.E) == true && KeyboardStateLast.IsKeyUp(Keys.E) == true)
176 | {
177 | CProgram.gQ2Game.gCMain.r_drawentities = !CProgram.gQ2Game.gCMain.r_drawentities;
178 | }
179 |
180 | // set the gamma intensity
181 | if (KeyboardStateCurrent.IsKeyDown(Keys.Subtract) == true)
182 | {
183 | CProgram.gQ2Game.gCGamma.GammaDarken();
184 | }
185 | if (KeyboardStateCurrent.IsKeyDown(Keys.Add) == true)
186 | {
187 | CProgram.gQ2Game.gCGamma.GammaLighten();
188 | }
189 |
190 | // switch hardware pointlight on and off
191 | if (KeyboardStateCurrent.IsKeyDown(Keys.P) == true && KeyboardStateLast.IsKeyUp(Keys.P) == true)
192 | {
193 | CProgram.gQ2Game.gCMain.gSGlobal.HLSL.xPointLights = !CProgram.gQ2Game.gCMain.gSGlobal.HLSL.xPointLights;
194 | }
195 |
196 | // switch between hardware per-pixel lighting and classic lightmaps
197 | if (KeyboardStateCurrent.IsKeyDown(Keys.H) == true && KeyboardStateLast.IsKeyUp(Keys.H) == true)
198 | {
199 | CProgram.gQ2Game.gCMain.r_hardwarelight = !CProgram.gQ2Game.gCMain.r_hardwarelight;
200 | }
201 |
202 | // switch pvs lock on and off
203 | if (KeyboardStateCurrent.IsKeyDown(Keys.L) == true && KeyboardStateLast.IsKeyUp(Keys.L) == true)
204 | {
205 | CProgram.gQ2Game.gCMain.r_lockpvs = !CProgram.gQ2Game.gCMain.r_lockpvs;
206 | }
207 |
208 | // switch bloom on and off
209 | if (KeyboardStateCurrent.IsKeyDown(Keys.B) == true && KeyboardStateLast.IsKeyUp(Keys.B) == true)
210 | {
211 | CProgram.gQ2Game.gCMain.r_bloom = !CProgram.gQ2Game.gCMain.r_bloom;
212 | }
213 |
214 | if (KeyboardStateCurrent.IsKeyDown(Keys.Space) == true && KeyboardStateLast.IsKeyUp(Keys.Space) == true)
215 | {
216 | CProgram.gQ2Game.gCMain.r_controls = !CProgram.gQ2Game.gCMain.r_controls;
217 | }
218 |
219 |
220 | // rotation
221 | RotationAdd = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), -RotationRoll);
222 | CClient.cl.RefDef.TargetAngles *= RotationAdd;
223 |
224 | // move left/right
225 | OriginAdd = Vector3.Transform(new Vector3(1, 0, 0), CClient.cl.RefDef.TargetAngles);
226 | CClient.cl.RefDef.TargetOrigin += OriginAdd * CProgram.gQ2Game.gCMain.SpeedSide;
227 |
228 | // move forward/backward
229 | OriginAdd = Vector3.Transform(new Vector3(0, 1, 0), CClient.cl.RefDef.TargetAngles);
230 | CClient.cl.RefDef.TargetOrigin += OriginAdd * CProgram.gQ2Game.gCMain.SpeedForward;
231 |
232 | // move up/down
233 | OriginAdd = Vector3.Transform(new Vector3(0, 0, 1), CClient.cl.RefDef.TargetAngles);
234 | CClient.cl.RefDef.TargetOrigin += OriginAdd * CProgram.gQ2Game.gCMain.SpeedUp;
235 |
236 | // update ViewOrigin
237 | CClient.cl.RefDef.ViewOrigin = CClient.cl.RefDef.TargetOrigin;
238 | }
239 |
240 | }
241 | }
242 |
--------------------------------------------------------------------------------
/Library/Command.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using System.IO;
30 | using System.Text;
31 |
32 | namespace Q2BSP.Library
33 | {
34 | public class CCommand
35 | {
36 | public const string TextReturn = "\r\n";
37 |
38 | public static bool WriteFile(string FilePath, string FileData)
39 | {
40 | FileStream FS;
41 | BinaryWriter BW;
42 |
43 | if (string.IsNullOrEmpty(FilePath) == true)
44 | return false;
45 |
46 | if (string.IsNullOrEmpty(FileData) == true)
47 | return false;
48 |
49 | FS = System.IO.File.Open(FilePath, FileMode.Create, FileAccess.Write);
50 |
51 | if (FS == null)
52 | return false;
53 |
54 | BW = new BinaryWriter(FS);
55 | for (int i = 0; i < FileData.Length; i++)
56 | {
57 | BW.Write(FileData[i]);
58 | }
59 |
60 | BW.Close();
61 | BW = null;
62 |
63 | FS.Close();
64 | FS.Dispose();
65 | FS = null;
66 |
67 | return true;
68 | }
69 |
70 | public static string LoadFile(string FileName)
71 | {
72 | string MapData;
73 | char[] ch;
74 | FileStream FS;
75 | BinaryReader BR;
76 | StringBuilder SB;
77 |
78 | if (string.IsNullOrEmpty(FileName) == true)
79 | return null;
80 |
81 | FS = System.IO.File.OpenRead(FileName);
82 |
83 | if (FS == null)
84 | return null;
85 |
86 | BR = new BinaryReader(FS);
87 | ch = BR.ReadChars((int)FS.Length);
88 |
89 | BR.Close();
90 | BR = null;
91 |
92 | FS.Close();
93 | FS.Dispose();
94 | FS = null;
95 |
96 | SB = new StringBuilder(ch.Length);
97 | SB.Append(ch);
98 |
99 | MapData = SB.ToString();
100 |
101 | if (string.IsNullOrEmpty(MapData) == true)
102 | return null;
103 |
104 | // fix line ends
105 | MapData = MapData.Replace("\r", "").Replace("\n", "\r\n");
106 |
107 | return MapData;
108 | }
109 |
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/Library/Script.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using System.Text;
30 |
31 | namespace Q2BSP.Library
32 | {
33 | public class CScript
34 | {
35 | private const int MAX_INCLUDES = 8;
36 | private const int MAX_TOKEN = 1024;
37 |
38 | //private cCommand vCommand;
39 |
40 | //private string InputData;
41 | //private SScript[] ScriptStack;
42 | private List Script;
43 | public int ScriptLine;
44 |
45 | public string Token;
46 | //private bool ScriptEnd;
47 | private bool TokenReady; // only qtrue if UnGetToken was just called
48 |
49 | public CScript(/*string Input*/)
50 | {
51 | //if (string.IsNullOrEmpty(Input) == true)
52 | // InputData = null;
53 | //else
54 | // InputData = Input.Trim();
55 |
56 | //vCommand = new cCommand();
57 |
58 | //ScriptStack = new SScript[MAX_INCLUDES];
59 | Script = new List();
60 | }
61 |
62 | /*public bool BufferAvailable()
63 | {
64 | if (string.IsNullOrEmpty(Script[Script.Count - 1].Buffer) == true)
65 | return false;
66 | else
67 | return true;
68 | }*/
69 |
70 | // ================
71 | // AddScriptToStack
72 | // ================
73 | private void AddScriptToStack(string FileName)
74 | {
75 | SScript _Script;
76 |
77 | if (Script.Count == MAX_INCLUDES - 1)
78 | CMain.Error(CMain.EErrorParm.ERR_FATAL, "Script file exceeded MAX_INCLUDES");
79 |
80 | _Script.FileName = FileName;
81 | _Script.Buffer = CCommand.LoadFile(_Script.FileName);
82 |
83 | CMain.Printf("entering " + _Script.FileName + "\n");
84 |
85 | _Script.Line = 1;
86 |
87 | // jkrige - todo
88 | _Script.StartPosition = 0;
89 | _Script.EndPosition = _Script.Buffer.Length - 1;
90 | //script->script_p = script->buffer;
91 | //script->end_p = script->buffer + size;
92 | // jkrige - todo
93 |
94 | Script.Add(_Script);
95 | }
96 |
97 | // ================
98 | // LoadScriptFile
99 | // ================
100 | public string LoadScriptFile(string FileName)
101 | {
102 | AddScriptToStack(FileName);
103 |
104 | //ScriptEnd = false;
105 | TokenReady = false;
106 |
107 | return Script[Script.Count - 1].Buffer;
108 | }
109 |
110 | // ================
111 | // ParseFromMemory
112 | // ================
113 | public void ParseFromMemory(string buffer)
114 | {
115 | SScript _Script;
116 |
117 | if (Script.Count == MAX_INCLUDES)
118 | CMain.Error(CMain.EErrorParm.ERR_FATAL, "Script file exceeded MAX_INCLUDES");
119 |
120 | _Script.FileName = "memory buffer";
121 | _Script.Buffer = buffer;
122 |
123 | _Script.Line = 1;
124 |
125 | // jkrige - todo
126 | _Script.StartPosition = 0;
127 | _Script.EndPosition = _Script.Buffer.Length - 1;
128 | //script->script_p = script->buffer;
129 | //script->end_p = script->buffer + size;
130 | // jkrige - todo
131 |
132 | Script.Add(_Script);
133 |
134 | //ScriptEnd = false;
135 | TokenReady = false;
136 | }
137 |
138 | // ================
139 | // UnGetToken
140 | //
141 | // Signals that the current token was not used, and should be reported for the next GetToken.
142 | // Note that
143 | //
144 | // GetToken(qtrue);
145 | // UnGetToken();
146 | // GetToken (qfalse);
147 | //
148 | // could cross a line boundary.
149 | // ================
150 | public void UnGetToken()
151 | {
152 | TokenReady = true;
153 | }
154 |
155 | public bool EndOfScript(bool CrossLine)
156 | {
157 | SScript _Script;
158 |
159 | if (CrossLine == false)
160 | CMain.Error(CMain.EErrorParm.ERR_FATAL, "Line " + ScriptLine + " is incomplete.");
161 |
162 | if (Script[Script.Count - 1].FileName == "memory buffer")
163 | {
164 | //ScriptEnd = true;
165 | return false;
166 | }
167 |
168 | _Script = Script[Script.Count - 1];
169 | _Script.Buffer = "";
170 | Script[Script.Count - 1] = _Script;
171 |
172 | // jkrige - check : this IF statement
173 | //if (Script.Count == MAX_INCLUDES)
174 | // return false;
175 |
176 | if (Script.Count == 1)
177 | {
178 | return false;
179 | }
180 | // jkrige - check : this IF statement
181 |
182 | Script.RemoveAt(Script.Count - 1);
183 | ScriptLine = Script[Script.Count - 1].Line;
184 | CMain.Printf("returning to " + Script[Script.Count - 1].FileName + "\n");
185 |
186 | return GetToken(CrossLine);
187 | }
188 |
189 | // ================
190 | // GetToken
191 | // ================
192 | public bool GetToken(bool CrossLine)
193 | {
194 | string token_p;
195 | SScript _Script;
196 |
197 | // is a token already waiting?
198 | if (TokenReady == true)
199 | {
200 | TokenReady = false;
201 | return true;
202 | }
203 |
204 | //token_p = "";
205 | _Script = Script[Script.Count - 1];
206 |
207 | if (_Script.StartPosition >= _Script.EndPosition)
208 | return EndOfScript(CrossLine);
209 |
210 |
211 | //
212 | // skip space
213 | //
214 |
215 | skipspace:
216 | while (_Script.Buffer[_Script.StartPosition] <= 32)
217 | {
218 | if (_Script.StartPosition >= _Script.EndPosition)
219 | {
220 | Script[Script.Count - 1] = _Script;
221 | return EndOfScript(CrossLine);
222 | }
223 |
224 | if (_Script.Buffer[_Script.StartPosition++] == '\n')
225 | {
226 | if(CrossLine == false)
227 | CMain.Error(CMain.EErrorParm.ERR_FATAL, "Line " + ScriptLine + " is incomplete.");
228 |
229 | ScriptLine = _Script.Line++;
230 | }
231 | }
232 |
233 | if (_Script.StartPosition >= _Script.EndPosition)
234 | {
235 | Script[Script.Count - 1] = _Script;
236 | return EndOfScript(CrossLine);
237 | }
238 |
239 | // ; # // comments
240 | if (
241 | _Script.Buffer[_Script.StartPosition] == ';'
242 | || _Script.Buffer[_Script.StartPosition] == '#'
243 | || (_Script.Buffer[_Script.StartPosition] == '/' && _Script.Buffer[_Script.StartPosition + 1] == '/')
244 | )
245 | {
246 | if (CrossLine == false)
247 | CMain.Error(CMain.EErrorParm.ERR_FATAL, "Line " + ScriptLine + " is incomplete.");
248 |
249 | while (_Script.Buffer[_Script.StartPosition++] != '\n')
250 | {
251 | if (_Script.StartPosition >= _Script.EndPosition)
252 | {
253 | Script[Script.Count - 1] = _Script;
254 | return EndOfScript(CrossLine);
255 | }
256 | }
257 |
258 | ScriptLine = _Script.Line++;
259 | Script[Script.Count - 1] = _Script;
260 | goto skipspace;
261 | }
262 |
263 | // /* */ comments
264 | if (_Script.Buffer[_Script.StartPosition] == '/' && _Script.Buffer[_Script.StartPosition + 1] == '*')
265 | {
266 | if (CrossLine == false)
267 | CMain.Error(CMain.EErrorParm.ERR_FATAL, "Line " + ScriptLine + " is incomplete.");
268 |
269 | _Script.StartPosition += 2;
270 |
271 | while (_Script.Buffer[_Script.StartPosition] != '*' && _Script.Buffer[_Script.StartPosition + 1] != '/')
272 | {
273 | if (_Script.Buffer[_Script.StartPosition] == '\n')
274 | ScriptLine = _Script.Line++;
275 |
276 | _Script.StartPosition++;
277 |
278 | if (_Script.StartPosition >= _Script.EndPosition)
279 | {
280 | Script[Script.Count - 1] = _Script;
281 | return EndOfScript(CrossLine);
282 | }
283 | }
284 |
285 | _Script.StartPosition += 2;
286 | Script[Script.Count - 1] = _Script;
287 | goto skipspace;
288 | }
289 |
290 |
291 | //
292 | // copy token
293 | //
294 |
295 | token_p = "";
296 | //token_p = Token;
297 | //int test = _Script.Position;
298 |
299 | if (_Script.Buffer[_Script.StartPosition] == '"')
300 | {
301 | // quoted token
302 | _Script.StartPosition++;
303 |
304 | while (_Script.Buffer[_Script.StartPosition] != '"')
305 | {
306 | token_p = token_p + _Script.Buffer[_Script.StartPosition++];
307 |
308 | if (_Script.StartPosition == _Script.EndPosition)
309 | break;
310 |
311 | if (token_p.Length >= MAX_TOKEN)
312 | CMain.Error(CMain.EErrorParm.ERR_FATAL, "Token too large on line " + ScriptLine + ".");
313 | }
314 | _Script.StartPosition++;
315 | }
316 | else
317 | {
318 | // regular token
319 | while (_Script.Buffer[_Script.StartPosition] > 32 && _Script.Buffer[_Script.StartPosition] != ';')
320 | {
321 | token_p = token_p + _Script.Buffer[_Script.StartPosition++];
322 |
323 | if (_Script.StartPosition == _Script.EndPosition)
324 | break;
325 |
326 | if (token_p.Length >= MAX_TOKEN)
327 | CMain.Error(CMain.EErrorParm.ERR_FATAL, "Token too large on line " + ScriptLine + ".");
328 | }
329 | }
330 |
331 | Token = token_p;
332 | Script[Script.Count - 1] = _Script;
333 |
334 | if (Token == "$include")
335 | {
336 | GetToken(false);
337 | AddScriptToStack(Token);
338 |
339 | return GetToken(CrossLine);
340 | }
341 |
342 | return true;
343 | }
344 |
345 | // ================
346 | // TokenAvailable
347 | //
348 | // Returns qtrue if there is another token on the line
349 | // ================
350 | public bool TokenAvailable()
351 | {
352 | int oldLine;
353 | bool r;
354 |
355 | oldLine = Script[Script.Count - 1].Line;
356 | r = GetToken(true);
357 |
358 | if (r == false)
359 | return false;
360 |
361 | UnGetToken();
362 |
363 | if (oldLine == Script[Script.Count - 1].Line)
364 | return true;
365 |
366 | return false;
367 | }
368 |
369 |
370 | // =====================================================================
371 |
372 | public void MatchToken(string Match)
373 | {
374 | GetToken(true);
375 |
376 | if (Token != Match)
377 | CMain.Error(CMain.EErrorParm.ERR_FATAL, "MatchToken( \"" + Match + "\" ) failed at line " + ScriptLine + ".");
378 | }
379 |
380 | /*public void Parse1DMatrix(int x, ref cMath.Vec[] v, int vPosition)
381 | {
382 | MatchToken("(");
383 |
384 | if (v != null)
385 | {
386 | for (int i = 0; i < x; i++)
387 | {
388 | GetToken(false);
389 | v[vPosition + i].Value = Convert.ToSingle(Token);
390 | }
391 | }
392 |
393 | MatchToken(")");
394 | }*/
395 |
396 | /*public void Parse2DMatrix(int y, int x, ref cMath.Vec[] v, int vPosition)
397 | {
398 | MatchToken("(");
399 |
400 | if (v != null)
401 | {
402 | for (int i = 0; i < y; i++)
403 | {
404 | Parse1DMatrix(x, ref v, vPosition + i * x);
405 | }
406 | }
407 |
408 | MatchToken(")");
409 | }*/
410 |
411 | /*public void Parse3DMatrix(int z, int y, int x, ref cMath.Vec[] v, int vPosition)
412 | {
413 | MatchToken("(");
414 |
415 | if (v != null)
416 | {
417 | for (int i = 0; i < z; i++)
418 | {
419 | Parse2DMatrix(y, x, ref v, vPosition + i * x * y);
420 | }
421 | }
422 |
423 | MatchToken(")");
424 | }*/
425 |
426 | /*public void Write1DMatrix(System.IO.FileStream FS, int x, ref cMath.Vec[] v, int vPosition)
427 | {
428 | System.IO.BinaryWriter BW = new System.IO.BinaryWriter(FS);
429 |
430 | BW.Write("( ");
431 |
432 | if (v != null)
433 | {
434 | for (int i = 0; i < x; i++)
435 | {
436 | if (v[vPosition + i].Value == System.Math.Round(v[vPosition + i].Value))
437 | {
438 | BW.Write(System.Math.Round(v[vPosition + i].Value).ToString() + " ");
439 | }
440 | else
441 | {
442 | BW.Write(v[vPosition + i].Value.ToString() + " ");
443 | }
444 | }
445 | }
446 |
447 | BW.Write(")");
448 | }*/
449 |
450 | /*public void Write2DMatrix(System.IO.FileStream FS, int y, int x, ref cMath.Vec[] v, int vPosition)
451 | {
452 | System.IO.BinaryWriter BW = new System.IO.BinaryWriter(FS);
453 |
454 | BW.Write("( ");
455 |
456 | if (v != null)
457 | {
458 | for (int i = 0; i < y; i++)
459 | {
460 | Write1DMatrix(FS, x, ref v, vPosition + i * x);
461 | BW.Write(" ");
462 | }
463 | }
464 |
465 | BW.Write(")\n");
466 | }*/
467 |
468 | /*public void Write3DMatrix(System.IO.FileStream FS, int z, int y, int x, ref cMath.Vec[] v, int vPosition)
469 | {
470 | System.IO.BinaryWriter BW = new System.IO.BinaryWriter(FS);
471 |
472 | BW.Write("(\n");
473 |
474 | if (v != null)
475 | {
476 | for (int i = 0; i < z; i++)
477 | {
478 | Write2DMatrix(FS, y, x, ref v, vPosition + i * x * y);
479 | }
480 | }
481 |
482 | BW.Write(")\n");
483 | }*/
484 |
485 | private struct SScript
486 | {
487 | public string FileName;
488 | public string Buffer;
489 | public int StartPosition;
490 | public int EndPosition;
491 | public int Line;
492 | }
493 |
494 | }
495 | }
496 |
--------------------------------------------------------------------------------
/Local.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using Microsoft.Xna.Framework;
30 | using Microsoft.Xna.Framework.Graphics;
31 |
32 | namespace Q2BSP
33 | {
34 | public class CLocal
35 | {
36 | public const int MAX_LIGHTSTYLES = 256;
37 | public const int TEXNUM_LIGHTMAPS = 1024;
38 | public const int MAX_LBM_HEIGHT = 480;
39 |
40 | public const float gl_modulate = 1.0f;
41 |
42 | public static BoundingBox ClearBounds()
43 | {
44 | BoundingBox bounds;
45 |
46 | bounds.Min.X = bounds.Min.Y = bounds.Min.Z = 99999;
47 | bounds.Max.X = bounds.Max.Y = bounds.Max.Z = -99999;
48 |
49 | return bounds;
50 | }
51 |
52 | public static void AddPointToBounds(Vector3 v, ref BoundingBox bounds)
53 | {
54 | if (v.X < bounds.Min.X)
55 | bounds.Min.X = v.X;
56 |
57 | if (v.X > bounds.Max.X)
58 | bounds.Max.X = v.X;
59 |
60 |
61 | if (v.Y < bounds.Min.Y)
62 | bounds.Min.Y = v.Y;
63 |
64 | if (v.Y > bounds.Max.Y)
65 | bounds.Max.Y = v.Y;
66 |
67 |
68 | if (v.Z < bounds.Min.Z)
69 | bounds.Min.Z = v.Z;
70 |
71 | if (v.Z > bounds.Max.Z)
72 | bounds.Max.Z = v.Z;
73 | }
74 |
75 |
76 |
77 | public struct SLightStyle
78 | {
79 | public float[] rgb; // size: 3 (0.0 - 2.0)
80 | public float white; // highest of rgb
81 | }
82 |
83 | public struct SRefDef
84 | {
85 | public Vector3 ViewOrigin;
86 | public Vector3 ViewAngles;
87 | public Vector3 ViewUp;
88 |
89 | public Vector3 TargetOrigin;
90 | public Quaternion TargetAngles;
91 |
92 | public BoundingFrustum FrustumBounds;
93 |
94 | public int EntityIndex;
95 |
96 | public string MapName;
97 |
98 | public SLightStyle[] lightstyles; // size: MAX_LIGHTSTYLES
99 | }
100 |
101 | public struct SHLSL
102 | {
103 | public Matrix xViewMatrix;
104 | public Matrix xProjectionMatrix;
105 | public Matrix xWorld;
106 | public Color xLightModel;
107 | public Color xLightAmbient;
108 | public float xLightPower;
109 | public float xTextureAlpha;
110 | public float xGamma;
111 | public float xRealTime;
112 | public float xBloomThreshold;
113 | public float xBaseIntensity;
114 | public float xBloomIntensity;
115 | public float xBaseSaturation;
116 | public float xBloomSaturation;
117 | public bool xPointLights;
118 | public bool xFlow;
119 | }
120 |
121 | public struct SGlobal
122 | {
123 | public SHLSL HLSL;
124 | public SHLSL OldHLSL;
125 | }
126 |
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/PointLight.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using Microsoft.Xna.Framework;
30 | using Microsoft.Xna.Framework.Graphics;
31 | using System.Text;
32 |
33 | namespace Q2BSP
34 | {
35 | public class CPointLight
36 | {
37 | //////////////////////////////////////////////////////////////
38 | // The only parameter that will be changing for every light //
39 | // each frame is the postion parameter. For the sake of //
40 | // reducing string look-ups, the position parameter is //
41 | // stored as a parameter instance. The other parameters //
42 | // are updated much less frequently, so a tradeoff has been //
43 | // made for clarity. //
44 | //////////////////////////////////////////////////////////////
45 |
46 | private EffectParameter positionParameter;
47 | private EffectParameter instanceParameter;
48 |
49 | private float LightRange = 300.0f;
50 | private float LightFalloff = 1.1f;
51 | private Vector4 LightPosition;
52 | private Color LightColor = Color.White;
53 |
54 | public CPointLight(Vector4 initialPosition)
55 | {
56 | gPosition = initialPosition;
57 | }
58 |
59 | public CPointLight(Vector4 initialPosition, float initialRange)
60 | {
61 | gPosition = initialPosition;
62 | gRange = initialRange;
63 | }
64 |
65 | public CPointLight(Vector4 initialPosition, float initialRange, float Red, float Green, float Blue)
66 | {
67 | gPosition = initialPosition;
68 | gRange = initialRange;
69 | LightColor.R = (byte)(255 * Red);
70 | LightColor.G = (byte)(255 * Green);
71 | LightColor.B = (byte)(255 * Blue);
72 | LightColor.A = (byte)255;
73 | gColor = LightColor;
74 | }
75 |
76 | public CPointLight(Vector4 initialPosition, EffectParameter lightParameter)
77 | {
78 | //////////////////////////////////////////////////////////////
79 | // An instance of a light is bound to an instance of a //
80 | // Light structure defined in the effect. The //
81 | // "StructureMembers" property of a parameter is used to //
82 | // access the individual fields of a structure. //
83 | //////////////////////////////////////////////////////////////
84 | instanceParameter = lightParameter;
85 | positionParameter = instanceParameter.StructureMembers["position"];
86 | gPosition = initialPosition;
87 | instanceParameter.StructureMembers["range"].SetValue(LightRange);
88 | instanceParameter.StructureMembers["falloff"].SetValue(LightFalloff);
89 | instanceParameter.StructureMembers["color"].SetValue(LightColor.ToVector4());
90 | }
91 |
92 | public void SetLight(EffectParameter lightParameter)
93 | {
94 | instanceParameter = lightParameter;
95 |
96 | //if (CProgram.gQ2Game.gCMain.r_hardwarelight == false)
97 | // return;
98 |
99 | instanceParameter.StructureMembers["position"].SetValue(LightPosition);
100 | instanceParameter.StructureMembers["range"].SetValue(LightRange);
101 | instanceParameter.StructureMembers["falloff"].SetValue(LightFalloff);
102 | instanceParameter.StructureMembers["color"].SetValue(LightColor.ToVector4());
103 |
104 | // generic.fx
105 | //struct Light
106 | //{
107 | // float4 color; // 0
108 | // float4 position; // 1
109 | // float falloff; // 2
110 | // float range; // 3
111 | //};
112 | //instanceParameter.StructureMembers[0].SetValue(LightColor.ToVector4()); // "color"
113 | //instanceParameter.StructureMembers[1].SetValue(LightPosition); // "position"
114 | //instanceParameter.StructureMembers[2].SetValue(LightFalloff); // "falloff"
115 | //instanceParameter.StructureMembers[3].SetValue(LightRange); // "range"
116 | }
117 |
118 | #region Light Properties
119 | public Vector4 gPosition
120 | {
121 | set
122 | {
123 | LightPosition = value;
124 |
125 | if (positionParameter != null)
126 | positionParameter.SetValue(LightPosition);
127 | }
128 | get
129 | {
130 | return LightPosition;
131 | }
132 | }
133 |
134 |
135 | public Color gColor
136 | {
137 | set
138 | {
139 | LightColor = value;
140 |
141 | if (instanceParameter != null)
142 | instanceParameter.StructureMembers["color"].SetValue(LightColor.ToVector4());
143 | }
144 | get
145 | {
146 | return LightColor;
147 | }
148 | }
149 |
150 | public float gRange
151 | {
152 | set
153 | {
154 | LightRange = value;
155 |
156 | if (instanceParameter != null)
157 | instanceParameter.StructureMembers["range"].SetValue(LightRange);
158 | }
159 | get
160 | {
161 | return LightRange;
162 | }
163 | }
164 |
165 |
166 | public float gFalloff
167 | {
168 | set
169 | {
170 | LightFalloff = value;
171 |
172 | if (instanceParameter != null)
173 | instanceParameter.StructureMembers["falloff"].SetValue(LightFalloff);
174 | }
175 | get
176 | {
177 | return LightFalloff;
178 | }
179 | }
180 | #endregion
181 | }
182 | }
183 |
--------------------------------------------------------------------------------
/Program.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 |
29 | namespace Q2BSP
30 | {
31 | public static class CProgram
32 | {
33 | public static CQ2Game gQ2Game;
34 |
35 | ///
36 | /// Main
37 | /// ----
38 | /// The main entry point for the application.
39 | ///
40 | static void Main(string[] args)
41 | {
42 | using (gQ2Game = new CQ2Game())
43 | {
44 | gQ2Game.Run();
45 | }
46 | }
47 | }
48 | }
49 |
50 |
--------------------------------------------------------------------------------
/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Q2BSP")]
9 | [assembly: AssemblyProduct("Q2BSP")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyCompany("Korvin Korax")]
12 |
13 | [assembly: AssemblyCopyright("Copyright © Korvin Korax 2011")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("c505cbf7-5ceb-41e7-8119-5a179c33bf3e")]
24 |
25 |
26 | // Version information for an assembly consists of the following four values:
27 | //
28 | // Major Version
29 | // Minor Version
30 | // Build Number
31 | // Revision
32 | //
33 | [assembly: AssemblyVersion("1.0.0.0")]
34 |
--------------------------------------------------------------------------------
/Q2BSP.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {16A93DDD-6C32-43A3-B219-E5BD5A27AF39}
5 | {6D335F3A-9D43-41b4-9D22-F6F17C4BE596};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
6 | Debug
7 | x86
8 | WinExe
9 | Properties
10 | Q2BSP
11 | Q2BSP
12 | v4.0
13 | v4.0
14 | Windows
15 | e6fb21a1-52c0-49f5-83fa-6a793ad6ba24
16 | Game.ico
17 | GameThumbnail.png
18 | true
19 |
20 |
21 | Game
22 | HiDef
23 | Client
24 |
25 |
26 | 3.5
27 |
28 | http://localhost/Q2BSP/
29 | true
30 | Web
31 | true
32 | Foreground
33 | 7
34 | Days
35 | false
36 | false
37 | true
38 | 0
39 | 1.0.0.%2a
40 | false
41 | true
42 |
43 |
44 | true
45 | full
46 | false
47 | bin\x86\Debug
48 | DEBUG;TRACE;WINDOWS
49 | prompt
50 | 4
51 | true
52 | false
53 | x86
54 | false
55 | AllRules.ruleset
56 |
57 |
58 | pdbonly
59 | true
60 | bin\x86\Release
61 | TRACE;WINDOWS
62 | prompt
63 | 4
64 | true
65 | false
66 | x86
67 | True
68 | AllRules.ruleset
69 |
70 |
71 |
72 | False
73 |
74 |
75 | False
76 |
77 |
78 | False
79 |
80 |
81 | False
82 |
83 |
84 | False
85 |
86 |
87 | False
88 |
89 |
90 | False
91 |
92 |
93 | False
94 |
95 |
96 | False
97 |
98 |
99 | False
100 |
101 |
102 | False
103 |
104 |
105 | False
106 |
107 |
108 |
109 |
110 |
111 | False
112 |
113 |
114 | False
115 |
116 |
117 | False
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 | 29204dfd-5723-48db-ac99-a8208752e4f1
159 | False
160 |
161 |
162 |
163 |
164 | False
165 | .NET Framework 3.5 SP1 Client Profile
166 | false
167 |
168 |
169 | False
170 | .NET Framework 2.0 %28x86%29
171 | false
172 |
173 |
174 | False
175 | .NET Framework 3.0 %28x86%29
176 | false
177 |
178 |
179 | False
180 | .NET Framework 3.5
181 | false
182 |
183 |
184 | False
185 | .NET Framework 3.5 SP1
186 | true
187 |
188 |
189 | False
190 | Windows Installer 3.1
191 | true
192 |
193 |
194 | False
195 | Microsoft XNA Framework Redistributable 3.0
196 | true
197 |
198 |
199 | False
200 | Microsoft XNA Framework Redistributable 4.0
201 | true
202 |
203 |
204 |
205 |
206 | {29204DFD-5723-48DB-AC99-A8208752E4F1}
207 | Q2BSPContent %28Content%29
208 | Content
209 |
210 |
211 |
212 |
213 | Designer
214 |
215 |
216 |
217 |
218 |
225 |
--------------------------------------------------------------------------------
/Q2BSP.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Q2BSP", "Q2BSP.csproj", "{16A93DDD-6C32-43A3-B219-E5BD5A27AF39}"
5 | EndProject
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Q2BSPContent", "Content\Q2BSPContent.contentproj", "{29204DFD-5723-48DB-AC99-A8208752E4F1}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x86 = Debug|x86
11 | Release|x86 = Release|x86
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {16A93DDD-6C32-43A3-B219-E5BD5A27AF39}.Debug|x86.ActiveCfg = Debug|x86
15 | {16A93DDD-6C32-43A3-B219-E5BD5A27AF39}.Debug|x86.Build.0 = Debug|x86
16 | {16A93DDD-6C32-43A3-B219-E5BD5A27AF39}.Release|x86.ActiveCfg = Release|x86
17 | {16A93DDD-6C32-43A3-B219-E5BD5A27AF39}.Release|x86.Build.0 = Release|x86
18 | {29204DFD-5723-48DB-AC99-A8208752E4F1}.Debug|x86.ActiveCfg = Debug|x86
19 | {29204DFD-5723-48DB-AC99-A8208752E4F1}.Release|x86.ActiveCfg = Release|x86
20 | EndGlobalSection
21 | GlobalSection(SolutionProperties) = preSolution
22 | HideSolutionNode = FALSE
23 | EndGlobalSection
24 | EndGlobal
25 |
--------------------------------------------------------------------------------
/Q2Game.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using Microsoft.Xna.Framework;
30 | using Microsoft.Xna.Framework.Audio;
31 | using Microsoft.Xna.Framework.Content;
32 | using Microsoft.Xna.Framework.GamerServices;
33 | using Microsoft.Xna.Framework.Graphics;
34 | using Microsoft.Xna.Framework.Input;
35 | using Microsoft.Xna.Framework.Media;
36 | using Microsoft.Xna.Framework.Net;
37 | using Microsoft.Xna.Framework.Storage;
38 |
39 | namespace Q2BSP
40 | {
41 | ///
42 | /// This is the main type for your game
43 | ///
44 | public class CQ2Game : Microsoft.Xna.Framework.Game
45 | {
46 | public GraphicsDeviceManager gGraphicsDeviceManager;
47 | public GraphicsDevice gGraphicsDevice;
48 | public Effect gEffect;
49 | public SpriteBatch spriteBatch;
50 |
51 | public CMain gCMain;
52 | public CCommon gCCommon;
53 | public CGamma gCGamma;
54 |
55 | // temporary text drawing
56 | SpriteFont Font1;
57 | Vector2 FontPos;
58 |
59 | ///
60 | /// CQ2Game
61 | /// ----------
62 | /// The game constructor
63 | ///
64 | public CQ2Game()
65 | {
66 | gGraphicsDeviceManager = new GraphicsDeviceManager(this);
67 |
68 | Content.RootDirectory = "Content";
69 | }
70 |
71 | private void DrawOverlayText(Vector2 Origin, string Text, Color TextColor)
72 | {
73 | spriteBatch.Begin();
74 |
75 | Origin.X -= 1;
76 | Origin.Y -= 1;
77 | spriteBatch.DrawString(Font1, Text, FontPos, Color.Black, 0, Origin, 1.0f, SpriteEffects.None, 0.5f);
78 |
79 | Origin.X += 1;
80 | Origin.Y += 1;
81 | spriteBatch.DrawString(Font1, Text, FontPos, TextColor, 0, Origin, 1.0f, SpriteEffects.None, 0.5f);
82 |
83 | spriteBatch.End();
84 | }
85 |
86 |
87 | // =====================================================================
88 | //
89 | // XNA SPECIFIC FUNCTIONS
90 | //
91 | // =====================================================================
92 |
93 | ///
94 | /// Initialize
95 | /// ----------
96 | /// Allows the game to perform any initialization it needs to before starting to run.
97 | /// This is where it can query for any required services and load any non-graphic
98 | /// related content. Calling base.Initialize will enumerate through any components
99 | /// and initialize them as well.
100 | ///
101 | protected override void Initialize()
102 | {
103 | Window.Title = CMain.GameTitle;
104 | gGraphicsDeviceManager.PreferMultiSampling = true;
105 | gGraphicsDeviceManager.IsFullScreen = CConfig.GetConfigBOOL("Fullscreen");
106 |
107 | if (gGraphicsDeviceManager.IsFullScreen == true)
108 | {
109 | int Width;
110 | int Height;
111 |
112 | try
113 | {
114 | Width = Convert.ToInt32(CConfig.GetConfigSTRING("Width"));
115 | Height = Convert.ToInt32(CConfig.GetConfigSTRING("Height"));
116 | }
117 | catch
118 | {
119 | Width = 1024;
120 | Height = 768;
121 | }
122 |
123 | gGraphicsDeviceManager.PreferredBackBufferWidth = Width;
124 | gGraphicsDeviceManager.PreferredBackBufferHeight = Height;
125 | }
126 | else
127 | {
128 | gGraphicsDeviceManager.PreferredBackBufferWidth = 1024;
129 | gGraphicsDeviceManager.PreferredBackBufferHeight = 768;
130 | }
131 |
132 | if (CConfig.GetConfigBOOL("Vertical Sync") == true)
133 | {
134 | gGraphicsDeviceManager.SynchronizeWithVerticalRetrace = true;
135 | gGraphicsDeviceManager.GraphicsDevice.PresentationParameters.PresentationInterval = PresentInterval.Default;
136 | }
137 | else
138 | {
139 | gGraphicsDeviceManager.SynchronizeWithVerticalRetrace = false;
140 | gGraphicsDeviceManager.GraphicsDevice.PresentationParameters.PresentationInterval = PresentInterval.Immediate;
141 |
142 | TargetElapsedTime = TimeSpan.FromMilliseconds(1);
143 | }
144 | IsFixedTimeStep = true;
145 |
146 | gGraphicsDeviceManager.ApplyChanges();
147 | gGraphicsDevice = gGraphicsDeviceManager.GraphicsDevice;
148 |
149 | gCMain = new CMain();
150 | gCCommon = new CCommon();
151 | gCGamma = new CGamma();
152 |
153 | base.Initialize();
154 | }
155 |
156 | ///
157 | /// LoadContent
158 | /// -----------
159 | /// Will be called once per game and is the place to load
160 | /// all of your content.
161 | ///
162 | protected override void LoadContent()
163 | {
164 | // Create a new SpriteBatch, which can be used to draw textures.
165 | spriteBatch = new SpriteBatch(GraphicsDevice);
166 |
167 | if (CProgram.gQ2Game.gGraphicsDevice.GraphicsProfile == GraphicsProfile.HiDef)
168 | {
169 | //gCMain.r_maxLights = 8;
170 | //gEffect = Content.Load("effects30");
171 |
172 | // "Cannot mix shader model 3.0 with earlier shader models. If either the vertex shader or pixel shader is compiled as 3.0, they must both be."
173 | // FIXME: Not sure how to get tis fixed... using SM2 instead
174 | gCMain.r_maxLights = 2;
175 | gEffect = Content.Load("effects20");
176 | }
177 | else
178 | {
179 | gCMain.r_maxLights = 2;
180 | gEffect = Content.Load("effects20");
181 | }
182 |
183 | Font1 = Content.Load("SpriteFont1");
184 | FontPos = new Vector2(5, 5);
185 |
186 | gCMain.gCBloom.Setup();
187 |
188 | gCMain.BuildWorldModel(CConfig.GetConfigSTRING("Map Name"));
189 | gCMain.WorldViewInit();
190 | }
191 |
192 | ///
193 | /// UnloadContent
194 | /// -------------
195 | /// Will be called once per game and is the place to unload
196 | /// all content.
197 | ///
198 | protected override void UnloadContent()
199 | {
200 | gCMain.gCBloom.Release();
201 | }
202 |
203 | ///
204 | /// Update
205 | /// ------
206 | /// Allows the game to run logic such as updating the world,
207 | /// checking for collisions, gathering input, and playing audio.
208 | ///
209 | /// Provides a snapshot of timing values.
210 | protected override void Update(GameTime gameTime)
211 | {
212 | gCMain.gTimeGame = gameTime;
213 |
214 | gCMain.FrameUpdate();
215 | gCCommon.Qcommon_Frame(1);
216 |
217 | base.Update(gameTime);
218 | }
219 |
220 | ///
221 | /// Draw
222 | /// ----
223 | /// This is called when the game should draw itself.
224 | ///
225 | /// Provides a snapshot of timing values.
226 | protected override void Draw(GameTime gameTime)
227 | {
228 | Vector2 FontOrigin;
229 | gCMain.gTimeGame = gameTime;
230 |
231 | gCMain.gCBloom.DrawBloom();
232 |
233 | gGraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1.0f, 0);
234 |
235 |
236 | // reset and set the rasterizer states
237 | CProgram.gQ2Game.gCMain.gRasterizerState = new RasterizerState();
238 | CProgram.gQ2Game.gCMain.gRasterizerState.CullMode = CullMode.CullCounterClockwiseFace;
239 |
240 | if (CProgram.gQ2Game.gCMain.r_wireframe == false)
241 | CProgram.gQ2Game.gCMain.gRasterizerState.FillMode = FillMode.Solid;
242 | else
243 | CProgram.gQ2Game.gCMain.gRasterizerState.FillMode = FillMode.WireFrame;
244 |
245 | gGraphicsDevice.RasterizerState = CProgram.gQ2Game.gCMain.gRasterizerState;
246 |
247 |
248 | // reset the blend and depth states
249 | gGraphicsDevice.BlendState = BlendState.Opaque;
250 |
251 |
252 | // reset and set the depthstencil states
253 | CProgram.gQ2Game.gCMain.gDepthStencilState = new DepthStencilState();
254 | CProgram.gQ2Game.gCMain.gDepthStencilState.DepthBufferEnable = true;
255 | gGraphicsDevice.DepthStencilState = CProgram.gQ2Game.gCMain.gDepthStencilState;
256 |
257 |
258 | gCMain.FrameRenderView();
259 | gCMain.gCBloom.Draw();
260 |
261 |
262 | // we are drawing the overlay text here, because we don't want it to be affected by postprocessing
263 |
264 | // reset and set the rasterizer states
265 | CProgram.gQ2Game.gCMain.gRasterizerState = new RasterizerState();
266 | CProgram.gQ2Game.gCMain.gRasterizerState.FillMode = FillMode.Solid;
267 | gGraphicsDevice.RasterizerState = CProgram.gQ2Game.gCMain.gRasterizerState;
268 |
269 |
270 | FontOrigin.X = 0;
271 | FontOrigin.Y = 0;
272 | DrawOverlayText(FontOrigin, CClient.cl.RefDef.MapName, Color.White);
273 |
274 | FontOrigin.X = 0;
275 | FontOrigin.Y = -40;
276 | DrawOverlayText(FontOrigin, "FPS Rate: " + gCMain.FrameRate.FrameRate.ToString(), Color.Silver);
277 |
278 | FontOrigin.X = 0;
279 | FontOrigin.Y = -60;
280 | DrawOverlayText(FontOrigin, "PVS Cluster: " + CMain.r_viewcluster.ToString(), Color.Silver);
281 |
282 | FontOrigin.X = 0;
283 | FontOrigin.Y = -80;
284 | DrawOverlayText(FontOrigin, "PVS Locked: " + gCMain.r_lockpvs.ToString(), Color.Silver);
285 |
286 | FontOrigin.X = 0;
287 | FontOrigin.Y = -100;
288 | DrawOverlayText(FontOrigin, "Bloom: " + gCMain.r_bloom.ToString(), Color.Silver);
289 |
290 | FontOrigin.X = 0;
291 | FontOrigin.Y = -120;
292 | DrawOverlayText(FontOrigin, "Primitives: " + CMain.c_brush_polys.ToString(), Color.Silver);
293 |
294 | FontOrigin.X = 0;
295 | FontOrigin.Y = -140;
296 | DrawOverlayText(FontOrigin, "Origin: (XYZ) " + Convert.ToInt64(CClient.cl.RefDef.ViewOrigin.X).ToString() + ", " + Convert.ToInt64(CClient.cl.RefDef.ViewOrigin.Y).ToString() + ", " + Convert.ToInt64(CClient.cl.RefDef.ViewOrigin.Z).ToString(), Color.Silver);
297 |
298 | FontOrigin.X = 0;
299 | FontOrigin.Y = -160;
300 | DrawOverlayText(FontOrigin, "View: (XYZ) " + Convert.ToInt64(CClient.cl.RefDef.ViewAngles.X).ToString() + ", " + Convert.ToInt64(CClient.cl.RefDef.ViewAngles.Y).ToString() + ", " + Convert.ToInt64(CClient.cl.RefDef.ViewAngles.Z).ToString(), Color.Silver);
301 |
302 | FontOrigin.X = 0;
303 | FontOrigin.Y = -180;
304 | DrawOverlayText(FontOrigin, "Gamma: " + gCMain.gSGlobal.HLSL.xGamma.ToString(), Color.Silver);
305 |
306 | FontOrigin.X = 0;
307 | FontOrigin.Y = -220;
308 | DrawOverlayText(FontOrigin, "[SPACE] show/hide controls", Color.Gray);
309 |
310 | if (CProgram.gQ2Game.gCMain.r_controls == true)
311 | {
312 | FontOrigin.X = 0;
313 | FontOrigin.Y = -240;
314 | DrawOverlayText(FontOrigin, "[ARROWS] forward/back, roll", Color.Gray);
315 |
316 | FontOrigin.X = 0;
317 | FontOrigin.Y = -260;
318 | DrawOverlayText(FontOrigin, "[Q]/[A] up/down", Color.Gray);
319 |
320 | FontOrigin.X = 0;
321 | FontOrigin.Y = -280;
322 | DrawOverlayText(FontOrigin, "[Z]/[X] left/right", Color.Gray);
323 |
324 | FontOrigin.X = 0;
325 | FontOrigin.Y = -300;
326 | DrawOverlayText(FontOrigin, "[MOUSE] pitch/yaw", Color.Gray);
327 |
328 | FontOrigin.X = 0;
329 | FontOrigin.Y = -320;
330 | DrawOverlayText(FontOrigin, "[O] fill mode", Color.Gray);
331 |
332 | FontOrigin.X = 0;
333 | FontOrigin.Y = -340;
334 | DrawOverlayText(FontOrigin, "[+]/[-] gamma", Color.Gray);
335 |
336 | FontOrigin.X = 0;
337 | FontOrigin.Y = -360;
338 | DrawOverlayText(FontOrigin, "[P] pointlights on/off", Color.Gray);
339 |
340 | FontOrigin.X = 0;
341 | FontOrigin.Y = -380;
342 | DrawOverlayText(FontOrigin, "[H] lightmaps on/off", Color.Gray);
343 |
344 | FontOrigin.X = 0;
345 | FontOrigin.Y = -400;
346 | DrawOverlayText(FontOrigin, "[L] pvs lock on/off", Color.Gray);
347 |
348 | FontOrigin.X = 0;
349 | FontOrigin.Y = -420;
350 | DrawOverlayText(FontOrigin, "[B] bloom on/off", Color.Gray);
351 |
352 | FontOrigin.X = 0;
353 | FontOrigin.Y = -440;
354 | DrawOverlayText(FontOrigin, "[E] entities on/off", Color.Gray);
355 | }
356 |
357 | base.Draw(gameTime);
358 | }
359 |
360 | }
361 | }
362 |
--------------------------------------------------------------------------------
/Q2MD2.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using System.IO;
30 | using Microsoft.Xna.Framework;
31 | using Microsoft.Xna.Framework.Graphics;
32 | using System.Text;
33 |
34 | namespace Q2BSP
35 | {
36 | public class CQ2MD2
37 | {
38 | private void BuildAliasModelBuffer(ref CModel.SModelMD2 _SModelMD2)
39 | {
40 | List vertbuffer;
41 |
42 | if (_SModelMD2.vbModel != null)
43 | return;
44 |
45 | CProgram.gQ2Game.gCMain.ModelVertexDeclaration = new VertexDeclaration(CModel.ModelVertexFormat.VertexElements);
46 |
47 | _SModelMD2.vbModel = new VertexBuffer[_SModelMD2.md2.num_frames];
48 |
49 | // builds a vertexbuffer for each animation frame
50 | for (int i = 0; i < _SModelMD2.md2.num_frames; i++)
51 | {
52 | vertbuffer = new List();
53 |
54 | for (int j = 0; j < _SModelMD2.md2.num_tris; j++)
55 | {
56 | for (int k = 0; k < 3; k++)
57 | {
58 | CModel.ModelVertexFormat _vert;
59 |
60 | _vert.Position.X = ((float)_SModelMD2.aliasframes[i].verts[_SModelMD2.triangles[j].index_xyz[k]].v[0]) * _SModelMD2.aliasframes[i].scale[0];
61 | _vert.Position.Y = ((float)_SModelMD2.aliasframes[i].verts[_SModelMD2.triangles[j].index_xyz[k]].v[1]) * _SModelMD2.aliasframes[i].scale[1];
62 | _vert.Position.Z = ((float)_SModelMD2.aliasframes[i].verts[_SModelMD2.triangles[j].index_xyz[k]].v[2]) * _SModelMD2.aliasframes[i].scale[2];
63 | _vert.Position.X += _SModelMD2.aliasframes[i].translate[0];
64 | _vert.Position.Y += _SModelMD2.aliasframes[i].translate[1];
65 | _vert.Position.Z += _SModelMD2.aliasframes[i].translate[2];
66 |
67 | _vert.TextureCoordinate.X = (float)(((double)_SModelMD2.st[_SModelMD2.triangles[j].index_st[k]].s + 0.5) / (double)_SModelMD2.md2.skinwidth);
68 | _vert.TextureCoordinate.Y = (float)(((double)_SModelMD2.st[_SModelMD2.triangles[j].index_st[k]].t + 0.5) / (double)_SModelMD2.md2.skinheight);
69 |
70 | _vert.Normal.X = 0.0f;
71 | _vert.Normal.Y = 0.0f;
72 | _vert.Normal.Z = 0.0f;
73 |
74 | vertbuffer.Add(_vert);
75 | }
76 | }
77 |
78 | // set up model frame vertex buffer
79 | _SModelMD2.vbModel[i] = new VertexBuffer(CProgram.gQ2Game.gGraphicsDevice, CProgram.gQ2Game.gCMain.ModelVertexDeclaration, vertbuffer.Count, BufferUsage.WriteOnly);
80 | _SModelMD2.vbModel[i].SetData(vertbuffer.ToArray());
81 |
82 | vertbuffer.Clear();
83 | vertbuffer = null;
84 | }
85 | }
86 |
87 | public void Mod_LoadAliasModel(ref CModel.SModel _SModel, MemoryStream ms)
88 | {
89 | BinaryReader br;
90 | List skinnames;
91 | List st;
92 | List triangles;
93 | List aliasframes;
94 |
95 | // HACK - prevent model loading if in Heretic II mode
96 | if (CProgram.gQ2Game.gCMain.r_htic2 == true)
97 | return;
98 |
99 | ms.Seek(0, System.IO.SeekOrigin.Begin);
100 | br = new BinaryReader(ms);
101 |
102 |
103 | // identity (header)
104 | _SModel.ModelMD2.md2.identification = br.ReadBytes(4);
105 | if (_SModel.ModelMD2.md2.identification[0] != 'I'
106 | || _SModel.ModelMD2.md2.identification[1] != 'D'
107 | || _SModel.ModelMD2.md2.identification[2] != 'P'
108 | || _SModel.ModelMD2.md2.identification[3] != '2')
109 | {
110 | System.Diagnostics.Debug.WriteLine("MDL file " + _SModel.name + " doesn't have IDP2 id");
111 |
112 | br.Close();
113 | return;
114 | }
115 |
116 |
117 | // model version
118 | _SModel.ModelMD2.md2.version = br.ReadInt32();
119 | if (_SModel.ModelMD2.md2.version != ALIAS_VERSION)
120 | {
121 | System.Diagnostics.Debug.WriteLine(_SModel.name + " has wrong version number (" + _SModel.ModelMD2.md2.version + " should be " + ALIAS_VERSION + ")");
122 |
123 | br.Close();
124 | return;
125 | }
126 |
127 |
128 | // skin size
129 | _SModel.ModelMD2.md2.skinwidth = br.ReadInt32();
130 | _SModel.ModelMD2.md2.skinheight = br.ReadInt32();
131 | if (_SModel.ModelMD2.md2.skinheight > CLocal.MAX_LBM_HEIGHT)
132 | {
133 | System.Diagnostics.Debug.WriteLine("model " + _SModel.name + " has a skin taller than " + CLocal.MAX_LBM_HEIGHT + ".");
134 |
135 | br.Close();
136 | return;
137 | }
138 |
139 |
140 | // frame size
141 | _SModel.ModelMD2.md2.framesize = br.ReadInt32();
142 |
143 |
144 | // number of skins
145 | _SModel.ModelMD2.md2.num_skins = br.ReadInt32();
146 |
147 |
148 | // number of vertices
149 | _SModel.ModelMD2.md2.num_xyz = br.ReadInt32();
150 | if (_SModel.ModelMD2.md2.num_xyz > MAX_VERTS)
151 | {
152 | System.Diagnostics.Debug.WriteLine("model " + _SModel.name + " has too many vertices");
153 |
154 | br.Close();
155 | return;
156 | }
157 |
158 |
159 | // number of st vertices
160 | _SModel.ModelMD2.md2.num_st = br.ReadInt32();
161 | if (_SModel.ModelMD2.md2.num_st <= 0)
162 | {
163 | System.Diagnostics.Debug.WriteLine("model " + _SModel.name + " has no st vertices");
164 |
165 | br.Close();
166 | return;
167 | }
168 |
169 |
170 | // number of triangles
171 | _SModel.ModelMD2.md2.num_tris = br.ReadInt32();
172 | if (_SModel.ModelMD2.md2.num_tris <= 0)
173 | {
174 | System.Diagnostics.Debug.WriteLine("model " + _SModel.name + " has no triangles");
175 |
176 | br.Close();
177 | return;
178 | }
179 |
180 |
181 | // number of gl commands
182 | _SModel.ModelMD2.md2.num_glcmds = br.ReadInt32();
183 |
184 |
185 | // number of frames
186 | _SModel.ModelMD2.md2.num_frames = br.ReadInt32();
187 | if (_SModel.ModelMD2.md2.num_frames <= 0)
188 | {
189 | System.Diagnostics.Debug.WriteLine("model " + _SModel.name + " has no frames");
190 |
191 | br.Close();
192 | return;
193 | }
194 |
195 |
196 | // load offsets
197 | _SModel.ModelMD2.md2.ofs_skins = br.ReadInt32(); // each skin is a MAX_SKINNAME string
198 | _SModel.ModelMD2.md2.ofs_st = br.ReadInt32(); // byte offset from start for stverts
199 | _SModel.ModelMD2.md2.ofs_tris = br.ReadInt32(); // offset for dtriangles
200 | _SModel.ModelMD2.md2.ofs_frames = br.ReadInt32(); // offset for first frame
201 | _SModel.ModelMD2.md2.ofs_glcmds = br.ReadInt32(); // offset for strip/fan command list
202 | _SModel.ModelMD2.md2.ofs_end = br.ReadInt32(); // end of file
203 |
204 |
205 | //
206 | // load the skin names
207 | //
208 | skinnames = new List();
209 | for (int i = 0; i < _SModel.ModelMD2.md2.num_skins; i++)
210 | {
211 | skinnames.Add(CShared.Com_ToString(br.ReadChars(MAX_SKINNAME)));
212 | }
213 |
214 | if (skinnames.Count != 0)
215 | {
216 | _SModel.ModelMD2.skinnames = skinnames.ToArray();
217 | skinnames.Clear();
218 | skinnames = null;
219 | }
220 |
221 |
222 | //
223 | // load base s and t vertices (not used in gl version)
224 | //
225 | st = new List();
226 | for (int i = 0; i < _SModel.ModelMD2.md2.num_st; i++)
227 | {
228 | SSTVert _SSTVert;
229 |
230 | _SSTVert.s = br.ReadInt16();
231 | _SSTVert.t = br.ReadInt16();
232 |
233 | st.Add(_SSTVert);
234 | }
235 |
236 | if (st.Count != 0)
237 | {
238 | _SModel.ModelMD2.st = st.ToArray();
239 | st.Clear();
240 | st = null;
241 | }
242 |
243 |
244 | //
245 | // load the triangles
246 | //
247 | triangles = new List();
248 | for (int i = 0; i < _SModel.ModelMD2.md2.num_tris; i++)
249 | {
250 | SDTriangle _SDTriangle;
251 |
252 | _SDTriangle.index_xyz = new short[3];
253 | _SDTriangle.index_xyz[0] = br.ReadInt16();
254 | _SDTriangle.index_xyz[1] = br.ReadInt16();
255 | _SDTriangle.index_xyz[2] = br.ReadInt16();
256 |
257 | _SDTriangle.index_st = new short[3];
258 | _SDTriangle.index_st[0] = br.ReadInt16();
259 | _SDTriangle.index_st[1] = br.ReadInt16();
260 | _SDTriangle.index_st[2] = br.ReadInt16();
261 |
262 | triangles.Add(_SDTriangle);
263 | }
264 |
265 | if (triangles.Count != 0)
266 | {
267 | _SModel.ModelMD2.triangles = triangles.ToArray();
268 | triangles.Clear();
269 | triangles = null;
270 | }
271 |
272 |
273 | //
274 | // load the frames
275 | //
276 | aliasframes = new List();
277 | for (int i = 0; i < _SModel.ModelMD2.md2.num_frames; i++)
278 | {
279 | SAliasFrameDesc _SAliasFrameDesc;
280 |
281 | _SAliasFrameDesc.scale = new float[3];
282 | _SAliasFrameDesc.scale[0] = br.ReadSingle();
283 | _SAliasFrameDesc.scale[1] = br.ReadSingle();
284 | _SAliasFrameDesc.scale[2] = br.ReadSingle();
285 |
286 | _SAliasFrameDesc.translate = new float[3];
287 | _SAliasFrameDesc.translate[0] = br.ReadSingle();
288 | _SAliasFrameDesc.translate[1] = br.ReadSingle();
289 | _SAliasFrameDesc.translate[2] = br.ReadSingle();
290 |
291 | _SAliasFrameDesc.name = br.ReadChars(16);
292 |
293 | _SAliasFrameDesc.verts = new STrivertx[_SModel.ModelMD2.md2.num_xyz];
294 | for (int j = 0; j < _SModel.ModelMD2.md2.num_xyz; j++)
295 | {
296 | _SAliasFrameDesc.verts[j].v = new byte[3];
297 | _SAliasFrameDesc.verts[j].v[0] = br.ReadByte();
298 | _SAliasFrameDesc.verts[j].v[1] = br.ReadByte();
299 | _SAliasFrameDesc.verts[j].v[2] = br.ReadByte();
300 |
301 | _SAliasFrameDesc.verts[j].lightnormalindex = br.ReadByte();
302 | }
303 |
304 | aliasframes.Add(_SAliasFrameDesc);
305 | }
306 |
307 | if (aliasframes.Count != 0)
308 | {
309 | _SModel.ModelMD2.aliasframes = aliasframes.ToArray();
310 | aliasframes.Clear();
311 | aliasframes = null;
312 | }
313 |
314 |
315 | //
316 | // load the gl commands
317 | //
318 | _SModel.ModelMD2.glcmds = br.ReadBytes(_SModel.ModelMD2.md2.num_glcmds * sizeof(int));
319 |
320 |
321 |
322 | // set the model type
323 | _SModel.ModType = CModel.EModType.MOD_ALIAS;
324 |
325 |
326 | // register all skins
327 | _SModel.ModelMD2.skins = new Microsoft.Xna.Framework.Graphics.Texture2D[_SModel.ModelMD2.md2.num_skins];
328 | for (int i = 0; i < _SModel.ModelMD2.md2.num_skins; i++)
329 | {
330 | _SModel.ModelMD2.skins[i] = CProgram.gQ2Game.gCMain.gCImage.LoadSkin(_SModel.ModelMD2.skinnames[i]);
331 | }
332 |
333 | // set default mins/maxs
334 | _SModel.mins.X = -32;
335 | _SModel.mins.Y = -32;
336 | _SModel.mins.Z = -32;
337 | _SModel.maxs.X = 32;
338 | _SModel.maxs.Y = 32;
339 | _SModel.maxs.Z = 32;
340 |
341 | // close the binary reader
342 | br.Close();
343 | br = null;
344 |
345 | // close the memory stream
346 | ms.Close();
347 | ms = null;
348 |
349 | BuildAliasModelBuffer(ref _SModel.ModelMD2);
350 | }
351 |
352 | public void R_DrawAliasModel(CModel.SEntities _CurrentEntity)
353 | {
354 | Matrix wMatrix;
355 | Color shadelight;
356 |
357 | if (_CurrentEntity.Model.ModelMD2.vbModel == null)
358 | return;
359 |
360 | // set vertex buffer
361 | CProgram.gQ2Game.gGraphicsDevice.SetVertexBuffer(_CurrentEntity.Model.ModelMD2.vbModel[_CurrentEntity.ModelFrameSeqStart + _CurrentEntity.ModelFrameCurrent]);
362 |
363 | // create model rotation and translation matrix
364 | wMatrix = Matrix.CreateFromYawPitchRoll(_CurrentEntity.Angles.Y, _CurrentEntity.Angles.X, _CurrentEntity.Angles.Z);
365 | wMatrix *= Matrix.CreateTranslation(_CurrentEntity.Origin);
366 |
367 | // calculate the model light color
368 | shadelight = new Color();
369 | CProgram.gQ2Game.gCMain.gCLight.R_LightPoint(_CurrentEntity.Origin, ref shadelight);
370 |
371 | // update HLSL variables
372 | CProgram.gQ2Game.gEffect.Parameters["xWorld"].SetValue(wMatrix);
373 | CProgram.gQ2Game.gEffect.Parameters["xLightModel"].SetValue(shadelight.ToVector4());
374 |
375 |
376 | CProgram.gQ2Game.gEffect.CurrentTechnique = CProgram.gQ2Game.gEffect.Techniques["TexturedSkin"];
377 |
378 |
379 | // bind new texture
380 | CProgram.gQ2Game.gEffect.Parameters["xTextureSkin"].SetValue(_CurrentEntity.Model.ModelMD2.skins[_CurrentEntity.ModelCurrentSkin]);
381 |
382 | foreach (EffectPass pass in CProgram.gQ2Game.gEffect.CurrentTechnique.Passes)
383 | {
384 | pass.Apply();
385 | CProgram.gQ2Game.gGraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, _CurrentEntity.Model.ModelMD2.md2.num_tris);
386 | }
387 |
388 | CMain.c_brush_polys += _CurrentEntity.Model.ModelMD2.md2.num_tris;
389 | }
390 |
391 |
392 |
393 | // md2 model renderfx flags
394 | [Flags]
395 | public enum EModelFlags : int
396 | {
397 | RF_MINLIGHT = 1, // allways have some light (viewmodel)
398 | RF_VIEWERMODEL = 2, // don't draw through eyes, only mirrors
399 | RF_WEAPONMODEL = 4, // only draw through eyes
400 | RF_FULLBRIGHT = 8, // allways draw full intensity
401 | RF_DEPTHHACK = 16, // for view weapon Z crunching
402 | RF_TRANSLUCENT = 32,
403 | RF_FRAMELERP = 64,
404 | RF_BEAM = 128,
405 | RF_CUSTOMSKIN = 256, // skin is an index in image_precache
406 | RF_GLOW = 512, // pulse lighting for bonus items
407 | RF_SHELL_RED = 1024,
408 | RF_SHELL_GREEN = 2048,
409 | RF_SHELL_BLUE = 4096
410 | }
411 |
412 |
413 | // ================================================================
414 | //
415 | // MD2 MODELS
416 | //
417 | // ================================================================
418 |
419 | public const int IDALIASHEADER = (('2' << 24) + ('P' << 16) + ('D' << 8) + 'I');
420 | private const int ALIAS_VERSION = 8;
421 | private const int MAX_TRIANGLES = 4096;
422 | private const int MAX_VERTS = 2048;
423 | private const int MAX_FRAMES = 512;
424 | private const int MAX_MD2SKINS = 32;
425 | private const int MAX_GLCMDS = 16384;
426 |
427 | private const int MAX_FRAMENAME = 16;
428 | private const int MAX_SKINNAME = 64;
429 |
430 | public struct SSTVert
431 | {
432 | public short s;
433 | public short t;
434 | }
435 |
436 | public struct SDTriangle
437 | {
438 | public short[] index_xyz; // size 3
439 | public short[] index_st; // size 3
440 | }
441 |
442 | public struct STrivertx
443 | {
444 | public byte[] v; // size 3
445 | public byte lightnormalindex;
446 | }
447 |
448 | public struct SAliasFrameDesc
449 | {
450 | public float[] scale; // size 3 (multiply byte verts by this)
451 | public float[] translate; // size 3 (then add this)
452 | public char[] name; // size 16 (frame name from grabbing)
453 | public STrivertx[] verts;
454 | }
455 |
456 | // the glcmd format:
457 | // a positive integer starts a tristrip command, followed by that many
458 | // vertex structures.
459 | // a negative integer starts a trifan command, followed by -x vertexes
460 | // a zero indicates the end of the command list.
461 | // a vertex consists of a floating point s, a floating point t,
462 | // and an integer vertex index.
463 |
464 | public struct SMd2
465 | {
466 | public byte[] identification; // size 4 (should be IDP2)
467 | public int version; // version: must be 8
468 |
469 | public int skinwidth; // texture width
470 | public int skinheight; // texture height
471 |
472 | public int framesize; // byte size of each frame
473 |
474 | public int num_skins; // number of skins
475 | public int num_xyz; // number of vertices
476 | public int num_st; // number of texture coordinates (greater than num_xyz for seams)
477 | public int num_tris; // number of triangles
478 | public int num_glcmds; // dwords in strip/fan command list
479 | public int num_frames; // number of frames
480 |
481 | public int ofs_skins; // each skin is a MAX_SKINNAME string
482 | public int ofs_st; // byte offset from start for stverts
483 | public int ofs_tris; // offset for dtriangles
484 | public int ofs_frames; // offset for first frame
485 | public int ofs_glcmds; // offset for strip/fan command list
486 | public int ofs_end; // end of file
487 | }
488 |
489 | }
490 | }
491 |
--------------------------------------------------------------------------------
/Server.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using System.Text;
30 |
31 | namespace Q2BSP
32 | {
33 | public class CServer
34 | {
35 | // max recipients for heartbeat packets
36 | public const int MAX_MASTERS = 8;
37 |
38 | //server_static_t svs; // persistant server info
39 | public static SServer sv; // local server
40 |
41 |
42 | public struct SServer
43 | {
44 | public EServerState state; // precache commands are only valid during load
45 |
46 | public bool attractloop; // running cinematics and demos for the local system only
47 | public bool loadgame; // client begins should reuse existing entity
48 |
49 | public uint time; // always sv.framenum * 100 msec
50 | public int framenum;
51 |
52 | public string name; // size: MAX_QPATH (map name, or cinematic name)
53 | //struct cmodel_s *models[MAX_MODELS];
54 |
55 | public string[] configstrings; // size: [MAX_CONFIGSTRINGS, MAX_QPATH]
56 | public EClientState[] baselines; // size: MAX_EDICTS
57 |
58 | // the multicast buffer is used to send a message to a set of clients
59 | // it is only used to marshall data until SV_Multicast is called
60 | public CCommon.SSizeBuf multicast;
61 | public byte[] multicast_buf; // size: MAX_MSGLEN
62 |
63 | // demo server information
64 | //FILE *demofile;
65 | public bool timedemo; // don't time sync
66 | }
67 |
68 |
69 |
70 |
71 | /*typedef struct
72 | {
73 | server_state_t state; // precache commands are only valid during load
74 |
75 | qboolean attractloop; // running cinematics and demos for the local system only
76 | qboolean loadgame; // client begins should reuse existing entity
77 |
78 | unsigned time; // always sv.framenum * 100 msec
79 | int framenum;
80 |
81 | char name[MAX_QPATH]; // map name, or cinematic name
82 | struct cmodel_s *models[MAX_MODELS];
83 |
84 | char configstrings[MAX_CONFIGSTRINGS][MAX_QPATH];
85 | entity_state_t baselines[MAX_EDICTS];
86 |
87 | // the multicast buffer is used to send a message to a set of clients
88 | // it is only used to marshall data until SV_Multicast is called
89 | sizebuf_t multicast;
90 | byte multicast_buf[MAX_MSGLEN];
91 |
92 | // demo server information
93 | FILE *demofile;
94 | qboolean timedemo; // don't time sync
95 | } server_t;*/
96 |
97 |
98 |
99 |
100 |
101 | public enum EServerState
102 | {
103 | ss_dead, // no map loaded
104 | ss_loading, // spawning level edicts
105 | ss_game, // actively running
106 | ss_cinematic,
107 | ss_demo,
108 | ss_pic
109 | }
110 | // some qc commands are only valid before the server has finished
111 | // initializing (precache commands, static sounds / objects, etc)
112 |
113 | public enum EClientState
114 | {
115 | cs_free, // can be reused for a new connection
116 | cs_zombie, // client has been disconnected, but don't reuse connection for a couple seconds
117 | cs_connected, // has been assigned to a client_t, but not in game yet
118 | cs_spawned // client is fully in game
119 | }
120 |
121 |
122 |
123 |
124 |
125 |
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/Shared.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using System.Text;
30 | using Microsoft.Xna.Framework;
31 |
32 | namespace Q2BSP
33 | {
34 | public class CShared
35 | {
36 | public const int MAX_QPATH = 64;
37 | public static Vector3 vec3_origin;
38 |
39 | public static string Com_ToString(char[] chr)
40 | {
41 | string str;
42 |
43 | if (chr == null)
44 | return null;
45 |
46 | if (chr.Length == 0)
47 | return "";
48 |
49 | System.Text.StringBuilder SB = new System.Text.StringBuilder();
50 | SB.Append(chr);
51 |
52 | str = SB.ToString().Trim();
53 | SB = null;
54 |
55 | if (str.IndexOf('\0') != -1)
56 | str = str.Substring(0, str.IndexOf('\0'));
57 |
58 | return str;
59 | }
60 |
61 | public static char[] Com_ToChar(string str, bool nullTerminate)
62 | {
63 | int i;
64 | char[] chr;
65 |
66 | if (str == null)
67 | return null;
68 |
69 | if (nullTerminate == true)
70 | chr = new char[str.Length + 1];
71 | else
72 | chr = new char[str.Length];
73 |
74 | for (i = 0; i < str.Length; i++)
75 | {
76 | chr[i] = str[i];
77 | }
78 |
79 | if (nullTerminate == true)
80 | chr[i] = '\0';
81 |
82 | return chr;
83 | }
84 |
85 | public static void VectorScale(Vector3 vecIn, float scale, ref Vector3 vecOut)
86 | {
87 | vecOut.X = vecIn.X * scale;
88 | vecOut.Y = vecIn.Y * scale;
89 | vecOut.Z = vecIn.Z * scale;
90 | }
91 |
92 | public static void AngleVectors(Vector3 angles, ref Vector3 forward, ref Vector3 right, ref Vector3 up)
93 | {
94 | float angle;
95 | float sr, sp, sy, cr, cp, cy;
96 |
97 | angle = (float)(angles.Y * (Math.PI * 2 / 360));
98 | sy = (float)Math.Sin(angle);
99 | cy = (float)Math.Cos(angle);
100 |
101 | angle = (float)(angles.X * (Math.PI * 2 / 360));
102 | sp = (float)Math.Sin(angle);
103 | cp = (float)Math.Cos(angle);
104 |
105 | angle = (float)(angles.Z * (Math.PI * 2 / 360));
106 | sr = (float)Math.Sin(angle);
107 | cr = (float)Math.Cos(angle);
108 |
109 |
110 | forward.X = cp * cy;
111 | forward.Y = cp * sy;
112 | forward.Z = -sp;
113 |
114 | right.X = (-1 * sr * sp * cy + -1 * cr * -sy);
115 | right.Y = (-1 * sr * sp * sy + -1 * cr * cy);
116 | right.Z = -1 * sr * cp;
117 |
118 | up.X = (cr * sp * cy + -sr * -sy);
119 | up.Y = (cr * sp * sy + -sr * cy);
120 | up.Z = cr * cp;
121 | }
122 |
123 | /*void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
124 | {
125 | float angle;
126 | static float sr, sp, sy, cr, cp, cy;
127 | // static to help MS compiler fp bugs
128 |
129 | angle = angles[YAW] * (M_PI*2 / 360);
130 | sy = sin(angle);
131 | cy = cos(angle);
132 | angle = angles[PITCH] * (M_PI*2 / 360);
133 | sp = sin(angle);
134 | cp = cos(angle);
135 | angle = angles[ROLL] * (M_PI*2 / 360);
136 | sr = sin(angle);
137 | cr = cos(angle);
138 |
139 | if (forward)
140 | {
141 | forward[0] = cp*cy;
142 | forward[1] = cp*sy;
143 | forward[2] = -sp;
144 | }
145 | if (right)
146 | {
147 | right[0] = (-1*sr*sp*cy+-1*cr*-sy);
148 | right[1] = (-1*sr*sp*sy+-1*cr*cy);
149 | right[2] = -1*sr*cp;
150 | }
151 | if (up)
152 | {
153 | up[0] = (cr*sp*cy+-sr*-sy);
154 | up[1] = (cr*sp*sy+-sr*cy);
155 | up[2] = cr*cp;
156 | }
157 | }*/
158 |
159 |
160 |
161 | public struct SCPlane
162 | {
163 | public Microsoft.Xna.Framework.Vector3 normal;
164 | public float dist;
165 | public byte type; // for fast side tests: 0,1,2 = axial, 3 = nonaxial
166 | public byte signbits; // signx + (signy<<1) + (signz<<2), used as lookup during collision
167 |
168 | // unused - alignment?
169 | public byte[] pad; // size: 2
170 | }
171 |
172 |
173 |
174 | //
175 | // per-level limits
176 | //
177 | public const int MAX_CLIENTS = 256; // absolute limit
178 | public const int MAX_EDICTS = 1024; // must change protocol to increase more
179 | public const int MAX_LIGHTSTYLES = 256;
180 | public const int MAX_MODELS = 256; // these are sent over the net as bytes
181 | public const int MAX_SOUNDS = 256; // so they cannot be blindly increased
182 | public const int MAX_IMAGES = 256;
183 | public const int MAX_ITEMS = 256;
184 | public const int MAX_GENERAL = (MAX_CLIENTS * 2); // general config strings
185 |
186 |
187 | //
188 | // Config strings are a general means of communication from the server to all connected clients.
189 | // Each config string can be at most MAX_QPATH characters.
190 | //
191 | public const int CS_NAME = 0;
192 | public const int CS_CDTRACK = 1;
193 | public const int CS_SKY = 2;
194 | public const int CS_SKYAXIS = 3; // %f %f %f format
195 | public const int CS_SKYROTATE = 4;
196 | public const int CS_STATUSBAR = 5; // display program string
197 |
198 | public const int CS_AIRACCEL = 29; // air acceleration control
199 | public const int CS_MAXCLIENTS = 30;
200 | public const int CS_MAPCHECKSUM = 31; // for catching cheater maps
201 |
202 | public const int CS_MODELS = 32;
203 | public const int CS_SOUNDS = (CS_MODELS + MAX_MODELS);
204 | public const int CS_IMAGES = (CS_SOUNDS + MAX_SOUNDS);
205 | public const int CS_LIGHTS = (CS_IMAGES + MAX_IMAGES);
206 | public const int CS_ITEMS = (CS_LIGHTS + MAX_LIGHTSTYLES);
207 | public const int CS_PLAYERSKINS = (CS_ITEMS + MAX_ITEMS);
208 | public const int CS_GENERAL = (CS_PLAYERSKINS + MAX_CLIENTS);
209 | public const int MAX_CONFIGSTRINGS = (CS_GENERAL + MAX_GENERAL);
210 |
211 |
212 |
213 |
214 |
215 | }
216 | }
217 |
--------------------------------------------------------------------------------
/Sky.cs:
--------------------------------------------------------------------------------
1 | /*
2 | ===========================================================================
3 | Copyright (C) 2000-2011 Korvin Korax
4 | Author: Jacques Krige
5 | http://www.sagamedev.com
6 | http://www.korvinkorax.com
7 |
8 | This file is part of Quake2 BSP XNA Renderer source code.
9 | Parts of the source code is copyright (C) Id Software, Inc.
10 |
11 | Quake2 BSP XNA Renderer source code is free software; you can redistribute it
12 | and/or modify it under the terms of the GNU General Public License as
13 | published by the Free Software Foundation; either version 2 of the License,
14 | or (at your option) any later version.
15 |
16 | Quake2 BSP XNA Renderer source code is distributed in the hope that it will be
17 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with Foobar; if not, write to the Free Software
23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 | ===========================================================================
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using Microsoft.Xna.Framework;
30 | using Microsoft.Xna.Framework.Graphics;
31 | using System.Text;
32 |
33 | namespace Q2BSP
34 | {
35 | public class CSky
36 | {
37 | private int[] skytexorder;
38 | private string[] suf;
39 |
40 | private string skyname; // size: MAX_QPATH
41 | private float skyrotate;
42 | private Vector3 skyaxis;
43 |
44 | private float[,] skymins;
45 | private float[,] skymaxs;
46 |
47 | Quaternion SkyboxRotation;
48 |
49 | private VertexDeclaration SkyboxVertexDeclaration;
50 | private int[,] st_to_vec;
51 |
52 | public CSky()
53 | {
54 | skytexorder = new int[] { 0, 2, 1, 3, 4, 5 };
55 | suf = new string[] { "rt", "bk", "lf", "ft", "up", "dn" };
56 |
57 | // 1 = s, 2 = t, 3 = 2048
58 | st_to_vec = new int[,]
59 | {
60 | { 3, -1, 2 },
61 | { -3, 1, 2 },
62 | { 1, 3, 2 },
63 | { -1, -3, 2 },
64 | { -2, -1, 3 }, // 0 degrees yaw, look straight up
65 | { 2, -1, -3 } // look straight down
66 | }; // [6, 3]
67 |
68 | skymins = new float[,]
69 | {
70 | { -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f },
71 | { -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f }
72 | }; // [2, 6]
73 |
74 | skymaxs = new float[,]
75 | {
76 | { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f },
77 | { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }
78 | }; // [2, 6]
79 |
80 | SkyboxRotation = Quaternion.CreateFromYawPitchRoll(0.0f, 0.0f, 0.0f);
81 | }
82 |
83 | private SkyboxVertexFormat MakeSkyVec(int Width, float s, float t, int axis)
84 | {
85 | Vector3 v;
86 | SkyboxVertexFormat SVF;
87 | float[] v2 = new float[3];
88 | float[] b = new float[] { s * Width, t * Width, Width };
89 | float sky_min = 1.0f / Width;
90 | float sky_max = (Width - 1.0f) / Width;
91 |
92 | for (int i = 0; i < 3; i++)
93 | {
94 | int k = st_to_vec[axis, i];
95 |
96 | if (k < 0)
97 | v2[i] = -b[-k - 1];
98 | else
99 | v2[i] = b[k - 1];
100 | }
101 |
102 | v.X = v2[0];
103 | v.Y = v2[1];
104 | v.Z = v2[2];
105 |
106 | // avoid bilerp seam
107 | s = (s + 1) * 0.5f;
108 | t = (t + 1) * 0.5f;
109 |
110 | if (s < sky_min)
111 | s = sky_min;
112 | else if (s > sky_max)
113 | s = sky_max;
114 |
115 | if (t < sky_min)
116 | t = sky_min;
117 | else if (t > sky_max)
118 | t = sky_max;
119 |
120 | t = 1.0f - t;
121 |
122 | SVF.Position.X = v.X;
123 | SVF.Position.Y = v.Y;
124 | SVF.Position.Z = v.Z;
125 | SVF.TextureCoordinate.X = s;
126 | SVF.TextureCoordinate.Y = t;
127 |
128 | return SVF;
129 | }
130 |
131 | public void DrawSkyBox()
132 | {
133 | Matrix wMatrix;
134 | float RotationSpeed = ((float)CProgram.gQ2Game.gCMain.gTimeGame.ElapsedGameTime.TotalMilliseconds / 1000.0f) * skyrotate;
135 |
136 | // update skybox rotation
137 | SkyboxRotation *= Quaternion.CreateFromYawPitchRoll
138 | (
139 | Microsoft.Xna.Framework.MathHelper.ToRadians(skyaxis.Y * RotationSpeed),
140 | Microsoft.Xna.Framework.MathHelper.ToRadians(skyaxis.X * RotationSpeed),
141 | Microsoft.Xna.Framework.MathHelper.ToRadians(skyaxis.Z * RotationSpeed)
142 | );
143 |
144 | // update HLSL variables
145 | CProgram.gQ2Game.gCMain.UpdateHLSL(-1);
146 |
147 | // set vertex buffer
148 | CProgram.gQ2Game.gGraphicsDevice.SetVertexBuffer(CQ2BSP.SWorldData.vbSkybox);
149 |
150 | // create skybox rotation and translation matrix
151 | wMatrix = Matrix.CreateFromQuaternion(SkyboxRotation);
152 | wMatrix *= Matrix.CreateTranslation(CClient.cl.RefDef.ViewOrigin);
153 |
154 | // update HLSL variables
155 | CProgram.gQ2Game.gEffect.Parameters["xWorld"].SetValue(wMatrix);
156 |
157 | // set a rendering technique
158 | CProgram.gQ2Game.gEffect.CurrentTechnique = CProgram.gQ2Game.gEffect.Techniques["TexturedSkybox"];
159 |
160 | // reset the depthstencil state and disable the depth buffer
161 | CProgram.gQ2Game.gCMain.gDepthStencilState = new DepthStencilState();
162 | CProgram.gQ2Game.gCMain.gDepthStencilState.DepthBufferWriteEnable = false;
163 | CProgram.gQ2Game.gGraphicsDevice.DepthStencilState = CProgram.gQ2Game.gCMain.gDepthStencilState;
164 |
165 | for (int i = 0; i < 6; i++)
166 | {
167 | // bind the skybox side texture
168 | CProgram.gQ2Game.gEffect.Parameters["xTextureDiffuse"].SetValue(CQ2BSP.SWorldData.WorldSkies[skytexorder[i]]);
169 |
170 | // render the skybox side primitives
171 | foreach (EffectPass pass in CProgram.gQ2Game.gEffect.CurrentTechnique.Passes)
172 | {
173 | pass.Apply();
174 | CProgram.gQ2Game.gGraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, i * 6, 2);
175 | }
176 | }
177 |
178 | // reset the depthstencil state and enable the depth buffer
179 | CProgram.gQ2Game.gCMain.gDepthStencilState = new DepthStencilState();
180 | CProgram.gQ2Game.gCMain.gDepthStencilState.DepthBufferWriteEnable = true;
181 | CProgram.gQ2Game.gGraphicsDevice.DepthStencilState = CProgram.gQ2Game.gCMain.gDepthStencilState;
182 | }
183 |
184 | public void BuildSkybox()
185 | {
186 | List vertbuffer = new List();
187 | SkyboxVertexDeclaration = new VertexDeclaration(SkyboxVertexFormat.VertexElements);
188 |
189 | // get skybox info from the worldspawn
190 | // "sky" : environment map name
191 | // "skyaxis" : vector axis for rotating sky
192 | // "skyrotate" : speed of rotation in degrees/second
193 | for (int i = 0; i < CQ2BSP.SWorldData.entities.Length; i++)
194 | {
195 | if (CProgram.gQ2Game.gCMain.gCModel.ValueForKey(CQ2BSP.SWorldData.entities[i], "classname") == "worldspawn")
196 | {
197 | string _skyrotate;
198 | string _skyaxis;
199 |
200 | skyname = CProgram.gQ2Game.gCMain.gCModel.ValueForKey(CQ2BSP.SWorldData.entities[i], "sky");
201 | if (string.IsNullOrEmpty(skyname) == true)
202 | skyname = "unit1_";
203 |
204 | _skyaxis = CProgram.gQ2Game.gCMain.gCModel.ValueForKey(CQ2BSP.SWorldData.entities[i], "skyaxis");
205 | if (string.IsNullOrEmpty(_skyaxis) == true)
206 | {
207 | skyaxis.X = 0.0f;
208 | skyaxis.Y = 0.0f;
209 | skyaxis.Z = 0.0f;
210 | }
211 | else
212 | {
213 | string[] SkyAxisArgs;
214 | char[] delim = new char[1];
215 |
216 | delim[0] = ' ';
217 | SkyAxisArgs = _skyaxis.Split(delim, StringSplitOptions.RemoveEmptyEntries);
218 |
219 | if (SkyAxisArgs.Length == 3)
220 | {
221 | skyaxis.X = Convert.ToSingle(SkyAxisArgs[0]);
222 | skyaxis.Y = Convert.ToSingle(SkyAxisArgs[1]);
223 | skyaxis.Z = Convert.ToSingle(SkyAxisArgs[2]);
224 | }
225 | }
226 |
227 | _skyrotate = CProgram.gQ2Game.gCMain.gCModel.ValueForKey(CQ2BSP.SWorldData.entities[i], "skyrotate");
228 | if (string.IsNullOrEmpty(_skyrotate) == true)
229 | skyrotate = 0.0f;
230 | else
231 | skyrotate = Convert.ToSingle(_skyrotate);
232 | }
233 | }
234 |
235 |
236 | CProgram.gQ2Game.gCMain.gCImage.StartSky(ref CQ2BSP.SWorldData);
237 |
238 | for (int i = 0; i < 6; i++)
239 | {
240 | int Width;
241 | int Height;
242 |
243 | CProgram.gQ2Game.gCMain.gCImage.FindImage(skyname + suf[i], out Width, out Height, CImage.EImageType.IT_SKY);
244 |
245 | // triangle 1 (TriangleList)
246 | vertbuffer.Add(MakeSkyVec(Width, skymins[0, i], skymins[1, i], i));
247 | vertbuffer.Add(MakeSkyVec(Width, skymins[0, i], skymaxs[1, i], i));
248 | vertbuffer.Add(MakeSkyVec(Width, skymaxs[0, i], skymaxs[1, i], i));
249 |
250 | // triangle 2 (TriangleList)
251 | vertbuffer.Add(MakeSkyVec(Width, skymins[0, i], skymins[1, i], i));
252 | vertbuffer.Add(MakeSkyVec(Width, skymaxs[0, i], skymaxs[1, i], i));
253 | vertbuffer.Add(MakeSkyVec(Width, skymaxs[0, i], skymins[1, i], i));
254 |
255 | // TriangleFan
256 | //vertbuffer.Add(MakeSkyVec(Width, skymins[0, i], skymins[1, i], i));
257 | //vertbuffer.Add(MakeSkyVec(Width, skymins[0, i], skymaxs[1, i], i));
258 | //vertbuffer.Add(MakeSkyVec(Width, skymaxs[0, i], skymaxs[1, i], i));
259 | //vertbuffer.Add(MakeSkyVec(Width, skymaxs[0, i], skymins[1, i], i));
260 | }
261 |
262 | CQ2BSP.SWorldData.vbSkybox = new VertexBuffer(CProgram.gQ2Game.gGraphicsDevice, SkyboxVertexDeclaration, vertbuffer.Count, BufferUsage.WriteOnly);
263 | CQ2BSP.SWorldData.vbSkybox.SetData(vertbuffer.ToArray());
264 |
265 | CProgram.gQ2Game.gCMain.gCImage.FinalizeSky(ref CQ2BSP.SWorldData);
266 | }
267 |
268 |
269 | // ================================================================
270 | //
271 | // SKYBOX VERTEX FORMAT
272 | //
273 | // ================================================================
274 |
275 | public struct SkyboxVertexFormat
276 | {
277 | public Vector3 Position;
278 | public Vector2 TextureCoordinate;
279 |
280 | public static VertexElement[] VertexElements =
281 | {
282 | new VertexElement(sizeof(float) * 0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
283 | new VertexElement(sizeof(float) * 3, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0),
284 | };
285 | }
286 |
287 | }
288 | }
289 |
--------------------------------------------------------------------------------