fna-workbench

fna-workbench Commit Details


Date:2016-01-13 14:45:45 (9 years 7 months ago)
Author:Ethan Lee
Branch:master
Commit:5fa4cba009415fbe7972006bad2511a6a238ed7e
Parents: 64a5c503d34d6fdb9bd4f7f6c31b7b3a3c00a3d8
Message:Pushing more responsibility onto Game over GamePlatform

Changes:

File differences

src/Game.cs
3535
3636
3737
38
3839
3940
4041
......
8182
8283
8384
85
8486
8587
8688
8789
88
90
91
92
93
94
95
96
97
98
8999
90100
91101
......
93103
94104
95105
96
106
97107
98108
99109
100
110
111
112
113
114
101115
102116
103117
......
109123
110124
111125
112
113
114
115
116
117126
118127
119128
......
122131
123132
124133
125
126
127
128
129
134
130135
131136
132137
......
190195
191196
192197
193
198
199
200
201
202
203
204
205
206
207
194208
195209
196210
......
232246
233247
234248
249
250
251
252
253
235254
236255
237256
......
269288
270289
271290
272
273
274291
275292
276293
......
332349
333350
334351
335
336
337352
338353
339354
355
340356
341357
342358
......
388404
389405
390406
391
392407
393408
394409
......
404419
405420
406421
407
422
408423
409424
410425
......
427442
428443
429444
430
431
432
433
434
435
436445
437446
438447
......
567576
568577
569578
570
579
571580
572581
573582
......
632641
633642
634643
635
644
645
646
647
648
636649
637650
638651
......
784797
785798
786799
787
788
789
790
791
792
793
794
795
796
797
798
799
800800
801801
802802
......
810810
811811
812812
813
814
815
813
816814
817
818
815
819816
820817
821818
......
824821
825822
826823
824
825
826
827
828
829
830
831
832
833
834
827835
828836
829837
using System.Reflection;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
#endregion
}
}
public bool IsActive
{
get
{
return Platform.IsActive;
return _isActive;
}
internal set
{
if (_isActive != value)
{
_isActive = value;
Raise(_isActive ? Activated : Deactivated, EventArgs.Empty);
}
}
}
{
get
{
return Platform.IsMouseVisible;
return _isMouseVisible;
}
set
{
Platform.IsMouseVisible = value;
if (_isMouseVisible != value)
{
_isMouseVisible = value;
Platform.OnIsMouseVisibleChanged(value);
}
}
}
}
set
{
/* Give GamePlatform implementations an opportunity to override
* the new value.
*/
value = Platform.TargetElapsedTimeChanging(value);
if (value <= TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(
);
}
if (value != _targetElapsedTime)
{
_targetElapsedTime = value;
Platform.TargetElapsedTimeChanged();
}
_targetElapsedTime = value;
}
}
{
get
{
return Platform.Window;
return _window;
}
internal set
{
if (_window == null)
{
Mouse.WindowHandle = value.Handle;
}
_window = value;
}
}
private IGraphicsDeviceService _graphicsDeviceService;
private GameWindow _window;
private bool _isActive = true;
private bool _isMouseVisible = false;
private bool _initialized = false;
private bool _isFixedTimeStep = true;
_content = new ContentManager(_services);
Platform = GamePlatform.Create(this);
Platform.Activated += OnActivated;
Platform.Deactivated += OnDeactivated;
_services.AddService(typeof(GamePlatform), Platform);
AudioDevice.Initialize();
if (Platform != null)
{
Platform.Activated -= OnActivated;
Platform.Deactivated -= OnDeactivated;
_services.RemoveService(typeof(GamePlatform));
Platform.Dispose();
Platform = null;
Mouse.WindowHandle = IntPtr.Zero;
}
ContentTypeReaderManager.ClearTypeCreators();
{
if (_initialized)
{
Platform.ResetElapsedTime();
_gameTimer.Reset();
_gameTimer.Start();
_accumulatedElapsedTime = TimeSpan.Zero;
public void RunOneFrame()
{
if (Platform == null || !Platform.BeforeRun())
if (Platform == null)
{
return;
}
public void Run()
{
AssertNotDisposed();
if (!Platform.BeforeRun())
{
BeginRun();
_gameTimer = Stopwatch.StartNew();
return;
}
if (!_initialized)
{
* http://stackoverflow.com/questions/4054936/manual-control-over-when-to-redraw-the-screen/4057180#4057180
* http://stackoverflow.com/questions/4235439/xna-3-1-to-4-0-requires-constant-redraw-or-will-display-a-purple-screen
*/
if (Platform.BeforeDraw(_gameTime) && BeginDraw())
if (BeginDraw())
{
Draw(_gameTime);
EndDraw();
12
);
#endif
Platform.Present();
if (GraphicsDevice != null)
{
GraphicsDevice.Present();
Platform.Present(GraphicsDevice);
}
}
protected virtual void BeginRun()
#endregion
#region Internal Methods
[Conditional("DEBUG")]
internal void Log(string Message)
{
if (Platform != null)
{
Platform.Log(Message);
}
}
#endregion
#region Private Methods
/* FIXME: We should work toward eliminating internal methods. They
#if BASIC_PROFILER
updateStart = _gameTimer.ElapsedTicks;
#endif
if (Platform.BeforeUpdate(gameTime))
{
AudioDevice.Update();
AudioDevice.Update();
Update(gameTime);
}
Update(gameTime);
#if BASIC_PROFILER
updateTime = _gameTimer.ElapsedTicks - updateStart;
#endif
private void DoInitialize()
{
AssertNotDisposed();
IsActive = true;
if (GraphicsDevice == null)
{
IGraphicsDeviceManager graphicsDeviceManager = Services.GetService(
typeof(IGraphicsDeviceManager)
) as IGraphicsDeviceManager;
graphicsDeviceManager.CreateDevice();
}
Platform.BeforeInitialize();
Initialize();
src/GamePlatform.cs
3030
3131
3232
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
33
8734
8835
8936
......
9542
9643
9744
98
99
100
101
45
46
10247
10348
10449
10550
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
12251
12352
12453
......
12958
13059
13160
61
13262
13363
13464
......
14272
14373
14474
145
146
147
148
149
150
151
15275
15376
15477
78
79
80
81
82
83
84
85
15586
15687
15788
15889
15990
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
91
18392
18493
18594
......
193102
194103
195104
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225105
226106
227107
......
250130
251131
252132
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
133
269134
270
135
271136
272137
273138
274139
275140
276141
277
278
279
280
281
142
282143
283
144
284145
285
146
286147
287
148
288149
289
150
290151
291152
292153
......
296157
297158
298159
299
160
300161
301162
302163
......
305166
306167
307168
308
169
309170
310
171
311172
312
313
314
315
316
317
318
319
320
321
322
323
324
325
173
326174
327175
328176
......
358206
359207
360208
361
209
362210
363
364
365
211
366212
367213
368214
369
370
371
372
373
374
375
376
377
378215
379216
380217
private set;
}
public bool IsActive
{
get
{
return _isActive;
}
internal set
{
if (_isActive != value)
{
_isActive = value;
Raise(_isActive ? Activated : Deactivated, EventArgs.Empty);
}
}
}
public bool IsMouseVisible
{
get
{
return _isMouseVisible;
}
set
{
if (_isMouseVisible != value)
{
_isMouseVisible = value;
OnIsMouseVisibleChanged();
}
}
}
public GameWindow Window
{
get
{
return _window;
}
protected set
{
if (_window == null)
{
Mouse.WindowHandle = value.Handle;
}
_window = value;
}
}
#endregion
#region Internal Properties
internal string OSVersion
public string OSVersion
{
get;
private set;
protected bool IsDisposed
{
get
{
return disposed;
}
get;
private set;
}
#endregion
#region Protected Variables
protected TimeSpan _inactiveSleepTime = TimeSpan.FromMilliseconds(20.0);
protected bool _needsToResetElapsedTime = false;
#endregion
#region Private Variables
bool disposed;
private bool _isActive;
private bool _isMouseVisible;
private GameWindow _window;
#endregion
#region Protected Constructor
protected GamePlatform(Game game, string osVersion)
}
Game = game;
OSVersion = osVersion;
IsDisposed = false;
}
#endregion
#endregion
#region Events
public event EventHandler<EventArgs> Activated;
public event EventHandler<EventArgs> Deactivated;
#endregion
#region Public Methods
/// <summary>
/// Log the specified Message.
/// </summary>
/// <param name='Message'>
/// The string to print to the log.
/// </param>
public abstract void Log(string Message);
/// <summary>
/// Gives derived classes an opportunity to do work before any
/// components are initialized. Note that the base implementation sets
/// IsActive to true, so derived classes should either call the base
/// implementation or set IsActive to true by their own means.
/// </summary>
public virtual void BeforeInitialize()
{
IsActive = true;
if (this.Game.GraphicsDevice == null)
{
IGraphicsDeviceManager graphicsDeviceManager = Game.Services.GetService(
typeof(IGraphicsDeviceManager)
) as IGraphicsDeviceManager;
graphicsDeviceManager.CreateDevice();
}
}
/// <summary>
/// Gives derived classes an opportunity to do work just before the
/// run loop is begun. Implementations may also return false to prevent
/// the run loop from starting.
/// </summary>
/// <returns></returns>
public virtual bool BeforeRun()
{
return true;
}
public abstract void BeforeInitialize();
/// <summary>
/// When implemented in a derived class, ends the active run loop.
public abstract void RunLoop();
/// <summary>
/// Gives derived classes an opportunity to do work just before Update
/// is called for all IUpdatable components. Returning false from this
/// method will result in this round of Update calls being skipped.
/// </summary>
/// <param name="gameTime"></param>
/// <returns></returns>
public abstract bool BeforeUpdate(GameTime gameTime);
/// <summary>
/// Gives derived classes an opportunity to do work just before Draw
/// is called for all IDrawable components. Returning false from this
/// method will result in this round of Draw calls being skipped.
/// </summary>
/// <param name="gameTime"></param>
/// <returns></returns>
public abstract bool BeforeDraw(GameTime gameTime);
/// <summary>
/// Gives derived classes an opportunity to modify
/// Game.TargetElapsedTime before it is set.
/// </summary>
/// <param name="value">The proposed new value of TargetElapsedTime.</param>
/// <returns>The new value of TargetElapsedTime that will be set.</returns>
public virtual TimeSpan TargetElapsedTimeChanging(TimeSpan value)
{
return value;
}
/// <summary>
/// Starts a device transition (windowed to full screen or vice versa).
/// </summary>
/// <param name='willBeFullScreen'>
int clientHeight
);
/// <summary>
/// Gives derived classes an opportunity to take action after
/// Game.TargetElapsedTime has been set.
/// </summary>
public virtual void TargetElapsedTimeChanged() {}
/// <summary>
/// MSDN: Use this method if your game is recovering from a slow-running state, and
/// ElapsedGameTime is too large to be useful. Frame timing is generally handled
/// by the Game class, but some platforms still handle it elsewhere. Once all
/// platforms rely on the Game class's functionality, this method and any overrides
/// should be removed.
/// </summary>
public virtual void ResetElapsedTime() {}
protected virtual void OnIsMouseVisibleChanged() {}
public abstract void OnIsMouseVisibleChanged(bool visible);
public virtual void Present() {}
public abstract void Present(GraphicsDevice device);
public abstract void ShowRuntimeError(
String title,
String message
);
#endregion
#region Internal Methods
internal abstract DisplayMode GetCurrentDisplayMode();
public abstract DisplayMode GetCurrentDisplayMode();
internal abstract DisplayModeCollection GetDisplayModes();
public abstract DisplayModeCollection GetDisplayModes();
internal abstract void SetPresentationInterval(PresentInterval interval);
public abstract void SetPresentationInterval(PresentInterval interval);
internal abstract bool HasTouch();
public abstract bool HasTouch();
internal abstract void TextureDataFromStream(
public abstract void TextureDataFromStream(
Stream stream,
out int width,
out int height,
bool zoom = false
);
internal abstract void SavePNG(
public abstract void SavePNG(
Stream stream,
int width,
int height,
byte[] data
);
internal abstract Keys GetKeyFromScancode(Keys scancode);
public abstract Keys GetKeyFromScancode(Keys scancode);
internal abstract string GetStorageRoot();
public abstract string GetStorageRoot();
internal abstract bool IsStoragePathConnected(string path);
#endregion
#region Private Methods
private void Raise<TEventArgs>(EventHandler<TEventArgs> handler, TEventArgs e)
where TEventArgs : EventArgs
{
if (handler != null)
{
handler(this, e);
}
}
public abstract bool IsStoragePathConnected(string path);
#endregion
protected virtual void Dispose(bool disposing)
{
if (!disposed)
if (!IsDisposed)
{
Mouse.WindowHandle = IntPtr.Zero;
disposed = true;
IsDisposed = true;
}
}
/// <summary>
/// Log the specified Message.
/// </summary>
/// <param name='Message'>
///
/// </param>
[System.Diagnostics.Conditional("DEBUG")]
public virtual void Log(string Message) {}
#endregion
}
}
src/SDL2/SDL2_GamePlatform.cs
193193
194194
195195
196
196
197197
198198
199199
......
203203
204204
205205
206
206
207207
208208
209209
......
211211
212212
213213
214
215
216
217
218
219
220
221
222
223
224
225
214
226215
227216
228217
......
243232
244233
245234
246
235
247236
248237
249238
......
263252
264253
265254
266
255
267256
268257
269258
......
274263
275264
276265
277
266
278267
279268
280269
......
326315
327316
328317
329
318
330319
331320
332321
333322
334323
335
324
336325
337326
338327
......
344333
345334
346335
347
336
348337
349338
350339
351
340
352341
353342
354343
......
362351
363352
364353
365
354
366355
367356
368357
......
399388
400389
401390
402
391
403392
404393
405394
......
480469
481470
482471
483
484
485472
486473
487474
......
496483
497484
498485
499
500
501
502
503
504
505
506
507
508
509486
510487
511
488
512489
513490
514491
515492
516
493
517494
518495
519496
......
525502
526503
527504
528
505
529506
530
531
532
533
534
535
536507
537
538
539
540
541
542
543
544
545
546
547
548
549
550
508
509
510
511
512
513
514
515
516
517
518
519
551520
521
552522
553523
554524
......
557527
558528
559529
560
530
561531
562532
563533
564
565
566
567
568
534
569535
570536
571537
......
576542
577543
578544
579
545
580546
581547
582548
583549
584
550
585551
586552
587553
......
618584
619585
620586
621
587
622588
623589
624590
625591
626
592
627593
628594
629595
......
777743
778744
779745
780
746
781747
782748
783749
......
856822
857823
858824
859
825
860826
861827
862828
863829
864
830
865831
866832
867833
......
898864
899865
900866
901
867
902868
903869
904870
......
923889
924890
925891
892
893
894
895
896
926897
927898
928899
929900
930
931
932
933
934
935901
936902
937903
938904
939
905
940906
941907
942908
......
949915
950916
951917
952
918
953919
954
920
955921
956922
957923
bool forceCoreProfile = Environment.GetEnvironmentVariable(
"FNA_OPENGL_FORCE_CORE_PROFILE"
) == "1";
Window = new SDL2_GameWindow(
game.Window = new SDL2_GameWindow(
forceES2 ||
OSVersion.Equals("Emscripten") ||
OSVersion.Equals("Android") ||
// Create the DisplayMode list
displayIndex = SDL.SDL_GetWindowDisplayIndex(
Window.Handle
game.Window.Handle
);
INTERNAL_GenerateDisplayModes();
SDL.SDL_DisableScreenSaver();
// We hide the mouse cursor by default.
if (IsMouseVisible)
{
IsMouseVisible = false;
}
else
{
/* Since IsMouseVisible is already false, OnMouseVisibleChanged
* will NOT be called! So we get to do it ourselves.
* -flibit
*/
SDL.SDL_ShowCursor(0);
}
SDL.SDL_ShowCursor(0);
// OSX has some fancy fullscreen features, let's use them!
if (OSVersion.Equals("Mac OS X"))
INTERNAL_TextInputControlRepeat = new int[4];
// Assume we will have focus.
IsActive = true;
game.IsActive = true;
// Ready to run the loop!
INTERNAL_runApplication = true;
return;
}
DRC.drc_enable_system_input_feeder(wiiuStream);
Rectangle bounds = Window.ClientBounds;
Rectangle bounds = game.Window.ClientBounds;
wiiuPixelData = new byte[bounds.Width * bounds.Height * 4];
#endif
}
public override void RunLoop()
{
SDL.SDL_ShowWindow(Window.Handle);
SDL.SDL_ShowWindow(Game.Window.Handle);
SDL.SDL_Event evt;
// Window Focus
if (evt.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_FOCUS_GAINED)
{
IsActive = true;
Game.IsActive = true;
if (!INTERNAL_useFullscreenSpaces)
{
// If we alt-tab away, we lose the 'fullscreen desktop' flag on some WMs
SDL.SDL_SetWindowFullscreen(
Window.Handle,
Game.Window.Handle,
Game.GraphicsDevice.PresentationParameters.IsFullScreen ?
(uint) SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP :
0
}
else if (evt.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_FOCUS_LOST)
{
IsActive = false;
Game.IsActive = false;
if (!INTERNAL_useFullscreenSpaces)
{
SDL.SDL_SetWindowFullscreen(Window.Handle, 0);
SDL.SDL_SetWindowFullscreen(Game.Window.Handle, 0);
}
// Give the screensaver back, we're not that important now.
Mouse.INTERNAL_WindowHeight = evt.window.data2;
// Should be called on user resize only, NOT ApplyChanges!
((SDL2_GameWindow) Window).INTERNAL_ClientSizeChanged();
((SDL2_GameWindow) Game.Window).INTERNAL_ClientSizeChanged();
}
else if (evt.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_SIZE_CHANGED)
{
* -flibit
*/
int newIndex = SDL.SDL_GetWindowDisplayIndex(
Window.Handle
Game.Window.Handle
);
if (newIndex != displayIndex)
{
public override void BeforeInitialize()
{
base.BeforeInitialize();
// We want to initialize the controllers ASAP!
SDL.SDL_Event[] evt = new SDL.SDL_Event[1];
SDL.SDL_PumpEvents(); // Required to get OSX device events this early.
}
}
public override bool BeforeUpdate(GameTime gameTime)
{
return true;
}
public override bool BeforeDraw(GameTime gameTime)
{
return true;
}
public override void BeginScreenDeviceChange(bool willBeFullScreen)
{
Window.BeginScreenDeviceChange(willBeFullScreen);
Game.Window.BeginScreenDeviceChange(willBeFullScreen);
}
public override void EndScreenDeviceChange(string screenDeviceName, int clientWidth, int clientHeight)
{
Window.EndScreenDeviceChange(screenDeviceName, clientWidth, clientHeight);
Game.Window.EndScreenDeviceChange(screenDeviceName, clientWidth, clientHeight);
#if WIIU_GAMEPAD
wiiuPixelData = new byte[clientWidth * clientHeight * 4];
Console.WriteLine(Message);
}
public override void Present()
public override void Present(GraphicsDevice device)
{
base.Present();
GraphicsDevice device = Game.GraphicsDevice;
if (device != null)
{
device.Present();
#if WIIU_GAMEPAD
if (wiiuStream != IntPtr.Zero)
{
device.GetBackBufferData(wiiuPixelData);
DRC.drc_push_vid_frame(
wiiuStream,
wiiuPixelData,
(uint) wiiuPixelData.Length,
(ushort) device.GLDevice.Backbuffer.Width,
(ushort) device.GLDevice.Backbuffer.Height,
DRC.drc_pixel_format.DRC_RGBA,
DRC.drc_flipping_mode.DRC_NO_FLIP
);
}
#endif
if (wiiuStream != IntPtr.Zero)
{
device.GetBackBufferData(wiiuPixelData);
DRC.drc_push_vid_frame(
wiiuStream,
wiiuPixelData,
(uint) wiiuPixelData.Length,
(ushort) device.GLDevice.Backbuffer.Width,
(ushort) device.GLDevice.Backbuffer.Height,
DRC.drc_pixel_format.DRC_RGBA,
DRC.drc_flipping_mode.DRC_NO_FLIP
);
}
#endif
}
public override void ShowRuntimeError(string title, string message)
SDL.SDL_MessageBoxFlags.SDL_MESSAGEBOX_ERROR,
title,
message,
Window.Handle
Game.Window.Handle
);
}
#endregion
#region Internal GamePlatform Methods
internal override DisplayMode GetCurrentDisplayMode()
public override DisplayMode GetCurrentDisplayMode()
{
SDL.SDL_DisplayMode mode;
SDL.SDL_GetCurrentDisplayMode(displayIndex, out mode);
);
}
internal override DisplayModeCollection GetDisplayModes()
public override DisplayModeCollection GetDisplayModes()
{
return supportedDisplayModes;
}
internal override void SetPresentationInterval(PresentInterval interval)
public override void SetPresentationInterval(PresentInterval interval)
{
if (interval == PresentInterval.Default || interval == PresentInterval.One)
{
}
}
internal override bool HasTouch()
public override bool HasTouch()
{
return SDL.SDL_GetNumTouchDevices() > 0;
}
internal override void TextureDataFromStream(
public override void TextureDataFromStream(
Stream stream,
out int width,
out int height,
}
}
internal override void SavePNG(
public override void SavePNG(
Stream stream,
int width,
int height,
stream.Write(pngOut, 0, size);
}
internal override Keys GetKeyFromScancode(Keys scancode)
public override Keys GetKeyFromScancode(Keys scancode)
{
return SDL2_KeyboardUtil.KeyFromScancode(scancode);
}
internal override string GetStorageRoot()
public override string GetStorageRoot()
{
if (OSVersion.Equals("Windows"))
{
throw new Exception("StorageDevice: Platform.OSVersion not handled!");
}
internal override bool IsStoragePathConnected(string path)
public override bool IsStoragePathConnected(string path)
{
if (OSVersion.Equals("Linux") ||
OSVersion.Equals("Mac OS X"))
throw new Exception("StorageDevice: Platform.OSVersion not handled!");
}
public override void OnIsMouseVisibleChanged(bool visible)
{
SDL.SDL_ShowCursor(visible ? 1 : 0);
}
#endregion
#region Protected GamePlatform Methods
protected override void OnIsMouseVisibleChanged()
{
SDL.SDL_ShowCursor(IsMouseVisible ? 1 : 0);
}
protected override void Dispose(bool disposing)
{
if (!IsDisposed)
{
if (Window != null)
if (Game.Window != null)
{
/* Some window managers might try to minimize the window as we're
* destroying it. This looks pretty stupid and could cause problems,
SDL.SDL_HintPriority.SDL_HINT_OVERRIDE
);
SDL.SDL_DestroyWindow(Window.Handle);
SDL.SDL_DestroyWindow(Game.Window.Handle);
Window = null;
Game.Window = null;
}
#if WIIU_GAMEPAD

Archive Download the corresponding diff file

Branches

Number of commits:
Page rendered in 1.37697s using 13 queries.